diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-03-19 03:05:10 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-03-19 03:05:10 -0400 |
commit | b4b7a4ef097f288f724420b473dbf92a89c0ab7e (patch) | |
tree | 23ad8101e3e77c32a8d1e1b95a9c1cd7f7a475b7 /drivers | |
parent | e9ce335df51ff782035a15c261a3c0c9892a1767 (diff) | |
parent | a3d3203e4bb40f253b1541e310dc0f9305be7c84 (diff) |
Merge branch 'master' into for-linus
Conflicts:
block/Kconfig
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers')
505 files changed, 9662 insertions, 7180 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 81e36596b1e9..34f1e1064dbc 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -99,6 +99,7 @@ obj-$(CONFIG_SGI_SN) += sn/ | |||
99 | obj-y += firmware/ | 99 | obj-y += firmware/ |
100 | obj-$(CONFIG_CRYPTO) += crypto/ | 100 | obj-$(CONFIG_CRYPTO) += crypto/ |
101 | obj-$(CONFIG_SUPERH) += sh/ | 101 | obj-$(CONFIG_SUPERH) += sh/ |
102 | obj-$(CONFIG_ARCH_SHMOBILE) += sh/ | ||
102 | obj-$(CONFIG_GENERIC_TIME) += clocksource/ | 103 | obj-$(CONFIG_GENERIC_TIME) += clocksource/ |
103 | obj-$(CONFIG_DMA_ENGINE) += dma/ | 104 | obj-$(CONFIG_DMA_ENGINE) += dma/ |
104 | obj-$(CONFIG_DCA) += dca/ | 105 | obj-$(CONFIG_DCA) += dca/ |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 66cc3f36a954..a8d8998dd5c5 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -32,7 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o | |||
32 | # | 32 | # |
33 | acpi-y += bus.o glue.o | 33 | acpi-y += bus.o glue.o |
34 | acpi-y += scan.o | 34 | acpi-y += scan.o |
35 | acpi-y += processor_pdc.o | 35 | acpi-y += processor_core.o |
36 | acpi-y += ec.o | 36 | acpi-y += ec.o |
37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
@@ -61,7 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o | |||
61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | 61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o |
62 | 62 | ||
63 | # processor has its own "processor." module_param namespace | 63 | # processor has its own "processor." module_param namespace |
64 | processor-y := processor_core.o processor_throttling.o | 64 | processor-y := processor_driver.o processor_throttling.o |
65 | processor-y += processor_idle.o processor_thermal.o | 65 | processor-y += processor_idle.o processor_thermal.o |
66 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | 66 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o |
67 | 67 | ||
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index cc8a10268f68..7116bc86494d 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -375,8 +375,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
375 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); | 375 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); |
376 | } | 376 | } |
377 | 377 | ||
378 | /* Must have a valid thread ID */ | 378 | /* Must have a valid thread. */ |
379 | |||
380 | if (!walk_state->thread) { | 379 | if (!walk_state->thread) { |
381 | ACPI_ERROR((AE_INFO, | 380 | ACPI_ERROR((AE_INFO, |
382 | "Cannot release Mutex [%4.4s], null thread info", | 381 | "Cannot release Mutex [%4.4s], null thread info", |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 58d2c91ba62b..75f39f2c166d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 54 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
55 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 55 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
56 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 | 56 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 |
57 | #define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 | ||
57 | 58 | ||
58 | #define _COMPONENT ACPI_BATTERY_COMPONENT | 59 | #define _COMPONENT ACPI_BATTERY_COMPONENT |
59 | 60 | ||
@@ -88,10 +89,15 @@ static const struct acpi_device_id battery_device_ids[] = { | |||
88 | 89 | ||
89 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); | 90 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); |
90 | 91 | ||
91 | /* For buggy DSDTs that report negative 16-bit values for either charging | 92 | enum { |
92 | * or discharging current and/or report 0 as 65536 due to bad math. | 93 | ACPI_BATTERY_ALARM_PRESENT, |
93 | */ | 94 | ACPI_BATTERY_XINFO_PRESENT, |
94 | #define QUIRK_SIGNED16_CURRENT 0x0001 | 95 | /* For buggy DSDTs that report negative 16-bit values for either |
96 | * charging or discharging current and/or report 0 as 65536 | ||
97 | * due to bad math. | ||
98 | */ | ||
99 | ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, | ||
100 | }; | ||
95 | 101 | ||
96 | struct acpi_battery { | 102 | struct acpi_battery { |
97 | struct mutex lock; | 103 | struct mutex lock; |
@@ -109,6 +115,12 @@ struct acpi_battery { | |||
109 | int design_voltage; | 115 | int design_voltage; |
110 | int design_capacity_warning; | 116 | int design_capacity_warning; |
111 | int design_capacity_low; | 117 | int design_capacity_low; |
118 | int cycle_count; | ||
119 | int measurement_accuracy; | ||
120 | int max_sampling_time; | ||
121 | int min_sampling_time; | ||
122 | int max_averaging_interval; | ||
123 | int min_averaging_interval; | ||
112 | int capacity_granularity_1; | 124 | int capacity_granularity_1; |
113 | int capacity_granularity_2; | 125 | int capacity_granularity_2; |
114 | int alarm; | 126 | int alarm; |
@@ -118,8 +130,7 @@ struct acpi_battery { | |||
118 | char oem_info[32]; | 130 | char oem_info[32]; |
119 | int state; | 131 | int state; |
120 | int power_unit; | 132 | int power_unit; |
121 | u8 alarm_present; | 133 | unsigned long flags; |
122 | long quirks; | ||
123 | }; | 134 | }; |
124 | 135 | ||
125 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 136 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
@@ -198,6 +209,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
198 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 209 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
199 | val->intval = acpi_battery_technology(battery); | 210 | val->intval = acpi_battery_technology(battery); |
200 | break; | 211 | break; |
212 | case POWER_SUPPLY_PROP_CYCLE_COUNT: | ||
213 | val->intval = battery->cycle_count; | ||
214 | break; | ||
201 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 215 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
202 | val->intval = battery->design_voltage * 1000; | 216 | val->intval = battery->design_voltage * 1000; |
203 | break; | 217 | break; |
@@ -239,6 +253,7 @@ static enum power_supply_property charge_battery_props[] = { | |||
239 | POWER_SUPPLY_PROP_STATUS, | 253 | POWER_SUPPLY_PROP_STATUS, |
240 | POWER_SUPPLY_PROP_PRESENT, | 254 | POWER_SUPPLY_PROP_PRESENT, |
241 | POWER_SUPPLY_PROP_TECHNOLOGY, | 255 | POWER_SUPPLY_PROP_TECHNOLOGY, |
256 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
242 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 257 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
243 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 258 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
244 | POWER_SUPPLY_PROP_CURRENT_NOW, | 259 | POWER_SUPPLY_PROP_CURRENT_NOW, |
@@ -254,6 +269,7 @@ static enum power_supply_property energy_battery_props[] = { | |||
254 | POWER_SUPPLY_PROP_STATUS, | 269 | POWER_SUPPLY_PROP_STATUS, |
255 | POWER_SUPPLY_PROP_PRESENT, | 270 | POWER_SUPPLY_PROP_PRESENT, |
256 | POWER_SUPPLY_PROP_TECHNOLOGY, | 271 | POWER_SUPPLY_PROP_TECHNOLOGY, |
272 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
257 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 273 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
258 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 274 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
259 | POWER_SUPPLY_PROP_CURRENT_NOW, | 275 | POWER_SUPPLY_PROP_CURRENT_NOW, |
@@ -305,6 +321,28 @@ static struct acpi_offsets info_offsets[] = { | |||
305 | {offsetof(struct acpi_battery, oem_info), 1}, | 321 | {offsetof(struct acpi_battery, oem_info), 1}, |
306 | }; | 322 | }; |
307 | 323 | ||
324 | static struct acpi_offsets extended_info_offsets[] = { | ||
325 | {offsetof(struct acpi_battery, power_unit), 0}, | ||
326 | {offsetof(struct acpi_battery, design_capacity), 0}, | ||
327 | {offsetof(struct acpi_battery, full_charge_capacity), 0}, | ||
328 | {offsetof(struct acpi_battery, technology), 0}, | ||
329 | {offsetof(struct acpi_battery, design_voltage), 0}, | ||
330 | {offsetof(struct acpi_battery, design_capacity_warning), 0}, | ||
331 | {offsetof(struct acpi_battery, design_capacity_low), 0}, | ||
332 | {offsetof(struct acpi_battery, cycle_count), 0}, | ||
333 | {offsetof(struct acpi_battery, measurement_accuracy), 0}, | ||
334 | {offsetof(struct acpi_battery, max_sampling_time), 0}, | ||
335 | {offsetof(struct acpi_battery, min_sampling_time), 0}, | ||
336 | {offsetof(struct acpi_battery, max_averaging_interval), 0}, | ||
337 | {offsetof(struct acpi_battery, min_averaging_interval), 0}, | ||
338 | {offsetof(struct acpi_battery, capacity_granularity_1), 0}, | ||
339 | {offsetof(struct acpi_battery, capacity_granularity_2), 0}, | ||
340 | {offsetof(struct acpi_battery, model_number), 1}, | ||
341 | {offsetof(struct acpi_battery, serial_number), 1}, | ||
342 | {offsetof(struct acpi_battery, type), 1}, | ||
343 | {offsetof(struct acpi_battery, oem_info), 1}, | ||
344 | }; | ||
345 | |||
308 | static int extract_package(struct acpi_battery *battery, | 346 | static int extract_package(struct acpi_battery *battery, |
309 | union acpi_object *package, | 347 | union acpi_object *package, |
310 | struct acpi_offsets *offsets, int num) | 348 | struct acpi_offsets *offsets, int num) |
@@ -350,22 +388,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery) | |||
350 | { | 388 | { |
351 | int result = -EFAULT; | 389 | int result = -EFAULT; |
352 | acpi_status status = 0; | 390 | acpi_status status = 0; |
391 | char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)? | ||
392 | "_BIX" : "_BIF"; | ||
393 | |||
353 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 394 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
354 | 395 | ||
355 | if (!acpi_battery_present(battery)) | 396 | if (!acpi_battery_present(battery)) |
356 | return 0; | 397 | return 0; |
357 | mutex_lock(&battery->lock); | 398 | mutex_lock(&battery->lock); |
358 | status = acpi_evaluate_object(battery->device->handle, "_BIF", | 399 | status = acpi_evaluate_object(battery->device->handle, name, |
359 | NULL, &buffer); | 400 | NULL, &buffer); |
360 | mutex_unlock(&battery->lock); | 401 | mutex_unlock(&battery->lock); |
361 | 402 | ||
362 | if (ACPI_FAILURE(status)) { | 403 | if (ACPI_FAILURE(status)) { |
363 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 404 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name)); |
364 | return -ENODEV; | 405 | return -ENODEV; |
365 | } | 406 | } |
366 | 407 | if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) | |
367 | result = extract_package(battery, buffer.pointer, | 408 | result = extract_package(battery, buffer.pointer, |
368 | info_offsets, ARRAY_SIZE(info_offsets)); | 409 | extended_info_offsets, |
410 | ARRAY_SIZE(extended_info_offsets)); | ||
411 | else | ||
412 | result = extract_package(battery, buffer.pointer, | ||
413 | info_offsets, ARRAY_SIZE(info_offsets)); | ||
369 | kfree(buffer.pointer); | 414 | kfree(buffer.pointer); |
370 | return result; | 415 | return result; |
371 | } | 416 | } |
@@ -399,7 +444,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
399 | battery->update_time = jiffies; | 444 | battery->update_time = jiffies; |
400 | kfree(buffer.pointer); | 445 | kfree(buffer.pointer); |
401 | 446 | ||
402 | if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && | 447 | if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) && |
403 | battery->rate_now != -1) | 448 | battery->rate_now != -1) |
404 | battery->rate_now = abs((s16)battery->rate_now); | 449 | battery->rate_now = abs((s16)battery->rate_now); |
405 | 450 | ||
@@ -412,7 +457,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) | |||
412 | union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; | 457 | union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; |
413 | struct acpi_object_list arg_list = { 1, &arg0 }; | 458 | struct acpi_object_list arg_list = { 1, &arg0 }; |
414 | 459 | ||
415 | if (!acpi_battery_present(battery)|| !battery->alarm_present) | 460 | if (!acpi_battery_present(battery) || |
461 | !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) | ||
416 | return -ENODEV; | 462 | return -ENODEV; |
417 | 463 | ||
418 | arg0.integer.value = battery->alarm; | 464 | arg0.integer.value = battery->alarm; |
@@ -437,10 +483,10 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) | |||
437 | /* See if alarms are supported, and if so, set default */ | 483 | /* See if alarms are supported, and if so, set default */ |
438 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); | 484 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); |
439 | if (ACPI_FAILURE(status)) { | 485 | if (ACPI_FAILURE(status)) { |
440 | battery->alarm_present = 0; | 486 | clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
441 | return 0; | 487 | return 0; |
442 | } | 488 | } |
443 | battery->alarm_present = 1; | 489 | set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); |
444 | if (!battery->alarm) | 490 | if (!battery->alarm) |
445 | battery->alarm = battery->design_capacity_warning; | 491 | battery->alarm = battery->design_capacity_warning; |
446 | return acpi_battery_set_alarm(battery); | 492 | return acpi_battery_set_alarm(battery); |
@@ -510,9 +556,8 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
510 | 556 | ||
511 | static void acpi_battery_quirks(struct acpi_battery *battery) | 557 | static void acpi_battery_quirks(struct acpi_battery *battery) |
512 | { | 558 | { |
513 | battery->quirks = 0; | ||
514 | if (dmi_name_in_vendors("Acer") && battery->power_unit) { | 559 | if (dmi_name_in_vendors("Acer") && battery->power_unit) { |
515 | battery->quirks |= QUIRK_SIGNED16_CURRENT; | 560 | set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags); |
516 | } | 561 | } |
517 | } | 562 | } |
518 | 563 | ||
@@ -590,6 +635,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) | |||
590 | seq_printf(seq, "design capacity low: %d %sh\n", | 635 | seq_printf(seq, "design capacity low: %d %sh\n", |
591 | battery->design_capacity_low, | 636 | battery->design_capacity_low, |
592 | acpi_battery_units(battery)); | 637 | acpi_battery_units(battery)); |
638 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
593 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | 639 | seq_printf(seq, "capacity granularity 1: %d %sh\n", |
594 | battery->capacity_granularity_1, | 640 | battery->capacity_granularity_1, |
595 | acpi_battery_units(battery)); | 641 | acpi_battery_units(battery)); |
@@ -841,6 +887,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
841 | { | 887 | { |
842 | int result = 0; | 888 | int result = 0; |
843 | struct acpi_battery *battery = NULL; | 889 | struct acpi_battery *battery = NULL; |
890 | acpi_handle handle; | ||
844 | if (!device) | 891 | if (!device) |
845 | return -EINVAL; | 892 | return -EINVAL; |
846 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); | 893 | battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); |
@@ -851,6 +898,9 @@ static int acpi_battery_add(struct acpi_device *device) | |||
851 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 898 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
852 | device->driver_data = battery; | 899 | device->driver_data = battery; |
853 | mutex_init(&battery->lock); | 900 | mutex_init(&battery->lock); |
901 | if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, | ||
902 | "_BIX", &handle))) | ||
903 | set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); | ||
854 | acpi_battery_update(battery); | 904 | acpi_battery_update(battery); |
855 | #ifdef CONFIG_ACPI_PROCFS_POWER | 905 | #ifdef CONFIG_ACPI_PROCFS_POWER |
856 | result = acpi_battery_add_fs(device); | 906 | result = acpi_battery_add_fs(device); |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a52126e46307..b70cd3756142 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -190,16 +190,16 @@ int acpi_bus_get_power(acpi_handle handle, int *state) | |||
190 | * Get the device's power state either directly (via _PSC) or | 190 | * Get the device's power state either directly (via _PSC) or |
191 | * indirectly (via power resources). | 191 | * indirectly (via power resources). |
192 | */ | 192 | */ |
193 | if (device->power.flags.explicit_get) { | 193 | if (device->power.flags.power_resources) { |
194 | result = acpi_power_get_inferred_state(device); | ||
195 | if (result) | ||
196 | return result; | ||
197 | } else if (device->power.flags.explicit_get) { | ||
194 | status = acpi_evaluate_integer(device->handle, "_PSC", | 198 | status = acpi_evaluate_integer(device->handle, "_PSC", |
195 | NULL, &psc); | 199 | NULL, &psc); |
196 | if (ACPI_FAILURE(status)) | 200 | if (ACPI_FAILURE(status)) |
197 | return -ENODEV; | 201 | return -ENODEV; |
198 | device->power.state = (int)psc; | 202 | device->power.state = (int)psc; |
199 | } else if (device->power.flags.power_resources) { | ||
200 | result = acpi_power_get_inferred_state(device); | ||
201 | if (result) | ||
202 | return result; | ||
203 | } | 203 | } |
204 | 204 | ||
205 | *state = device->power.state; | 205 | *state = device->power.state; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index b2586f57e1f5..d9a85f1ddde6 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -605,7 +605,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, | |||
605 | list_for_each_entry(dock_station, &dock_stations, sibling) { | 605 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
606 | /* | 606 | /* |
607 | * An ATA bay can be in a dock and itself can be ejected | 607 | * An ATA bay can be in a dock and itself can be ejected |
608 | * seperately, so there are two 'dock stations' which need the | 608 | * separately, so there are two 'dock stations' which need the |
609 | * ops | 609 | * ops |
610 | */ | 610 | */ |
611 | dd = find_dock_dependent_device(dock_station, handle); | 611 | dd = find_dock_dependent_device(dock_station, handle); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d7a6bbbb834c..1ac28c6a672e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -76,8 +76,9 @@ enum ec_command { | |||
76 | enum { | 76 | enum { |
77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
80 | * OpReg are installed */ | 80 | * OpReg are installed */ |
81 | EC_FLAGS_FROZEN, /* Transactions are suspended */ | ||
81 | }; | 82 | }; |
82 | 83 | ||
83 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 84 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
@@ -291,6 +292,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
291 | if (t->rdata) | 292 | if (t->rdata) |
292 | memset(t->rdata, 0, t->rlen); | 293 | memset(t->rdata, 0, t->rlen); |
293 | mutex_lock(&ec->lock); | 294 | mutex_lock(&ec->lock); |
295 | if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { | ||
296 | status = -EINVAL; | ||
297 | goto unlock; | ||
298 | } | ||
294 | if (ec->global_lock) { | 299 | if (ec->global_lock) { |
295 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 300 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
296 | if (ACPI_FAILURE(status)) { | 301 | if (ACPI_FAILURE(status)) { |
@@ -453,6 +458,32 @@ int ec_transaction(u8 command, | |||
453 | 458 | ||
454 | EXPORT_SYMBOL(ec_transaction); | 459 | EXPORT_SYMBOL(ec_transaction); |
455 | 460 | ||
461 | void acpi_ec_suspend_transactions(void) | ||
462 | { | ||
463 | struct acpi_ec *ec = first_ec; | ||
464 | |||
465 | if (!ec) | ||
466 | return; | ||
467 | |||
468 | mutex_lock(&ec->lock); | ||
469 | /* Prevent transactions from being carried out */ | ||
470 | set_bit(EC_FLAGS_FROZEN, &ec->flags); | ||
471 | mutex_unlock(&ec->lock); | ||
472 | } | ||
473 | |||
474 | void acpi_ec_resume_transactions(void) | ||
475 | { | ||
476 | struct acpi_ec *ec = first_ec; | ||
477 | |||
478 | if (!ec) | ||
479 | return; | ||
480 | |||
481 | mutex_lock(&ec->lock); | ||
482 | /* Allow transactions to be carried out again */ | ||
483 | clear_bit(EC_FLAGS_FROZEN, &ec->flags); | ||
484 | mutex_unlock(&ec->lock); | ||
485 | } | ||
486 | |||
456 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) | 487 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) |
457 | { | 488 | { |
458 | int result; | 489 | int result; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 9c4c962e46e3..e28411367239 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -49,6 +49,8 @@ void acpi_early_processor_set_pdc(void); | |||
49 | int acpi_ec_init(void); | 49 | int acpi_ec_init(void); |
50 | int acpi_ec_ecdt_probe(void); | 50 | int acpi_ec_ecdt_probe(void); |
51 | int acpi_boot_ec_enable(void); | 51 | int acpi_boot_ec_enable(void); |
52 | void acpi_ec_suspend_transactions(void); | ||
53 | void acpi_ec_resume_transactions(void); | ||
52 | 54 | ||
53 | /*-------------------------------------------------------------------------- | 55 | /*-------------------------------------------------------------------------- |
54 | Suspend/Resume | 56 | Suspend/Resume |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index d0d25e2e1ced..1ac678d2c51c 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -435,7 +435,7 @@ acpi_system_write_wakeup_device(struct file *file, | |||
435 | found_dev->wakeup.gpe_device)) { | 435 | found_dev->wakeup.gpe_device)) { |
436 | printk(KERN_WARNING | 436 | printk(KERN_WARNING |
437 | "ACPI: '%s' and '%s' have the same GPE, " | 437 | "ACPI: '%s' and '%s' have the same GPE, " |
438 | "can't disable/enable one seperately\n", | 438 | "can't disable/enable one separately\n", |
439 | dev->pnp.bus_id, found_dev->pnp.bus_id); | 439 | dev->pnp.bus_id, found_dev->pnp.bus_id); |
440 | dev->wakeup.state.enabled = | 440 | dev->wakeup.state.enabled = |
441 | found_dev->wakeup.state.enabled; | 441 | found_dev->wakeup.state.enabled; |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9b7b402dbfb..791ac7b0f8df 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -1,383 +1,62 @@ | |||
1 | /* | 1 | /* |
2 | * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) | 2 | * Copyright (C) 2005 Intel Corporation |
3 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. | ||
3 | * | 4 | * |
4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | 5 | * Alex Chiang <achiang@hp.com> |
5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | 6 | * - Unified x86/ia64 implementations |
6 | * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> | 7 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
7 | * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | 8 | * - Added _PDC for platforms with Intel CPUs |
8 | * - Added processor hotplug support | ||
9 | * | ||
10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
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 (at | ||
15 | * your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, but | ||
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License along | ||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
25 | * | ||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
27 | * TBD: | ||
28 | * 1. Make # power states dynamic. | ||
29 | * 2. Support duty_cycle values that span bit 4. | ||
30 | * 3. Optimize by having scheduler determine business instead of | ||
31 | * having us try to calculate it here. | ||
32 | * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. | ||
33 | */ | 9 | */ |
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/types.h> | ||
39 | #include <linux/pci.h> | ||
40 | #include <linux/pm.h> | ||
41 | #include <linux/cpufreq.h> | ||
42 | #include <linux/cpu.h> | ||
43 | #include <linux/proc_fs.h> | ||
44 | #include <linux/seq_file.h> | ||
45 | #include <linux/dmi.h> | 10 | #include <linux/dmi.h> |
46 | #include <linux/moduleparam.h> | ||
47 | #include <linux/cpuidle.h> | ||
48 | 11 | ||
49 | #include <asm/io.h> | ||
50 | #include <asm/system.h> | ||
51 | #include <asm/cpu.h> | ||
52 | #include <asm/delay.h> | ||
53 | #include <asm/uaccess.h> | ||
54 | #include <asm/processor.h> | ||
55 | #include <asm/smp.h> | ||
56 | #include <asm/acpi.h> | ||
57 | |||
58 | #include <acpi/acpi_bus.h> | ||
59 | #include <acpi/acpi_drivers.h> | 12 | #include <acpi/acpi_drivers.h> |
60 | #include <acpi/processor.h> | 13 | #include <acpi/processor.h> |
61 | 14 | ||
62 | #define PREFIX "ACPI: " | 15 | #include "internal.h" |
63 | |||
64 | #define ACPI_PROCESSOR_CLASS "processor" | ||
65 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | ||
66 | #define ACPI_PROCESSOR_FILE_INFO "info" | ||
67 | #define ACPI_PROCESSOR_FILE_THROTTLING "throttling" | ||
68 | #define ACPI_PROCESSOR_FILE_LIMIT "limit" | ||
69 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | ||
70 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | ||
71 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | ||
72 | |||
73 | #define ACPI_PROCESSOR_LIMIT_USER 0 | ||
74 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | ||
75 | 16 | ||
17 | #define PREFIX "ACPI: " | ||
76 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 18 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
77 | ACPI_MODULE_NAME("processor_core"); | 19 | ACPI_MODULE_NAME("processor_core"); |
78 | 20 | ||
79 | MODULE_AUTHOR("Paul Diefenbaugh"); | 21 | static int set_no_mwait(const struct dmi_system_id *id) |
80 | MODULE_DESCRIPTION("ACPI Processor Driver"); | ||
81 | MODULE_LICENSE("GPL"); | ||
82 | |||
83 | static int acpi_processor_add(struct acpi_device *device); | ||
84 | static int acpi_processor_remove(struct acpi_device *device, int type); | ||
85 | #ifdef CONFIG_ACPI_PROCFS | ||
86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | ||
87 | #endif | ||
88 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | ||
89 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | ||
90 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | ||
91 | |||
92 | |||
93 | static const struct acpi_device_id processor_device_ids[] = { | ||
94 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | ||
95 | {"ACPI0007", 0}, | ||
96 | {"", 0}, | ||
97 | }; | ||
98 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | ||
99 | |||
100 | static struct acpi_driver acpi_processor_driver = { | ||
101 | .name = "processor", | ||
102 | .class = ACPI_PROCESSOR_CLASS, | ||
103 | .ids = processor_device_ids, | ||
104 | .ops = { | ||
105 | .add = acpi_processor_add, | ||
106 | .remove = acpi_processor_remove, | ||
107 | .suspend = acpi_processor_suspend, | ||
108 | .resume = acpi_processor_resume, | ||
109 | .notify = acpi_processor_notify, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | #define INSTALL_NOTIFY_HANDLER 1 | ||
114 | #define UNINSTALL_NOTIFY_HANDLER 2 | ||
115 | #ifdef CONFIG_ACPI_PROCFS | ||
116 | static const struct file_operations acpi_processor_info_fops = { | ||
117 | .owner = THIS_MODULE, | ||
118 | .open = acpi_processor_info_open_fs, | ||
119 | .read = seq_read, | ||
120 | .llseek = seq_lseek, | ||
121 | .release = single_release, | ||
122 | }; | ||
123 | #endif | ||
124 | |||
125 | DEFINE_PER_CPU(struct acpi_processor *, processors); | ||
126 | EXPORT_PER_CPU_SYMBOL(processors); | ||
127 | |||
128 | struct acpi_processor_errata errata __read_mostly; | ||
129 | |||
130 | /* -------------------------------------------------------------------------- | ||
131 | Errata Handling | ||
132 | -------------------------------------------------------------------------- */ | ||
133 | |||
134 | static int acpi_processor_errata_piix4(struct pci_dev *dev) | ||
135 | { | 22 | { |
136 | u8 value1 = 0; | 23 | printk(KERN_NOTICE PREFIX "%s detected - " |
137 | u8 value2 = 0; | 24 | "disabling mwait for CPU C-states\n", id->ident); |
138 | 25 | idle_nomwait = 1; | |
139 | |||
140 | if (!dev) | ||
141 | return -EINVAL; | ||
142 | |||
143 | /* | ||
144 | * Note that 'dev' references the PIIX4 ACPI Controller. | ||
145 | */ | ||
146 | |||
147 | switch (dev->revision) { | ||
148 | case 0: | ||
149 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); | ||
150 | break; | ||
151 | case 1: | ||
152 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); | ||
153 | break; | ||
154 | case 2: | ||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); | ||
156 | break; | ||
157 | case 3: | ||
158 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); | ||
159 | break; | ||
160 | default: | ||
161 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | switch (dev->revision) { | ||
166 | |||
167 | case 0: /* PIIX4 A-step */ | ||
168 | case 1: /* PIIX4 B-step */ | ||
169 | /* | ||
170 | * See specification changes #13 ("Manual Throttle Duty Cycle") | ||
171 | * and #14 ("Enabling and Disabling Manual Throttle"), plus | ||
172 | * erratum #5 ("STPCLK# Deassertion Time") from the January | ||
173 | * 2002 PIIX4 specification update. Applies to only older | ||
174 | * PIIX4 models. | ||
175 | */ | ||
176 | errata.piix4.throttle = 1; | ||
177 | |||
178 | case 2: /* PIIX4E */ | ||
179 | case 3: /* PIIX4M */ | ||
180 | /* | ||
181 | * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA | ||
182 | * Livelock") from the January 2002 PIIX4 specification update. | ||
183 | * Applies to all PIIX4 models. | ||
184 | */ | ||
185 | |||
186 | /* | ||
187 | * BM-IDE | ||
188 | * ------ | ||
189 | * Find the PIIX4 IDE Controller and get the Bus Master IDE | ||
190 | * Status register address. We'll use this later to read | ||
191 | * each IDE controller's DMA status to make sure we catch all | ||
192 | * DMA activity. | ||
193 | */ | ||
194 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | ||
195 | PCI_DEVICE_ID_INTEL_82371AB, | ||
196 | PCI_ANY_ID, PCI_ANY_ID, NULL); | ||
197 | if (dev) { | ||
198 | errata.piix4.bmisx = pci_resource_start(dev, 4); | ||
199 | pci_dev_put(dev); | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * Type-F DMA | ||
204 | * ---------- | ||
205 | * Find the PIIX4 ISA Controller and read the Motherboard | ||
206 | * DMA controller's status to see if Type-F (Fast) DMA mode | ||
207 | * is enabled (bit 7) on either channel. Note that we'll | ||
208 | * disable C3 support if this is enabled, as some legacy | ||
209 | * devices won't operate well if fast DMA is disabled. | ||
210 | */ | ||
211 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | ||
212 | PCI_DEVICE_ID_INTEL_82371AB_0, | ||
213 | PCI_ANY_ID, PCI_ANY_ID, NULL); | ||
214 | if (dev) { | ||
215 | pci_read_config_byte(dev, 0x76, &value1); | ||
216 | pci_read_config_byte(dev, 0x77, &value2); | ||
217 | if ((value1 & 0x80) || (value2 & 0x80)) | ||
218 | errata.piix4.fdma = 1; | ||
219 | pci_dev_put(dev); | ||
220 | } | ||
221 | |||
222 | break; | ||
223 | } | ||
224 | |||
225 | if (errata.piix4.bmisx) | ||
226 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
227 | "Bus master activity detection (BM-IDE) erratum enabled\n")); | ||
228 | if (errata.piix4.fdma) | ||
229 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
230 | "Type-F DMA livelock erratum (C3 disabled)\n")); | ||
231 | |||
232 | return 0; | 26 | return 0; |
233 | } | 27 | } |
234 | 28 | ||
235 | static int acpi_processor_errata(struct acpi_processor *pr) | 29 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { |
236 | { | 30 | { |
237 | int result = 0; | 31 | set_no_mwait, "IFL91 board", { |
238 | struct pci_dev *dev = NULL; | 32 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), |
239 | 33 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | |
240 | 34 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | |
241 | if (!pr) | 35 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, |
242 | return -EINVAL; | 36 | { |
243 | 37 | set_no_mwait, "Extensa 5220", { | |
244 | /* | 38 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
245 | * PIIX4 | 39 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
246 | */ | 40 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), |
247 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | 41 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, |
248 | PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, | 42 | {}, |
249 | PCI_ANY_ID, NULL); | 43 | }; |
250 | if (dev) { | ||
251 | result = acpi_processor_errata_piix4(dev); | ||
252 | pci_dev_put(dev); | ||
253 | } | ||
254 | |||
255 | return result; | ||
256 | } | ||
257 | |||
258 | /* -------------------------------------------------------------------------- | ||
259 | FS Interface (/proc) | ||
260 | -------------------------------------------------------------------------- */ | ||
261 | |||
262 | #ifdef CONFIG_ACPI_PROCFS | ||
263 | static struct proc_dir_entry *acpi_processor_dir = NULL; | ||
264 | |||
265 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | ||
266 | { | ||
267 | struct acpi_processor *pr = seq->private; | ||
268 | |||
269 | |||
270 | if (!pr) | ||
271 | goto end; | ||
272 | |||
273 | seq_printf(seq, "processor id: %d\n" | ||
274 | "acpi id: %d\n" | ||
275 | "bus mastering control: %s\n" | ||
276 | "power management: %s\n" | ||
277 | "throttling control: %s\n" | ||
278 | "limit interface: %s\n", | ||
279 | pr->id, | ||
280 | pr->acpi_id, | ||
281 | pr->flags.bm_control ? "yes" : "no", | ||
282 | pr->flags.power ? "yes" : "no", | ||
283 | pr->flags.throttling ? "yes" : "no", | ||
284 | pr->flags.limit ? "yes" : "no"); | ||
285 | |||
286 | end: | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) | ||
291 | { | ||
292 | return single_open(file, acpi_processor_info_seq_show, | ||
293 | PDE(inode)->data); | ||
294 | } | ||
295 | |||
296 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | ||
297 | { | ||
298 | struct proc_dir_entry *entry = NULL; | ||
299 | |||
300 | |||
301 | if (!acpi_device_dir(device)) { | ||
302 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
303 | acpi_processor_dir); | ||
304 | if (!acpi_device_dir(device)) | ||
305 | return -ENODEV; | ||
306 | } | ||
307 | |||
308 | /* 'info' [R] */ | ||
309 | entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, | ||
310 | S_IRUGO, acpi_device_dir(device), | ||
311 | &acpi_processor_info_fops, | ||
312 | acpi_driver_data(device)); | ||
313 | if (!entry) | ||
314 | return -EIO; | ||
315 | |||
316 | /* 'throttling' [R/W] */ | ||
317 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, | ||
318 | S_IFREG | S_IRUGO | S_IWUSR, | ||
319 | acpi_device_dir(device), | ||
320 | &acpi_processor_throttling_fops, | ||
321 | acpi_driver_data(device)); | ||
322 | if (!entry) | ||
323 | return -EIO; | ||
324 | |||
325 | /* 'limit' [R/W] */ | ||
326 | entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, | ||
327 | S_IFREG | S_IRUGO | S_IWUSR, | ||
328 | acpi_device_dir(device), | ||
329 | &acpi_processor_limit_fops, | ||
330 | acpi_driver_data(device)); | ||
331 | if (!entry) | ||
332 | return -EIO; | ||
333 | return 0; | ||
334 | } | ||
335 | static int acpi_processor_remove_fs(struct acpi_device *device) | ||
336 | { | ||
337 | |||
338 | if (acpi_device_dir(device)) { | ||
339 | remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, | ||
340 | acpi_device_dir(device)); | ||
341 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, | ||
342 | acpi_device_dir(device)); | ||
343 | remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, | ||
344 | acpi_device_dir(device)); | ||
345 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); | ||
346 | acpi_device_dir(device) = NULL; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | #else | ||
352 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
353 | { | ||
354 | return 0; | ||
355 | } | ||
356 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
357 | { | ||
358 | return 0; | ||
359 | } | ||
360 | #endif | ||
361 | |||
362 | /* Use the acpiid in MADT to map cpus in case of SMP */ | ||
363 | |||
364 | #ifndef CONFIG_SMP | ||
365 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } | ||
366 | #else | ||
367 | |||
368 | static struct acpi_table_madt *madt; | ||
369 | 44 | ||
45 | #ifdef CONFIG_SMP | ||
370 | static int map_lapic_id(struct acpi_subtable_header *entry, | 46 | static int map_lapic_id(struct acpi_subtable_header *entry, |
371 | u32 acpi_id, int *apic_id) | 47 | u32 acpi_id, int *apic_id) |
372 | { | 48 | { |
373 | struct acpi_madt_local_apic *lapic = | 49 | struct acpi_madt_local_apic *lapic = |
374 | (struct acpi_madt_local_apic *)entry; | 50 | (struct acpi_madt_local_apic *)entry; |
375 | if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && | 51 | |
376 | lapic->processor_id == acpi_id) { | 52 | if (!(lapic->lapic_flags & ACPI_MADT_ENABLED)) |
377 | *apic_id = lapic->id; | 53 | return 0; |
378 | return 1; | 54 | |
379 | } | 55 | if (lapic->processor_id != acpi_id) |
380 | return 0; | 56 | return 0; |
57 | |||
58 | *apic_id = lapic->id; | ||
59 | return 1; | ||
381 | } | 60 | } |
382 | 61 | ||
383 | static int map_x2apic_id(struct acpi_subtable_header *entry, | 62 | static int map_x2apic_id(struct acpi_subtable_header *entry, |
@@ -385,22 +64,16 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, | |||
385 | { | 64 | { |
386 | struct acpi_madt_local_x2apic *apic = | 65 | struct acpi_madt_local_x2apic *apic = |
387 | (struct acpi_madt_local_x2apic *)entry; | 66 | (struct acpi_madt_local_x2apic *)entry; |
388 | u32 tmp = apic->local_apic_id; | ||
389 | 67 | ||
390 | /* Only check enabled APICs*/ | ||
391 | if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) | 68 | if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) |
392 | return 0; | 69 | return 0; |
393 | 70 | ||
394 | /* Device statement declaration type */ | 71 | if (device_declaration && (apic->uid == acpi_id)) { |
395 | if (device_declaration) { | 72 | *apic_id = apic->local_apic_id; |
396 | if (apic->uid == acpi_id) | 73 | return 1; |
397 | goto found; | ||
398 | } | 74 | } |
399 | 75 | ||
400 | return 0; | 76 | return 0; |
401 | found: | ||
402 | *apic_id = tmp; | ||
403 | return 1; | ||
404 | } | 77 | } |
405 | 78 | ||
406 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 79 | static int map_lsapic_id(struct acpi_subtable_header *entry, |
@@ -408,35 +81,34 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, | |||
408 | { | 81 | { |
409 | struct acpi_madt_local_sapic *lsapic = | 82 | struct acpi_madt_local_sapic *lsapic = |
410 | (struct acpi_madt_local_sapic *)entry; | 83 | (struct acpi_madt_local_sapic *)entry; |
411 | u32 tmp = (lsapic->id << 8) | lsapic->eid; | ||
412 | 84 | ||
413 | /* Only check enabled APICs*/ | ||
414 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) | 85 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) |
415 | return 0; | 86 | return 0; |
416 | 87 | ||
417 | /* Device statement declaration type */ | ||
418 | if (device_declaration) { | 88 | if (device_declaration) { |
419 | if (entry->length < 16) | 89 | if ((entry->length < 16) || (lsapic->uid != acpi_id)) |
420 | printk(KERN_ERR PREFIX | 90 | return 0; |
421 | "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", | 91 | } else if (lsapic->processor_id != acpi_id) |
422 | tmp); | 92 | return 0; |
423 | else if (lsapic->uid == acpi_id) | ||
424 | goto found; | ||
425 | /* Processor statement declaration type */ | ||
426 | } else if (lsapic->processor_id == acpi_id) | ||
427 | goto found; | ||
428 | 93 | ||
429 | return 0; | 94 | *apic_id = (lsapic->id << 8) | lsapic->eid; |
430 | found: | ||
431 | *apic_id = tmp; | ||
432 | return 1; | 95 | return 1; |
433 | } | 96 | } |
434 | 97 | ||
435 | static int map_madt_entry(int type, u32 acpi_id) | 98 | static int map_madt_entry(int type, u32 acpi_id) |
436 | { | 99 | { |
437 | unsigned long madt_end, entry; | 100 | unsigned long madt_end, entry; |
101 | static struct acpi_table_madt *madt; | ||
102 | static int read_madt; | ||
438 | int apic_id = -1; | 103 | int apic_id = -1; |
439 | 104 | ||
105 | if (!read_madt) { | ||
106 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | ||
107 | (struct acpi_table_header **)&madt))) | ||
108 | madt = NULL; | ||
109 | read_madt++; | ||
110 | } | ||
111 | |||
440 | if (!madt) | 112 | if (!madt) |
441 | return apic_id; | 113 | return apic_id; |
442 | 114 | ||
@@ -496,7 +168,7 @@ exit: | |||
496 | return apic_id; | 168 | return apic_id; |
497 | } | 169 | } |
498 | 170 | ||
499 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) | 171 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) |
500 | { | 172 | { |
501 | int i; | 173 | int i; |
502 | int apic_id = -1; | 174 | int apic_id = -1; |
@@ -513,630 +185,170 @@ static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) | |||
513 | } | 185 | } |
514 | return -1; | 186 | return -1; |
515 | } | 187 | } |
188 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | ||
516 | #endif | 189 | #endif |
517 | 190 | ||
518 | /* -------------------------------------------------------------------------- | 191 | static bool processor_physically_present(acpi_handle handle) |
519 | Driver Interface | ||
520 | -------------------------------------------------------------------------- */ | ||
521 | |||
522 | static int acpi_processor_get_info(struct acpi_device *device) | ||
523 | { | 192 | { |
524 | acpi_status status = 0; | 193 | int cpuid, type; |
194 | u32 acpi_id; | ||
195 | acpi_status status; | ||
196 | acpi_object_type acpi_type; | ||
197 | unsigned long long tmp; | ||
525 | union acpi_object object = { 0 }; | 198 | union acpi_object object = { 0 }; |
526 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 199 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
527 | struct acpi_processor *pr; | ||
528 | int cpu_index, device_declaration = 0; | ||
529 | static int cpu0_initialized; | ||
530 | |||
531 | pr = acpi_driver_data(device); | ||
532 | if (!pr) | ||
533 | return -EINVAL; | ||
534 | |||
535 | if (num_online_cpus() > 1) | ||
536 | errata.smp = TRUE; | ||
537 | |||
538 | acpi_processor_errata(pr); | ||
539 | |||
540 | /* | ||
541 | * Check to see if we have bus mastering arbitration control. This | ||
542 | * is required for proper C3 usage (to maintain cache coherency). | ||
543 | */ | ||
544 | if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { | ||
545 | pr->flags.bm_control = 1; | ||
546 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
547 | "Bus mastering arbitration control present\n")); | ||
548 | } else | ||
549 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
550 | "No bus mastering arbitration control\n")); | ||
551 | |||
552 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { | ||
553 | /* Declared with "Processor" statement; match ProcessorID */ | ||
554 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
555 | if (ACPI_FAILURE(status)) { | ||
556 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
557 | return -ENODEV; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
562 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
563 | * arch/xxx/acpi.c | ||
564 | */ | ||
565 | pr->acpi_id = object.processor.proc_id; | ||
566 | } else { | ||
567 | /* | ||
568 | * Declared with "Device" statement; match _UID. | ||
569 | * Note that we don't handle string _UIDs yet. | ||
570 | */ | ||
571 | unsigned long long value; | ||
572 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | ||
573 | NULL, &value); | ||
574 | if (ACPI_FAILURE(status)) { | ||
575 | printk(KERN_ERR PREFIX | ||
576 | "Evaluating processor _UID [%#x]\n", status); | ||
577 | return -ENODEV; | ||
578 | } | ||
579 | device_declaration = 1; | ||
580 | pr->acpi_id = value; | ||
581 | } | ||
582 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); | ||
583 | |||
584 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | ||
585 | if (!cpu0_initialized && (cpu_index == -1) && | ||
586 | (num_online_cpus() == 1)) { | ||
587 | cpu_index = 0; | ||
588 | } | ||
589 | |||
590 | cpu0_initialized = 1; | ||
591 | |||
592 | pr->id = cpu_index; | ||
593 | |||
594 | /* | ||
595 | * Extra Processor objects may be enumerated on MP systems with | ||
596 | * less than the max # of CPUs. They should be ignored _iff | ||
597 | * they are physically not present. | ||
598 | */ | ||
599 | if (pr->id == -1) { | ||
600 | if (ACPI_FAILURE | ||
601 | (acpi_processor_hotadd_init(pr->handle, &pr->id))) { | ||
602 | return -ENODEV; | ||
603 | } | ||
604 | } | ||
605 | /* | ||
606 | * On some boxes several processors use the same processor bus id. | ||
607 | * But they are located in different scope. For example: | ||
608 | * \_SB.SCK0.CPU0 | ||
609 | * \_SB.SCK1.CPU0 | ||
610 | * Rename the processor device bus id. And the new bus id will be | ||
611 | * generated as the following format: | ||
612 | * CPU+CPU ID. | ||
613 | */ | ||
614 | sprintf(acpi_device_bid(device), "CPU%X", pr->id); | ||
615 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, | ||
616 | pr->acpi_id)); | ||
617 | |||
618 | if (!object.processor.pblk_address) | ||
619 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); | ||
620 | else if (object.processor.pblk_length != 6) | ||
621 | printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", | ||
622 | object.processor.pblk_length); | ||
623 | else { | ||
624 | pr->throttling.address = object.processor.pblk_address; | ||
625 | pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; | ||
626 | pr->throttling.duty_width = acpi_gbl_FADT.duty_width; | ||
627 | |||
628 | pr->pblk = object.processor.pblk_address; | ||
629 | |||
630 | /* | ||
631 | * We don't care about error returns - we just try to mark | ||
632 | * these reserved so that nobody else is confused into thinking | ||
633 | * that this region might be unused.. | ||
634 | * | ||
635 | * (In particular, allocating the IO range for Cardbus) | ||
636 | */ | ||
637 | request_region(pr->throttling.address, 6, "ACPI CPU throttle"); | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * If ACPI describes a slot number for this CPU, we can use it | ||
642 | * ensure we get the right value in the "physical id" field | ||
643 | * of /proc/cpuinfo | ||
644 | */ | ||
645 | status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); | ||
646 | if (ACPI_SUCCESS(status)) | ||
647 | arch_fix_phys_package_id(pr->id, object.integer.value); | ||
648 | |||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | static DEFINE_PER_CPU(void *, processor_device_array); | ||
653 | |||
654 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | ||
655 | { | ||
656 | struct acpi_processor *pr = acpi_driver_data(device); | ||
657 | int saved; | ||
658 | |||
659 | if (!pr) | ||
660 | return; | ||
661 | 200 | ||
662 | switch (event) { | 201 | status = acpi_get_type(handle, &acpi_type); |
663 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: | 202 | if (ACPI_FAILURE(status)) |
664 | saved = pr->performance_platform_limit; | 203 | return false; |
665 | acpi_processor_ppc_has_changed(pr, 1); | 204 | |
666 | if (saved == pr->performance_platform_limit) | 205 | switch (acpi_type) { |
667 | break; | 206 | case ACPI_TYPE_PROCESSOR: |
668 | acpi_bus_generate_proc_event(device, event, | 207 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); |
669 | pr->performance_platform_limit); | 208 | if (ACPI_FAILURE(status)) |
670 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 209 | return false; |
671 | dev_name(&device->dev), event, | 210 | acpi_id = object.processor.proc_id; |
672 | pr->performance_platform_limit); | ||
673 | break; | 211 | break; |
674 | case ACPI_PROCESSOR_NOTIFY_POWER: | 212 | case ACPI_TYPE_DEVICE: |
675 | acpi_processor_cst_has_changed(pr); | 213 | status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); |
676 | acpi_bus_generate_proc_event(device, event, 0); | 214 | if (ACPI_FAILURE(status)) |
677 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 215 | return false; |
678 | dev_name(&device->dev), event, 0); | 216 | acpi_id = tmp; |
679 | break; | 217 | break; |
680 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | ||
681 | acpi_processor_tstate_has_changed(pr); | ||
682 | acpi_bus_generate_proc_event(device, event, 0); | ||
683 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
684 | dev_name(&device->dev), event, 0); | ||
685 | default: | 218 | default: |
686 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 219 | return false; |
687 | "Unsupported event [0x%x]\n", event)); | ||
688 | break; | ||
689 | } | 220 | } |
690 | 221 | ||
691 | return; | 222 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; |
692 | } | 223 | cpuid = acpi_get_cpuid(handle, type, acpi_id); |
693 | 224 | ||
694 | static int acpi_cpu_soft_notify(struct notifier_block *nfb, | 225 | if (cpuid == -1) |
695 | unsigned long action, void *hcpu) | 226 | return false; |
696 | { | ||
697 | unsigned int cpu = (unsigned long)hcpu; | ||
698 | struct acpi_processor *pr = per_cpu(processors, cpu); | ||
699 | 227 | ||
700 | if (action == CPU_ONLINE && pr) { | 228 | return true; |
701 | acpi_processor_ppc_has_changed(pr, 0); | ||
702 | acpi_processor_cst_has_changed(pr); | ||
703 | acpi_processor_tstate_has_changed(pr); | ||
704 | } | ||
705 | return NOTIFY_OK; | ||
706 | } | 229 | } |
707 | 230 | ||
708 | static struct notifier_block acpi_cpu_notifier = | 231 | static void acpi_set_pdc_bits(u32 *buf) |
709 | { | 232 | { |
710 | .notifier_call = acpi_cpu_soft_notify, | 233 | buf[0] = ACPI_PDC_REVISION_ID; |
711 | }; | 234 | buf[1] = 1; |
712 | |||
713 | static int __cpuinit acpi_processor_add(struct acpi_device *device) | ||
714 | { | ||
715 | struct acpi_processor *pr = NULL; | ||
716 | int result = 0; | ||
717 | struct sys_device *sysdev; | ||
718 | |||
719 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | ||
720 | if (!pr) | ||
721 | return -ENOMEM; | ||
722 | |||
723 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { | ||
724 | kfree(pr); | ||
725 | return -ENOMEM; | ||
726 | } | ||
727 | |||
728 | pr->handle = device->handle; | ||
729 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); | ||
730 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | ||
731 | device->driver_data = pr; | ||
732 | |||
733 | result = acpi_processor_get_info(device); | ||
734 | if (result) { | ||
735 | /* Processor is physically not present */ | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
740 | |||
741 | /* | ||
742 | * Buggy BIOS check | ||
743 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
744 | * Don't trust it blindly | ||
745 | */ | ||
746 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
747 | per_cpu(processor_device_array, pr->id) != device) { | ||
748 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
749 | "for the processor\n"); | ||
750 | result = -ENODEV; | ||
751 | goto err_free_cpumask; | ||
752 | } | ||
753 | per_cpu(processor_device_array, pr->id) = device; | ||
754 | 235 | ||
755 | per_cpu(processors, pr->id) = pr; | 236 | /* Enable coordination with firmware's _TSD info */ |
237 | buf[2] = ACPI_PDC_SMP_T_SWCOORD; | ||
756 | 238 | ||
757 | result = acpi_processor_add_fs(device); | 239 | /* Twiddle arch-specific bits needed for _PDC */ |
758 | if (result) | 240 | arch_acpi_set_pdc_bits(buf); |
759 | goto err_free_cpumask; | ||
760 | |||
761 | sysdev = get_cpu_sysdev(pr->id); | ||
762 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
763 | result = -EFAULT; | ||
764 | goto err_remove_fs; | ||
765 | } | ||
766 | |||
767 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
768 | acpi_processor_set_pdc(pr->handle); | ||
769 | |||
770 | #ifdef CONFIG_CPU_FREQ | ||
771 | acpi_processor_ppc_has_changed(pr, 0); | ||
772 | #endif | ||
773 | acpi_processor_get_throttling_info(pr); | ||
774 | acpi_processor_get_limit_info(pr); | ||
775 | |||
776 | |||
777 | acpi_processor_power_init(pr, device); | ||
778 | |||
779 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
780 | &processor_cooling_ops); | ||
781 | if (IS_ERR(pr->cdev)) { | ||
782 | result = PTR_ERR(pr->cdev); | ||
783 | goto err_power_exit; | ||
784 | } | ||
785 | |||
786 | dev_dbg(&device->dev, "registered as cooling_device%d\n", | ||
787 | pr->cdev->id); | ||
788 | |||
789 | result = sysfs_create_link(&device->dev.kobj, | ||
790 | &pr->cdev->device.kobj, | ||
791 | "thermal_cooling"); | ||
792 | if (result) { | ||
793 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
794 | goto err_thermal_unregister; | ||
795 | } | ||
796 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
797 | &device->dev.kobj, | ||
798 | "device"); | ||
799 | if (result) { | ||
800 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
801 | goto err_remove_sysfs; | ||
802 | } | ||
803 | |||
804 | return 0; | ||
805 | |||
806 | err_remove_sysfs: | ||
807 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
808 | err_thermal_unregister: | ||
809 | thermal_cooling_device_unregister(pr->cdev); | ||
810 | err_power_exit: | ||
811 | acpi_processor_power_exit(pr, device); | ||
812 | err_remove_fs: | ||
813 | acpi_processor_remove_fs(device); | ||
814 | err_free_cpumask: | ||
815 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
816 | |||
817 | return result; | ||
818 | } | 241 | } |
819 | 242 | ||
820 | static int acpi_processor_remove(struct acpi_device *device, int type) | 243 | static struct acpi_object_list *acpi_processor_alloc_pdc(void) |
821 | { | 244 | { |
822 | struct acpi_processor *pr = NULL; | 245 | struct acpi_object_list *obj_list; |
823 | 246 | union acpi_object *obj; | |
824 | 247 | u32 *buf; | |
825 | if (!device || !acpi_driver_data(device)) | ||
826 | return -EINVAL; | ||
827 | |||
828 | pr = acpi_driver_data(device); | ||
829 | |||
830 | if (pr->id >= nr_cpu_ids) | ||
831 | goto free; | ||
832 | 248 | ||
833 | if (type == ACPI_BUS_REMOVAL_EJECT) { | 249 | /* allocate and initialize pdc. It will be used later. */ |
834 | if (acpi_processor_handle_eject(pr)) | 250 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); |
835 | return -EINVAL; | 251 | if (!obj_list) { |
252 | printk(KERN_ERR "Memory allocation error\n"); | ||
253 | return NULL; | ||
836 | } | 254 | } |
837 | 255 | ||
838 | acpi_processor_power_exit(pr, device); | 256 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); |
839 | 257 | if (!obj) { | |
840 | sysfs_remove_link(&device->dev.kobj, "sysdev"); | 258 | printk(KERN_ERR "Memory allocation error\n"); |
841 | 259 | kfree(obj_list); | |
842 | acpi_processor_remove_fs(device); | 260 | return NULL; |
843 | |||
844 | if (pr->cdev) { | ||
845 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
846 | sysfs_remove_link(&pr->cdev->device.kobj, "device"); | ||
847 | thermal_cooling_device_unregister(pr->cdev); | ||
848 | pr->cdev = NULL; | ||
849 | } | 261 | } |
850 | 262 | ||
851 | per_cpu(processors, pr->id) = NULL; | 263 | buf = kmalloc(12, GFP_KERNEL); |
852 | per_cpu(processor_device_array, pr->id) = NULL; | 264 | if (!buf) { |
853 | 265 | printk(KERN_ERR "Memory allocation error\n"); | |
854 | free: | 266 | kfree(obj); |
855 | free_cpumask_var(pr->throttling.shared_cpu_map); | 267 | kfree(obj_list); |
856 | kfree(pr); | 268 | return NULL; |
857 | |||
858 | return 0; | ||
859 | } | ||
860 | |||
861 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
862 | /**************************************************************************** | ||
863 | * Acpi processor hotplug support * | ||
864 | ****************************************************************************/ | ||
865 | |||
866 | static int is_processor_present(acpi_handle handle) | ||
867 | { | ||
868 | acpi_status status; | ||
869 | unsigned long long sta = 0; | ||
870 | |||
871 | |||
872 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
873 | |||
874 | if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) | ||
875 | return 1; | ||
876 | |||
877 | /* | ||
878 | * _STA is mandatory for a processor that supports hot plug | ||
879 | */ | ||
880 | if (status == AE_NOT_FOUND) | ||
881 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
882 | "Processor does not support hot plug\n")); | ||
883 | else | ||
884 | ACPI_EXCEPTION((AE_INFO, status, | ||
885 | "Processor Device is not present")); | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | static | ||
890 | int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | ||
891 | { | ||
892 | acpi_handle phandle; | ||
893 | struct acpi_device *pdev; | ||
894 | |||
895 | |||
896 | if (acpi_get_parent(handle, &phandle)) { | ||
897 | return -ENODEV; | ||
898 | } | 269 | } |
899 | 270 | ||
900 | if (acpi_bus_get_device(phandle, &pdev)) { | 271 | acpi_set_pdc_bits(buf); |
901 | return -ENODEV; | ||
902 | } | ||
903 | 272 | ||
904 | if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { | 273 | obj->type = ACPI_TYPE_BUFFER; |
905 | return -ENODEV; | 274 | obj->buffer.length = 12; |
906 | } | 275 | obj->buffer.pointer = (u8 *) buf; |
276 | obj_list->count = 1; | ||
277 | obj_list->pointer = obj; | ||
907 | 278 | ||
908 | return 0; | 279 | return obj_list; |
909 | } | 280 | } |
910 | 281 | ||
911 | static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | 282 | /* |
912 | u32 event, void *data) | 283 | * _PDC is required for a BIOS-OS handshake for most of the newer |
284 | * ACPI processor features. | ||
285 | */ | ||
286 | static int | ||
287 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | ||
913 | { | 288 | { |
914 | struct acpi_processor *pr; | 289 | acpi_status status = AE_OK; |
915 | struct acpi_device *device = NULL; | ||
916 | int result; | ||
917 | |||
918 | 290 | ||
919 | switch (event) { | 291 | if (idle_nomwait) { |
920 | case ACPI_NOTIFY_BUS_CHECK: | 292 | /* |
921 | case ACPI_NOTIFY_DEVICE_CHECK: | 293 | * If mwait is disabled for CPU C-states, the C2C3_FFH access |
922 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 294 | * mode will be disabled in the parameter of _PDC object. |
923 | "Processor driver received %s event\n", | 295 | * Of course C1_FFH access mode will also be disabled. |
924 | (event == ACPI_NOTIFY_BUS_CHECK) ? | 296 | */ |
925 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); | 297 | union acpi_object *obj; |
926 | 298 | u32 *buffer = NULL; | |
927 | if (!is_processor_present(handle)) | ||
928 | break; | ||
929 | 299 | ||
930 | if (acpi_bus_get_device(handle, &device)) { | 300 | obj = pdc_in->pointer; |
931 | result = acpi_processor_device_add(handle, &device); | 301 | buffer = (u32 *)(obj->buffer.pointer); |
932 | if (result) | 302 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); |
933 | printk(KERN_ERR PREFIX | ||
934 | "Unable to add the device\n"); | ||
935 | break; | ||
936 | } | ||
937 | break; | ||
938 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
939 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
940 | "received ACPI_NOTIFY_EJECT_REQUEST\n")); | ||
941 | 303 | ||
942 | if (acpi_bus_get_device(handle, &device)) { | ||
943 | printk(KERN_ERR PREFIX | ||
944 | "Device don't exist, dropping EJECT\n"); | ||
945 | break; | ||
946 | } | ||
947 | pr = acpi_driver_data(device); | ||
948 | if (!pr) { | ||
949 | printk(KERN_ERR PREFIX | ||
950 | "Driver data is NULL, dropping EJECT\n"); | ||
951 | return; | ||
952 | } | ||
953 | break; | ||
954 | default: | ||
955 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
956 | "Unsupported event [0x%x]\n", event)); | ||
957 | break; | ||
958 | } | 304 | } |
305 | status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); | ||
959 | 306 | ||
960 | return; | ||
961 | } | ||
962 | |||
963 | static acpi_status | ||
964 | processor_walk_namespace_cb(acpi_handle handle, | ||
965 | u32 lvl, void *context, void **rv) | ||
966 | { | ||
967 | acpi_status status; | ||
968 | int *action = context; | ||
969 | acpi_object_type type = 0; | ||
970 | |||
971 | status = acpi_get_type(handle, &type); | ||
972 | if (ACPI_FAILURE(status)) | 307 | if (ACPI_FAILURE(status)) |
973 | return (AE_OK); | 308 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
974 | 309 | "Could not evaluate _PDC, using legacy perf. control.\n")); | |
975 | if (type != ACPI_TYPE_PROCESSOR) | ||
976 | return (AE_OK); | ||
977 | |||
978 | switch (*action) { | ||
979 | case INSTALL_NOTIFY_HANDLER: | ||
980 | acpi_install_notify_handler(handle, | ||
981 | ACPI_SYSTEM_NOTIFY, | ||
982 | acpi_processor_hotplug_notify, | ||
983 | NULL); | ||
984 | break; | ||
985 | case UNINSTALL_NOTIFY_HANDLER: | ||
986 | acpi_remove_notify_handler(handle, | ||
987 | ACPI_SYSTEM_NOTIFY, | ||
988 | acpi_processor_hotplug_notify); | ||
989 | break; | ||
990 | default: | ||
991 | break; | ||
992 | } | ||
993 | 310 | ||
994 | return (AE_OK); | 311 | return status; |
995 | } | 312 | } |
996 | 313 | ||
997 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) | 314 | void acpi_processor_set_pdc(acpi_handle handle) |
998 | { | 315 | { |
316 | struct acpi_object_list *obj_list; | ||
999 | 317 | ||
1000 | if (!is_processor_present(handle)) { | 318 | if (arch_has_acpi_pdc() == false) |
1001 | return AE_ERROR; | 319 | return; |
1002 | } | ||
1003 | 320 | ||
1004 | if (acpi_map_lsapic(handle, p_cpu)) | 321 | obj_list = acpi_processor_alloc_pdc(); |
1005 | return AE_ERROR; | 322 | if (!obj_list) |
323 | return; | ||
1006 | 324 | ||
1007 | if (arch_register_cpu(*p_cpu)) { | 325 | acpi_processor_eval_pdc(handle, obj_list); |
1008 | acpi_unmap_lsapic(*p_cpu); | ||
1009 | return AE_ERROR; | ||
1010 | } | ||
1011 | 326 | ||
1012 | return AE_OK; | 327 | kfree(obj_list->pointer->buffer.pointer); |
328 | kfree(obj_list->pointer); | ||
329 | kfree(obj_list); | ||
1013 | } | 330 | } |
331 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | ||
1014 | 332 | ||
1015 | static int acpi_processor_handle_eject(struct acpi_processor *pr) | 333 | static acpi_status |
334 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1016 | { | 335 | { |
1017 | if (cpu_online(pr->id)) | 336 | if (processor_physically_present(handle) == false) |
1018 | cpu_down(pr->id); | 337 | return AE_OK; |
1019 | 338 | ||
1020 | arch_unregister_cpu(pr->id); | 339 | acpi_processor_set_pdc(handle); |
1021 | acpi_unmap_lsapic(pr->id); | 340 | return AE_OK; |
1022 | return (0); | ||
1023 | } | ||
1024 | #else | ||
1025 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) | ||
1026 | { | ||
1027 | return AE_ERROR; | ||
1028 | } | ||
1029 | static int acpi_processor_handle_eject(struct acpi_processor *pr) | ||
1030 | { | ||
1031 | return (-EINVAL); | ||
1032 | } | 341 | } |
1033 | #endif | ||
1034 | 342 | ||
1035 | static | 343 | void __init acpi_early_processor_set_pdc(void) |
1036 | void acpi_processor_install_hotplug_notify(void) | ||
1037 | { | 344 | { |
1038 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 345 | /* |
1039 | int action = INSTALL_NOTIFY_HANDLER; | 346 | * Check whether the system is DMI table. If yes, OSPM |
1040 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | 347 | * should not use mwait for CPU-states. |
1041 | ACPI_ROOT_OBJECT, | 348 | */ |
1042 | ACPI_UINT32_MAX, | 349 | dmi_check_system(processor_idle_dmi_table); |
1043 | processor_walk_namespace_cb, NULL, &action, NULL); | ||
1044 | #endif | ||
1045 | register_hotcpu_notifier(&acpi_cpu_notifier); | ||
1046 | } | ||
1047 | 350 | ||
1048 | static | 351 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
1049 | void acpi_processor_uninstall_hotplug_notify(void) | ||
1050 | { | ||
1051 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
1052 | int action = UNINSTALL_NOTIFY_HANDLER; | ||
1053 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | ||
1054 | ACPI_ROOT_OBJECT, | ||
1055 | ACPI_UINT32_MAX, | 352 | ACPI_UINT32_MAX, |
1056 | processor_walk_namespace_cb, NULL, &action, NULL); | 353 | early_init_pdc, NULL, NULL, NULL); |
1057 | #endif | ||
1058 | unregister_hotcpu_notifier(&acpi_cpu_notifier); | ||
1059 | } | 354 | } |
1060 | |||
1061 | /* | ||
1062 | * We keep the driver loaded even when ACPI is not running. | ||
1063 | * This is needed for the powernow-k8 driver, that works even without | ||
1064 | * ACPI, but needs symbols from this driver | ||
1065 | */ | ||
1066 | |||
1067 | static int __init acpi_processor_init(void) | ||
1068 | { | ||
1069 | int result = 0; | ||
1070 | |||
1071 | if (acpi_disabled) | ||
1072 | return 0; | ||
1073 | |||
1074 | memset(&errata, 0, sizeof(errata)); | ||
1075 | |||
1076 | #ifdef CONFIG_SMP | ||
1077 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | ||
1078 | (struct acpi_table_header **)&madt))) | ||
1079 | madt = NULL; | ||
1080 | #endif | ||
1081 | #ifdef CONFIG_ACPI_PROCFS | ||
1082 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
1083 | if (!acpi_processor_dir) | ||
1084 | return -ENOMEM; | ||
1085 | #endif | ||
1086 | result = cpuidle_register_driver(&acpi_idle_driver); | ||
1087 | if (result < 0) | ||
1088 | goto out_proc; | ||
1089 | |||
1090 | result = acpi_bus_register_driver(&acpi_processor_driver); | ||
1091 | if (result < 0) | ||
1092 | goto out_cpuidle; | ||
1093 | |||
1094 | acpi_processor_install_hotplug_notify(); | ||
1095 | |||
1096 | acpi_thermal_cpufreq_init(); | ||
1097 | |||
1098 | acpi_processor_ppc_init(); | ||
1099 | |||
1100 | acpi_processor_throttling_init(); | ||
1101 | |||
1102 | return 0; | ||
1103 | |||
1104 | out_cpuidle: | ||
1105 | cpuidle_unregister_driver(&acpi_idle_driver); | ||
1106 | |||
1107 | out_proc: | ||
1108 | #ifdef CONFIG_ACPI_PROCFS | ||
1109 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
1110 | #endif | ||
1111 | |||
1112 | return result; | ||
1113 | } | ||
1114 | |||
1115 | static void __exit acpi_processor_exit(void) | ||
1116 | { | ||
1117 | if (acpi_disabled) | ||
1118 | return; | ||
1119 | |||
1120 | acpi_processor_ppc_exit(); | ||
1121 | |||
1122 | acpi_thermal_cpufreq_exit(); | ||
1123 | |||
1124 | acpi_processor_uninstall_hotplug_notify(); | ||
1125 | |||
1126 | acpi_bus_unregister_driver(&acpi_processor_driver); | ||
1127 | |||
1128 | cpuidle_unregister_driver(&acpi_idle_driver); | ||
1129 | |||
1130 | #ifdef CONFIG_ACPI_PROCFS | ||
1131 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
1132 | #endif | ||
1133 | |||
1134 | return; | ||
1135 | } | ||
1136 | |||
1137 | module_init(acpi_processor_init); | ||
1138 | module_exit(acpi_processor_exit); | ||
1139 | |||
1140 | EXPORT_SYMBOL(acpi_processor_set_thermal_limit); | ||
1141 | |||
1142 | MODULE_ALIAS("processor"); | ||
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c new file mode 100644 index 000000000000..b5658cdce27f --- /dev/null +++ b/drivers/acpi/processor_driver.c | |||
@@ -0,0 +1,978 @@ | |||
1 | /* | ||
2 | * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | ||
5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | ||
6 | * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> | ||
7 | * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | ||
8 | * - Added processor hotplug support | ||
9 | * | ||
10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
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 (at | ||
15 | * your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, but | ||
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License along | ||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
25 | * | ||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
27 | * TBD: | ||
28 | * 1. Make # power states dynamic. | ||
29 | * 2. Support duty_cycle values that span bit 4. | ||
30 | * 3. Optimize by having scheduler determine business instead of | ||
31 | * having us try to calculate it here. | ||
32 | * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. | ||
33 | */ | ||
34 | |||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/types.h> | ||
39 | #include <linux/pci.h> | ||
40 | #include <linux/pm.h> | ||
41 | #include <linux/cpufreq.h> | ||
42 | #include <linux/cpu.h> | ||
43 | #include <linux/proc_fs.h> | ||
44 | #include <linux/seq_file.h> | ||
45 | #include <linux/dmi.h> | ||
46 | #include <linux/moduleparam.h> | ||
47 | #include <linux/cpuidle.h> | ||
48 | |||
49 | #include <asm/io.h> | ||
50 | #include <asm/system.h> | ||
51 | #include <asm/cpu.h> | ||
52 | #include <asm/delay.h> | ||
53 | #include <asm/uaccess.h> | ||
54 | #include <asm/processor.h> | ||
55 | #include <asm/smp.h> | ||
56 | #include <asm/acpi.h> | ||
57 | |||
58 | #include <acpi/acpi_bus.h> | ||
59 | #include <acpi/acpi_drivers.h> | ||
60 | #include <acpi/processor.h> | ||
61 | |||
62 | #define PREFIX "ACPI: " | ||
63 | |||
64 | #define ACPI_PROCESSOR_CLASS "processor" | ||
65 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | ||
66 | #define ACPI_PROCESSOR_FILE_INFO "info" | ||
67 | #define ACPI_PROCESSOR_FILE_THROTTLING "throttling" | ||
68 | #define ACPI_PROCESSOR_FILE_LIMIT "limit" | ||
69 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 | ||
70 | #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 | ||
71 | #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 | ||
72 | |||
73 | #define ACPI_PROCESSOR_LIMIT_USER 0 | ||
74 | #define ACPI_PROCESSOR_LIMIT_THERMAL 1 | ||
75 | |||
76 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | ||
77 | ACPI_MODULE_NAME("processor_driver"); | ||
78 | |||
79 | MODULE_AUTHOR("Paul Diefenbaugh"); | ||
80 | MODULE_DESCRIPTION("ACPI Processor Driver"); | ||
81 | MODULE_LICENSE("GPL"); | ||
82 | |||
83 | static int acpi_processor_add(struct acpi_device *device); | ||
84 | static int acpi_processor_remove(struct acpi_device *device, int type); | ||
85 | #ifdef CONFIG_ACPI_PROCFS | ||
86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | ||
87 | #endif | ||
88 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | ||
89 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | ||
90 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | ||
91 | |||
92 | |||
93 | static const struct acpi_device_id processor_device_ids[] = { | ||
94 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | ||
95 | {"ACPI0007", 0}, | ||
96 | {"", 0}, | ||
97 | }; | ||
98 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | ||
99 | |||
100 | static struct acpi_driver acpi_processor_driver = { | ||
101 | .name = "processor", | ||
102 | .class = ACPI_PROCESSOR_CLASS, | ||
103 | .ids = processor_device_ids, | ||
104 | .ops = { | ||
105 | .add = acpi_processor_add, | ||
106 | .remove = acpi_processor_remove, | ||
107 | .suspend = acpi_processor_suspend, | ||
108 | .resume = acpi_processor_resume, | ||
109 | .notify = acpi_processor_notify, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | #define INSTALL_NOTIFY_HANDLER 1 | ||
114 | #define UNINSTALL_NOTIFY_HANDLER 2 | ||
115 | #ifdef CONFIG_ACPI_PROCFS | ||
116 | static const struct file_operations acpi_processor_info_fops = { | ||
117 | .owner = THIS_MODULE, | ||
118 | .open = acpi_processor_info_open_fs, | ||
119 | .read = seq_read, | ||
120 | .llseek = seq_lseek, | ||
121 | .release = single_release, | ||
122 | }; | ||
123 | #endif | ||
124 | |||
125 | DEFINE_PER_CPU(struct acpi_processor *, processors); | ||
126 | EXPORT_PER_CPU_SYMBOL(processors); | ||
127 | |||
128 | struct acpi_processor_errata errata __read_mostly; | ||
129 | |||
130 | /* -------------------------------------------------------------------------- | ||
131 | Errata Handling | ||
132 | -------------------------------------------------------------------------- */ | ||
133 | |||
134 | static int acpi_processor_errata_piix4(struct pci_dev *dev) | ||
135 | { | ||
136 | u8 value1 = 0; | ||
137 | u8 value2 = 0; | ||
138 | |||
139 | |||
140 | if (!dev) | ||
141 | return -EINVAL; | ||
142 | |||
143 | /* | ||
144 | * Note that 'dev' references the PIIX4 ACPI Controller. | ||
145 | */ | ||
146 | |||
147 | switch (dev->revision) { | ||
148 | case 0: | ||
149 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); | ||
150 | break; | ||
151 | case 1: | ||
152 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); | ||
153 | break; | ||
154 | case 2: | ||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); | ||
156 | break; | ||
157 | case 3: | ||
158 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); | ||
159 | break; | ||
160 | default: | ||
161 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | switch (dev->revision) { | ||
166 | |||
167 | case 0: /* PIIX4 A-step */ | ||
168 | case 1: /* PIIX4 B-step */ | ||
169 | /* | ||
170 | * See specification changes #13 ("Manual Throttle Duty Cycle") | ||
171 | * and #14 ("Enabling and Disabling Manual Throttle"), plus | ||
172 | * erratum #5 ("STPCLK# Deassertion Time") from the January | ||
173 | * 2002 PIIX4 specification update. Applies to only older | ||
174 | * PIIX4 models. | ||
175 | */ | ||
176 | errata.piix4.throttle = 1; | ||
177 | |||
178 | case 2: /* PIIX4E */ | ||
179 | case 3: /* PIIX4M */ | ||
180 | /* | ||
181 | * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA | ||
182 | * Livelock") from the January 2002 PIIX4 specification update. | ||
183 | * Applies to all PIIX4 models. | ||
184 | */ | ||
185 | |||
186 | /* | ||
187 | * BM-IDE | ||
188 | * ------ | ||
189 | * Find the PIIX4 IDE Controller and get the Bus Master IDE | ||
190 | * Status register address. We'll use this later to read | ||
191 | * each IDE controller's DMA status to make sure we catch all | ||
192 | * DMA activity. | ||
193 | */ | ||
194 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | ||
195 | PCI_DEVICE_ID_INTEL_82371AB, | ||
196 | PCI_ANY_ID, PCI_ANY_ID, NULL); | ||
197 | if (dev) { | ||
198 | errata.piix4.bmisx = pci_resource_start(dev, 4); | ||
199 | pci_dev_put(dev); | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * Type-F DMA | ||
204 | * ---------- | ||
205 | * Find the PIIX4 ISA Controller and read the Motherboard | ||
206 | * DMA controller's status to see if Type-F (Fast) DMA mode | ||
207 | * is enabled (bit 7) on either channel. Note that we'll | ||
208 | * disable C3 support if this is enabled, as some legacy | ||
209 | * devices won't operate well if fast DMA is disabled. | ||
210 | */ | ||
211 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | ||
212 | PCI_DEVICE_ID_INTEL_82371AB_0, | ||
213 | PCI_ANY_ID, PCI_ANY_ID, NULL); | ||
214 | if (dev) { | ||
215 | pci_read_config_byte(dev, 0x76, &value1); | ||
216 | pci_read_config_byte(dev, 0x77, &value2); | ||
217 | if ((value1 & 0x80) || (value2 & 0x80)) | ||
218 | errata.piix4.fdma = 1; | ||
219 | pci_dev_put(dev); | ||
220 | } | ||
221 | |||
222 | break; | ||
223 | } | ||
224 | |||
225 | if (errata.piix4.bmisx) | ||
226 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
227 | "Bus master activity detection (BM-IDE) erratum enabled\n")); | ||
228 | if (errata.piix4.fdma) | ||
229 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
230 | "Type-F DMA livelock erratum (C3 disabled)\n")); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int acpi_processor_errata(struct acpi_processor *pr) | ||
236 | { | ||
237 | int result = 0; | ||
238 | struct pci_dev *dev = NULL; | ||
239 | |||
240 | |||
241 | if (!pr) | ||
242 | return -EINVAL; | ||
243 | |||
244 | /* | ||
245 | * PIIX4 | ||
246 | */ | ||
247 | dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, | ||
248 | PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, | ||
249 | PCI_ANY_ID, NULL); | ||
250 | if (dev) { | ||
251 | result = acpi_processor_errata_piix4(dev); | ||
252 | pci_dev_put(dev); | ||
253 | } | ||
254 | |||
255 | return result; | ||
256 | } | ||
257 | |||
258 | /* -------------------------------------------------------------------------- | ||
259 | FS Interface (/proc) | ||
260 | -------------------------------------------------------------------------- */ | ||
261 | |||
262 | #ifdef CONFIG_ACPI_PROCFS | ||
263 | static struct proc_dir_entry *acpi_processor_dir = NULL; | ||
264 | |||
265 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | ||
266 | { | ||
267 | struct acpi_processor *pr = seq->private; | ||
268 | |||
269 | |||
270 | if (!pr) | ||
271 | goto end; | ||
272 | |||
273 | seq_printf(seq, "processor id: %d\n" | ||
274 | "acpi id: %d\n" | ||
275 | "bus mastering control: %s\n" | ||
276 | "power management: %s\n" | ||
277 | "throttling control: %s\n" | ||
278 | "limit interface: %s\n", | ||
279 | pr->id, | ||
280 | pr->acpi_id, | ||
281 | pr->flags.bm_control ? "yes" : "no", | ||
282 | pr->flags.power ? "yes" : "no", | ||
283 | pr->flags.throttling ? "yes" : "no", | ||
284 | pr->flags.limit ? "yes" : "no"); | ||
285 | |||
286 | end: | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) | ||
291 | { | ||
292 | return single_open(file, acpi_processor_info_seq_show, | ||
293 | PDE(inode)->data); | ||
294 | } | ||
295 | |||
296 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | ||
297 | { | ||
298 | struct proc_dir_entry *entry = NULL; | ||
299 | |||
300 | |||
301 | if (!acpi_device_dir(device)) { | ||
302 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
303 | acpi_processor_dir); | ||
304 | if (!acpi_device_dir(device)) | ||
305 | return -ENODEV; | ||
306 | } | ||
307 | |||
308 | /* 'info' [R] */ | ||
309 | entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, | ||
310 | S_IRUGO, acpi_device_dir(device), | ||
311 | &acpi_processor_info_fops, | ||
312 | acpi_driver_data(device)); | ||
313 | if (!entry) | ||
314 | return -EIO; | ||
315 | |||
316 | /* 'throttling' [R/W] */ | ||
317 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, | ||
318 | S_IFREG | S_IRUGO | S_IWUSR, | ||
319 | acpi_device_dir(device), | ||
320 | &acpi_processor_throttling_fops, | ||
321 | acpi_driver_data(device)); | ||
322 | if (!entry) | ||
323 | return -EIO; | ||
324 | |||
325 | /* 'limit' [R/W] */ | ||
326 | entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, | ||
327 | S_IFREG | S_IRUGO | S_IWUSR, | ||
328 | acpi_device_dir(device), | ||
329 | &acpi_processor_limit_fops, | ||
330 | acpi_driver_data(device)); | ||
331 | if (!entry) | ||
332 | return -EIO; | ||
333 | return 0; | ||
334 | } | ||
335 | static int acpi_processor_remove_fs(struct acpi_device *device) | ||
336 | { | ||
337 | |||
338 | if (acpi_device_dir(device)) { | ||
339 | remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, | ||
340 | acpi_device_dir(device)); | ||
341 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, | ||
342 | acpi_device_dir(device)); | ||
343 | remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, | ||
344 | acpi_device_dir(device)); | ||
345 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); | ||
346 | acpi_device_dir(device) = NULL; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | #else | ||
352 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
353 | { | ||
354 | return 0; | ||
355 | } | ||
356 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
357 | { | ||
358 | return 0; | ||
359 | } | ||
360 | #endif | ||
361 | |||
362 | /* -------------------------------------------------------------------------- | ||
363 | Driver Interface | ||
364 | -------------------------------------------------------------------------- */ | ||
365 | |||
366 | static int acpi_processor_get_info(struct acpi_device *device) | ||
367 | { | ||
368 | acpi_status status = 0; | ||
369 | union acpi_object object = { 0 }; | ||
370 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | ||
371 | struct acpi_processor *pr; | ||
372 | int cpu_index, device_declaration = 0; | ||
373 | static int cpu0_initialized; | ||
374 | |||
375 | pr = acpi_driver_data(device); | ||
376 | if (!pr) | ||
377 | return -EINVAL; | ||
378 | |||
379 | if (num_online_cpus() > 1) | ||
380 | errata.smp = TRUE; | ||
381 | |||
382 | acpi_processor_errata(pr); | ||
383 | |||
384 | /* | ||
385 | * Check to see if we have bus mastering arbitration control. This | ||
386 | * is required for proper C3 usage (to maintain cache coherency). | ||
387 | */ | ||
388 | if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { | ||
389 | pr->flags.bm_control = 1; | ||
390 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
391 | "Bus mastering arbitration control present\n")); | ||
392 | } else | ||
393 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
394 | "No bus mastering arbitration control\n")); | ||
395 | |||
396 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { | ||
397 | /* Declared with "Processor" statement; match ProcessorID */ | ||
398 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
399 | if (ACPI_FAILURE(status)) { | ||
400 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
401 | return -ENODEV; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
406 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
407 | * arch/xxx/acpi.c | ||
408 | */ | ||
409 | pr->acpi_id = object.processor.proc_id; | ||
410 | } else { | ||
411 | /* | ||
412 | * Declared with "Device" statement; match _UID. | ||
413 | * Note that we don't handle string _UIDs yet. | ||
414 | */ | ||
415 | unsigned long long value; | ||
416 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | ||
417 | NULL, &value); | ||
418 | if (ACPI_FAILURE(status)) { | ||
419 | printk(KERN_ERR PREFIX | ||
420 | "Evaluating processor _UID [%#x]\n", status); | ||
421 | return -ENODEV; | ||
422 | } | ||
423 | device_declaration = 1; | ||
424 | pr->acpi_id = value; | ||
425 | } | ||
426 | cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id); | ||
427 | |||
428 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | ||
429 | if (!cpu0_initialized && (cpu_index == -1) && | ||
430 | (num_online_cpus() == 1)) { | ||
431 | cpu_index = 0; | ||
432 | } | ||
433 | |||
434 | cpu0_initialized = 1; | ||
435 | |||
436 | pr->id = cpu_index; | ||
437 | |||
438 | /* | ||
439 | * Extra Processor objects may be enumerated on MP systems with | ||
440 | * less than the max # of CPUs. They should be ignored _iff | ||
441 | * they are physically not present. | ||
442 | */ | ||
443 | if (pr->id == -1) { | ||
444 | if (ACPI_FAILURE | ||
445 | (acpi_processor_hotadd_init(pr->handle, &pr->id))) { | ||
446 | return -ENODEV; | ||
447 | } | ||
448 | } | ||
449 | /* | ||
450 | * On some boxes several processors use the same processor bus id. | ||
451 | * But they are located in different scope. For example: | ||
452 | * \_SB.SCK0.CPU0 | ||
453 | * \_SB.SCK1.CPU0 | ||
454 | * Rename the processor device bus id. And the new bus id will be | ||
455 | * generated as the following format: | ||
456 | * CPU+CPU ID. | ||
457 | */ | ||
458 | sprintf(acpi_device_bid(device), "CPU%X", pr->id); | ||
459 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, | ||
460 | pr->acpi_id)); | ||
461 | |||
462 | if (!object.processor.pblk_address) | ||
463 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); | ||
464 | else if (object.processor.pblk_length != 6) | ||
465 | printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", | ||
466 | object.processor.pblk_length); | ||
467 | else { | ||
468 | pr->throttling.address = object.processor.pblk_address; | ||
469 | pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; | ||
470 | pr->throttling.duty_width = acpi_gbl_FADT.duty_width; | ||
471 | |||
472 | pr->pblk = object.processor.pblk_address; | ||
473 | |||
474 | /* | ||
475 | * We don't care about error returns - we just try to mark | ||
476 | * these reserved so that nobody else is confused into thinking | ||
477 | * that this region might be unused.. | ||
478 | * | ||
479 | * (In particular, allocating the IO range for Cardbus) | ||
480 | */ | ||
481 | request_region(pr->throttling.address, 6, "ACPI CPU throttle"); | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * If ACPI describes a slot number for this CPU, we can use it | ||
486 | * ensure we get the right value in the "physical id" field | ||
487 | * of /proc/cpuinfo | ||
488 | */ | ||
489 | status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); | ||
490 | if (ACPI_SUCCESS(status)) | ||
491 | arch_fix_phys_package_id(pr->id, object.integer.value); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static DEFINE_PER_CPU(void *, processor_device_array); | ||
497 | |||
498 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | ||
499 | { | ||
500 | struct acpi_processor *pr = acpi_driver_data(device); | ||
501 | int saved; | ||
502 | |||
503 | if (!pr) | ||
504 | return; | ||
505 | |||
506 | switch (event) { | ||
507 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: | ||
508 | saved = pr->performance_platform_limit; | ||
509 | acpi_processor_ppc_has_changed(pr, 1); | ||
510 | if (saved == pr->performance_platform_limit) | ||
511 | break; | ||
512 | acpi_bus_generate_proc_event(device, event, | ||
513 | pr->performance_platform_limit); | ||
514 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
515 | dev_name(&device->dev), event, | ||
516 | pr->performance_platform_limit); | ||
517 | break; | ||
518 | case ACPI_PROCESSOR_NOTIFY_POWER: | ||
519 | acpi_processor_cst_has_changed(pr); | ||
520 | acpi_bus_generate_proc_event(device, event, 0); | ||
521 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
522 | dev_name(&device->dev), event, 0); | ||
523 | break; | ||
524 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | ||
525 | acpi_processor_tstate_has_changed(pr); | ||
526 | acpi_bus_generate_proc_event(device, event, 0); | ||
527 | acpi_bus_generate_netlink_event(device->pnp.device_class, | ||
528 | dev_name(&device->dev), event, 0); | ||
529 | default: | ||
530 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
531 | "Unsupported event [0x%x]\n", event)); | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | return; | ||
536 | } | ||
537 | |||
538 | static int acpi_cpu_soft_notify(struct notifier_block *nfb, | ||
539 | unsigned long action, void *hcpu) | ||
540 | { | ||
541 | unsigned int cpu = (unsigned long)hcpu; | ||
542 | struct acpi_processor *pr = per_cpu(processors, cpu); | ||
543 | |||
544 | if (action == CPU_ONLINE && pr) { | ||
545 | acpi_processor_ppc_has_changed(pr, 0); | ||
546 | acpi_processor_cst_has_changed(pr); | ||
547 | acpi_processor_tstate_has_changed(pr); | ||
548 | } | ||
549 | return NOTIFY_OK; | ||
550 | } | ||
551 | |||
552 | static struct notifier_block acpi_cpu_notifier = | ||
553 | { | ||
554 | .notifier_call = acpi_cpu_soft_notify, | ||
555 | }; | ||
556 | |||
557 | static int __cpuinit acpi_processor_add(struct acpi_device *device) | ||
558 | { | ||
559 | struct acpi_processor *pr = NULL; | ||
560 | int result = 0; | ||
561 | struct sys_device *sysdev; | ||
562 | |||
563 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | ||
564 | if (!pr) | ||
565 | return -ENOMEM; | ||
566 | |||
567 | if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { | ||
568 | kfree(pr); | ||
569 | return -ENOMEM; | ||
570 | } | ||
571 | |||
572 | pr->handle = device->handle; | ||
573 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); | ||
574 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | ||
575 | device->driver_data = pr; | ||
576 | |||
577 | result = acpi_processor_get_info(device); | ||
578 | if (result) { | ||
579 | /* Processor is physically not present */ | ||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
584 | |||
585 | /* | ||
586 | * Buggy BIOS check | ||
587 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
588 | * Don't trust it blindly | ||
589 | */ | ||
590 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
591 | per_cpu(processor_device_array, pr->id) != device) { | ||
592 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
593 | "for the processor\n"); | ||
594 | result = -ENODEV; | ||
595 | goto err_free_cpumask; | ||
596 | } | ||
597 | per_cpu(processor_device_array, pr->id) = device; | ||
598 | |||
599 | per_cpu(processors, pr->id) = pr; | ||
600 | |||
601 | result = acpi_processor_add_fs(device); | ||
602 | if (result) | ||
603 | goto err_free_cpumask; | ||
604 | |||
605 | sysdev = get_cpu_sysdev(pr->id); | ||
606 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
607 | result = -EFAULT; | ||
608 | goto err_remove_fs; | ||
609 | } | ||
610 | |||
611 | #ifdef CONFIG_CPU_FREQ | ||
612 | acpi_processor_ppc_has_changed(pr, 0); | ||
613 | #endif | ||
614 | acpi_processor_get_throttling_info(pr); | ||
615 | acpi_processor_get_limit_info(pr); | ||
616 | |||
617 | |||
618 | acpi_processor_power_init(pr, device); | ||
619 | |||
620 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
621 | &processor_cooling_ops); | ||
622 | if (IS_ERR(pr->cdev)) { | ||
623 | result = PTR_ERR(pr->cdev); | ||
624 | goto err_power_exit; | ||
625 | } | ||
626 | |||
627 | dev_dbg(&device->dev, "registered as cooling_device%d\n", | ||
628 | pr->cdev->id); | ||
629 | |||
630 | result = sysfs_create_link(&device->dev.kobj, | ||
631 | &pr->cdev->device.kobj, | ||
632 | "thermal_cooling"); | ||
633 | if (result) { | ||
634 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
635 | goto err_thermal_unregister; | ||
636 | } | ||
637 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
638 | &device->dev.kobj, | ||
639 | "device"); | ||
640 | if (result) { | ||
641 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
642 | goto err_remove_sysfs; | ||
643 | } | ||
644 | |||
645 | return 0; | ||
646 | |||
647 | err_remove_sysfs: | ||
648 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
649 | err_thermal_unregister: | ||
650 | thermal_cooling_device_unregister(pr->cdev); | ||
651 | err_power_exit: | ||
652 | acpi_processor_power_exit(pr, device); | ||
653 | err_remove_fs: | ||
654 | acpi_processor_remove_fs(device); | ||
655 | err_free_cpumask: | ||
656 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
657 | |||
658 | return result; | ||
659 | } | ||
660 | |||
661 | static int acpi_processor_remove(struct acpi_device *device, int type) | ||
662 | { | ||
663 | struct acpi_processor *pr = NULL; | ||
664 | |||
665 | |||
666 | if (!device || !acpi_driver_data(device)) | ||
667 | return -EINVAL; | ||
668 | |||
669 | pr = acpi_driver_data(device); | ||
670 | |||
671 | if (pr->id >= nr_cpu_ids) | ||
672 | goto free; | ||
673 | |||
674 | if (type == ACPI_BUS_REMOVAL_EJECT) { | ||
675 | if (acpi_processor_handle_eject(pr)) | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
679 | acpi_processor_power_exit(pr, device); | ||
680 | |||
681 | sysfs_remove_link(&device->dev.kobj, "sysdev"); | ||
682 | |||
683 | acpi_processor_remove_fs(device); | ||
684 | |||
685 | if (pr->cdev) { | ||
686 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
687 | sysfs_remove_link(&pr->cdev->device.kobj, "device"); | ||
688 | thermal_cooling_device_unregister(pr->cdev); | ||
689 | pr->cdev = NULL; | ||
690 | } | ||
691 | |||
692 | per_cpu(processors, pr->id) = NULL; | ||
693 | per_cpu(processor_device_array, pr->id) = NULL; | ||
694 | |||
695 | free: | ||
696 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
697 | kfree(pr); | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
703 | /**************************************************************************** | ||
704 | * Acpi processor hotplug support * | ||
705 | ****************************************************************************/ | ||
706 | |||
707 | static int is_processor_present(acpi_handle handle) | ||
708 | { | ||
709 | acpi_status status; | ||
710 | unsigned long long sta = 0; | ||
711 | |||
712 | |||
713 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
714 | |||
715 | if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) | ||
716 | return 1; | ||
717 | |||
718 | /* | ||
719 | * _STA is mandatory for a processor that supports hot plug | ||
720 | */ | ||
721 | if (status == AE_NOT_FOUND) | ||
722 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
723 | "Processor does not support hot plug\n")); | ||
724 | else | ||
725 | ACPI_EXCEPTION((AE_INFO, status, | ||
726 | "Processor Device is not present")); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static | ||
731 | int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | ||
732 | { | ||
733 | acpi_handle phandle; | ||
734 | struct acpi_device *pdev; | ||
735 | |||
736 | |||
737 | if (acpi_get_parent(handle, &phandle)) { | ||
738 | return -ENODEV; | ||
739 | } | ||
740 | |||
741 | if (acpi_bus_get_device(phandle, &pdev)) { | ||
742 | return -ENODEV; | ||
743 | } | ||
744 | |||
745 | if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { | ||
746 | return -ENODEV; | ||
747 | } | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | ||
753 | u32 event, void *data) | ||
754 | { | ||
755 | struct acpi_processor *pr; | ||
756 | struct acpi_device *device = NULL; | ||
757 | int result; | ||
758 | |||
759 | |||
760 | switch (event) { | ||
761 | case ACPI_NOTIFY_BUS_CHECK: | ||
762 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
763 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
764 | "Processor driver received %s event\n", | ||
765 | (event == ACPI_NOTIFY_BUS_CHECK) ? | ||
766 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); | ||
767 | |||
768 | if (!is_processor_present(handle)) | ||
769 | break; | ||
770 | |||
771 | if (acpi_bus_get_device(handle, &device)) { | ||
772 | result = acpi_processor_device_add(handle, &device); | ||
773 | if (result) | ||
774 | printk(KERN_ERR PREFIX | ||
775 | "Unable to add the device\n"); | ||
776 | break; | ||
777 | } | ||
778 | break; | ||
779 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
780 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
781 | "received ACPI_NOTIFY_EJECT_REQUEST\n")); | ||
782 | |||
783 | if (acpi_bus_get_device(handle, &device)) { | ||
784 | printk(KERN_ERR PREFIX | ||
785 | "Device don't exist, dropping EJECT\n"); | ||
786 | break; | ||
787 | } | ||
788 | pr = acpi_driver_data(device); | ||
789 | if (!pr) { | ||
790 | printk(KERN_ERR PREFIX | ||
791 | "Driver data is NULL, dropping EJECT\n"); | ||
792 | return; | ||
793 | } | ||
794 | break; | ||
795 | default: | ||
796 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
797 | "Unsupported event [0x%x]\n", event)); | ||
798 | break; | ||
799 | } | ||
800 | |||
801 | return; | ||
802 | } | ||
803 | |||
804 | static acpi_status | ||
805 | processor_walk_namespace_cb(acpi_handle handle, | ||
806 | u32 lvl, void *context, void **rv) | ||
807 | { | ||
808 | acpi_status status; | ||
809 | int *action = context; | ||
810 | acpi_object_type type = 0; | ||
811 | |||
812 | status = acpi_get_type(handle, &type); | ||
813 | if (ACPI_FAILURE(status)) | ||
814 | return (AE_OK); | ||
815 | |||
816 | if (type != ACPI_TYPE_PROCESSOR) | ||
817 | return (AE_OK); | ||
818 | |||
819 | switch (*action) { | ||
820 | case INSTALL_NOTIFY_HANDLER: | ||
821 | acpi_install_notify_handler(handle, | ||
822 | ACPI_SYSTEM_NOTIFY, | ||
823 | acpi_processor_hotplug_notify, | ||
824 | NULL); | ||
825 | break; | ||
826 | case UNINSTALL_NOTIFY_HANDLER: | ||
827 | acpi_remove_notify_handler(handle, | ||
828 | ACPI_SYSTEM_NOTIFY, | ||
829 | acpi_processor_hotplug_notify); | ||
830 | break; | ||
831 | default: | ||
832 | break; | ||
833 | } | ||
834 | |||
835 | return (AE_OK); | ||
836 | } | ||
837 | |||
838 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) | ||
839 | { | ||
840 | |||
841 | if (!is_processor_present(handle)) { | ||
842 | return AE_ERROR; | ||
843 | } | ||
844 | |||
845 | if (acpi_map_lsapic(handle, p_cpu)) | ||
846 | return AE_ERROR; | ||
847 | |||
848 | if (arch_register_cpu(*p_cpu)) { | ||
849 | acpi_unmap_lsapic(*p_cpu); | ||
850 | return AE_ERROR; | ||
851 | } | ||
852 | |||
853 | return AE_OK; | ||
854 | } | ||
855 | |||
856 | static int acpi_processor_handle_eject(struct acpi_processor *pr) | ||
857 | { | ||
858 | if (cpu_online(pr->id)) | ||
859 | cpu_down(pr->id); | ||
860 | |||
861 | arch_unregister_cpu(pr->id); | ||
862 | acpi_unmap_lsapic(pr->id); | ||
863 | return (0); | ||
864 | } | ||
865 | #else | ||
866 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) | ||
867 | { | ||
868 | return AE_ERROR; | ||
869 | } | ||
870 | static int acpi_processor_handle_eject(struct acpi_processor *pr) | ||
871 | { | ||
872 | return (-EINVAL); | ||
873 | } | ||
874 | #endif | ||
875 | |||
876 | static | ||
877 | void acpi_processor_install_hotplug_notify(void) | ||
878 | { | ||
879 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
880 | int action = INSTALL_NOTIFY_HANDLER; | ||
881 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | ||
882 | ACPI_ROOT_OBJECT, | ||
883 | ACPI_UINT32_MAX, | ||
884 | processor_walk_namespace_cb, NULL, &action, NULL); | ||
885 | #endif | ||
886 | register_hotcpu_notifier(&acpi_cpu_notifier); | ||
887 | } | ||
888 | |||
889 | static | ||
890 | void acpi_processor_uninstall_hotplug_notify(void) | ||
891 | { | ||
892 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
893 | int action = UNINSTALL_NOTIFY_HANDLER; | ||
894 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, | ||
895 | ACPI_ROOT_OBJECT, | ||
896 | ACPI_UINT32_MAX, | ||
897 | processor_walk_namespace_cb, NULL, &action, NULL); | ||
898 | #endif | ||
899 | unregister_hotcpu_notifier(&acpi_cpu_notifier); | ||
900 | } | ||
901 | |||
902 | /* | ||
903 | * We keep the driver loaded even when ACPI is not running. | ||
904 | * This is needed for the powernow-k8 driver, that works even without | ||
905 | * ACPI, but needs symbols from this driver | ||
906 | */ | ||
907 | |||
908 | static int __init acpi_processor_init(void) | ||
909 | { | ||
910 | int result = 0; | ||
911 | |||
912 | if (acpi_disabled) | ||
913 | return 0; | ||
914 | |||
915 | memset(&errata, 0, sizeof(errata)); | ||
916 | |||
917 | #ifdef CONFIG_ACPI_PROCFS | ||
918 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
919 | if (!acpi_processor_dir) | ||
920 | return -ENOMEM; | ||
921 | #endif | ||
922 | result = cpuidle_register_driver(&acpi_idle_driver); | ||
923 | if (result < 0) | ||
924 | goto out_proc; | ||
925 | |||
926 | result = acpi_bus_register_driver(&acpi_processor_driver); | ||
927 | if (result < 0) | ||
928 | goto out_cpuidle; | ||
929 | |||
930 | acpi_processor_install_hotplug_notify(); | ||
931 | |||
932 | acpi_thermal_cpufreq_init(); | ||
933 | |||
934 | acpi_processor_ppc_init(); | ||
935 | |||
936 | acpi_processor_throttling_init(); | ||
937 | |||
938 | return 0; | ||
939 | |||
940 | out_cpuidle: | ||
941 | cpuidle_unregister_driver(&acpi_idle_driver); | ||
942 | |||
943 | out_proc: | ||
944 | #ifdef CONFIG_ACPI_PROCFS | ||
945 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
946 | #endif | ||
947 | |||
948 | return result; | ||
949 | } | ||
950 | |||
951 | static void __exit acpi_processor_exit(void) | ||
952 | { | ||
953 | if (acpi_disabled) | ||
954 | return; | ||
955 | |||
956 | acpi_processor_ppc_exit(); | ||
957 | |||
958 | acpi_thermal_cpufreq_exit(); | ||
959 | |||
960 | acpi_processor_uninstall_hotplug_notify(); | ||
961 | |||
962 | acpi_bus_unregister_driver(&acpi_processor_driver); | ||
963 | |||
964 | cpuidle_unregister_driver(&acpi_idle_driver); | ||
965 | |||
966 | #ifdef CONFIG_ACPI_PROCFS | ||
967 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | ||
968 | #endif | ||
969 | |||
970 | return; | ||
971 | } | ||
972 | |||
973 | module_init(acpi_processor_init); | ||
974 | module_exit(acpi_processor_exit); | ||
975 | |||
976 | EXPORT_SYMBOL(acpi_processor_set_thermal_limit); | ||
977 | |||
978 | MODULE_ALIAS("processor"); | ||
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c deleted file mode 100644 index e306ba9aa34e..000000000000 --- a/drivers/acpi/processor_pdc.c +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Intel Corporation | ||
3 | * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. | ||
4 | * | ||
5 | * Alex Chiang <achiang@hp.com> | ||
6 | * - Unified x86/ia64 implementations | ||
7 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
8 | * - Added _PDC for platforms with Intel CPUs | ||
9 | */ | ||
10 | #include <linux/dmi.h> | ||
11 | |||
12 | #include <acpi/acpi_drivers.h> | ||
13 | #include <acpi/processor.h> | ||
14 | |||
15 | #include "internal.h" | ||
16 | |||
17 | #define PREFIX "ACPI: " | ||
18 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | ||
19 | ACPI_MODULE_NAME("processor_pdc"); | ||
20 | |||
21 | static int set_no_mwait(const struct dmi_system_id *id) | ||
22 | { | ||
23 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
24 | "disabling mwait for CPU C-states\n", id->ident); | ||
25 | idle_nomwait = 1; | ||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | ||
30 | { | ||
31 | set_no_mwait, "IFL91 board", { | ||
32 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
33 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
34 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
35 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
36 | { | ||
37 | set_no_mwait, "Extensa 5220", { | ||
38 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
39 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
40 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
41 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, | ||
42 | {}, | ||
43 | }; | ||
44 | |||
45 | static void acpi_set_pdc_bits(u32 *buf) | ||
46 | { | ||
47 | buf[0] = ACPI_PDC_REVISION_ID; | ||
48 | buf[1] = 1; | ||
49 | |||
50 | /* Enable coordination with firmware's _TSD info */ | ||
51 | buf[2] = ACPI_PDC_SMP_T_SWCOORD; | ||
52 | |||
53 | /* Twiddle arch-specific bits needed for _PDC */ | ||
54 | arch_acpi_set_pdc_bits(buf); | ||
55 | } | ||
56 | |||
57 | static struct acpi_object_list *acpi_processor_alloc_pdc(void) | ||
58 | { | ||
59 | struct acpi_object_list *obj_list; | ||
60 | union acpi_object *obj; | ||
61 | u32 *buf; | ||
62 | |||
63 | /* allocate and initialize pdc. It will be used later. */ | ||
64 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); | ||
65 | if (!obj_list) { | ||
66 | printk(KERN_ERR "Memory allocation error\n"); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); | ||
71 | if (!obj) { | ||
72 | printk(KERN_ERR "Memory allocation error\n"); | ||
73 | kfree(obj_list); | ||
74 | return NULL; | ||
75 | } | ||
76 | |||
77 | buf = kmalloc(12, GFP_KERNEL); | ||
78 | if (!buf) { | ||
79 | printk(KERN_ERR "Memory allocation error\n"); | ||
80 | kfree(obj); | ||
81 | kfree(obj_list); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | acpi_set_pdc_bits(buf); | ||
86 | |||
87 | obj->type = ACPI_TYPE_BUFFER; | ||
88 | obj->buffer.length = 12; | ||
89 | obj->buffer.pointer = (u8 *) buf; | ||
90 | obj_list->count = 1; | ||
91 | obj_list->pointer = obj; | ||
92 | |||
93 | return obj_list; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * _PDC is required for a BIOS-OS handshake for most of the newer | ||
98 | * ACPI processor features. | ||
99 | */ | ||
100 | static int | ||
101 | acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | ||
102 | { | ||
103 | acpi_status status = AE_OK; | ||
104 | |||
105 | if (idle_nomwait) { | ||
106 | /* | ||
107 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | ||
108 | * mode will be disabled in the parameter of _PDC object. | ||
109 | * Of course C1_FFH access mode will also be disabled. | ||
110 | */ | ||
111 | union acpi_object *obj; | ||
112 | u32 *buffer = NULL; | ||
113 | |||
114 | obj = pdc_in->pointer; | ||
115 | buffer = (u32 *)(obj->buffer.pointer); | ||
116 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | ||
117 | |||
118 | } | ||
119 | status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); | ||
120 | |||
121 | if (ACPI_FAILURE(status)) | ||
122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
123 | "Could not evaluate _PDC, using legacy perf. control.\n")); | ||
124 | |||
125 | return status; | ||
126 | } | ||
127 | |||
128 | static int early_pdc_done; | ||
129 | |||
130 | void acpi_processor_set_pdc(acpi_handle handle) | ||
131 | { | ||
132 | struct acpi_object_list *obj_list; | ||
133 | |||
134 | if (arch_has_acpi_pdc() == false) | ||
135 | return; | ||
136 | |||
137 | if (early_pdc_done) | ||
138 | return; | ||
139 | |||
140 | obj_list = acpi_processor_alloc_pdc(); | ||
141 | if (!obj_list) | ||
142 | return; | ||
143 | |||
144 | acpi_processor_eval_pdc(handle, obj_list); | ||
145 | |||
146 | kfree(obj_list->pointer->buffer.pointer); | ||
147 | kfree(obj_list->pointer); | ||
148 | kfree(obj_list); | ||
149 | } | ||
150 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | ||
151 | |||
152 | static int early_pdc_optin; | ||
153 | static int set_early_pdc_optin(const struct dmi_system_id *id) | ||
154 | { | ||
155 | early_pdc_optin = 1; | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int param_early_pdc_optin(char *s) | ||
160 | { | ||
161 | early_pdc_optin = 1; | ||
162 | return 1; | ||
163 | } | ||
164 | __setup("acpi_early_pdc_eval", param_early_pdc_optin); | ||
165 | |||
166 | static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { | ||
167 | { | ||
168 | set_early_pdc_optin, "HP Envy", { | ||
169 | DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), | ||
170 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL}, | ||
171 | { | ||
172 | set_early_pdc_optin, "HP Pavilion dv6", { | ||
173 | DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), | ||
174 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL}, | ||
175 | { | ||
176 | set_early_pdc_optin, "HP Pavilion dv7", { | ||
177 | DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), | ||
178 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL}, | ||
179 | {}, | ||
180 | }; | ||
181 | |||
182 | static acpi_status | ||
183 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
184 | { | ||
185 | acpi_processor_set_pdc(handle); | ||
186 | return AE_OK; | ||
187 | } | ||
188 | |||
189 | void __init acpi_early_processor_set_pdc(void) | ||
190 | { | ||
191 | /* | ||
192 | * Check whether the system is DMI table. If yes, OSPM | ||
193 | * should not use mwait for CPU-states. | ||
194 | */ | ||
195 | dmi_check_system(processor_idle_dmi_table); | ||
196 | |||
197 | /* | ||
198 | * Allow systems to opt-in to early _PDC evaluation. | ||
199 | */ | ||
200 | dmi_check_system(early_pdc_optin_table); | ||
201 | if (!early_pdc_optin) | ||
202 | return; | ||
203 | |||
204 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
205 | ACPI_UINT32_MAX, | ||
206 | early_init_pdc, NULL, NULL, NULL); | ||
207 | |||
208 | early_pdc_done = 1; | ||
209 | } | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 7ded7542fc9d..29c6f5766dcf 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -1133,9 +1133,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1133 | int result = 0; | 1133 | int result = 0; |
1134 | struct acpi_processor_throttling *pthrottling; | 1134 | struct acpi_processor_throttling *pthrottling; |
1135 | 1135 | ||
1136 | if (!pr) | ||
1137 | return -EINVAL; | ||
1138 | |||
1139 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1136 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
1140 | "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", | 1137 | "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", |
1141 | pr->throttling.address, | 1138 | pr->throttling.address, |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index b16ddbf23a9c..89ad11138e48 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -217,6 +217,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, | |||
217 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 217 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
218 | val->intval = acpi_battery_technology(battery); | 218 | val->intval = acpi_battery_technology(battery); |
219 | break; | 219 | break; |
220 | case POWER_SUPPLY_PROP_CYCLE_COUNT: | ||
221 | val->intval = battery->cycle_count; | ||
222 | break; | ||
220 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | 223 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
221 | val->intval = battery->design_voltage * | 224 | val->intval = battery->design_voltage * |
222 | acpi_battery_vscale(battery) * 1000; | 225 | acpi_battery_vscale(battery) * 1000; |
@@ -276,6 +279,7 @@ static enum power_supply_property sbs_charge_battery_props[] = { | |||
276 | POWER_SUPPLY_PROP_STATUS, | 279 | POWER_SUPPLY_PROP_STATUS, |
277 | POWER_SUPPLY_PROP_PRESENT, | 280 | POWER_SUPPLY_PROP_PRESENT, |
278 | POWER_SUPPLY_PROP_TECHNOLOGY, | 281 | POWER_SUPPLY_PROP_TECHNOLOGY, |
282 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
279 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 283 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
280 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 284 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
281 | POWER_SUPPLY_PROP_CURRENT_NOW, | 285 | POWER_SUPPLY_PROP_CURRENT_NOW, |
@@ -560,6 +564,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) | |||
560 | battery->design_voltage * acpi_battery_vscale(battery)); | 564 | battery->design_voltage * acpi_battery_vscale(battery)); |
561 | seq_printf(seq, "design capacity warning: unknown\n"); | 565 | seq_printf(seq, "design capacity warning: unknown\n"); |
562 | seq_printf(seq, "design capacity low: unknown\n"); | 566 | seq_printf(seq, "design capacity low: unknown\n"); |
567 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
563 | seq_printf(seq, "capacity granularity 1: unknown\n"); | 568 | seq_printf(seq, "capacity granularity 1: unknown\n"); |
564 | seq_printf(seq, "capacity granularity 2: unknown\n"); | 569 | seq_printf(seq, "capacity granularity 2: unknown\n"); |
565 | seq_printf(seq, "model number: %s\n", battery->device_name); | 570 | seq_printf(seq, "model number: %s\n", battery->device_name); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 3bde594a9979..f74834a544fd 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -552,8 +552,17 @@ static void acpi_hibernation_leave(void) | |||
552 | hibernate_nvs_restore(); | 552 | hibernate_nvs_restore(); |
553 | } | 553 | } |
554 | 554 | ||
555 | static void acpi_pm_enable_gpes(void) | 555 | static int acpi_pm_pre_restore(void) |
556 | { | 556 | { |
557 | acpi_disable_all_gpes(); | ||
558 | acpi_os_wait_events_complete(NULL); | ||
559 | acpi_ec_suspend_transactions(); | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static void acpi_pm_restore_cleanup(void) | ||
564 | { | ||
565 | acpi_ec_resume_transactions(); | ||
557 | acpi_enable_all_runtime_gpes(); | 566 | acpi_enable_all_runtime_gpes(); |
558 | } | 567 | } |
559 | 568 | ||
@@ -565,8 +574,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { | |||
565 | .prepare = acpi_pm_prepare, | 574 | .prepare = acpi_pm_prepare, |
566 | .enter = acpi_hibernation_enter, | 575 | .enter = acpi_hibernation_enter, |
567 | .leave = acpi_hibernation_leave, | 576 | .leave = acpi_hibernation_leave, |
568 | .pre_restore = acpi_pm_disable_gpes, | 577 | .pre_restore = acpi_pm_pre_restore, |
569 | .restore_cleanup = acpi_pm_enable_gpes, | 578 | .restore_cleanup = acpi_pm_restore_cleanup, |
570 | }; | 579 | }; |
571 | 580 | ||
572 | /** | 581 | /** |
@@ -618,8 +627,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { | |||
618 | .prepare = acpi_pm_disable_gpes, | 627 | .prepare = acpi_pm_disable_gpes, |
619 | .enter = acpi_hibernation_enter, | 628 | .enter = acpi_hibernation_enter, |
620 | .leave = acpi_hibernation_leave, | 629 | .leave = acpi_hibernation_leave, |
621 | .pre_restore = acpi_pm_disable_gpes, | 630 | .pre_restore = acpi_pm_pre_restore, |
622 | .restore_cleanup = acpi_pm_enable_gpes, | 631 | .restore_cleanup = acpi_pm_restore_cleanup, |
623 | .recover = acpi_pm_finish, | 632 | .recover = acpi_pm_finish, |
624 | }; | 633 | }; |
625 | #endif /* CONFIG_HIBERNATION */ | 634 | #endif /* CONFIG_HIBERNATION */ |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index a206a12da78a..743f2445e2a1 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -101,6 +101,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
101 | struct acpi_table_header *header = NULL; | 101 | struct acpi_table_header *header = NULL; |
102 | struct acpi_table_attr *attr = NULL; | 102 | struct acpi_table_attr *attr = NULL; |
103 | 103 | ||
104 | sysfs_attr_init(&table_attr->attr.attr); | ||
104 | if (table_header->signature[0] != '\0') | 105 | if (table_header->signature[0] != '\0') |
105 | memcpy(table_attr->name, table_header->signature, | 106 | memcpy(table_attr->name, table_header->signature, |
106 | ACPI_NAME_SIZE); | 107 | ACPI_NAME_SIZE); |
@@ -475,6 +476,7 @@ void acpi_irq_stats_init(void) | |||
475 | goto fail; | 476 | goto fail; |
476 | strncpy(name, buffer, strlen(buffer) + 1); | 477 | strncpy(name, buffer, strlen(buffer) + 1); |
477 | 478 | ||
479 | sysfs_attr_init(&counter_attrs[i].attr); | ||
478 | counter_attrs[i].attr.name = name; | 480 | counter_attrs[i].attr.name = name; |
479 | counter_attrs[i].attr.mode = 0644; | 481 | counter_attrs[i].attr.mode = 0644; |
480 | counter_attrs[i].show = counter_show; | 482 | counter_attrs[i].show = counter_show; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9073ada88835..5d3893558cf7 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -368,7 +368,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
368 | int valid = 0; | 368 | int valid = 0; |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | /* Critical Shutdown (required) */ | 371 | /* Critical Shutdown */ |
372 | if (flag & ACPI_TRIPS_CRITICAL) { | 372 | if (flag & ACPI_TRIPS_CRITICAL) { |
373 | status = acpi_evaluate_integer(tz->device->handle, | 373 | status = acpi_evaluate_integer(tz->device->handle, |
374 | "_CRT", NULL, &tmp); | 374 | "_CRT", NULL, &tmp); |
@@ -379,17 +379,19 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
379 | * Below zero (Celsius) values clearly aren't right for sure.. | 379 | * Below zero (Celsius) values clearly aren't right for sure.. |
380 | * ... so lets discard those as invalid. | 380 | * ... so lets discard those as invalid. |
381 | */ | 381 | */ |
382 | if (ACPI_FAILURE(status) || | 382 | if (ACPI_FAILURE(status)) { |
383 | tz->trips.critical.temperature <= 2732) { | 383 | tz->trips.critical.flags.valid = 0; |
384 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
385 | "No critical threshold\n")); | ||
386 | } else if (tmp <= 2732) { | ||
387 | printk(KERN_WARNING FW_BUG "Invalid critical threshold " | ||
388 | "(%llu)\n", tmp); | ||
384 | tz->trips.critical.flags.valid = 0; | 389 | tz->trips.critical.flags.valid = 0; |
385 | ACPI_EXCEPTION((AE_INFO, status, | ||
386 | "No or invalid critical threshold")); | ||
387 | return -ENODEV; | ||
388 | } else { | 390 | } else { |
389 | tz->trips.critical.flags.valid = 1; | 391 | tz->trips.critical.flags.valid = 1; |
390 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 392 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
391 | "Found critical threshold [%lu]\n", | 393 | "Found critical threshold [%lu]\n", |
392 | tz->trips.critical.temperature)); | 394 | tz->trips.critical.temperature)); |
393 | } | 395 | } |
394 | if (tz->trips.critical.flags.valid == 1) { | 396 | if (tz->trips.critical.flags.valid == 1) { |
395 | if (crt == -1) { | 397 | if (crt == -1) { |
@@ -575,7 +577,23 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
575 | 577 | ||
576 | static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | 578 | static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) |
577 | { | 579 | { |
578 | return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); | 580 | int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); |
581 | |||
582 | if (ret) | ||
583 | return ret; | ||
584 | |||
585 | valid = tz->trips.critical.flags.valid | | ||
586 | tz->trips.hot.flags.valid | | ||
587 | tz->trips.passive.flags.valid; | ||
588 | |||
589 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) | ||
590 | valid |= tz->trips.active[i].flags.valid; | ||
591 | |||
592 | if (!valid) { | ||
593 | printk(KERN_WARNING FW_BUG "No valid trip found\n"); | ||
594 | return -ENODEV; | ||
595 | } | ||
596 | return 0; | ||
579 | } | 597 | } |
580 | 598 | ||
581 | static void acpi_thermal_check(void *data) | 599 | static void acpi_thermal_check(void *data) |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 11882dbe2094..c9a49f4747e6 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -289,51 +289,6 @@ acpi_evaluate_integer(acpi_handle handle, | |||
289 | 289 | ||
290 | EXPORT_SYMBOL(acpi_evaluate_integer); | 290 | EXPORT_SYMBOL(acpi_evaluate_integer); |
291 | 291 | ||
292 | #if 0 | ||
293 | acpi_status | ||
294 | acpi_evaluate_string(acpi_handle handle, | ||
295 | acpi_string pathname, | ||
296 | acpi_object_list * arguments, acpi_string * data) | ||
297 | { | ||
298 | acpi_status status = AE_OK; | ||
299 | acpi_object *element = NULL; | ||
300 | acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
301 | |||
302 | |||
303 | if (!data) | ||
304 | return AE_BAD_PARAMETER; | ||
305 | |||
306 | status = acpi_evaluate_object(handle, pathname, arguments, &buffer); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | acpi_util_eval_error(handle, pathname, status); | ||
309 | return status; | ||
310 | } | ||
311 | |||
312 | element = (acpi_object *) buffer.pointer; | ||
313 | |||
314 | if ((element->type != ACPI_TYPE_STRING) | ||
315 | || (element->type != ACPI_TYPE_BUFFER) | ||
316 | || !element->string.length) { | ||
317 | acpi_util_eval_error(handle, pathname, AE_BAD_DATA); | ||
318 | return AE_BAD_DATA; | ||
319 | } | ||
320 | |||
321 | *data = kzalloc(element->string.length + 1, GFP_KERNEL); | ||
322 | if (!data) { | ||
323 | printk(KERN_ERR PREFIX "Memory allocation\n"); | ||
324 | return -ENOMEM; | ||
325 | } | ||
326 | |||
327 | memcpy(*data, element->string.pointer, element->string.length); | ||
328 | |||
329 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); | ||
330 | |||
331 | kfree(buffer.pointer); | ||
332 | |||
333 | return AE_OK; | ||
334 | } | ||
335 | #endif | ||
336 | |||
337 | acpi_status | 292 | acpi_status |
338 | acpi_evaluate_reference(acpi_handle handle, | 293 | acpi_evaluate_reference(acpi_handle handle, |
339 | acpi_string pathname, | 294 | acpi_string pathname, |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 6e9b49149fce..2ff2b6ab5b6c 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -327,7 +327,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, | |||
327 | int level); | 327 | int level); |
328 | static int acpi_video_device_lcd_get_level_current( | 328 | static int acpi_video_device_lcd_get_level_current( |
329 | struct acpi_video_device *device, | 329 | struct acpi_video_device *device, |
330 | unsigned long long *level); | 330 | unsigned long long *level, int init); |
331 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 331 | static int acpi_video_get_next_level(struct acpi_video_device *device, |
332 | u32 level_current, u32 event); | 332 | u32 level_current, u32 event); |
333 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 333 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
@@ -345,7 +345,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) | |||
345 | struct acpi_video_device *vd = | 345 | struct acpi_video_device *vd = |
346 | (struct acpi_video_device *)bl_get_data(bd); | 346 | (struct acpi_video_device *)bl_get_data(bd); |
347 | 347 | ||
348 | if (acpi_video_device_lcd_get_level_current(vd, &cur_level)) | 348 | if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0)) |
349 | return -EINVAL; | 349 | return -EINVAL; |
350 | for (i = 2; i < vd->brightness->count; i++) { | 350 | for (i = 2; i < vd->brightness->count; i++) { |
351 | if (vd->brightness->levels[i] == cur_level) | 351 | if (vd->brightness->levels[i] == cur_level) |
@@ -414,7 +414,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig | |||
414 | unsigned long long level; | 414 | unsigned long long level; |
415 | int offset; | 415 | int offset; |
416 | 416 | ||
417 | if (acpi_video_device_lcd_get_level_current(video, &level)) | 417 | if (acpi_video_device_lcd_get_level_current(video, &level, 0)) |
418 | return -EINVAL; | 418 | return -EINVAL; |
419 | for (offset = 2; offset < video->brightness->count; offset++) | 419 | for (offset = 2; offset < video->brightness->count; offset++) |
420 | if (level == video->brightness->levels[offset]) { | 420 | if (level == video->brightness->levels[offset]) { |
@@ -609,7 +609,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
609 | 609 | ||
610 | static int | 610 | static int |
611 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | 611 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, |
612 | unsigned long long *level) | 612 | unsigned long long *level, int init) |
613 | { | 613 | { |
614 | acpi_status status = AE_OK; | 614 | acpi_status status = AE_OK; |
615 | int i; | 615 | int i; |
@@ -633,10 +633,16 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
633 | device->brightness->curr = *level; | 633 | device->brightness->curr = *level; |
634 | return 0; | 634 | return 0; |
635 | } | 635 | } |
636 | /* BQC returned an invalid level. Stop using it. */ | 636 | if (!init) { |
637 | ACPI_WARNING((AE_INFO, "%s returned an invalid level", | 637 | /* |
638 | buf)); | 638 | * BQC returned an invalid level. |
639 | device->cap._BQC = device->cap._BCQ = 0; | 639 | * Stop using it. |
640 | */ | ||
641 | ACPI_WARNING((AE_INFO, | ||
642 | "%s returned an invalid level", | ||
643 | buf)); | ||
644 | device->cap._BQC = device->cap._BCQ = 0; | ||
645 | } | ||
640 | } else { | 646 | } else { |
641 | /* Fixme: | 647 | /* Fixme: |
642 | * should we return an error or ignore this failure? | 648 | * should we return an error or ignore this failure? |
@@ -892,7 +898,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
892 | if (!device->cap._BQC) | 898 | if (!device->cap._BQC) |
893 | goto set_level; | 899 | goto set_level; |
894 | 900 | ||
895 | result = acpi_video_device_lcd_get_level_current(device, &level_old); | 901 | result = acpi_video_device_lcd_get_level_current(device, &level_old, 1); |
896 | if (result) | 902 | if (result) |
897 | goto out_free_levels; | 903 | goto out_free_levels; |
898 | 904 | ||
@@ -903,7 +909,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
903 | if (result) | 909 | if (result) |
904 | goto out_free_levels; | 910 | goto out_free_levels; |
905 | 911 | ||
906 | result = acpi_video_device_lcd_get_level_current(device, &level); | 912 | result = acpi_video_device_lcd_get_level_current(device, &level, 0); |
907 | if (result) | 913 | if (result) |
908 | goto out_free_levels; | 914 | goto out_free_levels; |
909 | 915 | ||
@@ -1996,7 +2002,7 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) | |||
1996 | goto out; | 2002 | goto out; |
1997 | 2003 | ||
1998 | result = acpi_video_device_lcd_get_level_current(device, | 2004 | result = acpi_video_device_lcd_get_level_current(device, |
1999 | &level_current); | 2005 | &level_current, 0); |
2000 | if (result) | 2006 | if (result) |
2001 | goto out; | 2007 | goto out; |
2002 | 2008 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9c77b0d1a9d0..4a28420efff2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -2232,7 +2232,7 @@ retry: | |||
2232 | * Some drives were very specific about that exact sequence. | 2232 | * Some drives were very specific about that exact sequence. |
2233 | * | 2233 | * |
2234 | * Note that ATA4 says lba is mandatory so the second check | 2234 | * Note that ATA4 says lba is mandatory so the second check |
2235 | * shoud never trigger. | 2235 | * should never trigger. |
2236 | */ | 2236 | */ |
2237 | if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { | 2237 | if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { |
2238 | err_mask = ata_dev_init_params(dev, id[3], id[6]); | 2238 | err_mask = ata_dev_init_params(dev, id[3], id[6]); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 02441fd57e9e..561dec2481cb 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2287,7 +2287,7 @@ EXPORT_SYMBOL_GPL(ata_sff_postreset); | |||
2287 | * @qc: command | 2287 | * @qc: command |
2288 | * | 2288 | * |
2289 | * Drain the FIFO and device of any stuck data following a command | 2289 | * Drain the FIFO and device of any stuck data following a command |
2290 | * failing to complete. In some cases this is neccessary before a | 2290 | * failing to complete. In some cases this is necessary before a |
2291 | * reset will recover the device. | 2291 | * reset will recover the device. |
2292 | * | 2292 | * |
2293 | */ | 2293 | */ |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 294f3020a78a..8e5e13210426 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -161,7 +161,7 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
161 | * | 161 | * |
162 | * Called when the libata layer is about to issue a command. We wrap | 162 | * Called when the libata layer is about to issue a command. We wrap |
163 | * this interface so that we can load the correct ATA timings if | 163 | * this interface so that we can load the correct ATA timings if |
164 | * neccessary. | 164 | * necessary. |
165 | */ | 165 | */ |
166 | 166 | ||
167 | static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc) | 167 | static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc) |
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index c86c71639a95..727a81ce4c9f 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c | |||
@@ -180,7 +180,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev) | |||
180 | * @id: Entry in match table | 180 | * @id: Entry in match table |
181 | * | 181 | * |
182 | * Perform basic initialisation. We set the device up so we access all | 182 | * Perform basic initialisation. We set the device up so we access all |
183 | * ports via BAR4. This is neccessary to work around errata. | 183 | * ports via BAR4. This is necessary to work around errata. |
184 | */ | 184 | */ |
185 | 185 | ||
186 | static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 186 | static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 36103531feeb..147de2fd66d2 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -131,7 +131,7 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev, | |||
131 | * @qc: command | 131 | * @qc: command |
132 | * | 132 | * |
133 | * Drain the FIFO and device of any stuck data following a command | 133 | * Drain the FIFO and device of any stuck data following a command |
134 | * failing to complete. In some cases this is neccessary before a | 134 | * failing to complete. In some cases this is necessary before a |
135 | * reset will recover the device. | 135 | * reset will recover the device. |
136 | * | 136 | * |
137 | */ | 137 | */ |
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index fe3a865be4e5..b0ca5a47f47d 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c | |||
@@ -81,7 +81,7 @@ static struct fb_ops cfag12864bfb_ops = { | |||
81 | .fb_mmap = cfag12864bfb_mmap, | 81 | .fb_mmap = cfag12864bfb_mmap, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static int __init cfag12864bfb_probe(struct platform_device *device) | 84 | static int __devinit cfag12864bfb_probe(struct platform_device *device) |
85 | { | 85 | { |
86 | int ret = -EINVAL; | 86 | int ret = -EINVAL; |
87 | struct fb_info *info = framebuffer_alloc(0, &device->dev); | 87 | struct fb_info *info = framebuffer_alloc(0, &device->dev); |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index ee377270beb9..fd52c48ee762 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -3,35 +3,50 @@ menu "Generic Driver Options" | |||
3 | config UEVENT_HELPER_PATH | 3 | config UEVENT_HELPER_PATH |
4 | string "path to uevent helper" | 4 | string "path to uevent helper" |
5 | depends on HOTPLUG | 5 | depends on HOTPLUG |
6 | default "/sbin/hotplug" | 6 | default "" |
7 | help | 7 | help |
8 | Path to uevent helper program forked by the kernel for | 8 | Path to uevent helper program forked by the kernel for |
9 | every uevent. | 9 | every uevent. |
10 | Before the switch to the netlink-based uevent source, this was | ||
11 | used to hook hotplug scripts into kernel device events. It | ||
12 | usually pointed to a shell script at /sbin/hotplug. | ||
13 | This should not be used today, because usual systems create | ||
14 | many events at bootup or device discovery in a very short time | ||
15 | frame. One forked process per event can create so many processes | ||
16 | that it creates a high system load, or on smaller systems | ||
17 | it is known to create out-of-memory situations during bootup. | ||
10 | 18 | ||
11 | config DEVTMPFS | 19 | config DEVTMPFS |
12 | bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)" | 20 | bool "Maintain a devtmpfs filesystem to mount at /dev" |
13 | depends on HOTPLUG && SHMEM && TMPFS | 21 | depends on HOTPLUG && SHMEM && TMPFS |
14 | help | 22 | help |
15 | This creates a tmpfs filesystem, and mounts it at bootup | 23 | This creates a tmpfs filesystem instance early at bootup. |
16 | and mounts it at /dev. The kernel driver core creates device | 24 | In this filesystem, the kernel driver core maintains device |
17 | nodes for all registered devices in that filesystem. All device | 25 | nodes with their default names and permissions for all |
18 | nodes are owned by root and have the default mode of 0600. | 26 | registered devices with an assigned major/minor number. |
19 | Userspace can add and delete the nodes as needed. This is | 27 | Userspace can modify the filesystem content as needed, add |
20 | intended to simplify bootup, and make it possible to delay | 28 | symlinks, and apply needed permissions. |
21 | the initial coldplug at bootup done by udev in userspace. | 29 | It provides a fully functional /dev directory, where usually |
22 | It should also provide a simpler way for rescue systems | 30 | udev runs on top, managing permissions and adding meaningful |
23 | to bring up a kernel with dynamic major/minor numbers. | 31 | symlinks. |
24 | Meaningful symlinks, permissions and device ownership must | 32 | In very limited environments, it may provide a sufficient |
25 | still be handled by userspace. | 33 | functional /dev without any further help. It also allows simple |
26 | If unsure, say N here. | 34 | rescue systems, and reliably handles dynamic major/minor numbers. |
27 | 35 | ||
28 | config DEVTMPFS_MOUNT | 36 | config DEVTMPFS_MOUNT |
29 | bool "Automount devtmpfs at /dev" | 37 | bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs" |
30 | depends on DEVTMPFS | 38 | depends on DEVTMPFS |
31 | help | 39 | help |
32 | This will mount devtmpfs at /dev if the kernel mounts the root | 40 | This will instruct the kernel to automatically mount the |
33 | filesystem. It will not affect initramfs based mounting. | 41 | devtmpfs filesystem at /dev, directly after the kernel has |
34 | If unsure, say N here. | 42 | mounted the root filesystem. The behavior can be overridden |
43 | with the commandline parameter: devtmpfs.mount=0|1. | ||
44 | This option does not affect initramfs based booting, here | ||
45 | the devtmpfs filesystem always needs to be mounted manually | ||
46 | after the roots is mounted. | ||
47 | With this option enabled, it allows to bring up a system in | ||
48 | rescue mode with init=/bin/sh, even when the /dev directory | ||
49 | on the rootfs is completely empty. | ||
35 | 50 | ||
36 | config STANDALONE | 51 | config STANDALONE |
37 | bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL | 52 | bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index c0c5a43d9fb3..71f6af5c8b0b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -70,7 +70,7 @@ static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, | |||
70 | return ret; | 70 | return ret; |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct sysfs_ops driver_sysfs_ops = { | 73 | static const struct sysfs_ops driver_sysfs_ops = { |
74 | .show = drv_attr_show, | 74 | .show = drv_attr_show, |
75 | .store = drv_attr_store, | 75 | .store = drv_attr_store, |
76 | }; | 76 | }; |
@@ -115,7 +115,7 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, | |||
115 | return ret; | 115 | return ret; |
116 | } | 116 | } |
117 | 117 | ||
118 | static struct sysfs_ops bus_sysfs_ops = { | 118 | static const struct sysfs_ops bus_sysfs_ops = { |
119 | .show = bus_attr_show, | 119 | .show = bus_attr_show, |
120 | .store = bus_attr_store, | 120 | .store = bus_attr_store, |
121 | }; | 121 | }; |
@@ -154,7 +154,7 @@ static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | static struct kset_uevent_ops bus_uevent_ops = { | 157 | static const struct kset_uevent_ops bus_uevent_ops = { |
158 | .filter = bus_uevent_filter, | 158 | .filter = bus_uevent_filter, |
159 | }; | 159 | }; |
160 | 160 | ||
@@ -173,10 +173,10 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
173 | dev = bus_find_device_by_name(bus, NULL, buf); | 173 | dev = bus_find_device_by_name(bus, NULL, buf); |
174 | if (dev && dev->driver == drv) { | 174 | if (dev && dev->driver == drv) { |
175 | if (dev->parent) /* Needed for USB */ | 175 | if (dev->parent) /* Needed for USB */ |
176 | down(&dev->parent->sem); | 176 | device_lock(dev->parent); |
177 | device_release_driver(dev); | 177 | device_release_driver(dev); |
178 | if (dev->parent) | 178 | if (dev->parent) |
179 | up(&dev->parent->sem); | 179 | device_unlock(dev->parent); |
180 | err = count; | 180 | err = count; |
181 | } | 181 | } |
182 | put_device(dev); | 182 | put_device(dev); |
@@ -200,12 +200,12 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
200 | dev = bus_find_device_by_name(bus, NULL, buf); | 200 | dev = bus_find_device_by_name(bus, NULL, buf); |
201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { | 201 | if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { |
202 | if (dev->parent) /* Needed for USB */ | 202 | if (dev->parent) /* Needed for USB */ |
203 | down(&dev->parent->sem); | 203 | device_lock(dev->parent); |
204 | down(&dev->sem); | 204 | device_lock(dev); |
205 | err = driver_probe_device(drv, dev); | 205 | err = driver_probe_device(drv, dev); |
206 | up(&dev->sem); | 206 | device_unlock(dev); |
207 | if (dev->parent) | 207 | if (dev->parent) |
208 | up(&dev->parent->sem); | 208 | device_unlock(dev->parent); |
209 | 209 | ||
210 | if (err > 0) { | 210 | if (err > 0) { |
211 | /* success */ | 211 | /* success */ |
@@ -744,10 +744,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
744 | 744 | ||
745 | if (!dev->driver) { | 745 | if (!dev->driver) { |
746 | if (dev->parent) /* Needed for USB */ | 746 | if (dev->parent) /* Needed for USB */ |
747 | down(&dev->parent->sem); | 747 | device_lock(dev->parent); |
748 | ret = device_attach(dev); | 748 | ret = device_attach(dev); |
749 | if (dev->parent) | 749 | if (dev->parent) |
750 | up(&dev->parent->sem); | 750 | device_unlock(dev->parent); |
751 | } | 751 | } |
752 | return ret < 0 ? ret : 0; | 752 | return ret < 0 ? ret : 0; |
753 | } | 753 | } |
@@ -779,10 +779,10 @@ int device_reprobe(struct device *dev) | |||
779 | { | 779 | { |
780 | if (dev->driver) { | 780 | if (dev->driver) { |
781 | if (dev->parent) /* Needed for USB */ | 781 | if (dev->parent) /* Needed for USB */ |
782 | down(&dev->parent->sem); | 782 | device_lock(dev->parent); |
783 | device_release_driver(dev); | 783 | device_release_driver(dev); |
784 | if (dev->parent) | 784 | if (dev->parent) |
785 | up(&dev->parent->sem); | 785 | device_unlock(dev->parent); |
786 | } | 786 | } |
787 | return bus_rescan_devices_helper(dev, NULL); | 787 | return bus_rescan_devices_helper(dev, NULL); |
788 | } | 788 | } |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 6e2c3b064f53..0147f476b8a9 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, | |||
31 | ssize_t ret = -EIO; | 31 | ssize_t ret = -EIO; |
32 | 32 | ||
33 | if (class_attr->show) | 33 | if (class_attr->show) |
34 | ret = class_attr->show(cp->class, buf); | 34 | ret = class_attr->show(cp->class, class_attr, buf); |
35 | return ret; | 35 | return ret; |
36 | } | 36 | } |
37 | 37 | ||
@@ -43,7 +43,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, | |||
43 | ssize_t ret = -EIO; | 43 | ssize_t ret = -EIO; |
44 | 44 | ||
45 | if (class_attr->store) | 45 | if (class_attr->store) |
46 | ret = class_attr->store(cp->class, buf, count); | 46 | ret = class_attr->store(cp->class, class_attr, buf, count); |
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
@@ -63,7 +63,7 @@ static void class_release(struct kobject *kobj) | |||
63 | kfree(cp); | 63 | kfree(cp); |
64 | } | 64 | } |
65 | 65 | ||
66 | static struct sysfs_ops class_sysfs_ops = { | 66 | static const struct sysfs_ops class_sysfs_ops = { |
67 | .show = class_attr_show, | 67 | .show = class_attr_show, |
68 | .store = class_attr_store, | 68 | .store = class_attr_store, |
69 | }; | 69 | }; |
@@ -490,6 +490,16 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
490 | class_put(parent); | 490 | class_put(parent); |
491 | } | 491 | } |
492 | 492 | ||
493 | ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, | ||
494 | char *buf) | ||
495 | { | ||
496 | struct class_attribute_string *cs; | ||
497 | cs = container_of(attr, struct class_attribute_string, attr); | ||
498 | return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); | ||
499 | } | ||
500 | |||
501 | EXPORT_SYMBOL_GPL(show_class_attr_string); | ||
502 | |||
493 | struct class_compat { | 503 | struct class_compat { |
494 | struct kobject *kobj; | 504 | struct kobject *kobj; |
495 | }; | 505 | }; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 282025770429..ef55df34ddd0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -100,7 +100,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
102 | 102 | ||
103 | static struct sysfs_ops dev_sysfs_ops = { | 103 | static const struct sysfs_ops dev_sysfs_ops = { |
104 | .show = dev_attr_show, | 104 | .show = dev_attr_show, |
105 | .store = dev_attr_store, | 105 | .store = dev_attr_store, |
106 | }; | 106 | }; |
@@ -252,7 +252,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
252 | return retval; | 252 | return retval; |
253 | } | 253 | } |
254 | 254 | ||
255 | static struct kset_uevent_ops device_uevent_ops = { | 255 | static const struct kset_uevent_ops device_uevent_ops = { |
256 | .filter = dev_uevent_filter, | 256 | .filter = dev_uevent_filter, |
257 | .name = dev_uevent_name, | 257 | .name = dev_uevent_name, |
258 | .uevent = dev_uevent, | 258 | .uevent = dev_uevent, |
@@ -306,15 +306,10 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
306 | { | 306 | { |
307 | enum kobject_action action; | 307 | enum kobject_action action; |
308 | 308 | ||
309 | if (kobject_action_type(buf, count, &action) == 0) { | 309 | if (kobject_action_type(buf, count, &action) == 0) |
310 | kobject_uevent(&dev->kobj, action); | 310 | kobject_uevent(&dev->kobj, action); |
311 | goto out; | 311 | else |
312 | } | 312 | dev_err(dev, "uevent: unknown action-string\n"); |
313 | |||
314 | dev_err(dev, "uevent: unsupported action-string; this will " | ||
315 | "be ignored in a future kernel version\n"); | ||
316 | kobject_uevent(&dev->kobj, KOBJ_ADD); | ||
317 | out: | ||
318 | return count; | 313 | return count; |
319 | } | 314 | } |
320 | 315 | ||
@@ -607,6 +602,7 @@ static struct kobject *get_device_parent(struct device *dev, | |||
607 | int retval; | 602 | int retval; |
608 | 603 | ||
609 | if (dev->class) { | 604 | if (dev->class) { |
605 | static DEFINE_MUTEX(gdp_mutex); | ||
610 | struct kobject *kobj = NULL; | 606 | struct kobject *kobj = NULL; |
611 | struct kobject *parent_kobj; | 607 | struct kobject *parent_kobj; |
612 | struct kobject *k; | 608 | struct kobject *k; |
@@ -623,6 +619,8 @@ static struct kobject *get_device_parent(struct device *dev, | |||
623 | else | 619 | else |
624 | parent_kobj = &parent->kobj; | 620 | parent_kobj = &parent->kobj; |
625 | 621 | ||
622 | mutex_lock(&gdp_mutex); | ||
623 | |||
626 | /* find our class-directory at the parent and reference it */ | 624 | /* find our class-directory at the parent and reference it */ |
627 | spin_lock(&dev->class->p->class_dirs.list_lock); | 625 | spin_lock(&dev->class->p->class_dirs.list_lock); |
628 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) | 626 | list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) |
@@ -631,20 +629,26 @@ static struct kobject *get_device_parent(struct device *dev, | |||
631 | break; | 629 | break; |
632 | } | 630 | } |
633 | spin_unlock(&dev->class->p->class_dirs.list_lock); | 631 | spin_unlock(&dev->class->p->class_dirs.list_lock); |
634 | if (kobj) | 632 | if (kobj) { |
633 | mutex_unlock(&gdp_mutex); | ||
635 | return kobj; | 634 | return kobj; |
635 | } | ||
636 | 636 | ||
637 | /* or create a new class-directory at the parent device */ | 637 | /* or create a new class-directory at the parent device */ |
638 | k = kobject_create(); | 638 | k = kobject_create(); |
639 | if (!k) | 639 | if (!k) { |
640 | mutex_unlock(&gdp_mutex); | ||
640 | return NULL; | 641 | return NULL; |
642 | } | ||
641 | k->kset = &dev->class->p->class_dirs; | 643 | k->kset = &dev->class->p->class_dirs; |
642 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | 644 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); |
643 | if (retval < 0) { | 645 | if (retval < 0) { |
646 | mutex_unlock(&gdp_mutex); | ||
644 | kobject_put(k); | 647 | kobject_put(k); |
645 | return NULL; | 648 | return NULL; |
646 | } | 649 | } |
647 | /* do not emit an uevent for this simple "glue" directory */ | 650 | /* do not emit an uevent for this simple "glue" directory */ |
651 | mutex_unlock(&gdp_mutex); | ||
648 | return k; | 652 | return k; |
649 | } | 653 | } |
650 | 654 | ||
@@ -1574,22 +1578,16 @@ int device_rename(struct device *dev, char *new_name) | |||
1574 | if (old_class_name) { | 1578 | if (old_class_name) { |
1575 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | 1579 | new_class_name = make_class_name(dev->class->name, &dev->kobj); |
1576 | if (new_class_name) { | 1580 | if (new_class_name) { |
1577 | error = sysfs_create_link_nowarn(&dev->parent->kobj, | 1581 | error = sysfs_rename_link(&dev->parent->kobj, |
1578 | &dev->kobj, | 1582 | &dev->kobj, |
1579 | new_class_name); | 1583 | old_class_name, |
1580 | if (error) | 1584 | new_class_name); |
1581 | goto out; | ||
1582 | sysfs_remove_link(&dev->parent->kobj, old_class_name); | ||
1583 | } | 1585 | } |
1584 | } | 1586 | } |
1585 | #else | 1587 | #else |
1586 | if (dev->class) { | 1588 | if (dev->class) { |
1587 | error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj, | 1589 | error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, |
1588 | &dev->kobj, dev_name(dev)); | 1590 | &dev->kobj, old_device_name, new_name); |
1589 | if (error) | ||
1590 | goto out; | ||
1591 | sysfs_remove_link(&dev->class->p->class_subsys.kobj, | ||
1592 | old_device_name); | ||
1593 | } | 1591 | } |
1594 | #endif | 1592 | #endif |
1595 | 1593 | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 958bd1540c30..7036e8e96ab8 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -13,8 +13,11 @@ | |||
13 | 13 | ||
14 | #include "base.h" | 14 | #include "base.h" |
15 | 15 | ||
16 | static struct sysdev_class_attribute *cpu_sysdev_class_attrs[]; | ||
17 | |||
16 | struct sysdev_class cpu_sysdev_class = { | 18 | struct sysdev_class cpu_sysdev_class = { |
17 | .name = "cpu", | 19 | .name = "cpu", |
20 | .attrs = cpu_sysdev_class_attrs, | ||
18 | }; | 21 | }; |
19 | EXPORT_SYMBOL(cpu_sysdev_class); | 22 | EXPORT_SYMBOL(cpu_sysdev_class); |
20 | 23 | ||
@@ -76,34 +79,24 @@ void unregister_cpu(struct cpu *cpu) | |||
76 | } | 79 | } |
77 | 80 | ||
78 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | 81 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE |
79 | static ssize_t cpu_probe_store(struct class *class, const char *buf, | 82 | static ssize_t cpu_probe_store(struct sys_device *dev, |
83 | struct sysdev_attribute *attr, | ||
84 | const char *buf, | ||
80 | size_t count) | 85 | size_t count) |
81 | { | 86 | { |
82 | return arch_cpu_probe(buf, count); | 87 | return arch_cpu_probe(buf, count); |
83 | } | 88 | } |
84 | 89 | ||
85 | static ssize_t cpu_release_store(struct class *class, const char *buf, | 90 | static ssize_t cpu_release_store(struct sys_device *dev, |
91 | struct sysdev_attribute *attr, | ||
92 | const char *buf, | ||
86 | size_t count) | 93 | size_t count) |
87 | { | 94 | { |
88 | return arch_cpu_release(buf, count); | 95 | return arch_cpu_release(buf, count); |
89 | } | 96 | } |
90 | 97 | ||
91 | static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); | 98 | static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); |
92 | static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store); | 99 | static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store); |
93 | |||
94 | int __init cpu_probe_release_init(void) | ||
95 | { | ||
96 | int rc; | ||
97 | |||
98 | rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, | ||
99 | &class_attr_probe.attr); | ||
100 | if (!rc) | ||
101 | rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, | ||
102 | &class_attr_release.attr); | ||
103 | |||
104 | return rc; | ||
105 | } | ||
106 | device_initcall(cpu_probe_release_init); | ||
107 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ | 100 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ |
108 | 101 | ||
109 | #else /* ... !CONFIG_HOTPLUG_CPU */ | 102 | #else /* ... !CONFIG_HOTPLUG_CPU */ |
@@ -141,31 +134,39 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | |||
141 | /* | 134 | /* |
142 | * Print cpu online, possible, present, and system maps | 135 | * Print cpu online, possible, present, and system maps |
143 | */ | 136 | */ |
144 | static ssize_t print_cpus_map(char *buf, const struct cpumask *map) | 137 | |
138 | struct cpu_attr { | ||
139 | struct sysdev_class_attribute attr; | ||
140 | const struct cpumask *const * const map; | ||
141 | }; | ||
142 | |||
143 | static ssize_t show_cpus_attr(struct sysdev_class *class, | ||
144 | struct sysdev_class_attribute *attr, | ||
145 | char *buf) | ||
145 | { | 146 | { |
146 | int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map); | 147 | struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr); |
148 | int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map)); | ||
147 | 149 | ||
148 | buf[n++] = '\n'; | 150 | buf[n++] = '\n'; |
149 | buf[n] = '\0'; | 151 | buf[n] = '\0'; |
150 | return n; | 152 | return n; |
151 | } | 153 | } |
152 | 154 | ||
153 | #define print_cpus_func(type) \ | 155 | #define _CPU_ATTR(name, map) \ |
154 | static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ | 156 | { _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map } |
155 | { \ | ||
156 | return print_cpus_map(buf, cpu_##type##_mask); \ | ||
157 | } \ | ||
158 | static struct sysdev_class_attribute attr_##type##_map = \ | ||
159 | _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) | ||
160 | 157 | ||
161 | print_cpus_func(online); | 158 | /* Keep in sync with cpu_sysdev_class_attrs */ |
162 | print_cpus_func(possible); | 159 | static struct cpu_attr cpu_attrs[] = { |
163 | print_cpus_func(present); | 160 | _CPU_ATTR(online, &cpu_online_mask), |
161 | _CPU_ATTR(possible, &cpu_possible_mask), | ||
162 | _CPU_ATTR(present, &cpu_present_mask), | ||
163 | }; | ||
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Print values for NR_CPUS and offlined cpus | 166 | * Print values for NR_CPUS and offlined cpus |
167 | */ | 167 | */ |
168 | static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf) | 168 | static ssize_t print_cpus_kernel_max(struct sysdev_class *class, |
169 | struct sysdev_class_attribute *attr, char *buf) | ||
169 | { | 170 | { |
170 | int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); | 171 | int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); |
171 | return n; | 172 | return n; |
@@ -175,7 +176,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL); | |||
175 | /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ | 176 | /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ |
176 | unsigned int total_cpus; | 177 | unsigned int total_cpus; |
177 | 178 | ||
178 | static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) | 179 | static ssize_t print_cpus_offline(struct sysdev_class *class, |
180 | struct sysdev_class_attribute *attr, char *buf) | ||
179 | { | 181 | { |
180 | int n = 0, len = PAGE_SIZE-2; | 182 | int n = 0, len = PAGE_SIZE-2; |
181 | cpumask_var_t offline; | 183 | cpumask_var_t offline; |
@@ -204,29 +206,6 @@ static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) | |||
204 | } | 206 | } |
205 | static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL); | 207 | static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL); |
206 | 208 | ||
207 | static struct sysdev_class_attribute *cpu_state_attr[] = { | ||
208 | &attr_online_map, | ||
209 | &attr_possible_map, | ||
210 | &attr_present_map, | ||
211 | &attr_kernel_max, | ||
212 | &attr_offline, | ||
213 | }; | ||
214 | |||
215 | static int cpu_states_init(void) | ||
216 | { | ||
217 | int i; | ||
218 | int err = 0; | ||
219 | |||
220 | for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) { | ||
221 | int ret; | ||
222 | ret = sysdev_class_create_file(&cpu_sysdev_class, | ||
223 | cpu_state_attr[i]); | ||
224 | if (!err) | ||
225 | err = ret; | ||
226 | } | ||
227 | return err; | ||
228 | } | ||
229 | |||
230 | /* | 209 | /* |
231 | * register_cpu - Setup a sysfs device for a CPU. | 210 | * register_cpu - Setup a sysfs device for a CPU. |
232 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in | 211 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in |
@@ -272,9 +251,6 @@ int __init cpu_dev_init(void) | |||
272 | int err; | 251 | int err; |
273 | 252 | ||
274 | err = sysdev_class_register(&cpu_sysdev_class); | 253 | err = sysdev_class_register(&cpu_sysdev_class); |
275 | if (!err) | ||
276 | err = cpu_states_init(); | ||
277 | |||
278 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | 254 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) |
279 | if (!err) | 255 | if (!err) |
280 | err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); | 256 | err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); |
@@ -282,3 +258,16 @@ int __init cpu_dev_init(void) | |||
282 | 258 | ||
283 | return err; | 259 | return err; |
284 | } | 260 | } |
261 | |||
262 | static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = { | ||
263 | #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE | ||
264 | &attr_probe, | ||
265 | &attr_release, | ||
266 | #endif | ||
267 | &cpu_attrs[0].attr, | ||
268 | &cpu_attrs[1].attr, | ||
269 | &cpu_attrs[2].attr, | ||
270 | &attr_kernel_max, | ||
271 | &attr_offline, | ||
272 | NULL | ||
273 | }; | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index ee95c76bfd3d..c89291f8a16b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev) | |||
85 | * for before calling this. (It is ok to call with no other effort | 85 | * for before calling this. (It is ok to call with no other effort |
86 | * from a driver's probe() method.) | 86 | * from a driver's probe() method.) |
87 | * | 87 | * |
88 | * This function must be called with @dev->sem held. | 88 | * This function must be called with the device lock held. |
89 | */ | 89 | */ |
90 | int device_bind_driver(struct device *dev) | 90 | int device_bind_driver(struct device *dev) |
91 | { | 91 | { |
@@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); | |||
190 | * This function returns -ENODEV if the device is not registered, | 190 | * This function returns -ENODEV if the device is not registered, |
191 | * 1 if the device is bound successfully and 0 otherwise. | 191 | * 1 if the device is bound successfully and 0 otherwise. |
192 | * | 192 | * |
193 | * This function must be called with @dev->sem held. When called for a | 193 | * This function must be called with @dev lock held. When called for a |
194 | * USB interface, @dev->parent->sem must be held as well. | 194 | * USB interface, @dev->parent lock must be held as well. |
195 | */ | 195 | */ |
196 | int driver_probe_device(struct device_driver *drv, struct device *dev) | 196 | int driver_probe_device(struct device_driver *drv, struct device *dev) |
197 | { | 197 | { |
@@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data) | |||
233 | * 0 if no matching driver was found; | 233 | * 0 if no matching driver was found; |
234 | * -ENODEV if the device is not registered. | 234 | * -ENODEV if the device is not registered. |
235 | * | 235 | * |
236 | * When called for a USB interface, @dev->parent->sem must be held. | 236 | * When called for a USB interface, @dev->parent lock must be held. |
237 | */ | 237 | */ |
238 | int device_attach(struct device *dev) | 238 | int device_attach(struct device *dev) |
239 | { | 239 | { |
240 | int ret = 0; | 240 | int ret = 0; |
241 | 241 | ||
242 | down(&dev->sem); | 242 | device_lock(dev); |
243 | if (dev->driver) { | 243 | if (dev->driver) { |
244 | ret = device_bind_driver(dev); | 244 | ret = device_bind_driver(dev); |
245 | if (ret == 0) | 245 | if (ret == 0) |
@@ -253,7 +253,7 @@ int device_attach(struct device *dev) | |||
253 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | 253 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); |
254 | pm_runtime_put_sync(dev); | 254 | pm_runtime_put_sync(dev); |
255 | } | 255 | } |
256 | up(&dev->sem); | 256 | device_unlock(dev); |
257 | return ret; | 257 | return ret; |
258 | } | 258 | } |
259 | EXPORT_SYMBOL_GPL(device_attach); | 259 | EXPORT_SYMBOL_GPL(device_attach); |
@@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data) | |||
276 | return 0; | 276 | return 0; |
277 | 277 | ||
278 | if (dev->parent) /* Needed for USB */ | 278 | if (dev->parent) /* Needed for USB */ |
279 | down(&dev->parent->sem); | 279 | device_lock(dev->parent); |
280 | down(&dev->sem); | 280 | device_lock(dev); |
281 | if (!dev->driver) | 281 | if (!dev->driver) |
282 | driver_probe_device(drv, dev); | 282 | driver_probe_device(drv, dev); |
283 | up(&dev->sem); | 283 | device_unlock(dev); |
284 | if (dev->parent) | 284 | if (dev->parent) |
285 | up(&dev->parent->sem); | 285 | device_unlock(dev->parent); |
286 | 286 | ||
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
@@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv) | |||
303 | EXPORT_SYMBOL_GPL(driver_attach); | 303 | EXPORT_SYMBOL_GPL(driver_attach); |
304 | 304 | ||
305 | /* | 305 | /* |
306 | * __device_release_driver() must be called with @dev->sem held. | 306 | * __device_release_driver() must be called with @dev lock held. |
307 | * When called for a USB interface, @dev->parent->sem must be held as well. | 307 | * When called for a USB interface, @dev->parent lock must be held as well. |
308 | */ | 308 | */ |
309 | static void __device_release_driver(struct device *dev) | 309 | static void __device_release_driver(struct device *dev) |
310 | { | 310 | { |
@@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev) | |||
343 | * @dev: device. | 343 | * @dev: device. |
344 | * | 344 | * |
345 | * Manually detach device from driver. | 345 | * Manually detach device from driver. |
346 | * When called for a USB interface, @dev->parent->sem must be held. | 346 | * When called for a USB interface, @dev->parent lock must be held. |
347 | */ | 347 | */ |
348 | void device_release_driver(struct device *dev) | 348 | void device_release_driver(struct device *dev) |
349 | { | 349 | { |
@@ -352,9 +352,9 @@ void device_release_driver(struct device *dev) | |||
352 | * within their ->remove callback for the same device, they | 352 | * within their ->remove callback for the same device, they |
353 | * will deadlock right here. | 353 | * will deadlock right here. |
354 | */ | 354 | */ |
355 | down(&dev->sem); | 355 | device_lock(dev); |
356 | __device_release_driver(dev); | 356 | __device_release_driver(dev); |
357 | up(&dev->sem); | 357 | device_unlock(dev); |
358 | } | 358 | } |
359 | EXPORT_SYMBOL_GPL(device_release_driver); | 359 | EXPORT_SYMBOL_GPL(device_release_driver); |
360 | 360 | ||
@@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv) | |||
381 | spin_unlock(&drv->p->klist_devices.k_lock); | 381 | spin_unlock(&drv->p->klist_devices.k_lock); |
382 | 382 | ||
383 | if (dev->parent) /* Needed for USB */ | 383 | if (dev->parent) /* Needed for USB */ |
384 | down(&dev->parent->sem); | 384 | device_lock(dev->parent); |
385 | down(&dev->sem); | 385 | device_lock(dev); |
386 | if (dev->driver == drv) | 386 | if (dev->driver == drv) |
387 | __device_release_driver(dev); | 387 | __device_release_driver(dev); |
388 | up(&dev->sem); | 388 | device_unlock(dev); |
389 | if (dev->parent) | 389 | if (dev->parent) |
390 | up(&dev->parent->sem); | 390 | device_unlock(dev->parent); |
391 | put_device(dev); | 391 | put_device(dev); |
392 | } | 392 | } |
393 | } | 393 | } |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 42ae452b36b0..dac478c6e460 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -301,6 +301,19 @@ int devtmpfs_delete_node(struct device *dev) | |||
301 | if (dentry->d_inode) { | 301 | if (dentry->d_inode) { |
302 | err = vfs_getattr(nd.path.mnt, dentry, &stat); | 302 | err = vfs_getattr(nd.path.mnt, dentry, &stat); |
303 | if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { | 303 | if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { |
304 | struct iattr newattrs; | ||
305 | /* | ||
306 | * before unlinking this node, reset permissions | ||
307 | * of possible references like hardlinks | ||
308 | */ | ||
309 | newattrs.ia_uid = 0; | ||
310 | newattrs.ia_gid = 0; | ||
311 | newattrs.ia_mode = stat.mode & ~0777; | ||
312 | newattrs.ia_valid = | ||
313 | ATTR_UID|ATTR_GID|ATTR_MODE; | ||
314 | mutex_lock(&dentry->d_inode->i_mutex); | ||
315 | notify_change(dentry, &newattrs); | ||
316 | mutex_unlock(&dentry->d_inode->i_mutex); | ||
304 | err = vfs_unlink(nd.path.dentry->d_inode, | 317 | err = vfs_unlink(nd.path.dentry->d_inode, |
305 | dentry); | 318 | dentry); |
306 | if (!err || err == -ENOENT) | 319 | if (!err || err == -ENOENT) |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index a95024166b66..d0dc26ad5387 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
20 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include "base.h" | ||
23 | 22 | ||
24 | #define to_dev(obj) container_of(obj, struct device, kobj) | 23 | #define to_dev(obj) container_of(obj, struct device, kobj) |
25 | 24 | ||
@@ -69,7 +68,9 @@ fw_load_abort(struct firmware_priv *fw_priv) | |||
69 | } | 68 | } |
70 | 69 | ||
71 | static ssize_t | 70 | static ssize_t |
72 | firmware_timeout_show(struct class *class, char *buf) | 71 | firmware_timeout_show(struct class *class, |
72 | struct class_attribute *attr, | ||
73 | char *buf) | ||
73 | { | 74 | { |
74 | return sprintf(buf, "%d\n", loading_timeout); | 75 | return sprintf(buf, "%d\n", loading_timeout); |
75 | } | 76 | } |
@@ -87,7 +88,9 @@ firmware_timeout_show(struct class *class, char *buf) | |||
87 | * Note: zero means 'wait forever'. | 88 | * Note: zero means 'wait forever'. |
88 | **/ | 89 | **/ |
89 | static ssize_t | 90 | static ssize_t |
90 | firmware_timeout_store(struct class *class, const char *buf, size_t count) | 91 | firmware_timeout_store(struct class *class, |
92 | struct class_attribute *attr, | ||
93 | const char *buf, size_t count) | ||
91 | { | 94 | { |
92 | loading_timeout = simple_strtol(buf, NULL, 10); | 95 | loading_timeout = simple_strtol(buf, NULL, 10); |
93 | if (loading_timeout < 0) | 96 | if (loading_timeout < 0) |
@@ -610,7 +613,7 @@ request_firmware_work_func(void *arg) | |||
610 | } | 613 | } |
611 | 614 | ||
612 | /** | 615 | /** |
613 | * request_firmware_nowait: asynchronous version of request_firmware | 616 | * request_firmware_nowait - asynchronous version of request_firmware |
614 | * @module: module requesting the firmware | 617 | * @module: module requesting the firmware |
615 | * @uevent: sends uevent to copy the firmware image if this flag | 618 | * @uevent: sends uevent to copy the firmware image if this flag |
616 | * is non-zero else the firmware copy must be done manually. | 619 | * is non-zero else the firmware copy must be done manually. |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index bd025059711f..2f8691511190 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -44,7 +44,7 @@ static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uev | |||
44 | return retval; | 44 | return retval; |
45 | } | 45 | } |
46 | 46 | ||
47 | static struct kset_uevent_ops memory_uevent_ops = { | 47 | static const struct kset_uevent_ops memory_uevent_ops = { |
48 | .name = memory_uevent_name, | 48 | .name = memory_uevent_name, |
49 | .uevent = memory_uevent, | 49 | .uevent = memory_uevent, |
50 | }; | 50 | }; |
@@ -309,17 +309,18 @@ static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); | |||
309 | * Block size attribute stuff | 309 | * Block size attribute stuff |
310 | */ | 310 | */ |
311 | static ssize_t | 311 | static ssize_t |
312 | print_block_size(struct class *class, char *buf) | 312 | print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr, |
313 | char *buf) | ||
313 | { | 314 | { |
314 | return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); | 315 | return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); |
315 | } | 316 | } |
316 | 317 | ||
317 | static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); | 318 | static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); |
318 | 319 | ||
319 | static int block_size_init(void) | 320 | static int block_size_init(void) |
320 | { | 321 | { |
321 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, | 322 | return sysfs_create_file(&memory_sysdev_class.kset.kobj, |
322 | &class_attr_block_size_bytes.attr); | 323 | &attr_block_size_bytes.attr); |
323 | } | 324 | } |
324 | 325 | ||
325 | /* | 326 | /* |
@@ -330,7 +331,8 @@ static int block_size_init(void) | |||
330 | */ | 331 | */ |
331 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 332 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
332 | static ssize_t | 333 | static ssize_t |
333 | memory_probe_store(struct class *class, const char *buf, size_t count) | 334 | memory_probe_store(struct class *class, struct class_attribute *attr, |
335 | const char *buf, size_t count) | ||
334 | { | 336 | { |
335 | u64 phys_addr; | 337 | u64 phys_addr; |
336 | int nid; | 338 | int nid; |
@@ -367,7 +369,9 @@ static inline int memory_probe_init(void) | |||
367 | 369 | ||
368 | /* Soft offline a page */ | 370 | /* Soft offline a page */ |
369 | static ssize_t | 371 | static ssize_t |
370 | store_soft_offline_page(struct class *class, const char *buf, size_t count) | 372 | store_soft_offline_page(struct class *class, |
373 | struct class_attribute *attr, | ||
374 | const char *buf, size_t count) | ||
371 | { | 375 | { |
372 | int ret; | 376 | int ret; |
373 | u64 pfn; | 377 | u64 pfn; |
@@ -384,7 +388,9 @@ store_soft_offline_page(struct class *class, const char *buf, size_t count) | |||
384 | 388 | ||
385 | /* Forcibly offline a page, including killing processes. */ | 389 | /* Forcibly offline a page, including killing processes. */ |
386 | static ssize_t | 390 | static ssize_t |
387 | store_hard_offline_page(struct class *class, const char *buf, size_t count) | 391 | store_hard_offline_page(struct class *class, |
392 | struct class_attribute *attr, | ||
393 | const char *buf, size_t count) | ||
388 | { | 394 | { |
389 | int ret; | 395 | int ret; |
390 | u64 pfn; | 396 | u64 pfn; |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 70122791683d..ad43185ec15a 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -16,8 +16,11 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | 18 | ||
19 | static struct sysdev_class_attribute *node_state_attrs[]; | ||
20 | |||
19 | static struct sysdev_class node_class = { | 21 | static struct sysdev_class node_class = { |
20 | .name = "node", | 22 | .name = "node", |
23 | .attrs = node_state_attrs, | ||
21 | }; | 24 | }; |
22 | 25 | ||
23 | 26 | ||
@@ -544,76 +547,52 @@ static ssize_t print_nodes_state(enum node_states state, char *buf) | |||
544 | return n; | 547 | return n; |
545 | } | 548 | } |
546 | 549 | ||
547 | static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf) | 550 | struct node_attr { |
548 | { | 551 | struct sysdev_class_attribute attr; |
549 | return print_nodes_state(N_POSSIBLE, buf); | 552 | enum node_states state; |
550 | } | 553 | }; |
551 | |||
552 | static ssize_t print_nodes_online(struct sysdev_class *class, char *buf) | ||
553 | { | ||
554 | return print_nodes_state(N_ONLINE, buf); | ||
555 | } | ||
556 | |||
557 | static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class, | ||
558 | char *buf) | ||
559 | { | ||
560 | return print_nodes_state(N_NORMAL_MEMORY, buf); | ||
561 | } | ||
562 | 554 | ||
563 | static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf) | 555 | static ssize_t show_node_state(struct sysdev_class *class, |
556 | struct sysdev_class_attribute *attr, char *buf) | ||
564 | { | 557 | { |
565 | return print_nodes_state(N_CPU, buf); | 558 | struct node_attr *na = container_of(attr, struct node_attr, attr); |
559 | return print_nodes_state(na->state, buf); | ||
566 | } | 560 | } |
567 | 561 | ||
568 | static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL); | 562 | #define _NODE_ATTR(name, state) \ |
569 | static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL); | 563 | { _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state } |
570 | static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory, | ||
571 | NULL); | ||
572 | static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL); | ||
573 | 564 | ||
565 | static struct node_attr node_state_attr[] = { | ||
566 | _NODE_ATTR(possible, N_POSSIBLE), | ||
567 | _NODE_ATTR(online, N_ONLINE), | ||
568 | _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY), | ||
569 | _NODE_ATTR(has_cpu, N_CPU), | ||
574 | #ifdef CONFIG_HIGHMEM | 570 | #ifdef CONFIG_HIGHMEM |
575 | static ssize_t print_nodes_has_high_memory(struct sysdev_class *class, | 571 | _NODE_ATTR(has_high_memory, N_HIGH_MEMORY), |
576 | char *buf) | ||
577 | { | ||
578 | return print_nodes_state(N_HIGH_MEMORY, buf); | ||
579 | } | ||
580 | |||
581 | static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory, | ||
582 | NULL); | ||
583 | #endif | 572 | #endif |
573 | }; | ||
584 | 574 | ||
585 | struct sysdev_class_attribute *node_state_attr[] = { | 575 | static struct sysdev_class_attribute *node_state_attrs[] = { |
586 | &attr_possible, | 576 | &node_state_attr[0].attr, |
587 | &attr_online, | 577 | &node_state_attr[1].attr, |
588 | &attr_has_normal_memory, | 578 | &node_state_attr[2].attr, |
579 | &node_state_attr[3].attr, | ||
589 | #ifdef CONFIG_HIGHMEM | 580 | #ifdef CONFIG_HIGHMEM |
590 | &attr_has_high_memory, | 581 | &node_state_attr[4].attr, |
591 | #endif | 582 | #endif |
592 | &attr_has_cpu, | 583 | NULL |
593 | }; | 584 | }; |
594 | 585 | ||
595 | static int node_states_init(void) | ||
596 | { | ||
597 | int i; | ||
598 | int err = 0; | ||
599 | |||
600 | for (i = 0; i < NR_NODE_STATES; i++) { | ||
601 | int ret; | ||
602 | ret = sysdev_class_create_file(&node_class, node_state_attr[i]); | ||
603 | if (!err) | ||
604 | err = ret; | ||
605 | } | ||
606 | return err; | ||
607 | } | ||
608 | |||
609 | #define NODE_CALLBACK_PRI 2 /* lower than SLAB */ | 586 | #define NODE_CALLBACK_PRI 2 /* lower than SLAB */ |
610 | static int __init register_node_type(void) | 587 | static int __init register_node_type(void) |
611 | { | 588 | { |
612 | int ret; | 589 | int ret; |
613 | 590 | ||
591 | BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES); | ||
592 | BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES); | ||
593 | |||
614 | ret = sysdev_class_register(&node_class); | 594 | ret = sysdev_class_register(&node_class); |
615 | if (!ret) { | 595 | if (!ret) { |
616 | ret = node_states_init(); | ||
617 | hotplug_memory_notifier(node_memory_callback, | 596 | hotplug_memory_notifier(node_memory_callback, |
618 | NODE_CALLBACK_PRI); | 597 | NODE_CALLBACK_PRI); |
619 | } | 598 | } |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 58efaf2f1259..1ba9d617d241 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -128,7 +128,7 @@ struct platform_object { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | /** | 130 | /** |
131 | * platform_device_put | 131 | * platform_device_put - destroy a platform device |
132 | * @pdev: platform device to free | 132 | * @pdev: platform device to free |
133 | * | 133 | * |
134 | * Free all memory associated with a platform device. This function must | 134 | * Free all memory associated with a platform device. This function must |
@@ -152,7 +152,7 @@ static void platform_device_release(struct device *dev) | |||
152 | } | 152 | } |
153 | 153 | ||
154 | /** | 154 | /** |
155 | * platform_device_alloc | 155 | * platform_device_alloc - create a platform device |
156 | * @name: base name of the device we're adding | 156 | * @name: base name of the device we're adding |
157 | * @id: instance id | 157 | * @id: instance id |
158 | * | 158 | * |
@@ -177,7 +177,7 @@ struct platform_device *platform_device_alloc(const char *name, int id) | |||
177 | EXPORT_SYMBOL_GPL(platform_device_alloc); | 177 | EXPORT_SYMBOL_GPL(platform_device_alloc); |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * platform_device_add_resources | 180 | * platform_device_add_resources - add resources to a platform device |
181 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 181 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
182 | * @res: set of resources that needs to be allocated for the device | 182 | * @res: set of resources that needs to be allocated for the device |
183 | * @num: number of resources | 183 | * @num: number of resources |
@@ -202,7 +202,7 @@ int platform_device_add_resources(struct platform_device *pdev, | |||
202 | EXPORT_SYMBOL_GPL(platform_device_add_resources); | 202 | EXPORT_SYMBOL_GPL(platform_device_add_resources); |
203 | 203 | ||
204 | /** | 204 | /** |
205 | * platform_device_add_data | 205 | * platform_device_add_data - add platform-specific data to a platform device |
206 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 206 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
207 | * @data: platform specific data for this platform device | 207 | * @data: platform specific data for this platform device |
208 | * @size: size of platform specific data | 208 | * @size: size of platform specific data |
@@ -344,7 +344,7 @@ void platform_device_unregister(struct platform_device *pdev) | |||
344 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 344 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
345 | 345 | ||
346 | /** | 346 | /** |
347 | * platform_device_register_simple | 347 | * platform_device_register_simple - add a platform-level device and its resources |
348 | * @name: base name of the device we're adding | 348 | * @name: base name of the device we're adding |
349 | * @id: instance id | 349 | * @id: instance id |
350 | * @res: set of resources that needs to be allocated for the device | 350 | * @res: set of resources that needs to be allocated for the device |
@@ -396,7 +396,7 @@ error: | |||
396 | EXPORT_SYMBOL_GPL(platform_device_register_simple); | 396 | EXPORT_SYMBOL_GPL(platform_device_register_simple); |
397 | 397 | ||
398 | /** | 398 | /** |
399 | * platform_device_register_data | 399 | * platform_device_register_data - add a platform-level device with platform-specific data |
400 | * @parent: parent device for the device we're adding | 400 | * @parent: parent device for the device we're adding |
401 | * @name: base name of the device we're adding | 401 | * @name: base name of the device we're adding |
402 | * @id: instance id | 402 | * @id: instance id |
@@ -473,7 +473,7 @@ static void platform_drv_shutdown(struct device *_dev) | |||
473 | } | 473 | } |
474 | 474 | ||
475 | /** | 475 | /** |
476 | * platform_driver_register | 476 | * platform_driver_register - register a driver for platform-level devices |
477 | * @drv: platform driver structure | 477 | * @drv: platform driver structure |
478 | */ | 478 | */ |
479 | int platform_driver_register(struct platform_driver *drv) | 479 | int platform_driver_register(struct platform_driver *drv) |
@@ -491,7 +491,7 @@ int platform_driver_register(struct platform_driver *drv) | |||
491 | EXPORT_SYMBOL_GPL(platform_driver_register); | 491 | EXPORT_SYMBOL_GPL(platform_driver_register); |
492 | 492 | ||
493 | /** | 493 | /** |
494 | * platform_driver_unregister | 494 | * platform_driver_unregister - unregister a driver for platform-level devices |
495 | * @drv: platform driver structure | 495 | * @drv: platform driver structure |
496 | */ | 496 | */ |
497 | void platform_driver_unregister(struct platform_driver *drv) | 497 | void platform_driver_unregister(struct platform_driver *drv) |
@@ -548,6 +548,64 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
548 | } | 548 | } |
549 | EXPORT_SYMBOL_GPL(platform_driver_probe); | 549 | EXPORT_SYMBOL_GPL(platform_driver_probe); |
550 | 550 | ||
551 | /** | ||
552 | * platform_create_bundle - register driver and create corresponding device | ||
553 | * @driver: platform driver structure | ||
554 | * @probe: the driver probe routine, probably from an __init section | ||
555 | * @res: set of resources that needs to be allocated for the device | ||
556 | * @n_res: number of resources | ||
557 | * @data: platform specific data for this platform device | ||
558 | * @size: size of platform specific data | ||
559 | * | ||
560 | * Use this in legacy-style modules that probe hardware directly and | ||
561 | * register a single platform device and corresponding platform driver. | ||
562 | */ | ||
563 | struct platform_device * __init_or_module platform_create_bundle( | ||
564 | struct platform_driver *driver, | ||
565 | int (*probe)(struct platform_device *), | ||
566 | struct resource *res, unsigned int n_res, | ||
567 | const void *data, size_t size) | ||
568 | { | ||
569 | struct platform_device *pdev; | ||
570 | int error; | ||
571 | |||
572 | pdev = platform_device_alloc(driver->driver.name, -1); | ||
573 | if (!pdev) { | ||
574 | error = -ENOMEM; | ||
575 | goto err_out; | ||
576 | } | ||
577 | |||
578 | if (res) { | ||
579 | error = platform_device_add_resources(pdev, res, n_res); | ||
580 | if (error) | ||
581 | goto err_pdev_put; | ||
582 | } | ||
583 | |||
584 | if (data) { | ||
585 | error = platform_device_add_data(pdev, data, size); | ||
586 | if (error) | ||
587 | goto err_pdev_put; | ||
588 | } | ||
589 | |||
590 | error = platform_device_add(pdev); | ||
591 | if (error) | ||
592 | goto err_pdev_put; | ||
593 | |||
594 | error = platform_driver_probe(driver, probe); | ||
595 | if (error) | ||
596 | goto err_pdev_del; | ||
597 | |||
598 | return pdev; | ||
599 | |||
600 | err_pdev_del: | ||
601 | platform_device_del(pdev); | ||
602 | err_pdev_put: | ||
603 | platform_device_put(pdev); | ||
604 | err_out: | ||
605 | return ERR_PTR(error); | ||
606 | } | ||
607 | EXPORT_SYMBOL_GPL(platform_create_bundle); | ||
608 | |||
551 | /* modalias support enables more hands-off userspace setup: | 609 | /* modalias support enables more hands-off userspace setup: |
552 | * (a) environment variable lets new-style hotplug events work once system is | 610 | * (a) environment variable lets new-style hotplug events work once system is |
553 | * fully running: "modprobe $MODALIAS" | 611 | * fully running: "modprobe $MODALIAS" |
@@ -578,7 +636,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
578 | } | 636 | } |
579 | 637 | ||
580 | static const struct platform_device_id *platform_match_id( | 638 | static const struct platform_device_id *platform_match_id( |
581 | struct platform_device_id *id, | 639 | const struct platform_device_id *id, |
582 | struct platform_device *pdev) | 640 | struct platform_device *pdev) |
583 | { | 641 | { |
584 | while (id->name[0]) { | 642 | while (id->name[0]) { |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 0e26a6f6fd48..d477f4dc5e51 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -35,8 +35,8 @@ | |||
35 | * because children are guaranteed to be discovered after parents, and | 35 | * because children are guaranteed to be discovered after parents, and |
36 | * are inserted at the back of the list on discovery. | 36 | * are inserted at the back of the list on discovery. |
37 | * | 37 | * |
38 | * Since device_pm_add() may be called with a device semaphore held, | 38 | * Since device_pm_add() may be called with a device lock held, |
39 | * we must never try to acquire a device semaphore while holding | 39 | * we must never try to acquire a device lock while holding |
40 | * dpm_list_mutex. | 40 | * dpm_list_mutex. |
41 | */ | 41 | */ |
42 | 42 | ||
@@ -508,7 +508,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
508 | TRACE_RESUME(0); | 508 | TRACE_RESUME(0); |
509 | 509 | ||
510 | dpm_wait(dev->parent, async); | 510 | dpm_wait(dev->parent, async); |
511 | down(&dev->sem); | 511 | device_lock(dev); |
512 | 512 | ||
513 | dev->power.status = DPM_RESUMING; | 513 | dev->power.status = DPM_RESUMING; |
514 | 514 | ||
@@ -543,7 +543,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) | |||
543 | } | 543 | } |
544 | } | 544 | } |
545 | End: | 545 | End: |
546 | up(&dev->sem); | 546 | device_unlock(dev); |
547 | complete_all(&dev->power.completion); | 547 | complete_all(&dev->power.completion); |
548 | 548 | ||
549 | TRACE_RESUME(error); | 549 | TRACE_RESUME(error); |
@@ -629,7 +629,7 @@ static void dpm_resume(pm_message_t state) | |||
629 | */ | 629 | */ |
630 | static void device_complete(struct device *dev, pm_message_t state) | 630 | static void device_complete(struct device *dev, pm_message_t state) |
631 | { | 631 | { |
632 | down(&dev->sem); | 632 | device_lock(dev); |
633 | 633 | ||
634 | if (dev->class && dev->class->pm && dev->class->pm->complete) { | 634 | if (dev->class && dev->class->pm && dev->class->pm->complete) { |
635 | pm_dev_dbg(dev, state, "completing class "); | 635 | pm_dev_dbg(dev, state, "completing class "); |
@@ -646,7 +646,7 @@ static void device_complete(struct device *dev, pm_message_t state) | |||
646 | dev->bus->pm->complete(dev); | 646 | dev->bus->pm->complete(dev); |
647 | } | 647 | } |
648 | 648 | ||
649 | up(&dev->sem); | 649 | device_unlock(dev); |
650 | } | 650 | } |
651 | 651 | ||
652 | /** | 652 | /** |
@@ -809,7 +809,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
809 | int error = 0; | 809 | int error = 0; |
810 | 810 | ||
811 | dpm_wait_for_children(dev, async); | 811 | dpm_wait_for_children(dev, async); |
812 | down(&dev->sem); | 812 | device_lock(dev); |
813 | 813 | ||
814 | if (async_error) | 814 | if (async_error) |
815 | goto End; | 815 | goto End; |
@@ -849,7 +849,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) | |||
849 | dev->power.status = DPM_OFF; | 849 | dev->power.status = DPM_OFF; |
850 | 850 | ||
851 | End: | 851 | End: |
852 | up(&dev->sem); | 852 | device_unlock(dev); |
853 | complete_all(&dev->power.completion); | 853 | complete_all(&dev->power.completion); |
854 | 854 | ||
855 | return error; | 855 | return error; |
@@ -938,7 +938,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
938 | { | 938 | { |
939 | int error = 0; | 939 | int error = 0; |
940 | 940 | ||
941 | down(&dev->sem); | 941 | device_lock(dev); |
942 | 942 | ||
943 | if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { | 943 | if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { |
944 | pm_dev_dbg(dev, state, "preparing "); | 944 | pm_dev_dbg(dev, state, "preparing "); |
@@ -962,7 +962,7 @@ static int device_prepare(struct device *dev, pm_message_t state) | |||
962 | suspend_report_result(dev->class->pm->prepare, error); | 962 | suspend_report_result(dev->class->pm->prepare, error); |
963 | } | 963 | } |
964 | End: | 964 | End: |
965 | up(&dev->sem); | 965 | device_unlock(dev); |
966 | 966 | ||
967 | return error; | 967 | return error; |
968 | } | 968 | } |
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 0d903909af7e..8980feec5d14 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -54,7 +54,7 @@ sysdev_store(struct kobject *kobj, struct attribute *attr, | |||
54 | return -EIO; | 54 | return -EIO; |
55 | } | 55 | } |
56 | 56 | ||
57 | static struct sysfs_ops sysfs_ops = { | 57 | static const struct sysfs_ops sysfs_ops = { |
58 | .show = sysdev_show, | 58 | .show = sysdev_show, |
59 | .store = sysdev_store, | 59 | .store = sysdev_store, |
60 | }; | 60 | }; |
@@ -89,7 +89,7 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, | |||
89 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | 89 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
90 | 90 | ||
91 | if (class_attr->show) | 91 | if (class_attr->show) |
92 | return class_attr->show(class, buffer); | 92 | return class_attr->show(class, class_attr, buffer); |
93 | return -EIO; | 93 | return -EIO; |
94 | } | 94 | } |
95 | 95 | ||
@@ -100,11 +100,11 @@ static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, | |||
100 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); | 100 | struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); |
101 | 101 | ||
102 | if (class_attr->store) | 102 | if (class_attr->store) |
103 | return class_attr->store(class, buffer, count); | 103 | return class_attr->store(class, class_attr, buffer, count); |
104 | return -EIO; | 104 | return -EIO; |
105 | } | 105 | } |
106 | 106 | ||
107 | static struct sysfs_ops sysfs_class_ops = { | 107 | static const struct sysfs_ops sysfs_class_ops = { |
108 | .show = sysdev_class_show, | 108 | .show = sysdev_class_show, |
109 | .store = sysdev_class_store, | 109 | .store = sysdev_class_store, |
110 | }; | 110 | }; |
@@ -145,13 +145,20 @@ int sysdev_class_register(struct sysdev_class *cls) | |||
145 | if (retval) | 145 | if (retval) |
146 | return retval; | 146 | return retval; |
147 | 147 | ||
148 | return kset_register(&cls->kset); | 148 | retval = kset_register(&cls->kset); |
149 | if (!retval && cls->attrs) | ||
150 | retval = sysfs_create_files(&cls->kset.kobj, | ||
151 | (const struct attribute **)cls->attrs); | ||
152 | return retval; | ||
149 | } | 153 | } |
150 | 154 | ||
151 | void sysdev_class_unregister(struct sysdev_class *cls) | 155 | void sysdev_class_unregister(struct sysdev_class *cls) |
152 | { | 156 | { |
153 | pr_debug("Unregistering sysdev class '%s'\n", | 157 | pr_debug("Unregistering sysdev class '%s'\n", |
154 | kobject_name(&cls->kset.kobj)); | 158 | kobject_name(&cls->kset.kobj)); |
159 | if (cls->attrs) | ||
160 | sysfs_remove_files(&cls->kset.kobj, | ||
161 | (const struct attribute **)cls->attrs); | ||
155 | kset_unregister(&cls->kset); | 162 | kset_unregister(&cls->kset); |
156 | } | 163 | } |
157 | 164 | ||
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2d5cebbbf253..e5e86a781820 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -95,7 +95,7 @@ extern char usermode_helper[]; | |||
95 | 95 | ||
96 | /* All EEs on the free list should have ID_VACANT (== 0) | 96 | /* All EEs on the free list should have ID_VACANT (== 0) |
97 | * freshly allocated EEs get !ID_VACANT (== 1) | 97 | * freshly allocated EEs get !ID_VACANT (== 1) |
98 | * so if it says "cannot dereference null pointer at adress 0x00000001", | 98 | * so if it says "cannot dereference null pointer at address 0x00000001", |
99 | * it is most likely one of these :( */ | 99 | * it is most likely one of these :( */ |
100 | 100 | ||
101 | #define ID_IN_SYNC (4711ULL) | 101 | #define ID_IN_SYNC (4711ULL) |
@@ -1181,7 +1181,7 @@ extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf | |||
1181 | /* Meta data layout | 1181 | /* Meta data layout |
1182 | We reserve a 128MB Block (4k aligned) | 1182 | We reserve a 128MB Block (4k aligned) |
1183 | * either at the end of the backing device | 1183 | * either at the end of the backing device |
1184 | * or on a seperate meta data device. */ | 1184 | * or on a separate meta data device. */ |
1185 | 1185 | ||
1186 | #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ | 1186 | #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ |
1187 | /* The following numbers are sectors */ | 1187 | /* The following numbers are sectors */ |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index f22c1bc8ec7e..16119d7056cc 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
@@ -57,7 +57,7 @@ | |||
57 | * | 57 | * |
58 | * It may me handed over to the local disk subsystem. | 58 | * It may me handed over to the local disk subsystem. |
59 | * It may be completed by the local disk subsystem, | 59 | * It may be completed by the local disk subsystem, |
60 | * either sucessfully or with io-error. | 60 | * either successfully or with io-error. |
61 | * In case it is a READ request, and it failed locally, | 61 | * In case it is a READ request, and it failed locally, |
62 | * it may be retried remotely. | 62 | * it may be retried remotely. |
63 | * | 63 | * |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index b9b117059b62..90c4038702da 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -144,13 +144,23 @@ | |||
144 | * Better audit of register_blkdev. | 144 | * Better audit of register_blkdev. |
145 | */ | 145 | */ |
146 | 146 | ||
147 | #define FLOPPY_SANITY_CHECK | ||
148 | #undef FLOPPY_SILENT_DCL_CLEAR | 147 | #undef FLOPPY_SILENT_DCL_CLEAR |
149 | 148 | ||
150 | #define REALLY_SLOW_IO | 149 | #define REALLY_SLOW_IO |
151 | 150 | ||
152 | #define DEBUGT 2 | 151 | #define DEBUGT 2 |
153 | #define DCL_DEBUG /* debug disk change line */ | 152 | |
153 | #define DPRINT(format, args...) \ | ||
154 | pr_info("floppy%d: " format, current_drive, ##args) | ||
155 | |||
156 | #define DCL_DEBUG /* debug disk change line */ | ||
157 | #ifdef DCL_DEBUG | ||
158 | #define debug_dcl(test, fmt, args...) \ | ||
159 | do { if ((test) & FD_DEBUG) DPRINT(fmt, ##args); } while (0) | ||
160 | #else | ||
161 | #define debug_dcl(test, fmt, args...) \ | ||
162 | do { if (0) DPRINT(fmt, ##args); } while (0) | ||
163 | #endif | ||
154 | 164 | ||
155 | /* do print messages for unexpected interrupts */ | 165 | /* do print messages for unexpected interrupts */ |
156 | static int print_unex = 1; | 166 | static int print_unex = 1; |
@@ -180,6 +190,8 @@ static int print_unex = 1; | |||
180 | #include <linux/mod_devicetable.h> | 190 | #include <linux/mod_devicetable.h> |
181 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ | 191 | #include <linux/buffer_head.h> /* for invalidate_buffers() */ |
182 | #include <linux/mutex.h> | 192 | #include <linux/mutex.h> |
193 | #include <linux/io.h> | ||
194 | #include <linux/uaccess.h> | ||
183 | 195 | ||
184 | /* | 196 | /* |
185 | * PS/2 floppies have much slower step rates than regular floppies. | 197 | * PS/2 floppies have much slower step rates than regular floppies. |
@@ -191,8 +203,6 @@ static int slow_floppy; | |||
191 | #include <asm/dma.h> | 203 | #include <asm/dma.h> |
192 | #include <asm/irq.h> | 204 | #include <asm/irq.h> |
193 | #include <asm/system.h> | 205 | #include <asm/system.h> |
194 | #include <asm/io.h> | ||
195 | #include <asm/uaccess.h> | ||
196 | 206 | ||
197 | static int FLOPPY_IRQ = 6; | 207 | static int FLOPPY_IRQ = 6; |
198 | static int FLOPPY_DMA = 2; | 208 | static int FLOPPY_DMA = 2; |
@@ -241,8 +251,6 @@ static int allowed_drive_mask = 0x33; | |||
241 | 251 | ||
242 | static int irqdma_allocated; | 252 | static int irqdma_allocated; |
243 | 253 | ||
244 | #define DEVICE_NAME "floppy" | ||
245 | |||
246 | #include <linux/blkdev.h> | 254 | #include <linux/blkdev.h> |
247 | #include <linux/blkpg.h> | 255 | #include <linux/blkpg.h> |
248 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ | 256 | #include <linux/cdrom.h> /* for the compatibility eject ioctl */ |
@@ -250,7 +258,7 @@ static int irqdma_allocated; | |||
250 | 258 | ||
251 | static struct request *current_req; | 259 | static struct request *current_req; |
252 | static struct request_queue *floppy_queue; | 260 | static struct request_queue *floppy_queue; |
253 | static void do_fd_request(struct request_queue * q); | 261 | static void do_fd_request(struct request_queue *q); |
254 | 262 | ||
255 | #ifndef fd_get_dma_residue | 263 | #ifndef fd_get_dma_residue |
256 | #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) | 264 | #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) |
@@ -263,7 +271,7 @@ static void do_fd_request(struct request_queue * q); | |||
263 | #endif | 271 | #endif |
264 | 272 | ||
265 | #ifndef fd_dma_mem_alloc | 273 | #ifndef fd_dma_mem_alloc |
266 | #define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size)) | 274 | #define fd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL, get_order(size)) |
267 | #endif | 275 | #endif |
268 | 276 | ||
269 | static inline void fallback_on_nodma_alloc(char **addr, size_t l) | 277 | static inline void fallback_on_nodma_alloc(char **addr, size_t l) |
@@ -273,7 +281,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) | |||
273 | return; /* we have the memory */ | 281 | return; /* we have the memory */ |
274 | if (can_use_virtual_dma != 2) | 282 | if (can_use_virtual_dma != 2) |
275 | return; /* no fallback allowed */ | 283 | return; /* no fallback allowed */ |
276 | printk("DMA memory shortage. Temporarily falling back on virtual DMA\n"); | 284 | pr_info("DMA memory shortage. Temporarily falling back on virtual DMA\n"); |
277 | *addr = (char *)nodma_mem_alloc(l); | 285 | *addr = (char *)nodma_mem_alloc(l); |
278 | #else | 286 | #else |
279 | return; | 287 | return; |
@@ -283,59 +291,50 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l) | |||
283 | /* End dma memory related stuff */ | 291 | /* End dma memory related stuff */ |
284 | 292 | ||
285 | static unsigned long fake_change; | 293 | static unsigned long fake_change; |
286 | static int initialising = 1; | 294 | static bool initialized; |
287 | 295 | ||
288 | #define ITYPE(x) (((x)>>2) & 0x1f) | 296 | #define ITYPE(x) (((x) >> 2) & 0x1f) |
289 | #define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) | 297 | #define TOMINOR(x) ((x & 3) | ((x & 4) << 5)) |
290 | #define UNIT(x) ((x) & 0x03) /* drive on fdc */ | 298 | #define UNIT(x) ((x) & 0x03) /* drive on fdc */ |
291 | #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ | 299 | #define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */ |
292 | /* reverse mapping from unit and fdc to drive */ | 300 | /* reverse mapping from unit and fdc to drive */ |
293 | #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) | 301 | #define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2)) |
294 | #define DP (&drive_params[current_drive]) | ||
295 | #define DRS (&drive_state[current_drive]) | ||
296 | #define DRWE (&write_errors[current_drive]) | ||
297 | #define FDCS (&fdc_state[fdc]) | ||
298 | #define CLEARF(x) clear_bit(x##_BIT, &DRS->flags) | ||
299 | #define SETF(x) set_bit(x##_BIT, &DRS->flags) | ||
300 | #define TESTF(x) test_bit(x##_BIT, &DRS->flags) | ||
301 | 302 | ||
302 | #define UDP (&drive_params[drive]) | 303 | #define DP (&drive_params[current_drive]) |
303 | #define UDRS (&drive_state[drive]) | 304 | #define DRS (&drive_state[current_drive]) |
304 | #define UDRWE (&write_errors[drive]) | 305 | #define DRWE (&write_errors[current_drive]) |
305 | #define UFDCS (&fdc_state[FDC(drive)]) | 306 | #define FDCS (&fdc_state[fdc]) |
306 | #define UCLEARF(x) clear_bit(x##_BIT, &UDRS->flags) | ||
307 | #define USETF(x) set_bit(x##_BIT, &UDRS->flags) | ||
308 | #define UTESTF(x) test_bit(x##_BIT, &UDRS->flags) | ||
309 | 307 | ||
310 | #define DPRINT(format, args...) printk(DEVICE_NAME "%d: " format, current_drive , ## args) | 308 | #define UDP (&drive_params[drive]) |
309 | #define UDRS (&drive_state[drive]) | ||
310 | #define UDRWE (&write_errors[drive]) | ||
311 | #define UFDCS (&fdc_state[FDC(drive)]) | ||
311 | 312 | ||
312 | #define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2) | 313 | #define PH_HEAD(floppy, head) (((((floppy)->stretch & 2) >> 1) ^ head) << 2) |
313 | #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) | 314 | #define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH) |
314 | |||
315 | #define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x))) | ||
316 | 315 | ||
317 | /* read/write */ | 316 | /* read/write */ |
318 | #define COMMAND raw_cmd->cmd[0] | 317 | #define COMMAND (raw_cmd->cmd[0]) |
319 | #define DR_SELECT raw_cmd->cmd[1] | 318 | #define DR_SELECT (raw_cmd->cmd[1]) |
320 | #define TRACK raw_cmd->cmd[2] | 319 | #define TRACK (raw_cmd->cmd[2]) |
321 | #define HEAD raw_cmd->cmd[3] | 320 | #define HEAD (raw_cmd->cmd[3]) |
322 | #define SECTOR raw_cmd->cmd[4] | 321 | #define SECTOR (raw_cmd->cmd[4]) |
323 | #define SIZECODE raw_cmd->cmd[5] | 322 | #define SIZECODE (raw_cmd->cmd[5]) |
324 | #define SECT_PER_TRACK raw_cmd->cmd[6] | 323 | #define SECT_PER_TRACK (raw_cmd->cmd[6]) |
325 | #define GAP raw_cmd->cmd[7] | 324 | #define GAP (raw_cmd->cmd[7]) |
326 | #define SIZECODE2 raw_cmd->cmd[8] | 325 | #define SIZECODE2 (raw_cmd->cmd[8]) |
327 | #define NR_RW 9 | 326 | #define NR_RW 9 |
328 | 327 | ||
329 | /* format */ | 328 | /* format */ |
330 | #define F_SIZECODE raw_cmd->cmd[2] | 329 | #define F_SIZECODE (raw_cmd->cmd[2]) |
331 | #define F_SECT_PER_TRACK raw_cmd->cmd[3] | 330 | #define F_SECT_PER_TRACK (raw_cmd->cmd[3]) |
332 | #define F_GAP raw_cmd->cmd[4] | 331 | #define F_GAP (raw_cmd->cmd[4]) |
333 | #define F_FILL raw_cmd->cmd[5] | 332 | #define F_FILL (raw_cmd->cmd[5]) |
334 | #define NR_F 6 | 333 | #define NR_F 6 |
335 | 334 | ||
336 | /* | 335 | /* |
337 | * Maximum disk size (in kilobytes). This default is used whenever the | 336 | * Maximum disk size (in kilobytes). |
338 | * current disk size is unknown. | 337 | * This default is used whenever the current disk size is unknown. |
339 | * [Now it is rather a minimum] | 338 | * [Now it is rather a minimum] |
340 | */ | 339 | */ |
341 | #define MAX_DISK_SIZE 4 /* 3984 */ | 340 | #define MAX_DISK_SIZE 4 /* 3984 */ |
@@ -345,16 +344,17 @@ static int initialising = 1; | |||
345 | */ | 344 | */ |
346 | #define MAX_REPLIES 16 | 345 | #define MAX_REPLIES 16 |
347 | static unsigned char reply_buffer[MAX_REPLIES]; | 346 | static unsigned char reply_buffer[MAX_REPLIES]; |
348 | static int inr; /* size of reply buffer, when called from interrupt */ | 347 | static int inr; /* size of reply buffer, when called from interrupt */ |
349 | #define ST0 (reply_buffer[0]) | 348 | #define ST0 (reply_buffer[0]) |
350 | #define ST1 (reply_buffer[1]) | 349 | #define ST1 (reply_buffer[1]) |
351 | #define ST2 (reply_buffer[2]) | 350 | #define ST2 (reply_buffer[2]) |
352 | #define ST3 (reply_buffer[0]) /* result of GETSTATUS */ | 351 | #define ST3 (reply_buffer[0]) /* result of GETSTATUS */ |
353 | #define R_TRACK (reply_buffer[3]) | 352 | #define R_TRACK (reply_buffer[3]) |
354 | #define R_HEAD (reply_buffer[4]) | 353 | #define R_HEAD (reply_buffer[4]) |
355 | #define R_SECTOR (reply_buffer[5]) | 354 | #define R_SECTOR (reply_buffer[5]) |
356 | #define R_SIZECODE (reply_buffer[6]) | 355 | #define R_SIZECODE (reply_buffer[6]) |
357 | #define SEL_DLY (2*HZ/100) | 356 | |
357 | #define SEL_DLY (2 * HZ / 100) | ||
358 | 358 | ||
359 | /* | 359 | /* |
360 | * this struct defines the different floppy drive types. | 360 | * this struct defines the different floppy drive types. |
@@ -505,9 +505,9 @@ static char floppy_device_name[] = "floppy"; | |||
505 | static int probing; | 505 | static int probing; |
506 | 506 | ||
507 | /* Synchronization of FDC access. */ | 507 | /* Synchronization of FDC access. */ |
508 | #define FD_COMMAND_NONE -1 | 508 | #define FD_COMMAND_NONE -1 |
509 | #define FD_COMMAND_ERROR 2 | 509 | #define FD_COMMAND_ERROR 2 |
510 | #define FD_COMMAND_OKAY 3 | 510 | #define FD_COMMAND_OKAY 3 |
511 | 511 | ||
512 | static volatile int command_status = FD_COMMAND_NONE; | 512 | static volatile int command_status = FD_COMMAND_NONE; |
513 | static unsigned long fdc_busy; | 513 | static unsigned long fdc_busy; |
@@ -515,11 +515,6 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); | |||
515 | static DECLARE_WAIT_QUEUE_HEAD(command_done); | 515 | static DECLARE_WAIT_QUEUE_HEAD(command_done); |
516 | 516 | ||
517 | #define NO_SIGNAL (!interruptible || !signal_pending(current)) | 517 | #define NO_SIGNAL (!interruptible || !signal_pending(current)) |
518 | #define CALL(x) if ((x) == -EINTR) return -EINTR | ||
519 | #define ECALL(x) if ((ret = (x))) return ret; | ||
520 | #define _WAIT(x,i) CALL(ret=wait_til_done((x),i)) | ||
521 | #define WAIT(x) _WAIT((x),interruptible) | ||
522 | #define IWAIT(x) _WAIT((x),1) | ||
523 | 518 | ||
524 | /* Errors during formatting are counted here. */ | 519 | /* Errors during formatting are counted here. */ |
525 | static int format_errors; | 520 | static int format_errors; |
@@ -545,8 +540,9 @@ static int max_buffer_sectors; | |||
545 | static int *errors; | 540 | static int *errors; |
546 | typedef void (*done_f)(int); | 541 | typedef void (*done_f)(int); |
547 | static struct cont_t { | 542 | static struct cont_t { |
548 | void (*interrupt)(void); /* this is called after the interrupt of the | 543 | void (*interrupt)(void); |
549 | * main command */ | 544 | /* this is called after the interrupt of the |
545 | * main command */ | ||
550 | void (*redo)(void); /* this is called to retry the operation */ | 546 | void (*redo)(void); /* this is called to retry the operation */ |
551 | void (*error)(void); /* this is called to tally an error */ | 547 | void (*error)(void); /* this is called to tally an error */ |
552 | done_f done; /* this is called to say if the operation has | 548 | done_f done; /* this is called to say if the operation has |
@@ -571,7 +567,6 @@ static void floppy_release_irq_and_dma(void); | |||
571 | * reset doesn't need to be tested before sending commands, because | 567 | * reset doesn't need to be tested before sending commands, because |
572 | * output_byte is automatically disabled when reset is set. | 568 | * output_byte is automatically disabled when reset is set. |
573 | */ | 569 | */ |
574 | #define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } } | ||
575 | static void reset_fdc(void); | 570 | static void reset_fdc(void); |
576 | 571 | ||
577 | /* | 572 | /* |
@@ -579,9 +574,9 @@ static void reset_fdc(void); | |||
579 | * information to interrupts. They are the data used for the current | 574 | * information to interrupts. They are the data used for the current |
580 | * request. | 575 | * request. |
581 | */ | 576 | */ |
582 | #define NO_TRACK -1 | 577 | #define NO_TRACK -1 |
583 | #define NEED_1_RECAL -2 | 578 | #define NEED_1_RECAL -2 |
584 | #define NEED_2_RECAL -3 | 579 | #define NEED_2_RECAL -3 |
585 | 580 | ||
586 | static int usage_count; | 581 | static int usage_count; |
587 | 582 | ||
@@ -621,39 +616,35 @@ static inline void set_debugt(void) | |||
621 | debugtimer = jiffies; | 616 | debugtimer = jiffies; |
622 | } | 617 | } |
623 | 618 | ||
624 | static inline void debugt(const char *message) | 619 | static inline void debugt(const char *func, const char *msg) |
625 | { | 620 | { |
626 | if (DP->flags & DEBUGT) | 621 | if (DP->flags & DEBUGT) |
627 | printk("%s dtime=%lu\n", message, jiffies - debugtimer); | 622 | pr_info("%s:%s dtime=%lu\n", func, msg, jiffies - debugtimer); |
628 | } | 623 | } |
629 | #else | 624 | #else |
630 | static inline void set_debugt(void) { } | 625 | static inline void set_debugt(void) { } |
631 | static inline void debugt(const char *message) { } | 626 | static inline void debugt(const char *func, const char *msg) { } |
632 | #endif /* DEBUGT */ | 627 | #endif /* DEBUGT */ |
633 | 628 | ||
634 | typedef void (*timeout_fn) (unsigned long); | 629 | typedef void (*timeout_fn)(unsigned long); |
635 | static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); | 630 | static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); |
636 | 631 | ||
637 | static const char *timeout_message; | 632 | static const char *timeout_message; |
638 | 633 | ||
639 | #ifdef FLOPPY_SANITY_CHECK | 634 | static void is_alive(const char *func, const char *message) |
640 | static void is_alive(const char *message) | ||
641 | { | 635 | { |
642 | /* this routine checks whether the floppy driver is "alive" */ | 636 | /* this routine checks whether the floppy driver is "alive" */ |
643 | if (test_bit(0, &fdc_busy) && command_status < 2 | 637 | if (test_bit(0, &fdc_busy) && command_status < 2 && |
644 | && !timer_pending(&fd_timeout)) { | 638 | !timer_pending(&fd_timeout)) { |
645 | DPRINT("timeout handler died: %s\n", message); | 639 | DPRINT("%s: timeout handler died. %s\n", func, message); |
646 | } | 640 | } |
647 | } | 641 | } |
648 | #endif | ||
649 | 642 | ||
650 | static void (*do_floppy) (void) = NULL; | 643 | static void (*do_floppy)(void) = NULL; |
651 | |||
652 | #ifdef FLOPPY_SANITY_CHECK | ||
653 | 644 | ||
654 | #define OLOGSIZE 20 | 645 | #define OLOGSIZE 20 |
655 | 646 | ||
656 | static void (*lasthandler) (void); | 647 | static void (*lasthandler)(void); |
657 | static unsigned long interruptjiffies; | 648 | static unsigned long interruptjiffies; |
658 | static unsigned long resultjiffies; | 649 | static unsigned long resultjiffies; |
659 | static int resultsize; | 650 | static int resultsize; |
@@ -666,12 +657,11 @@ static struct output_log { | |||
666 | } output_log[OLOGSIZE]; | 657 | } output_log[OLOGSIZE]; |
667 | 658 | ||
668 | static int output_log_pos; | 659 | static int output_log_pos; |
669 | #endif | ||
670 | 660 | ||
671 | #define current_reqD -1 | 661 | #define current_reqD -1 |
672 | #define MAXTIMEOUT -2 | 662 | #define MAXTIMEOUT -2 |
673 | 663 | ||
674 | static void __reschedule_timeout(int drive, const char *message, int marg) | 664 | static void __reschedule_timeout(int drive, const char *message) |
675 | { | 665 | { |
676 | if (drive == current_reqD) | 666 | if (drive == current_reqD) |
677 | drive = current_drive; | 667 | drive = current_drive; |
@@ -682,25 +672,22 @@ static void __reschedule_timeout(int drive, const char *message, int marg) | |||
682 | } else | 672 | } else |
683 | fd_timeout.expires = jiffies + UDP->timeout; | 673 | fd_timeout.expires = jiffies + UDP->timeout; |
684 | add_timer(&fd_timeout); | 674 | add_timer(&fd_timeout); |
685 | if (UDP->flags & FD_DEBUG) { | 675 | if (UDP->flags & FD_DEBUG) |
686 | DPRINT("reschedule timeout "); | 676 | DPRINT("reschedule timeout %s\n", message); |
687 | printk(message, marg); | ||
688 | printk("\n"); | ||
689 | } | ||
690 | timeout_message = message; | 677 | timeout_message = message; |
691 | } | 678 | } |
692 | 679 | ||
693 | static void reschedule_timeout(int drive, const char *message, int marg) | 680 | static void reschedule_timeout(int drive, const char *message) |
694 | { | 681 | { |
695 | unsigned long flags; | 682 | unsigned long flags; |
696 | 683 | ||
697 | spin_lock_irqsave(&floppy_lock, flags); | 684 | spin_lock_irqsave(&floppy_lock, flags); |
698 | __reschedule_timeout(drive, message, marg); | 685 | __reschedule_timeout(drive, message); |
699 | spin_unlock_irqrestore(&floppy_lock, flags); | 686 | spin_unlock_irqrestore(&floppy_lock, flags); |
700 | } | 687 | } |
701 | 688 | ||
702 | #define INFBOUND(a,b) (a)=max_t(int, a, b) | 689 | #define INFBOUND(a, b) (a) = max_t(int, a, b) |
703 | #define SUPBOUND(a,b) (a)=min_t(int, a, b) | 690 | #define SUPBOUND(a, b) (a) = min_t(int, a, b) |
704 | 691 | ||
705 | /* | 692 | /* |
706 | * Bottom half floppy driver. | 693 | * Bottom half floppy driver. |
@@ -739,7 +726,6 @@ static int disk_change(int drive) | |||
739 | { | 726 | { |
740 | int fdc = FDC(drive); | 727 | int fdc = FDC(drive); |
741 | 728 | ||
742 | #ifdef FLOPPY_SANITY_CHECK | ||
743 | if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) | 729 | if (time_before(jiffies, UDRS->select_date + UDP->select_delay)) |
744 | DPRINT("WARNING disk change called early\n"); | 730 | DPRINT("WARNING disk change called early\n"); |
745 | if (!(FDCS->dor & (0x10 << UNIT(drive))) || | 731 | if (!(FDCS->dor & (0x10 << UNIT(drive))) || |
@@ -748,31 +734,27 @@ static int disk_change(int drive) | |||
748 | DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), | 734 | DPRINT("drive=%d fdc=%d dor=%x\n", drive, FDC(drive), |
749 | (unsigned int)FDCS->dor); | 735 | (unsigned int)FDCS->dor); |
750 | } | 736 | } |
751 | #endif | ||
752 | 737 | ||
753 | #ifdef DCL_DEBUG | 738 | debug_dcl(UDP->flags, |
754 | if (UDP->flags & FD_DEBUG) { | 739 | "checking disk change line for drive %d\n", drive); |
755 | DPRINT("checking disk change line for drive %d\n", drive); | 740 | debug_dcl(UDP->flags, "jiffies=%lu\n", jiffies); |
756 | DPRINT("jiffies=%lu\n", jiffies); | 741 | debug_dcl(UDP->flags, "disk change line=%x\n", fd_inb(FD_DIR) & 0x80); |
757 | DPRINT("disk change line=%x\n", fd_inb(FD_DIR) & 0x80); | 742 | debug_dcl(UDP->flags, "flags=%lx\n", UDRS->flags); |
758 | DPRINT("flags=%lx\n", UDRS->flags); | 743 | |
759 | } | ||
760 | #endif | ||
761 | if (UDP->flags & FD_BROKEN_DCL) | 744 | if (UDP->flags & FD_BROKEN_DCL) |
762 | return UTESTF(FD_DISK_CHANGED); | 745 | return test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
763 | if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) { | 746 | if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80) { |
764 | USETF(FD_VERIFY); /* verify write protection */ | 747 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
765 | if (UDRS->maxblock) { | 748 | /* verify write protection */ |
766 | /* mark it changed */ | 749 | |
767 | USETF(FD_DISK_CHANGED); | 750 | if (UDRS->maxblock) /* mark it changed */ |
768 | } | 751 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
769 | 752 | ||
770 | /* invalidate its geometry */ | 753 | /* invalidate its geometry */ |
771 | if (UDRS->keep_data >= 0) { | 754 | if (UDRS->keep_data >= 0) { |
772 | if ((UDP->flags & FTD_MSG) && | 755 | if ((UDP->flags & FTD_MSG) && |
773 | current_type[drive] != NULL) | 756 | current_type[drive] != NULL) |
774 | DPRINT("Disk type is undefined after " | 757 | DPRINT("Disk type is undefined after disk change\n"); |
775 | "disk change\n"); | ||
776 | current_type[drive] = NULL; | 758 | current_type[drive] = NULL; |
777 | floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; | 759 | floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1; |
778 | } | 760 | } |
@@ -780,7 +762,7 @@ static int disk_change(int drive) | |||
780 | return 1; | 762 | return 1; |
781 | } else { | 763 | } else { |
782 | UDRS->last_checked = jiffies; | 764 | UDRS->last_checked = jiffies; |
783 | UCLEARF(FD_DISK_NEWCHANGE); | 765 | clear_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); |
784 | } | 766 | } |
785 | return 0; | 767 | return 0; |
786 | } | 768 | } |
@@ -790,6 +772,12 @@ static inline int is_selected(int dor, int unit) | |||
790 | return ((dor & (0x10 << unit)) && (dor & 3) == unit); | 772 | return ((dor & (0x10 << unit)) && (dor & 3) == unit); |
791 | } | 773 | } |
792 | 774 | ||
775 | static bool is_ready_state(int status) | ||
776 | { | ||
777 | int state = status & (STATUS_READY | STATUS_DIR | STATUS_DMA); | ||
778 | return state == STATUS_READY; | ||
779 | } | ||
780 | |||
793 | static int set_dor(int fdc, char mask, char data) | 781 | static int set_dor(int fdc, char mask, char data) |
794 | { | 782 | { |
795 | unsigned char unit; | 783 | unsigned char unit; |
@@ -806,11 +794,8 @@ static int set_dor(int fdc, char mask, char data) | |||
806 | unit = olddor & 0x3; | 794 | unit = olddor & 0x3; |
807 | if (is_selected(olddor, unit) && !is_selected(newdor, unit)) { | 795 | if (is_selected(olddor, unit) && !is_selected(newdor, unit)) { |
808 | drive = REVDRIVE(fdc, unit); | 796 | drive = REVDRIVE(fdc, unit); |
809 | #ifdef DCL_DEBUG | 797 | debug_dcl(UDP->flags, |
810 | if (UDP->flags & FD_DEBUG) { | 798 | "calling disk change from set_dor\n"); |
811 | DPRINT("calling disk change from set_dor\n"); | ||
812 | } | ||
813 | #endif | ||
814 | disk_change(drive); | 799 | disk_change(drive); |
815 | } | 800 | } |
816 | FDCS->dor = newdor; | 801 | FDCS->dor = newdor; |
@@ -834,8 +819,10 @@ static void twaddle(void) | |||
834 | DRS->select_date = jiffies; | 819 | DRS->select_date = jiffies; |
835 | } | 820 | } |
836 | 821 | ||
837 | /* reset all driver information about the current fdc. This is needed after | 822 | /* |
838 | * a reset, and after a raw command. */ | 823 | * Reset all driver information about the current fdc. |
824 | * This is needed after a reset, and after a raw command. | ||
825 | */ | ||
839 | static void reset_fdc_info(int mode) | 826 | static void reset_fdc_info(int mode) |
840 | { | 827 | { |
841 | int drive; | 828 | int drive; |
@@ -857,7 +844,7 @@ static void set_fdc(int drive) | |||
857 | current_drive = drive; | 844 | current_drive = drive; |
858 | } | 845 | } |
859 | if (fdc != 1 && fdc != 0) { | 846 | if (fdc != 1 && fdc != 0) { |
860 | printk("bad fdc value\n"); | 847 | pr_info("bad fdc value\n"); |
861 | return; | 848 | return; |
862 | } | 849 | } |
863 | set_dor(fdc, ~0, 8); | 850 | set_dor(fdc, ~0, 8); |
@@ -871,11 +858,10 @@ static void set_fdc(int drive) | |||
871 | } | 858 | } |
872 | 859 | ||
873 | /* locks the driver */ | 860 | /* locks the driver */ |
874 | static int _lock_fdc(int drive, int interruptible, int line) | 861 | static int _lock_fdc(int drive, bool interruptible, int line) |
875 | { | 862 | { |
876 | if (!usage_count) { | 863 | if (!usage_count) { |
877 | printk(KERN_ERR | 864 | pr_err("Trying to lock fdc while usage count=0 at line %d\n", |
878 | "Trying to lock fdc while usage count=0 at line %d\n", | ||
879 | line); | 865 | line); |
880 | return -1; | 866 | return -1; |
881 | } | 867 | } |
@@ -904,15 +890,13 @@ static int _lock_fdc(int drive, int interruptible, int line) | |||
904 | } | 890 | } |
905 | command_status = FD_COMMAND_NONE; | 891 | command_status = FD_COMMAND_NONE; |
906 | 892 | ||
907 | __reschedule_timeout(drive, "lock fdc", 0); | 893 | __reschedule_timeout(drive, "lock fdc"); |
908 | set_fdc(drive); | 894 | set_fdc(drive); |
909 | return 0; | 895 | return 0; |
910 | } | 896 | } |
911 | 897 | ||
912 | #define lock_fdc(drive,interruptible) _lock_fdc(drive,interruptible, __LINE__) | 898 | #define lock_fdc(drive, interruptible) \ |
913 | 899 | _lock_fdc(drive, interruptible, __LINE__) | |
914 | #define LOCK_FDC(drive,interruptible) \ | ||
915 | if (lock_fdc(drive,interruptible)) return -EINTR; | ||
916 | 900 | ||
917 | /* unlocks the driver */ | 901 | /* unlocks the driver */ |
918 | static inline void unlock_fdc(void) | 902 | static inline void unlock_fdc(void) |
@@ -924,7 +908,7 @@ static inline void unlock_fdc(void) | |||
924 | DPRINT("FDC access conflict!\n"); | 908 | DPRINT("FDC access conflict!\n"); |
925 | 909 | ||
926 | if (do_floppy) | 910 | if (do_floppy) |
927 | DPRINT("device interrupt still active at FDC release: %p!\n", | 911 | DPRINT("device interrupt still active at FDC release: %pf!\n", |
928 | do_floppy); | 912 | do_floppy); |
929 | command_status = FD_COMMAND_NONE; | 913 | command_status = FD_COMMAND_NONE; |
930 | spin_lock_irqsave(&floppy_lock, flags); | 914 | spin_lock_irqsave(&floppy_lock, flags); |
@@ -1003,7 +987,7 @@ static void empty(void) | |||
1003 | 987 | ||
1004 | static DECLARE_WORK(floppy_work, NULL); | 988 | static DECLARE_WORK(floppy_work, NULL); |
1005 | 989 | ||
1006 | static void schedule_bh(void (*handler) (void)) | 990 | static void schedule_bh(void (*handler)(void)) |
1007 | { | 991 | { |
1008 | PREPARE_WORK(&floppy_work, (work_func_t)handler); | 992 | PREPARE_WORK(&floppy_work, (work_func_t)handler); |
1009 | schedule_work(&floppy_work); | 993 | schedule_work(&floppy_work); |
@@ -1026,11 +1010,7 @@ static void cancel_activity(void) | |||
1026 | * transfer */ | 1010 | * transfer */ |
1027 | static void fd_watchdog(void) | 1011 | static void fd_watchdog(void) |
1028 | { | 1012 | { |
1029 | #ifdef DCL_DEBUG | 1013 | debug_dcl(DP->flags, "calling disk change from watchdog\n"); |
1030 | if (DP->flags & FD_DEBUG) { | ||
1031 | DPRINT("calling disk change from watchdog\n"); | ||
1032 | } | ||
1033 | #endif | ||
1034 | 1014 | ||
1035 | if (disk_change(current_drive)) { | 1015 | if (disk_change(current_drive)) { |
1036 | DPRINT("disk removed during i/o\n"); | 1016 | DPRINT("disk removed during i/o\n"); |
@@ -1039,7 +1019,7 @@ static void fd_watchdog(void) | |||
1039 | reset_fdc(); | 1019 | reset_fdc(); |
1040 | } else { | 1020 | } else { |
1041 | del_timer(&fd_timer); | 1021 | del_timer(&fd_timer); |
1042 | fd_timer.function = (timeout_fn) fd_watchdog; | 1022 | fd_timer.function = (timeout_fn)fd_watchdog; |
1043 | fd_timer.expires = jiffies + HZ / 10; | 1023 | fd_timer.expires = jiffies + HZ / 10; |
1044 | add_timer(&fd_timer); | 1024 | add_timer(&fd_timer); |
1045 | } | 1025 | } |
@@ -1105,25 +1085,23 @@ static void setup_DMA(void) | |||
1105 | { | 1085 | { |
1106 | unsigned long f; | 1086 | unsigned long f; |
1107 | 1087 | ||
1108 | #ifdef FLOPPY_SANITY_CHECK | ||
1109 | if (raw_cmd->length == 0) { | 1088 | if (raw_cmd->length == 0) { |
1110 | int i; | 1089 | int i; |
1111 | 1090 | ||
1112 | printk("zero dma transfer size:"); | 1091 | pr_info("zero dma transfer size:"); |
1113 | for (i = 0; i < raw_cmd->cmd_count; i++) | 1092 | for (i = 0; i < raw_cmd->cmd_count; i++) |
1114 | printk("%x,", raw_cmd->cmd[i]); | 1093 | pr_cont("%x,", raw_cmd->cmd[i]); |
1115 | printk("\n"); | 1094 | pr_cont("\n"); |
1116 | cont->done(0); | 1095 | cont->done(0); |
1117 | FDCS->reset = 1; | 1096 | FDCS->reset = 1; |
1118 | return; | 1097 | return; |
1119 | } | 1098 | } |
1120 | if (((unsigned long)raw_cmd->kernel_data) % 512) { | 1099 | if (((unsigned long)raw_cmd->kernel_data) % 512) { |
1121 | printk("non aligned address: %p\n", raw_cmd->kernel_data); | 1100 | pr_info("non aligned address: %p\n", raw_cmd->kernel_data); |
1122 | cont->done(0); | 1101 | cont->done(0); |
1123 | FDCS->reset = 1; | 1102 | FDCS->reset = 1; |
1124 | return; | 1103 | return; |
1125 | } | 1104 | } |
1126 | #endif | ||
1127 | f = claim_dma_lock(); | 1105 | f = claim_dma_lock(); |
1128 | fd_disable_dma(); | 1106 | fd_disable_dma(); |
1129 | #ifdef fd_dma_setup | 1107 | #ifdef fd_dma_setup |
@@ -1165,7 +1143,7 @@ static int wait_til_ready(void) | |||
1165 | if (status & STATUS_READY) | 1143 | if (status & STATUS_READY) |
1166 | return status; | 1144 | return status; |
1167 | } | 1145 | } |
1168 | if (!initialising) { | 1146 | if (initialized) { |
1169 | DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc); | 1147 | DPRINT("Getstatus times out (%x) on fdc %d\n", status, fdc); |
1170 | show_floppy(); | 1148 | show_floppy(); |
1171 | } | 1149 | } |
@@ -1176,22 +1154,21 @@ static int wait_til_ready(void) | |||
1176 | /* sends a command byte to the fdc */ | 1154 | /* sends a command byte to the fdc */ |
1177 | static int output_byte(char byte) | 1155 | static int output_byte(char byte) |
1178 | { | 1156 | { |
1179 | int status; | 1157 | int status = wait_til_ready(); |
1180 | 1158 | ||
1181 | if ((status = wait_til_ready()) < 0) | 1159 | if (status < 0) |
1182 | return -1; | 1160 | return -1; |
1183 | if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) { | 1161 | |
1162 | if (is_ready_state(status)) { | ||
1184 | fd_outb(byte, FD_DATA); | 1163 | fd_outb(byte, FD_DATA); |
1185 | #ifdef FLOPPY_SANITY_CHECK | ||
1186 | output_log[output_log_pos].data = byte; | 1164 | output_log[output_log_pos].data = byte; |
1187 | output_log[output_log_pos].status = status; | 1165 | output_log[output_log_pos].status = status; |
1188 | output_log[output_log_pos].jiffies = jiffies; | 1166 | output_log[output_log_pos].jiffies = jiffies; |
1189 | output_log_pos = (output_log_pos + 1) % OLOGSIZE; | 1167 | output_log_pos = (output_log_pos + 1) % OLOGSIZE; |
1190 | #endif | ||
1191 | return 0; | 1168 | return 0; |
1192 | } | 1169 | } |
1193 | FDCS->reset = 1; | 1170 | FDCS->reset = 1; |
1194 | if (!initialising) { | 1171 | if (initialized) { |
1195 | DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", | 1172 | DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n", |
1196 | byte, fdc, status); | 1173 | byte, fdc, status); |
1197 | show_floppy(); | 1174 | show_floppy(); |
@@ -1199,8 +1176,6 @@ static int output_byte(char byte) | |||
1199 | return -1; | 1176 | return -1; |
1200 | } | 1177 | } |
1201 | 1178 | ||
1202 | #define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;} | ||
1203 | |||
1204 | /* gets the response from the fdc */ | 1179 | /* gets the response from the fdc */ |
1205 | static int result(void) | 1180 | static int result(void) |
1206 | { | 1181 | { |
@@ -1208,14 +1183,13 @@ static int result(void) | |||
1208 | int status = 0; | 1183 | int status = 0; |
1209 | 1184 | ||
1210 | for (i = 0; i < MAX_REPLIES; i++) { | 1185 | for (i = 0; i < MAX_REPLIES; i++) { |
1211 | if ((status = wait_til_ready()) < 0) | 1186 | status = wait_til_ready(); |
1187 | if (status < 0) | ||
1212 | break; | 1188 | break; |
1213 | status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA; | 1189 | status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA; |
1214 | if ((status & ~STATUS_BUSY) == STATUS_READY) { | 1190 | if ((status & ~STATUS_BUSY) == STATUS_READY) { |
1215 | #ifdef FLOPPY_SANITY_CHECK | ||
1216 | resultjiffies = jiffies; | 1191 | resultjiffies = jiffies; |
1217 | resultsize = i; | 1192 | resultsize = i; |
1218 | #endif | ||
1219 | return i; | 1193 | return i; |
1220 | } | 1194 | } |
1221 | if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY)) | 1195 | if (status == (STATUS_DIR | STATUS_READY | STATUS_BUSY)) |
@@ -1223,10 +1197,9 @@ static int result(void) | |||
1223 | else | 1197 | else |
1224 | break; | 1198 | break; |
1225 | } | 1199 | } |
1226 | if (!initialising) { | 1200 | if (initialized) { |
1227 | DPRINT | 1201 | DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n", |
1228 | ("get result error. Fdc=%d Last status=%x Read bytes=%d\n", | 1202 | fdc, status, i); |
1229 | fdc, status, i); | ||
1230 | show_floppy(); | 1203 | show_floppy(); |
1231 | } | 1204 | } |
1232 | FDCS->reset = 1; | 1205 | FDCS->reset = 1; |
@@ -1237,12 +1210,14 @@ static int result(void) | |||
1237 | /* does the fdc need more output? */ | 1210 | /* does the fdc need more output? */ |
1238 | static int need_more_output(void) | 1211 | static int need_more_output(void) |
1239 | { | 1212 | { |
1240 | int status; | 1213 | int status = wait_til_ready(); |
1241 | 1214 | ||
1242 | if ((status = wait_til_ready()) < 0) | 1215 | if (status < 0) |
1243 | return -1; | 1216 | return -1; |
1244 | if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY) | 1217 | |
1218 | if (is_ready_state(status)) | ||
1245 | return MORE_OUTPUT; | 1219 | return MORE_OUTPUT; |
1220 | |||
1246 | return result(); | 1221 | return result(); |
1247 | } | 1222 | } |
1248 | 1223 | ||
@@ -1264,9 +1239,12 @@ static inline void perpendicular_mode(void) | |||
1264 | default: | 1239 | default: |
1265 | DPRINT("Invalid data rate for perpendicular mode!\n"); | 1240 | DPRINT("Invalid data rate for perpendicular mode!\n"); |
1266 | cont->done(0); | 1241 | cont->done(0); |
1267 | FDCS->reset = 1; /* convenient way to return to | 1242 | FDCS->reset = 1; |
1268 | * redo without to much hassle (deep | 1243 | /* |
1269 | * stack et al. */ | 1244 | * convenient way to return to |
1245 | * redo without too much hassle | ||
1246 | * (deep stack et al.) | ||
1247 | */ | ||
1270 | return; | 1248 | return; |
1271 | } | 1249 | } |
1272 | } else | 1250 | } else |
@@ -1366,9 +1344,9 @@ static void fdc_specify(void) | |||
1366 | 1344 | ||
1367 | /* Convert step rate from microseconds to milliseconds and 4 bits */ | 1345 | /* Convert step rate from microseconds to milliseconds and 4 bits */ |
1368 | srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); | 1346 | srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); |
1369 | if (slow_floppy) { | 1347 | if (slow_floppy) |
1370 | srt = srt / 4; | 1348 | srt = srt / 4; |
1371 | } | 1349 | |
1372 | SUPBOUND(srt, 0xf); | 1350 | SUPBOUND(srt, 0xf); |
1373 | INFBOUND(srt, 0); | 1351 | INFBOUND(srt, 0); |
1374 | 1352 | ||
@@ -1415,16 +1393,46 @@ static int fdc_dtr(void) | |||
1415 | * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) | 1393 | * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) |
1416 | */ | 1394 | */ |
1417 | FDCS->dtr = raw_cmd->rate & 3; | 1395 | FDCS->dtr = raw_cmd->rate & 3; |
1418 | return (fd_wait_for_completion(jiffies + 2UL * HZ / 100, | 1396 | return fd_wait_for_completion(jiffies + 2UL * HZ / 100, |
1419 | (timeout_fn) floppy_ready)); | 1397 | (timeout_fn)floppy_ready); |
1420 | } /* fdc_dtr */ | 1398 | } /* fdc_dtr */ |
1421 | 1399 | ||
1422 | static void tell_sector(void) | 1400 | static void tell_sector(void) |
1423 | { | 1401 | { |
1424 | printk(": track %d, head %d, sector %d, size %d", | 1402 | pr_cont(": track %d, head %d, sector %d, size %d", |
1425 | R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); | 1403 | R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE); |
1426 | } /* tell_sector */ | 1404 | } /* tell_sector */ |
1427 | 1405 | ||
1406 | static void print_errors(void) | ||
1407 | { | ||
1408 | DPRINT(""); | ||
1409 | if (ST0 & ST0_ECE) { | ||
1410 | pr_cont("Recalibrate failed!"); | ||
1411 | } else if (ST2 & ST2_CRC) { | ||
1412 | pr_cont("data CRC error"); | ||
1413 | tell_sector(); | ||
1414 | } else if (ST1 & ST1_CRC) { | ||
1415 | pr_cont("CRC error"); | ||
1416 | tell_sector(); | ||
1417 | } else if ((ST1 & (ST1_MAM | ST1_ND)) || | ||
1418 | (ST2 & ST2_MAM)) { | ||
1419 | if (!probing) { | ||
1420 | pr_cont("sector not found"); | ||
1421 | tell_sector(); | ||
1422 | } else | ||
1423 | pr_cont("probe failed..."); | ||
1424 | } else if (ST2 & ST2_WC) { /* seek error */ | ||
1425 | pr_cont("wrong cylinder"); | ||
1426 | } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ | ||
1427 | pr_cont("bad cylinder"); | ||
1428 | } else { | ||
1429 | pr_cont("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", | ||
1430 | ST0, ST1, ST2); | ||
1431 | tell_sector(); | ||
1432 | } | ||
1433 | pr_cont("\n"); | ||
1434 | } | ||
1435 | |||
1428 | /* | 1436 | /* |
1429 | * OK, this error interpreting routine is called after a | 1437 | * OK, this error interpreting routine is called after a |
1430 | * DMA read/write has succeeded | 1438 | * DMA read/write has succeeded |
@@ -1437,7 +1445,7 @@ static int interpret_errors(void) | |||
1437 | char bad; | 1445 | char bad; |
1438 | 1446 | ||
1439 | if (inr != 7) { | 1447 | if (inr != 7) { |
1440 | DPRINT("-- FDC reply error"); | 1448 | DPRINT("-- FDC reply error\n"); |
1441 | FDCS->reset = 1; | 1449 | FDCS->reset = 1; |
1442 | return 1; | 1450 | return 1; |
1443 | } | 1451 | } |
@@ -1450,43 +1458,17 @@ static int interpret_errors(void) | |||
1450 | bad = 1; | 1458 | bad = 1; |
1451 | if (ST1 & ST1_WP) { | 1459 | if (ST1 & ST1_WP) { |
1452 | DPRINT("Drive is write protected\n"); | 1460 | DPRINT("Drive is write protected\n"); |
1453 | CLEARF(FD_DISK_WRITABLE); | 1461 | clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1454 | cont->done(0); | 1462 | cont->done(0); |
1455 | bad = 2; | 1463 | bad = 2; |
1456 | } else if (ST1 & ST1_ND) { | 1464 | } else if (ST1 & ST1_ND) { |
1457 | SETF(FD_NEED_TWADDLE); | 1465 | set_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); |
1458 | } else if (ST1 & ST1_OR) { | 1466 | } else if (ST1 & ST1_OR) { |
1459 | if (DP->flags & FTD_MSG) | 1467 | if (DP->flags & FTD_MSG) |
1460 | DPRINT("Over/Underrun - retrying\n"); | 1468 | DPRINT("Over/Underrun - retrying\n"); |
1461 | bad = 0; | 1469 | bad = 0; |
1462 | } else if (*errors >= DP->max_errors.reporting) { | 1470 | } else if (*errors >= DP->max_errors.reporting) { |
1463 | DPRINT(""); | 1471 | print_errors(); |
1464 | if (ST0 & ST0_ECE) { | ||
1465 | printk("Recalibrate failed!"); | ||
1466 | } else if (ST2 & ST2_CRC) { | ||
1467 | printk("data CRC error"); | ||
1468 | tell_sector(); | ||
1469 | } else if (ST1 & ST1_CRC) { | ||
1470 | printk("CRC error"); | ||
1471 | tell_sector(); | ||
1472 | } else if ((ST1 & (ST1_MAM | ST1_ND)) | ||
1473 | || (ST2 & ST2_MAM)) { | ||
1474 | if (!probing) { | ||
1475 | printk("sector not found"); | ||
1476 | tell_sector(); | ||
1477 | } else | ||
1478 | printk("probe failed..."); | ||
1479 | } else if (ST2 & ST2_WC) { /* seek error */ | ||
1480 | printk("wrong cylinder"); | ||
1481 | } else if (ST2 & ST2_BC) { /* cylinder marked as bad */ | ||
1482 | printk("bad cylinder"); | ||
1483 | } else { | ||
1484 | printk | ||
1485 | ("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", | ||
1486 | ST0, ST1, ST2); | ||
1487 | tell_sector(); | ||
1488 | } | ||
1489 | printk("\n"); | ||
1490 | } | 1472 | } |
1491 | if (ST2 & ST2_WC || ST2 & ST2_BC) | 1473 | if (ST2 & ST2_WC || ST2 & ST2_BC) |
1492 | /* wrong cylinder => recal */ | 1474 | /* wrong cylinder => recal */ |
@@ -1531,9 +1513,9 @@ static void setup_rw_floppy(void) | |||
1531 | */ | 1513 | */ |
1532 | if (time_after(ready_date, jiffies + DP->select_delay)) { | 1514 | if (time_after(ready_date, jiffies + DP->select_delay)) { |
1533 | ready_date -= DP->select_delay; | 1515 | ready_date -= DP->select_delay; |
1534 | function = (timeout_fn) floppy_start; | 1516 | function = (timeout_fn)floppy_start; |
1535 | } else | 1517 | } else |
1536 | function = (timeout_fn) setup_rw_floppy; | 1518 | function = (timeout_fn)setup_rw_floppy; |
1537 | 1519 | ||
1538 | /* wait until the floppy is spinning fast enough */ | 1520 | /* wait until the floppy is spinning fast enough */ |
1539 | if (fd_wait_for_completion(ready_date, function)) | 1521 | if (fd_wait_for_completion(ready_date, function)) |
@@ -1551,7 +1533,7 @@ static void setup_rw_floppy(void) | |||
1551 | for (i = 0; i < raw_cmd->cmd_count; i++) | 1533 | for (i = 0; i < raw_cmd->cmd_count; i++) |
1552 | r |= output_byte(raw_cmd->cmd[i]); | 1534 | r |= output_byte(raw_cmd->cmd[i]); |
1553 | 1535 | ||
1554 | debugt("rw_command: "); | 1536 | debugt(__func__, "rw_command"); |
1555 | 1537 | ||
1556 | if (r) { | 1538 | if (r) { |
1557 | cont->error(); | 1539 | cont->error(); |
@@ -1574,7 +1556,7 @@ static int blind_seek; | |||
1574 | */ | 1556 | */ |
1575 | static void seek_interrupt(void) | 1557 | static void seek_interrupt(void) |
1576 | { | 1558 | { |
1577 | debugt("seek interrupt:"); | 1559 | debugt(__func__, ""); |
1578 | if (inr != 2 || (ST0 & 0xF8) != 0x20) { | 1560 | if (inr != 2 || (ST0 & 0xF8) != 0x20) { |
1579 | DPRINT("seek failed\n"); | 1561 | DPRINT("seek failed\n"); |
1580 | DRS->track = NEED_2_RECAL; | 1562 | DRS->track = NEED_2_RECAL; |
@@ -1583,14 +1565,11 @@ static void seek_interrupt(void) | |||
1583 | return; | 1565 | return; |
1584 | } | 1566 | } |
1585 | if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) { | 1567 | if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek) { |
1586 | #ifdef DCL_DEBUG | 1568 | debug_dcl(DP->flags, |
1587 | if (DP->flags & FD_DEBUG) { | 1569 | "clearing NEWCHANGE flag because of effective seek\n"); |
1588 | DPRINT | 1570 | debug_dcl(DP->flags, "jiffies=%lu\n", jiffies); |
1589 | ("clearing NEWCHANGE flag because of effective seek\n"); | 1571 | clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
1590 | DPRINT("jiffies=%lu\n", jiffies); | 1572 | /* effective seek */ |
1591 | } | ||
1592 | #endif | ||
1593 | CLEARF(FD_DISK_NEWCHANGE); /* effective seek */ | ||
1594 | DRS->select_date = jiffies; | 1573 | DRS->select_date = jiffies; |
1595 | } | 1574 | } |
1596 | DRS->track = ST1; | 1575 | DRS->track = ST1; |
@@ -1599,26 +1578,23 @@ static void seek_interrupt(void) | |||
1599 | 1578 | ||
1600 | static void check_wp(void) | 1579 | static void check_wp(void) |
1601 | { | 1580 | { |
1602 | if (TESTF(FD_VERIFY)) { | 1581 | if (test_bit(FD_VERIFY_BIT, &DRS->flags)) { |
1603 | /* check write protection */ | 1582 | /* check write protection */ |
1604 | output_byte(FD_GETSTATUS); | 1583 | output_byte(FD_GETSTATUS); |
1605 | output_byte(UNIT(current_drive)); | 1584 | output_byte(UNIT(current_drive)); |
1606 | if (result() != 1) { | 1585 | if (result() != 1) { |
1607 | FDCS->reset = 1; | 1586 | FDCS->reset = 1; |
1608 | return; | 1587 | return; |
1609 | } | 1588 | } |
1610 | CLEARF(FD_VERIFY); | 1589 | clear_bit(FD_VERIFY_BIT, &DRS->flags); |
1611 | CLEARF(FD_NEED_TWADDLE); | 1590 | clear_bit(FD_NEED_TWADDLE_BIT, &DRS->flags); |
1612 | #ifdef DCL_DEBUG | 1591 | debug_dcl(DP->flags, |
1613 | if (DP->flags & FD_DEBUG) { | 1592 | "checking whether disk is write protected\n"); |
1614 | DPRINT("checking whether disk is write protected\n"); | 1593 | debug_dcl(DP->flags, "wp=%x\n", ST3 & 0x40); |
1615 | DPRINT("wp=%x\n", ST3 & 0x40); | ||
1616 | } | ||
1617 | #endif | ||
1618 | if (!(ST3 & 0x40)) | 1594 | if (!(ST3 & 0x40)) |
1619 | SETF(FD_DISK_WRITABLE); | 1595 | set_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1620 | else | 1596 | else |
1621 | CLEARF(FD_DISK_WRITABLE); | 1597 | clear_bit(FD_DISK_WRITABLE_BIT, &DRS->flags); |
1622 | } | 1598 | } |
1623 | } | 1599 | } |
1624 | 1600 | ||
@@ -1628,19 +1604,15 @@ static void seek_floppy(void) | |||
1628 | 1604 | ||
1629 | blind_seek = 0; | 1605 | blind_seek = 0; |
1630 | 1606 | ||
1631 | #ifdef DCL_DEBUG | 1607 | debug_dcl(DP->flags, "calling disk change from %s\n", __func__); |
1632 | if (DP->flags & FD_DEBUG) { | ||
1633 | DPRINT("calling disk change from seek\n"); | ||
1634 | } | ||
1635 | #endif | ||
1636 | 1608 | ||
1637 | if (!TESTF(FD_DISK_NEWCHANGE) && | 1609 | if (!test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && |
1638 | disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { | 1610 | disk_change(current_drive) && (raw_cmd->flags & FD_RAW_NEED_DISK)) { |
1639 | /* the media changed flag should be cleared after the seek. | 1611 | /* the media changed flag should be cleared after the seek. |
1640 | * If it isn't, this means that there is really no disk in | 1612 | * If it isn't, this means that there is really no disk in |
1641 | * the drive. | 1613 | * the drive. |
1642 | */ | 1614 | */ |
1643 | SETF(FD_DISK_CHANGED); | 1615 | set_bit(FD_DISK_CHANGED_BIT, &DRS->flags); |
1644 | cont->done(0); | 1616 | cont->done(0); |
1645 | cont->redo(); | 1617 | cont->redo(); |
1646 | return; | 1618 | return; |
@@ -1648,7 +1620,7 @@ static void seek_floppy(void) | |||
1648 | if (DRS->track <= NEED_1_RECAL) { | 1620 | if (DRS->track <= NEED_1_RECAL) { |
1649 | recalibrate_floppy(); | 1621 | recalibrate_floppy(); |
1650 | return; | 1622 | return; |
1651 | } else if (TESTF(FD_DISK_NEWCHANGE) && | 1623 | } else if (test_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags) && |
1652 | (raw_cmd->flags & FD_RAW_NEED_DISK) && | 1624 | (raw_cmd->flags & FD_RAW_NEED_DISK) && |
1653 | (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { | 1625 | (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) { |
1654 | /* we seek to clear the media-changed condition. Does anybody | 1626 | /* we seek to clear the media-changed condition. Does anybody |
@@ -1677,19 +1649,22 @@ static void seek_floppy(void) | |||
1677 | do_floppy = seek_interrupt; | 1649 | do_floppy = seek_interrupt; |
1678 | output_byte(FD_SEEK); | 1650 | output_byte(FD_SEEK); |
1679 | output_byte(UNIT(current_drive)); | 1651 | output_byte(UNIT(current_drive)); |
1680 | LAST_OUT(track); | 1652 | if (output_byte(track) < 0) { |
1681 | debugt("seek command:"); | 1653 | reset_fdc(); |
1654 | return; | ||
1655 | } | ||
1656 | debugt(__func__, ""); | ||
1682 | } | 1657 | } |
1683 | 1658 | ||
1684 | static void recal_interrupt(void) | 1659 | static void recal_interrupt(void) |
1685 | { | 1660 | { |
1686 | debugt("recal interrupt:"); | 1661 | debugt(__func__, ""); |
1687 | if (inr != 2) | 1662 | if (inr != 2) |
1688 | FDCS->reset = 1; | 1663 | FDCS->reset = 1; |
1689 | else if (ST0 & ST0_ECE) { | 1664 | else if (ST0 & ST0_ECE) { |
1690 | switch (DRS->track) { | 1665 | switch (DRS->track) { |
1691 | case NEED_1_RECAL: | 1666 | case NEED_1_RECAL: |
1692 | debugt("recal interrupt need 1 recal:"); | 1667 | debugt(__func__, "need 1 recal"); |
1693 | /* after a second recalibrate, we still haven't | 1668 | /* after a second recalibrate, we still haven't |
1694 | * reached track 0. Probably no drive. Raise an | 1669 | * reached track 0. Probably no drive. Raise an |
1695 | * error, as failing immediately might upset | 1670 | * error, as failing immediately might upset |
@@ -1698,25 +1673,21 @@ static void recal_interrupt(void) | |||
1698 | cont->redo(); | 1673 | cont->redo(); |
1699 | return; | 1674 | return; |
1700 | case NEED_2_RECAL: | 1675 | case NEED_2_RECAL: |
1701 | debugt("recal interrupt need 2 recal:"); | 1676 | debugt(__func__, "need 2 recal"); |
1702 | /* If we already did a recalibrate, | 1677 | /* If we already did a recalibrate, |
1703 | * and we are not at track 0, this | 1678 | * and we are not at track 0, this |
1704 | * means we have moved. (The only way | 1679 | * means we have moved. (The only way |
1705 | * not to move at recalibration is to | 1680 | * not to move at recalibration is to |
1706 | * be already at track 0.) Clear the | 1681 | * be already at track 0.) Clear the |
1707 | * new change flag */ | 1682 | * new change flag */ |
1708 | #ifdef DCL_DEBUG | 1683 | debug_dcl(DP->flags, |
1709 | if (DP->flags & FD_DEBUG) { | 1684 | "clearing NEWCHANGE flag because of second recalibrate\n"); |
1710 | DPRINT | ||
1711 | ("clearing NEWCHANGE flag because of second recalibrate\n"); | ||
1712 | } | ||
1713 | #endif | ||
1714 | 1685 | ||
1715 | CLEARF(FD_DISK_NEWCHANGE); | 1686 | clear_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
1716 | DRS->select_date = jiffies; | 1687 | DRS->select_date = jiffies; |
1717 | /* fall through */ | 1688 | /* fall through */ |
1718 | default: | 1689 | default: |
1719 | debugt("recal interrupt default:"); | 1690 | debugt(__func__, "default"); |
1720 | /* Recalibrate moves the head by at | 1691 | /* Recalibrate moves the head by at |
1721 | * most 80 steps. If after one | 1692 | * most 80 steps. If after one |
1722 | * recalibrate we don't have reached | 1693 | * recalibrate we don't have reached |
@@ -1738,8 +1709,8 @@ static void print_result(char *message, int inr) | |||
1738 | DPRINT("%s ", message); | 1709 | DPRINT("%s ", message); |
1739 | if (inr >= 0) | 1710 | if (inr >= 0) |
1740 | for (i = 0; i < inr; i++) | 1711 | for (i = 0; i < inr; i++) |
1741 | printk("repl[%d]=%x ", i, reply_buffer[i]); | 1712 | pr_cont("repl[%d]=%x ", i, reply_buffer[i]); |
1742 | printk("\n"); | 1713 | pr_cont("\n"); |
1743 | } | 1714 | } |
1744 | 1715 | ||
1745 | /* interrupt handler. Note that this can be called externally on the Sparc */ | 1716 | /* interrupt handler. Note that this can be called externally on the Sparc */ |
@@ -1760,10 +1731,10 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1760 | do_floppy = NULL; | 1731 | do_floppy = NULL; |
1761 | if (fdc >= N_FDC || FDCS->address == -1) { | 1732 | if (fdc >= N_FDC || FDCS->address == -1) { |
1762 | /* we don't even know which FDC is the culprit */ | 1733 | /* we don't even know which FDC is the culprit */ |
1763 | printk("DOR0=%x\n", fdc_state[0].dor); | 1734 | pr_info("DOR0=%x\n", fdc_state[0].dor); |
1764 | printk("floppy interrupt on bizarre fdc %d\n", fdc); | 1735 | pr_info("floppy interrupt on bizarre fdc %d\n", fdc); |
1765 | printk("handler=%p\n", handler); | 1736 | pr_info("handler=%pf\n", handler); |
1766 | is_alive("bizarre fdc"); | 1737 | is_alive(__func__, "bizarre fdc"); |
1767 | return IRQ_NONE; | 1738 | return IRQ_NONE; |
1768 | } | 1739 | } |
1769 | 1740 | ||
@@ -1777,7 +1748,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1777 | * activity. | 1748 | * activity. |
1778 | */ | 1749 | */ |
1779 | 1750 | ||
1780 | do_print = !handler && print_unex && !initialising; | 1751 | do_print = !handler && print_unex && initialized; |
1781 | 1752 | ||
1782 | inr = result(); | 1753 | inr = result(); |
1783 | if (do_print) | 1754 | if (do_print) |
@@ -1790,15 +1761,15 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1790 | if (do_print) | 1761 | if (do_print) |
1791 | print_result("sensei", inr); | 1762 | print_result("sensei", inr); |
1792 | max_sensei--; | 1763 | max_sensei--; |
1793 | } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2 | 1764 | } while ((ST0 & 0x83) != UNIT(current_drive) && |
1794 | && max_sensei); | 1765 | inr == 2 && max_sensei); |
1795 | } | 1766 | } |
1796 | if (!handler) { | 1767 | if (!handler) { |
1797 | FDCS->reset = 1; | 1768 | FDCS->reset = 1; |
1798 | return IRQ_NONE; | 1769 | return IRQ_NONE; |
1799 | } | 1770 | } |
1800 | schedule_bh(handler); | 1771 | schedule_bh(handler); |
1801 | is_alive("normal interrupt end"); | 1772 | is_alive(__func__, "normal interrupt end"); |
1802 | 1773 | ||
1803 | /* FIXME! Was it really for us? */ | 1774 | /* FIXME! Was it really for us? */ |
1804 | return IRQ_HANDLED; | 1775 | return IRQ_HANDLED; |
@@ -1806,10 +1777,11 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) | |||
1806 | 1777 | ||
1807 | static void recalibrate_floppy(void) | 1778 | static void recalibrate_floppy(void) |
1808 | { | 1779 | { |
1809 | debugt("recalibrate floppy:"); | 1780 | debugt(__func__, ""); |
1810 | do_floppy = recal_interrupt; | 1781 | do_floppy = recal_interrupt; |
1811 | output_byte(FD_RECALIBRATE); | 1782 | output_byte(FD_RECALIBRATE); |
1812 | LAST_OUT(UNIT(current_drive)); | 1783 | if (output_byte(UNIT(current_drive)) < 0) |
1784 | reset_fdc(); | ||
1813 | } | 1785 | } |
1814 | 1786 | ||
1815 | /* | 1787 | /* |
@@ -1817,10 +1789,10 @@ static void recalibrate_floppy(void) | |||
1817 | */ | 1789 | */ |
1818 | static void reset_interrupt(void) | 1790 | static void reset_interrupt(void) |
1819 | { | 1791 | { |
1820 | debugt("reset interrupt:"); | 1792 | debugt(__func__, ""); |
1821 | result(); /* get the status ready for set_fdc */ | 1793 | result(); /* get the status ready for set_fdc */ |
1822 | if (FDCS->reset) { | 1794 | if (FDCS->reset) { |
1823 | printk("reset set in interrupt, calling %p\n", cont->error); | 1795 | pr_info("reset set in interrupt, calling %pf\n", cont->error); |
1824 | cont->error(); /* a reset just after a reset. BAD! */ | 1796 | cont->error(); /* a reset just after a reset. BAD! */ |
1825 | } | 1797 | } |
1826 | cont->redo(); | 1798 | cont->redo(); |
@@ -1858,53 +1830,49 @@ static void show_floppy(void) | |||
1858 | { | 1830 | { |
1859 | int i; | 1831 | int i; |
1860 | 1832 | ||
1861 | printk("\n"); | 1833 | pr_info("\n"); |
1862 | printk("floppy driver state\n"); | 1834 | pr_info("floppy driver state\n"); |
1863 | printk("-------------------\n"); | 1835 | pr_info("-------------------\n"); |
1864 | printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n", | 1836 | pr_info("now=%lu last interrupt=%lu diff=%lu last called handler=%pf\n", |
1865 | jiffies, interruptjiffies, jiffies - interruptjiffies, | 1837 | jiffies, interruptjiffies, jiffies - interruptjiffies, |
1866 | lasthandler); | 1838 | lasthandler); |
1867 | 1839 | ||
1868 | #ifdef FLOPPY_SANITY_CHECK | 1840 | pr_info("timeout_message=%s\n", timeout_message); |
1869 | printk("timeout_message=%s\n", timeout_message); | 1841 | pr_info("last output bytes:\n"); |
1870 | printk("last output bytes:\n"); | ||
1871 | for (i = 0; i < OLOGSIZE; i++) | 1842 | for (i = 0; i < OLOGSIZE; i++) |
1872 | printk("%2x %2x %lu\n", | 1843 | pr_info("%2x %2x %lu\n", |
1873 | output_log[(i + output_log_pos) % OLOGSIZE].data, | 1844 | output_log[(i + output_log_pos) % OLOGSIZE].data, |
1874 | output_log[(i + output_log_pos) % OLOGSIZE].status, | 1845 | output_log[(i + output_log_pos) % OLOGSIZE].status, |
1875 | output_log[(i + output_log_pos) % OLOGSIZE].jiffies); | 1846 | output_log[(i + output_log_pos) % OLOGSIZE].jiffies); |
1876 | printk("last result at %lu\n", resultjiffies); | 1847 | pr_info("last result at %lu\n", resultjiffies); |
1877 | printk("last redo_fd_request at %lu\n", lastredo); | 1848 | pr_info("last redo_fd_request at %lu\n", lastredo); |
1878 | for (i = 0; i < resultsize; i++) { | 1849 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, |
1879 | printk("%2x ", reply_buffer[i]); | 1850 | reply_buffer, resultsize, true); |
1880 | } | 1851 | |
1881 | printk("\n"); | 1852 | pr_info("status=%x\n", fd_inb(FD_STATUS)); |
1882 | #endif | 1853 | pr_info("fdc_busy=%lu\n", fdc_busy); |
1883 | |||
1884 | printk("status=%x\n", fd_inb(FD_STATUS)); | ||
1885 | printk("fdc_busy=%lu\n", fdc_busy); | ||
1886 | if (do_floppy) | 1854 | if (do_floppy) |
1887 | printk("do_floppy=%p\n", do_floppy); | 1855 | pr_info("do_floppy=%pf\n", do_floppy); |
1888 | if (work_pending(&floppy_work)) | 1856 | if (work_pending(&floppy_work)) |
1889 | printk("floppy_work.func=%p\n", floppy_work.func); | 1857 | pr_info("floppy_work.func=%pf\n", floppy_work.func); |
1890 | if (timer_pending(&fd_timer)) | 1858 | if (timer_pending(&fd_timer)) |
1891 | printk("fd_timer.function=%p\n", fd_timer.function); | 1859 | pr_info("fd_timer.function=%pf\n", fd_timer.function); |
1892 | if (timer_pending(&fd_timeout)) { | 1860 | if (timer_pending(&fd_timeout)) { |
1893 | printk("timer_function=%p\n", fd_timeout.function); | 1861 | pr_info("timer_function=%pf\n", fd_timeout.function); |
1894 | printk("expires=%lu\n", fd_timeout.expires - jiffies); | 1862 | pr_info("expires=%lu\n", fd_timeout.expires - jiffies); |
1895 | printk("now=%lu\n", jiffies); | 1863 | pr_info("now=%lu\n", jiffies); |
1896 | } | 1864 | } |
1897 | printk("cont=%p\n", cont); | 1865 | pr_info("cont=%p\n", cont); |
1898 | printk("current_req=%p\n", current_req); | 1866 | pr_info("current_req=%p\n", current_req); |
1899 | printk("command_status=%d\n", command_status); | 1867 | pr_info("command_status=%d\n", command_status); |
1900 | printk("\n"); | 1868 | pr_info("\n"); |
1901 | } | 1869 | } |
1902 | 1870 | ||
1903 | static void floppy_shutdown(unsigned long data) | 1871 | static void floppy_shutdown(unsigned long data) |
1904 | { | 1872 | { |
1905 | unsigned long flags; | 1873 | unsigned long flags; |
1906 | 1874 | ||
1907 | if (!initialising) | 1875 | if (initialized) |
1908 | show_floppy(); | 1876 | show_floppy(); |
1909 | cancel_activity(); | 1877 | cancel_activity(); |
1910 | 1878 | ||
@@ -1916,17 +1884,17 @@ static void floppy_shutdown(unsigned long data) | |||
1916 | 1884 | ||
1917 | /* avoid dma going to a random drive after shutdown */ | 1885 | /* avoid dma going to a random drive after shutdown */ |
1918 | 1886 | ||
1919 | if (!initialising) | 1887 | if (initialized) |
1920 | DPRINT("floppy timeout called\n"); | 1888 | DPRINT("floppy timeout called\n"); |
1921 | FDCS->reset = 1; | 1889 | FDCS->reset = 1; |
1922 | if (cont) { | 1890 | if (cont) { |
1923 | cont->done(0); | 1891 | cont->done(0); |
1924 | cont->redo(); /* this will recall reset when needed */ | 1892 | cont->redo(); /* this will recall reset when needed */ |
1925 | } else { | 1893 | } else { |
1926 | printk("no cont in shutdown!\n"); | 1894 | pr_info("no cont in shutdown!\n"); |
1927 | process_fd_request(); | 1895 | process_fd_request(); |
1928 | } | 1896 | } |
1929 | is_alive("floppy shutdown"); | 1897 | is_alive(__func__, ""); |
1930 | } | 1898 | } |
1931 | 1899 | ||
1932 | /* start motor, check media-changed condition and write protection */ | 1900 | /* start motor, check media-changed condition and write protection */ |
@@ -1954,27 +1922,26 @@ static int start_motor(void (*function)(void)) | |||
1954 | set_dor(fdc, mask, data); | 1922 | set_dor(fdc, mask, data); |
1955 | 1923 | ||
1956 | /* wait_for_completion also schedules reset if needed. */ | 1924 | /* wait_for_completion also schedules reset if needed. */ |
1957 | return (fd_wait_for_completion(DRS->select_date + DP->select_delay, | 1925 | return fd_wait_for_completion(DRS->select_date + DP->select_delay, |
1958 | (timeout_fn) function)); | 1926 | (timeout_fn)function); |
1959 | } | 1927 | } |
1960 | 1928 | ||
1961 | static void floppy_ready(void) | 1929 | static void floppy_ready(void) |
1962 | { | 1930 | { |
1963 | CHECK_RESET; | 1931 | if (FDCS->reset) { |
1932 | reset_fdc(); | ||
1933 | return; | ||
1934 | } | ||
1964 | if (start_motor(floppy_ready)) | 1935 | if (start_motor(floppy_ready)) |
1965 | return; | 1936 | return; |
1966 | if (fdc_dtr()) | 1937 | if (fdc_dtr()) |
1967 | return; | 1938 | return; |
1968 | 1939 | ||
1969 | #ifdef DCL_DEBUG | 1940 | debug_dcl(DP->flags, "calling disk change from floppy_ready\n"); |
1970 | if (DP->flags & FD_DEBUG) { | ||
1971 | DPRINT("calling disk change from floppy_ready\n"); | ||
1972 | } | ||
1973 | #endif | ||
1974 | if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && | 1941 | if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) && |
1975 | disk_change(current_drive) && !DP->select_delay) | 1942 | disk_change(current_drive) && !DP->select_delay) |
1976 | twaddle(); /* this clears the dcl on certain drive/controller | 1943 | twaddle(); /* this clears the dcl on certain |
1977 | * combinations */ | 1944 | * drive/controller combinations */ |
1978 | 1945 | ||
1979 | #ifdef fd_chose_dma_mode | 1946 | #ifdef fd_chose_dma_mode |
1980 | if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { | 1947 | if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) { |
@@ -1998,15 +1965,11 @@ static void floppy_ready(void) | |||
1998 | 1965 | ||
1999 | static void floppy_start(void) | 1966 | static void floppy_start(void) |
2000 | { | 1967 | { |
2001 | reschedule_timeout(current_reqD, "floppy start", 0); | 1968 | reschedule_timeout(current_reqD, "floppy start"); |
2002 | 1969 | ||
2003 | scandrives(); | 1970 | scandrives(); |
2004 | #ifdef DCL_DEBUG | 1971 | debug_dcl(DP->flags, "setting NEWCHANGE in floppy_start\n"); |
2005 | if (DP->flags & FD_DEBUG) { | 1972 | set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
2006 | DPRINT("setting NEWCHANGE in floppy_start\n"); | ||
2007 | } | ||
2008 | #endif | ||
2009 | SETF(FD_DISK_NEWCHANGE); | ||
2010 | floppy_ready(); | 1973 | floppy_ready(); |
2011 | } | 1974 | } |
2012 | 1975 | ||
@@ -2026,7 +1989,7 @@ static void floppy_start(void) | |||
2026 | 1989 | ||
2027 | static void do_wakeup(void) | 1990 | static void do_wakeup(void) |
2028 | { | 1991 | { |
2029 | reschedule_timeout(MAXTIMEOUT, "do wakeup", 0); | 1992 | reschedule_timeout(MAXTIMEOUT, "do wakeup"); |
2030 | cont = NULL; | 1993 | cont = NULL; |
2031 | command_status += 2; | 1994 | command_status += 2; |
2032 | wake_up(&command_done); | 1995 | wake_up(&command_done); |
@@ -2046,7 +2009,7 @@ static struct cont_t intr_cont = { | |||
2046 | .done = (done_f)empty | 2009 | .done = (done_f)empty |
2047 | }; | 2010 | }; |
2048 | 2011 | ||
2049 | static int wait_til_done(void (*handler)(void), int interruptible) | 2012 | static int wait_til_done(void (*handler)(void), bool interruptible) |
2050 | { | 2013 | { |
2051 | int ret; | 2014 | int ret; |
2052 | 2015 | ||
@@ -2064,7 +2027,7 @@ static int wait_til_done(void (*handler)(void), int interruptible) | |||
2064 | if (command_status >= 2 || !NO_SIGNAL) | 2027 | if (command_status >= 2 || !NO_SIGNAL) |
2065 | break; | 2028 | break; |
2066 | 2029 | ||
2067 | is_alive("wait_til_done"); | 2030 | is_alive(__func__, ""); |
2068 | schedule(); | 2031 | schedule(); |
2069 | } | 2032 | } |
2070 | 2033 | ||
@@ -2180,9 +2143,9 @@ static void format_interrupt(void) | |||
2180 | cont->redo(); | 2143 | cont->redo(); |
2181 | } | 2144 | } |
2182 | 2145 | ||
2183 | #define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2) | 2146 | #define FM_MODE(x, y) ((y) & ~(((x)->rate & 0x80) >> 1)) |
2184 | #define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1)) | ||
2185 | #define CT(x) ((x) | 0xc0) | 2147 | #define CT(x) ((x) | 0xc0) |
2148 | |||
2186 | static void setup_format_params(int track) | 2149 | static void setup_format_params(int track) |
2187 | { | 2150 | { |
2188 | int n; | 2151 | int n; |
@@ -2197,8 +2160,8 @@ static void setup_format_params(int track) | |||
2197 | raw_cmd = &default_raw_cmd; | 2160 | raw_cmd = &default_raw_cmd; |
2198 | raw_cmd->track = track; | 2161 | raw_cmd->track = track; |
2199 | 2162 | ||
2200 | raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | | 2163 | raw_cmd->flags = (FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN | |
2201 | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; | 2164 | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK); |
2202 | raw_cmd->rate = _floppy->rate & 0x43; | 2165 | raw_cmd->rate = _floppy->rate & 0x43; |
2203 | raw_cmd->cmd_count = NR_F; | 2166 | raw_cmd->cmd_count = NR_F; |
2204 | COMMAND = FM_MODE(_floppy, FD_FORMAT); | 2167 | COMMAND = FM_MODE(_floppy, FD_FORMAT); |
@@ -2257,7 +2220,7 @@ static void redo_format(void) | |||
2257 | buffer_track = -1; | 2220 | buffer_track = -1; |
2258 | setup_format_params(format_req.track << STRETCH(_floppy)); | 2221 | setup_format_params(format_req.track << STRETCH(_floppy)); |
2259 | floppy_start(); | 2222 | floppy_start(); |
2260 | debugt("queue format request"); | 2223 | debugt(__func__, "queue format request"); |
2261 | } | 2224 | } |
2262 | 2225 | ||
2263 | static struct cont_t format_cont = { | 2226 | static struct cont_t format_cont = { |
@@ -2271,7 +2234,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) | |||
2271 | { | 2234 | { |
2272 | int ret; | 2235 | int ret; |
2273 | 2236 | ||
2274 | LOCK_FDC(drive, 1); | 2237 | if (lock_fdc(drive, true)) |
2238 | return -EINTR; | ||
2239 | |||
2275 | set_floppy(drive); | 2240 | set_floppy(drive); |
2276 | if (!_floppy || | 2241 | if (!_floppy || |
2277 | _floppy->track > DP->tracks || | 2242 | _floppy->track > DP->tracks || |
@@ -2286,7 +2251,9 @@ static int do_format(int drive, struct format_descr *tmp_format_req) | |||
2286 | format_errors = 0; | 2251 | format_errors = 0; |
2287 | cont = &format_cont; | 2252 | cont = &format_cont; |
2288 | errors = &format_errors; | 2253 | errors = &format_errors; |
2289 | IWAIT(redo_format); | 2254 | ret = wait_til_done(redo_format, true); |
2255 | if (ret == -EINTR) | ||
2256 | return -EINTR; | ||
2290 | process_fd_request(); | 2257 | process_fd_request(); |
2291 | return ret; | 2258 | return ret; |
2292 | } | 2259 | } |
@@ -2320,12 +2287,14 @@ static void request_done(int uptodate) | |||
2320 | struct request *req = current_req; | 2287 | struct request *req = current_req; |
2321 | unsigned long flags; | 2288 | unsigned long flags; |
2322 | int block; | 2289 | int block; |
2290 | char msg[sizeof("request done ") + sizeof(int) * 3]; | ||
2323 | 2291 | ||
2324 | probing = 0; | 2292 | probing = 0; |
2325 | reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate); | 2293 | snprintf(msg, sizeof(msg), "request done %d", uptodate); |
2294 | reschedule_timeout(MAXTIMEOUT, msg); | ||
2326 | 2295 | ||
2327 | if (!req) { | 2296 | if (!req) { |
2328 | printk("floppy.c: no request in request_done\n"); | 2297 | pr_info("floppy.c: no request in request_done\n"); |
2329 | return; | 2298 | return; |
2330 | } | 2299 | } |
2331 | 2300 | ||
@@ -2377,7 +2346,7 @@ static void rw_interrupt(void) | |||
2377 | DRS->first_read_date = jiffies; | 2346 | DRS->first_read_date = jiffies; |
2378 | 2347 | ||
2379 | nr_sectors = 0; | 2348 | nr_sectors = 0; |
2380 | CODE2SIZE; | 2349 | ssize = DIV_ROUND_UP(1 << SIZECODE, 4); |
2381 | 2350 | ||
2382 | if (ST1 & ST1_EOC) | 2351 | if (ST1 & ST1_EOC) |
2383 | eoc = 1; | 2352 | eoc = 1; |
@@ -2393,20 +2362,18 @@ static void rw_interrupt(void) | |||
2393 | R_HEAD - HEAD) * SECT_PER_TRACK + | 2362 | R_HEAD - HEAD) * SECT_PER_TRACK + |
2394 | R_SECTOR - SECTOR + eoc) << SIZECODE >> 2; | 2363 | R_SECTOR - SECTOR + eoc) << SIZECODE >> 2; |
2395 | 2364 | ||
2396 | #ifdef FLOPPY_SANITY_CHECK | ||
2397 | if (nr_sectors / ssize > | 2365 | if (nr_sectors / ssize > |
2398 | DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) { | 2366 | DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) { |
2399 | DPRINT("long rw: %x instead of %lx\n", | 2367 | DPRINT("long rw: %x instead of %lx\n", |
2400 | nr_sectors, current_count_sectors); | 2368 | nr_sectors, current_count_sectors); |
2401 | printk("rs=%d s=%d\n", R_SECTOR, SECTOR); | 2369 | pr_info("rs=%d s=%d\n", R_SECTOR, SECTOR); |
2402 | printk("rh=%d h=%d\n", R_HEAD, HEAD); | 2370 | pr_info("rh=%d h=%d\n", R_HEAD, HEAD); |
2403 | printk("rt=%d t=%d\n", R_TRACK, TRACK); | 2371 | pr_info("rt=%d t=%d\n", R_TRACK, TRACK); |
2404 | printk("heads=%d eoc=%d\n", heads, eoc); | 2372 | pr_info("heads=%d eoc=%d\n", heads, eoc); |
2405 | printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK, | 2373 | pr_info("spt=%d st=%d ss=%d\n", |
2406 | fsector_t, ssize); | 2374 | SECT_PER_TRACK, fsector_t, ssize); |
2407 | printk("in_sector_offset=%d\n", in_sector_offset); | 2375 | pr_info("in_sector_offset=%d\n", in_sector_offset); |
2408 | } | 2376 | } |
2409 | #endif | ||
2410 | 2377 | ||
2411 | nr_sectors -= in_sector_offset; | 2378 | nr_sectors -= in_sector_offset; |
2412 | INFBOUND(nr_sectors, 0); | 2379 | INFBOUND(nr_sectors, 0); |
@@ -2511,19 +2478,17 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2511 | blk_rq_sectors(current_req)); | 2478 | blk_rq_sectors(current_req)); |
2512 | 2479 | ||
2513 | remaining = current_count_sectors << 9; | 2480 | remaining = current_count_sectors << 9; |
2514 | #ifdef FLOPPY_SANITY_CHECK | ||
2515 | if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) { | 2481 | if (remaining > blk_rq_bytes(current_req) && CT(COMMAND) == FD_WRITE) { |
2516 | DPRINT("in copy buffer\n"); | 2482 | DPRINT("in copy buffer\n"); |
2517 | printk("current_count_sectors=%ld\n", current_count_sectors); | 2483 | pr_info("current_count_sectors=%ld\n", current_count_sectors); |
2518 | printk("remaining=%d\n", remaining >> 9); | 2484 | pr_info("remaining=%d\n", remaining >> 9); |
2519 | printk("current_req->nr_sectors=%u\n", | 2485 | pr_info("current_req->nr_sectors=%u\n", |
2520 | blk_rq_sectors(current_req)); | 2486 | blk_rq_sectors(current_req)); |
2521 | printk("current_req->current_nr_sectors=%u\n", | 2487 | pr_info("current_req->current_nr_sectors=%u\n", |
2522 | blk_rq_cur_sectors(current_req)); | 2488 | blk_rq_cur_sectors(current_req)); |
2523 | printk("max_sector=%d\n", max_sector); | 2489 | pr_info("max_sector=%d\n", max_sector); |
2524 | printk("ssize=%d\n", ssize); | 2490 | pr_info("ssize=%d\n", ssize); |
2525 | } | 2491 | } |
2526 | #endif | ||
2527 | 2492 | ||
2528 | buffer_max = max(max_sector, buffer_max); | 2493 | buffer_max = max(max_sector, buffer_max); |
2529 | 2494 | ||
@@ -2539,26 +2504,24 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2539 | SUPBOUND(size, remaining); | 2504 | SUPBOUND(size, remaining); |
2540 | 2505 | ||
2541 | buffer = page_address(bv->bv_page) + bv->bv_offset; | 2506 | buffer = page_address(bv->bv_page) + bv->bv_offset; |
2542 | #ifdef FLOPPY_SANITY_CHECK | ||
2543 | if (dma_buffer + size > | 2507 | if (dma_buffer + size > |
2544 | floppy_track_buffer + (max_buffer_sectors << 10) || | 2508 | floppy_track_buffer + (max_buffer_sectors << 10) || |
2545 | dma_buffer < floppy_track_buffer) { | 2509 | dma_buffer < floppy_track_buffer) { |
2546 | DPRINT("buffer overrun in copy buffer %d\n", | 2510 | DPRINT("buffer overrun in copy buffer %d\n", |
2547 | (int)((floppy_track_buffer - | 2511 | (int)((floppy_track_buffer - dma_buffer) >> 9)); |
2548 | dma_buffer) >> 9)); | 2512 | pr_info("fsector_t=%d buffer_min=%d\n", |
2549 | printk("fsector_t=%d buffer_min=%d\n", | 2513 | fsector_t, buffer_min); |
2550 | fsector_t, buffer_min); | 2514 | pr_info("current_count_sectors=%ld\n", |
2551 | printk("current_count_sectors=%ld\n", | 2515 | current_count_sectors); |
2552 | current_count_sectors); | ||
2553 | if (CT(COMMAND) == FD_READ) | 2516 | if (CT(COMMAND) == FD_READ) |
2554 | printk("read\n"); | 2517 | pr_info("read\n"); |
2555 | if (CT(COMMAND) == FD_WRITE) | 2518 | if (CT(COMMAND) == FD_WRITE) |
2556 | printk("write\n"); | 2519 | pr_info("write\n"); |
2557 | break; | 2520 | break; |
2558 | } | 2521 | } |
2559 | if (((unsigned long)buffer) % 512) | 2522 | if (((unsigned long)buffer) % 512) |
2560 | DPRINT("%p buffer not aligned\n", buffer); | 2523 | DPRINT("%p buffer not aligned\n", buffer); |
2561 | #endif | 2524 | |
2562 | if (CT(COMMAND) == FD_READ) | 2525 | if (CT(COMMAND) == FD_READ) |
2563 | memcpy(buffer, dma_buffer, size); | 2526 | memcpy(buffer, dma_buffer, size); |
2564 | else | 2527 | else |
@@ -2567,13 +2530,11 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2) | |||
2567 | remaining -= size; | 2530 | remaining -= size; |
2568 | dma_buffer += size; | 2531 | dma_buffer += size; |
2569 | } | 2532 | } |
2570 | #ifdef FLOPPY_SANITY_CHECK | ||
2571 | if (remaining) { | 2533 | if (remaining) { |
2572 | if (remaining > 0) | 2534 | if (remaining > 0) |
2573 | max_sector -= remaining >> 9; | 2535 | max_sector -= remaining >> 9; |
2574 | DPRINT("weirdness: remaining %d\n", remaining >> 9); | 2536 | DPRINT("weirdness: remaining %d\n", remaining >> 9); |
2575 | } | 2537 | } |
2576 | #endif | ||
2577 | } | 2538 | } |
2578 | 2539 | ||
2579 | /* work around a bug in pseudo DMA | 2540 | /* work around a bug in pseudo DMA |
@@ -2593,15 +2554,14 @@ static void virtualdmabug_workaround(void) | |||
2593 | 2554 | ||
2594 | hard_sectors = raw_cmd->length >> (7 + SIZECODE); | 2555 | hard_sectors = raw_cmd->length >> (7 + SIZECODE); |
2595 | end_sector = SECTOR + hard_sectors - 1; | 2556 | end_sector = SECTOR + hard_sectors - 1; |
2596 | #ifdef FLOPPY_SANITY_CHECK | ||
2597 | if (end_sector > SECT_PER_TRACK) { | 2557 | if (end_sector > SECT_PER_TRACK) { |
2598 | printk("too many sectors %d > %d\n", | 2558 | pr_info("too many sectors %d > %d\n", |
2599 | end_sector, SECT_PER_TRACK); | 2559 | end_sector, SECT_PER_TRACK); |
2600 | return; | 2560 | return; |
2601 | } | 2561 | } |
2602 | #endif | 2562 | SECT_PER_TRACK = end_sector; |
2603 | SECT_PER_TRACK = end_sector; /* make sure SECT_PER_TRACK points | 2563 | /* make sure SECT_PER_TRACK |
2604 | * to end of transfer */ | 2564 | * points to end of transfer */ |
2605 | } | 2565 | } |
2606 | } | 2566 | } |
2607 | 2567 | ||
@@ -2624,7 +2584,7 @@ static int make_raw_rw_request(void) | |||
2624 | int ssize; | 2584 | int ssize; |
2625 | 2585 | ||
2626 | if (max_buffer_sectors == 0) { | 2586 | if (max_buffer_sectors == 0) { |
2627 | printk("VFS: Block I/O scheduled on unopened device\n"); | 2587 | pr_info("VFS: Block I/O scheduled on unopened device\n"); |
2628 | return 0; | 2588 | return 0; |
2629 | } | 2589 | } |
2630 | 2590 | ||
@@ -2641,7 +2601,7 @@ static int make_raw_rw_request(void) | |||
2641 | raw_cmd->flags |= FD_RAW_WRITE; | 2601 | raw_cmd->flags |= FD_RAW_WRITE; |
2642 | COMMAND = FM_MODE(_floppy, FD_WRITE); | 2602 | COMMAND = FM_MODE(_floppy, FD_WRITE); |
2643 | } else { | 2603 | } else { |
2644 | DPRINT("make_raw_rw_request: unknown command\n"); | 2604 | DPRINT("%s: unknown command\n", __func__); |
2645 | return 0; | 2605 | return 0; |
2646 | } | 2606 | } |
2647 | 2607 | ||
@@ -2659,7 +2619,8 @@ static int make_raw_rw_request(void) | |||
2659 | HEAD = fsector_t / _floppy->sect; | 2619 | HEAD = fsector_t / _floppy->sect; |
2660 | 2620 | ||
2661 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || | 2621 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || |
2662 | TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) | 2622 | test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) && |
2623 | fsector_t < _floppy->sect) | ||
2663 | max_sector = _floppy->sect; | 2624 | max_sector = _floppy->sect; |
2664 | 2625 | ||
2665 | /* 2M disks have phantom sectors on the first track */ | 2626 | /* 2M disks have phantom sectors on the first track */ |
@@ -2685,7 +2646,7 @@ static int make_raw_rw_request(void) | |||
2685 | raw_cmd->track = TRACK << STRETCH(_floppy); | 2646 | raw_cmd->track = TRACK << STRETCH(_floppy); |
2686 | DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD); | 2647 | DR_SELECT = UNIT(current_drive) + PH_HEAD(_floppy, HEAD); |
2687 | GAP = _floppy->gap; | 2648 | GAP = _floppy->gap; |
2688 | CODE2SIZE; | 2649 | ssize = DIV_ROUND_UP(1 << SIZECODE, 4); |
2689 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; | 2650 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; |
2690 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + | 2651 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + |
2691 | FD_SECTBASE(_floppy); | 2652 | FD_SECTBASE(_floppy); |
@@ -2730,8 +2691,10 @@ static int make_raw_rw_request(void) | |||
2730 | } | 2691 | } |
2731 | } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) { | 2692 | } else if (in_sector_offset || blk_rq_sectors(current_req) < ssize) { |
2732 | if (CT(COMMAND) == FD_WRITE) { | 2693 | if (CT(COMMAND) == FD_WRITE) { |
2733 | if (fsector_t + blk_rq_sectors(current_req) > ssize && | 2694 | unsigned int sectors; |
2734 | fsector_t + blk_rq_sectors(current_req) < ssize + ssize) | 2695 | |
2696 | sectors = fsector_t + blk_rq_sectors(current_req); | ||
2697 | if (sectors > ssize && sectors < ssize + ssize) | ||
2735 | max_size = ssize + ssize; | 2698 | max_size = ssize + ssize; |
2736 | else | 2699 | else |
2737 | max_size = ssize; | 2700 | max_size = ssize; |
@@ -2752,12 +2715,10 @@ static int make_raw_rw_request(void) | |||
2752 | * on a 64 bit machine! | 2715 | * on a 64 bit machine! |
2753 | */ | 2716 | */ |
2754 | max_size = buffer_chain_size(); | 2717 | max_size = buffer_chain_size(); |
2755 | dma_limit = | 2718 | dma_limit = (MAX_DMA_ADDRESS - |
2756 | (MAX_DMA_ADDRESS - | 2719 | ((unsigned long)current_req->buffer)) >> 9; |
2757 | ((unsigned long)current_req->buffer)) >> 9; | 2720 | if ((unsigned long)max_size > dma_limit) |
2758 | if ((unsigned long)max_size > dma_limit) { | ||
2759 | max_size = dma_limit; | 2721 | max_size = dma_limit; |
2760 | } | ||
2761 | /* 64 kb boundaries */ | 2722 | /* 64 kb boundaries */ |
2762 | if (CROSS_64KB(current_req->buffer, max_size << 9)) | 2723 | if (CROSS_64KB(current_req->buffer, max_size << 9)) |
2763 | max_size = (K_64 - | 2724 | max_size = (K_64 - |
@@ -2773,16 +2734,16 @@ static int make_raw_rw_request(void) | |||
2773 | */ | 2734 | */ |
2774 | if (!direct || | 2735 | if (!direct || |
2775 | (indirect * 2 > direct * 3 && | 2736 | (indirect * 2 > direct * 3 && |
2776 | *errors < DP->max_errors.read_track && ((!probing | 2737 | *errors < DP->max_errors.read_track && |
2777 | || (DP->read_track & (1 << DRS->probed_format)))))) { | 2738 | ((!probing || |
2739 | (DP->read_track & (1 << DRS->probed_format)))))) { | ||
2778 | max_size = blk_rq_sectors(current_req); | 2740 | max_size = blk_rq_sectors(current_req); |
2779 | } else { | 2741 | } else { |
2780 | raw_cmd->kernel_data = current_req->buffer; | 2742 | raw_cmd->kernel_data = current_req->buffer; |
2781 | raw_cmd->length = current_count_sectors << 9; | 2743 | raw_cmd->length = current_count_sectors << 9; |
2782 | if (raw_cmd->length == 0) { | 2744 | if (raw_cmd->length == 0) { |
2783 | DPRINT | 2745 | DPRINT("%s: zero dma transfer attempted\n", __func__); |
2784 | ("zero dma transfer attempted from make_raw_request\n"); | 2746 | DPRINT("indirect=%d direct=%d fsector_t=%d\n", |
2785 | DPRINT("indirect=%d direct=%d fsector_t=%d", | ||
2786 | indirect, direct, fsector_t); | 2747 | indirect, direct, fsector_t); |
2787 | return 0; | 2748 | return 0; |
2788 | } | 2749 | } |
@@ -2802,25 +2763,22 @@ static int make_raw_rw_request(void) | |||
2802 | ((CT(COMMAND) == FD_READ || | 2763 | ((CT(COMMAND) == FD_READ || |
2803 | (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) && | 2764 | (!in_sector_offset && blk_rq_sectors(current_req) >= ssize)) && |
2804 | max_sector > 2 * max_buffer_sectors + buffer_min && | 2765 | max_sector > 2 * max_buffer_sectors + buffer_min && |
2805 | max_size + fsector_t > 2 * max_buffer_sectors + buffer_min) | 2766 | max_size + fsector_t > 2 * max_buffer_sectors + buffer_min)) { |
2806 | /* not enough space */ | 2767 | /* not enough space */ |
2807 | ) { | ||
2808 | buffer_track = -1; | 2768 | buffer_track = -1; |
2809 | buffer_drive = current_drive; | 2769 | buffer_drive = current_drive; |
2810 | buffer_max = buffer_min = aligned_sector_t; | 2770 | buffer_max = buffer_min = aligned_sector_t; |
2811 | } | 2771 | } |
2812 | raw_cmd->kernel_data = floppy_track_buffer + | 2772 | raw_cmd->kernel_data = floppy_track_buffer + |
2813 | ((aligned_sector_t - buffer_min) << 9); | 2773 | ((aligned_sector_t - buffer_min) << 9); |
2814 | 2774 | ||
2815 | if (CT(COMMAND) == FD_WRITE) { | 2775 | if (CT(COMMAND) == FD_WRITE) { |
2816 | /* copy write buffer to track buffer. | 2776 | /* copy write buffer to track buffer. |
2817 | * if we get here, we know that the write | 2777 | * if we get here, we know that the write |
2818 | * is either aligned or the data already in the buffer | 2778 | * is either aligned or the data already in the buffer |
2819 | * (buffer will be overwritten) */ | 2779 | * (buffer will be overwritten) */ |
2820 | #ifdef FLOPPY_SANITY_CHECK | ||
2821 | if (in_sector_offset && buffer_track == -1) | 2780 | if (in_sector_offset && buffer_track == -1) |
2822 | DPRINT("internal error offset !=0 on write\n"); | 2781 | DPRINT("internal error offset !=0 on write\n"); |
2823 | #endif | ||
2824 | buffer_track = raw_cmd->track; | 2782 | buffer_track = raw_cmd->track; |
2825 | buffer_drive = current_drive; | 2783 | buffer_drive = current_drive; |
2826 | copy_buffer(ssize, max_sector, | 2784 | copy_buffer(ssize, max_sector, |
@@ -2834,7 +2792,6 @@ static int make_raw_rw_request(void) | |||
2834 | raw_cmd->length = in_sector_offset + current_count_sectors; | 2792 | raw_cmd->length = in_sector_offset + current_count_sectors; |
2835 | raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; | 2793 | raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1; |
2836 | raw_cmd->length <<= 9; | 2794 | raw_cmd->length <<= 9; |
2837 | #ifdef FLOPPY_SANITY_CHECK | ||
2838 | if ((raw_cmd->length < current_count_sectors << 9) || | 2795 | if ((raw_cmd->length < current_count_sectors << 9) || |
2839 | (raw_cmd->kernel_data != current_req->buffer && | 2796 | (raw_cmd->kernel_data != current_req->buffer && |
2840 | CT(COMMAND) == FD_WRITE && | 2797 | CT(COMMAND) == FD_WRITE && |
@@ -2845,19 +2802,19 @@ static int make_raw_rw_request(void) | |||
2845 | DPRINT("fractionary current count b=%lx s=%lx\n", | 2802 | DPRINT("fractionary current count b=%lx s=%lx\n", |
2846 | raw_cmd->length, current_count_sectors); | 2803 | raw_cmd->length, current_count_sectors); |
2847 | if (raw_cmd->kernel_data != current_req->buffer) | 2804 | if (raw_cmd->kernel_data != current_req->buffer) |
2848 | printk("addr=%d, length=%ld\n", | 2805 | pr_info("addr=%d, length=%ld\n", |
2849 | (int)((raw_cmd->kernel_data - | 2806 | (int)((raw_cmd->kernel_data - |
2850 | floppy_track_buffer) >> 9), | 2807 | floppy_track_buffer) >> 9), |
2851 | current_count_sectors); | 2808 | current_count_sectors); |
2852 | printk("st=%d ast=%d mse=%d msi=%d\n", | 2809 | pr_info("st=%d ast=%d mse=%d msi=%d\n", |
2853 | fsector_t, aligned_sector_t, max_sector, max_size); | 2810 | fsector_t, aligned_sector_t, max_sector, max_size); |
2854 | printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); | 2811 | pr_info("ssize=%x SIZECODE=%d\n", ssize, SIZECODE); |
2855 | printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", | 2812 | pr_info("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n", |
2856 | COMMAND, SECTOR, HEAD, TRACK); | 2813 | COMMAND, SECTOR, HEAD, TRACK); |
2857 | printk("buffer drive=%d\n", buffer_drive); | 2814 | pr_info("buffer drive=%d\n", buffer_drive); |
2858 | printk("buffer track=%d\n", buffer_track); | 2815 | pr_info("buffer track=%d\n", buffer_track); |
2859 | printk("buffer_min=%d\n", buffer_min); | 2816 | pr_info("buffer_min=%d\n", buffer_min); |
2860 | printk("buffer_max=%d\n", buffer_max); | 2817 | pr_info("buffer_max=%d\n", buffer_max); |
2861 | return 0; | 2818 | return 0; |
2862 | } | 2819 | } |
2863 | 2820 | ||
@@ -2868,14 +2825,14 @@ static int make_raw_rw_request(void) | |||
2868 | raw_cmd->kernel_data + raw_cmd->length > | 2825 | raw_cmd->kernel_data + raw_cmd->length > |
2869 | floppy_track_buffer + (max_buffer_sectors << 10)) { | 2826 | floppy_track_buffer + (max_buffer_sectors << 10)) { |
2870 | DPRINT("buffer overrun in schedule dma\n"); | 2827 | DPRINT("buffer overrun in schedule dma\n"); |
2871 | printk("fsector_t=%d buffer_min=%d current_count=%ld\n", | 2828 | pr_info("fsector_t=%d buffer_min=%d current_count=%ld\n", |
2872 | fsector_t, buffer_min, raw_cmd->length >> 9); | 2829 | fsector_t, buffer_min, raw_cmd->length >> 9); |
2873 | printk("current_count_sectors=%ld\n", | 2830 | pr_info("current_count_sectors=%ld\n", |
2874 | current_count_sectors); | 2831 | current_count_sectors); |
2875 | if (CT(COMMAND) == FD_READ) | 2832 | if (CT(COMMAND) == FD_READ) |
2876 | printk("read\n"); | 2833 | pr_info("read\n"); |
2877 | if (CT(COMMAND) == FD_WRITE) | 2834 | if (CT(COMMAND) == FD_WRITE) |
2878 | printk("write\n"); | 2835 | pr_info("write\n"); |
2879 | return 0; | 2836 | return 0; |
2880 | } | 2837 | } |
2881 | } else if (raw_cmd->length > blk_rq_bytes(current_req) || | 2838 | } else if (raw_cmd->length > blk_rq_bytes(current_req) || |
@@ -2884,14 +2841,13 @@ static int make_raw_rw_request(void) | |||
2884 | return 0; | 2841 | return 0; |
2885 | } else if (raw_cmd->length < current_count_sectors << 9) { | 2842 | } else if (raw_cmd->length < current_count_sectors << 9) { |
2886 | DPRINT("more sectors than bytes\n"); | 2843 | DPRINT("more sectors than bytes\n"); |
2887 | printk("bytes=%ld\n", raw_cmd->length >> 9); | 2844 | pr_info("bytes=%ld\n", raw_cmd->length >> 9); |
2888 | printk("sectors=%ld\n", current_count_sectors); | 2845 | pr_info("sectors=%ld\n", current_count_sectors); |
2889 | } | 2846 | } |
2890 | if (raw_cmd->length == 0) { | 2847 | if (raw_cmd->length == 0) { |
2891 | DPRINT("zero dma transfer attempted from make_raw_request\n"); | 2848 | DPRINT("zero dma transfer attempted from make_raw_request\n"); |
2892 | return 0; | 2849 | return 0; |
2893 | } | 2850 | } |
2894 | #endif | ||
2895 | 2851 | ||
2896 | virtualdmabug_workaround(); | 2852 | virtualdmabug_workaround(); |
2897 | return 2; | 2853 | return 2; |
@@ -2899,7 +2855,6 @@ static int make_raw_rw_request(void) | |||
2899 | 2855 | ||
2900 | static void redo_fd_request(void) | 2856 | static void redo_fd_request(void) |
2901 | { | 2857 | { |
2902 | #define REPEAT {request_done(0); continue; } | ||
2903 | int drive; | 2858 | int drive; |
2904 | int tmp; | 2859 | int tmp; |
2905 | 2860 | ||
@@ -2907,63 +2862,63 @@ static void redo_fd_request(void) | |||
2907 | if (current_drive < N_DRIVE) | 2862 | if (current_drive < N_DRIVE) |
2908 | floppy_off(current_drive); | 2863 | floppy_off(current_drive); |
2909 | 2864 | ||
2910 | for (;;) { | 2865 | do_request: |
2911 | if (!current_req) { | 2866 | if (!current_req) { |
2912 | struct request *req; | 2867 | struct request *req; |
2913 | |||
2914 | spin_lock_irq(floppy_queue->queue_lock); | ||
2915 | req = blk_fetch_request(floppy_queue); | ||
2916 | spin_unlock_irq(floppy_queue->queue_lock); | ||
2917 | if (!req) { | ||
2918 | do_floppy = NULL; | ||
2919 | unlock_fdc(); | ||
2920 | return; | ||
2921 | } | ||
2922 | current_req = req; | ||
2923 | } | ||
2924 | drive = (long)current_req->rq_disk->private_data; | ||
2925 | set_fdc(drive); | ||
2926 | reschedule_timeout(current_reqD, "redo fd request", 0); | ||
2927 | 2868 | ||
2928 | set_floppy(drive); | 2869 | spin_lock_irq(floppy_queue->queue_lock); |
2929 | raw_cmd = &default_raw_cmd; | 2870 | req = blk_fetch_request(floppy_queue); |
2930 | raw_cmd->flags = 0; | 2871 | spin_unlock_irq(floppy_queue->queue_lock); |
2931 | if (start_motor(redo_fd_request)) | 2872 | if (!req) { |
2873 | do_floppy = NULL; | ||
2874 | unlock_fdc(); | ||
2932 | return; | 2875 | return; |
2933 | disk_change(current_drive); | ||
2934 | if (test_bit(current_drive, &fake_change) || | ||
2935 | TESTF(FD_DISK_CHANGED)) { | ||
2936 | DPRINT("disk absent or changed during operation\n"); | ||
2937 | REPEAT; | ||
2938 | } | ||
2939 | if (!_floppy) { /* Autodetection */ | ||
2940 | if (!probing) { | ||
2941 | DRS->probed_format = 0; | ||
2942 | if (next_valid_format()) { | ||
2943 | DPRINT("no autodetectable formats\n"); | ||
2944 | _floppy = NULL; | ||
2945 | REPEAT; | ||
2946 | } | ||
2947 | } | ||
2948 | probing = 1; | ||
2949 | _floppy = | ||
2950 | floppy_type + DP->autodetect[DRS->probed_format]; | ||
2951 | } else | ||
2952 | probing = 0; | ||
2953 | errors = &(current_req->errors); | ||
2954 | tmp = make_raw_rw_request(); | ||
2955 | if (tmp < 2) { | ||
2956 | request_done(tmp); | ||
2957 | continue; | ||
2958 | } | 2876 | } |
2877 | current_req = req; | ||
2878 | } | ||
2879 | drive = (long)current_req->rq_disk->private_data; | ||
2880 | set_fdc(drive); | ||
2881 | reschedule_timeout(current_reqD, "redo fd request"); | ||
2959 | 2882 | ||
2960 | if (TESTF(FD_NEED_TWADDLE)) | 2883 | set_floppy(drive); |
2961 | twaddle(); | 2884 | raw_cmd = &default_raw_cmd; |
2962 | schedule_bh(floppy_start); | 2885 | raw_cmd->flags = 0; |
2963 | debugt("queue fd request"); | 2886 | if (start_motor(redo_fd_request)) |
2964 | return; | 2887 | return; |
2888 | |||
2889 | disk_change(current_drive); | ||
2890 | if (test_bit(current_drive, &fake_change) || | ||
2891 | test_bit(FD_DISK_CHANGED_BIT, &DRS->flags)) { | ||
2892 | DPRINT("disk absent or changed during operation\n"); | ||
2893 | request_done(0); | ||
2894 | goto do_request; | ||
2895 | } | ||
2896 | if (!_floppy) { /* Autodetection */ | ||
2897 | if (!probing) { | ||
2898 | DRS->probed_format = 0; | ||
2899 | if (next_valid_format()) { | ||
2900 | DPRINT("no autodetectable formats\n"); | ||
2901 | _floppy = NULL; | ||
2902 | request_done(0); | ||
2903 | goto do_request; | ||
2904 | } | ||
2905 | } | ||
2906 | probing = 1; | ||
2907 | _floppy = floppy_type + DP->autodetect[DRS->probed_format]; | ||
2908 | } else | ||
2909 | probing = 0; | ||
2910 | errors = &(current_req->errors); | ||
2911 | tmp = make_raw_rw_request(); | ||
2912 | if (tmp < 2) { | ||
2913 | request_done(tmp); | ||
2914 | goto do_request; | ||
2965 | } | 2915 | } |
2966 | #undef REPEAT | 2916 | |
2917 | if (test_bit(FD_NEED_TWADDLE_BIT, &DRS->flags)) | ||
2918 | twaddle(); | ||
2919 | schedule_bh(floppy_start); | ||
2920 | debugt(__func__, "queue fd request"); | ||
2921 | return; | ||
2967 | } | 2922 | } |
2968 | 2923 | ||
2969 | static struct cont_t rw_cont = { | 2924 | static struct cont_t rw_cont = { |
@@ -2979,30 +2934,30 @@ static void process_fd_request(void) | |||
2979 | schedule_bh(redo_fd_request); | 2934 | schedule_bh(redo_fd_request); |
2980 | } | 2935 | } |
2981 | 2936 | ||
2982 | static void do_fd_request(struct request_queue * q) | 2937 | static void do_fd_request(struct request_queue *q) |
2983 | { | 2938 | { |
2984 | if (max_buffer_sectors == 0) { | 2939 | if (max_buffer_sectors == 0) { |
2985 | printk("VFS: do_fd_request called on non-open device\n"); | 2940 | pr_info("VFS: %s called on non-open device\n", __func__); |
2986 | return; | 2941 | return; |
2987 | } | 2942 | } |
2988 | 2943 | ||
2989 | if (usage_count == 0) { | 2944 | if (usage_count == 0) { |
2990 | printk("warning: usage count=0, current_req=%p exiting\n", | 2945 | pr_info("warning: usage count=0, current_req=%p exiting\n", |
2991 | current_req); | 2946 | current_req); |
2992 | printk("sect=%ld type=%x flags=%x\n", | 2947 | pr_info("sect=%ld type=%x flags=%x\n", |
2993 | (long)blk_rq_pos(current_req), current_req->cmd_type, | 2948 | (long)blk_rq_pos(current_req), current_req->cmd_type, |
2994 | current_req->cmd_flags); | 2949 | current_req->cmd_flags); |
2995 | return; | 2950 | return; |
2996 | } | 2951 | } |
2997 | if (test_bit(0, &fdc_busy)) { | 2952 | if (test_bit(0, &fdc_busy)) { |
2998 | /* fdc busy, this new request will be treated when the | 2953 | /* fdc busy, this new request will be treated when the |
2999 | current one is done */ | 2954 | current one is done */ |
3000 | is_alive("do fd request, old request running"); | 2955 | is_alive(__func__, "old request running"); |
3001 | return; | 2956 | return; |
3002 | } | 2957 | } |
3003 | lock_fdc(MAXTIMEOUT, 0); | 2958 | lock_fdc(MAXTIMEOUT, false); |
3004 | process_fd_request(); | 2959 | process_fd_request(); |
3005 | is_alive("do fd request"); | 2960 | is_alive(__func__, ""); |
3006 | } | 2961 | } |
3007 | 2962 | ||
3008 | static struct cont_t poll_cont = { | 2963 | static struct cont_t poll_cont = { |
@@ -3012,24 +2967,18 @@ static struct cont_t poll_cont = { | |||
3012 | .done = generic_done | 2967 | .done = generic_done |
3013 | }; | 2968 | }; |
3014 | 2969 | ||
3015 | static int poll_drive(int interruptible, int flag) | 2970 | static int poll_drive(bool interruptible, int flag) |
3016 | { | 2971 | { |
3017 | int ret; | ||
3018 | |||
3019 | /* no auto-sense, just clear dcl */ | 2972 | /* no auto-sense, just clear dcl */ |
3020 | raw_cmd = &default_raw_cmd; | 2973 | raw_cmd = &default_raw_cmd; |
3021 | raw_cmd->flags = flag; | 2974 | raw_cmd->flags = flag; |
3022 | raw_cmd->track = 0; | 2975 | raw_cmd->track = 0; |
3023 | raw_cmd->cmd_count = 0; | 2976 | raw_cmd->cmd_count = 0; |
3024 | cont = &poll_cont; | 2977 | cont = &poll_cont; |
3025 | #ifdef DCL_DEBUG | 2978 | debug_dcl(DP->flags, "setting NEWCHANGE in poll_drive\n"); |
3026 | if (DP->flags & FD_DEBUG) { | 2979 | set_bit(FD_DISK_NEWCHANGE_BIT, &DRS->flags); |
3027 | DPRINT("setting NEWCHANGE in poll_drive\n"); | 2980 | |
3028 | } | 2981 | return wait_til_done(floppy_ready, interruptible); |
3029 | #endif | ||
3030 | SETF(FD_DISK_NEWCHANGE); | ||
3031 | WAIT(floppy_ready); | ||
3032 | return ret; | ||
3033 | } | 2982 | } |
3034 | 2983 | ||
3035 | /* | 2984 | /* |
@@ -3039,7 +2988,7 @@ static int poll_drive(int interruptible, int flag) | |||
3039 | 2988 | ||
3040 | static void reset_intr(void) | 2989 | static void reset_intr(void) |
3041 | { | 2990 | { |
3042 | printk("weird, reset interrupt called\n"); | 2991 | pr_info("weird, reset interrupt called\n"); |
3043 | } | 2992 | } |
3044 | 2993 | ||
3045 | static struct cont_t reset_cont = { | 2994 | static struct cont_t reset_cont = { |
@@ -3049,20 +2998,23 @@ static struct cont_t reset_cont = { | |||
3049 | .done = generic_done | 2998 | .done = generic_done |
3050 | }; | 2999 | }; |
3051 | 3000 | ||
3052 | static int user_reset_fdc(int drive, int arg, int interruptible) | 3001 | static int user_reset_fdc(int drive, int arg, bool interruptible) |
3053 | { | 3002 | { |
3054 | int ret; | 3003 | int ret; |
3055 | 3004 | ||
3056 | ret = 0; | 3005 | if (lock_fdc(drive, interruptible)) |
3057 | LOCK_FDC(drive, interruptible); | 3006 | return -EINTR; |
3007 | |||
3058 | if (arg == FD_RESET_ALWAYS) | 3008 | if (arg == FD_RESET_ALWAYS) |
3059 | FDCS->reset = 1; | 3009 | FDCS->reset = 1; |
3060 | if (FDCS->reset) { | 3010 | if (FDCS->reset) { |
3061 | cont = &reset_cont; | 3011 | cont = &reset_cont; |
3062 | WAIT(reset_fdc); | 3012 | ret = wait_til_done(reset_fdc, interruptible); |
3013 | if (ret == -EINTR) | ||
3014 | return -EINTR; | ||
3063 | } | 3015 | } |
3064 | process_fd_request(); | 3016 | process_fd_request(); |
3065 | return ret; | 3017 | return 0; |
3066 | } | 3018 | } |
3067 | 3019 | ||
3068 | /* | 3020 | /* |
@@ -3075,17 +3027,12 @@ static inline int fd_copyout(void __user *param, const void *address, | |||
3075 | return copy_to_user(param, address, size) ? -EFAULT : 0; | 3027 | return copy_to_user(param, address, size) ? -EFAULT : 0; |
3076 | } | 3028 | } |
3077 | 3029 | ||
3078 | static inline int fd_copyin(void __user *param, void *address, unsigned long size) | 3030 | static inline int fd_copyin(void __user *param, void *address, |
3031 | unsigned long size) | ||
3079 | { | 3032 | { |
3080 | return copy_from_user(address, param, size) ? -EFAULT : 0; | 3033 | return copy_from_user(address, param, size) ? -EFAULT : 0; |
3081 | } | 3034 | } |
3082 | 3035 | ||
3083 | #define _COPYOUT(x) (copy_to_user((void __user *)param, &(x), sizeof(x)) ? -EFAULT : 0) | ||
3084 | #define _COPYIN(x) (copy_from_user(&(x), (void __user *)param, sizeof(x)) ? -EFAULT : 0) | ||
3085 | |||
3086 | #define COPYOUT(x) ECALL(_COPYOUT(x)) | ||
3087 | #define COPYIN(x) ECALL(_COPYIN(x)) | ||
3088 | |||
3089 | static inline const char *drive_name(int type, int drive) | 3036 | static inline const char *drive_name(int type, int drive) |
3090 | { | 3037 | { |
3091 | struct floppy_struct *floppy; | 3038 | struct floppy_struct *floppy; |
@@ -3156,23 +3103,29 @@ static struct cont_t raw_cmd_cont = { | |||
3156 | .done = raw_cmd_done | 3103 | .done = raw_cmd_done |
3157 | }; | 3104 | }; |
3158 | 3105 | ||
3159 | static inline int raw_cmd_copyout(int cmd, char __user *param, | 3106 | static inline int raw_cmd_copyout(int cmd, void __user *param, |
3160 | struct floppy_raw_cmd *ptr) | 3107 | struct floppy_raw_cmd *ptr) |
3161 | { | 3108 | { |
3162 | int ret; | 3109 | int ret; |
3163 | 3110 | ||
3164 | while (ptr) { | 3111 | while (ptr) { |
3165 | COPYOUT(*ptr); | 3112 | ret = copy_to_user(param, ptr, sizeof(*ptr)); |
3113 | if (ret) | ||
3114 | return -EFAULT; | ||
3166 | param += sizeof(struct floppy_raw_cmd); | 3115 | param += sizeof(struct floppy_raw_cmd); |
3167 | if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { | 3116 | if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) { |
3168 | if (ptr->length >= 0 | 3117 | if (ptr->length >= 0 && |
3169 | && ptr->length <= ptr->buffer_length) | 3118 | ptr->length <= ptr->buffer_length) { |
3170 | ECALL(fd_copyout | 3119 | long length = ptr->buffer_length - ptr->length; |
3171 | (ptr->data, ptr->kernel_data, | 3120 | ret = fd_copyout(ptr->data, ptr->kernel_data, |
3172 | ptr->buffer_length - ptr->length)); | 3121 | length); |
3122 | if (ret) | ||
3123 | return ret; | ||
3124 | } | ||
3173 | } | 3125 | } |
3174 | ptr = ptr->next; | 3126 | ptr = ptr->next; |
3175 | } | 3127 | } |
3128 | |||
3176 | return 0; | 3129 | return 0; |
3177 | } | 3130 | } |
3178 | 3131 | ||
@@ -3195,7 +3148,7 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) | |||
3195 | } | 3148 | } |
3196 | } | 3149 | } |
3197 | 3150 | ||
3198 | static inline int raw_cmd_copyin(int cmd, char __user *param, | 3151 | static inline int raw_cmd_copyin(int cmd, void __user *param, |
3199 | struct floppy_raw_cmd **rcmd) | 3152 | struct floppy_raw_cmd **rcmd) |
3200 | { | 3153 | { |
3201 | struct floppy_raw_cmd *ptr; | 3154 | struct floppy_raw_cmd *ptr; |
@@ -3203,17 +3156,19 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, | |||
3203 | int i; | 3156 | int i; |
3204 | 3157 | ||
3205 | *rcmd = NULL; | 3158 | *rcmd = NULL; |
3206 | while (1) { | 3159 | |
3207 | ptr = (struct floppy_raw_cmd *) | 3160 | loop: |
3208 | kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); | 3161 | ptr = kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER); |
3209 | if (!ptr) | 3162 | if (!ptr) |
3210 | return -ENOMEM; | 3163 | return -ENOMEM; |
3211 | *rcmd = ptr; | 3164 | *rcmd = ptr; |
3212 | COPYIN(*ptr); | 3165 | ret = copy_from_user(ptr, param, sizeof(*ptr)); |
3213 | ptr->next = NULL; | 3166 | if (ret) |
3214 | ptr->buffer_length = 0; | 3167 | return -EFAULT; |
3215 | param += sizeof(struct floppy_raw_cmd); | 3168 | ptr->next = NULL; |
3216 | if (ptr->cmd_count > 33) | 3169 | ptr->buffer_length = 0; |
3170 | param += sizeof(struct floppy_raw_cmd); | ||
3171 | if (ptr->cmd_count > 33) | ||
3217 | /* the command may now also take up the space | 3172 | /* the command may now also take up the space |
3218 | * initially intended for the reply & the | 3173 | * initially intended for the reply & the |
3219 | * reply count. Needed for long 82078 commands | 3174 | * reply count. Needed for long 82078 commands |
@@ -3222,31 +3177,35 @@ static inline int raw_cmd_copyin(int cmd, char __user *param, | |||
3222 | * 16 bytes for a structure, you'll one day | 3177 | * 16 bytes for a structure, you'll one day |
3223 | * discover that you really need 17... | 3178 | * discover that you really need 17... |
3224 | */ | 3179 | */ |
3180 | return -EINVAL; | ||
3181 | |||
3182 | for (i = 0; i < 16; i++) | ||
3183 | ptr->reply[i] = 0; | ||
3184 | ptr->resultcode = 0; | ||
3185 | ptr->kernel_data = NULL; | ||
3186 | |||
3187 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { | ||
3188 | if (ptr->length <= 0) | ||
3225 | return -EINVAL; | 3189 | return -EINVAL; |
3190 | ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); | ||
3191 | fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); | ||
3192 | if (!ptr->kernel_data) | ||
3193 | return -ENOMEM; | ||
3194 | ptr->buffer_length = ptr->length; | ||
3195 | } | ||
3196 | if (ptr->flags & FD_RAW_WRITE) { | ||
3197 | ret = fd_copyin(ptr->data, ptr->kernel_data, ptr->length); | ||
3198 | if (ret) | ||
3199 | return ret; | ||
3200 | } | ||
3226 | 3201 | ||
3227 | for (i = 0; i < 16; i++) | 3202 | if (ptr->flags & FD_RAW_MORE) { |
3228 | ptr->reply[i] = 0; | ||
3229 | ptr->resultcode = 0; | ||
3230 | ptr->kernel_data = NULL; | ||
3231 | |||
3232 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { | ||
3233 | if (ptr->length <= 0) | ||
3234 | return -EINVAL; | ||
3235 | ptr->kernel_data = | ||
3236 | (char *)fd_dma_mem_alloc(ptr->length); | ||
3237 | fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); | ||
3238 | if (!ptr->kernel_data) | ||
3239 | return -ENOMEM; | ||
3240 | ptr->buffer_length = ptr->length; | ||
3241 | } | ||
3242 | if (ptr->flags & FD_RAW_WRITE) | ||
3243 | ECALL(fd_copyin(ptr->data, ptr->kernel_data, | ||
3244 | ptr->length)); | ||
3245 | rcmd = &(ptr->next); | 3203 | rcmd = &(ptr->next); |
3246 | if (!(ptr->flags & FD_RAW_MORE)) | ||
3247 | return 0; | ||
3248 | ptr->rate &= 0x43; | 3204 | ptr->rate &= 0x43; |
3205 | goto loop; | ||
3249 | } | 3206 | } |
3207 | |||
3208 | return 0; | ||
3250 | } | 3209 | } |
3251 | 3210 | ||
3252 | static int raw_cmd_ioctl(int cmd, void __user *param) | 3211 | static int raw_cmd_ioctl(int cmd, void __user *param) |
@@ -3283,12 +3242,8 @@ static int raw_cmd_ioctl(int cmd, void __user *param) | |||
3283 | 3242 | ||
3284 | raw_cmd = my_raw_cmd; | 3243 | raw_cmd = my_raw_cmd; |
3285 | cont = &raw_cmd_cont; | 3244 | cont = &raw_cmd_cont; |
3286 | ret = wait_til_done(floppy_start, 1); | 3245 | ret = wait_til_done(floppy_start, true); |
3287 | #ifdef DCL_DEBUG | 3246 | debug_dcl(DP->flags, "calling disk change from raw_cmd ioctl\n"); |
3288 | if (DP->flags & FD_DEBUG) { | ||
3289 | DPRINT("calling disk change from raw_cmd ioctl\n"); | ||
3290 | } | ||
3291 | #endif | ||
3292 | 3247 | ||
3293 | if (ret != -EINTR && FDCS->reset) | 3248 | if (ret != -EINTR && FDCS->reset) |
3294 | ret = -EIO; | 3249 | ret = -EIO; |
@@ -3327,7 +3282,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3327 | if (!capable(CAP_SYS_ADMIN)) | 3282 | if (!capable(CAP_SYS_ADMIN)) |
3328 | return -EPERM; | 3283 | return -EPERM; |
3329 | mutex_lock(&open_lock); | 3284 | mutex_lock(&open_lock); |
3330 | if (lock_fdc(drive, 1)) { | 3285 | if (lock_fdc(drive, true)) { |
3331 | mutex_unlock(&open_lock); | 3286 | mutex_unlock(&open_lock); |
3332 | return -EINTR; | 3287 | return -EINTR; |
3333 | } | 3288 | } |
@@ -3346,11 +3301,15 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3346 | mutex_unlock(&open_lock); | 3301 | mutex_unlock(&open_lock); |
3347 | } else { | 3302 | } else { |
3348 | int oldStretch; | 3303 | int oldStretch; |
3349 | LOCK_FDC(drive, 1); | 3304 | |
3350 | if (cmd != FDDEFPRM) | 3305 | if (lock_fdc(drive, true)) |
3306 | return -EINTR; | ||
3307 | if (cmd != FDDEFPRM) { | ||
3351 | /* notice a disk change immediately, else | 3308 | /* notice a disk change immediately, else |
3352 | * we lose our settings immediately*/ | 3309 | * we lose our settings immediately*/ |
3353 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | 3310 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) |
3311 | return -EINTR; | ||
3312 | } | ||
3354 | oldStretch = g->stretch; | 3313 | oldStretch = g->stretch; |
3355 | user_params[drive] = *g; | 3314 | user_params[drive] = *g; |
3356 | if (buffer_drive == drive) | 3315 | if (buffer_drive == drive) |
@@ -3415,7 +3374,7 @@ static inline int normalize_ioctl(int *cmd, int *size) | |||
3415 | *size = _IOC_SIZE(*cmd); | 3374 | *size = _IOC_SIZE(*cmd); |
3416 | *cmd = ioctl_table[i]; | 3375 | *cmd = ioctl_table[i]; |
3417 | if (*size > _IOC_SIZE(*cmd)) { | 3376 | if (*size > _IOC_SIZE(*cmd)) { |
3418 | printk("ioctl not yet supported\n"); | 3377 | pr_info("ioctl not yet supported\n"); |
3419 | return -EFAULT; | 3378 | return -EFAULT; |
3420 | } | 3379 | } |
3421 | return 0; | 3380 | return 0; |
@@ -3429,8 +3388,10 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) | |||
3429 | if (type) | 3388 | if (type) |
3430 | *g = &floppy_type[type]; | 3389 | *g = &floppy_type[type]; |
3431 | else { | 3390 | else { |
3432 | LOCK_FDC(drive, 0); | 3391 | if (lock_fdc(drive, false)) |
3433 | CALL(poll_drive(0, 0)); | 3392 | return -EINTR; |
3393 | if (poll_drive(false, 0) == -EINTR) | ||
3394 | return -EINTR; | ||
3434 | process_fd_request(); | 3395 | process_fd_request(); |
3435 | *g = current_type[drive]; | 3396 | *g = current_type[drive]; |
3436 | } | 3397 | } |
@@ -3459,10 +3420,6 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
3459 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | 3420 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, |
3460 | unsigned long param) | 3421 | unsigned long param) |
3461 | { | 3422 | { |
3462 | #define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL)) | ||
3463 | #define OUT(c,x) case c: outparam = (const char *) (x); break | ||
3464 | #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 | ||
3465 | |||
3466 | int drive = (long)bdev->bd_disk->private_data; | 3423 | int drive = (long)bdev->bd_disk->private_data; |
3467 | int type = ITYPE(UDRS->fd_device); | 3424 | int type = ITYPE(UDRS->fd_device); |
3468 | int i; | 3425 | int i; |
@@ -3474,26 +3431,28 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3474 | struct floppy_max_errors max_errors; | 3431 | struct floppy_max_errors max_errors; |
3475 | struct floppy_drive_params dp; | 3432 | struct floppy_drive_params dp; |
3476 | } inparam; /* parameters coming from user space */ | 3433 | } inparam; /* parameters coming from user space */ |
3477 | const char *outparam; /* parameters passed back to user space */ | 3434 | const void *outparam; /* parameters passed back to user space */ |
3478 | 3435 | ||
3479 | /* convert compatibility eject ioctls into floppy eject ioctl. | 3436 | /* convert compatibility eject ioctls into floppy eject ioctl. |
3480 | * We do this in order to provide a means to eject floppy disks before | 3437 | * We do this in order to provide a means to eject floppy disks before |
3481 | * installing the new fdutils package */ | 3438 | * installing the new fdutils package */ |
3482 | if (cmd == CDROMEJECT || /* CD-ROM eject */ | 3439 | if (cmd == CDROMEJECT || /* CD-ROM eject */ |
3483 | cmd == 0x6470 /* SunOS floppy eject */ ) { | 3440 | cmd == 0x6470) { /* SunOS floppy eject */ |
3484 | DPRINT("obsolete eject ioctl\n"); | 3441 | DPRINT("obsolete eject ioctl\n"); |
3485 | DPRINT("please use floppycontrol --eject\n"); | 3442 | DPRINT("please use floppycontrol --eject\n"); |
3486 | cmd = FDEJECT; | 3443 | cmd = FDEJECT; |
3487 | } | 3444 | } |
3488 | 3445 | ||
3489 | /* convert the old style command into a new style command */ | 3446 | if (!((cmd & 0xff00) == 0x0200)) |
3490 | if ((cmd & 0xff00) == 0x0200) { | ||
3491 | ECALL(normalize_ioctl(&cmd, &size)); | ||
3492 | } else | ||
3493 | return -EINVAL; | 3447 | return -EINVAL; |
3494 | 3448 | ||
3449 | /* convert the old style command into a new style command */ | ||
3450 | ret = normalize_ioctl(&cmd, &size); | ||
3451 | if (ret) | ||
3452 | return ret; | ||
3453 | |||
3495 | /* permission checks */ | 3454 | /* permission checks */ |
3496 | if (((cmd & 0x40) && !FD_IOCTL_ALLOWED) || | 3455 | if (((cmd & 0x40) && !(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL))) || |
3497 | ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) | 3456 | ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))) |
3498 | return -EPERM; | 3457 | return -EPERM; |
3499 | 3458 | ||
@@ -3501,129 +3460,142 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3501 | return -EINVAL; | 3460 | return -EINVAL; |
3502 | 3461 | ||
3503 | /* copyin */ | 3462 | /* copyin */ |
3504 | CLEARSTRUCT(&inparam); | 3463 | memset(&inparam, 0, sizeof(inparam)); |
3505 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 3464 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
3506 | ECALL(fd_copyin((void __user *)param, &inparam, size)) | 3465 | ret = fd_copyin((void __user *)param, &inparam, size); |
3507 | 3466 | if (ret) | |
3508 | switch (cmd) { | ||
3509 | case FDEJECT: | ||
3510 | if (UDRS->fd_ref != 1) | ||
3511 | /* somebody else has this drive open */ | ||
3512 | return -EBUSY; | ||
3513 | LOCK_FDC(drive, 1); | ||
3514 | |||
3515 | /* do the actual eject. Fails on | ||
3516 | * non-Sparc architectures */ | ||
3517 | ret = fd_eject(UNIT(drive)); | ||
3518 | |||
3519 | USETF(FD_DISK_CHANGED); | ||
3520 | USETF(FD_VERIFY); | ||
3521 | process_fd_request(); | ||
3522 | return ret; | 3467 | return ret; |
3523 | case FDCLRPRM: | 3468 | } |
3524 | LOCK_FDC(drive, 1); | ||
3525 | current_type[drive] = NULL; | ||
3526 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3527 | UDRS->keep_data = 0; | ||
3528 | return invalidate_drive(bdev); | ||
3529 | case FDSETPRM: | ||
3530 | case FDDEFPRM: | ||
3531 | return set_geometry(cmd, &inparam.g, | ||
3532 | drive, type, bdev); | ||
3533 | case FDGETPRM: | ||
3534 | ECALL(get_floppy_geometry(drive, type, | ||
3535 | (struct floppy_struct **) | ||
3536 | &outparam)); | ||
3537 | break; | ||
3538 | |||
3539 | case FDMSGON: | ||
3540 | UDP->flags |= FTD_MSG; | ||
3541 | return 0; | ||
3542 | case FDMSGOFF: | ||
3543 | UDP->flags &= ~FTD_MSG; | ||
3544 | return 0; | ||
3545 | |||
3546 | case FDFMTBEG: | ||
3547 | LOCK_FDC(drive, 1); | ||
3548 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3549 | ret = UDRS->flags; | ||
3550 | process_fd_request(); | ||
3551 | if (ret & FD_VERIFY) | ||
3552 | return -ENODEV; | ||
3553 | if (!(ret & FD_DISK_WRITABLE)) | ||
3554 | return -EROFS; | ||
3555 | return 0; | ||
3556 | case FDFMTTRK: | ||
3557 | if (UDRS->fd_ref != 1) | ||
3558 | return -EBUSY; | ||
3559 | return do_format(drive, &inparam.f); | ||
3560 | case FDFMTEND: | ||
3561 | case FDFLUSH: | ||
3562 | LOCK_FDC(drive, 1); | ||
3563 | return invalidate_drive(bdev); | ||
3564 | |||
3565 | case FDSETEMSGTRESH: | ||
3566 | UDP->max_errors.reporting = | ||
3567 | (unsigned short)(param & 0x0f); | ||
3568 | return 0; | ||
3569 | OUT(FDGETMAXERRS, &UDP->max_errors); | ||
3570 | IN(FDSETMAXERRS, &UDP->max_errors, max_errors); | ||
3571 | |||
3572 | case FDGETDRVTYP: | ||
3573 | outparam = drive_name(type, drive); | ||
3574 | SUPBOUND(size, strlen(outparam) + 1); | ||
3575 | break; | ||
3576 | |||
3577 | IN(FDSETDRVPRM, UDP, dp); | ||
3578 | OUT(FDGETDRVPRM, UDP); | ||
3579 | |||
3580 | case FDPOLLDRVSTAT: | ||
3581 | LOCK_FDC(drive, 1); | ||
3582 | CALL(poll_drive(1, FD_RAW_NEED_DISK)); | ||
3583 | process_fd_request(); | ||
3584 | /* fall through */ | ||
3585 | OUT(FDGETDRVSTAT, UDRS); | ||
3586 | |||
3587 | case FDRESET: | ||
3588 | return user_reset_fdc(drive, (int)param, 1); | ||
3589 | |||
3590 | OUT(FDGETFDCSTAT, UFDCS); | ||
3591 | 3469 | ||
3592 | case FDWERRORCLR: | 3470 | switch (cmd) { |
3593 | CLEARSTRUCT(UDRWE); | 3471 | case FDEJECT: |
3594 | return 0; | 3472 | if (UDRS->fd_ref != 1) |
3595 | OUT(FDWERRORGET, UDRWE); | 3473 | /* somebody else has this drive open */ |
3596 | 3474 | return -EBUSY; | |
3597 | case FDRAWCMD: | 3475 | if (lock_fdc(drive, true)) |
3598 | if (type) | 3476 | return -EINTR; |
3599 | return -EINVAL; | ||
3600 | LOCK_FDC(drive, 1); | ||
3601 | set_floppy(drive); | ||
3602 | CALL(i = raw_cmd_ioctl(cmd, (void __user *)param)); | ||
3603 | process_fd_request(); | ||
3604 | return i; | ||
3605 | 3477 | ||
3606 | case FDTWADDLE: | 3478 | /* do the actual eject. Fails on |
3607 | LOCK_FDC(drive, 1); | 3479 | * non-Sparc architectures */ |
3608 | twaddle(); | 3480 | ret = fd_eject(UNIT(drive)); |
3609 | process_fd_request(); | ||
3610 | return 0; | ||
3611 | 3481 | ||
3612 | default: | 3482 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3483 | set_bit(FD_VERIFY_BIT, &UDRS->flags); | ||
3484 | process_fd_request(); | ||
3485 | return ret; | ||
3486 | case FDCLRPRM: | ||
3487 | if (lock_fdc(drive, true)) | ||
3488 | return -EINTR; | ||
3489 | current_type[drive] = NULL; | ||
3490 | floppy_sizes[drive] = MAX_DISK_SIZE << 1; | ||
3491 | UDRS->keep_data = 0; | ||
3492 | return invalidate_drive(bdev); | ||
3493 | case FDSETPRM: | ||
3494 | case FDDEFPRM: | ||
3495 | return set_geometry(cmd, &inparam.g, drive, type, bdev); | ||
3496 | case FDGETPRM: | ||
3497 | ret = get_floppy_geometry(drive, type, | ||
3498 | (struct floppy_struct **)&outparam); | ||
3499 | if (ret) | ||
3500 | return ret; | ||
3501 | break; | ||
3502 | case FDMSGON: | ||
3503 | UDP->flags |= FTD_MSG; | ||
3504 | return 0; | ||
3505 | case FDMSGOFF: | ||
3506 | UDP->flags &= ~FTD_MSG; | ||
3507 | return 0; | ||
3508 | case FDFMTBEG: | ||
3509 | if (lock_fdc(drive, true)) | ||
3510 | return -EINTR; | ||
3511 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) | ||
3512 | return -EINTR; | ||
3513 | ret = UDRS->flags; | ||
3514 | process_fd_request(); | ||
3515 | if (ret & FD_VERIFY) | ||
3516 | return -ENODEV; | ||
3517 | if (!(ret & FD_DISK_WRITABLE)) | ||
3518 | return -EROFS; | ||
3519 | return 0; | ||
3520 | case FDFMTTRK: | ||
3521 | if (UDRS->fd_ref != 1) | ||
3522 | return -EBUSY; | ||
3523 | return do_format(drive, &inparam.f); | ||
3524 | case FDFMTEND: | ||
3525 | case FDFLUSH: | ||
3526 | if (lock_fdc(drive, true)) | ||
3527 | return -EINTR; | ||
3528 | return invalidate_drive(bdev); | ||
3529 | case FDSETEMSGTRESH: | ||
3530 | UDP->max_errors.reporting = (unsigned short)(param & 0x0f); | ||
3531 | return 0; | ||
3532 | case FDGETMAXERRS: | ||
3533 | outparam = &UDP->max_errors; | ||
3534 | break; | ||
3535 | case FDSETMAXERRS: | ||
3536 | UDP->max_errors = inparam.max_errors; | ||
3537 | break; | ||
3538 | case FDGETDRVTYP: | ||
3539 | outparam = drive_name(type, drive); | ||
3540 | SUPBOUND(size, strlen((const char *)outparam) + 1); | ||
3541 | break; | ||
3542 | case FDSETDRVPRM: | ||
3543 | *UDP = inparam.dp; | ||
3544 | break; | ||
3545 | case FDGETDRVPRM: | ||
3546 | outparam = UDP; | ||
3547 | break; | ||
3548 | case FDPOLLDRVSTAT: | ||
3549 | if (lock_fdc(drive, true)) | ||
3550 | return -EINTR; | ||
3551 | if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR) | ||
3552 | return -EINTR; | ||
3553 | process_fd_request(); | ||
3554 | /* fall through */ | ||
3555 | case FDGETDRVSTAT: | ||
3556 | outparam = UDRS; | ||
3557 | break; | ||
3558 | case FDRESET: | ||
3559 | return user_reset_fdc(drive, (int)param, true); | ||
3560 | case FDGETFDCSTAT: | ||
3561 | outparam = UFDCS; | ||
3562 | break; | ||
3563 | case FDWERRORCLR: | ||
3564 | memset(UDRWE, 0, sizeof(*UDRWE)); | ||
3565 | return 0; | ||
3566 | case FDWERRORGET: | ||
3567 | outparam = UDRWE; | ||
3568 | break; | ||
3569 | case FDRAWCMD: | ||
3570 | if (type) | ||
3613 | return -EINVAL; | 3571 | return -EINVAL; |
3614 | } | 3572 | if (lock_fdc(drive, true)) |
3573 | return -EINTR; | ||
3574 | set_floppy(drive); | ||
3575 | i = raw_cmd_ioctl(cmd, (void __user *)param); | ||
3576 | if (i == -EINTR) | ||
3577 | return -EINTR; | ||
3578 | process_fd_request(); | ||
3579 | return i; | ||
3580 | case FDTWADDLE: | ||
3581 | if (lock_fdc(drive, true)) | ||
3582 | return -EINTR; | ||
3583 | twaddle(); | ||
3584 | process_fd_request(); | ||
3585 | return 0; | ||
3586 | default: | ||
3587 | return -EINVAL; | ||
3588 | } | ||
3615 | 3589 | ||
3616 | if (_IOC_DIR(cmd) & _IOC_READ) | 3590 | if (_IOC_DIR(cmd) & _IOC_READ) |
3617 | return fd_copyout((void __user *)param, outparam, size); | 3591 | return fd_copyout((void __user *)param, outparam, size); |
3618 | else | 3592 | |
3619 | return 0; | 3593 | return 0; |
3620 | #undef OUT | ||
3621 | #undef IN | ||
3622 | } | 3594 | } |
3623 | 3595 | ||
3624 | static void __init config_types(void) | 3596 | static void __init config_types(void) |
3625 | { | 3597 | { |
3626 | int first = 1; | 3598 | bool has_drive = false; |
3627 | int drive; | 3599 | int drive; |
3628 | 3600 | ||
3629 | /* read drive info out of physical CMOS */ | 3601 | /* read drive info out of physical CMOS */ |
@@ -3655,17 +3627,22 @@ static void __init config_types(void) | |||
3655 | name = temparea; | 3627 | name = temparea; |
3656 | } | 3628 | } |
3657 | if (name) { | 3629 | if (name) { |
3658 | const char *prepend = ","; | 3630 | const char *prepend; |
3659 | if (first) { | 3631 | if (!has_drive) { |
3660 | prepend = KERN_INFO "Floppy drive(s):"; | 3632 | prepend = ""; |
3661 | first = 0; | 3633 | has_drive = true; |
3634 | pr_info("Floppy drive(s):"); | ||
3635 | } else { | ||
3636 | prepend = ","; | ||
3662 | } | 3637 | } |
3663 | printk("%s fd%d is %s", prepend, drive, name); | 3638 | |
3639 | pr_cont("%s fd%d is %s", prepend, drive, name); | ||
3664 | } | 3640 | } |
3665 | *UDP = *params; | 3641 | *UDP = *params; |
3666 | } | 3642 | } |
3667 | if (!first) | 3643 | |
3668 | printk("\n"); | 3644 | if (has_drive) |
3645 | pr_cont("\n"); | ||
3669 | } | 3646 | } |
3670 | 3647 | ||
3671 | static int floppy_release(struct gendisk *disk, fmode_t mode) | 3648 | static int floppy_release(struct gendisk *disk, fmode_t mode) |
@@ -3705,8 +3682,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3705 | goto out2; | 3682 | goto out2; |
3706 | 3683 | ||
3707 | if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { | 3684 | if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { |
3708 | USETF(FD_DISK_CHANGED); | 3685 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3709 | USETF(FD_VERIFY); | 3686 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
3710 | } | 3687 | } |
3711 | 3688 | ||
3712 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) | 3689 | if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) |
@@ -3735,9 +3712,8 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3735 | INFBOUND(try, 16); | 3712 | INFBOUND(try, 16); |
3736 | tmp = (char *)fd_dma_mem_alloc(1024 * try); | 3713 | tmp = (char *)fd_dma_mem_alloc(1024 * try); |
3737 | } | 3714 | } |
3738 | if (!tmp && !floppy_track_buffer) { | 3715 | if (!tmp && !floppy_track_buffer) |
3739 | fallback_on_nodma_alloc(&tmp, 2048 * try); | 3716 | fallback_on_nodma_alloc(&tmp, 2048 * try); |
3740 | } | ||
3741 | if (!tmp && !floppy_track_buffer) { | 3717 | if (!tmp && !floppy_track_buffer) { |
3742 | DPRINT("Unable to allocate DMA memory\n"); | 3718 | DPRINT("Unable to allocate DMA memory\n"); |
3743 | goto out; | 3719 | goto out; |
@@ -3767,11 +3743,12 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3767 | if (mode & (FMODE_READ|FMODE_WRITE)) { | 3743 | if (mode & (FMODE_READ|FMODE_WRITE)) { |
3768 | UDRS->last_checked = 0; | 3744 | UDRS->last_checked = 0; |
3769 | check_disk_change(bdev); | 3745 | check_disk_change(bdev); |
3770 | if (UTESTF(FD_DISK_CHANGED)) | 3746 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) |
3771 | goto out; | 3747 | goto out; |
3772 | } | 3748 | } |
3773 | res = -EROFS; | 3749 | res = -EROFS; |
3774 | if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE))) | 3750 | if ((mode & FMODE_WRITE) && |
3751 | !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) | ||
3775 | goto out; | 3752 | goto out; |
3776 | } | 3753 | } |
3777 | mutex_unlock(&open_lock); | 3754 | mutex_unlock(&open_lock); |
@@ -3795,17 +3772,18 @@ static int check_floppy_change(struct gendisk *disk) | |||
3795 | { | 3772 | { |
3796 | int drive = (long)disk->private_data; | 3773 | int drive = (long)disk->private_data; |
3797 | 3774 | ||
3798 | if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY)) | 3775 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3776 | test_bit(FD_VERIFY_BIT, &UDRS->flags)) | ||
3799 | return 1; | 3777 | return 1; |
3800 | 3778 | ||
3801 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { | 3779 | if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { |
3802 | lock_fdc(drive, 0); | 3780 | lock_fdc(drive, false); |
3803 | poll_drive(0, 0); | 3781 | poll_drive(false, 0); |
3804 | process_fd_request(); | 3782 | process_fd_request(); |
3805 | } | 3783 | } |
3806 | 3784 | ||
3807 | if (UTESTF(FD_DISK_CHANGED) || | 3785 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3808 | UTESTF(FD_VERIFY) || | 3786 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || |
3809 | test_bit(drive, &fake_change) || | 3787 | test_bit(drive, &fake_change) || |
3810 | (!ITYPE(UDRS->fd_device) && !current_type[drive])) | 3788 | (!ITYPE(UDRS->fd_device) && !current_type[drive])) |
3811 | return 1; | 3789 | return 1; |
@@ -3818,8 +3796,7 @@ static int check_floppy_change(struct gendisk *disk) | |||
3818 | * a disk in the drive, and whether that disk is writable. | 3796 | * a disk in the drive, and whether that disk is writable. |
3819 | */ | 3797 | */ |
3820 | 3798 | ||
3821 | static void floppy_rb0_complete(struct bio *bio, | 3799 | static void floppy_rb0_complete(struct bio *bio, int err) |
3822 | int err) | ||
3823 | { | 3800 | { |
3824 | complete((struct completion *)bio->bi_private); | 3801 | complete((struct completion *)bio->bi_private); |
3825 | } | 3802 | } |
@@ -3877,14 +3854,16 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3877 | int cf; | 3854 | int cf; |
3878 | int res = 0; | 3855 | int res = 0; |
3879 | 3856 | ||
3880 | if (UTESTF(FD_DISK_CHANGED) || | 3857 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3881 | UTESTF(FD_VERIFY) || test_bit(drive, &fake_change) || NO_GEOM) { | 3858 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || |
3859 | test_bit(drive, &fake_change) || NO_GEOM) { | ||
3882 | if (usage_count == 0) { | 3860 | if (usage_count == 0) { |
3883 | printk("VFS: revalidate called on non-open device.\n"); | 3861 | pr_info("VFS: revalidate called on non-open device.\n"); |
3884 | return -EFAULT; | 3862 | return -EFAULT; |
3885 | } | 3863 | } |
3886 | lock_fdc(drive, 0); | 3864 | lock_fdc(drive, false); |
3887 | cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY); | 3865 | cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3866 | test_bit(FD_VERIFY_BIT, &UDRS->flags)); | ||
3888 | if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { | 3867 | if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { |
3889 | process_fd_request(); /*already done by another thread */ | 3868 | process_fd_request(); /*already done by another thread */ |
3890 | return 0; | 3869 | return 0; |
@@ -3894,7 +3873,7 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3894 | if (buffer_drive == drive) | 3873 | if (buffer_drive == drive) |
3895 | buffer_track = -1; | 3874 | buffer_track = -1; |
3896 | clear_bit(drive, &fake_change); | 3875 | clear_bit(drive, &fake_change); |
3897 | UCLEARF(FD_DISK_CHANGED); | 3876 | clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
3898 | if (cf) | 3877 | if (cf) |
3899 | UDRS->generation++; | 3878 | UDRS->generation++; |
3900 | if (NO_GEOM) { | 3879 | if (NO_GEOM) { |
@@ -3902,7 +3881,7 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3902 | res = __floppy_read_block_0(opened_bdev[drive]); | 3881 | res = __floppy_read_block_0(opened_bdev[drive]); |
3903 | } else { | 3882 | } else { |
3904 | if (cf) | 3883 | if (cf) |
3905 | poll_drive(0, FD_RAW_NEED_DISK); | 3884 | poll_drive(false, FD_RAW_NEED_DISK); |
3906 | process_fd_request(); | 3885 | process_fd_request(); |
3907 | } | 3886 | } |
3908 | } | 3887 | } |
@@ -3934,21 +3913,21 @@ static char __init get_fdc_version(void) | |||
3934 | output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ | 3913 | output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */ |
3935 | if (FDCS->reset) | 3914 | if (FDCS->reset) |
3936 | return FDC_NONE; | 3915 | return FDC_NONE; |
3937 | if ((r = result()) <= 0x00) | 3916 | r = result(); |
3917 | if (r <= 0x00) | ||
3938 | return FDC_NONE; /* No FDC present ??? */ | 3918 | return FDC_NONE; /* No FDC present ??? */ |
3939 | if ((r == 1) && (reply_buffer[0] == 0x80)) { | 3919 | if ((r == 1) && (reply_buffer[0] == 0x80)) { |
3940 | printk(KERN_INFO "FDC %d is an 8272A\n", fdc); | 3920 | pr_info("FDC %d is an 8272A\n", fdc); |
3941 | return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ | 3921 | return FDC_8272A; /* 8272a/765 don't know DUMPREGS */ |
3942 | } | 3922 | } |
3943 | if (r != 10) { | 3923 | if (r != 10) { |
3944 | printk | 3924 | pr_info("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", |
3945 | ("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n", | 3925 | fdc, r); |
3946 | fdc, r); | ||
3947 | return FDC_UNKNOWN; | 3926 | return FDC_UNKNOWN; |
3948 | } | 3927 | } |
3949 | 3928 | ||
3950 | if (!fdc_configure()) { | 3929 | if (!fdc_configure()) { |
3951 | printk(KERN_INFO "FDC %d is an 82072\n", fdc); | 3930 | pr_info("FDC %d is an 82072\n", fdc); |
3952 | return FDC_82072; /* 82072 doesn't know CONFIGURE */ | 3931 | return FDC_82072; /* 82072 doesn't know CONFIGURE */ |
3953 | } | 3932 | } |
3954 | 3933 | ||
@@ -3956,52 +3935,50 @@ static char __init get_fdc_version(void) | |||
3956 | if (need_more_output() == MORE_OUTPUT) { | 3935 | if (need_more_output() == MORE_OUTPUT) { |
3957 | output_byte(0); | 3936 | output_byte(0); |
3958 | } else { | 3937 | } else { |
3959 | printk(KERN_INFO "FDC %d is an 82072A\n", fdc); | 3938 | pr_info("FDC %d is an 82072A\n", fdc); |
3960 | return FDC_82072A; /* 82072A as found on Sparcs. */ | 3939 | return FDC_82072A; /* 82072A as found on Sparcs. */ |
3961 | } | 3940 | } |
3962 | 3941 | ||
3963 | output_byte(FD_UNLOCK); | 3942 | output_byte(FD_UNLOCK); |
3964 | r = result(); | 3943 | r = result(); |
3965 | if ((r == 1) && (reply_buffer[0] == 0x80)) { | 3944 | if ((r == 1) && (reply_buffer[0] == 0x80)) { |
3966 | printk(KERN_INFO "FDC %d is a pre-1991 82077\n", fdc); | 3945 | pr_info("FDC %d is a pre-1991 82077\n", fdc); |
3967 | return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know | 3946 | return FDC_82077_ORIG; /* Pre-1991 82077, doesn't know |
3968 | * LOCK/UNLOCK */ | 3947 | * LOCK/UNLOCK */ |
3969 | } | 3948 | } |
3970 | if ((r != 1) || (reply_buffer[0] != 0x00)) { | 3949 | if ((r != 1) || (reply_buffer[0] != 0x00)) { |
3971 | printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", | 3950 | pr_info("FDC %d init: UNLOCK: unexpected return of %d bytes.\n", |
3972 | fdc, r); | 3951 | fdc, r); |
3973 | return FDC_UNKNOWN; | 3952 | return FDC_UNKNOWN; |
3974 | } | 3953 | } |
3975 | output_byte(FD_PARTID); | 3954 | output_byte(FD_PARTID); |
3976 | r = result(); | 3955 | r = result(); |
3977 | if (r != 1) { | 3956 | if (r != 1) { |
3978 | printk("FDC %d init: PARTID: unexpected return of %d bytes.\n", | 3957 | pr_info("FDC %d init: PARTID: unexpected return of %d bytes.\n", |
3979 | fdc, r); | 3958 | fdc, r); |
3980 | return FDC_UNKNOWN; | 3959 | return FDC_UNKNOWN; |
3981 | } | 3960 | } |
3982 | if (reply_buffer[0] == 0x80) { | 3961 | if (reply_buffer[0] == 0x80) { |
3983 | printk(KERN_INFO "FDC %d is a post-1991 82077\n", fdc); | 3962 | pr_info("FDC %d is a post-1991 82077\n", fdc); |
3984 | return FDC_82077; /* Revised 82077AA passes all the tests */ | 3963 | return FDC_82077; /* Revised 82077AA passes all the tests */ |
3985 | } | 3964 | } |
3986 | switch (reply_buffer[0] >> 5) { | 3965 | switch (reply_buffer[0] >> 5) { |
3987 | case 0x0: | 3966 | case 0x0: |
3988 | /* Either a 82078-1 or a 82078SL running at 5Volt */ | 3967 | /* Either a 82078-1 or a 82078SL running at 5Volt */ |
3989 | printk(KERN_INFO "FDC %d is an 82078.\n", fdc); | 3968 | pr_info("FDC %d is an 82078.\n", fdc); |
3990 | return FDC_82078; | 3969 | return FDC_82078; |
3991 | case 0x1: | 3970 | case 0x1: |
3992 | printk(KERN_INFO "FDC %d is a 44pin 82078\n", fdc); | 3971 | pr_info("FDC %d is a 44pin 82078\n", fdc); |
3993 | return FDC_82078; | 3972 | return FDC_82078; |
3994 | case 0x2: | 3973 | case 0x2: |
3995 | printk(KERN_INFO "FDC %d is a S82078B\n", fdc); | 3974 | pr_info("FDC %d is a S82078B\n", fdc); |
3996 | return FDC_S82078B; | 3975 | return FDC_S82078B; |
3997 | case 0x3: | 3976 | case 0x3: |
3998 | printk(KERN_INFO "FDC %d is a National Semiconductor PC87306\n", | 3977 | pr_info("FDC %d is a National Semiconductor PC87306\n", fdc); |
3999 | fdc); | ||
4000 | return FDC_87306; | 3978 | return FDC_87306; |
4001 | default: | 3979 | default: |
4002 | printk(KERN_INFO | 3980 | pr_info("FDC %d init: 82078 variant with unknown PARTID=%d.\n", |
4003 | "FDC %d init: 82078 variant with unknown PARTID=%d.\n", | 3981 | fdc, reply_buffer[0] >> 5); |
4004 | fdc, reply_buffer[0] >> 5); | ||
4005 | return FDC_82078_UNKN; | 3982 | return FDC_82078_UNKN; |
4006 | } | 3983 | } |
4007 | } /* get_fdc_version */ | 3984 | } /* get_fdc_version */ |
@@ -4113,9 +4090,9 @@ static int __init floppy_setup(char *str) | |||
4113 | else | 4090 | else |
4114 | param = config_params[i].def_param; | 4091 | param = config_params[i].def_param; |
4115 | if (config_params[i].fn) | 4092 | if (config_params[i].fn) |
4116 | config_params[i]. | 4093 | config_params[i].fn(ints, param, |
4117 | fn(ints, param, | 4094 | config_params[i]. |
4118 | config_params[i].param2); | 4095 | param2); |
4119 | if (config_params[i].var) { | 4096 | if (config_params[i].var) { |
4120 | DPRINT("%s=%d\n", str, param); | 4097 | DPRINT("%s=%d\n", str, param); |
4121 | *config_params[i].var = param; | 4098 | *config_params[i].var = param; |
@@ -4129,8 +4106,8 @@ static int __init floppy_setup(char *str) | |||
4129 | 4106 | ||
4130 | DPRINT("allowed options are:"); | 4107 | DPRINT("allowed options are:"); |
4131 | for (i = 0; i < ARRAY_SIZE(config_params); i++) | 4108 | for (i = 0; i < ARRAY_SIZE(config_params); i++) |
4132 | printk(" %s", config_params[i].name); | 4109 | pr_cont(" %s", config_params[i].name); |
4133 | printk("\n"); | 4110 | pr_cont("\n"); |
4134 | } else | 4111 | } else |
4135 | DPRINT("botched floppy option\n"); | 4112 | DPRINT("botched floppy option\n"); |
4136 | DPRINT("Read Documentation/blockdev/floppy.txt\n"); | 4113 | DPRINT("Read Documentation/blockdev/floppy.txt\n"); |
@@ -4148,7 +4125,8 @@ static ssize_t floppy_cmos_show(struct device *dev, | |||
4148 | drive = p->id; | 4125 | drive = p->id; |
4149 | return sprintf(buf, "%X\n", UDP->cmos); | 4126 | return sprintf(buf, "%X\n", UDP->cmos); |
4150 | } | 4127 | } |
4151 | DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); | 4128 | |
4129 | DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL); | ||
4152 | 4130 | ||
4153 | static void floppy_device_release(struct device *dev) | 4131 | static void floppy_device_release(struct device *dev) |
4154 | { | 4132 | { |
@@ -4160,7 +4138,7 @@ static int floppy_resume(struct device *dev) | |||
4160 | 4138 | ||
4161 | for (fdc = 0; fdc < N_FDC; fdc++) | 4139 | for (fdc = 0; fdc < N_FDC; fdc++) |
4162 | if (FDCS->address != -1) | 4140 | if (FDCS->address != -1) |
4163 | user_reset_fdc(-1, FD_RESET_ALWAYS, 0); | 4141 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); |
4164 | 4142 | ||
4165 | return 0; | 4143 | return 0; |
4166 | } | 4144 | } |
@@ -4172,8 +4150,8 @@ static const struct dev_pm_ops floppy_pm_ops = { | |||
4172 | 4150 | ||
4173 | static struct platform_driver floppy_driver = { | 4151 | static struct platform_driver floppy_driver = { |
4174 | .driver = { | 4152 | .driver = { |
4175 | .name = "floppy", | 4153 | .name = "floppy", |
4176 | .pm = &floppy_pm_ops, | 4154 | .pm = &floppy_pm_ops, |
4177 | }, | 4155 | }, |
4178 | }; | 4156 | }; |
4179 | 4157 | ||
@@ -4245,16 +4223,16 @@ static int __init floppy_init(void) | |||
4245 | else | 4223 | else |
4246 | floppy_sizes[i] = MAX_DISK_SIZE << 1; | 4224 | floppy_sizes[i] = MAX_DISK_SIZE << 1; |
4247 | 4225 | ||
4248 | reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT); | 4226 | reschedule_timeout(MAXTIMEOUT, "floppy init"); |
4249 | config_types(); | 4227 | config_types(); |
4250 | 4228 | ||
4251 | for (i = 0; i < N_FDC; i++) { | 4229 | for (i = 0; i < N_FDC; i++) { |
4252 | fdc = i; | 4230 | fdc = i; |
4253 | CLEARSTRUCT(FDCS); | 4231 | memset(FDCS, 0, sizeof(*FDCS)); |
4254 | FDCS->dtr = -1; | 4232 | FDCS->dtr = -1; |
4255 | FDCS->dor = 0x4; | 4233 | FDCS->dor = 0x4; |
4256 | #if defined(__sparc__) || defined(__mc68000__) | 4234 | #if defined(__sparc__) || defined(__mc68000__) |
4257 | /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ | 4235 | /*sparcs/sun3x don't have a DOR reset which we can fall back on to */ |
4258 | #ifdef __mc68000__ | 4236 | #ifdef __mc68000__ |
4259 | if (MACH_IS_SUN3X) | 4237 | if (MACH_IS_SUN3X) |
4260 | #endif | 4238 | #endif |
@@ -4283,11 +4261,11 @@ static int __init floppy_init(void) | |||
4283 | 4261 | ||
4284 | /* initialise drive state */ | 4262 | /* initialise drive state */ |
4285 | for (drive = 0; drive < N_DRIVE; drive++) { | 4263 | for (drive = 0; drive < N_DRIVE; drive++) { |
4286 | CLEARSTRUCT(UDRS); | 4264 | memset(UDRS, 0, sizeof(*UDRS)); |
4287 | CLEARSTRUCT(UDRWE); | 4265 | memset(UDRWE, 0, sizeof(*UDRWE)); |
4288 | USETF(FD_DISK_NEWCHANGE); | 4266 | set_bit(FD_DISK_NEWCHANGE_BIT, &UDRS->flags); |
4289 | USETF(FD_DISK_CHANGED); | 4267 | set_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); |
4290 | USETF(FD_VERIFY); | 4268 | set_bit(FD_VERIFY_BIT, &UDRS->flags); |
4291 | UDRS->fd_device = -1; | 4269 | UDRS->fd_device = -1; |
4292 | floppy_track_buffer = NULL; | 4270 | floppy_track_buffer = NULL; |
4293 | max_buffer_sectors = 0; | 4271 | max_buffer_sectors = 0; |
@@ -4307,7 +4285,7 @@ static int __init floppy_init(void) | |||
4307 | if (FDCS->address == -1) | 4285 | if (FDCS->address == -1) |
4308 | continue; | 4286 | continue; |
4309 | FDCS->rawcmd = 2; | 4287 | FDCS->rawcmd = 2; |
4310 | if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { | 4288 | if (user_reset_fdc(-1, FD_RESET_ALWAYS, false)) { |
4311 | /* free ioports reserved by floppy_grab_irq_and_dma() */ | 4289 | /* free ioports reserved by floppy_grab_irq_and_dma() */ |
4312 | floppy_release_regions(fdc); | 4290 | floppy_release_regions(fdc); |
4313 | FDCS->address = -1; | 4291 | FDCS->address = -1; |
@@ -4330,12 +4308,12 @@ static int __init floppy_init(void) | |||
4330 | * properly, so force a reset for the standard FDC clones, | 4308 | * properly, so force a reset for the standard FDC clones, |
4331 | * to avoid interrupt garbage. | 4309 | * to avoid interrupt garbage. |
4332 | */ | 4310 | */ |
4333 | user_reset_fdc(-1, FD_RESET_ALWAYS, 0); | 4311 | user_reset_fdc(-1, FD_RESET_ALWAYS, false); |
4334 | } | 4312 | } |
4335 | fdc = 0; | 4313 | fdc = 0; |
4336 | del_timer(&fd_timeout); | 4314 | del_timer(&fd_timeout); |
4337 | current_drive = 0; | 4315 | current_drive = 0; |
4338 | initialising = 0; | 4316 | initialized = true; |
4339 | if (have_no_fdc) { | 4317 | if (have_no_fdc) { |
4340 | DPRINT("no floppy controllers found\n"); | 4318 | DPRINT("no floppy controllers found\n"); |
4341 | err = have_no_fdc; | 4319 | err = have_no_fdc; |
@@ -4356,7 +4334,8 @@ static int __init floppy_init(void) | |||
4356 | if (err) | 4334 | if (err) |
4357 | goto out_flush_work; | 4335 | goto out_flush_work; |
4358 | 4336 | ||
4359 | err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); | 4337 | err = device_create_file(&floppy_device[drive].dev, |
4338 | &dev_attr_cmos); | ||
4360 | if (err) | 4339 | if (err) |
4361 | goto out_unreg_platform_dev; | 4340 | goto out_unreg_platform_dev; |
4362 | 4341 | ||
@@ -4420,8 +4399,10 @@ static int floppy_request_regions(int fdc) | |||
4420 | const struct io_region *p; | 4399 | const struct io_region *p; |
4421 | 4400 | ||
4422 | for (p = io_regions; p < ARRAY_END(io_regions); p++) { | 4401 | for (p = io_regions; p < ARRAY_END(io_regions); p++) { |
4423 | if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { | 4402 | if (!request_region(FDCS->address + p->offset, |
4424 | DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); | 4403 | p->size, "floppy")) { |
4404 | DPRINT("Floppy io-port 0x%04lx in use\n", | ||
4405 | FDCS->address + p->offset); | ||
4425 | floppy_release_allocated_regions(fdc, p); | 4406 | floppy_release_allocated_regions(fdc, p); |
4426 | return -EBUSY; | 4407 | return -EBUSY; |
4427 | } | 4408 | } |
@@ -4512,11 +4493,9 @@ cleanup: | |||
4512 | static void floppy_release_irq_and_dma(void) | 4493 | static void floppy_release_irq_and_dma(void) |
4513 | { | 4494 | { |
4514 | int old_fdc; | 4495 | int old_fdc; |
4515 | #ifdef FLOPPY_SANITY_CHECK | ||
4516 | #ifndef __sparc__ | 4496 | #ifndef __sparc__ |
4517 | int drive; | 4497 | int drive; |
4518 | #endif | 4498 | #endif |
4519 | #endif | ||
4520 | long tmpsize; | 4499 | long tmpsize; |
4521 | unsigned long tmpaddr; | 4500 | unsigned long tmpaddr; |
4522 | unsigned long flags; | 4501 | unsigned long flags; |
@@ -4547,20 +4526,18 @@ static void floppy_release_irq_and_dma(void) | |||
4547 | buffer_min = buffer_max = -1; | 4526 | buffer_min = buffer_max = -1; |
4548 | fd_dma_mem_free(tmpaddr, tmpsize); | 4527 | fd_dma_mem_free(tmpaddr, tmpsize); |
4549 | } | 4528 | } |
4550 | #ifdef FLOPPY_SANITY_CHECK | ||
4551 | #ifndef __sparc__ | 4529 | #ifndef __sparc__ |
4552 | for (drive = 0; drive < N_FDC * 4; drive++) | 4530 | for (drive = 0; drive < N_FDC * 4; drive++) |
4553 | if (timer_pending(motor_off_timer + drive)) | 4531 | if (timer_pending(motor_off_timer + drive)) |
4554 | printk("motor off timer %d still active\n", drive); | 4532 | pr_info("motor off timer %d still active\n", drive); |
4555 | #endif | 4533 | #endif |
4556 | 4534 | ||
4557 | if (timer_pending(&fd_timeout)) | 4535 | if (timer_pending(&fd_timeout)) |
4558 | printk("floppy timer still active:%s\n", timeout_message); | 4536 | pr_info("floppy timer still active:%s\n", timeout_message); |
4559 | if (timer_pending(&fd_timer)) | 4537 | if (timer_pending(&fd_timer)) |
4560 | printk("auxiliary floppy timer still active\n"); | 4538 | pr_info("auxiliary floppy timer still active\n"); |
4561 | if (work_pending(&floppy_work)) | 4539 | if (work_pending(&floppy_work)) |
4562 | printk("work still pending\n"); | 4540 | pr_info("work still pending\n"); |
4563 | #endif | ||
4564 | old_fdc = fdc; | 4541 | old_fdc = fdc; |
4565 | for (fdc = 0; fdc < N_FDC; fdc++) | 4542 | for (fdc = 0; fdc < N_FDC; fdc++) |
4566 | if (FDCS->address != -1) | 4543 | if (FDCS->address != -1) |
@@ -4577,7 +4554,9 @@ static void __init parse_floppy_cfg_string(char *cfg) | |||
4577 | char *ptr; | 4554 | char *ptr; |
4578 | 4555 | ||
4579 | while (*cfg) { | 4556 | while (*cfg) { |
4580 | for (ptr = cfg; *cfg && *cfg != ' ' && *cfg != '\t'; cfg++) ; | 4557 | ptr = cfg; |
4558 | while (*cfg && *cfg != ' ' && *cfg != '\t') | ||
4559 | cfg++; | ||
4581 | if (*cfg) { | 4560 | if (*cfg) { |
4582 | *cfg = '\0'; | 4561 | *cfg = '\0'; |
4583 | cfg++; | 4562 | cfg++; |
@@ -4625,6 +4604,7 @@ static void __exit floppy_module_exit(void) | |||
4625 | /* eject disk, if any */ | 4604 | /* eject disk, if any */ |
4626 | fd_eject(0); | 4605 | fd_eject(0); |
4627 | } | 4606 | } |
4607 | |||
4628 | module_exit(floppy_module_exit); | 4608 | module_exit(floppy_module_exit); |
4629 | 4609 | ||
4630 | module_param(floppy, charp, 0); | 4610 | module_param(floppy, charp, 0); |
@@ -4636,9 +4616,10 @@ MODULE_LICENSE("GPL"); | |||
4636 | 4616 | ||
4637 | /* This doesn't actually get used other than for module information */ | 4617 | /* This doesn't actually get used other than for module information */ |
4638 | static const struct pnp_device_id floppy_pnpids[] = { | 4618 | static const struct pnp_device_id floppy_pnpids[] = { |
4639 | { "PNP0700", 0 }, | 4619 | {"PNP0700", 0}, |
4640 | { } | 4620 | {} |
4641 | }; | 4621 | }; |
4622 | |||
4642 | MODULE_DEVICE_TABLE(pnp, floppy_pnpids); | 4623 | MODULE_DEVICE_TABLE(pnp, floppy_pnpids); |
4643 | 4624 | ||
4644 | #else | 4625 | #else |
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index a808b1530b3b..eb2091aa1c19 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c | |||
@@ -476,7 +476,9 @@ static void class_osdblk_release(struct class *cls) | |||
476 | kfree(cls); | 476 | kfree(cls); |
477 | } | 477 | } |
478 | 478 | ||
479 | static ssize_t class_osdblk_list(struct class *c, char *data) | 479 | static ssize_t class_osdblk_list(struct class *c, |
480 | struct class_attribute *attr, | ||
481 | char *data) | ||
480 | { | 482 | { |
481 | int n = 0; | 483 | int n = 0; |
482 | struct list_head *tmp; | 484 | struct list_head *tmp; |
@@ -500,7 +502,9 @@ static ssize_t class_osdblk_list(struct class *c, char *data) | |||
500 | return n; | 502 | return n; |
501 | } | 503 | } |
502 | 504 | ||
503 | static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) | 505 | static ssize_t class_osdblk_add(struct class *c, |
506 | struct class_attribute *attr, | ||
507 | const char *buf, size_t count) | ||
504 | { | 508 | { |
505 | struct osdblk_device *osdev; | 509 | struct osdblk_device *osdev; |
506 | ssize_t rc; | 510 | ssize_t rc; |
@@ -592,7 +596,9 @@ err_out_mod: | |||
592 | return rc; | 596 | return rc; |
593 | } | 597 | } |
594 | 598 | ||
595 | static ssize_t class_osdblk_remove(struct class *c, const char *buf, | 599 | static ssize_t class_osdblk_remove(struct class *c, |
600 | struct class_attribute *attr, | ||
601 | const char *buf, | ||
596 | size_t count) | 602 | size_t count) |
597 | { | 603 | { |
598 | struct osdblk_device *osdev = NULL; | 604 | struct osdblk_device *osdev = NULL; |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index b72935b8f203..39c8514442eb 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -284,7 +284,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, | |||
284 | return len; | 284 | return len; |
285 | } | 285 | } |
286 | 286 | ||
287 | static struct sysfs_ops kobj_pkt_ops = { | 287 | static const struct sysfs_ops kobj_pkt_ops = { |
288 | .show = kobj_pkt_show, | 288 | .show = kobj_pkt_show, |
289 | .store = kobj_pkt_store | 289 | .store = kobj_pkt_store |
290 | }; | 290 | }; |
@@ -337,7 +337,9 @@ static void class_pktcdvd_release(struct class *cls) | |||
337 | { | 337 | { |
338 | kfree(cls); | 338 | kfree(cls); |
339 | } | 339 | } |
340 | static ssize_t class_pktcdvd_show_map(struct class *c, char *data) | 340 | static ssize_t class_pktcdvd_show_map(struct class *c, |
341 | struct class_attribute *attr, | ||
342 | char *data) | ||
341 | { | 343 | { |
342 | int n = 0; | 344 | int n = 0; |
343 | int idx; | 345 | int idx; |
@@ -356,7 +358,9 @@ static ssize_t class_pktcdvd_show_map(struct class *c, char *data) | |||
356 | return n; | 358 | return n; |
357 | } | 359 | } |
358 | 360 | ||
359 | static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, | 361 | static ssize_t class_pktcdvd_store_add(struct class *c, |
362 | struct class_attribute *attr, | ||
363 | const char *buf, | ||
360 | size_t count) | 364 | size_t count) |
361 | { | 365 | { |
362 | unsigned int major, minor; | 366 | unsigned int major, minor; |
@@ -376,7 +380,9 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, | |||
376 | return -EINVAL; | 380 | return -EINVAL; |
377 | } | 381 | } |
378 | 382 | ||
379 | static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf, | 383 | static ssize_t class_pktcdvd_store_remove(struct class *c, |
384 | struct class_attribute *attr, | ||
385 | const char *buf, | ||
380 | size_t count) | 386 | size_t count) |
381 | { | 387 | { |
382 | unsigned int major, minor; | 388 | unsigned int major, minor; |
diff --git a/drivers/char/ChangeLog b/drivers/char/ChangeLog deleted file mode 100644 index 56b8a2e76ab1..000000000000 --- a/drivers/char/ChangeLog +++ /dev/null | |||
@@ -1,775 +0,0 @@ | |||
1 | 2001-08-11 Tim Waugh <twaugh@redhat.com> | ||
2 | |||
3 | * serial.c (get_pci_port): Deal with awkward Titan cards. | ||
4 | |||
5 | 1998-08-26 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
6 | |||
7 | * serial.c (rs_open): Correctly decrement the module in-use count | ||
8 | on errors. | ||
9 | |||
10 | Thu Feb 19 14:24:08 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
11 | |||
12 | * tty_io.c (tty_name): Remove the non-reentrant (and non-SMP safe) | ||
13 | version of tty_name, and rename the reentrant _tty_name | ||
14 | function to be tty_name. | ||
15 | (tty_open): Add a warning message stating callout devices | ||
16 | are deprecated. | ||
17 | |||
18 | Mon Dec 1 08:24:15 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
19 | |||
20 | * tty_io.c (tty_get_baud_rate): Print a warning syslog if the | ||
21 | tty->alt_speed kludge is used; this means the system is | ||
22 | using the deprecated SPD_HI ioctls. | ||
23 | |||
24 | Mon Nov 24 10:37:49 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
25 | |||
26 | * serial.c, esp.c, rocket.c: Change drivers to take advantage of | ||
27 | tty_get_baud_rate(). | ||
28 | |||
29 | * tty_io.c (tty_get_baud_rate): New function which computes the | ||
30 | correct baud rate for the tty. More factoring out of | ||
31 | common code out of the serial driver to the high-level tty | ||
32 | functions.... | ||
33 | |||
34 | Sat Nov 22 07:53:36 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
35 | |||
36 | * serial.c, esp.c, rocket.c: Add tty->driver.break() routine, and | ||
37 | allow high-level tty code to handle the break and soft | ||
38 | carrier ioctls. | ||
39 | |||
40 | * tty_ioctl.c (n_tty_ioctl): Support TIOCGSOFTCAR and | ||
41 | TIOCSSOFTCAR, so that device drivers don't have to support | ||
42 | it. | ||
43 | |||
44 | * serial.c (autoconfig): Change 16750 test to hopefully eliminate | ||
45 | false results by people with strange 16550As being | ||
46 | detected as 16750s. Hopefully 16750s will still be | ||
47 | detected as 16750, and other weird UARTs won't get poorly | ||
48 | autodetected. If this doesn't work, I'll have to disable | ||
49 | the auto identification for the 16750. | ||
50 | |||
51 | * tty_io.c (tty_hangup): Now actually do the tty hangup | ||
52 | processing during the timer processing, and disable | ||
53 | interrupts while doing the hangup processing. This avoids | ||
54 | several nasty race conditions which happened when the | ||
55 | hangup processing was done asynchronously. | ||
56 | (tty_ioctl): Do break handling in the tty driver if | ||
57 | driver's break function is supported. | ||
58 | (tty_flip_buffer_push): New exported function which should | ||
59 | be used by drivers to push characters in the flip buffer | ||
60 | to the tty handler. This may either be done using a task | ||
61 | queue function for better CPU efficiency, or directly for | ||
62 | low latency operation. | ||
63 | |||
64 | * serial.c (rs_set_termios): Fix bug rs_set_termios when | ||
65 | transitioning away from B0, submitted by Stanislav | ||
66 | Voronyi. | ||
67 | |||
68 | Thu Jun 19 20:05:58 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
69 | |||
70 | * serial.c (begin_break, end_break, rs_ioctl): Applied patch | ||
71 | to support BSD ioctls to set and clear the break | ||
72 | condition explicitly. | ||
73 | |||
74 | * console.c (scrup, scrdown, insert_line, delete_line): Applied | ||
75 | fix suggested by Aaron Tiensivu to speed up block scrolls | ||
76 | up and down. | ||
77 | |||
78 | * n_tty.c (opost_block, write_chan): Added a modified "fast | ||
79 | console" patch which processes a block of text via | ||
80 | "cooking" efficiently. | ||
81 | |||
82 | Wed Jun 18 15:25:50 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
83 | |||
84 | * tty_io.c (init_dev, release_dev): Applied fix suggested by Bill | ||
85 | Hawes to prevent race conditions in the tty code. | ||
86 | |||
87 | * n_tty.c (n_tty_chars_in_buffer): Applied fix suggested by Bill | ||
88 | Hawes so that n_tty_chars_in_buffer returns the correct | ||
89 | value in the case when the tty is in cannonical mode. (To | ||
90 | avoid a pty deadlock with telnetd.) | ||
91 | |||
92 | Thu Feb 27 01:53:08 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
93 | |||
94 | * serial.c (change_speed): Add support for the termios flag | ||
95 | CMSPAR, which allows the user to select stick parity. | ||
96 | (i.e, if PARODD is set, the parity bit is always 1; if | ||
97 | PARRODD is not set, then the parity bit is always 0). | ||
98 | |||
99 | Wed Feb 26 19:03:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
100 | |||
101 | * serial.c (cleanup_module): Fix memory leak when using the serial | ||
102 | driver as a module; make sure tmp_buf gets freed! | ||
103 | |||
104 | Tue Feb 25 11:01:59 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
105 | |||
106 | * serial.c (set_modem_info): Add support for setting and clearing | ||
107 | the OUT1 and OUT2 bits. (For special case UART's, usually | ||
108 | for half-duplex.) | ||
109 | (autoconfig, change_speed): Fix TI 16750 support. | ||
110 | |||
111 | Sun Feb 16 00:14:43 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
112 | |||
113 | * tty_io.c (release_dev): Add sanity check to make sure there are | ||
114 | no waiters on tty->read_wait or tty->write_wait. | ||
115 | |||
116 | * serial.c (rs_init): Don't autoconfig a device if the I/O region | ||
117 | is already reserved. | ||
118 | |||
119 | * serial.c (serial_proc_info): Add support for /proc/serial. | ||
120 | |||
121 | Thu Feb 13 00:49:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
122 | |||
123 | * serial.c (receive_chars): When the UART repotrs an overrun | ||
124 | condition, it does so with a valid character. Changed to | ||
125 | not throw away the valid character, but instead report the | ||
126 | overrun after the valid character. | ||
127 | |||
128 | * serial.c: Added new #ifdef's for some of the advanced serial | ||
129 | driver features. A minimal driver that only supports COM | ||
130 | 1/2/3/4 without sharing serial interrupts only takes 17k; | ||
131 | the full driver takes 32k. | ||
132 | |||
133 | Wed Feb 12 14:50:44 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
134 | |||
135 | * vt.c: | ||
136 | * pty.c: | ||
137 | * tty_ioctl.c: | ||
138 | * serial.c: Update routines to use the new 2.1 memory access | ||
139 | routines. | ||
140 | |||
141 | Wed Dec 4 07:51:52 1996 Theodore Ts'o <tytso@localhost.mit.edu> | ||
142 | |||
143 | * serial.c (change_speed): Use save_flags(); cli() and | ||
144 | restore_flags() in order to ensure we don't accidentally | ||
145 | turn on interrupts when starting up the port. | ||
146 | (startup): Move the insertion of serial structure into the | ||
147 | IRQ chain earlier into the startup processing. Interrupts | ||
148 | should be off this whole time, but we eventually will want | ||
149 | to reduce this window. | ||
150 | |||
151 | Thu Nov 21 10:05:22 1996 Theodore Ts'o <tytso@localhost.mit.edu> | ||
152 | |||
153 | * tty_ioctl.c (tty_wait_until_sent): Always check the driver | ||
154 | wait_until_ready routine, even if there are no characters | ||
155 | in the xmit buffer. (There may be charactes in the device | ||
156 | FIFO.) | ||
157 | (n_tty_ioctl): Add new flag tty->flow_stopped which | ||
158 | indicates whether the tty is stopped due to a request by | ||
159 | the TCXONC ioctl (used by tcflow). If so, don't let an | ||
160 | incoming XOFF character restart the tty. The tty can only | ||
161 | be restarted by another TCXONC request. | ||
162 | |||
163 | * tty_io.c (start_tty): Don't allow the tty to be restarted if | ||
164 | tty->flow_stopped is true. | ||
165 | |||
166 | * n_tty.c (n_tty_receive_char): If tty->flow_stopped is true, and | ||
167 | IXANY is set, don't eat a character trying to restart the | ||
168 | tty. | ||
169 | |||
170 | * serial.c (startup): Remove need for MCR_noint from the | ||
171 | async_struct structure. Only turn on DTR and RTS if the | ||
172 | baud rate is not zero. | ||
173 | (change_speed): More accurately calculate the timeout | ||
174 | value based on the word size. Move responsibility of | ||
175 | hangup when speed becomes B0 to rs_set_termios() | ||
176 | (set_serial_info): When changing the UART type set the | ||
177 | current xmit_fifo_size as well as the permanent | ||
178 | xmit_fifo_size. | ||
179 | (rs_ioctl): Fix TCSBRK (used by tcdrain) and TCSBRKP | ||
180 | ioctls to return EINTR if interrupted by a signal. | ||
181 | (rs_set_termios): If the baud rate changes to or from B0, | ||
182 | this function is now responsible for setting or clearing | ||
183 | DTR and RTS. DTR and RTS are only be changed on the | ||
184 | transition to or from the B0 state. | ||
185 | (rs_close): Wait for the characters to drain based on | ||
186 | info->timeout. At low baud rates (50 bps), it may take a | ||
187 | long time for the FIFO to completely drain out! | ||
188 | (rs_wait_until_sent): Fixed timeout handling. Now | ||
189 | releases control to the scheduler, but checks frequently | ||
190 | enough so that the function is sensitive enough to pass | ||
191 | the timing requirements of the NIST-PCTS. | ||
192 | (block_til_ready): When opening the device, don't turn on | ||
193 | DTR and RTS if the baud rate is B0. | ||
194 | |||
195 | Thu Nov 14 00:06:09 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
196 | |||
197 | * serial.c (autoconfig): Fix autoconfiguration problems; | ||
198 | info->flags wasn't getting initialized from the state | ||
199 | structure. Put in more paranoid test for the 16750. | ||
200 | |||
201 | Fri Nov 8 20:19:50 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
202 | |||
203 | * n_tty.c (n_tty_flush_buffer): Only call driver->unthrottle() if | ||
204 | the tty was previous throttled. | ||
205 | (n_tty_set_termios, write_chan): Add changes suggested by | ||
206 | Simon P. Allen to allow hardware cooking. | ||
207 | |||
208 | * tty_ioctl.c (set_termios): If we get a signal while waiting for | ||
209 | the tty to drain, return -EINTR. | ||
210 | |||
211 | * serial.c (change_speed): Add support for CREAD, as required by | ||
212 | POSIX. | ||
213 | |||
214 | Sat Nov 2 20:43:10 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
215 | |||
216 | * serial.c: Wholesale changes. Added support for the Startech | ||
217 | 16650 and 16650V2 chips. (WARNING: the new startech | ||
218 | 16650A may or may not work!) Added support for the | ||
219 | TI16750 (not yet tested). Split async_struct into a | ||
220 | transient part (async_struct) and a permanent part | ||
221 | (serial_state) which contains the configuration | ||
222 | information for the ports. Added new driver routines | ||
223 | wait_until_sent() and send_xchar() to help with POSIX | ||
224 | compliance. Added support for radio clocks which waggle | ||
225 | the carrier detect line (CONFIG_HARD_PPS). | ||
226 | |||
227 | * tty_ioctl.c (tty_wait_until_sent): Added call to new driver | ||
228 | function tty->driver.wait_until_sent(), which returns when | ||
229 | the tty's device xmit buffers are drained. Needed for | ||
230 | full POSIX compliance. | ||
231 | |||
232 | (send_prio_char): New function, called by the ioctl's | ||
233 | TCIOFF and TCION; uses the new driver call send_xchar(), | ||
234 | which will send the XON or XOFF character at high priority | ||
235 | (and even if tty output is stopped). | ||
236 | |||
237 | Wed Jun 5 18:52:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
238 | |||
239 | * pty.c (pty_close): When closing a pty, make sure packet mode is | ||
240 | cleared. | ||
241 | |||
242 | Sun May 26 09:33:52 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
243 | |||
244 | * vesa_blank.c (set_vesa_blanking): Add missing verify_area() call. | ||
245 | |||
246 | * selection.c (set_selection): Add missing verify_area() call. | ||
247 | |||
248 | * tty_io.c (tty_ioctl): Add missing verify_area() calls. | ||
249 | |||
250 | * serial.c (rs_ioctl): Add missing verify_area() calls. | ||
251 | (rs_init): Allow initialization of serial driver | ||
252 | configuration from a module. | ||
253 | |||
254 | * random.c (extract_entropy): Add missing verify_area call. | ||
255 | Don't limit number of characters returned to | ||
256 | 32,768. Extract entropy is now no longer a inlined | ||
257 | function. | ||
258 | |||
259 | (random_read): Check return value in case extract_entropy | ||
260 | returns an error. | ||
261 | |||
262 | (secure_tcp_sequence_number): New function which returns a | ||
263 | secure TCP sequence number. This is needed to prevent some | ||
264 | nasty TCP hijacking attacks. | ||
265 | |||
266 | (init_std_data): Initialize using gettimeofday() instead of | ||
267 | struct timeval xtime. | ||
268 | |||
269 | (fast_add_entropy_word, add_entropy_word): Rename the | ||
270 | inline function add_entropy_word() to | ||
271 | fast_add_entropy_word(). Make add_entropy_word() be the | ||
272 | non-inlined function which is used in non-timing critical | ||
273 | places, in order to save space. | ||
274 | |||
275 | (initialize_benchmark, begin_benchmark, end_benchmark): New | ||
276 | functions defined when RANDOM_BENCHMARK is defined. They | ||
277 | allow us to benchmark the speed of the | ||
278 | add_timer_randomness() call. | ||
279 | |||
280 | (int_ln, rotate_left): Add two new inline functions with | ||
281 | i386 optimized asm instructions. This speeds up the | ||
282 | critical add_entropy_word() and add_timer_randomness() | ||
283 | functions, which are called from interrupt handlers. | ||
284 | |||
285 | Tue May 7 22:51:11 1996 <tytso@rsts-11.mit.edu> | ||
286 | |||
287 | * random.c (add_timer_randomness): Limit the amount randomness | ||
288 | that we estimate to 12 bits. (An arbitrary amount). | ||
289 | |||
290 | (extract_entropy): To make it harder to analyze the hash | ||
291 | function, fold the hash function in half using XOR, and | ||
292 | use the folded result as the value to emit to the user. | ||
293 | Also, add timer randomness each pass through the | ||
294 | exact_entropy call, to increase the amount of unknown | ||
295 | values during the extraction process. | ||
296 | |||
297 | (random_ioctl): Use IOR/IOW definitions to define the | ||
298 | ioctl values used by the /dev/random driver. Allow the | ||
299 | old ioctl values to be used for backwards compatibility | ||
300 | (for a limited amount of time). | ||
301 | |||
302 | Wed Apr 24 14:02:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> | ||
303 | |||
304 | * random.c (add_timer_randomness): Use 2nd derivative as well to | ||
305 | better estimate entropy. | ||
306 | |||
307 | (rand_initialize): Explicitly initialize all the pointers | ||
308 | to NULL. (Clearing pointers using memset isn't portable.) | ||
309 | Initialize the random pool with OS-dependent data. | ||
310 | |||
311 | (random_write): Add sanity checking to the arguments to | ||
312 | random_write(), so that bad arguments won't cause a kernel | ||
313 | SEGV. | ||
314 | |||
315 | (random_read): Update the access time of the device inode | ||
316 | when you return data to the user. | ||
317 | |||
318 | (random_ioctl): Wake up the random_wait channel when there | ||
319 | are only WAIT_INPUT_BITS available. Add more paranoia | ||
320 | checks to make sure entropy_count doesn't go beyond the | ||
321 | bounds of (0, POOLSIZE). Add a few missing verify_area | ||
322 | checks. Add support for the RNDCLEARPOOL ioctl, which | ||
323 | zaps the random pool. | ||
324 | |||
325 | (add_timer_randomness): Wake up the random_wait | ||
326 | channel only when there are WAIT_INPUT_BITS available. | ||
327 | |||
328 | (random_select): Allow a random refresh daemon process to | ||
329 | select on /dev/random for writing; wake up the daemon when | ||
330 | there are less than WAIT_OUTPUT_BITS bits of randomness | ||
331 | available. | ||
332 | |||
333 | Tue Apr 23 22:56:07 1996 <tytso@rsts-11.mit.edu> | ||
334 | |||
335 | * tty_io.c (init_dev): Change return code when user attempts to | ||
336 | open master pty which is already open from EAGAIN to EIO, | ||
337 | to match with BSD expectations. EIO is more correct | ||
338 | anyway, since EAGAIN implies that retrying will be | ||
339 | successful --- which it might be.... Eventually!! | ||
340 | |||
341 | * pty.c (pty_open, pty_close): Fix wait loop so that we don't | ||
342 | busy loop while waiting for the master side to open. | ||
343 | Fix tty opening/closing logic. TTY_SLAVE_CLOSED was | ||
344 | renamed to TTY_OTHER_CLOSED, so that the name is more | ||
345 | descriptive. Also fixed code so that the tty flag | ||
346 | actually works correctly now.... | ||
347 | |||
348 | Mon Apr 1 10:22:01 1996 <tytso@rsts-11.mit.edu> | ||
349 | |||
350 | * serial.c (rs_close): Cleaned up modularization changes. | ||
351 | Remove code which forced line discipline back to N_TTY | ||
352 | this is done in the tty upper layers, and there's no | ||
353 | reason to do it here. (Making this change also | ||
354 | removed the requirement that the serial module access | ||
355 | the internal kernel symbol "ldiscs".) | ||
356 | |||
357 | * tty_io.c (tty_init): Formally register a tty_driver entry for | ||
358 | /dev/tty (device 4, 0) and /dev/console (device 5, 0). | ||
359 | This guarantees that major device numbers 4 and 5 will be | ||
360 | reserved for the tty subsystem (as they have to be because | ||
361 | of /dev/tty and /dev/console). Removed tty_regdev, as | ||
362 | this interface is no longer necessary. | ||
363 | |||
364 | Sun Mar 17 20:42:47 GMT 1996 <ah@doc.ic.ac.uk> | ||
365 | |||
366 | * serial.c : modularisation (changes in linux/fs/device.c allow | ||
367 | kerneld to automatically load the serial module). | ||
368 | |||
369 | * Makefile, Config.in : serial modularisation adds. | ||
370 | |||
371 | * tty_io.c : tty_init_ctty used by to register "cua" driver just | ||
372 | for the /dev/tty device (5,0). Added tty_regdev. | ||
373 | |||
374 | * serial.c (shutdown, rs_ioctl) : when port shuts down wakeup processes | ||
375 | waiting on delta_msr_wait. The TIOCMIWAIT ioctl returns EIO | ||
376 | if no change was done since the time of call. | ||
377 | |||
378 | Sat Mar 16 14:33:13 1996 <aeb@cwi.nl> | ||
379 | |||
380 | * tty_io.c (disassociate_ctty): If disassociate_ctty is called by | ||
381 | exit, do not perform an implicit vhangup on a pty. | ||
382 | |||
383 | Fri Feb 9 14:15:47 1996 <tytso@rsts-11.mit.edu> | ||
384 | |||
385 | * serial.c (block_til_ready): Fixed another race condition which | ||
386 | happens if a hangup happens during the open. | ||
387 | |||
388 | Wed Jan 10 10:08:00 1996 <tytso@rsts-11.mit.edu> | ||
389 | |||
390 | * serial.c (block_til_ready): Remove race condition which happened | ||
391 | if a hangup condition happened during the setup of the | ||
392 | UART, before rs_open() called block_til_ready(). This | ||
393 | caused the info->count counter to be erroneously | ||
394 | decremented. | ||
395 | |||
396 | * serial.c (startup, rs_open): Remove race condition that could | ||
397 | cause a memory leak of one page. (Fortunately, both race | ||
398 | conditions were relatively rare in practice.) | ||
399 | |||
400 | Tue Dec 5 13:21:27 1995 <tytso@rsts-11.mit.edu> | ||
401 | |||
402 | * serial.c (check_modem_status, rs_ioctl): Support the new | ||
403 | ioctl()'s TIOCGICOUNT, TIOCMIWAIT. These allow an | ||
404 | application program to wait on a modem serial register | ||
405 | status bit change, and to find out how many changes have | ||
406 | taken place for the MSR bits. | ||
407 | |||
408 | (rs_write): Eliminate a race condition which is introduced | ||
409 | if it is necessary to wait for the semaphore. | ||
410 | |||
411 | Sat Nov 4 17:14:45 1995 <tytso@rsts-11.mit.edu> | ||
412 | |||
413 | * tty_io.c (tty_init): Move registration of TTY_MAJOR and | ||
414 | TTY_AUX_MAJOR to the end, so that /proc/devices looks | ||
415 | prettier. | ||
416 | |||
417 | * pty.c (pty_init): Use new major numbers for PTY master and slave | ||
418 | devices. This allow us to have more than 64 pty's. We | ||
419 | register the old pty devices for backwards compatibility. | ||
420 | Note that a system should either be using the old pty | ||
421 | devices or the new pty devices --- in general, it should | ||
422 | try to use both, since they map into the same pty table. | ||
423 | The old pty devices are strictly for backwards compatibility. | ||
424 | |||
425 | Wed Oct 11 12:45:24 1995 <tytso@rsts-11.mit.edu> | ||
426 | |||
427 | * tty_io.c (disassociate_ctty): If disassociate_ctty is called by | ||
428 | exit, perform an implicit vhangup on the tty. | ||
429 | |||
430 | * pty.c (pty_close): When the master pty is closed, send a hangup | ||
431 | to the slave pty. | ||
432 | (pty_open): Use the flag TTY_SLAVE_CLOSED to test to see | ||
433 | if there are any open slave ptys, instead of using | ||
434 | tty->link->count. The old method got confused if there | ||
435 | were processes that had hung-up file descriptors on the | ||
436 | slave tty. | ||
437 | |||
438 | Tue May 2 00:53:25 1995 <tytso@rsx-11.mit.edu> | ||
439 | |||
440 | * tty_io.c (tty_set_ldisc): Wait until the output buffer is | ||
441 | drained before closing the old line discipline --- needed | ||
442 | in only one case: XON/XOFF processing. | ||
443 | |||
444 | * n_tty.c (n_tty_close): Don't bother waiting until the output | ||
445 | driver is closed; in general, the line discipline | ||
446 | shouldn't care if the hardware is finished | ||
447 | transmitting before the line discipline terminates. | ||
448 | |||
449 | * tty_io.c (release_dev): Shutdown the line discipline after | ||
450 | decrementing the tty count variable; but set the | ||
451 | TTY_CLOSING flag so that we know that this tty structure | ||
452 | isn't long for this world. | ||
453 | |||
454 | * tty_io.c (init_dev): Add sanity code to check to see if | ||
455 | TTY_CLOSING is set on a tty structure; if so, something | ||
456 | bad has happened (probably a line discipline close blocked | ||
457 | when it shouldn't have; so do a kernel printk and then | ||
458 | return an error). | ||
459 | |||
460 | Wed Apr 26 10:23:44 1995 Theodore Y. Ts'o <tytso@localhost> | ||
461 | |||
462 | * tty_io.c (release_dev): Try to shutdown the line discipline | ||
463 | *before* decrementing the tty count variable; this removes | ||
464 | a potential race condition which occurs when the line | ||
465 | discipline close blocks, and another process then tries | ||
466 | open the same serial port. | ||
467 | |||
468 | * serial.c (rs_hangup): When hanging up, flush the output buffer | ||
469 | before shutting down the UART. Otherwise the line | ||
470 | discipline close blocks waiting for the characters to get | ||
471 | flushed, which never happens until the serial port gets reused. | ||
472 | |||
473 | Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost> | ||
474 | |||
475 | * serial.c (do_serial_hangup, do_softint, check_modem_status, | ||
476 | rs_init): Hangups are now scheduled via a separate tqueue | ||
477 | structure in the async_struct structure, tqueue_hangup. | ||
478 | This task is pushed on to the tq_schedule queue, so that | ||
479 | it is processed synchronously by the scheduler. | ||
480 | |||
481 | Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
482 | |||
483 | * tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear | ||
484 | current->tty_old_pgrp field when a session leader | ||
485 | acquires a controlling tty, and after a session leader | ||
486 | has disassociated from a controlling tty. | ||
487 | |||
488 | Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
489 | |||
490 | * serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi): | ||
491 | Change the number of passes made from 64 to be 256, | ||
492 | configurable with the #define RS_ISR_PASS_LIMIT. | ||
493 | |||
494 | * serial.c (rs_init, set_serial_info, get_serial_info, rs_close): | ||
495 | Remove support for closing_wait2. Instead, set | ||
496 | tty->closing and rely on the line discipline to prevent | ||
497 | echo wars. | ||
498 | |||
499 | * n_tty.c (n_tty_receive_char): IEXTEN does not need to be | ||
500 | enabled in order for IXANY to be active. | ||
501 | |||
502 | If tty->closing is set, then only process XON and XOFF | ||
503 | characters. | ||
504 | |||
505 | Sun Feb 12 23:57:48 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
506 | |||
507 | * serial.c (rs_timer): Change the interrupt poll time from 60 | ||
508 | seconds to 10 seconds, configurable with the #define | ||
509 | RS_STROBE_TIME. | ||
510 | |||
511 | * serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl, | ||
512 | set_multiport_struct, get_multiport_struct): Add | ||
513 | provisions for a new type of interrupt service routine, | ||
514 | which better supports multiple serial ports on a single | ||
515 | IRQ. | ||
516 | |||
517 | Sun Feb 5 19:35:11 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
518 | |||
519 | * tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent): | ||
520 | * serial.c (rs_ioctl, rs_close): | ||
521 | * cyclades.c (cy_ioctl, cy_close): | ||
522 | * n_tty.c (n_tty_close): Rename wait_until_sent to | ||
523 | tty_wait_until_sent, so that it's a better name to export | ||
524 | in ksyms.c. | ||
525 | |||
526 | Sat Feb 4 23:36:20 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
527 | |||
528 | * serial.c (rs_close): Added missing check for closing_wait2 being | ||
529 | ASYNC_CLOSING_WAIT_NONE. | ||
530 | |||
531 | Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
532 | |||
533 | * serial.c (rs_init, set_serial_info, get_serial_info, | ||
534 | rs_close): Support close_wait in the serial driver. | ||
535 | This is helpful for slow devices (like serial | ||
536 | plotters) so that their outputs don't get flushed upon | ||
537 | device close. This has to be configurable because | ||
538 | normally we don't want ports to be hung up for long | ||
539 | periods of time during a close when they are not | ||
540 | connected to a device, or the device is powered off. | ||
541 | |||
542 | The default is to wait 30 seconds; in the case of a | ||
543 | very slow device, the close_wait timeout should be | ||
544 | lengthened. If it is set to 0, the kernel will wait | ||
545 | forever for all of the data to be transmitted. | ||
546 | |||
547 | Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11) | ||
548 | |||
549 | * serial.c (startup, change_speed, rs_init): Add support to detect | ||
550 | the StarTech 16650 chip. Treat it as a 16450 for now, | ||
551 | because of its FIFO bugs. | ||
552 | |||
553 | Thu Jan 5 21:21:57 1995 <dahinds@users.sourceforge.net> | ||
554 | |||
555 | * serial.c: (receive_char): Added counter to prevent infinite loop | ||
556 | when a PCMCIA serial device is ejected. | ||
557 | |||
558 | Thu Dec 29 17:53:48 1994 <tytso@rsx-11.mit.edu> | ||
559 | |||
560 | * tty_io.c (check_tty_count): New procedure which checks | ||
561 | tty->count to make sure that it matches with the number of | ||
562 | open file descriptors which point at the structure. If | ||
563 | the number doesn't match, it prints a warning message. | ||
564 | |||
565 | Wed Dec 28 15:41:51 1994 <tytso@rsx-11.mit.edu> | ||
566 | |||
567 | * tty_io.c (do_tty_hangup, disassociate_ctty): At hangup time, | ||
568 | save the tty's current foreground process group in the | ||
569 | session leader's task structure. When the session leader | ||
570 | terminates, send a SIGHUP, SIGCONT to that process group. | ||
571 | This is not required by POSIX, but it's not prohibited | ||
572 | either, and it appears to be the least intrusive way | ||
573 | to fix a problem that dialup servers have with | ||
574 | orphaned process groups caused by modem hangups. | ||
575 | |||
576 | Thu Dec 8 14:52:11 1994 <tytso@rsx-11.mit.edu> | ||
577 | |||
578 | * serial.c (rs_ioctl): Don't allow most ioctl's if the serial port | ||
579 | isn't initialized. | ||
580 | |||
581 | * serial.c (rs_close): Don't clear the IER if the serial port | ||
582 | isn't initialized. | ||
583 | |||
584 | * serial.c (block_til_ready): Don't try to block on the dialin | ||
585 | port if the serial port isn't initialized. | ||
586 | |||
587 | Wed Dec 7 10:48:30 1994 Si Park (si@wimpol.demon.co.uk) | ||
588 | * tty_io.c (tty_register_driver): Fix bug when linking onto | ||
589 | the tty_drivers list. We now test that there are elements | ||
590 | already on the list before setting the back link from the | ||
591 | first element to the new driver. | ||
592 | |||
593 | * tty_io.c (tty_unregister_driver): Fix bug in unlinking the | ||
594 | specified driver from the tty_drivers list. We were not | ||
595 | setting the back link correctly. This used to result in | ||
596 | a dangling back link pointer and cause panics on the next | ||
597 | call to get_tty_driver(). | ||
598 | |||
599 | Tue Nov 29 10:21:09 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
600 | |||
601 | * tty_io.c (tty_unregister_driver): Fix bug in | ||
602 | tty_unregister_driver where the pointer to the refcount is | ||
603 | tested, instead of the refcount itself. This caused | ||
604 | tty_unregister_driver to always return EBUSY. | ||
605 | |||
606 | Sat Nov 26 11:59:24 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
607 | |||
608 | * tty_io.c (tty_ioctl): Add support for the new ioctl | ||
609 | TIOCTTYGSTRUCT, which allow a kernel debugging program | ||
610 | direct read access to the tty and tty_driver structures. | ||
611 | |||
612 | Fri Nov 25 17:26:22 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
613 | |||
614 | * serial.c (rs_set_termios): Don't wake up processes blocked in | ||
615 | open when the CLOCAL flag changes, since a blocking | ||
616 | open only samples the CLOCAL flag once when it blocks, | ||
617 | and doesn't check it again. (n.b. FreeBSD has a | ||
618 | different behavior for blocking opens; it's not clear | ||
619 | whether Linux or FreeBSD's interpretation is correct. | ||
620 | POSIX doesn't give clear guidance on this issue, so | ||
621 | this may change in the future....) | ||
622 | |||
623 | * serial.c (block_til_ready): Use the correct termios structure to | ||
624 | check the CLOCAL flag. If the cuaXX device is active, | ||
625 | then check the saved termios for the ttySXX device. | ||
626 | Otherwise, use the currently active termios structure. | ||
627 | |||
628 | Sun Nov 6 21:05:44 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
629 | |||
630 | * serial.c (change_speed): Add support for direct access of | ||
631 | 57,600 and 115,200 bps. | ||
632 | |||
633 | Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
634 | |||
635 | * n_tty.c (n_tty_receive_room): Only allow excess characters | ||
636 | through if we are in ICANON mode *and* there are other no | ||
637 | pending lines in the buffer. Otherwise cut and paste over | ||
638 | 4k breaks. | ||
639 | |||
640 | Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
641 | |||
642 | * serial.c (rs_ioctl, get_lsr_info): Added patch suggested by Arne | ||
643 | Riiber so that user mode programs can tell when the | ||
644 | transmitter shift register is empty. | ||
645 | |||
646 | Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
647 | |||
648 | * tty_ioctl.c (wait_until_sent): Added debugging printk statements | ||
649 | (under the #ifdef TTY_DEBUG_WAIT_UNTIL_SENT) | ||
650 | |||
651 | * serial.c (rs_interrupt, rs_interrupt_single, receive_chars, | ||
652 | change_speed, rs_close): rs_close now disables receiver | ||
653 | interrupts when closing the serial port. This allows the | ||
654 | serial port to close quickly when Linux and a modem (or a | ||
655 | mouse) are engaged in an echo war; when closing the serial | ||
656 | port, we now first stop listening to incoming characters, | ||
657 | and *then* wait for the transmit buffer to drain. | ||
658 | |||
659 | In order to make this change, the info->read_status_mask | ||
660 | is now used to control what bits of the line status | ||
661 | register are looked at in the interrupt routine in all | ||
662 | cases; previously it was only used in receive_chars to | ||
663 | select a few of the status bits. | ||
664 | |||
665 | Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
666 | |||
667 | * serial.c (rs_close): Add a timeout to the transmitter flush | ||
668 | loop; this is just a sanity check in case we have flaky | ||
669 | (or non-existent-but-configured-by-the-user) hardware. | ||
670 | |||
671 | Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
672 | |||
673 | * tty_io.c (tty_fasync): When asynchronous I/O is enabled, if the | ||
674 | process or process group has not be specified yet, set it | ||
675 | to be the tty's process group, or if that is not yet set, | ||
676 | to the current process's pid. | ||
677 | |||
678 | Thu Oct 20 23:17:28 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
679 | |||
680 | * n_tty.c (n_tty_receive_room): If we are doing input | ||
681 | canonicalization, let as many characters through as | ||
682 | possible, so that the excess characters can be "beeped". | ||
683 | |||
684 | Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
685 | |||
686 | * serial.c (rs_start): Removed an incorrect '!' that was | ||
687 | preventing transmit interrupts from being re-enabled in | ||
688 | rs_start(). Fortunately in most cases it would be | ||
689 | re-enabled elsewhere, but this still should be fixed | ||
690 | correctly. | ||
691 | |||
692 | Sun Oct 9 23:46:03 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
693 | |||
694 | * tty_io.c (do_tty_hangup): If the tty driver flags | ||
695 | TTY_DRIVER_RESET_TERMIOS is set, then reset the termios | ||
696 | settings back to the driver's initial configuration. This | ||
697 | allows the termios settings to be reset even if a process | ||
698 | has hung up file descriptors keeping a pty's termios from | ||
699 | being freed and reset. | ||
700 | |||
701 | * tty_io.c (release_dev): Fix memory leak. The pty's other | ||
702 | termios structure should also be freed. | ||
703 | |||
704 | * serial.c (rs_close, shutdown): Change how we wait for the | ||
705 | transmitter to completely drain before shutting down the | ||
706 | serial port. We now do it by scheduling in another | ||
707 | process instead of busy looping with the interrupts turned | ||
708 | on. This may eliminate some race condition problems that | ||
709 | some people seem to be reporting. | ||
710 | |||
711 | Sun Sep 25 14:18:14 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
712 | |||
713 | * tty_io.c (release_dev): When freeing a tty make sure that both | ||
714 | the tty and the o_tty (if present) aren't a process's | ||
715 | controlling tty. (Previously, we only checked the tty.) | ||
716 | |||
717 | * serial.c (change_speed): Only enable the Modem Status | ||
718 | Interrupt for a port if CLOCAL is not set or CRTSCTS | ||
719 | is set. If we're not checking the carrier detect and | ||
720 | CTS line, there's no point in enabling the modem | ||
721 | status interrupt. This will save spurious interrupts | ||
722 | from slowing down systems who have terminals that | ||
723 | don't support either line. (Of course, if you want | ||
724 | only one of CD and CTS support, you will need a | ||
725 | properly wired serial cable.) | ||
726 | |||
727 | Thu Sep 22 08:32:48 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
728 | |||
729 | * tty_io.c (do_SAK): Return if tty is null. | ||
730 | |||
731 | * tty_io.c (_tty_name): Return "NULL tty" if the passed in tty is | ||
732 | NULL. | ||
733 | |||
734 | Sat Sep 17 13:19:25 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
735 | |||
736 | * tty_ioctl.c (n_tty_ioctl): Fix TIOCGLCKTRMIOS and | ||
737 | TIOCSLCKTRMIOS, which were totally broken. Remove | ||
738 | extra indirection from argument; it should be a struct | ||
739 | termios *, not a struct termios **. | ||
740 | &real_tty->termios_locked should have been | ||
741 | real_tty->termios_locked. This caused us to be | ||
742 | reading and writing the termios_locked structure to | ||
743 | random places in kernel memory. | ||
744 | |||
745 | * tty_io.c (release_dev): Oops! Forgot to delete a critical kfree | ||
746 | of the locked_termios. This leaves the locked_termios | ||
747 | structure pointed at a freed object. | ||
748 | |||
749 | Fri Sep 16 08:13:25 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
750 | |||
751 | * tty_io.c (tty_open): Don't check for an exclusive open until | ||
752 | after the device specific open routine has been called. | ||
753 | Otherwise, the serial device ref counting will be screwed | ||
754 | up. | ||
755 | |||
756 | * serial.c (rs_open, block_til_ready): Don't set termios structure | ||
757 | until after block_til_ready has returned successfully. | ||
758 | Modify block_til_ready to check the normal_termios | ||
759 | structure directly, so it doesn't rely on termios being | ||
760 | set before it's called. | ||
761 | |||
762 | Thu Sep 15 23:34:01 1994 Theodore Y. Ts'o (tytso@rt-11) | ||
763 | |||
764 | * serial.c (rs_close): Turn off interrupts during rs_close() to | ||
765 | prevent a race condition with the hangup code (which | ||
766 | runs during a software interrupt). | ||
767 | |||
768 | * tty_io.c (release_dev): Don't free the locked_termios structure; | ||
769 | its state must be retained across device opens. | ||
770 | |||
771 | |||
772 | * tty_io.c (tty_unregister_driver): Added function to unregister a | ||
773 | tty driver. (For loadable device drivers.) | ||
774 | |||
775 | |||
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 2fb3a480f6b0..4b66c69eaf57 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -57,7 +57,7 @@ config AGP_AMD | |||
57 | 57 | ||
58 | config AGP_AMD64 | 58 | config AGP_AMD64 |
59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" | 59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" |
60 | depends on AGP && X86 | 60 | depends on AGP && X86 && K8_NB |
61 | help | 61 | help |
62 | This option gives you AGP support for the GLX component of | 62 | This option gives you AGP support for the GLX component of |
63 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. | 63 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 919a28558d36..a3e10dc7cc25 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -298,7 +298,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, | |||
298 | j++; | 298 | j++; |
299 | } | 299 | } |
300 | } else { | 300 | } else { |
301 | /* sg may merge pages, but we have to seperate | 301 | /* sg may merge pages, but we have to separate |
302 | * per-page addr for GTT */ | 302 | * per-page addr for GTT */ |
303 | unsigned int len, m; | 303 | unsigned int len, m; |
304 | 304 | ||
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index fe2cb2f5db17..a7424bf7eacf 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -14,7 +14,7 @@ | |||
14 | /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */ | 14 | /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */ |
15 | /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */ | 15 | /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */ |
16 | /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */ | 16 | /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */ |
17 | /* adresses de base des cartes, IOCTL 6 plus complet */ | 17 | /* addresses de base des cartes, IOCTL 6 plus complet */ |
18 | /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */ | 18 | /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */ |
19 | /* de code autre que le texte V2.6.1 en V2.8.0 */ | 19 | /* de code autre que le texte V2.6.1 en V2.8.0 */ |
20 | /*****************************************************************************/ | 20 | /*****************************************************************************/ |
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index fd0242676a2a..21c54955084e 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c | |||
@@ -353,7 +353,7 @@ static void hvc_close_event(struct HvLpEvent *event) | |||
353 | 353 | ||
354 | if (!hvlpevent_is_int(event)) { | 354 | if (!hvlpevent_is_int(event)) { |
355 | printk(KERN_WARNING | 355 | printk(KERN_WARNING |
356 | "hvc: got unexpected close acknowlegement\n"); | 356 | "hvc: got unexpected close acknowledgement\n"); |
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | 359 | ||
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index 21681a81cc35..37b0542a4eeb 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c | |||
@@ -139,6 +139,8 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num) | |||
139 | * | 139 | * |
140 | * This function allocates a new struct iucv_tty_buffer element and, optionally, | 140 | * This function allocates a new struct iucv_tty_buffer element and, optionally, |
141 | * allocates an internal data buffer with the specified size @size. | 141 | * allocates an internal data buffer with the specified size @size. |
142 | * The internal data buffer is always allocated with GFP_DMA which is | ||
143 | * required for receiving and sending data with IUCV. | ||
142 | * Note: The total message size arises from the internal buffer size and the | 144 | * Note: The total message size arises from the internal buffer size and the |
143 | * members of the iucv_tty_msg structure. | 145 | * members of the iucv_tty_msg structure. |
144 | * The function returns NULL if memory allocation has failed. | 146 | * The function returns NULL if memory allocation has failed. |
@@ -154,7 +156,7 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags) | |||
154 | 156 | ||
155 | if (size > 0) { | 157 | if (size > 0) { |
156 | bufp->msg.length = MSG_SIZE(size); | 158 | bufp->msg.length = MSG_SIZE(size); |
157 | bufp->mbuf = kmalloc(bufp->msg.length, flags); | 159 | bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA); |
158 | if (!bufp->mbuf) { | 160 | if (!bufp->mbuf) { |
159 | mempool_free(bufp, hvc_iucv_mempool); | 161 | mempool_free(bufp, hvc_iucv_mempool); |
160 | return NULL; | 162 | return NULL; |
@@ -237,7 +239,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv, | |||
237 | if (!rb->mbuf) { /* message not yet received ... */ | 239 | if (!rb->mbuf) { /* message not yet received ... */ |
238 | /* allocate mem to store msg data; if no memory is available | 240 | /* allocate mem to store msg data; if no memory is available |
239 | * then leave the buffer on the list and re-try later */ | 241 | * then leave the buffer on the list and re-try later */ |
240 | rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC); | 242 | rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA); |
241 | if (!rb->mbuf) | 243 | if (!rb->mbuf) |
242 | return -ENOMEM; | 244 | return -ENOMEM; |
243 | 245 | ||
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 9b3e09cd41f9..10f868eefaa6 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c | |||
@@ -71,7 +71,7 @@ MODULE_VERSION(DRV_MODULE_VERSION); | |||
71 | * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1 | 71 | * x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1 |
72 | * | 72 | * |
73 | * The RNG_CTL_VCO value of each noise cell must be programmed | 73 | * The RNG_CTL_VCO value of each noise cell must be programmed |
74 | * seperately. This is why 4 control register values must be provided | 74 | * separately. This is why 4 control register values must be provided |
75 | * to the hypervisor. During a write, the hypervisor writes them all, | 75 | * to the hypervisor. During a write, the hypervisor writes them all, |
76 | * one at a time, to the actual RNG_CTL register. The first three | 76 | * one at a time, to the actual RNG_CTL register. The first three |
77 | * values are used to setup the desired RNG_CTL_VCO for each entropy | 77 | * values are used to setup the desired RNG_CTL_VCO for each entropy |
diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h index 8aa6e7ab8d5b..c0ba6c05f0cd 100644 --- a/drivers/char/ip2/i2hw.h +++ b/drivers/char/ip2/i2hw.h | |||
@@ -559,7 +559,7 @@ Loadware may be sent to the board in two ways: | |||
559 | 559 | ||
560 | 2) It may be hard-coded into your source by including a .h file (typically | 560 | 2) It may be hard-coded into your source by including a .h file (typically |
561 | supplied by Computone), which declares a data array and initializes every | 561 | supplied by Computone), which declares a data array and initializes every |
562 | element. This acheives the same result as if an entire loadware file had | 562 | element. This achieves the same result as if an entire loadware file had |
563 | been read into the array. | 563 | been read into the array. |
564 | 564 | ||
565 | This requires more data space in your program, but access to the file system | 565 | This requires more data space in your program, but access to the file system |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 176f1751237f..4462b113ba3f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -295,6 +295,9 @@ struct smi_info { | |||
295 | static int force_kipmid[SI_MAX_PARMS]; | 295 | static int force_kipmid[SI_MAX_PARMS]; |
296 | static int num_force_kipmid; | 296 | static int num_force_kipmid; |
297 | 297 | ||
298 | static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; | ||
299 | static int num_max_busy_us; | ||
300 | |||
298 | static int unload_when_empty = 1; | 301 | static int unload_when_empty = 1; |
299 | 302 | ||
300 | static int try_smi_init(struct smi_info *smi); | 303 | static int try_smi_init(struct smi_info *smi); |
@@ -925,23 +928,77 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion) | |||
925 | } | 928 | } |
926 | } | 929 | } |
927 | 930 | ||
931 | /* | ||
932 | * Use -1 in the nsec value of the busy waiting timespec to tell that | ||
933 | * we are spinning in kipmid looking for something and not delaying | ||
934 | * between checks | ||
935 | */ | ||
936 | static inline void ipmi_si_set_not_busy(struct timespec *ts) | ||
937 | { | ||
938 | ts->tv_nsec = -1; | ||
939 | } | ||
940 | static inline int ipmi_si_is_busy(struct timespec *ts) | ||
941 | { | ||
942 | return ts->tv_nsec != -1; | ||
943 | } | ||
944 | |||
945 | static int ipmi_thread_busy_wait(enum si_sm_result smi_result, | ||
946 | const struct smi_info *smi_info, | ||
947 | struct timespec *busy_until) | ||
948 | { | ||
949 | unsigned int max_busy_us = 0; | ||
950 | |||
951 | if (smi_info->intf_num < num_max_busy_us) | ||
952 | max_busy_us = kipmid_max_busy_us[smi_info->intf_num]; | ||
953 | if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY) | ||
954 | ipmi_si_set_not_busy(busy_until); | ||
955 | else if (!ipmi_si_is_busy(busy_until)) { | ||
956 | getnstimeofday(busy_until); | ||
957 | timespec_add_ns(busy_until, max_busy_us*NSEC_PER_USEC); | ||
958 | } else { | ||
959 | struct timespec now; | ||
960 | getnstimeofday(&now); | ||
961 | if (unlikely(timespec_compare(&now, busy_until) > 0)) { | ||
962 | ipmi_si_set_not_busy(busy_until); | ||
963 | return 0; | ||
964 | } | ||
965 | } | ||
966 | return 1; | ||
967 | } | ||
968 | |||
969 | |||
970 | /* | ||
971 | * A busy-waiting loop for speeding up IPMI operation. | ||
972 | * | ||
973 | * Lousy hardware makes this hard. This is only enabled for systems | ||
974 | * that are not BT and do not have interrupts. It starts spinning | ||
975 | * when an operation is complete or until max_busy tells it to stop | ||
976 | * (if that is enabled). See the paragraph on kimid_max_busy_us in | ||
977 | * Documentation/IPMI.txt for details. | ||
978 | */ | ||
928 | static int ipmi_thread(void *data) | 979 | static int ipmi_thread(void *data) |
929 | { | 980 | { |
930 | struct smi_info *smi_info = data; | 981 | struct smi_info *smi_info = data; |
931 | unsigned long flags; | 982 | unsigned long flags; |
932 | enum si_sm_result smi_result; | 983 | enum si_sm_result smi_result; |
984 | struct timespec busy_until; | ||
933 | 985 | ||
986 | ipmi_si_set_not_busy(&busy_until); | ||
934 | set_user_nice(current, 19); | 987 | set_user_nice(current, 19); |
935 | while (!kthread_should_stop()) { | 988 | while (!kthread_should_stop()) { |
989 | int busy_wait; | ||
990 | |||
936 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 991 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
937 | smi_result = smi_event_handler(smi_info, 0); | 992 | smi_result = smi_event_handler(smi_info, 0); |
938 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 993 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
994 | busy_wait = ipmi_thread_busy_wait(smi_result, smi_info, | ||
995 | &busy_until); | ||
939 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) | 996 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) |
940 | ; /* do nothing */ | 997 | ; /* do nothing */ |
941 | else if (smi_result == SI_SM_CALL_WITH_DELAY) | 998 | else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) |
942 | schedule(); | 999 | schedule(); |
943 | else | 1000 | else |
944 | schedule_timeout_interruptible(1); | 1001 | schedule_timeout_interruptible(0); |
945 | } | 1002 | } |
946 | return 0; | 1003 | return 0; |
947 | } | 1004 | } |
@@ -1144,7 +1201,7 @@ static int regsizes[SI_MAX_PARMS]; | |||
1144 | static unsigned int num_regsizes; | 1201 | static unsigned int num_regsizes; |
1145 | static int regshifts[SI_MAX_PARMS]; | 1202 | static int regshifts[SI_MAX_PARMS]; |
1146 | static unsigned int num_regshifts; | 1203 | static unsigned int num_regshifts; |
1147 | static int slave_addrs[SI_MAX_PARMS]; | 1204 | static int slave_addrs[SI_MAX_PARMS]; /* Leaving 0 chooses the default value */ |
1148 | static unsigned int num_slave_addrs; | 1205 | static unsigned int num_slave_addrs; |
1149 | 1206 | ||
1150 | #define IPMI_IO_ADDR_SPACE 0 | 1207 | #define IPMI_IO_ADDR_SPACE 0 |
@@ -1212,6 +1269,11 @@ module_param(unload_when_empty, int, 0); | |||
1212 | MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are" | 1269 | MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are" |
1213 | " specified or found, default is 1. Setting to 0" | 1270 | " specified or found, default is 1. Setting to 0" |
1214 | " is useful for hot add of devices using hotmod."); | 1271 | " is useful for hot add of devices using hotmod."); |
1272 | module_param_array(kipmid_max_busy_us, uint, &num_max_busy_us, 0644); | ||
1273 | MODULE_PARM_DESC(kipmid_max_busy_us, | ||
1274 | "Max time (in microseconds) to busy-wait for IPMI data before" | ||
1275 | " sleeping. 0 (default) means to wait forever. Set to 100-500" | ||
1276 | " if kipmid is using up a lot of CPU time."); | ||
1215 | 1277 | ||
1216 | 1278 | ||
1217 | static void std_irq_cleanup(struct smi_info *info) | 1279 | static void std_irq_cleanup(struct smi_info *info) |
@@ -1607,7 +1669,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1607 | regsize = 1; | 1669 | regsize = 1; |
1608 | regshift = 0; | 1670 | regshift = 0; |
1609 | irq = 0; | 1671 | irq = 0; |
1610 | ipmb = 0x20; | 1672 | ipmb = 0; /* Choose the default if not specified */ |
1611 | 1673 | ||
1612 | next = strchr(curr, ':'); | 1674 | next = strchr(curr, ':'); |
1613 | if (next) { | 1675 | if (next) { |
@@ -1799,6 +1861,7 @@ static __devinit void hardcode_find_bmc(void) | |||
1799 | info->irq = irqs[i]; | 1861 | info->irq = irqs[i]; |
1800 | if (info->irq) | 1862 | if (info->irq) |
1801 | info->irq_setup = std_irq_setup; | 1863 | info->irq_setup = std_irq_setup; |
1864 | info->slave_addr = slave_addrs[i]; | ||
1802 | 1865 | ||
1803 | try_smi_init(info); | 1866 | try_smi_init(info); |
1804 | } | 1867 | } |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 48788db4e280..1f3215ac085b 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * | 5 | * |
6 | * Added devfs support. | 6 | * Added devfs support. |
7 | * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> | 7 | * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> |
8 | * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> | 8 | * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> |
9 | */ | 9 | */ |
@@ -44,36 +44,6 @@ static inline unsigned long size_inside_page(unsigned long start, | |||
44 | return min(sz, size); | 44 | return min(sz, size); |
45 | } | 45 | } |
46 | 46 | ||
47 | /* | ||
48 | * Architectures vary in how they handle caching for addresses | ||
49 | * outside of main memory. | ||
50 | * | ||
51 | */ | ||
52 | static inline int uncached_access(struct file *file, unsigned long addr) | ||
53 | { | ||
54 | #if defined(CONFIG_IA64) | ||
55 | /* | ||
56 | * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases. | ||
57 | */ | ||
58 | return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); | ||
59 | #elif defined(CONFIG_MIPS) | ||
60 | { | ||
61 | extern int __uncached_access(struct file *file, | ||
62 | unsigned long addr); | ||
63 | |||
64 | return __uncached_access(file, addr); | ||
65 | } | ||
66 | #else | ||
67 | /* | ||
68 | * Accessing memory above the top the kernel knows about or through a file pointer | ||
69 | * that was marked O_DSYNC will be done non-cached. | ||
70 | */ | ||
71 | if (file->f_flags & O_DSYNC) | ||
72 | return 1; | ||
73 | return addr >= __pa(high_memory); | ||
74 | #endif | ||
75 | } | ||
76 | |||
77 | #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE | 47 | #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE |
78 | static inline int valid_phys_addr_range(unsigned long addr, size_t count) | 48 | static inline int valid_phys_addr_range(unsigned long addr, size_t count) |
79 | { | 49 | { |
@@ -115,15 +85,15 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) | |||
115 | } | 85 | } |
116 | #endif | 86 | #endif |
117 | 87 | ||
118 | void __attribute__((weak)) unxlate_dev_mem_ptr(unsigned long phys, void *addr) | 88 | void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) |
119 | { | 89 | { |
120 | } | 90 | } |
121 | 91 | ||
122 | /* | 92 | /* |
123 | * This funcion reads the *physical* memory. The f_pos points directly to the | 93 | * This funcion reads the *physical* memory. The f_pos points directly to the |
124 | * memory location. | 94 | * memory location. |
125 | */ | 95 | */ |
126 | static ssize_t read_mem(struct file * file, char __user * buf, | 96 | static ssize_t read_mem(struct file *file, char __user *buf, |
127 | size_t count, loff_t *ppos) | 97 | size_t count, loff_t *ppos) |
128 | { | 98 | { |
129 | unsigned long p = *ppos; | 99 | unsigned long p = *ppos; |
@@ -140,10 +110,10 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
140 | if (sz > 0) { | 110 | if (sz > 0) { |
141 | if (clear_user(buf, sz)) | 111 | if (clear_user(buf, sz)) |
142 | return -EFAULT; | 112 | return -EFAULT; |
143 | buf += sz; | 113 | buf += sz; |
144 | p += sz; | 114 | p += sz; |
145 | count -= sz; | 115 | count -= sz; |
146 | read += sz; | 116 | read += sz; |
147 | } | 117 | } |
148 | } | 118 | } |
149 | #endif | 119 | #endif |
@@ -157,9 +127,9 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
157 | return -EPERM; | 127 | return -EPERM; |
158 | 128 | ||
159 | /* | 129 | /* |
160 | * On ia64 if a page has been mapped somewhere as | 130 | * On ia64 if a page has been mapped somewhere as uncached, then |
161 | * uncached, then it must also be accessed uncached | 131 | * it must also be accessed uncached by the kernel or data |
162 | * by the kernel or data corruption may occur | 132 | * corruption may occur. |
163 | */ | 133 | */ |
164 | ptr = xlate_dev_mem_ptr(p); | 134 | ptr = xlate_dev_mem_ptr(p); |
165 | if (!ptr) | 135 | if (!ptr) |
@@ -180,7 +150,7 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
180 | return read; | 150 | return read; |
181 | } | 151 | } |
182 | 152 | ||
183 | static ssize_t write_mem(struct file * file, const char __user * buf, | 153 | static ssize_t write_mem(struct file *file, const char __user *buf, |
184 | size_t count, loff_t *ppos) | 154 | size_t count, loff_t *ppos) |
185 | { | 155 | { |
186 | unsigned long p = *ppos; | 156 | unsigned long p = *ppos; |
@@ -212,9 +182,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
212 | return -EPERM; | 182 | return -EPERM; |
213 | 183 | ||
214 | /* | 184 | /* |
215 | * On ia64 if a page has been mapped somewhere as | 185 | * On ia64 if a page has been mapped somewhere as uncached, then |
216 | * uncached, then it must also be accessed uncached | 186 | * it must also be accessed uncached by the kernel or data |
217 | * by the kernel or data corruption may occur | 187 | * corruption may occur. |
218 | */ | 188 | */ |
219 | ptr = xlate_dev_mem_ptr(p); | 189 | ptr = xlate_dev_mem_ptr(p); |
220 | if (!ptr) { | 190 | if (!ptr) { |
@@ -242,13 +212,46 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
242 | return written; | 212 | return written; |
243 | } | 213 | } |
244 | 214 | ||
245 | int __attribute__((weak)) phys_mem_access_prot_allowed(struct file *file, | 215 | int __weak phys_mem_access_prot_allowed(struct file *file, |
246 | unsigned long pfn, unsigned long size, pgprot_t *vma_prot) | 216 | unsigned long pfn, unsigned long size, pgprot_t *vma_prot) |
247 | { | 217 | { |
248 | return 1; | 218 | return 1; |
249 | } | 219 | } |
250 | 220 | ||
251 | #ifndef __HAVE_PHYS_MEM_ACCESS_PROT | 221 | #ifndef __HAVE_PHYS_MEM_ACCESS_PROT |
222 | |||
223 | /* | ||
224 | * Architectures vary in how they handle caching for addresses | ||
225 | * outside of main memory. | ||
226 | * | ||
227 | */ | ||
228 | static int uncached_access(struct file *file, unsigned long addr) | ||
229 | { | ||
230 | #if defined(CONFIG_IA64) | ||
231 | /* | ||
232 | * On ia64, we ignore O_DSYNC because we cannot tolerate memory | ||
233 | * attribute aliases. | ||
234 | */ | ||
235 | return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); | ||
236 | #elif defined(CONFIG_MIPS) | ||
237 | { | ||
238 | extern int __uncached_access(struct file *file, | ||
239 | unsigned long addr); | ||
240 | |||
241 | return __uncached_access(file, addr); | ||
242 | } | ||
243 | #else | ||
244 | /* | ||
245 | * Accessing memory above the top the kernel knows about or through a | ||
246 | * file pointer | ||
247 | * that was marked O_DSYNC will be done non-cached. | ||
248 | */ | ||
249 | if (file->f_flags & O_DSYNC) | ||
250 | return 1; | ||
251 | return addr >= __pa(high_memory); | ||
252 | #endif | ||
253 | } | ||
254 | |||
252 | static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | 255 | static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, |
253 | unsigned long size, pgprot_t vma_prot) | 256 | unsigned long size, pgprot_t vma_prot) |
254 | { | 257 | { |
@@ -294,7 +297,7 @@ static const struct vm_operations_struct mmap_mem_ops = { | |||
294 | #endif | 297 | #endif |
295 | }; | 298 | }; |
296 | 299 | ||
297 | static int mmap_mem(struct file * file, struct vm_area_struct * vma) | 300 | static int mmap_mem(struct file *file, struct vm_area_struct *vma) |
298 | { | 301 | { |
299 | size_t size = vma->vm_end - vma->vm_start; | 302 | size_t size = vma->vm_end - vma->vm_start; |
300 | 303 | ||
@@ -329,7 +332,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
329 | } | 332 | } |
330 | 333 | ||
331 | #ifdef CONFIG_DEVKMEM | 334 | #ifdef CONFIG_DEVKMEM |
332 | static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | 335 | static int mmap_kmem(struct file *file, struct vm_area_struct *vma) |
333 | { | 336 | { |
334 | unsigned long pfn; | 337 | unsigned long pfn; |
335 | 338 | ||
@@ -337,9 +340,9 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) | |||
337 | pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; | 340 | pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; |
338 | 341 | ||
339 | /* | 342 | /* |
340 | * RED-PEN: on some architectures there is more mapped memory | 343 | * RED-PEN: on some architectures there is more mapped memory than |
341 | * than available in mem_map which pfn_valid checks | 344 | * available in mem_map which pfn_valid checks for. Perhaps should add a |
342 | * for. Perhaps should add a new macro here. | 345 | * new macro here. |
343 | * | 346 | * |
344 | * RED-PEN: vmalloc is not supported right now. | 347 | * RED-PEN: vmalloc is not supported right now. |
345 | */ | 348 | */ |
@@ -389,7 +392,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf, | |||
389 | /* | 392 | /* |
390 | * This function reads the *virtual* memory as seen by the kernel. | 393 | * This function reads the *virtual* memory as seen by the kernel. |
391 | */ | 394 | */ |
392 | static ssize_t read_kmem(struct file *file, char __user *buf, | 395 | static ssize_t read_kmem(struct file *file, char __user *buf, |
393 | size_t count, loff_t *ppos) | 396 | size_t count, loff_t *ppos) |
394 | { | 397 | { |
395 | unsigned long p = *ppos; | 398 | unsigned long p = *ppos; |
@@ -400,8 +403,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf, | |||
400 | read = 0; | 403 | read = 0; |
401 | if (p < (unsigned long) high_memory) { | 404 | if (p < (unsigned long) high_memory) { |
402 | low_count = count; | 405 | low_count = count; |
403 | if (count > (unsigned long) high_memory - p) | 406 | if (count > (unsigned long)high_memory - p) |
404 | low_count = (unsigned long) high_memory - p; | 407 | low_count = (unsigned long)high_memory - p; |
405 | 408 | ||
406 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED | 409 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
407 | /* we don't have page 0 mapped on sparc and m68k.. */ | 410 | /* we don't have page 0 mapped on sparc and m68k.. */ |
@@ -465,9 +468,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf, | |||
465 | } | 468 | } |
466 | 469 | ||
467 | 470 | ||
468 | static inline ssize_t | 471 | static ssize_t do_write_kmem(unsigned long p, const char __user *buf, |
469 | do_write_kmem(unsigned long p, const char __user *buf, | 472 | size_t count, loff_t *ppos) |
470 | size_t count, loff_t *ppos) | ||
471 | { | 473 | { |
472 | ssize_t written, sz; | 474 | ssize_t written, sz; |
473 | unsigned long copied; | 475 | unsigned long copied; |
@@ -491,9 +493,9 @@ do_write_kmem(unsigned long p, const char __user *buf, | |||
491 | sz = size_inside_page(p, count); | 493 | sz = size_inside_page(p, count); |
492 | 494 | ||
493 | /* | 495 | /* |
494 | * On ia64 if a page has been mapped somewhere as | 496 | * On ia64 if a page has been mapped somewhere as uncached, then |
495 | * uncached, then it must also be accessed uncached | 497 | * it must also be accessed uncached by the kernel or data |
496 | * by the kernel or data corruption may occur | 498 | * corruption may occur. |
497 | */ | 499 | */ |
498 | ptr = xlate_dev_kmem_ptr((char *)p); | 500 | ptr = xlate_dev_kmem_ptr((char *)p); |
499 | 501 | ||
@@ -514,11 +516,10 @@ do_write_kmem(unsigned long p, const char __user *buf, | |||
514 | return written; | 516 | return written; |
515 | } | 517 | } |
516 | 518 | ||
517 | |||
518 | /* | 519 | /* |
519 | * This function writes to the *virtual* memory as seen by the kernel. | 520 | * This function writes to the *virtual* memory as seen by the kernel. |
520 | */ | 521 | */ |
521 | static ssize_t write_kmem(struct file * file, const char __user * buf, | 522 | static ssize_t write_kmem(struct file *file, const char __user *buf, |
522 | size_t count, loff_t *ppos) | 523 | size_t count, loff_t *ppos) |
523 | { | 524 | { |
524 | unsigned long p = *ppos; | 525 | unsigned long p = *ppos; |
@@ -570,17 +571,17 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
570 | #endif | 571 | #endif |
571 | 572 | ||
572 | #ifdef CONFIG_DEVPORT | 573 | #ifdef CONFIG_DEVPORT |
573 | static ssize_t read_port(struct file * file, char __user * buf, | 574 | static ssize_t read_port(struct file *file, char __user *buf, |
574 | size_t count, loff_t *ppos) | 575 | size_t count, loff_t *ppos) |
575 | { | 576 | { |
576 | unsigned long i = *ppos; | 577 | unsigned long i = *ppos; |
577 | char __user *tmp = buf; | 578 | char __user *tmp = buf; |
578 | 579 | ||
579 | if (!access_ok(VERIFY_WRITE, buf, count)) | 580 | if (!access_ok(VERIFY_WRITE, buf, count)) |
580 | return -EFAULT; | 581 | return -EFAULT; |
581 | while (count-- > 0 && i < 65536) { | 582 | while (count-- > 0 && i < 65536) { |
582 | if (__put_user(inb(i),tmp) < 0) | 583 | if (__put_user(inb(i), tmp) < 0) |
583 | return -EFAULT; | 584 | return -EFAULT; |
584 | i++; | 585 | i++; |
585 | tmp++; | 586 | tmp++; |
586 | } | 587 | } |
@@ -588,22 +589,22 @@ static ssize_t read_port(struct file * file, char __user * buf, | |||
588 | return tmp-buf; | 589 | return tmp-buf; |
589 | } | 590 | } |
590 | 591 | ||
591 | static ssize_t write_port(struct file * file, const char __user * buf, | 592 | static ssize_t write_port(struct file *file, const char __user *buf, |
592 | size_t count, loff_t *ppos) | 593 | size_t count, loff_t *ppos) |
593 | { | 594 | { |
594 | unsigned long i = *ppos; | 595 | unsigned long i = *ppos; |
595 | const char __user * tmp = buf; | 596 | const char __user * tmp = buf; |
596 | 597 | ||
597 | if (!access_ok(VERIFY_READ,buf,count)) | 598 | if (!access_ok(VERIFY_READ, buf, count)) |
598 | return -EFAULT; | 599 | return -EFAULT; |
599 | while (count-- > 0 && i < 65536) { | 600 | while (count-- > 0 && i < 65536) { |
600 | char c; | 601 | char c; |
601 | if (__get_user(c, tmp)) { | 602 | if (__get_user(c, tmp)) { |
602 | if (tmp > buf) | 603 | if (tmp > buf) |
603 | break; | 604 | break; |
604 | return -EFAULT; | 605 | return -EFAULT; |
605 | } | 606 | } |
606 | outb(c,i); | 607 | outb(c, i); |
607 | i++; | 608 | i++; |
608 | tmp++; | 609 | tmp++; |
609 | } | 610 | } |
@@ -612,13 +613,13 @@ static ssize_t write_port(struct file * file, const char __user * buf, | |||
612 | } | 613 | } |
613 | #endif | 614 | #endif |
614 | 615 | ||
615 | static ssize_t read_null(struct file * file, char __user * buf, | 616 | static ssize_t read_null(struct file *file, char __user *buf, |
616 | size_t count, loff_t *ppos) | 617 | size_t count, loff_t *ppos) |
617 | { | 618 | { |
618 | return 0; | 619 | return 0; |
619 | } | 620 | } |
620 | 621 | ||
621 | static ssize_t write_null(struct file * file, const char __user * buf, | 622 | static ssize_t write_null(struct file *file, const char __user *buf, |
622 | size_t count, loff_t *ppos) | 623 | size_t count, loff_t *ppos) |
623 | { | 624 | { |
624 | return count; | 625 | return count; |
@@ -630,13 +631,13 @@ static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
630 | return sd->len; | 631 | return sd->len; |
631 | } | 632 | } |
632 | 633 | ||
633 | static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out, | 634 | static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out, |
634 | loff_t *ppos, size_t len, unsigned int flags) | 635 | loff_t *ppos, size_t len, unsigned int flags) |
635 | { | 636 | { |
636 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); | 637 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); |
637 | } | 638 | } |
638 | 639 | ||
639 | static ssize_t read_zero(struct file * file, char __user * buf, | 640 | static ssize_t read_zero(struct file *file, char __user *buf, |
640 | size_t count, loff_t *ppos) | 641 | size_t count, loff_t *ppos) |
641 | { | 642 | { |
642 | size_t written; | 643 | size_t written; |
@@ -667,7 +668,7 @@ static ssize_t read_zero(struct file * file, char __user * buf, | |||
667 | return written ? written : -EFAULT; | 668 | return written ? written : -EFAULT; |
668 | } | 669 | } |
669 | 670 | ||
670 | static int mmap_zero(struct file * file, struct vm_area_struct * vma) | 671 | static int mmap_zero(struct file *file, struct vm_area_struct *vma) |
671 | { | 672 | { |
672 | #ifndef CONFIG_MMU | 673 | #ifndef CONFIG_MMU |
673 | return -ENOSYS; | 674 | return -ENOSYS; |
@@ -677,7 +678,7 @@ static int mmap_zero(struct file * file, struct vm_area_struct * vma) | |||
677 | return 0; | 678 | return 0; |
678 | } | 679 | } |
679 | 680 | ||
680 | static ssize_t write_full(struct file * file, const char __user * buf, | 681 | static ssize_t write_full(struct file *file, const char __user *buf, |
681 | size_t count, loff_t *ppos) | 682 | size_t count, loff_t *ppos) |
682 | { | 683 | { |
683 | return -ENOSPC; | 684 | return -ENOSPC; |
@@ -688,8 +689,7 @@ static ssize_t write_full(struct file * file, const char __user * buf, | |||
688 | * can fopen() both devices with "a" now. This was previously impossible. | 689 | * can fopen() both devices with "a" now. This was previously impossible. |
689 | * -- SRB. | 690 | * -- SRB. |
690 | */ | 691 | */ |
691 | 692 | static loff_t null_lseek(struct file *file, loff_t offset, int orig) | |
692 | static loff_t null_lseek(struct file * file, loff_t offset, int orig) | ||
693 | { | 693 | { |
694 | return file->f_pos = 0; | 694 | return file->f_pos = 0; |
695 | } | 695 | } |
@@ -702,24 +702,31 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig) | |||
702 | * also note that seeking relative to the "end of file" isn't supported: | 702 | * also note that seeking relative to the "end of file" isn't supported: |
703 | * it has no meaning, so it returns -EINVAL. | 703 | * it has no meaning, so it returns -EINVAL. |
704 | */ | 704 | */ |
705 | static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | 705 | static loff_t memory_lseek(struct file *file, loff_t offset, int orig) |
706 | { | 706 | { |
707 | loff_t ret; | 707 | loff_t ret; |
708 | 708 | ||
709 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); | 709 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); |
710 | switch (orig) { | 710 | switch (orig) { |
711 | case 0: | 711 | case SEEK_CUR: |
712 | file->f_pos = offset; | 712 | offset += file->f_pos; |
713 | ret = file->f_pos; | 713 | if ((unsigned long long)offset < |
714 | force_successful_syscall_return(); | 714 | (unsigned long long)file->f_pos) { |
715 | ret = -EOVERFLOW; | ||
715 | break; | 716 | break; |
716 | case 1: | 717 | } |
717 | file->f_pos += offset; | 718 | case SEEK_SET: |
718 | ret = file->f_pos; | 719 | /* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */ |
719 | force_successful_syscall_return(); | 720 | if ((unsigned long long)offset >= ~0xFFFULL) { |
721 | ret = -EOVERFLOW; | ||
720 | break; | 722 | break; |
721 | default: | 723 | } |
722 | ret = -EINVAL; | 724 | file->f_pos = offset; |
725 | ret = file->f_pos; | ||
726 | force_successful_syscall_return(); | ||
727 | break; | ||
728 | default: | ||
729 | ret = -EINVAL; | ||
723 | } | 730 | } |
724 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); | 731 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
725 | return ret; | 732 | return ret; |
@@ -803,7 +810,7 @@ static const struct file_operations oldmem_fops = { | |||
803 | }; | 810 | }; |
804 | #endif | 811 | #endif |
805 | 812 | ||
806 | static ssize_t kmsg_write(struct file * file, const char __user * buf, | 813 | static ssize_t kmsg_write(struct file *file, const char __user *buf, |
807 | size_t count, loff_t *ppos) | 814 | size_t count, loff_t *ppos) |
808 | { | 815 | { |
809 | char *tmp; | 816 | char *tmp; |
@@ -825,7 +832,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf, | |||
825 | } | 832 | } |
826 | 833 | ||
827 | static const struct file_operations kmsg_fops = { | 834 | static const struct file_operations kmsg_fops = { |
828 | .write = kmsg_write, | 835 | .write = kmsg_write, |
829 | }; | 836 | }; |
830 | 837 | ||
831 | static const struct memdev { | 838 | static const struct memdev { |
@@ -876,7 +883,7 @@ static int memory_open(struct inode *inode, struct file *filp) | |||
876 | } | 883 | } |
877 | 884 | ||
878 | static const struct file_operations memory_fops = { | 885 | static const struct file_operations memory_fops = { |
879 | .open = memory_open, | 886 | .open = memory_open, |
880 | }; | 887 | }; |
881 | 888 | ||
882 | static char *mem_devnode(struct device *dev, mode_t *mode) | 889 | static char *mem_devnode(struct device *dev, mode_t *mode) |
@@ -897,7 +904,7 @@ static int __init chr_dev_init(void) | |||
897 | if (err) | 904 | if (err) |
898 | return err; | 905 | return err; |
899 | 906 | ||
900 | if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) | 907 | if (register_chrdev(MEM_MAJOR, "mem", &memory_fops)) |
901 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); | 908 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); |
902 | 909 | ||
903 | mem_class = class_create(THIS_MODULE, "mem"); | 910 | mem_class = class_create(THIS_MODULE, "mem"); |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 918711aa56f3..04fd0d843b3b 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -546,7 +546,7 @@ static void mmtimer_tasklet(unsigned long data) | |||
546 | { | 546 | { |
547 | int nodeid = data; | 547 | int nodeid = data; |
548 | struct mmtimer_node *mn = &timers[nodeid]; | 548 | struct mmtimer_node *mn = &timers[nodeid]; |
549 | struct mmtimer *x = rb_entry(mn->next, struct mmtimer, list); | 549 | struct mmtimer *x; |
550 | struct k_itimer *t; | 550 | struct k_itimer *t; |
551 | unsigned long flags; | 551 | unsigned long flags; |
552 | 552 | ||
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 2e50f4dfc79c..bdae8327143c 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/audit.h> | 48 | #include <linux/audit.h> |
49 | #include <linux/file.h> | 49 | #include <linux/file.h> |
50 | #include <linux/uaccess.h> | 50 | #include <linux/uaccess.h> |
51 | #include <linux/module.h> | ||
51 | 52 | ||
52 | #include <asm/system.h> | 53 | #include <asm/system.h> |
53 | 54 | ||
@@ -2091,3 +2092,19 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
2091 | .receive_buf = n_tty_receive_buf, | 2092 | .receive_buf = n_tty_receive_buf, |
2092 | .write_wakeup = n_tty_write_wakeup | 2093 | .write_wakeup = n_tty_write_wakeup |
2093 | }; | 2094 | }; |
2095 | |||
2096 | /** | ||
2097 | * n_tty_inherit_ops - inherit N_TTY methods | ||
2098 | * @ops: struct tty_ldisc_ops where to save N_TTY methods | ||
2099 | * | ||
2100 | * Used by a generic struct tty_ldisc_ops to easily inherit N_TTY | ||
2101 | * methods. | ||
2102 | */ | ||
2103 | |||
2104 | void n_tty_inherit_ops(struct tty_ldisc_ops *ops) | ||
2105 | { | ||
2106 | *ops = tty_ldisc_N_TTY; | ||
2107 | ops->owner = NULL; | ||
2108 | ops->refcount = ops->flags = 0; | ||
2109 | } | ||
2110 | EXPORT_SYMBOL_GPL(n_tty_inherit_ops); | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 385c44b3034f..5ee424817263 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -220,7 +220,7 @@ static void pty_set_termios(struct tty_struct *tty, | |||
220 | * @tty: tty being resized | 220 | * @tty: tty being resized |
221 | * @ws: window size being set. | 221 | * @ws: window size being set. |
222 | * | 222 | * |
223 | * Update the termios variables and send the neccessary signals to | 223 | * Update the termios variables and send the necessary signals to |
224 | * peform a terminal resize correctly | 224 | * peform a terminal resize correctly |
225 | */ | 225 | */ |
226 | 226 | ||
diff --git a/drivers/char/random.c b/drivers/char/random.c index 2849713d2231..2fd3d39995d5 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1191,7 +1191,7 @@ const struct file_operations urandom_fops = { | |||
1191 | void generate_random_uuid(unsigned char uuid_out[16]) | 1191 | void generate_random_uuid(unsigned char uuid_out[16]) |
1192 | { | 1192 | { |
1193 | get_random_bytes(uuid_out, 16); | 1193 | get_random_bytes(uuid_out, 16); |
1194 | /* Set UUID version to 4 --- truely random generation */ | 1194 | /* Set UUID version to 4 --- truly random generation */ |
1195 | uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40; | 1195 | uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40; |
1196 | /* Set the UUID variant to DCE */ | 1196 | /* Set the UUID variant to DCE */ |
1197 | uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80; | 1197 | uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80; |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 986aa606a6b6..1ec3d5cd748f 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1989,7 +1989,7 @@ void mvme167_serial_console_setup(int cflag) | |||
1989 | /* | 1989 | /* |
1990 | * Attempt to set up all channels to something reasonable, and | 1990 | * Attempt to set up all channels to something reasonable, and |
1991 | * bang out a INIT_CHAN command. We should then be able to limit | 1991 | * bang out a INIT_CHAN command. We should then be able to limit |
1992 | * the ammount of fiddling we have to do in normal running. | 1992 | * the amount of fiddling we have to do in normal running. |
1993 | */ | 1993 | */ |
1994 | 1994 | ||
1995 | for (ch = 3; ch >= 0; ch--) { | 1995 | for (ch = 3; ch >= 0; ch--) { |
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index ac16fbec72d0..283a15bc84e3 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c | |||
@@ -148,7 +148,6 @@ void tty_audit_fork(struct signal_struct *sig) | |||
148 | spin_lock_irq(¤t->sighand->siglock); | 148 | spin_lock_irq(¤t->sighand->siglock); |
149 | sig->audit_tty = current->signal->audit_tty; | 149 | sig->audit_tty = current->signal->audit_tty; |
150 | spin_unlock_irq(¤t->sighand->siglock); | 150 | spin_unlock_irq(¤t->sighand->siglock); |
151 | sig->tty_audit_buf = NULL; | ||
152 | } | 151 | } |
153 | 152 | ||
154 | /** | 153 | /** |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index dcb9083ecde0..a42c466f7092 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2028,7 +2028,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
2028 | * @rows: rows (character) | 2028 | * @rows: rows (character) |
2029 | * @cols: cols (character) | 2029 | * @cols: cols (character) |
2030 | * | 2030 | * |
2031 | * Update the termios variables and send the neccessary signals to | 2031 | * Update the termios variables and send the necessary signals to |
2032 | * peform a terminal resize correctly | 2032 | * peform a terminal resize correctly |
2033 | */ | 2033 | */ |
2034 | 2034 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 50faa1fb0f06..bd1d1164fec5 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -821,7 +821,7 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, | |||
821 | * | 821 | * |
822 | * Resize a virtual console, clipping according to the actual constraints. | 822 | * Resize a virtual console, clipping according to the actual constraints. |
823 | * If the caller passes a tty structure then update the termios winsize | 823 | * If the caller passes a tty structure then update the termios winsize |
824 | * information and perform any neccessary signal handling. | 824 | * information and perform any necessary signal handling. |
825 | * | 825 | * |
826 | * Caller must hold the console semaphore. Takes the termios mutex and | 826 | * Caller must hold the console semaphore. Takes the termios mutex and |
827 | * ctrl_lock of the tty IFF a tty is passed. | 827 | * ctrl_lock of the tty IFF a tty is passed. |
@@ -2119,8 +2119,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2119 | uint8_t inverse; | 2119 | uint8_t inverse; |
2120 | uint8_t width; | 2120 | uint8_t width; |
2121 | u16 himask, charmask; | 2121 | u16 himask, charmask; |
2122 | const unsigned char *orig_buf = NULL; | ||
2123 | int orig_count; | ||
2124 | 2122 | ||
2125 | if (in_interrupt()) | 2123 | if (in_interrupt()) |
2126 | return count; | 2124 | return count; |
@@ -2142,8 +2140,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2142 | release_console_sem(); | 2140 | release_console_sem(); |
2143 | return 0; | 2141 | return 0; |
2144 | } | 2142 | } |
2145 | orig_buf = buf; | ||
2146 | orig_count = count; | ||
2147 | 2143 | ||
2148 | himask = vc->vc_hi_font_mask; | 2144 | himask = vc->vc_hi_font_mask; |
2149 | charmask = himask ? 0x1ff : 0xff; | 2145 | charmask = himask ? 0x1ff : 0xff; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 67bc2ece7b4b..2d5d575e889d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -766,7 +766,7 @@ static void cpufreq_sysfs_release(struct kobject *kobj) | |||
766 | complete(&policy->kobj_unregister); | 766 | complete(&policy->kobj_unregister); |
767 | } | 767 | } |
768 | 768 | ||
769 | static struct sysfs_ops sysfs_ops = { | 769 | static const struct sysfs_ops sysfs_ops = { |
770 | .show = show, | 770 | .show = show, |
771 | .store = store, | 771 | .store = store, |
772 | }; | 772 | }; |
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 97b003839fb6..8719b36e1a4d 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -22,6 +22,7 @@ static int __init cpuidle_sysfs_setup(char *unused) | |||
22 | __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); | 22 | __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); |
23 | 23 | ||
24 | static ssize_t show_available_governors(struct sysdev_class *class, | 24 | static ssize_t show_available_governors(struct sysdev_class *class, |
25 | struct sysdev_class_attribute *attr, | ||
25 | char *buf) | 26 | char *buf) |
26 | { | 27 | { |
27 | ssize_t i = 0; | 28 | ssize_t i = 0; |
@@ -41,6 +42,7 @@ out: | |||
41 | } | 42 | } |
42 | 43 | ||
43 | static ssize_t show_current_driver(struct sysdev_class *class, | 44 | static ssize_t show_current_driver(struct sysdev_class *class, |
45 | struct sysdev_class_attribute *attr, | ||
44 | char *buf) | 46 | char *buf) |
45 | { | 47 | { |
46 | ssize_t ret; | 48 | ssize_t ret; |
@@ -56,6 +58,7 @@ static ssize_t show_current_driver(struct sysdev_class *class, | |||
56 | } | 58 | } |
57 | 59 | ||
58 | static ssize_t show_current_governor(struct sysdev_class *class, | 60 | static ssize_t show_current_governor(struct sysdev_class *class, |
61 | struct sysdev_class_attribute *attr, | ||
59 | char *buf) | 62 | char *buf) |
60 | { | 63 | { |
61 | ssize_t ret; | 64 | ssize_t ret; |
@@ -71,6 +74,7 @@ static ssize_t show_current_governor(struct sysdev_class *class, | |||
71 | } | 74 | } |
72 | 75 | ||
73 | static ssize_t store_current_governor(struct sysdev_class *class, | 76 | static ssize_t store_current_governor(struct sysdev_class *class, |
77 | struct sysdev_class_attribute *attr, | ||
74 | const char *buf, size_t count) | 78 | const char *buf, size_t count) |
75 | { | 79 | { |
76 | char gov_name[CPUIDLE_NAME_LEN]; | 80 | char gov_name[CPUIDLE_NAME_LEN]; |
@@ -191,7 +195,7 @@ static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr, | |||
191 | return ret; | 195 | return ret; |
192 | } | 196 | } |
193 | 197 | ||
194 | static struct sysfs_ops cpuidle_sysfs_ops = { | 198 | static const struct sysfs_ops cpuidle_sysfs_ops = { |
195 | .show = cpuidle_show, | 199 | .show = cpuidle_show, |
196 | .store = cpuidle_store, | 200 | .store = cpuidle_store, |
197 | }; | 201 | }; |
@@ -277,7 +281,7 @@ static ssize_t cpuidle_state_show(struct kobject * kobj, | |||
277 | return ret; | 281 | return ret; |
278 | } | 282 | } |
279 | 283 | ||
280 | static struct sysfs_ops cpuidle_state_sysfs_ops = { | 284 | static const struct sysfs_ops cpuidle_state_sysfs_ops = { |
281 | .show = cpuidle_state_show, | 285 | .show = cpuidle_state_show, |
282 | }; | 286 | }; |
283 | 287 | ||
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 09ad9154d86c..73e8b1713b54 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c | |||
@@ -321,7 +321,7 @@ static atomic_t hifn_dev_number; | |||
321 | #define HIFN_PUBOPLEN_MOD_M 0x0000007f /* modulus length mask */ | 321 | #define HIFN_PUBOPLEN_MOD_M 0x0000007f /* modulus length mask */ |
322 | #define HIFN_PUBOPLEN_MOD_S 0 /* modulus length shift */ | 322 | #define HIFN_PUBOPLEN_MOD_S 0 /* modulus length shift */ |
323 | #define HIFN_PUBOPLEN_EXP_M 0x0003ff80 /* exponent length mask */ | 323 | #define HIFN_PUBOPLEN_EXP_M 0x0003ff80 /* exponent length mask */ |
324 | #define HIFN_PUBOPLEN_EXP_S 7 /* exponent lenght shift */ | 324 | #define HIFN_PUBOPLEN_EXP_S 7 /* exponent length shift */ |
325 | #define HIFN_PUBOPLEN_RED_M 0x003c0000 /* reducend length mask */ | 325 | #define HIFN_PUBOPLEN_RED_M 0x003c0000 /* reducend length mask */ |
326 | #define HIFN_PUBOPLEN_RED_S 18 /* reducend length shift */ | 326 | #define HIFN_PUBOPLEN_RED_S 18 /* reducend length shift */ |
327 | 327 | ||
diff --git a/drivers/dma/coh901318_lli.h b/drivers/dma/coh901318_lli.h index 7bf713b79c6b..7a5c80990e9e 100644 --- a/drivers/dma/coh901318_lli.h +++ b/drivers/dma/coh901318_lli.h | |||
@@ -30,7 +30,7 @@ struct device; | |||
30 | * @pool: pool handle | 30 | * @pool: pool handle |
31 | * @dev: dma device | 31 | * @dev: dma device |
32 | * @lli_nbr: number of lli:s in the pool | 32 | * @lli_nbr: number of lli:s in the pool |
33 | * @algin: adress alignemtn of lli:s | 33 | * @algin: address alignemtn of lli:s |
34 | * returns 0 on success otherwise none zero | 34 | * returns 0 on success otherwise none zero |
35 | */ | 35 | */ |
36 | int coh901318_pool_create(struct coh901318_pool *pool, | 36 | int coh901318_pool_create(struct coh901318_pool *pool, |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index af14c9a5b8d4..0099340b9616 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -1138,7 +1138,7 @@ ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
1138 | return entry->show(&chan->common, page); | 1138 | return entry->show(&chan->common, page); |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | struct sysfs_ops ioat_sysfs_ops = { | 1141 | const struct sysfs_ops ioat_sysfs_ops = { |
1142 | .show = ioat_attr_show, | 1142 | .show = ioat_attr_show, |
1143 | }; | 1143 | }; |
1144 | 1144 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 4f747a254074..86b97ac8774e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -346,7 +346,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, | |||
346 | unsigned long *phys_complete); | 346 | unsigned long *phys_complete); |
347 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); | 347 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); |
348 | void ioat_kobject_del(struct ioatdma_device *device); | 348 | void ioat_kobject_del(struct ioatdma_device *device); |
349 | extern struct sysfs_ops ioat_sysfs_ops; | 349 | extern const struct sysfs_ops ioat_sysfs_ops; |
350 | extern struct ioat_sysfs_entry ioat_version_attr; | 350 | extern struct ioat_sysfs_entry ioat_version_attr; |
351 | extern struct ioat_sysfs_entry ioat_cap_attr; | 351 | extern struct ioat_sysfs_entry ioat_cap_attr; |
352 | #endif /* IOATDMA_H */ | 352 | #endif /* IOATDMA_H */ |
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index d205d493a68a..243e9aacad69 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c | |||
@@ -75,6 +75,14 @@ static struct edac_pci_ctl_info *e752x_pci; | |||
75 | #define E752X_NR_CSROWS 8 /* number of csrows */ | 75 | #define E752X_NR_CSROWS 8 /* number of csrows */ |
76 | 76 | ||
77 | /* E752X register addresses - device 0 function 0 */ | 77 | /* E752X register addresses - device 0 function 0 */ |
78 | #define E752X_MCHSCRB 0x52 /* Memory Scrub register (16b) */ | ||
79 | /* | ||
80 | * 6:5 Scrub Completion Count | ||
81 | * 3:2 Scrub Rate (i3100 only) | ||
82 | * 01=fast 10=normal | ||
83 | * 1:0 Scrub Mode enable | ||
84 | * 00=off 10=on | ||
85 | */ | ||
78 | #define E752X_DRB 0x60 /* DRAM row boundary register (8b) */ | 86 | #define E752X_DRB 0x60 /* DRAM row boundary register (8b) */ |
79 | #define E752X_DRA 0x70 /* DRAM row attribute register (8b) */ | 87 | #define E752X_DRA 0x70 /* DRAM row attribute register (8b) */ |
80 | /* | 88 | /* |
@@ -240,6 +248,41 @@ static const struct e752x_dev_info e752x_devs[] = { | |||
240 | .ctl_name = "3100"}, | 248 | .ctl_name = "3100"}, |
241 | }; | 249 | }; |
242 | 250 | ||
251 | /* Valid scrub rates for the e752x/3100 hardware memory scrubber. We | ||
252 | * map the scrubbing bandwidth to a hardware register value. The 'set' | ||
253 | * operation finds the 'matching or higher value'. Note that scrubbing | ||
254 | * on the e752x can only be enabled/disabled. The 3100 supports | ||
255 | * a normal and fast mode. | ||
256 | */ | ||
257 | |||
258 | #define SDRATE_EOT 0xFFFFFFFF | ||
259 | |||
260 | struct scrubrate { | ||
261 | u32 bandwidth; /* bandwidth consumed by scrubbing in bytes/sec */ | ||
262 | u16 scrubval; /* register value for scrub rate */ | ||
263 | }; | ||
264 | |||
265 | /* Rate below assumes same performance as i3100 using PC3200 DDR2 in | ||
266 | * normal mode. e752x bridges don't support choosing normal or fast mode, | ||
267 | * so the scrubbing bandwidth value isn't all that important - scrubbing is | ||
268 | * either on or off. | ||
269 | */ | ||
270 | static const struct scrubrate scrubrates_e752x[] = { | ||
271 | {0, 0x00}, /* Scrubbing Off */ | ||
272 | {500000, 0x02}, /* Scrubbing On */ | ||
273 | {SDRATE_EOT, 0x00} /* End of Table */ | ||
274 | }; | ||
275 | |||
276 | /* Fast mode: 2 GByte PC3200 DDR2 scrubbed in 33s = 63161283 bytes/s | ||
277 | * Normal mode: 125 (32000 / 256) times slower than fast mode. | ||
278 | */ | ||
279 | static const struct scrubrate scrubrates_i3100[] = { | ||
280 | {0, 0x00}, /* Scrubbing Off */ | ||
281 | {500000, 0x0a}, /* Normal mode - 32k clocks */ | ||
282 | {62500000, 0x06}, /* Fast mode - 256 clocks */ | ||
283 | {SDRATE_EOT, 0x00} /* End of Table */ | ||
284 | }; | ||
285 | |||
243 | static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, | 286 | static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, |
244 | unsigned long page) | 287 | unsigned long page) |
245 | { | 288 | { |
@@ -915,6 +958,68 @@ static void e752x_check(struct mem_ctl_info *mci) | |||
915 | e752x_process_error_info(mci, &info, 1); | 958 | e752x_process_error_info(mci, &info, 1); |
916 | } | 959 | } |
917 | 960 | ||
961 | /* Program byte/sec bandwidth scrub rate to hardware */ | ||
962 | static int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *new_bw) | ||
963 | { | ||
964 | const struct scrubrate *scrubrates; | ||
965 | struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; | ||
966 | struct pci_dev *pdev = pvt->dev_d0f0; | ||
967 | int i; | ||
968 | |||
969 | if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0) | ||
970 | scrubrates = scrubrates_i3100; | ||
971 | else | ||
972 | scrubrates = scrubrates_e752x; | ||
973 | |||
974 | /* Translate the desired scrub rate to a e752x/3100 register value. | ||
975 | * Search for the bandwidth that is equal or greater than the | ||
976 | * desired rate and program the cooresponding register value. | ||
977 | */ | ||
978 | for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++) | ||
979 | if (scrubrates[i].bandwidth >= *new_bw) | ||
980 | break; | ||
981 | |||
982 | if (scrubrates[i].bandwidth == SDRATE_EOT) | ||
983 | return -1; | ||
984 | |||
985 | pci_write_config_word(pdev, E752X_MCHSCRB, scrubrates[i].scrubval); | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | /* Convert current scrub rate value into byte/sec bandwidth */ | ||
991 | static int get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw) | ||
992 | { | ||
993 | const struct scrubrate *scrubrates; | ||
994 | struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; | ||
995 | struct pci_dev *pdev = pvt->dev_d0f0; | ||
996 | u16 scrubval; | ||
997 | int i; | ||
998 | |||
999 | if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0) | ||
1000 | scrubrates = scrubrates_i3100; | ||
1001 | else | ||
1002 | scrubrates = scrubrates_e752x; | ||
1003 | |||
1004 | /* Find the bandwidth matching the memory scrubber configuration */ | ||
1005 | pci_read_config_word(pdev, E752X_MCHSCRB, &scrubval); | ||
1006 | scrubval = scrubval & 0x0f; | ||
1007 | |||
1008 | for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++) | ||
1009 | if (scrubrates[i].scrubval == scrubval) | ||
1010 | break; | ||
1011 | |||
1012 | if (scrubrates[i].bandwidth == SDRATE_EOT) { | ||
1013 | e752x_printk(KERN_WARNING, | ||
1014 | "Invalid sdram scrub control value: 0x%x\n", scrubval); | ||
1015 | return -1; | ||
1016 | } | ||
1017 | |||
1018 | *bw = scrubrates[i].bandwidth; | ||
1019 | |||
1020 | return 0; | ||
1021 | } | ||
1022 | |||
918 | /* Return 1 if dual channel mode is active. Else return 0. */ | 1023 | /* Return 1 if dual channel mode is active. Else return 0. */ |
919 | static inline int dual_channel_active(u16 ddrcsr) | 1024 | static inline int dual_channel_active(u16 ddrcsr) |
920 | { | 1025 | { |
@@ -1073,10 +1178,7 @@ fail: | |||
1073 | 1178 | ||
1074 | /* Setup system bus parity mask register. | 1179 | /* Setup system bus parity mask register. |
1075 | * Sysbus parity supported on: | 1180 | * Sysbus parity supported on: |
1076 | * e7320/e7520/e7525 + Xeon | 1181 | * e7320/e7520/e7525 + Xeon |
1077 | * i3100 + Xeon/Celeron | ||
1078 | * Sysbus parity not supported on: | ||
1079 | * i3100 + Pentium M/Celeron M/Core Duo/Core2 Duo | ||
1080 | */ | 1182 | */ |
1081 | static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt) | 1183 | static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt) |
1082 | { | 1184 | { |
@@ -1087,10 +1189,7 @@ static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt) | |||
1087 | /* Allow module parameter override, else see if CPU supports parity */ | 1189 | /* Allow module parameter override, else see if CPU supports parity */ |
1088 | if (sysbus_parity != -1) { | 1190 | if (sysbus_parity != -1) { |
1089 | enable = sysbus_parity; | 1191 | enable = sysbus_parity; |
1090 | } else if (cpu_id[0] && | 1192 | } else if (cpu_id[0] && !strstr(cpu_id, "Xeon")) { |
1091 | ((strstr(cpu_id, "Pentium") && strstr(cpu_id, " M ")) || | ||
1092 | (strstr(cpu_id, "Celeron") && strstr(cpu_id, " M ")) || | ||
1093 | (strstr(cpu_id, "Core") && strstr(cpu_id, "Duo")))) { | ||
1094 | e752x_printk(KERN_INFO, "System Bus Parity not " | 1193 | e752x_printk(KERN_INFO, "System Bus Parity not " |
1095 | "supported by CPU, disabling\n"); | 1194 | "supported by CPU, disabling\n"); |
1096 | enable = 0; | 1195 | enable = 0; |
@@ -1187,6 +1286,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
1187 | mci->dev_name = pci_name(pdev); | 1286 | mci->dev_name = pci_name(pdev); |
1188 | mci->edac_check = e752x_check; | 1287 | mci->edac_check = e752x_check; |
1189 | mci->ctl_page_to_phys = ctl_page_to_phys; | 1288 | mci->ctl_page_to_phys = ctl_page_to_phys; |
1289 | mci->set_sdram_scrub_rate = set_sdram_scrub_rate; | ||
1290 | mci->get_sdram_scrub_rate = get_sdram_scrub_rate; | ||
1190 | 1291 | ||
1191 | /* set the map type. 1 = normal, 0 = reversed | 1292 | /* set the map type. 1 = normal, 0 = reversed |
1192 | * Must be set before e752x_init_csrows in case csrow mapping | 1293 | * Must be set before e752x_init_csrows in case csrow mapping |
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index 53764577035f..5fdedbc0f545 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c | |||
@@ -137,7 +137,7 @@ static ssize_t edac_dev_ctl_info_store(struct kobject *kobj, | |||
137 | } | 137 | } |
138 | 138 | ||
139 | /* edac_dev file operations for an 'ctl_info' */ | 139 | /* edac_dev file operations for an 'ctl_info' */ |
140 | static struct sysfs_ops device_ctl_info_ops = { | 140 | static const struct sysfs_ops device_ctl_info_ops = { |
141 | .show = edac_dev_ctl_info_show, | 141 | .show = edac_dev_ctl_info_show, |
142 | .store = edac_dev_ctl_info_store | 142 | .store = edac_dev_ctl_info_store |
143 | }; | 143 | }; |
@@ -373,7 +373,7 @@ static ssize_t edac_dev_instance_store(struct kobject *kobj, | |||
373 | } | 373 | } |
374 | 374 | ||
375 | /* edac_dev file operations for an 'instance' */ | 375 | /* edac_dev file operations for an 'instance' */ |
376 | static struct sysfs_ops device_instance_ops = { | 376 | static const struct sysfs_ops device_instance_ops = { |
377 | .show = edac_dev_instance_show, | 377 | .show = edac_dev_instance_show, |
378 | .store = edac_dev_instance_store | 378 | .store = edac_dev_instance_store |
379 | }; | 379 | }; |
@@ -476,7 +476,7 @@ static ssize_t edac_dev_block_store(struct kobject *kobj, | |||
476 | } | 476 | } |
477 | 477 | ||
478 | /* edac_dev file operations for a 'block' */ | 478 | /* edac_dev file operations for a 'block' */ |
479 | static struct sysfs_ops device_block_ops = { | 479 | static const struct sysfs_ops device_block_ops = { |
480 | .show = edac_dev_block_show, | 480 | .show = edac_dev_block_show, |
481 | .store = edac_dev_block_store | 481 | .store = edac_dev_block_store |
482 | }; | 482 | }; |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index e1d4ce083481..88840e9fa3e0 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -245,7 +245,7 @@ static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr, | |||
245 | return -EIO; | 245 | return -EIO; |
246 | } | 246 | } |
247 | 247 | ||
248 | static struct sysfs_ops csrowfs_ops = { | 248 | static const struct sysfs_ops csrowfs_ops = { |
249 | .show = csrowdev_show, | 249 | .show = csrowdev_show, |
250 | .store = csrowdev_store | 250 | .store = csrowdev_store |
251 | }; | 251 | }; |
@@ -575,7 +575,7 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, | |||
575 | } | 575 | } |
576 | 576 | ||
577 | /* Intermediate show/store table */ | 577 | /* Intermediate show/store table */ |
578 | static struct sysfs_ops mci_ops = { | 578 | static const struct sysfs_ops mci_ops = { |
579 | .show = mcidev_show, | 579 | .show = mcidev_show, |
580 | .store = mcidev_store | 580 | .store = mcidev_store |
581 | }; | 581 | }; |
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index fb60a877d768..bef94e3d9944 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -121,7 +121,7 @@ static ssize_t edac_pci_instance_store(struct kobject *kobj, | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /* fs_ops table */ | 123 | /* fs_ops table */ |
124 | static struct sysfs_ops pci_instance_ops = { | 124 | static const struct sysfs_ops pci_instance_ops = { |
125 | .show = edac_pci_instance_show, | 125 | .show = edac_pci_instance_show, |
126 | .store = edac_pci_instance_store | 126 | .store = edac_pci_instance_store |
127 | }; | 127 | }; |
@@ -261,7 +261,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj, | |||
261 | return -EIO; | 261 | return -EIO; |
262 | } | 262 | } |
263 | 263 | ||
264 | static struct sysfs_ops edac_pci_sysfs_ops = { | 264 | static const struct sysfs_ops edac_pci_sysfs_ops = { |
265 | .show = edac_pci_dev_show, | 265 | .show = edac_pci_dev_show, |
266 | .store = edac_pci_dev_store | 266 | .store = edac_pci_dev_store |
267 | }; | 267 | }; |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index ecd5928d7110..94cac0aacea3 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -239,16 +239,15 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, | |||
239 | /* we only need the error registers */ | 239 | /* we only need the error registers */ |
240 | r.start += 0xe00; | 240 | r.start += 0xe00; |
241 | 241 | ||
242 | if (!devm_request_mem_region(&op->dev, r.start, | 242 | if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r), |
243 | r.end - r.start + 1, pdata->name)) { | 243 | pdata->name)) { |
244 | printk(KERN_ERR "%s: Error while requesting mem region\n", | 244 | printk(KERN_ERR "%s: Error while requesting mem region\n", |
245 | __func__); | 245 | __func__); |
246 | res = -EBUSY; | 246 | res = -EBUSY; |
247 | goto err; | 247 | goto err; |
248 | } | 248 | } |
249 | 249 | ||
250 | pdata->pci_vbase = devm_ioremap(&op->dev, r.start, | 250 | pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r)); |
251 | r.end - r.start + 1); | ||
252 | if (!pdata->pci_vbase) { | 251 | if (!pdata->pci_vbase) { |
253 | printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); | 252 | printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); |
254 | res = -ENOMEM; | 253 | res = -ENOMEM; |
@@ -668,15 +667,125 @@ static struct of_platform_driver mpc85xx_l2_err_driver = { | |||
668 | 667 | ||
669 | /**************************** MC Err device ***************************/ | 668 | /**************************** MC Err device ***************************/ |
670 | 669 | ||
670 | /* | ||
671 | * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the | ||
672 | * MPC8572 User's Manual. Each line represents a syndrome bit column as a | ||
673 | * 64-bit value, but split into an upper and lower 32-bit chunk. The labels | ||
674 | * below correspond to Freescale's manuals. | ||
675 | */ | ||
676 | static unsigned int ecc_table[16] = { | ||
677 | /* MSB LSB */ | ||
678 | /* [0:31] [32:63] */ | ||
679 | 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */ | ||
680 | 0x00ff00ff, 0x00fff0ff, | ||
681 | 0x0f0f0f0f, 0x0f0fff00, | ||
682 | 0x11113333, 0x7777000f, | ||
683 | 0x22224444, 0x8888222f, | ||
684 | 0x44448888, 0xffff4441, | ||
685 | 0x8888ffff, 0x11118882, | ||
686 | 0xffff1111, 0x22221114, /* Syndrome bit 0 */ | ||
687 | }; | ||
688 | |||
689 | /* | ||
690 | * Calculate the correct ECC value for a 64-bit value specified by high:low | ||
691 | */ | ||
692 | static u8 calculate_ecc(u32 high, u32 low) | ||
693 | { | ||
694 | u32 mask_low; | ||
695 | u32 mask_high; | ||
696 | int bit_cnt; | ||
697 | u8 ecc = 0; | ||
698 | int i; | ||
699 | int j; | ||
700 | |||
701 | for (i = 0; i < 8; i++) { | ||
702 | mask_high = ecc_table[i * 2]; | ||
703 | mask_low = ecc_table[i * 2 + 1]; | ||
704 | bit_cnt = 0; | ||
705 | |||
706 | for (j = 0; j < 32; j++) { | ||
707 | if ((mask_high >> j) & 1) | ||
708 | bit_cnt ^= (high >> j) & 1; | ||
709 | if ((mask_low >> j) & 1) | ||
710 | bit_cnt ^= (low >> j) & 1; | ||
711 | } | ||
712 | |||
713 | ecc |= bit_cnt << i; | ||
714 | } | ||
715 | |||
716 | return ecc; | ||
717 | } | ||
718 | |||
719 | /* | ||
720 | * Create the syndrome code which is generated if the data line specified by | ||
721 | * 'bit' failed. Eg generate an 8-bit codes seen in Table 8-55 in the MPC8641 | ||
722 | * User's Manual and 9-61 in the MPC8572 User's Manual. | ||
723 | */ | ||
724 | static u8 syndrome_from_bit(unsigned int bit) { | ||
725 | int i; | ||
726 | u8 syndrome = 0; | ||
727 | |||
728 | /* | ||
729 | * Cycle through the upper or lower 32-bit portion of each value in | ||
730 | * ecc_table depending on if 'bit' is in the upper or lower half of | ||
731 | * 64-bit data. | ||
732 | */ | ||
733 | for (i = bit < 32; i < 16; i += 2) | ||
734 | syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2); | ||
735 | |||
736 | return syndrome; | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * Decode data and ecc syndrome to determine what went wrong | ||
741 | * Note: This can only decode single-bit errors | ||
742 | */ | ||
743 | static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc, | ||
744 | int *bad_data_bit, int *bad_ecc_bit) | ||
745 | { | ||
746 | int i; | ||
747 | u8 syndrome; | ||
748 | |||
749 | *bad_data_bit = -1; | ||
750 | *bad_ecc_bit = -1; | ||
751 | |||
752 | /* | ||
753 | * Calculate the ECC of the captured data and XOR it with the captured | ||
754 | * ECC to find an ECC syndrome value we can search for | ||
755 | */ | ||
756 | syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc; | ||
757 | |||
758 | /* Check if a data line is stuck... */ | ||
759 | for (i = 0; i < 64; i++) { | ||
760 | if (syndrome == syndrome_from_bit(i)) { | ||
761 | *bad_data_bit = i; | ||
762 | return; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | /* If data is correct, check ECC bits for errors... */ | ||
767 | for (i = 0; i < 8; i++) { | ||
768 | if ((syndrome >> i) & 0x1) { | ||
769 | *bad_ecc_bit = i; | ||
770 | return; | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
671 | static void mpc85xx_mc_check(struct mem_ctl_info *mci) | 775 | static void mpc85xx_mc_check(struct mem_ctl_info *mci) |
672 | { | 776 | { |
673 | struct mpc85xx_mc_pdata *pdata = mci->pvt_info; | 777 | struct mpc85xx_mc_pdata *pdata = mci->pvt_info; |
674 | struct csrow_info *csrow; | 778 | struct csrow_info *csrow; |
779 | u32 bus_width; | ||
675 | u32 err_detect; | 780 | u32 err_detect; |
676 | u32 syndrome; | 781 | u32 syndrome; |
677 | u32 err_addr; | 782 | u32 err_addr; |
678 | u32 pfn; | 783 | u32 pfn; |
679 | int row_index; | 784 | int row_index; |
785 | u32 cap_high; | ||
786 | u32 cap_low; | ||
787 | int bad_data_bit; | ||
788 | int bad_ecc_bit; | ||
680 | 789 | ||
681 | err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); | 790 | err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); |
682 | if (!err_detect) | 791 | if (!err_detect) |
@@ -692,6 +801,15 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci) | |||
692 | } | 801 | } |
693 | 802 | ||
694 | syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC); | 803 | syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC); |
804 | |||
805 | /* Mask off appropriate bits of syndrome based on bus width */ | ||
806 | bus_width = (in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG) & | ||
807 | DSC_DBW_MASK) ? 32 : 64; | ||
808 | if (bus_width == 64) | ||
809 | syndrome &= 0xff; | ||
810 | else | ||
811 | syndrome &= 0xffff; | ||
812 | |||
695 | err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS); | 813 | err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS); |
696 | pfn = err_addr >> PAGE_SHIFT; | 814 | pfn = err_addr >> PAGE_SHIFT; |
697 | 815 | ||
@@ -701,14 +819,35 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci) | |||
701 | break; | 819 | break; |
702 | } | 820 | } |
703 | 821 | ||
704 | mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n", | 822 | cap_high = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_HI); |
705 | in_be32(pdata->mc_vbase + | 823 | cap_low = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_LO); |
706 | MPC85XX_MC_CAPTURE_DATA_HI)); | 824 | |
707 | mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n", | 825 | /* |
708 | in_be32(pdata->mc_vbase + | 826 | * Analyze single-bit errors on 64-bit wide buses |
709 | MPC85XX_MC_CAPTURE_DATA_LO)); | 827 | * TODO: Add support for 32-bit wide buses |
710 | mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#8.8x\n", syndrome); | 828 | */ |
711 | mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr); | 829 | if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) { |
830 | sbe_ecc_decode(cap_high, cap_low, syndrome, | ||
831 | &bad_data_bit, &bad_ecc_bit); | ||
832 | |||
833 | if (bad_data_bit != -1) | ||
834 | mpc85xx_mc_printk(mci, KERN_ERR, | ||
835 | "Faulty Data bit: %d\n", bad_data_bit); | ||
836 | if (bad_ecc_bit != -1) | ||
837 | mpc85xx_mc_printk(mci, KERN_ERR, | ||
838 | "Faulty ECC bit: %d\n", bad_ecc_bit); | ||
839 | |||
840 | mpc85xx_mc_printk(mci, KERN_ERR, | ||
841 | "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n", | ||
842 | cap_high ^ (1 << (bad_data_bit - 32)), | ||
843 | cap_low ^ (1 << bad_data_bit), | ||
844 | syndrome ^ (1 << bad_ecc_bit)); | ||
845 | } | ||
846 | |||
847 | mpc85xx_mc_printk(mci, KERN_ERR, | ||
848 | "Captured Data / ECC:\t%#8.8x_%08x / %#2.2x\n", | ||
849 | cap_high, cap_low, syndrome); | ||
850 | mpc85xx_mc_printk(mci, KERN_ERR, "Err addr: %#8.8x\n", err_addr); | ||
712 | mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn); | 851 | mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn); |
713 | 852 | ||
714 | /* we are out of range */ | 853 | /* we are out of range */ |
diff --git a/drivers/edac/mpc85xx_edac.h b/drivers/edac/mpc85xx_edac.h index 52432ee7c4b9..cb24df839460 100644 --- a/drivers/edac/mpc85xx_edac.h +++ b/drivers/edac/mpc85xx_edac.h | |||
@@ -48,6 +48,9 @@ | |||
48 | #define DSC_MEM_EN 0x80000000 | 48 | #define DSC_MEM_EN 0x80000000 |
49 | #define DSC_ECC_EN 0x20000000 | 49 | #define DSC_ECC_EN 0x20000000 |
50 | #define DSC_RD_EN 0x10000000 | 50 | #define DSC_RD_EN 0x10000000 |
51 | #define DSC_DBW_MASK 0x00180000 | ||
52 | #define DSC_DBW_32 0x00080000 | ||
53 | #define DSC_DBW_64 0x00000000 | ||
51 | 54 | ||
52 | #define DSC_SDTYPE_MASK 0x07000000 | 55 | #define DSC_SDTYPE_MASK 0x07000000 |
53 | 56 | ||
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 014cabd3afda..5db0518c66da 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/rwsem.h> | 35 | #include <linux/rwsem.h> |
36 | #include <linux/semaphore.h> | ||
37 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
38 | #include <linux/string.h> | 37 | #include <linux/string.h> |
39 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
@@ -828,9 +827,9 @@ static int update_unit(struct device *dev, void *data) | |||
828 | struct fw_driver *driver = (struct fw_driver *)dev->driver; | 827 | struct fw_driver *driver = (struct fw_driver *)dev->driver; |
829 | 828 | ||
830 | if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) { | 829 | if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) { |
831 | down(&dev->sem); | 830 | device_lock(dev); |
832 | driver->update(unit); | 831 | driver->update(unit); |
833 | up(&dev->sem); | 832 | device_unlock(dev); |
834 | } | 833 | } |
835 | 834 | ||
836 | return 0; | 835 | return 0; |
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 9e4f59dc7f1e..110e24e50883 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c | |||
@@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) | |||
122 | return ret; | 122 | return ret; |
123 | } | 123 | } |
124 | 124 | ||
125 | static struct sysfs_ops edd_attr_ops = { | 125 | static const struct sysfs_ops edd_attr_ops = { |
126 | .show = edd_attr_show, | 126 | .show = edd_attr_show, |
127 | }; | 127 | }; |
128 | 128 | ||
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index f4f709d1370b..082f06ecd327 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -362,7 +362,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr, | |||
362 | return ret; | 362 | return ret; |
363 | } | 363 | } |
364 | 364 | ||
365 | static struct sysfs_ops efivar_attr_ops = { | 365 | static const struct sysfs_ops efivar_attr_ops = { |
366 | .show = efivar_attr_show, | 366 | .show = efivar_attr_show, |
367 | .store = efivar_attr_store, | 367 | .store = efivar_attr_store, |
368 | }; | 368 | }; |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index a3600e3ed0fa..ed2801c378de 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
@@ -519,7 +519,7 @@ static ssize_t ibft_show_attribute(struct kobject *kobj, | |||
519 | return ret; | 519 | return ret; |
520 | } | 520 | } |
521 | 521 | ||
522 | static struct sysfs_ops ibft_attr_ops = { | 522 | static const struct sysfs_ops ibft_attr_ops = { |
523 | .show = ibft_show_attribute, | 523 | .show = ibft_show_attribute, |
524 | }; | 524 | }; |
525 | 525 | ||
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 20f645743ead..d59f7cad2269 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c | |||
@@ -74,7 +74,7 @@ static struct attribute *def_attrs[] = { | |||
74 | NULL | 74 | NULL |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct sysfs_ops memmap_attr_ops = { | 77 | static const struct sysfs_ops memmap_attr_ops = { |
78 | .show = memmap_attr_show, | 78 | .show = memmap_attr_show, |
79 | }; | 79 | }; |
80 | 80 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9006fdb26fea..6d1b86661e63 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -623,7 +623,9 @@ static const struct attribute_group gpiochip_attr_group = { | |||
623 | * /sys/class/gpio/unexport ... write-only | 623 | * /sys/class/gpio/unexport ... write-only |
624 | * integer N ... number of GPIO to unexport | 624 | * integer N ... number of GPIO to unexport |
625 | */ | 625 | */ |
626 | static ssize_t export_store(struct class *class, const char *buf, size_t len) | 626 | static ssize_t export_store(struct class *class, |
627 | struct class_attribute *attr, | ||
628 | const char *buf, size_t len) | ||
627 | { | 629 | { |
628 | long gpio; | 630 | long gpio; |
629 | int status; | 631 | int status; |
@@ -653,7 +655,9 @@ done: | |||
653 | return status ? : len; | 655 | return status ? : len; |
654 | } | 656 | } |
655 | 657 | ||
656 | static ssize_t unexport_store(struct class *class, const char *buf, size_t len) | 658 | static ssize_t unexport_store(struct class *class, |
659 | struct class_attribute *attr, | ||
660 | const char *buf, size_t len) | ||
657 | { | 661 | { |
658 | long gpio; | 662 | long gpio; |
659 | int status; | 663 | int status; |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 7e42b7e9d43a..014ce24761b9 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -70,19 +70,17 @@ static int drm_class_resume(struct device *dev) | |||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | /* Display the version of drm_core. This doesn't work right in current design */ | ||
74 | static ssize_t version_show(struct class *dev, char *buf) | ||
75 | { | ||
76 | return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR, | ||
77 | CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | ||
78 | } | ||
79 | |||
80 | static char *drm_devnode(struct device *dev, mode_t *mode) | 73 | static char *drm_devnode(struct device *dev, mode_t *mode) |
81 | { | 74 | { |
82 | return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); | 75 | return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); |
83 | } | 76 | } |
84 | 77 | ||
85 | static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | 78 | static CLASS_ATTR_STRING(version, S_IRUGO, |
79 | CORE_NAME " " | ||
80 | __stringify(CORE_MAJOR) "." | ||
81 | __stringify(CORE_MINOR) "." | ||
82 | __stringify(CORE_PATCHLEVEL) " " | ||
83 | CORE_DATE); | ||
86 | 84 | ||
87 | /** | 85 | /** |
88 | * drm_sysfs_create - create a struct drm_sysfs_class structure | 86 | * drm_sysfs_create - create a struct drm_sysfs_class structure |
@@ -109,7 +107,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name) | |||
109 | class->suspend = drm_class_suspend; | 107 | class->suspend = drm_class_suspend; |
110 | class->resume = drm_class_resume; | 108 | class->resume = drm_class_resume; |
111 | 109 | ||
112 | err = class_create_file(class, &class_attr_version); | 110 | err = class_create_file(class, &class_attr_version.attr); |
113 | if (err) | 111 | if (err) |
114 | goto err_out_class; | 112 | goto err_out_class; |
115 | 113 | ||
@@ -132,7 +130,7 @@ void drm_sysfs_destroy(void) | |||
132 | { | 130 | { |
133 | if ((drm_class == NULL) || (IS_ERR(drm_class))) | 131 | if ((drm_class == NULL) || (IS_ERR(drm_class))) |
134 | return; | 132 | return; |
135 | class_remove_file(drm_class, &class_attr_version); | 133 | class_remove_file(drm_class, &class_attr_version.attr); |
136 | class_destroy(drm_class); | 134 | class_destroy(drm_class); |
137 | } | 135 | } |
138 | 136 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 71247da17da5..75bceee76044 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -3545,7 +3545,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
3545 | * at which modes should be set up in the dual link style. | 3545 | * at which modes should be set up in the dual link style. |
3546 | * | 3546 | * |
3547 | * Following the header, the BMP (ver 0xa) table has several records, | 3547 | * Following the header, the BMP (ver 0xa) table has several records, |
3548 | * indexed by a seperate xlat table, indexed in turn by the fp strap in | 3548 | * indexed by a separate xlat table, indexed in turn by the fp strap in |
3549 | * EXTDEV_BOOT. Each record had a config byte, followed by 6 script | 3549 | * EXTDEV_BOOT. Each record had a config byte, followed by 6 script |
3550 | * numbers for use by INIT_SUB which controlled panel init and power, | 3550 | * numbers for use by INIT_SUB which controlled panel init and power, |
3551 | * and finally a dword of ms to sleep between power off and on | 3551 | * and finally a dword of ms to sleep between power off and on |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5f8d987af363..4b9aaf2a8d0f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -553,7 +553,7 @@ struct drm_nouveau_private { | |||
553 | uint32_t ramro_offset; | 553 | uint32_t ramro_offset; |
554 | uint32_t ramro_size; | 554 | uint32_t ramro_size; |
555 | 555 | ||
556 | /* base physical adresses */ | 556 | /* base physical addresses */ |
557 | uint64_t fb_phys; | 557 | uint64_t fb_phys; |
558 | uint64_t fb_available_size; | 558 | uint64_t fb_available_size; |
559 | uint64_t fb_mappable_pages; | 559 | uint64_t fb_mappable_pages; |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 3c32f840dcd2..40ab6d9c3736 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -1093,7 +1093,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, | |||
1093 | /* judging by the first tile offset needed, could possibly | 1093 | /* judging by the first tile offset needed, could possibly |
1094 | directly address/clear 4x4 tiles instead of 8x2 * 4x4 | 1094 | directly address/clear 4x4 tiles instead of 8x2 * 4x4 |
1095 | macro tiles, though would still need clear mask for | 1095 | macro tiles, though would still need clear mask for |
1096 | right/bottom if truely 4x4 granularity is desired ? */ | 1096 | right/bottom if truly 4x4 granularity is desired ? */ |
1097 | OUT_RING(tileoffset * 16); | 1097 | OUT_RING(tileoffset * 16); |
1098 | /* the number of tiles to clear */ | 1098 | /* the number of tiles to clear */ |
1099 | OUT_RING(nrtilesx + 1); | 1099 | OUT_RING(nrtilesx + 1); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce4567d..89c38c49066f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -128,7 +128,7 @@ static struct attribute *ttm_bo_global_attrs[] = { | |||
128 | NULL | 128 | NULL |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct sysfs_ops ttm_bo_global_ops = { | 131 | static const struct sysfs_ops ttm_bo_global_ops = { |
132 | .show = &ttm_bo_global_show | 132 | .show = &ttm_bo_global_show |
133 | }; | 133 | }; |
134 | 134 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index f5245c02b8fd..eb143e04d402 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c | |||
@@ -152,7 +152,7 @@ static struct attribute *ttm_mem_zone_attrs[] = { | |||
152 | NULL | 152 | NULL |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static struct sysfs_ops ttm_mem_zone_ops = { | 155 | static const struct sysfs_ops ttm_mem_zone_ops = { |
156 | .show = &ttm_mem_zone_show, | 156 | .show = &ttm_mem_zone_show, |
157 | .store = &ttm_mem_zone_store | 157 | .store = &ttm_mem_zone_store |
158 | }; | 158 | }; |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 5935b8842e86..34079f251cd4 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
@@ -150,7 +150,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
150 | cur_irq++; | 150 | cur_irq++; |
151 | } | 151 | } |
152 | 152 | ||
153 | /* Acknowlege interrupts */ | 153 | /* Acknowledge interrupts */ |
154 | VIA_WRITE(VIA_REG_INTERRUPT, status); | 154 | VIA_WRITE(VIA_REG_INTERRUPT, status); |
155 | 155 | ||
156 | 156 | ||
@@ -165,7 +165,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | |||
165 | u32 status; | 165 | u32 status; |
166 | 166 | ||
167 | if (dev_priv) { | 167 | if (dev_priv) { |
168 | /* Acknowlege interrupts */ | 168 | /* Acknowledge interrupts */ |
169 | status = VIA_READ(VIA_REG_INTERRUPT); | 169 | status = VIA_READ(VIA_REG_INTERRUPT); |
170 | VIA_WRITE(VIA_REG_INTERRUPT, status | | 170 | VIA_WRITE(VIA_REG_INTERRUPT, status | |
171 | dev_priv->irq_pending_mask); | 171 | dev_priv->irq_pending_mask); |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 79d9edd0bdfa..7a0d2e4661a1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -68,22 +68,25 @@ static const struct { | |||
68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ | 68 | #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ |
69 | &max, EV_KEY, (c)) | 69 | &max, EV_KEY, (c)) |
70 | 70 | ||
71 | static inline int match_scancode(int code, int scancode) | 71 | static inline int match_scancode(unsigned int code, unsigned int scancode) |
72 | { | 72 | { |
73 | if (scancode == 0) | 73 | if (scancode == 0) |
74 | return 1; | 74 | return 1; |
75 | return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode); | 75 | |
76 | return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; | ||
76 | } | 77 | } |
77 | 78 | ||
78 | static inline int match_keycode(int code, int keycode) | 79 | static inline int match_keycode(unsigned int code, unsigned int keycode) |
79 | { | 80 | { |
80 | if (keycode == 0) | 81 | if (keycode == 0) |
81 | return 1; | 82 | return 1; |
82 | return (code == keycode); | 83 | |
84 | return code == keycode; | ||
83 | } | 85 | } |
84 | 86 | ||
85 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, | 87 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, |
86 | int scancode, int keycode) | 88 | unsigned int scancode, |
89 | unsigned int keycode) | ||
87 | { | 90 | { |
88 | int i, j, k; | 91 | int i, j, k; |
89 | struct hid_report *report; | 92 | struct hid_report *report; |
@@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid, | |||
105 | return NULL; | 108 | return NULL; |
106 | } | 109 | } |
107 | 110 | ||
108 | static int hidinput_getkeycode(struct input_dev *dev, int scancode, | 111 | static int hidinput_getkeycode(struct input_dev *dev, |
109 | int *keycode) | 112 | unsigned int scancode, unsigned int *keycode) |
110 | { | 113 | { |
111 | struct hid_device *hid = input_get_drvdata(dev); | 114 | struct hid_device *hid = input_get_drvdata(dev); |
112 | struct hid_usage *usage; | 115 | struct hid_usage *usage; |
@@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode, | |||
119 | return -EINVAL; | 122 | return -EINVAL; |
120 | } | 123 | } |
121 | 124 | ||
122 | static int hidinput_setkeycode(struct input_dev *dev, int scancode, | 125 | static int hidinput_setkeycode(struct input_dev *dev, |
123 | int keycode) | 126 | unsigned int scancode, unsigned int keycode) |
124 | { | 127 | { |
125 | struct hid_device *hid = input_get_drvdata(dev); | 128 | struct hid_device *hid = input_get_drvdata(dev); |
126 | struct hid_usage *usage; | 129 | struct hid_usage *usage; |
127 | int old_keycode; | 130 | int old_keycode; |
128 | 131 | ||
129 | if (keycode < 0 || keycode > KEY_MAX) | ||
130 | return -EINVAL; | ||
131 | |||
132 | usage = hidinput_find_key(hid, scancode, 0); | 132 | usage = hidinput_find_key(hid, scancode, 0); |
133 | if (usage) { | 133 | if (usage) { |
134 | old_keycode = usage->code; | 134 | old_keycode = usage->code; |
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 02ce9cff5fcf..d06083fdffbb 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig | |||
@@ -73,7 +73,6 @@ config I2C_SMBUS | |||
73 | 73 | ||
74 | source drivers/i2c/algos/Kconfig | 74 | source drivers/i2c/algos/Kconfig |
75 | source drivers/i2c/busses/Kconfig | 75 | source drivers/i2c/busses/Kconfig |
76 | source drivers/i2c/chips/Kconfig | ||
77 | 76 | ||
78 | config I2C_DEBUG_CORE | 77 | config I2C_DEBUG_CORE |
79 | bool "I2C Core debugging messages" | 78 | bool "I2C Core debugging messages" |
@@ -98,12 +97,4 @@ config I2C_DEBUG_BUS | |||
98 | a problem with I2C support and want to see more of what is going | 97 | a problem with I2C support and want to see more of what is going |
99 | on. | 98 | on. |
100 | 99 | ||
101 | config I2C_DEBUG_CHIP | ||
102 | bool "I2C Chip debugging messages" | ||
103 | help | ||
104 | Say Y here if you want the I2C chip drivers to produce a bunch of | ||
105 | debug messages to the system log. Select this if you are having | ||
106 | a problem with I2C support and want to see more of what is going | ||
107 | on. | ||
108 | |||
109 | endif # I2C | 100 | endif # I2C |
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index acd0250c16a0..a7d9b4be9bb3 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
@@ -6,7 +6,7 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o | |||
6 | obj-$(CONFIG_I2C) += i2c-core.o | 6 | obj-$(CONFIG_I2C) += i2c-core.o |
7 | obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o | 7 | obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o |
8 | obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o | 8 | obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o |
9 | obj-y += busses/ chips/ algos/ | 9 | obj-y += algos/ busses/ |
10 | 10 | ||
11 | ifeq ($(CONFIG_I2C_DEBUG_CORE),y) | 11 | ifeq ($(CONFIG_I2C_DEBUG_CORE),y) |
12 | EXTRA_CFLAGS += -DDEBUG | 12 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index e25e13980af3..e8d568c3fb09 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -522,6 +522,12 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
522 | int i, ret; | 522 | int i, ret; |
523 | unsigned short nak_ok; | 523 | unsigned short nak_ok; |
524 | 524 | ||
525 | if (adap->pre_xfer) { | ||
526 | ret = adap->pre_xfer(i2c_adap); | ||
527 | if (ret < 0) | ||
528 | return ret; | ||
529 | } | ||
530 | |||
525 | bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); | 531 | bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); |
526 | i2c_start(adap); | 532 | i2c_start(adap); |
527 | for (i = 0; i < num; i++) { | 533 | for (i = 0; i < num; i++) { |
@@ -570,6 +576,9 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
570 | bailout: | 576 | bailout: |
571 | bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); | 577 | bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); |
572 | i2c_stop(adap); | 578 | i2c_stop(adap); |
579 | |||
580 | if (adap->post_xfer) | ||
581 | adap->post_xfer(i2c_adap); | ||
573 | return ret; | 582 | return ret; |
574 | } | 583 | } |
575 | 584 | ||
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 7ce75775ec73..6b6bd06202b2 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c | |||
@@ -176,7 +176,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
176 | */ | 176 | */ |
177 | if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { | 177 | if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { |
178 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); | 178 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); |
179 | return -ENXIO; /* definetly not PCF8584 */ | 179 | return -ENXIO; /* definitely not PCF8584 */ |
180 | } | 180 | } |
181 | 181 | ||
182 | /* load own address in S0, effective address is (own << 1) */ | 182 | /* load own address in S0, effective address is (own << 1) */ |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9da5b05cdb52..299b918455a3 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -416,9 +416,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, | |||
416 | data->block[0] = 32; /* max for SMBus block reads */ | 416 | data->block[0] = 32; /* max for SMBus block reads */ |
417 | } | 417 | } |
418 | 418 | ||
419 | /* Experience has shown that the block buffer can only be used for | ||
420 | SMBus (not I2C) block transactions, even though the datasheet | ||
421 | doesn't mention this limitation. */ | ||
419 | if ((i801_features & FEATURE_BLOCK_BUFFER) | 422 | if ((i801_features & FEATURE_BLOCK_BUFFER) |
420 | && !(command == I2C_SMBUS_I2C_BLOCK_DATA | 423 | && command != I2C_SMBUS_I2C_BLOCK_DATA |
421 | && read_write == I2C_SMBUS_READ) | ||
422 | && i801_set_block_buffer_mode() == 0) | 424 | && i801_set_block_buffer_mode() == 0) |
423 | result = i801_block_transaction_by_block(data, read_write, | 425 | result = i801_block_transaction_by_block(data, read_write, |
424 | hwpec); | 426 | hwpec); |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 913abd7c172f..c7c237537f81 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -850,7 +850,7 @@ static const struct i2c_algorithm omap_i2c_algo = { | |||
850 | .functionality = omap_i2c_func, | 850 | .functionality = omap_i2c_func, |
851 | }; | 851 | }; |
852 | 852 | ||
853 | static int __init | 853 | static int __devinit |
854 | omap_i2c_probe(struct platform_device *pdev) | 854 | omap_i2c_probe(struct platform_device *pdev) |
855 | { | 855 | { |
856 | struct omap_i2c_dev *dev; | 856 | struct omap_i2c_dev *dev; |
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 1c440a70ec61..b289ec99eeba 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c | |||
@@ -122,9 +122,14 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, | |||
122 | 122 | ||
123 | rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len); | 123 | rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len); |
124 | if (rc) { | 124 | if (rc) { |
125 | dev_err(&adap->dev, | 125 | if (rc == -ENXIO) |
126 | "I2C transfer at 0x%02x failed, size %d, err %d\n", | 126 | dev_dbg(&adap->dev, |
127 | addrdir >> 1, size, rc); | 127 | "I2C transfer at 0x%02x failed, size %d, " |
128 | "err %d\n", addrdir >> 1, size, rc); | ||
129 | else | ||
130 | dev_err(&adap->dev, | ||
131 | "I2C transfer at 0x%02x failed, size %d, " | ||
132 | "err %d\n", addrdir >> 1, size, rc); | ||
128 | goto bail; | 133 | goto bail; |
129 | } | 134 | } |
130 | 135 | ||
@@ -175,10 +180,16 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap, | |||
175 | goto bail; | 180 | goto bail; |
176 | } | 181 | } |
177 | rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); | 182 | rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); |
178 | if (rc < 0) | 183 | if (rc < 0) { |
179 | dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n", | 184 | if (rc == -ENXIO) |
180 | addrdir & 1 ? "read from" : "write to", addrdir >> 1, | 185 | dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n", |
181 | rc); | 186 | addrdir & 1 ? "read from" : "write to", |
187 | addrdir >> 1, rc); | ||
188 | else | ||
189 | dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n", | ||
190 | addrdir & 1 ? "read from" : "write to", | ||
191 | addrdir >> 1, rc); | ||
192 | } | ||
182 | bail: | 193 | bail: |
183 | pmac_i2c_close(bus); | 194 | pmac_i2c_close(bus); |
184 | return rc < 0 ? rc : 1; | 195 | return rc < 0 ? rc : 1; |
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 7647a20523a0..90ffbf6f9d4f 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | * History: | 13 | * History: |
14 | * Apr 2002: Initial version [CS] | 14 | * Apr 2002: Initial version [CS] |
15 | * Jun 2002: Properly seperated algo/adap [FB] | 15 | * Jun 2002: Properly separated algo/adap [FB] |
16 | * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem] | 16 | * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem] |
17 | * Jan 2003: added limited signal handling [Kai-Uwe Bloem] | 17 | * Jan 2003: added limited signal handling [Kai-Uwe Bloem] |
18 | * Sep 2004: Major rework to ensure efficient bus handling [RMK] | 18 | * Sep 2004: Major rework to ensure efficient bus handling [RMK] |
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index eece39a5a30e..f0ef8da6c554 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/delay.h> | ||
35 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
36 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
37 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig deleted file mode 100644 index ae4539d99bef..000000000000 --- a/drivers/i2c/chips/Kconfig +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | # | ||
2 | # Miscellaneous I2C chip drivers configuration | ||
3 | # | ||
4 | # *** DEPRECATED! Do not add new entries! See Makefile *** | ||
5 | # | ||
6 | |||
7 | menu "Miscellaneous I2C Chip support" | ||
8 | |||
9 | config SENSORS_TSL2550 | ||
10 | tristate "Taos TSL2550 ambient light sensor" | ||
11 | depends on EXPERIMENTAL | ||
12 | help | ||
13 | If you say yes here you get support for the Taos TSL2550 | ||
14 | ambient light sensor. | ||
15 | |||
16 | This driver can also be built as a module. If so, the module | ||
17 | will be called tsl2550. | ||
18 | |||
19 | endmenu | ||
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile deleted file mode 100644 index fe0af0f81f2d..000000000000 --- a/drivers/i2c/chips/Makefile +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for miscellaneous I2C chip drivers. | ||
3 | # | ||
4 | # Do not add new drivers to this directory! It is DEPRECATED. | ||
5 | # | ||
6 | # Device drivers are better grouped according to the functionality they | ||
7 | # implement rather than to the bus they are connected to. In particular: | ||
8 | # * Hardware monitoring chip drivers go to drivers/hwmon | ||
9 | # * RTC chip drivers go to drivers/rtc | ||
10 | # * I/O expander drivers go to drivers/gpio | ||
11 | # | ||
12 | |||
13 | obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o | ||
14 | |||
15 | ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) | ||
16 | EXTRA_CFLAGS += -DDEBUG | ||
17 | endif | ||
18 | |||
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 421278221243..7a8201ed2181 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/semaphore.h> | ||
26 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
27 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
28 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
@@ -55,7 +54,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) | |||
55 | * Drivers should either disable alerts, or provide at least | 54 | * Drivers should either disable alerts, or provide at least |
56 | * a minimal handler. Lock so client->driver won't change. | 55 | * a minimal handler. Lock so client->driver won't change. |
57 | */ | 56 | */ |
58 | down(&dev->sem); | 57 | device_lock(dev); |
59 | if (client->driver) { | 58 | if (client->driver) { |
60 | if (client->driver->alert) | 59 | if (client->driver->alert) |
61 | client->driver->alert(client, data->flag); | 60 | client->driver->alert(client, data->flag); |
@@ -63,7 +62,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) | |||
63 | dev_warn(&client->dev, "no driver alert()!\n"); | 62 | dev_warn(&client->dev, "no driver alert()!\n"); |
64 | } else | 63 | } else |
65 | dev_dbg(&client->dev, "alert with no driver\n"); | 64 | dev_dbg(&client->dev, "alert with no driver\n"); |
66 | up(&dev->sem); | 65 | device_unlock(dev); |
67 | 66 | ||
68 | /* Stop iterating after we find the device */ | 67 | /* Stop iterating after we find the device */ |
69 | return -EBUSY; | 68 | return -EBUSY; |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 5122b5a8aa2d..18350213479e 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/freezer.h> | 21 | #include <linux/freezer.h> |
22 | #include <linux/semaphore.h> | ||
23 | #include <asm/atomic.h> | 22 | #include <asm/atomic.h> |
24 | 23 | ||
25 | #include "csr.h" | 24 | #include "csr.h" |
@@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *dev, void *data) | |||
1397 | pdrv = container_of(drv, struct hpsb_protocol_driver, | 1396 | pdrv = container_of(drv, struct hpsb_protocol_driver, |
1398 | driver); | 1397 | driver); |
1399 | if (pdrv->update) { | 1398 | if (pdrv->update) { |
1400 | down(&ud->device.sem); | 1399 | device_lock(&ud->device); |
1401 | error = pdrv->update(ud); | 1400 | error = pdrv->update(ud); |
1402 | up(&ud->device.sem); | 1401 | device_unlock(&ud->device); |
1403 | } | 1402 | } |
1404 | if (error) | 1403 | if (error) |
1405 | device_release_driver(&ud->device); | 1404 | device_release_driver(&ud->device); |
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 9555fd253865..bf47fee79808 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c | |||
@@ -1452,7 +1452,7 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1452 | PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); | 1452 | PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c"); |
1453 | } else { | 1453 | } else { |
1454 | PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); | 1454 | PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom"); |
1455 | /* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a), | 1455 | /* FIXME: probably we should rewrite the max_rec, max_ROM(1394a), |
1456 | * generation(1394a) and link_spd(1394a) field and recalculate | 1456 | * generation(1394a) and link_spd(1394a) field and recalculate |
1457 | * the CRC */ | 1457 | * the CRC */ |
1458 | 1458 | ||
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 5130fc55b8e2..764787ebe8d8 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -3597,7 +3597,7 @@ static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr, | |||
3597 | atomic_long_read(&group->counter[cm_attr->index])); | 3597 | atomic_long_read(&group->counter[cm_attr->index])); |
3598 | } | 3598 | } |
3599 | 3599 | ||
3600 | static struct sysfs_ops cm_counter_ops = { | 3600 | static const struct sysfs_ops cm_counter_ops = { |
3601 | .show = cm_show_counter | 3601 | .show = cm_show_counter |
3602 | }; | 3602 | }; |
3603 | 3603 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 58463da814d1..e351b1548535 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -2953,6 +2953,9 @@ static void ib_mad_remove_device(struct ib_device *device) | |||
2953 | { | 2953 | { |
2954 | int i, num_ports, cur_port; | 2954 | int i, num_ports, cur_port; |
2955 | 2955 | ||
2956 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) | ||
2957 | return; | ||
2958 | |||
2956 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 2959 | if (device->node_type == RDMA_NODE_IB_SWITCH) { |
2957 | num_ports = 1; | 2960 | num_ports = 1; |
2958 | cur_port = 0; | 2961 | cur_port = 0; |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 158a214da2f7..1558bb7fc74d 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -79,7 +79,7 @@ static ssize_t port_attr_show(struct kobject *kobj, | |||
79 | return port_attr->show(p, port_attr, buf); | 79 | return port_attr->show(p, port_attr, buf); |
80 | } | 80 | } |
81 | 81 | ||
82 | static struct sysfs_ops port_sysfs_ops = { | 82 | static const struct sysfs_ops port_sysfs_ops = { |
83 | .show = port_attr_show | 83 | .show = port_attr_show |
84 | }; | 84 | }; |
85 | 85 | ||
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 1b09b735c5a8..017d6e24448f 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -1336,11 +1336,8 @@ static void ib_ucm_remove_one(struct ib_device *device) | |||
1336 | device_unregister(&ucm_dev->dev); | 1336 | device_unregister(&ucm_dev->dev); |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | static ssize_t show_abi_version(struct class *class, char *buf) | 1339 | static CLASS_ATTR_STRING(abi_version, S_IRUGO, |
1340 | { | 1340 | __stringify(IB_USER_CM_ABI_VERSION)); |
1341 | return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION); | ||
1342 | } | ||
1343 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); | ||
1344 | 1341 | ||
1345 | static int __init ib_ucm_init(void) | 1342 | static int __init ib_ucm_init(void) |
1346 | { | 1343 | { |
@@ -1353,7 +1350,7 @@ static int __init ib_ucm_init(void) | |||
1353 | goto error1; | 1350 | goto error1; |
1354 | } | 1351 | } |
1355 | 1352 | ||
1356 | ret = class_create_file(&cm_class, &class_attr_abi_version); | 1353 | ret = class_create_file(&cm_class, &class_attr_abi_version.attr); |
1357 | if (ret) { | 1354 | if (ret) { |
1358 | printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); | 1355 | printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); |
1359 | goto error2; | 1356 | goto error2; |
@@ -1367,7 +1364,7 @@ static int __init ib_ucm_init(void) | |||
1367 | return 0; | 1364 | return 0; |
1368 | 1365 | ||
1369 | error3: | 1366 | error3: |
1370 | class_remove_file(&cm_class, &class_attr_abi_version); | 1367 | class_remove_file(&cm_class, &class_attr_abi_version.attr); |
1371 | error2: | 1368 | error2: |
1372 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); | 1369 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); |
1373 | error1: | 1370 | error1: |
@@ -1377,7 +1374,7 @@ error1: | |||
1377 | static void __exit ib_ucm_cleanup(void) | 1374 | static void __exit ib_ucm_cleanup(void) |
1378 | { | 1375 | { |
1379 | ib_unregister_client(&ucm_client); | 1376 | ib_unregister_client(&ucm_client); |
1380 | class_remove_file(&cm_class, &class_attr_abi_version); | 1377 | class_remove_file(&cm_class, &class_attr_abi_version.attr); |
1381 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); | 1378 | unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); |
1382 | if (overflow_maj) | 1379 | if (overflow_maj) |
1383 | unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES); | 1380 | unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES); |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 02d360cfc2f7..04b585e86cb2 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -965,11 +965,8 @@ static ssize_t show_port(struct device *dev, struct device_attribute *attr, | |||
965 | } | 965 | } |
966 | static DEVICE_ATTR(port, S_IRUGO, show_port, NULL); | 966 | static DEVICE_ATTR(port, S_IRUGO, show_port, NULL); |
967 | 967 | ||
968 | static ssize_t show_abi_version(struct class *class, char *buf) | 968 | static CLASS_ATTR_STRING(abi_version, S_IRUGO, |
969 | { | 969 | __stringify(IB_USER_MAD_ABI_VERSION)); |
970 | return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION); | ||
971 | } | ||
972 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); | ||
973 | 970 | ||
974 | static dev_t overflow_maj; | 971 | static dev_t overflow_maj; |
975 | static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); | 972 | static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); |
@@ -1194,7 +1191,7 @@ static int __init ib_umad_init(void) | |||
1194 | goto out_chrdev; | 1191 | goto out_chrdev; |
1195 | } | 1192 | } |
1196 | 1193 | ||
1197 | ret = class_create_file(umad_class, &class_attr_abi_version); | 1194 | ret = class_create_file(umad_class, &class_attr_abi_version.attr); |
1198 | if (ret) { | 1195 | if (ret) { |
1199 | printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); | 1196 | printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); |
1200 | goto out_class; | 1197 | goto out_class; |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 4fa2e6516441..d805cf365c8d 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -691,11 +691,8 @@ static ssize_t show_dev_abi_version(struct device *device, | |||
691 | } | 691 | } |
692 | static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); | 692 | static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); |
693 | 693 | ||
694 | static ssize_t show_abi_version(struct class *class, char *buf) | 694 | static CLASS_ATTR_STRING(abi_version, S_IRUGO, |
695 | { | 695 | __stringify(IB_USER_VERBS_ABI_VERSION)); |
696 | return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION); | ||
697 | } | ||
698 | static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); | ||
699 | 696 | ||
700 | static dev_t overflow_maj; | 697 | static dev_t overflow_maj; |
701 | static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES); | 698 | static DECLARE_BITMAP(overflow_map, IB_UVERBS_MAX_DEVICES); |
@@ -841,7 +838,7 @@ static int __init ib_uverbs_init(void) | |||
841 | goto out_chrdev; | 838 | goto out_chrdev; |
842 | } | 839 | } |
843 | 840 | ||
844 | ret = class_create_file(uverbs_class, &class_attr_abi_version); | 841 | ret = class_create_file(uverbs_class, &class_attr_abi_version.attr); |
845 | if (ret) { | 842 | if (ret) { |
846 | printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n"); | 843 | printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n"); |
847 | goto out_class; | 844 | goto out_class; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index ee1d8b4d4541..63f975f3e30f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
@@ -189,6 +189,7 @@ static void close_rnic_dev(struct t3cdev *tdev) | |||
189 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { | 189 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { |
190 | if (dev->rdev.t3cdev_p == tdev) { | 190 | if (dev->rdev.t3cdev_p == tdev) { |
191 | dev->rdev.flags = CXIO_ERROR_FATAL; | 191 | dev->rdev.flags = CXIO_ERROR_FATAL; |
192 | synchronize_net(); | ||
192 | cancel_delayed_work_sync(&dev->db_drop_task); | 193 | cancel_delayed_work_sync(&dev->db_drop_task); |
193 | list_del(&dev->entry); | 194 | list_del(&dev->entry); |
194 | iwch_unregister_device(dev); | 195 | iwch_unregister_device(dev); |
@@ -217,6 +218,7 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id) | |||
217 | switch (evt) { | 218 | switch (evt) { |
218 | case OFFLOAD_STATUS_DOWN: { | 219 | case OFFLOAD_STATUS_DOWN: { |
219 | rdev->flags = CXIO_ERROR_FATAL; | 220 | rdev->flags = CXIO_ERROR_FATAL; |
221 | synchronize_net(); | ||
220 | event.event = IB_EVENT_DEVICE_FATAL; | 222 | event.event = IB_EVENT_DEVICE_FATAL; |
221 | dispatch = 1; | 223 | dispatch = 1; |
222 | break; | 224 | break; |
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h index 5d28e3e98a20..90c4efa67586 100644 --- a/drivers/infiniband/hw/ehca/ehca_qes.h +++ b/drivers/infiniband/hw/ehca/ehca_qes.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #include "ehca_tools.h" | 47 | #include "ehca_tools.h" |
48 | 48 | ||
49 | /* virtual scatter gather entry to specify remote adresses with length */ | 49 | /* virtual scatter gather entry to specify remote addresses with length */ |
50 | struct ehca_vsgentry { | 50 | struct ehca_vsgentry { |
51 | u64 vaddr; | 51 | u64 vaddr; |
52 | u32 lkey; | 52 | u32 lkey; |
@@ -148,7 +148,7 @@ struct ehca_wqe { | |||
148 | u32 immediate_data; | 148 | u32 immediate_data; |
149 | union { | 149 | union { |
150 | struct { | 150 | struct { |
151 | u64 remote_virtual_adress; | 151 | u64 remote_virtual_address; |
152 | u32 rkey; | 152 | u32 rkey; |
153 | u32 reserved; | 153 | u32 reserved; |
154 | u64 atomic_1st_op_dma_len; | 154 | u64 atomic_1st_op_dma_len; |
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index e3ec7fdd67bd..9a3fbfca9b41 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c | |||
@@ -269,7 +269,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, | |||
269 | /* no break is intentional here */ | 269 | /* no break is intentional here */ |
270 | case IB_QPT_RC: | 270 | case IB_QPT_RC: |
271 | /* TODO: atomic not implemented */ | 271 | /* TODO: atomic not implemented */ |
272 | wqe_p->u.nud.remote_virtual_adress = | 272 | wqe_p->u.nud.remote_virtual_address = |
273 | send_wr->wr.rdma.remote_addr; | 273 | send_wr->wr.rdma.remote_addr; |
274 | wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey; | 274 | wqe_p->u.nud.rkey = send_wr->wr.rdma.rkey; |
275 | 275 | ||
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index ce7f53833577..925075557dc2 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -1899,9 +1899,14 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1899 | u16 wqe_fragment_index; | 1899 | u16 wqe_fragment_index; |
1900 | u64 wqe_frag; | 1900 | u64 wqe_frag; |
1901 | u32 cqp_head; | 1901 | u32 cqp_head; |
1902 | u32 wqm_cfg0; | ||
1902 | unsigned long flags; | 1903 | unsigned long flags; |
1903 | int ret; | 1904 | int ret; |
1904 | 1905 | ||
1906 | /* clear wqe stall before destroying NIC QP */ | ||
1907 | wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0); | ||
1908 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF); | ||
1909 | |||
1905 | /* Free remaining NIC receive buffers */ | 1910 | /* Free remaining NIC receive buffers */ |
1906 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1911 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
1907 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1912 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
@@ -2020,6 +2025,9 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
2020 | 2025 | ||
2021 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, | 2026 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, |
2022 | nesvnic->nic_pbase); | 2027 | nesvnic->nic_pbase); |
2028 | |||
2029 | /* restore old wqm_cfg0 value */ | ||
2030 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0); | ||
2023 | } | 2031 | } |
2024 | 2032 | ||
2025 | /** | 2033 | /** |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 9b1e7f869d83..bbbfe9fc5a5a 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -160,6 +160,7 @@ enum indexed_regs { | |||
160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, | 160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, |
161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, | 161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, |
162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, | 162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, |
163 | NES_IDX_WQM_CONFIG0 = 0x5000, | ||
163 | NES_IDX_WQM_CONFIG1 = 0x5004, | 164 | NES_IDX_WQM_CONFIG1 = 0x5004, |
164 | NES_IDX_CM_CONFIG = 0x5100, | 165 | NES_IDX_CM_CONFIG = 0x5100, |
165 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, | 166 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index a1d79b6856ac..91fdde382e82 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1595,7 +1595,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1595 | struct nes_vnic *nesvnic; | 1595 | struct nes_vnic *nesvnic; |
1596 | struct net_device *netdev; | 1596 | struct net_device *netdev; |
1597 | struct nic_qp_map *curr_qp_map; | 1597 | struct nic_qp_map *curr_qp_map; |
1598 | u32 u32temp; | ||
1599 | u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; | 1598 | u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; |
1600 | 1599 | ||
1601 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); | 1600 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); |
@@ -1707,6 +1706,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1707 | ((phy_type == NES_PHY_TYPE_PUMA_1G) && | 1706 | ((phy_type == NES_PHY_TYPE_PUMA_1G) && |
1708 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || | 1707 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1709 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | 1708 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { |
1709 | u32 u32temp; | ||
1710 | u32 link_mask; | ||
1711 | u32 link_val; | ||
1712 | |||
1710 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1713 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1711 | (0x200 * (nesdev->mac_index & 1))); | 1714 | (0x200 * (nesdev->mac_index & 1))); |
1712 | if (phy_type != NES_PHY_TYPE_PUMA_1G) { | 1715 | if (phy_type != NES_PHY_TYPE_PUMA_1G) { |
@@ -1715,13 +1718,36 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1715 | (0x200 * (nesdev->mac_index & 1)), u32temp); | 1718 | (0x200 * (nesdev->mac_index & 1)), u32temp); |
1716 | } | 1719 | } |
1717 | 1720 | ||
1721 | /* Check and set linkup here. This is for back to back */ | ||
1722 | /* configuration where second port won't get link interrupt */ | ||
1723 | switch (phy_type) { | ||
1724 | case NES_PHY_TYPE_PUMA_1G: | ||
1725 | if (nesdev->mac_index < 2) { | ||
1726 | link_mask = 0x01010000; | ||
1727 | link_val = 0x01010000; | ||
1728 | } else { | ||
1729 | link_mask = 0x02020000; | ||
1730 | link_val = 0x02020000; | ||
1731 | } | ||
1732 | break; | ||
1733 | default: | ||
1734 | link_mask = 0x0f1f0000; | ||
1735 | link_val = 0x0f0f0000; | ||
1736 | break; | ||
1737 | } | ||
1738 | |||
1739 | u32temp = nes_read_indexed(nesdev, | ||
1740 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
1741 | (0x200 * (nesdev->mac_index & 1))); | ||
1742 | if ((u32temp & link_mask) == link_val) | ||
1743 | nesvnic->linkup = 1; | ||
1744 | |||
1718 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1745 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1719 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1746 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
1720 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); | 1747 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); |
1721 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); | 1748 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); |
1722 | 1749 | ||
1723 | nes_init_phy(nesdev); | 1750 | nes_init_phy(nesdev); |
1724 | |||
1725 | } | 1751 | } |
1726 | 1752 | ||
1727 | return netdev; | 1753 | return netdev; |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 815725f886c4..69928296d74b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -1323,6 +1323,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1323 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); | 1323 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); |
1324 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); | 1324 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); |
1325 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | | 1325 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | |
1326 | NES_QPCONTEXT_ORDIRD_AAH | | ||
1326 | ((((u32)nesadapter->max_irrq_wr) << | 1327 | ((((u32)nesadapter->max_irrq_wr) << |
1327 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); | 1328 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); |
1328 | if (disable_mpa_crc) { | 1329 | if (disable_mpa_crc) { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 83a7751c38d6..bc658373ad55 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -708,6 +708,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
708 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 708 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
709 | struct ipoib_cm_tx_buf *tx_req; | 709 | struct ipoib_cm_tx_buf *tx_req; |
710 | u64 addr; | 710 | u64 addr; |
711 | int rc; | ||
711 | 712 | ||
712 | if (unlikely(skb->len > tx->mtu)) { | 713 | if (unlikely(skb->len > tx->mtu)) { |
713 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", | 714 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", |
@@ -739,9 +740,10 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
739 | 740 | ||
740 | tx_req->mapping = addr; | 741 | tx_req->mapping = addr; |
741 | 742 | ||
742 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 743 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), |
743 | addr, skb->len))) { | 744 | addr, skb->len); |
744 | ipoib_warn(priv, "post_send failed\n"); | 745 | if (unlikely(rc)) { |
746 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | ||
745 | ++dev->stats.tx_errors; | 747 | ++dev->stats.tx_errors; |
746 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 748 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); |
747 | dev_kfree_skb_any(skb); | 749 | dev_kfree_skb_any(skb); |
@@ -752,6 +754,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
752 | if (++priv->tx_outstanding == ipoib_sendq_size) { | 754 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
753 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", | 755 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", |
754 | tx->qp->qp_num); | 756 | tx->qp->qp_num); |
757 | if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) | ||
758 | ipoib_warn(priv, "request notify on send CQ failed\n"); | ||
755 | netif_stop_queue(dev); | 759 | netif_stop_queue(dev); |
756 | } | 760 | } |
757 | } | 761 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8c91d9f37ada..5df40b128f81 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -529,7 +529,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
529 | { | 529 | { |
530 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 530 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
531 | struct ipoib_tx_buf *tx_req; | 531 | struct ipoib_tx_buf *tx_req; |
532 | int hlen; | 532 | int hlen, rc; |
533 | void *phead; | 533 | void *phead; |
534 | 534 | ||
535 | if (skb_is_gso(skb)) { | 535 | if (skb_is_gso(skb)) { |
@@ -585,9 +585,10 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
585 | netif_stop_queue(dev); | 585 | netif_stop_queue(dev); |
586 | } | 586 | } |
587 | 587 | ||
588 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 588 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
589 | address->ah, qpn, tx_req, phead, hlen))) { | 589 | address->ah, qpn, tx_req, phead, hlen); |
590 | ipoib_warn(priv, "post_send failed\n"); | 590 | if (unlikely(rc)) { |
591 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | ||
591 | ++dev->stats.tx_errors; | 592 | ++dev->stats.tx_errors; |
592 | --priv->tx_outstanding; | 593 | --priv->tx_outstanding; |
593 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 594 | ipoib_dma_unmap_tx(priv->ca, tx_req); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 9f9816baeb97..2ee6c7a68bdc 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -515,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
515 | struct input_absinfo abs; | 515 | struct input_absinfo abs; |
516 | struct ff_effect effect; | 516 | struct ff_effect effect; |
517 | int __user *ip = (int __user *)p; | 517 | int __user *ip = (int __user *)p; |
518 | int i, t, u, v; | 518 | unsigned int i, t, u, v; |
519 | int error; | 519 | int error; |
520 | 520 | ||
521 | switch (cmd) { | 521 | switch (cmd) { |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 41168d5f8c17..e2aad0a51826 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -582,7 +582,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | static int input_default_getkeycode(struct input_dev *dev, | 584 | static int input_default_getkeycode(struct input_dev *dev, |
585 | int scancode, int *keycode) | 585 | unsigned int scancode, |
586 | unsigned int *keycode) | ||
586 | { | 587 | { |
587 | if (!dev->keycodesize) | 588 | if (!dev->keycodesize) |
588 | return -EINVAL; | 589 | return -EINVAL; |
@@ -596,7 +597,8 @@ static int input_default_getkeycode(struct input_dev *dev, | |||
596 | } | 597 | } |
597 | 598 | ||
598 | static int input_default_setkeycode(struct input_dev *dev, | 599 | static int input_default_setkeycode(struct input_dev *dev, |
599 | int scancode, int keycode) | 600 | unsigned int scancode, |
601 | unsigned int keycode) | ||
600 | { | 602 | { |
601 | int old_keycode; | 603 | int old_keycode; |
602 | int i; | 604 | int i; |
@@ -654,11 +656,9 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
654 | * This function should be called by anyone interested in retrieving current | 656 | * This function should be called by anyone interested in retrieving current |
655 | * keymap. Presently keyboard and evdev handlers use it. | 657 | * keymap. Presently keyboard and evdev handlers use it. |
656 | */ | 658 | */ |
657 | int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) | 659 | int input_get_keycode(struct input_dev *dev, |
660 | unsigned int scancode, unsigned int *keycode) | ||
658 | { | 661 | { |
659 | if (scancode < 0) | ||
660 | return -EINVAL; | ||
661 | |||
662 | return dev->getkeycode(dev, scancode, keycode); | 662 | return dev->getkeycode(dev, scancode, keycode); |
663 | } | 663 | } |
664 | EXPORT_SYMBOL(input_get_keycode); | 664 | EXPORT_SYMBOL(input_get_keycode); |
@@ -672,16 +672,14 @@ EXPORT_SYMBOL(input_get_keycode); | |||
672 | * This function should be called by anyone needing to update current | 672 | * This function should be called by anyone needing to update current |
673 | * keymap. Presently keyboard and evdev handlers use it. | 673 | * keymap. Presently keyboard and evdev handlers use it. |
674 | */ | 674 | */ |
675 | int input_set_keycode(struct input_dev *dev, int scancode, int keycode) | 675 | int input_set_keycode(struct input_dev *dev, |
676 | unsigned int scancode, unsigned int keycode) | ||
676 | { | 677 | { |
677 | unsigned long flags; | 678 | unsigned long flags; |
678 | int old_keycode; | 679 | int old_keycode; |
679 | int retval; | 680 | int retval; |
680 | 681 | ||
681 | if (scancode < 0) | 682 | if (keycode > KEY_MAX) |
682 | return -EINVAL; | ||
683 | |||
684 | if (keycode < 0 || keycode > KEY_MAX) | ||
685 | return -EINVAL; | 683 | return -EINVAL; |
686 | 684 | ||
687 | spin_lock_irqsave(&dev->event_lock, flags); | 685 | spin_lock_irqsave(&dev->event_lock, flags); |
@@ -1881,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file) | |||
1881 | const struct file_operations *old_fops, *new_fops = NULL; | 1879 | const struct file_operations *old_fops, *new_fops = NULL; |
1882 | int err; | 1880 | int err; |
1883 | 1881 | ||
1884 | lock_kernel(); | 1882 | err = mutex_lock_interruptible(&input_mutex); |
1883 | if (err) | ||
1884 | return err; | ||
1885 | |||
1885 | /* No load-on-demand here? */ | 1886 | /* No load-on-demand here? */ |
1886 | handler = input_table[iminor(inode) >> 5]; | 1887 | handler = input_table[iminor(inode) >> 5]; |
1887 | if (!handler || !(new_fops = fops_get(handler->fops))) { | 1888 | if (handler) |
1888 | err = -ENODEV; | 1889 | new_fops = fops_get(handler->fops); |
1889 | goto out; | 1890 | |
1890 | } | 1891 | mutex_unlock(&input_mutex); |
1891 | 1892 | ||
1892 | /* | 1893 | /* |
1893 | * That's _really_ odd. Usually NULL ->open means "nothing special", | 1894 | * That's _really_ odd. Usually NULL ->open means "nothing special", |
1894 | * not "no device". Oh, well... | 1895 | * not "no device". Oh, well... |
1895 | */ | 1896 | */ |
1896 | if (!new_fops->open) { | 1897 | if (!new_fops || !new_fops->open) { |
1897 | fops_put(new_fops); | 1898 | fops_put(new_fops); |
1898 | err = -ENODEV; | 1899 | err = -ENODEV; |
1899 | goto out; | 1900 | goto out; |
1900 | } | 1901 | } |
1902 | |||
1901 | old_fops = file->f_op; | 1903 | old_fops = file->f_op; |
1902 | file->f_op = new_fops; | 1904 | file->f_op = new_fops; |
1903 | 1905 | ||
1904 | err = new_fops->open(inode, file); | 1906 | err = new_fops->open(inode, file); |
1905 | |||
1906 | if (err) { | 1907 | if (err) { |
1907 | fops_put(file->f_op); | 1908 | fops_put(file->f_op); |
1908 | file->f_op = fops_get(old_fops); | 1909 | file->f_op = fops_get(old_fops); |
1909 | } | 1910 | } |
1910 | fops_put(old_fops); | 1911 | fops_put(old_fops); |
1911 | out: | 1912 | out: |
1912 | unlock_kernel(); | ||
1913 | return err; | 1913 | return err; |
1914 | } | 1914 | } |
1915 | 1915 | ||
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ae998d99a5ae..7a55714a1486 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -819,7 +819,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
819 | int i; | 819 | int i; |
820 | int err; | 820 | int err; |
821 | 821 | ||
822 | if (pad_type < 1 || pad_type > GC_MAX) { | 822 | if (pad_type < 1 || pad_type >= GC_MAX) { |
823 | pr_err("Pad type %d unknown\n", pad_type); | 823 | pr_err("Pad type %d unknown\n", pad_type); |
824 | return -EINVAL; | 824 | return -EINVAL; |
825 | } | 825 | } |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a27fe57..593c052416b9 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -162,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) | |||
162 | input_sync(input); | 162 | input_sync(input); |
163 | 163 | ||
164 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { | 164 | if (bfin_kpad_get_keypressed(bf54x_kpad)) { |
165 | disable_irq(bf54x_kpad->irq); | 165 | disable_irq_nosync(bf54x_kpad->irq); |
166 | bf54x_kpad->lastkey = key; | 166 | bf54x_kpad->lastkey = key; |
167 | mod_timer(&bf54x_kpad->timer, | 167 | mod_timer(&bf54x_kpad->timer, |
168 | jiffies + bf54x_kpad->keyup_test_jiffies); | 168 | jiffies + bf54x_kpad->keyup_test_jiffies); |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 9caed30f3bbb..b1ab29861e1c 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -192,11 +192,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | 192 | static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) |
193 | { | 193 | { |
194 | struct locomokbd *locomokbd = dev_id; | 194 | struct locomokbd *locomokbd = dev_id; |
195 | u16 r; | ||
196 | |||
197 | r = locomo_readl(locomokbd->base + LOCOMO_KIC); | ||
198 | if ((r & 0x0001) == 0) | ||
199 | return IRQ_HANDLED; | ||
200 | |||
201 | locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */ | ||
202 | |||
195 | /** wait chattering delay **/ | 203 | /** wait chattering delay **/ |
196 | udelay(100); | 204 | udelay(100); |
197 | 205 | ||
198 | locomokbd_scankeyboard(locomokbd); | 206 | locomokbd_scankeyboard(locomokbd); |
199 | |||
200 | return IRQ_HANDLED; | 207 | return IRQ_HANDLED; |
201 | } | 208 | } |
202 | 209 | ||
@@ -210,6 +217,25 @@ static void locomokbd_timer_callback(unsigned long data) | |||
210 | locomokbd_scankeyboard(locomokbd); | 217 | locomokbd_scankeyboard(locomokbd); |
211 | } | 218 | } |
212 | 219 | ||
220 | static int locomokbd_open(struct input_dev *dev) | ||
221 | { | ||
222 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
223 | u16 r; | ||
224 | |||
225 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010; | ||
226 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static void locomokbd_close(struct input_dev *dev) | ||
231 | { | ||
232 | struct locomokbd *locomokbd = input_get_drvdata(dev); | ||
233 | u16 r; | ||
234 | |||
235 | r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010; | ||
236 | locomo_writel(r, locomokbd->base + LOCOMO_KIC); | ||
237 | } | ||
238 | |||
213 | static int __devinit locomokbd_probe(struct locomo_dev *dev) | 239 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
214 | { | 240 | { |
215 | struct locomokbd *locomokbd; | 241 | struct locomokbd *locomokbd; |
@@ -253,6 +279,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
253 | input_dev->id.vendor = 0x0001; | 279 | input_dev->id.vendor = 0x0001; |
254 | input_dev->id.product = 0x0001; | 280 | input_dev->id.product = 0x0001; |
255 | input_dev->id.version = 0x0100; | 281 | input_dev->id.version = 0x0100; |
282 | input_dev->open = locomokbd_open; | ||
283 | input_dev->close = locomokbd_close; | ||
256 | input_dev->dev.parent = &dev->dev; | 284 | input_dev->dev.parent = &dev->dev; |
257 | 285 | ||
258 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 286 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | |
@@ -261,6 +289,8 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev) | |||
261 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); | 289 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); |
262 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); | 290 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); |
263 | 291 | ||
292 | input_set_drvdata(input_dev, locomokbd); | ||
293 | |||
264 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); | 294 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); |
265 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) | 295 | for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) |
266 | set_bit(locomokbd->keycode[i], input_dev->keybit); | 296 | set_bit(locomokbd->keycode[i], input_dev->keybit); |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7097bfe581d7..23140a3bb8e0 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -214,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON | |||
214 | To compile this driver as a module, choose M here. The module will | 214 | To compile this driver as a module, choose M here. The module will |
215 | be called twl4030_pwrbutton. | 215 | be called twl4030_pwrbutton. |
216 | 216 | ||
217 | config INPUT_TWL4030_VIBRA | ||
218 | tristate "Support for TWL4030 Vibrator" | ||
219 | depends on TWL4030_CORE | ||
220 | select TWL4030_CODEC | ||
221 | select INPUT_FF_MEMLESS | ||
222 | help | ||
223 | This option enables support for TWL4030 Vibrator Driver. | ||
224 | |||
225 | To compile this driver as a module, choose M here. The module will | ||
226 | be called twl4030_vibra. | ||
227 | |||
217 | config INPUT_UINPUT | 228 | config INPUT_UINPUT |
218 | tristate "User level driver support" | 229 | tristate "User level driver support" |
219 | help | 230 | help |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index b611615e24ad..7e95a5d474dc 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | |||
26 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 26 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o |
27 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 27 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
28 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 28 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
29 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | ||
29 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 30 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
30 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o | 31 | obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o |
31 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 32 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 0501f0e65157..15be5430bc6d 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -474,10 +474,11 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
474 | } | 474 | } |
475 | 475 | ||
476 | static int ati_remote2_getkeycode(struct input_dev *idev, | 476 | static int ati_remote2_getkeycode(struct input_dev *idev, |
477 | int scancode, int *keycode) | 477 | unsigned int scancode, unsigned int *keycode) |
478 | { | 478 | { |
479 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 479 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
480 | int index, mode; | 480 | unsigned int mode; |
481 | int index; | ||
481 | 482 | ||
482 | mode = scancode >> 8; | 483 | mode = scancode >> 8; |
483 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 484 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
@@ -491,10 +492,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev, | |||
491 | return 0; | 492 | return 0; |
492 | } | 493 | } |
493 | 494 | ||
494 | static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) | 495 | static int ati_remote2_setkeycode(struct input_dev *idev, |
496 | unsigned int scancode, unsigned int keycode) | ||
495 | { | 497 | { |
496 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 498 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
497 | int index, mode, old_keycode; | 499 | unsigned int mode, old_keycode; |
500 | int index; | ||
498 | 501 | ||
499 | mode = scancode >> 8; | 502 | mode = scancode >> 8; |
500 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 503 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
@@ -504,9 +507,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc | |||
504 | if (index < 0) | 507 | if (index < 0) |
505 | return -EINVAL; | 508 | return -EINVAL; |
506 | 509 | ||
507 | if (keycode < KEY_RESERVED || keycode > KEY_MAX) | ||
508 | return -EINVAL; | ||
509 | |||
510 | old_keycode = ar2->keycode[mode][index]; | 510 | old_keycode = ar2->keycode[mode][index]; |
511 | ar2->keycode[mode][index] = keycode; | 511 | ar2->keycode[mode][index] = keycode; |
512 | __set_bit(keycode, idev->keybit); | 512 | __set_bit(keycode, idev->keybit); |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c new file mode 100644 index 000000000000..2fb79e064da3 --- /dev/null +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * twl4030-vibra.c - TWL4030 Vibrator driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Nokia Corporation | ||
5 | * | ||
6 | * Written by Henrik Saari <henrik.saari@nokia.com> | ||
7 | * Updates by Felipe Balbi <felipe.balbi@nokia.com> | ||
8 | * Input by Jari Vanhala <ext-jari.vanhala@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
22 | * 02110-1301 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/jiffies.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/workqueue.h> | ||
30 | #include <linux/i2c/twl.h> | ||
31 | #include <linux/mfd/twl4030-codec.h> | ||
32 | #include <linux/input.h> | ||
33 | |||
34 | /* MODULE ID2 */ | ||
35 | #define LEDEN 0x00 | ||
36 | |||
37 | /* ForceFeedback */ | ||
38 | #define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */ | ||
39 | |||
40 | struct vibra_info { | ||
41 | struct device *dev; | ||
42 | struct input_dev *input_dev; | ||
43 | |||
44 | struct workqueue_struct *workqueue; | ||
45 | struct work_struct play_work; | ||
46 | |||
47 | bool enabled; | ||
48 | int speed; | ||
49 | int direction; | ||
50 | |||
51 | bool coexist; | ||
52 | }; | ||
53 | |||
54 | static void vibra_disable_leds(void) | ||
55 | { | ||
56 | u8 reg; | ||
57 | |||
58 | /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */ | ||
59 | twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN); | ||
60 | reg &= ~0x03; | ||
61 | twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg); | ||
62 | } | ||
63 | |||
64 | /* Powers H-Bridge and enables audio clk */ | ||
65 | static void vibra_enable(struct vibra_info *info) | ||
66 | { | ||
67 | u8 reg; | ||
68 | |||
69 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); | ||
70 | |||
71 | /* turn H-Bridge on */ | ||
72 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
73 | ®, TWL4030_REG_VIBRA_CTL); | ||
74 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
75 | (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
76 | |||
77 | twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); | ||
78 | |||
79 | info->enabled = true; | ||
80 | } | ||
81 | |||
82 | static void vibra_disable(struct vibra_info *info) | ||
83 | { | ||
84 | u8 reg; | ||
85 | |||
86 | /* Power down H-Bridge */ | ||
87 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
88 | ®, TWL4030_REG_VIBRA_CTL); | ||
89 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
90 | (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); | ||
91 | |||
92 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); | ||
93 | twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); | ||
94 | |||
95 | info->enabled = false; | ||
96 | } | ||
97 | |||
98 | static void vibra_play_work(struct work_struct *work) | ||
99 | { | ||
100 | struct vibra_info *info = container_of(work, | ||
101 | struct vibra_info, play_work); | ||
102 | int dir; | ||
103 | int pwm; | ||
104 | u8 reg; | ||
105 | |||
106 | dir = info->direction; | ||
107 | pwm = info->speed; | ||
108 | |||
109 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
110 | ®, TWL4030_REG_VIBRA_CTL); | ||
111 | if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) { | ||
112 | |||
113 | if (!info->enabled) | ||
114 | vibra_enable(info); | ||
115 | |||
116 | /* set vibra rotation direction */ | ||
117 | twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
118 | ®, TWL4030_REG_VIBRA_CTL); | ||
119 | reg = (dir) ? (reg | TWL4030_VIBRA_DIR) : | ||
120 | (reg & ~TWL4030_VIBRA_DIR); | ||
121 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
122 | reg, TWL4030_REG_VIBRA_CTL); | ||
123 | |||
124 | /* set PWM, 1 = max, 255 = min */ | ||
125 | twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
126 | 256 - pwm, TWL4030_REG_VIBRA_SET); | ||
127 | } else { | ||
128 | if (info->enabled) | ||
129 | vibra_disable(info); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | /*** Input/ForceFeedback ***/ | ||
134 | |||
135 | static int vibra_play(struct input_dev *input, void *data, | ||
136 | struct ff_effect *effect) | ||
137 | { | ||
138 | struct vibra_info *info = input_get_drvdata(input); | ||
139 | |||
140 | info->speed = effect->u.rumble.strong_magnitude >> 8; | ||
141 | if (!info->speed) | ||
142 | info->speed = effect->u.rumble.weak_magnitude >> 9; | ||
143 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; | ||
144 | queue_work(info->workqueue, &info->play_work); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int twl4030_vibra_open(struct input_dev *input) | ||
149 | { | ||
150 | struct vibra_info *info = input_get_drvdata(input); | ||
151 | |||
152 | info->workqueue = create_singlethread_workqueue("vibra"); | ||
153 | if (info->workqueue == NULL) { | ||
154 | dev_err(&input->dev, "couldn't create workqueue\n"); | ||
155 | return -ENOMEM; | ||
156 | } | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static void twl4030_vibra_close(struct input_dev *input) | ||
161 | { | ||
162 | struct vibra_info *info = input_get_drvdata(input); | ||
163 | |||
164 | cancel_work_sync(&info->play_work); | ||
165 | INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ | ||
166 | destroy_workqueue(info->workqueue); | ||
167 | info->workqueue = NULL; | ||
168 | |||
169 | if (info->enabled) | ||
170 | vibra_disable(info); | ||
171 | } | ||
172 | |||
173 | /*** Module ***/ | ||
174 | #if CONFIG_PM | ||
175 | static int twl4030_vibra_suspend(struct device *dev) | ||
176 | { | ||
177 | struct platform_device *pdev = to_platform_device(dev); | ||
178 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
179 | |||
180 | if (info->enabled) | ||
181 | vibra_disable(info); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int twl4030_vibra_resume(struct device *dev) | ||
187 | { | ||
188 | vibra_disable_leds(); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | ||
193 | twl4030_vibra_suspend, twl4030_vibra_resume); | ||
194 | #endif | ||
195 | |||
196 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | ||
197 | { | ||
198 | struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; | ||
199 | struct vibra_info *info; | ||
200 | int ret; | ||
201 | |||
202 | if (!pdata) { | ||
203 | dev_dbg(&pdev->dev, "platform_data not available\n"); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
208 | if (!info) | ||
209 | return -ENOMEM; | ||
210 | |||
211 | info->dev = &pdev->dev; | ||
212 | info->coexist = pdata->coexist; | ||
213 | INIT_WORK(&info->play_work, vibra_play_work); | ||
214 | |||
215 | info->input_dev = input_allocate_device(); | ||
216 | if (info->input_dev == NULL) { | ||
217 | dev_err(&pdev->dev, "couldn't allocate input device\n"); | ||
218 | ret = -ENOMEM; | ||
219 | goto err_kzalloc; | ||
220 | } | ||
221 | |||
222 | input_set_drvdata(info->input_dev, info); | ||
223 | |||
224 | info->input_dev->name = "twl4030:vibrator"; | ||
225 | info->input_dev->id.version = 1; | ||
226 | info->input_dev->dev.parent = pdev->dev.parent; | ||
227 | info->input_dev->open = twl4030_vibra_open; | ||
228 | info->input_dev->close = twl4030_vibra_close; | ||
229 | __set_bit(FF_RUMBLE, info->input_dev->ffbit); | ||
230 | |||
231 | ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); | ||
232 | if (ret < 0) { | ||
233 | dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); | ||
234 | goto err_ialloc; | ||
235 | } | ||
236 | |||
237 | ret = input_register_device(info->input_dev); | ||
238 | if (ret < 0) { | ||
239 | dev_dbg(&pdev->dev, "couldn't register input device\n"); | ||
240 | goto err_iff; | ||
241 | } | ||
242 | |||
243 | vibra_disable_leds(); | ||
244 | |||
245 | platform_set_drvdata(pdev, info); | ||
246 | return 0; | ||
247 | |||
248 | err_iff: | ||
249 | input_ff_destroy(info->input_dev); | ||
250 | err_ialloc: | ||
251 | input_free_device(info->input_dev); | ||
252 | err_kzalloc: | ||
253 | kfree(info); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static int __devexit twl4030_vibra_remove(struct platform_device *pdev) | ||
258 | { | ||
259 | struct vibra_info *info = platform_get_drvdata(pdev); | ||
260 | |||
261 | /* this also free ff-memless and calls close if needed */ | ||
262 | input_unregister_device(info->input_dev); | ||
263 | kfree(info); | ||
264 | platform_set_drvdata(pdev, NULL); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static struct platform_driver twl4030_vibra_driver = { | ||
270 | .probe = twl4030_vibra_probe, | ||
271 | .remove = __devexit_p(twl4030_vibra_remove), | ||
272 | .driver = { | ||
273 | .name = "twl4030_codec_vibra", | ||
274 | .owner = THIS_MODULE, | ||
275 | #ifdef CONFIG_PM | ||
276 | .pm = &twl4030_vibra_pm_ops, | ||
277 | #endif | ||
278 | }, | ||
279 | }; | ||
280 | |||
281 | static int __init twl4030_vibra_init(void) | ||
282 | { | ||
283 | return platform_driver_register(&twl4030_vibra_driver); | ||
284 | } | ||
285 | module_init(twl4030_vibra_init); | ||
286 | |||
287 | static void __exit twl4030_vibra_exit(void) | ||
288 | { | ||
289 | platform_driver_unregister(&twl4030_vibra_driver); | ||
290 | } | ||
291 | module_exit(twl4030_vibra_exit); | ||
292 | |||
293 | MODULE_ALIAS("platform:twl4030_codec_vibra"); | ||
294 | |||
295 | MODULE_DESCRIPTION("TWL4030 Vibra driver"); | ||
296 | MODULE_LICENSE("GPL"); | ||
297 | MODULE_AUTHOR("Nokia Corporation"); | ||
diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index cbec3dfdd42b..9c155a43abc2 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c | |||
@@ -385,26 +385,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) | |||
385 | } | 385 | } |
386 | 386 | ||
387 | static int | 387 | static int |
388 | wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 388 | wbcir_getkeycode(struct input_dev *dev, |
389 | unsigned int scancode, unsigned int *keycode) | ||
389 | { | 390 | { |
390 | struct wbcir_data *data = input_get_drvdata(dev); | 391 | struct wbcir_data *data = input_get_drvdata(dev); |
391 | 392 | ||
392 | *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); | 393 | *keycode = wbcir_do_getkeycode(data, scancode); |
393 | return 0; | 394 | return 0; |
394 | } | 395 | } |
395 | 396 | ||
396 | static int | 397 | static int |
397 | wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) | 398 | wbcir_setkeycode(struct input_dev *dev, |
399 | unsigned int scancode, unsigned int keycode) | ||
398 | { | 400 | { |
399 | struct wbcir_data *data = input_get_drvdata(dev); | 401 | struct wbcir_data *data = input_get_drvdata(dev); |
400 | struct wbcir_keyentry *keyentry; | 402 | struct wbcir_keyentry *keyentry; |
401 | struct wbcir_keyentry *new_keyentry; | 403 | struct wbcir_keyentry *new_keyentry; |
402 | unsigned long flags; | 404 | unsigned long flags; |
403 | unsigned int old_keycode = KEY_RESERVED; | 405 | unsigned int old_keycode = KEY_RESERVED; |
404 | u32 scancode = (u32)sscancode; | ||
405 | |||
406 | if (keycode < 0 || keycode > KEY_MAX) | ||
407 | return -EINVAL; | ||
408 | 406 | ||
409 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); | 407 | new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); |
410 | if (!new_keyentry) | 408 | if (!new_keyentry) |
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index ba4f5dd7c60e..1e54bce72db5 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c | |||
@@ -97,8 +97,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
97 | wm831x_on->dev->phys = "wm831x_on/input0"; | 97 | wm831x_on->dev->phys = "wm831x_on/input0"; |
98 | wm831x_on->dev->dev.parent = &pdev->dev; | 98 | wm831x_on->dev->dev.parent = &pdev->dev; |
99 | 99 | ||
100 | ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, | 100 | ret = request_threaded_irq(irq, NULL, wm831x_on_irq, |
101 | IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); | 101 | IRQF_TRIGGER_RISING, "wm831x_on", |
102 | wm831x_on); | ||
102 | if (ret < 0) { | 103 | if (ret < 0) { |
103 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); | 104 | dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); |
104 | goto err_input_dev; | 105 | goto err_input_dev; |
@@ -114,7 +115,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
114 | return 0; | 115 | return 0; |
115 | 116 | ||
116 | err_irq: | 117 | err_irq: |
117 | wm831x_free_irq(wm831x, irq, NULL); | 118 | free_irq(irq, wm831x_on); |
118 | err_input_dev: | 119 | err_input_dev: |
119 | input_free_device(wm831x_on->dev); | 120 | input_free_device(wm831x_on->dev); |
120 | err: | 121 | err: |
@@ -127,7 +128,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev) | |||
127 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); | 128 | struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); |
128 | int irq = platform_get_irq(pdev, 0); | 129 | int irq = platform_get_irq(pdev, 0); |
129 | 130 | ||
130 | wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); | 131 | free_irq(irq, wm831x_on); |
131 | cancel_delayed_work_sync(&wm831x_on->work); | 132 | cancel_delayed_work_sync(&wm831x_on->work); |
132 | input_unregister_device(wm831x_on->dev); | 133 | input_unregister_device(wm831x_on->dev); |
133 | kfree(wm831x_on); | 134 | kfree(wm831x_on); |
diff --git a/drivers/input/misc/yealink.h b/drivers/input/misc/yealink.h index 48af0be9cbdf..1e0f52397010 100644 --- a/drivers/input/misc/yealink.h +++ b/drivers/input/misc/yealink.h | |||
@@ -127,7 +127,7 @@ struct yld_ctl_packet { | |||
127 | * yld_status struct. | 127 | * yld_status struct. |
128 | */ | 128 | */ |
129 | 129 | ||
130 | /* LCD, each segment must be driven seperately. | 130 | /* LCD, each segment must be driven separately. |
131 | * | 131 | * |
132 | * Layout: | 132 | * Layout: |
133 | * | 133 | * |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f93c2c0daf1f..7490f1da4a53 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -63,6 +63,8 @@ static const struct alps_model_info alps_model_data[] = { | |||
63 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, | 63 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
64 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 64 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, |
65 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 65 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
66 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, | ||
67 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | ||
66 | }; | 68 | }; |
67 | 69 | ||
68 | /* | 70 | /* |
@@ -118,40 +120,27 @@ static void alps_report_buttons(struct psmouse *psmouse, | |||
118 | struct input_dev *dev1, struct input_dev *dev2, | 120 | struct input_dev *dev1, struct input_dev *dev2, |
119 | int left, int right, int middle) | 121 | int left, int right, int middle) |
120 | { | 122 | { |
121 | struct alps_data *priv = psmouse->private; | 123 | struct input_dev *dev; |
122 | const struct alps_model_info *model = priv->i; | ||
123 | |||
124 | if (model->flags & ALPS_PS2_INTERLEAVED) { | ||
125 | struct input_dev *dev; | ||
126 | 124 | ||
127 | /* | 125 | /* |
128 | * If shared button has already been reported on the | 126 | * If shared button has already been reported on the |
129 | * other device (dev2) then this event should be also | 127 | * other device (dev2) then this event should be also |
130 | * sent through that device. | 128 | * sent through that device. |
131 | */ | 129 | */ |
132 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; | 130 | dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; |
133 | input_report_key(dev, BTN_LEFT, left); | 131 | input_report_key(dev, BTN_LEFT, left); |
134 | 132 | ||
135 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; | 133 | dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; |
136 | input_report_key(dev, BTN_RIGHT, right); | 134 | input_report_key(dev, BTN_RIGHT, right); |
137 | 135 | ||
138 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; | 136 | dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; |
139 | input_report_key(dev, BTN_MIDDLE, middle); | 137 | input_report_key(dev, BTN_MIDDLE, middle); |
140 | 138 | ||
141 | /* | 139 | /* |
142 | * Sync the _other_ device now, we'll do the first | 140 | * Sync the _other_ device now, we'll do the first |
143 | * device later once we report the rest of the events. | 141 | * device later once we report the rest of the events. |
144 | */ | 142 | */ |
145 | input_sync(dev2); | 143 | input_sync(dev2); |
146 | } else { | ||
147 | /* | ||
148 | * For devices with non-interleaved packets we know what | ||
149 | * device buttons belong to so we can simply report them. | ||
150 | */ | ||
151 | input_report_key(dev1, BTN_LEFT, left); | ||
152 | input_report_key(dev1, BTN_RIGHT, right); | ||
153 | input_report_key(dev1, BTN_MIDDLE, middle); | ||
154 | } | ||
155 | } | 144 | } |
156 | 145 | ||
157 | static void alps_process_packet(struct psmouse *psmouse) | 146 | static void alps_process_packet(struct psmouse *psmouse) |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 908b5b44052f..53ec7ddd1826 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -205,8 +205,8 @@ struct atp { | |||
205 | bool overflow_warned; | 205 | bool overflow_warned; |
206 | int x_old; /* last reported x/y, */ | 206 | int x_old; /* last reported x/y, */ |
207 | int y_old; /* used for smoothing */ | 207 | int y_old; /* used for smoothing */ |
208 | signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; | 208 | u8 xy_cur[ATP_XSENSORS + ATP_YSENSORS]; |
209 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; | 209 | u8 xy_old[ATP_XSENSORS + ATP_YSENSORS]; |
210 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 210 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
211 | int idlecount; /* number of empty packets */ | 211 | int idlecount; /* number of empty packets */ |
212 | struct work_struct work; | 212 | struct work_struct work; |
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) | |||
531 | 531 | ||
532 | for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { | 532 | for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { |
533 | /* accumulate the change */ | 533 | /* accumulate the change */ |
534 | signed char change = dev->xy_old[i] - dev->xy_cur[i]; | 534 | int change = dev->xy_old[i] - dev->xy_cur[i]; |
535 | dev->xy_acc[i] -= change; | 535 | dev->xy_acc[i] -= change; |
536 | 536 | ||
537 | /* prevent down drifting */ | 537 | /* prevent down drifting */ |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a13d80f7da17..f34b22bce4ff 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
542 | if (i >= MOUSEDEV_MINORS) | 541 | if (i >= MOUSEDEV_MINORS) |
543 | return -ENODEV; | 542 | return -ENODEV; |
544 | 543 | ||
545 | lock_kernel(); | ||
546 | error = mutex_lock_interruptible(&mousedev_table_mutex); | 544 | error = mutex_lock_interruptible(&mousedev_table_mutex); |
547 | if (error) { | 545 | if (error) { |
548 | unlock_kernel(); | ||
549 | return error; | 546 | return error; |
550 | } | 547 | } |
551 | mousedev = mousedev_table[i]; | 548 | mousedev = mousedev_table[i]; |
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
554 | mutex_unlock(&mousedev_table_mutex); | 551 | mutex_unlock(&mousedev_table_mutex); |
555 | 552 | ||
556 | if (!mousedev) { | 553 | if (!mousedev) { |
557 | unlock_kernel(); | ||
558 | return -ENODEV; | 554 | return -ENODEV; |
559 | } | 555 | } |
560 | 556 | ||
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
575 | goto err_free_client; | 571 | goto err_free_client; |
576 | 572 | ||
577 | file->private_data = client; | 573 | file->private_data = client; |
578 | unlock_kernel(); | ||
579 | return 0; | 574 | return 0; |
580 | 575 | ||
581 | err_free_client: | 576 | err_free_client: |
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file) | |||
583 | kfree(client); | 578 | kfree(client); |
584 | err_put_mousedev: | 579 | err_put_mousedev: |
585 | put_device(&mousedev->dev); | 580 | put_device(&mousedev->dev); |
586 | unlock_kernel(); | ||
587 | return error; | 581 | return error; |
588 | } | 582 | } |
589 | 583 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2a5982e532f8..ead0494721d0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -442,6 +442,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { | |||
442 | }, | 442 | }, |
443 | }, | 443 | }, |
444 | { | 444 | { |
445 | /* Medion Akoya E1222 */ | ||
446 | .matches = { | ||
447 | DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), | ||
448 | DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), | ||
449 | }, | ||
450 | }, | ||
451 | { | ||
445 | /* Mivvy M310 */ | 452 | /* Mivvy M310 */ |
446 | .matches = { | 453 | .matches = { |
447 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), | 454 | DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), |
@@ -624,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
624 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); | 631 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); |
625 | } | 632 | } |
626 | 633 | ||
634 | /* Keyboard ports are always supposed to be wakeup-enabled */ | ||
635 | device_set_wakeup_enable(&dev->dev, true); | ||
636 | |||
627 | i8042_pnp_kbd_devices++; | 637 | i8042_pnp_kbd_devices++; |
628 | return 0; | 638 | return 0; |
629 | } | 639 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index b54aee7cd9e3..9302ba0e48f8 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -430,7 +430,7 @@ static bool i8042_filter(unsigned char data, unsigned char str, | |||
430 | } | 430 | } |
431 | 431 | ||
432 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { | 432 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { |
433 | dbg("Filtered out by platfrom filter\n"); | 433 | dbg("Filtered out by platform filter\n"); |
434 | return true; | 434 | return true; |
435 | } | 435 | } |
436 | 436 | ||
@@ -1386,6 +1386,8 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1386 | { | 1386 | { |
1387 | int error; | 1387 | int error; |
1388 | 1388 | ||
1389 | i8042_platform_device = dev; | ||
1390 | |||
1389 | error = i8042_controller_selftest(); | 1391 | error = i8042_controller_selftest(); |
1390 | if (error) | 1392 | if (error) |
1391 | return error; | 1393 | return error; |
@@ -1421,6 +1423,7 @@ static int __init i8042_probe(struct platform_device *dev) | |||
1421 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ | 1423 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
1422 | i8042_free_irqs(); | 1424 | i8042_free_irqs(); |
1423 | i8042_controller_reset(); | 1425 | i8042_controller_reset(); |
1426 | i8042_platform_device = NULL; | ||
1424 | 1427 | ||
1425 | return error; | 1428 | return error; |
1426 | } | 1429 | } |
@@ -1430,6 +1433,7 @@ static int __devexit i8042_remove(struct platform_device *dev) | |||
1430 | i8042_unregister_ports(); | 1433 | i8042_unregister_ports(); |
1431 | i8042_free_irqs(); | 1434 | i8042_free_irqs(); |
1432 | i8042_controller_reset(); | 1435 | i8042_controller_reset(); |
1436 | i8042_platform_device = NULL; | ||
1433 | 1437 | ||
1434 | return 0; | 1438 | return 0; |
1435 | } | 1439 | } |
@@ -1448,6 +1452,7 @@ static struct platform_driver i8042_driver = { | |||
1448 | 1452 | ||
1449 | static int __init i8042_init(void) | 1453 | static int __init i8042_init(void) |
1450 | { | 1454 | { |
1455 | struct platform_device *pdev; | ||
1451 | int err; | 1456 | int err; |
1452 | 1457 | ||
1453 | dbg_init(); | 1458 | dbg_init(); |
@@ -1460,31 +1465,18 @@ static int __init i8042_init(void) | |||
1460 | if (err) | 1465 | if (err) |
1461 | goto err_platform_exit; | 1466 | goto err_platform_exit; |
1462 | 1467 | ||
1463 | i8042_platform_device = platform_device_alloc("i8042", -1); | 1468 | pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); |
1464 | if (!i8042_platform_device) { | 1469 | if (IS_ERR(pdev)) { |
1465 | err = -ENOMEM; | 1470 | err = PTR_ERR(pdev); |
1466 | goto err_platform_exit; | 1471 | goto err_platform_exit; |
1467 | } | 1472 | } |
1468 | 1473 | ||
1469 | err = platform_device_add(i8042_platform_device); | ||
1470 | if (err) | ||
1471 | goto err_free_device; | ||
1472 | |||
1473 | err = platform_driver_probe(&i8042_driver, i8042_probe); | ||
1474 | if (err) | ||
1475 | goto err_del_device; | ||
1476 | |||
1477 | panic_blink = i8042_panic_blink; | 1474 | panic_blink = i8042_panic_blink; |
1478 | 1475 | ||
1479 | return 0; | 1476 | return 0; |
1480 | 1477 | ||
1481 | err_del_device: | ||
1482 | platform_device_del(i8042_platform_device); | ||
1483 | err_free_device: | ||
1484 | platform_device_put(i8042_platform_device); | ||
1485 | err_platform_exit: | 1478 | err_platform_exit: |
1486 | i8042_platform_exit(); | 1479 | i8042_platform_exit(); |
1487 | |||
1488 | return err; | 1480 | return err; |
1489 | } | 1481 | } |
1490 | 1482 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 27fdaaffbb40..998664854440 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
81 | struct serio_raw_list *list; | 81 | struct serio_raw_list *list; |
82 | int retval = 0; | 82 | int retval = 0; |
83 | 83 | ||
84 | lock_kernel(); | ||
85 | retval = mutex_lock_interruptible(&serio_raw_mutex); | 84 | retval = mutex_lock_interruptible(&serio_raw_mutex); |
86 | if (retval) | 85 | if (retval) |
87 | goto out_bkl; | 86 | return retval; |
88 | 87 | ||
89 | if (!(serio_raw = serio_raw_locate(iminor(inode)))) { | 88 | serio_raw = serio_raw_locate(iminor(inode)); |
89 | if (!serio_raw) { | ||
90 | retval = -ENODEV; | 90 | retval = -ENODEV; |
91 | goto out; | 91 | goto out; |
92 | } | 92 | } |
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
96 | goto out; | 96 | goto out; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { | 99 | list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL); |
100 | if (!list) { | ||
100 | retval = -ENOMEM; | 101 | retval = -ENOMEM; |
101 | goto out; | 102 | goto out; |
102 | } | 103 | } |
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file) | |||
109 | 110 | ||
110 | out: | 111 | out: |
111 | mutex_unlock(&serio_raw_mutex); | 112 | mutex_unlock(&serio_raw_mutex); |
112 | out_bkl: | ||
113 | unlock_kernel(); | ||
114 | return retval; | 113 | return retval; |
115 | } | 114 | } |
116 | 115 | ||
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index fbd3987af57f..e6bde55e5203 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
@@ -64,7 +64,8 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, | |||
64 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); | 64 | EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); |
65 | 65 | ||
66 | static int sparse_keymap_getkeycode(struct input_dev *dev, | 66 | static int sparse_keymap_getkeycode(struct input_dev *dev, |
67 | int scancode, int *keycode) | 67 | unsigned int scancode, |
68 | unsigned int *keycode) | ||
68 | { | 69 | { |
69 | const struct key_entry *key = | 70 | const struct key_entry *key = |
70 | sparse_keymap_entry_from_scancode(dev, scancode); | 71 | sparse_keymap_entry_from_scancode(dev, scancode); |
@@ -78,7 +79,8 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, | |||
78 | } | 79 | } |
79 | 80 | ||
80 | static int sparse_keymap_setkeycode(struct input_dev *dev, | 81 | static int sparse_keymap_setkeycode(struct input_dev *dev, |
81 | int scancode, int keycode) | 82 | unsigned int scancode, |
83 | unsigned int keycode) | ||
82 | { | 84 | { |
83 | struct key_entry *key; | 85 | struct key_entry *key; |
84 | int old_keycode; | 86 | int old_keycode; |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 7d005a3616d7..4be039d7dcad 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -362,7 +362,7 @@ static const int macroKeyEvents[] = { | |||
362 | }; | 362 | }; |
363 | 363 | ||
364 | /*********************************************************************** | 364 | /*********************************************************************** |
365 | * Map values to strings and back. Every map shoudl have the following | 365 | * Map values to strings and back. Every map should have the following |
366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. | 366 | * as its last element: { NULL, AIPTEK_INVALID_VALUE }. |
367 | */ | 367 | */ |
368 | #define AIPTEK_INVALID_VALUE -1 | 368 | #define AIPTEK_INVALID_VALUE -1 |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a1770e6feeec..8b5d2873f0c4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
371 | } else if (pen) { | 371 | } else if (pen) { |
372 | /* penabled only accepts exact bytes of data */ | 372 | /* penabled only accepts exact bytes of data */ |
373 | if (features->type == TABLETPC2FG) | 373 | if (features->type == TABLETPC2FG) |
374 | features->pktlen = WACOM_PKGLEN_PENABLED; | 374 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
375 | features->device_type = BTN_TOOL_PEN; | 375 | features->device_type = BTN_TOOL_PEN; |
376 | features->x_max = | 376 | features->x_max = |
377 | wacom_le16_to_cpu(&report[i + 3]); | 377 | wacom_le16_to_cpu(&report[i + 3]); |
@@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
410 | } else if (pen) { | 410 | } else if (pen) { |
411 | /* penabled only accepts exact bytes of data */ | 411 | /* penabled only accepts exact bytes of data */ |
412 | if (features->type == TABLETPC2FG) | 412 | if (features->type == TABLETPC2FG) |
413 | features->pktlen = WACOM_PKGLEN_PENABLED; | 413 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
414 | features->device_type = BTN_TOOL_PEN; | 414 | features->device_type = BTN_TOOL_PEN; |
415 | features->y_max = | 415 | features->y_max = |
416 | wacom_le16_to_cpu(&report[i + 3]); | 416 | wacom_le16_to_cpu(&report[i + 3]); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 3d81443e683a..b3ba3437a2eb 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
155 | { | 155 | { |
156 | struct wacom_features *features = &wacom->features; | 156 | struct wacom_features *features = &wacom->features; |
157 | unsigned char *data = wacom->data; | 157 | unsigned char *data = wacom->data; |
158 | int x, y, rw; | 158 | int x, y, prox; |
159 | static int penData = 0; | 159 | int rw = 0; |
160 | int retval = 0; | ||
160 | 161 | ||
161 | if (data[0] != WACOM_REPORT_PENABLED) { | 162 | if (data[0] != WACOM_REPORT_PENABLED) { |
162 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 163 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
163 | return 0; | 164 | goto exit; |
164 | } | 165 | } |
165 | 166 | ||
166 | if (data[1] & 0x80) { | 167 | prox = data[1] & 0x80; |
167 | /* in prox and not a pad data */ | 168 | if (prox || wacom->id[0]) { |
168 | penData = 1; | 169 | if (prox) { |
169 | 170 | switch ((data[1] >> 5) & 3) { | |
170 | switch ((data[1] >> 5) & 3) { | ||
171 | 171 | ||
172 | case 0: /* Pen */ | 172 | case 0: /* Pen */ |
173 | wacom->tool[0] = BTN_TOOL_PEN; | 173 | wacom->tool[0] = BTN_TOOL_PEN; |
@@ -181,23 +181,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
181 | 181 | ||
182 | case 2: /* Mouse with wheel */ | 182 | case 2: /* Mouse with wheel */ |
183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); | 183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); |
184 | if (features->type == WACOM_G4 || features->type == WACOM_MO) { | ||
185 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); | ||
186 | wacom_report_rel(wcombo, REL_WHEEL, -rw); | ||
187 | } else | ||
188 | wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); | ||
189 | /* fall through */ | 184 | /* fall through */ |
190 | 185 | ||
191 | case 3: /* Mouse without wheel */ | 186 | case 3: /* Mouse without wheel */ |
192 | wacom->tool[0] = BTN_TOOL_MOUSE; | 187 | wacom->tool[0] = BTN_TOOL_MOUSE; |
193 | wacom->id[0] = CURSOR_DEVICE_ID; | 188 | wacom->id[0] = CURSOR_DEVICE_ID; |
194 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
195 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
196 | if (features->type == WACOM_G4 || features->type == WACOM_MO) | ||
197 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
198 | else | ||
199 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
200 | break; | 189 | break; |
190 | } | ||
201 | } | 191 | } |
202 | x = wacom_le16_to_cpu(&data[2]); | 192 | x = wacom_le16_to_cpu(&data[2]); |
203 | y = wacom_le16_to_cpu(&data[4]); | 193 | y = wacom_le16_to_cpu(&data[4]); |
@@ -208,36 +198,32 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
208 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 198 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); |
209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 199 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 200 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
211 | } | ||
212 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | ||
213 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
214 | } else if (wacom->id[0]) { | ||
215 | wacom_report_abs(wcombo, ABS_X, 0); | ||
216 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
217 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { | ||
218 | wacom_report_key(wcombo, BTN_LEFT, 0); | ||
219 | wacom_report_key(wcombo, BTN_RIGHT, 0); | ||
220 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | ||
221 | } else { | 201 | } else { |
222 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 202 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); |
223 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 203 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); |
224 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 204 | if (features->type == WACOM_G4 || |
225 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 205 | features->type == WACOM_MO) { |
206 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
207 | rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); | ||
208 | } else { | ||
209 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
210 | rw = -(signed)data[6]; | ||
211 | } | ||
212 | wacom_report_rel(wcombo, REL_WHEEL, rw); | ||
226 | } | 213 | } |
227 | wacom->id[0] = 0; | 214 | |
228 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 215 | if (!prox) |
229 | wacom_report_key(wcombo, wacom->tool[0], 0); | 216 | wacom->id[0] = 0; |
217 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | ||
218 | wacom_report_key(wcombo, wacom->tool[0], prox); | ||
219 | wacom_input_sync(wcombo); /* sync last event */ | ||
230 | } | 220 | } |
231 | 221 | ||
232 | /* send pad data */ | 222 | /* send pad data */ |
233 | switch (features->type) { | 223 | switch (features->type) { |
234 | case WACOM_G4: | 224 | case WACOM_G4: |
235 | if (data[7] & 0xf8) { | 225 | prox = data[7] & 0xf8; |
236 | if (penData) { | 226 | if (prox || wacom->id[1]) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
241 | wacom->id[1] = PAD_DEVICE_ID; | 227 | wacom->id[1] = PAD_DEVICE_ID; |
242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 228 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 229 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
@@ -245,29 +231,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
245 | wacom_report_rel(wcombo, REL_WHEEL, rw); | 231 | wacom_report_rel(wcombo, REL_WHEEL, rw); |
246 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 232 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 233 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 234 | if (!prox) |
249 | } else if (wacom->id[1]) { | 235 | wacom->id[1] = 0; |
250 | if (penData) { | 236 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
251 | wacom_input_sync(wcombo); /* sync last event */ | ||
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
255 | wacom->id[1] = 0; | ||
256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | ||
257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | ||
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
260 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 237 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
262 | } | 238 | } |
239 | retval = 1; | ||
263 | break; | 240 | break; |
264 | case WACOM_MO: | 241 | case WACOM_MO: |
265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { | 242 | prox = (data[7] & 0xf8) || data[8]; |
266 | if (penData) { | 243 | if (prox || wacom->id[1]) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | ||
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
271 | wacom->id[1] = PAD_DEVICE_ID; | 244 | wacom->id[1] = PAD_DEVICE_ID; |
272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 245 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 246 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -275,27 +248,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
275 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | 248 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); |
276 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | 249 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); |
277 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 250 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
251 | if (!prox) | ||
252 | wacom->id[1] = 0; | ||
278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 253 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 254 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
280 | } else if (wacom->id[1]) { | ||
281 | if (penData) { | ||
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
286 | wacom->id[1] = 0; | ||
287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | ||
288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | ||
289 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | ||
290 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | ||
291 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | ||
292 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
293 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
294 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
295 | } | 255 | } |
256 | retval = 1; | ||
296 | break; | 257 | break; |
297 | } | 258 | } |
298 | return 1; | 259 | exit: |
260 | return retval; | ||
299 | } | 261 | } |
300 | 262 | ||
301 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 263 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) |
@@ -636,9 +598,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
636 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | 598 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) |
637 | { | 599 | { |
638 | wacom_report_abs(wcombo, ABS_X, | 600 | wacom_report_abs(wcombo, ABS_X, |
639 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); | 601 | data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); |
640 | wacom_report_abs(wcombo, ABS_Y, | 602 | wacom_report_abs(wcombo, ABS_Y, |
641 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); | 603 | data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); |
642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 604 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
643 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 605 | wacom_report_key(wcombo, wacom->tool[idx], 1); |
644 | if (idx) | 606 | if (idx) |
@@ -782,31 +744,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
782 | 744 | ||
783 | touchInProx = 0; | 745 | touchInProx = 0; |
784 | 746 | ||
785 | if (prox) { /* in prox */ | 747 | if (!wacom->id[0]) { /* first in prox */ |
786 | if (!wacom->id[0]) { | 748 | /* Going into proximity select tool */ |
787 | /* Going into proximity select tool */ | 749 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
788 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 750 | if (wacom->tool[0] == BTN_TOOL_PEN) |
789 | if (wacom->tool[0] == BTN_TOOL_PEN) | 751 | wacom->id[0] = STYLUS_DEVICE_ID; |
790 | wacom->id[0] = STYLUS_DEVICE_ID; | 752 | else |
791 | else | 753 | wacom->id[0] = ERASER_DEVICE_ID; |
792 | wacom->id[0] = ERASER_DEVICE_ID; | 754 | } |
793 | } | 755 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
794 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 756 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
795 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 757 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); |
796 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 758 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); |
797 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 759 | pressure = ((data[7] & 0x01) << 8) | data[6]; |
798 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 760 | if (pressure < 0) |
799 | if (pressure < 0) | 761 | pressure = features->pressure_max + pressure + 1; |
800 | pressure = features->pressure_max + pressure + 1; | 762 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
801 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 763 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
802 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); | 764 | if (!prox) { /* out-prox */ |
803 | } else { | ||
804 | wacom_report_abs(wcombo, ABS_X, 0); | ||
805 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
806 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
807 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
808 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
809 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
810 | wacom->id[0] = 0; | 765 | wacom->id[0] = 0; |
811 | /* pen is out so touch can be enabled now */ | 766 | /* pen is out so touch can be enabled now */ |
812 | touchInProx = 1; | 767 | touchInProx = 1; |
@@ -1028,7 +983,7 @@ static const struct wacom_features wacom_features_0x93 = | |||
1028 | static const struct wacom_features wacom_features_0x9A = | 983 | static const struct wacom_features wacom_features_0x9A = |
1029 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; | 984 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
1030 | static const struct wacom_features wacom_features_0x9F = | 985 | static const struct wacom_features wacom_features_0x9F = |
1031 | { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }; | 986 | { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; |
1032 | static const struct wacom_features wacom_features_0xE2 = | 987 | static const struct wacom_features wacom_features_0xE2 = |
1033 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; | 988 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; |
1034 | static const struct wacom_features wacom_features_0xE3 = | 989 | static const struct wacom_features wacom_features_0xE3 = |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 8590b1e8ec37..b50cf04e61a8 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #define WACOM_PKGLEN_GRAPHIRE 8 | 17 | #define WACOM_PKGLEN_GRAPHIRE 8 |
18 | #define WACOM_PKGLEN_BBFUN 9 | 18 | #define WACOM_PKGLEN_BBFUN 9 |
19 | #define WACOM_PKGLEN_INTUOS 10 | 19 | #define WACOM_PKGLEN_INTUOS 10 |
20 | #define WACOM_PKGLEN_PENABLED 8 | ||
21 | #define WACOM_PKGLEN_TPC1FG 5 | 20 | #define WACOM_PKGLEN_TPC1FG 5 |
22 | #define WACOM_PKGLEN_TPC2FG 14 | 21 | #define WACOM_PKGLEN_TPC2FG 14 |
23 | 22 | ||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7208654a94ae..8a8fa4d2d6a8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -24,17 +24,18 @@ config TOUCHSCREEN_88PM860X | |||
24 | module will be called 88pm860x-ts. | 24 | module will be called 88pm860x-ts. |
25 | 25 | ||
26 | config TOUCHSCREEN_ADS7846 | 26 | config TOUCHSCREEN_ADS7846 |
27 | tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" | 27 | tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens" |
28 | depends on SPI_MASTER | 28 | depends on SPI_MASTER |
29 | depends on HWMON = n || HWMON | 29 | depends on HWMON = n || HWMON |
30 | help | 30 | help |
31 | Say Y here if you have a touchscreen interface using the | 31 | Say Y here if you have a touchscreen interface using the |
32 | ADS7846/TSC2046 or ADS7843 controller, and your board-specific | 32 | ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller, |
33 | setup code includes that in its table of SPI devices. | 33 | and your board-specific setup code includes that in its |
34 | table of SPI devices. | ||
34 | 35 | ||
35 | If HWMON is selected, and the driver is told the reference voltage | 36 | If HWMON is selected, and the driver is told the reference voltage |
36 | on your board, you will also get hwmon interfaces for the voltage | 37 | on your board, you will also get hwmon interfaces for the voltage |
37 | (and on ads7846/tsc2046, temperature) sensors of this chip. | 38 | (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip. |
38 | 39 | ||
39 | If unsure, say N (but it's safe to say "Y"). | 40 | If unsure, say N (but it's safe to say "Y"). |
40 | 41 | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index eb83939c705e..e019d53d1ab4 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/spi/ad7877.h> | 46 | #include <linux/spi/ad7877.h> |
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | 49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100) |
50 | 50 | ||
51 | #define MAX_SPI_FREQ_HZ 20000000 | 51 | #define MAX_SPI_FREQ_HZ 20000000 |
52 | #define MAX_12BIT ((1<<12)-1) | 52 | #define MAX_12BIT ((1<<12)-1) |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 8b05d8e97543..532279cda0e4 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -36,6 +36,7 @@ | |||
36 | * TSC2046 is just newer ads7846 silicon. | 36 | * TSC2046 is just newer ads7846 silicon. |
37 | * Support for ads7843 tested on Atmel at91sam926x-EK. | 37 | * Support for ads7843 tested on Atmel at91sam926x-EK. |
38 | * Support for ads7845 has only been stubbed in. | 38 | * Support for ads7845 has only been stubbed in. |
39 | * Support for Analog Devices AD7873 and AD7843 tested. | ||
39 | * | 40 | * |
40 | * IRQ handling needs a workaround because of a shortcoming in handling | 41 | * IRQ handling needs a workaround because of a shortcoming in handling |
41 | * edge triggered IRQs on some platforms like the OMAP1/2. These | 42 | * edge triggered IRQs on some platforms like the OMAP1/2. These |
@@ -821,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | |||
821 | 822 | ||
822 | spin_unlock_irq(&ts->lock); | 823 | spin_unlock_irq(&ts->lock); |
823 | 824 | ||
825 | if (device_may_wakeup(&ts->spi->dev)) | ||
826 | enable_irq_wake(ts->spi->irq); | ||
827 | |||
824 | return 0; | 828 | return 0; |
825 | 829 | ||
826 | } | 830 | } |
@@ -829,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi) | |||
829 | { | 833 | { |
830 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 834 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
831 | 835 | ||
836 | if (device_may_wakeup(&ts->spi->dev)) | ||
837 | disable_irq_wake(ts->spi->irq); | ||
838 | |||
832 | spin_lock_irq(&ts->lock); | 839 | spin_lock_irq(&ts->lock); |
833 | 840 | ||
834 | ts->is_suspended = 0; | 841 | ts->is_suspended = 0; |
@@ -984,6 +991,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
984 | 991 | ||
985 | vref = pdata->keep_vref_on; | 992 | vref = pdata->keep_vref_on; |
986 | 993 | ||
994 | if (ts->model == 7873) { | ||
995 | /* The AD7873 is almost identical to the ADS7846 | ||
996 | * keep VREF off during differential/ratiometric | ||
997 | * conversion modes | ||
998 | */ | ||
999 | ts->model = 7846; | ||
1000 | vref = 0; | ||
1001 | } | ||
1002 | |||
987 | /* set up the transfers to read touchscreen state; this assumes we | 1003 | /* set up the transfers to read touchscreen state; this assumes we |
988 | * use formula #2 for pressure, not #3. | 1004 | * use formula #2 for pressure, not #3. |
989 | */ | 1005 | */ |
@@ -1191,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1191 | if (err) | 1207 | if (err) |
1192 | goto err_remove_attr_group; | 1208 | goto err_remove_attr_group; |
1193 | 1209 | ||
1210 | device_init_wakeup(&spi->dev, pdata->wakeup); | ||
1211 | |||
1194 | return 0; | 1212 | return 0; |
1195 | 1213 | ||
1196 | err_remove_attr_group: | 1214 | err_remove_attr_group: |
@@ -1220,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1220 | { | 1238 | { |
1221 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1239 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1222 | 1240 | ||
1241 | device_init_wakeup(&spi->dev, false); | ||
1242 | |||
1223 | ads784x_hwmon_unregister(spi, ts); | 1243 | ads784x_hwmon_unregister(spi, ts); |
1224 | input_unregister_device(ts->input); | 1244 | input_unregister_device(ts->input); |
1225 | 1245 | ||
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index 09095c747110..f0bc6fa95809 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c | |||
@@ -1712,13 +1712,13 @@ mISDNisar_init(struct isar_hw *isar, void *hw) | |||
1712 | } | 1712 | } |
1713 | EXPORT_SYMBOL(mISDNisar_init); | 1713 | EXPORT_SYMBOL(mISDNisar_init); |
1714 | 1714 | ||
1715 | static int isar_mod_init(void) | 1715 | static int __init isar_mod_init(void) |
1716 | { | 1716 | { |
1717 | pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV); | 1717 | pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV); |
1718 | return 0; | 1718 | return 0; |
1719 | } | 1719 | } |
1720 | 1720 | ||
1721 | static void isar_mod_cleanup(void) | 1721 | static void __exit isar_mod_cleanup(void) |
1722 | { | 1722 | { |
1723 | pr_notice("mISDN: ISAR module unloaded\n"); | 1723 | pr_notice("mISDN: ISAR module unloaded\n"); |
1724 | } | 1724 | } |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index adb1e8c36b46..00c60e2e0ff7 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -1347,7 +1347,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) | |||
1347 | /* | 1347 | /* |
1348 | * isdn net devices manage lots of configuration variables as linked lists. | 1348 | * isdn net devices manage lots of configuration variables as linked lists. |
1349 | * Those lists must only be manipulated from user space. Some of the ioctl's | 1349 | * Those lists must only be manipulated from user space. Some of the ioctl's |
1350 | * service routines access user space and are not atomic. Therefor, ioctl's | 1350 | * service routines access user space and are not atomic. Therefore, ioctl's |
1351 | * manipulating the lists and ioctl's sleeping while accessing the lists | 1351 | * manipulating the lists and ioctl's sleeping while accessing the lists |
1352 | * are serialized by means of a semaphore. | 1352 | * are serialized by means of a semaphore. |
1353 | */ | 1353 | */ |
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 43ff4d3b046e..6eac588e0a37 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c | |||
@@ -1114,7 +1114,7 @@ static struct Bprotocol DSP = { | |||
1114 | .create = dspcreate | 1114 | .create = dspcreate |
1115 | }; | 1115 | }; |
1116 | 1116 | ||
1117 | static int dsp_init(void) | 1117 | static int __init dsp_init(void) |
1118 | { | 1118 | { |
1119 | int err; | 1119 | int err; |
1120 | int tics; | 1120 | int tics; |
@@ -1212,7 +1212,7 @@ static int dsp_init(void) | |||
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | 1214 | ||
1215 | static void dsp_cleanup(void) | 1215 | static void __exit dsp_cleanup(void) |
1216 | { | 1216 | { |
1217 | mISDN_unregister_Bprotocol(&DSP); | 1217 | mISDN_unregister_Bprotocol(&DSP); |
1218 | 1218 | ||
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index f1e8af54dff0..325b1ad7d4b8 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -477,7 +477,7 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len) | |||
477 | printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n", | 477 | printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n", |
478 | __func__, len); | 478 | __func__, len); |
479 | 479 | ||
480 | /* check lenght */ | 480 | /* check length */ |
481 | if (len < 1+1+2) { | 481 | if (len < 1+1+2) { |
482 | printk(KERN_WARNING "%s: packet error - length %d below " | 482 | printk(KERN_WARNING "%s: packet error - length %d below " |
483 | "4 bytes\n", __func__, len); | 483 | "4 bytes\n", __func__, len); |
@@ -1509,7 +1509,7 @@ l1oip_init(void) | |||
1509 | printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", | 1509 | printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", |
1510 | __func__, l1oip_cnt, pri ? "PRI" : "BRI", | 1510 | __func__, l1oip_cnt, pri ? "PRI" : "BRI", |
1511 | bundle ? "bundled IP packet for all B-channels" : | 1511 | bundle ? "bundled IP packet for all B-channels" : |
1512 | "seperate IP packets for every B-channel"); | 1512 | "separate IP packets for every B-channel"); |
1513 | 1513 | ||
1514 | hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); | 1514 | hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); |
1515 | if (!hc) { | 1515 | if (!hc) { |
diff --git a/drivers/isdn/sc/hardware.h b/drivers/isdn/sc/hardware.h index 9e6d5302bf8e..627324856ead 100644 --- a/drivers/isdn/sc/hardware.h +++ b/drivers/isdn/sc/hardware.h | |||
@@ -87,7 +87,7 @@ | |||
87 | #define BRI_CHANNELS 2 /* Number of B channels */ | 87 | #define BRI_CHANNELS 2 /* Number of B channels */ |
88 | #define BRI_BASEPG_VAL 0x98 | 88 | #define BRI_BASEPG_VAL 0x98 |
89 | #define BRI_MAGIC 0x60000 /* Magic Number */ | 89 | #define BRI_MAGIC 0x60000 /* Magic Number */ |
90 | #define BRI_MEMSIZE 0x10000 /* Ammount of RAM (64K) */ | 90 | #define BRI_MEMSIZE 0x10000 /* Amount of RAM (64K) */ |
91 | #define BRI_PARTNO "72-029" | 91 | #define BRI_PARTNO "72-029" |
92 | #define BRI_FEATURES ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS; | 92 | #define BRI_FEATURES ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS; |
93 | /* | 93 | /* |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 5738d8bf2d97..921373e4e3af 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -948,10 +948,16 @@ static void do_monitor_cpu_combined(void) | |||
948 | printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n", | 948 | printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n", |
949 | temp_combi >> 16); | 949 | temp_combi >> 16); |
950 | state0->overtemp += CPU_MAX_OVERTEMP / 4; | 950 | state0->overtemp += CPU_MAX_OVERTEMP / 4; |
951 | } else if (temp_combi > (state0->mpu.tmax << 16)) | 951 | } else if (temp_combi > (state0->mpu.tmax << 16)) { |
952 | state0->overtemp++; | 952 | state0->overtemp++; |
953 | else | 953 | printk(KERN_WARNING "Temperature %d above max %d. overtemp %d\n", |
954 | temp_combi >> 16, state0->mpu.tmax, state0->overtemp); | ||
955 | } else { | ||
956 | if (state0->overtemp) | ||
957 | printk(KERN_WARNING "Temperature back down to %d\n", | ||
958 | temp_combi >> 16); | ||
954 | state0->overtemp = 0; | 959 | state0->overtemp = 0; |
960 | } | ||
955 | if (state0->overtemp >= CPU_MAX_OVERTEMP) | 961 | if (state0->overtemp >= CPU_MAX_OVERTEMP) |
956 | critical_state = 1; | 962 | critical_state = 1; |
957 | if (state0->overtemp > 0) { | 963 | if (state0->overtemp > 0) { |
@@ -1023,10 +1029,16 @@ static void do_monitor_cpu_split(struct cpu_pid_state *state) | |||
1023 | " (%d) !\n", | 1029 | " (%d) !\n", |
1024 | state->index, temp >> 16); | 1030 | state->index, temp >> 16); |
1025 | state->overtemp += CPU_MAX_OVERTEMP / 4; | 1031 | state->overtemp += CPU_MAX_OVERTEMP / 4; |
1026 | } else if (temp > (state->mpu.tmax << 16)) | 1032 | } else if (temp > (state->mpu.tmax << 16)) { |
1027 | state->overtemp++; | 1033 | state->overtemp++; |
1028 | else | 1034 | printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n", |
1035 | state->index, temp >> 16, state->mpu.tmax, state->overtemp); | ||
1036 | } else { | ||
1037 | if (state->overtemp) | ||
1038 | printk(KERN_WARNING "CPU %d temperature back down to %d\n", | ||
1039 | state->index, temp >> 16); | ||
1029 | state->overtemp = 0; | 1040 | state->overtemp = 0; |
1041 | } | ||
1030 | if (state->overtemp >= CPU_MAX_OVERTEMP) | 1042 | if (state->overtemp >= CPU_MAX_OVERTEMP) |
1031 | critical_state = 1; | 1043 | critical_state = 1; |
1032 | if (state->overtemp > 0) { | 1044 | if (state->overtemp > 0) { |
@@ -1085,10 +1097,16 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state) | |||
1085 | " (%d) !\n", | 1097 | " (%d) !\n", |
1086 | state->index, temp >> 16); | 1098 | state->index, temp >> 16); |
1087 | state->overtemp = CPU_MAX_OVERTEMP / 4; | 1099 | state->overtemp = CPU_MAX_OVERTEMP / 4; |
1088 | } else if (temp > (state->mpu.tmax << 16)) | 1100 | } else if (temp > (state->mpu.tmax << 16)) { |
1089 | state->overtemp++; | 1101 | state->overtemp++; |
1090 | else | 1102 | printk(KERN_WARNING "CPU %d temperature %d above max %d. overtemp %d\n", |
1103 | state->index, temp >> 16, state->mpu.tmax, state->overtemp); | ||
1104 | } else { | ||
1105 | if (state->overtemp) | ||
1106 | printk(KERN_WARNING "CPU %d temperature back down to %d\n", | ||
1107 | state->index, temp >> 16); | ||
1091 | state->overtemp = 0; | 1108 | state->overtemp = 0; |
1109 | } | ||
1092 | if (state->overtemp >= CPU_MAX_OVERTEMP) | 1110 | if (state->overtemp >= CPU_MAX_OVERTEMP) |
1093 | critical_state = 1; | 1111 | critical_state = 1; |
1094 | if (state->overtemp > 0) { | 1112 | if (state->overtemp > 0) { |
diff --git a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h index 393cc9df94e1..df3680e2a22f 100644 --- a/drivers/macintosh/therm_pm72.h +++ b/drivers/macintosh/therm_pm72.h | |||
@@ -269,7 +269,7 @@ struct slots_pid_state | |||
269 | #define CPU_TEMP_HISTORY_SIZE 2 | 269 | #define CPU_TEMP_HISTORY_SIZE 2 |
270 | #define CPU_POWER_HISTORY_SIZE 10 | 270 | #define CPU_POWER_HISTORY_SIZE 10 |
271 | #define CPU_PID_INTERVAL 1 | 271 | #define CPU_PID_INTERVAL 1 |
272 | #define CPU_MAX_OVERTEMP 30 | 272 | #define CPU_MAX_OVERTEMP 90 |
273 | 273 | ||
274 | #define CPUA_PUMP_RPM_INDEX 7 | 274 | #define CPUA_PUMP_RPM_INDEX 7 |
275 | #define CPUB_PUMP_RPM_INDEX 8 | 275 | #define CPUB_PUMP_RPM_INDEX 8 |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 437f55c5d18d..419795f4a2aa 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -321,6 +321,7 @@ int wf_register_sensor(struct wf_sensor *new_sr) | |||
321 | kref_init(&new_sr->ref); | 321 | kref_init(&new_sr->ref); |
322 | list_add(&new_sr->link, &wf_sensors); | 322 | list_add(&new_sr->link, &wf_sensors); |
323 | 323 | ||
324 | sysfs_attr_init(&new_sr->attr.attr); | ||
324 | new_sr->attr.attr.name = new_sr->name; | 325 | new_sr->attr.attr.name = new_sr->name; |
325 | new_sr->attr.attr.mode = 0444; | 326 | new_sr->attr.attr.mode = 0444; |
326 | new_sr->attr.show = wf_show_sensor; | 327 | new_sr->attr.show = wf_show_sensor; |
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 6c68b9e5f5c4..43137b421f92 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c | |||
@@ -173,6 +173,7 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, | |||
173 | 173 | ||
174 | fct->fan_type = pwm_fan; | 174 | fct->fan_type = pwm_fan; |
175 | fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN; | 175 | fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN; |
176 | sysfs_attr_init(&fct->ctrl.attr.attr); | ||
176 | 177 | ||
177 | /* We use the name & location here the same way we do for SMU sensors, | 178 | /* We use the name & location here the same way we do for SMU sensors, |
178 | * see the comment in windfarm_smu_sensors.c. The locations are a bit | 179 | * see the comment in windfarm_smu_sensors.c. The locations are a bit |
diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c index f91b40942e07..84d2b91e4efb 100644 --- a/drivers/md/dm-sysfs.c +++ b/drivers/md/dm-sysfs.c | |||
@@ -75,7 +75,7 @@ static struct attribute *dm_attrs[] = { | |||
75 | NULL, | 75 | NULL, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct sysfs_ops dm_sysfs_ops = { | 78 | static const struct sysfs_ops dm_sysfs_ops = { |
79 | .show = dm_attr_show, | 79 | .show = dm_attr_show, |
80 | }; | 80 | }; |
81 | 81 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index a20a71e5efd3..fdc1890b6ac5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2642,7 +2642,7 @@ static void rdev_free(struct kobject *ko) | |||
2642 | mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj); | 2642 | mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj); |
2643 | kfree(rdev); | 2643 | kfree(rdev); |
2644 | } | 2644 | } |
2645 | static struct sysfs_ops rdev_sysfs_ops = { | 2645 | static const struct sysfs_ops rdev_sysfs_ops = { |
2646 | .show = rdev_attr_show, | 2646 | .show = rdev_attr_show, |
2647 | .store = rdev_attr_store, | 2647 | .store = rdev_attr_store, |
2648 | }; | 2648 | }; |
@@ -4059,7 +4059,7 @@ static void md_free(struct kobject *ko) | |||
4059 | kfree(mddev); | 4059 | kfree(mddev); |
4060 | } | 4060 | } |
4061 | 4061 | ||
4062 | static struct sysfs_ops md_sysfs_ops = { | 4062 | static const struct sysfs_ops md_sysfs_ops = { |
4063 | .show = md_attr_show, | 4063 | .show = md_attr_show, |
4064 | .store = md_attr_store, | 4064 | .store = md_attr_store, |
4065 | }; | 4065 | }; |
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 0903f539bf68..0a3b4ed38e48 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -123,7 +123,7 @@ static int ir_copy_table(struct ir_scancode_table *destin, | |||
123 | * If the key is not found, returns -EINVAL, otherwise, returns 0. | 123 | * If the key is not found, returns -EINVAL, otherwise, returns 0. |
124 | */ | 124 | */ |
125 | static int ir_getkeycode(struct input_dev *dev, | 125 | static int ir_getkeycode(struct input_dev *dev, |
126 | int scancode, int *keycode) | 126 | unsigned int scancode, unsigned int *keycode) |
127 | { | 127 | { |
128 | int elem; | 128 | int elem; |
129 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | 129 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
@@ -291,7 +291,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab, | |||
291 | * If the key is not found, returns -EINVAL, otherwise, returns 0. | 291 | * If the key is not found, returns -EINVAL, otherwise, returns 0. |
292 | */ | 292 | */ |
293 | static int ir_setkeycode(struct input_dev *dev, | 293 | static int ir_setkeycode(struct input_dev *dev, |
294 | int scancode, int keycode) | 294 | unsigned int scancode, unsigned int keycode) |
295 | { | 295 | { |
296 | int rc = 0; | 296 | int rc = 0; |
297 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); | 297 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 52e4ce4304ee..80dda308ff74 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -214,14 +214,14 @@ struct dvb_tuner_ops { | |||
214 | int (*get_status)(struct dvb_frontend *fe, u32 *status); | 214 | int (*get_status)(struct dvb_frontend *fe, u32 *status); |
215 | int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); | 215 | int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); |
216 | 216 | ||
217 | /** These are provided seperately from set_params in order to facilitate silicon | 217 | /** These are provided separately from set_params in order to facilitate silicon |
218 | * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ | 218 | * tuners which require sophisticated tuning loops, controlling each parameter separately. */ |
219 | int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); | 219 | int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); |
220 | int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); | 220 | int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); |
221 | 221 | ||
222 | /* | 222 | /* |
223 | * These are provided seperately from set_params in order to facilitate silicon | 223 | * These are provided separately from set_params in order to facilitate silicon |
224 | * tuners which require sophisticated tuning loops, controlling each parameter seperately. | 224 | * tuners which require sophisticated tuning loops, controlling each parameter separately. |
225 | */ | 225 | */ |
226 | int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); | 226 | int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); |
227 | int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); | 227 | int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index a03ef7efec9a..852fe89539cf 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/usb/input.h> | 9 | #include <linux/usb/input.h> |
10 | 10 | ||
11 | static int dvb_usb_getkeycode(struct input_dev *dev, | 11 | static int dvb_usb_getkeycode(struct input_dev *dev, |
12 | int scancode, int *keycode) | 12 | unsigned int scancode, unsigned int *keycode) |
13 | { | 13 | { |
14 | struct dvb_usb_device *d = input_get_drvdata(dev); | 14 | struct dvb_usb_device *d = input_get_drvdata(dev); |
15 | 15 | ||
@@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev, | |||
39 | } | 39 | } |
40 | 40 | ||
41 | static int dvb_usb_setkeycode(struct input_dev *dev, | 41 | static int dvb_usb_setkeycode(struct input_dev *dev, |
42 | int scancode, int keycode) | 42 | unsigned int scancode, unsigned int keycode) |
43 | { | 43 | { |
44 | struct dvb_usb_device *d = input_get_drvdata(dev); | 44 | struct dvb_usb_device *d = input_get_drvdata(dev); |
45 | 45 | ||
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 12279f6d9bc4..716870ae85d5 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -4404,7 +4404,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) | |||
4404 | /* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning] | 4404 | /* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning] |
4405 | * | 4405 | * |
4406 | * The CS16 (available on eBay cheap) is a PCI board with four Fusion | 4406 | * The CS16 (available on eBay cheap) is a PCI board with four Fusion |
4407 | * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator | 4407 | * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator |
4408 | * chips, ten eight input analog multiplexors, a not chip and a few | 4408 | * chips, ten eight input analog multiplexors, a not chip and a few |
4409 | * other components. | 4409 | * other components. |
4410 | * | 4410 | * |
@@ -4426,7 +4426,7 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) | |||
4426 | * | 4426 | * |
4427 | * There is an ATMEL microcontroller with an 8031 core on board. I have not | 4427 | * There is an ATMEL microcontroller with an 8031 core on board. I have not |
4428 | * determined what function (if any) it provides. With the microcontroller | 4428 | * determined what function (if any) it provides. With the microcontroller |
4429 | * and sync seperator chips a guess is that it might have to do with video | 4429 | * and sync separator chips a guess is that it might have to do with video |
4430 | * switching and maybe some digital I/O. | 4430 | * switching and maybe some digital I/O. |
4431 | */ | 4431 | */ |
4432 | static void tibetCS16_muxsel(struct bttv *btv, unsigned int input) | 4432 | static void tibetCS16_muxsel(struct bttv *btv, unsigned int input) |
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index bc4ced6c013b..f36e11a0458d 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -512,7 +512,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | |||
512 | /* | 512 | /* |
513 | * The FX2 chip does not give us a zero length read at end of frame. | 513 | * The FX2 chip does not give us a zero length read at end of frame. |
514 | * It does, however, give a short read at the end of a frame, if | 514 | * It does, however, give a short read at the end of a frame, if |
515 | * neccessary, rather than run two frames together. | 515 | * necessary, rather than run two frames together. |
516 | * | 516 | * |
517 | * By choosing the right bulk transfer size, we are guaranteed to always | 517 | * By choosing the right bulk transfer size, we are guaranteed to always |
518 | * get a short read for the last read of each frame. Frame sizes are | 518 | * get a short read for the last read of each frame. Frame sizes are |
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 7400eacb4d64..142c327afb32 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c | |||
@@ -1735,7 +1735,7 @@ static struct v4l2_int_device omap24xxcam = { | |||
1735 | * | 1735 | * |
1736 | */ | 1736 | */ |
1737 | 1737 | ||
1738 | static int __init omap24xxcam_probe(struct platform_device *pdev) | 1738 | static int __devinit omap24xxcam_probe(struct platform_device *pdev) |
1739 | { | 1739 | { |
1740 | struct omap24xxcam_device *cam; | 1740 | struct omap24xxcam_device *cam; |
1741 | struct resource *mem; | 1741 | struct resource *mem; |
diff --git a/drivers/media/video/pwc/philips.txt b/drivers/media/video/pwc/philips.txt index f9f3584281d8..d38dd791511e 100644 --- a/drivers/media/video/pwc/philips.txt +++ b/drivers/media/video/pwc/philips.txt | |||
@@ -33,7 +33,7 @@ a lot of extra information, a FAQ, and the binary plugin 'PWCX'. This plugin | |||
33 | contains decompression routines that allow you to use higher image sizes and | 33 | contains decompression routines that allow you to use higher image sizes and |
34 | framerates; in addition the webcam uses less bandwidth on the USB bus (handy | 34 | framerates; in addition the webcam uses less bandwidth on the USB bus (handy |
35 | if you want to run more than 1 camera simultaneously). These routines fall | 35 | if you want to run more than 1 camera simultaneously). These routines fall |
36 | under a NDA, and may therefor not be distributed as source; however, its use | 36 | under a NDA, and may therefore not be distributed as source; however, its use |
37 | is completely optional. | 37 | is completely optional. |
38 | 38 | ||
39 | You can build this code either into your kernel, or as a module. I recommend | 39 | You can build this code either into your kernel, or as a module. I recommend |
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 4af7382da5c5..494957b10bac 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h | |||
@@ -120,7 +120,7 @@ extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2], | |||
120 | /* | 120 | /* |
121 | Write multiple registers with constant values. For example: | 121 | Write multiple registers with constant values. For example: |
122 | sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); | 122 | sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); |
123 | Register adresses must be < 256. | 123 | Register addresses must be < 256. |
124 | */ | 124 | */ |
125 | #define sn9c102_write_const_regs(sn9c102_device, data...) \ | 125 | #define sn9c102_write_const_regs(sn9c102_device, data...) \ |
126 | ({ static const u8 _valreg[][2] = {data}; \ | 126 | ({ static const u8 _valreg[][2] = {data}; \ |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 0446524d3543..6bf6bc7dbc7f 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, | 7 | The tea6420 is a bus controlled audio-matrix with 5 stereo inputs, |
8 | 4 stereo outputs and gain control for each output. | 8 | 4 stereo outputs and gain control for each output. |
9 | It is cascadable, i.e. it can be found at the adresses 0x98 | 9 | It is cascadable, i.e. it can be found at the addresses 0x98 |
10 | and 0x9a on the i2c-bus. | 10 | and 0x9a on the i2c-bus. |
11 | 11 | ||
12 | For detailed informations download the specifications directly | 12 | For detailed informations download the specifications directly |
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index e5ab62141503..ef5ce2676f05 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c | |||
@@ -539,7 +539,7 @@ static int i2o_iop_reset(struct i2o_controller *c) | |||
539 | * which is indeterminate. We need to wait until the IOP has | 539 | * which is indeterminate. We need to wait until the IOP has |
540 | * rebooted before we can let the system talk to it. We read | 540 | * rebooted before we can let the system talk to it. We read |
541 | * the inbound Free_List until a message is available. If we | 541 | * the inbound Free_List until a message is available. If we |
542 | * can't read one in the given ammount of time, we assume the | 542 | * can't read one in the given amount of time, we assume the |
543 | * IOP could not reboot properly. | 543 | * IOP could not reboot properly. |
544 | */ | 544 | */ |
545 | osm_debug("%s: Reset in progress, waiting for reboot...\n", | 545 | osm_debug("%s: Reset in progress, waiting for reboot...\n", |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 951fa9b93fbe..2a5a0b78f84e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -11,7 +11,7 @@ config MFD_CORE | |||
11 | 11 | ||
12 | config MFD_88PM860X | 12 | config MFD_88PM860X |
13 | bool "Support Marvell 88PM8606/88PM8607" | 13 | bool "Support Marvell 88PM8606/88PM8607" |
14 | depends on I2C=y | 14 | depends on I2C=y && GENERIC_HARDIRQS |
15 | select MFD_CORE | 15 | select MFD_CORE |
16 | help | 16 | help |
17 | This supports for Marvell 88PM8606/88PM8607 Power Management IC. | 17 | This supports for Marvell 88PM8606/88PM8607 Power Management IC. |
@@ -205,7 +205,7 @@ config PMIC_ADP5520 | |||
205 | 205 | ||
206 | config MFD_MAX8925 | 206 | config MFD_MAX8925 |
207 | bool "Maxim Semiconductor MAX8925 PMIC Support" | 207 | bool "Maxim Semiconductor MAX8925 PMIC Support" |
208 | depends on I2C=y | 208 | depends on I2C=y && GENERIC_HARDIRQS |
209 | select MFD_CORE | 209 | select MFD_CORE |
210 | help | 210 | help |
211 | Say yes here to support for Maxim Semiconductor MAX8925. This is | 211 | Say yes here to support for Maxim Semiconductor MAX8925. This is |
@@ -226,7 +226,7 @@ config MFD_WM8400 | |||
226 | config MFD_WM831X | 226 | config MFD_WM831X |
227 | bool "Support Wolfson Microelectronics WM831x/2x PMICs" | 227 | bool "Support Wolfson Microelectronics WM831x/2x PMICs" |
228 | select MFD_CORE | 228 | select MFD_CORE |
229 | depends on I2C=y | 229 | depends on I2C=y && GENERIC_HARDIRQS |
230 | help | 230 | help |
231 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs. | 231 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs. |
232 | This driver provides common support for accessing the device, | 232 | This driver provides common support for accessing the device, |
@@ -235,6 +235,7 @@ config MFD_WM831X | |||
235 | 235 | ||
236 | config MFD_WM8350 | 236 | config MFD_WM8350 |
237 | bool | 237 | bool |
238 | depends on GENERIC_HARDIRQS | ||
238 | 239 | ||
239 | config MFD_WM8350_CONFIG_MODE_0 | 240 | config MFD_WM8350_CONFIG_MODE_0 |
240 | bool | 241 | bool |
@@ -287,7 +288,7 @@ config MFD_WM8352_CONFIG_MODE_3 | |||
287 | config MFD_WM8350_I2C | 288 | config MFD_WM8350_I2C |
288 | bool "Support Wolfson Microelectronics WM8350 with I2C" | 289 | bool "Support Wolfson Microelectronics WM8350 with I2C" |
289 | select MFD_WM8350 | 290 | select MFD_WM8350 |
290 | depends on I2C=y | 291 | depends on I2C=y && GENERIC_HARDIRQS |
291 | help | 292 | help |
292 | The WM8350 is an integrated audio and power management | 293 | The WM8350 is an integrated audio and power management |
293 | subsystem with watchdog and RTC functionality for embedded | 294 | subsystem with watchdog and RTC functionality for embedded |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index dc9ea95c0561..7b6652f60117 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -523,7 +523,7 @@ unsigned long sm501_set_clock(struct device *dev, | |||
523 | unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); | 523 | unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); |
524 | unsigned char reg; | 524 | unsigned char reg; |
525 | unsigned int pll_reg = 0; | 525 | unsigned int pll_reg = 0; |
526 | unsigned long sm501_freq; /* the actual frequency acheived */ | 526 | unsigned long sm501_freq; /* the actual frequency achieved */ |
527 | 527 | ||
528 | struct sm501_clock to; | 528 | struct sm501_clock to; |
529 | 529 | ||
@@ -533,7 +533,7 @@ unsigned long sm501_set_clock(struct device *dev, | |||
533 | 533 | ||
534 | switch (clksrc) { | 534 | switch (clksrc) { |
535 | case SM501_CLOCK_P2XCLK: | 535 | case SM501_CLOCK_P2XCLK: |
536 | /* This clock is divided in half so to achive the | 536 | /* This clock is divided in half so to achieve the |
537 | * requested frequency the value must be multiplied by | 537 | * requested frequency the value must be multiplied by |
538 | * 2. This clock also has an additional pre divisor */ | 538 | * 2. This clock also has an additional pre divisor */ |
539 | 539 | ||
@@ -562,7 +562,7 @@ unsigned long sm501_set_clock(struct device *dev, | |||
562 | break; | 562 | break; |
563 | 563 | ||
564 | case SM501_CLOCK_V2XCLK: | 564 | case SM501_CLOCK_V2XCLK: |
565 | /* This clock is divided in half so to achive the | 565 | /* This clock is divided in half so to achieve the |
566 | * requested frequency the value must be multiplied by 2. */ | 566 | * requested frequency the value must be multiplied by 2. */ |
567 | 567 | ||
568 | sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2); | 568 | sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2); |
@@ -648,7 +648,7 @@ unsigned long sm501_find_clock(struct device *dev, | |||
648 | unsigned long req_freq) | 648 | unsigned long req_freq) |
649 | { | 649 | { |
650 | struct sm501_devdata *sm = dev_get_drvdata(dev); | 650 | struct sm501_devdata *sm = dev_get_drvdata(dev); |
651 | unsigned long sm501_freq; /* the frequency achiveable by the 501 */ | 651 | unsigned long sm501_freq; /* the frequency achieveable by the 501 */ |
652 | struct sm501_clock to; | 652 | struct sm501_clock to; |
653 | 653 | ||
654 | switch (clksrc) { | 654 | switch (clksrc) { |
@@ -1430,7 +1430,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev) | |||
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | sm->regs_claim = request_mem_region(sm->io_res->start, | 1432 | sm->regs_claim = request_mem_region(sm->io_res->start, |
1433 | resource_size(sm->io_res), "sm501"); | 1433 | 0x100, "sm501"); |
1434 | 1434 | ||
1435 | if (sm->regs_claim == NULL) { | 1435 | if (sm->regs_claim == NULL) { |
1436 | dev_err(&dev->dev, "cannot claim registers\n"); | 1436 | dev_err(&dev->dev, "cannot claim registers\n"); |
@@ -1644,7 +1644,7 @@ static int __devinit sm501_pci_probe(struct pci_dev *dev, | |||
1644 | sm->mem_res = &dev->resource[0]; | 1644 | sm->mem_res = &dev->resource[0]; |
1645 | 1645 | ||
1646 | sm->regs_claim = request_mem_region(sm->io_res->start, | 1646 | sm->regs_claim = request_mem_region(sm->io_res->start, |
1647 | resource_size(sm->io_res), "sm501"); | 1647 | 0x100, "sm501"); |
1648 | if (sm->regs_claim == NULL) { | 1648 | if (sm->regs_claim == NULL) { |
1649 | dev_err(&dev->dev, "cannot claim registers\n"); | 1649 | dev_err(&dev->dev, "cannot claim registers\n"); |
1650 | err= -EBUSY; | 1650 | err= -EBUSY; |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d16af6a423fb..2191c8d896a0 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -268,6 +268,16 @@ config ISL29003 | |||
268 | This driver can also be built as a module. If so, the module | 268 | This driver can also be built as a module. If so, the module |
269 | will be called isl29003. | 269 | will be called isl29003. |
270 | 270 | ||
271 | config SENSORS_TSL2550 | ||
272 | tristate "Taos TSL2550 ambient light sensor" | ||
273 | depends on I2C && SYSFS | ||
274 | help | ||
275 | If you say yes here you get support for the Taos TSL2550 | ||
276 | ambient light sensor. | ||
277 | |||
278 | This driver can also be built as a module. If so, the module | ||
279 | will be called tsl2550. | ||
280 | |||
271 | config EP93XX_PWM | 281 | config EP93XX_PWM |
272 | tristate "EP93xx PWM support" | 282 | tristate "EP93xx PWM support" |
273 | depends on ARCH_EP93XX | 283 | depends on ARCH_EP93XX |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 049ff2482f30..27c484355414 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_SGI_GRU) += sgi-gru/ | |||
21 | obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o | 21 | obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o |
22 | obj-$(CONFIG_HP_ILO) += hpilo.o | 22 | obj-$(CONFIG_HP_ILO) += hpilo.o |
23 | obj-$(CONFIG_ISL29003) += isl29003.o | 23 | obj-$(CONFIG_ISL29003) += isl29003.o |
24 | obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o | ||
24 | obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o | 25 | obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o |
25 | obj-$(CONFIG_DS1682) += ds1682.o | 26 | obj-$(CONFIG_DS1682) += ds1682.o |
26 | obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o | 27 | obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 2cb2736d65aa..db7d0f21b65d 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -505,6 +505,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
505 | * Export the EEPROM bytes through sysfs, since that's convenient. | 505 | * Export the EEPROM bytes through sysfs, since that's convenient. |
506 | * By default, only root should see the data (maybe passwords etc) | 506 | * By default, only root should see the data (maybe passwords etc) |
507 | */ | 507 | */ |
508 | sysfs_bin_attr_init(&at24->bin); | ||
508 | at24->bin.attr.name = "eeprom"; | 509 | at24->bin.attr.name = "eeprom"; |
509 | at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; | 510 | at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; |
510 | at24->bin.read = at24_bin_read; | 511 | at24->bin.read = at24_bin_read; |
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index d902d81dde39..d194212a41f6 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c | |||
@@ -347,6 +347,7 @@ static int at25_probe(struct spi_device *spi) | |||
347 | * that's sensitive for read and/or write, like ethernet addresses, | 347 | * that's sensitive for read and/or write, like ethernet addresses, |
348 | * security codes, board-specific manufacturing calibrations, etc. | 348 | * security codes, board-specific manufacturing calibrations, etc. |
349 | */ | 349 | */ |
350 | sysfs_bin_attr_init(&at25->bin); | ||
350 | at25->bin.attr.name = "eeprom"; | 351 | at25->bin.attr.name = "eeprom"; |
351 | at25->bin.attr.mode = S_IRUSR; | 352 | at25->bin.attr.mode = S_IRUSR; |
352 | at25->bin.read = at25_bin_read; | 353 | at25->bin.read = at25_bin_read; |
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 04c27266f567..779aa8ebe4cf 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c | |||
@@ -497,12 +497,7 @@ static struct pci_driver phantom_pci_driver = { | |||
497 | .resume = phantom_resume | 497 | .resume = phantom_resume |
498 | }; | 498 | }; |
499 | 499 | ||
500 | static ssize_t phantom_show_version(struct class *cls, char *buf) | 500 | static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION); |
501 | { | ||
502 | return sprintf(buf, PHANTOM_VERSION "\n"); | ||
503 | } | ||
504 | |||
505 | static CLASS_ATTR(version, 0444, phantom_show_version, NULL); | ||
506 | 501 | ||
507 | static int __init phantom_init(void) | 502 | static int __init phantom_init(void) |
508 | { | 503 | { |
@@ -515,7 +510,7 @@ static int __init phantom_init(void) | |||
515 | printk(KERN_ERR "phantom: can't register phantom class\n"); | 510 | printk(KERN_ERR "phantom: can't register phantom class\n"); |
516 | goto err; | 511 | goto err; |
517 | } | 512 | } |
518 | retval = class_create_file(phantom_class, &class_attr_version); | 513 | retval = class_create_file(phantom_class, &class_attr_version.attr); |
519 | if (retval) { | 514 | if (retval) { |
520 | printk(KERN_ERR "phantom: can't create sysfs version file\n"); | 515 | printk(KERN_ERR "phantom: can't create sysfs version file\n"); |
521 | goto err_class; | 516 | goto err_class; |
@@ -541,7 +536,7 @@ static int __init phantom_init(void) | |||
541 | err_unchr: | 536 | err_unchr: |
542 | unregister_chrdev_region(dev, PHANTOM_MAX_MINORS); | 537 | unregister_chrdev_region(dev, PHANTOM_MAX_MINORS); |
543 | err_attr: | 538 | err_attr: |
544 | class_remove_file(phantom_class, &class_attr_version); | 539 | class_remove_file(phantom_class, &class_attr_version.attr); |
545 | err_class: | 540 | err_class: |
546 | class_destroy(phantom_class); | 541 | class_destroy(phantom_class); |
547 | err: | 542 | err: |
@@ -554,7 +549,7 @@ static void __exit phantom_exit(void) | |||
554 | 549 | ||
555 | unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS); | 550 | unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS); |
556 | 551 | ||
557 | class_remove_file(phantom_class, &class_attr_version); | 552 | class_remove_file(phantom_class, &class_attr_version.attr); |
558 | class_destroy(phantom_class); | 553 | class_destroy(phantom_class); |
559 | 554 | ||
560 | pr_debug("phantom: module successfully removed\n"); | 555 | pr_debug("phantom: module successfully removed\n"); |
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index 02a77b8b8eef..7a8b9068ea03 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h | |||
@@ -516,8 +516,7 @@ struct gru_blade_state { | |||
516 | 516 | ||
517 | /* Scan all active GRUs in a GRU bitmap */ | 517 | /* Scan all active GRUs in a GRU bitmap */ |
518 | #define for_each_gru_in_bitmap(gid, map) \ | 518 | #define for_each_gru_in_bitmap(gid, map) \ |
519 | for ((gid) = find_first_bit((map), GRU_MAX_GRUS); (gid) < GRU_MAX_GRUS;\ | 519 | for_each_set_bit((gid), (map), GRU_MAX_GRUS) |
520 | (gid)++, (gid) = find_next_bit((map), GRU_MAX_GRUS, (gid))) | ||
521 | 520 | ||
522 | /* Scan all active GRUs on a specific blade */ | 521 | /* Scan all active GRUs on a specific blade */ |
523 | #define for_each_gru_on_blade(gru, nid, i) \ | 522 | #define for_each_gru_on_blade(gru, nid, i) \ |
@@ -536,23 +535,17 @@ struct gru_blade_state { | |||
536 | 535 | ||
537 | /* Scan each CBR whose bit is set in a TFM (or copy of) */ | 536 | /* Scan each CBR whose bit is set in a TFM (or copy of) */ |
538 | #define for_each_cbr_in_tfm(i, map) \ | 537 | #define for_each_cbr_in_tfm(i, map) \ |
539 | for ((i) = find_first_bit(map, GRU_NUM_CBE); \ | 538 | for_each_set_bit((i), (map), GRU_NUM_CBE) |
540 | (i) < GRU_NUM_CBE; \ | ||
541 | (i)++, (i) = find_next_bit(map, GRU_NUM_CBE, i)) | ||
542 | 539 | ||
543 | /* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */ | 540 | /* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */ |
544 | #define for_each_cbr_in_allocation_map(i, map, k) \ | 541 | #define for_each_cbr_in_allocation_map(i, map, k) \ |
545 | for ((k) = find_first_bit(map, GRU_CBR_AU); (k) < GRU_CBR_AU; \ | 542 | for_each_set_bit((k), (map), GRU_CBR_AU) \ |
546 | (k) = find_next_bit(map, GRU_CBR_AU, (k) + 1)) \ | ||
547 | for ((i) = (k)*GRU_CBR_AU_SIZE; \ | 543 | for ((i) = (k)*GRU_CBR_AU_SIZE; \ |
548 | (i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++) | 544 | (i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++) |
549 | 545 | ||
550 | /* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */ | 546 | /* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */ |
551 | #define for_each_dsr_in_allocation_map(i, map, k) \ | 547 | #define for_each_dsr_in_allocation_map(i, map, k) \ |
552 | for ((k) = find_first_bit((const unsigned long *)map, GRU_DSR_AU);\ | 548 | for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU) \ |
553 | (k) < GRU_DSR_AU; \ | ||
554 | (k) = find_next_bit((const unsigned long *)map, \ | ||
555 | GRU_DSR_AU, (k) + 1)) \ | ||
556 | for ((i) = (k) * GRU_DSR_AU_CL; \ | 549 | for ((i) = (k) * GRU_DSR_AU_CL; \ |
557 | (i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++) | 550 | (i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++) |
558 | 551 | ||
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/misc/tsl2550.c index a0702f36a72f..483ae5f7f68e 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/misc/tsl2550.c | |||
@@ -47,8 +47,8 @@ struct tsl2550_data { | |||
47 | struct i2c_client *client; | 47 | struct i2c_client *client; |
48 | struct mutex update_lock; | 48 | struct mutex update_lock; |
49 | 49 | ||
50 | unsigned int power_state : 1; | 50 | unsigned int power_state:1; |
51 | unsigned int operating_mode : 1; | 51 | unsigned int operating_mode:1; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | /* | 54 | /* |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 3fab78ba8952..723e50894db9 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -575,7 +575,7 @@ static int uart_carrier_raised(struct tty_port *tport) | |||
575 | struct sdio_uart_port *port = | 575 | struct sdio_uart_port *port = |
576 | container_of(tport, struct sdio_uart_port, port); | 576 | container_of(tport, struct sdio_uart_port, port); |
577 | unsigned int ret = sdio_uart_claim_func(port); | 577 | unsigned int ret = sdio_uart_claim_func(port); |
578 | if (ret) /* Missing hardware shoudn't block for carrier */ | 578 | if (ret) /* Missing hardware shouldn't block for carrier */ |
579 | return 1; | 579 | return 1; |
580 | ret = sdio_uart_get_mctrl(port); | 580 | ret = sdio_uart_get_mctrl(port); |
581 | sdio_uart_release_func(port); | 581 | sdio_uart_release_func(port); |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f4b97d3c3d0f..3168ebd616b2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1089,6 +1089,7 @@ void mmc_rescan(struct work_struct *work) | |||
1089 | mmc_claim_host(host); | 1089 | mmc_claim_host(host); |
1090 | 1090 | ||
1091 | mmc_power_up(host); | 1091 | mmc_power_up(host); |
1092 | sdio_reset(host); | ||
1092 | mmc_go_idle(host); | 1093 | mmc_go_idle(host); |
1093 | 1094 | ||
1094 | mmc_send_if_cond(host, host->ocr_avail); | 1095 | mmc_send_if_cond(host, host->ocr_avail); |
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index 4eb7825fd1a7..dea36d9c22e6 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
67 | return err; | 67 | return err; |
68 | } | 68 | } |
69 | 69 | ||
70 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | 70 | static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, |
71 | unsigned addr, u8 in, u8* out) | 71 | unsigned addr, u8 in, u8 *out) |
72 | { | 72 | { |
73 | struct mmc_command cmd; | 73 | struct mmc_command cmd; |
74 | int err; | 74 | int err; |
75 | 75 | ||
76 | BUG_ON(!card); | 76 | BUG_ON(!host); |
77 | BUG_ON(fn > 7); | 77 | BUG_ON(fn > 7); |
78 | 78 | ||
79 | /* sanity check */ | 79 | /* sanity check */ |
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
90 | cmd.arg |= in; | 90 | cmd.arg |= in; |
91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; | 91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; |
92 | 92 | ||
93 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 93 | err = mmc_wait_for_cmd(host, &cmd, 0); |
94 | if (err) | 94 | if (err) |
95 | return err; | 95 | return err; |
96 | 96 | ||
97 | if (mmc_host_is_spi(card->host)) { | 97 | if (mmc_host_is_spi(host)) { |
98 | /* host driver already reported errors */ | 98 | /* host driver already reported errors */ |
99 | } else { | 99 | } else { |
100 | if (cmd.resp[0] & R5_ERROR) | 100 | if (cmd.resp[0] & R5_ERROR) |
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
106 | } | 106 | } |
107 | 107 | ||
108 | if (out) { | 108 | if (out) { |
109 | if (mmc_host_is_spi(card->host)) | 109 | if (mmc_host_is_spi(host)) |
110 | *out = (cmd.resp[0] >> 8) & 0xFF; | 110 | *out = (cmd.resp[0] >> 8) & 0xFF; |
111 | else | 111 | else |
112 | *out = cmd.resp[0] & 0xFF; | 112 | *out = cmd.resp[0] & 0xFF; |
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | ||
119 | unsigned addr, u8 in, u8 *out) | ||
120 | { | ||
121 | BUG_ON(!card); | ||
122 | return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out); | ||
123 | } | ||
124 | |||
118 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 125 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
119 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) | 126 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) |
120 | { | 127 | { |
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
182 | return 0; | 189 | return 0; |
183 | } | 190 | } |
184 | 191 | ||
192 | int sdio_reset(struct mmc_host *host) | ||
193 | { | ||
194 | int ret; | ||
195 | u8 abort; | ||
196 | |||
197 | /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */ | ||
198 | |||
199 | ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); | ||
200 | if (ret) | ||
201 | abort = 0x08; | ||
202 | else | ||
203 | abort |= 0x08; | ||
204 | |||
205 | ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index e2e74b0d17d8..12a4d3ab174c 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h | |||
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
17 | unsigned addr, u8 in, u8* out); | 17 | unsigned addr, u8 in, u8* out); |
18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); | 19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); |
20 | int sdio_reset(struct mmc_host *host); | ||
20 | 21 | ||
21 | #endif | 22 | #endif |
22 | 23 | ||
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index b31946e0b4ca..4c068e5fe6b2 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -1250,9 +1250,7 @@ msmsdcc_resume(struct platform_device *dev) | |||
1250 | 1250 | ||
1251 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) | 1251 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) |
1252 | mmc_resume_host(mmc); | 1252 | mmc_resume_host(mmc); |
1253 | if (host->stat_irq) | 1253 | if (host->stat_irq) |
1254 | enable_irq(host->stat_irq); | ||
1255 | else if (host->stat_irq) | ||
1256 | enable_irq(host->stat_irq); | 1254 | enable_irq(host->stat_irq); |
1257 | } | 1255 | } |
1258 | return 0; | 1256 | return 0; |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 60a2b69e54f5..2df90412abb5 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 | 4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 |
5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). | 5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). |
6 | * Unlike the hardware found on MX1, this hardware just works and does | 6 | * Unlike the hardware found on MX1, this hardware just works and does |
7 | * not need all the quirks found in imxmmc.c, hence the seperate driver. | 7 | * not need all the quirks found in imxmmc.c, hence the separate driver. |
8 | * | 8 | * |
9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | 9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> | 10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> |
@@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
708 | mmc->max_blk_size = 2048; | 708 | mmc->max_blk_size = 2048; |
709 | mmc->max_blk_count = 65535; | 709 | mmc->max_blk_count = 65535; |
710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
711 | mmc->max_seg_size = mmc->max_seg_size; | 711 | mmc->max_seg_size = mmc->max_req_size; |
712 | 712 | ||
713 | host = mmc_priv(mmc); | 713 | host = mmc_priv(mmc); |
714 | host->base = ioremap(r->start, resource_size(r)); | 714 | host->base = ioremap(r->start, resource_size(r)); |
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index ca584d0380b4..ca584d0380b4 100755..100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 1bec5e1ce6ac..8db1148dfa47 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
@@ -226,7 +226,7 @@ struct unlock_addr { | |||
226 | * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, | 226 | * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, |
227 | * should not be used. The problem is that structures with | 227 | * should not be used. The problem is that structures with |
228 | * initializers have extra fields initialized to 0. It is _very_ | 228 | * initializers have extra fields initialized to 0. It is _very_ |
229 | * desireable to have the unlock address entries for unsupported | 229 | * desirable to have the unlock address entries for unsupported |
230 | * data widths automatically initialized - that means that | 230 | * data widths automatically initialized - that means that |
231 | * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here | 231 | * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here |
232 | * must go unused. | 232 | * must go unused. |
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 8aca5523a337..8aca5523a337 100755..100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c | |||
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index c48cad271f5d..30e12c88d1da 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c | |||
@@ -118,7 +118,7 @@ static int __devinit pismo_add_device(struct pismo_data *pismo, int i, | |||
118 | { | 118 | { |
119 | struct platform_device *dev; | 119 | struct platform_device *dev; |
120 | struct resource res = { }; | 120 | struct resource res = { }; |
121 | phys_addr_t base = region.base; | 121 | phys_addr_t base = region->base; |
122 | int ret; | 122 | int ret; |
123 | 123 | ||
124 | if (base == ~0) | 124 | if (base == ~0) |
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index dafb91944e70..76a76be5a7bd 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * http://www.simtec.co.uk/products/SWLINUX/ | 4 | * http://www.simtec.co.uk/products/SWLINUX/ |
5 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * | 6 | * |
7 | * Generic platfrom device based RAM map | 7 | * Generic platform device based RAM map |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index bb6465604235..1157d5679e66 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -444,7 +444,7 @@ config MTD_NAND_FSL_UPM | |||
444 | 444 | ||
445 | config MTD_NAND_MXC | 445 | config MTD_NAND_MXC |
446 | tristate "MXC NAND support" | 446 | tristate "MXC NAND support" |
447 | depends on ARCH_MX2 || ARCH_MX3 | 447 | depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 |
448 | help | 448 | help |
449 | This enables the driver for the NAND flash controller on the | 449 | This enables the driver for the NAND flash controller on the |
450 | MXC processors. | 450 | MXC processors. |
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index 087bcd745bb7..7d1cca7a31a9 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c | |||
@@ -381,7 +381,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) | |||
381 | if (!r) | 381 | if (!r) |
382 | return -ENXIO; | 382 | return -ENXIO; |
383 | 383 | ||
384 | /* map physical adress */ | 384 | /* map physical address */ |
385 | bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1); | 385 | bcm_umi_io_base = ioremap(r->start, r->end - r->start + 1); |
386 | 386 | ||
387 | if (!bcm_umi_io_base) { | 387 | if (!bcm_umi_io_base) { |
@@ -525,7 +525,7 @@ static int bcm_umi_nand_remove(struct platform_device *pdev) | |||
525 | /* Release resources, unregister device */ | 525 | /* Release resources, unregister device */ |
526 | nand_release(board_mtd); | 526 | nand_release(board_mtd); |
527 | 527 | ||
528 | /* unmap physical adress */ | 528 | /* unmap physical address */ |
529 | iounmap(bcm_umi_io_base); | 529 | iounmap(bcm_umi_io_base); |
530 | 530 | ||
531 | /* Free the MTD device structure */ | 531 | /* Free the MTD device structure */ |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 45dec5770da0..b2900d8406d3 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -507,7 +507,7 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) | |||
507 | * MXC NANDFC can only perform full page+spare or | 507 | * MXC NANDFC can only perform full page+spare or |
508 | * spare-only read/write. When the upper layers | 508 | * spare-only read/write. When the upper layers |
509 | * layers perform a read/write buf operation, | 509 | * layers perform a read/write buf operation, |
510 | * we will used the saved column adress to index into | 510 | * we will used the saved column address to index into |
511 | * the full page. | 511 | * the full page. |
512 | */ | 512 | */ |
513 | send_addr(host, 0, page_addr == -1); | 513 | send_addr(host, 0, page_addr == -1); |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index bc45ef9af17d..fad40aa6f099 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -89,7 +89,8 @@ DEFINE_MUTEX(ubi_devices_mutex); | |||
89 | static DEFINE_SPINLOCK(ubi_devices_lock); | 89 | static DEFINE_SPINLOCK(ubi_devices_lock); |
90 | 90 | ||
91 | /* "Show" method for files in '/<sysfs>/class/ubi/' */ | 91 | /* "Show" method for files in '/<sysfs>/class/ubi/' */ |
92 | static ssize_t ubi_version_show(struct class *class, char *buf) | 92 | static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr, |
93 | char *buf) | ||
93 | { | 94 | { |
94 | return sprintf(buf, "%d\n", UBI_VERSION); | 95 | return sprintf(buf, "%d\n", UBI_VERSION); |
95 | } | 96 | } |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7029cd50c458..0ba5b8e50a7c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -907,7 +907,7 @@ config SMC91X | |||
907 | select CRC32 | 907 | select CRC32 |
908 | select MII | 908 | select MII |
909 | depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ | 909 | depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ |
910 | MIPS || BLACKFIN || MN10300 | 910 | MIPS || BLACKFIN || MN10300 || COLDFIRE |
911 | help | 911 | help |
912 | This is a driver for SMC's 91x series of Ethernet chipsets, | 912 | This is a driver for SMC's 91x series of Ethernet chipsets, |
913 | including the SMC91C94 and the SMC91C111. Say Y if you want it | 913 | including the SMC91C94 and the SMC91C111. Say Y if you want it |
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 8ca639127dbc..a1d4188c430b 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget) | |||
575 | if (work_done < budget) { | 575 | if (work_done < budget) { |
576 | unsigned long flags; | 576 | unsigned long flags; |
577 | spin_lock_irqsave(&ksp->rx_lock, flags); | 577 | spin_lock_irqsave(&ksp->rx_lock, flags); |
578 | __napi_complete(napi); | ||
578 | /*enable rx interrupt*/ | 579 | /*enable rx interrupt*/ |
579 | writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); | 580 | writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); |
580 | __napi_complete(napi); | ||
581 | spin_unlock_irqrestore(&ksp->rx_lock, flags); | 581 | spin_unlock_irqrestore(&ksp->rx_lock, flags); |
582 | } | 582 | } |
583 | return work_done; | 583 | return work_done; |
diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h index d918bbe621ea..927e4de6474d 100644 --- a/drivers/net/atlx/atl2.h +++ b/drivers/net/atlx/atl2.h | |||
@@ -442,7 +442,7 @@ struct atl2_hw { | |||
442 | struct atl2_ring_header { | 442 | struct atl2_ring_header { |
443 | /* pointer to the descriptor ring memory */ | 443 | /* pointer to the descriptor ring memory */ |
444 | void *desc; | 444 | void *desc; |
445 | /* physical adress of the descriptor ring */ | 445 | /* physical address of the descriptor ring */ |
446 | dma_addr_t dma; | 446 | dma_addr_t dma; |
447 | /* length of descriptor ring in bytes */ | 447 | /* length of descriptor ring in bytes */ |
448 | unsigned int size; | 448 | unsigned int size; |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index be81fb2d10f7..8f0752553681 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops; | |||
290 | 290 | ||
291 | #define drvr_stats(adapter) (&adapter->stats.drvr_stats) | 291 | #define drvr_stats(adapter) (&adapter->stats.drvr_stats) |
292 | 292 | ||
293 | static inline unsigned int be_pci_func(struct be_adapter *adapter) | ||
294 | { | ||
295 | return PCI_FUNC(adapter->pdev->devfn); | ||
296 | } | ||
297 | |||
298 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) | 293 | #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) |
299 | 294 | ||
300 | #define PAGE_SHIFT_4K 12 | 295 | #define PAGE_SHIFT_4K 12 |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 4b1f80519ca4..c59215361f4e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter, | |||
465 | 465 | ||
466 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); | 466 | req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); |
467 | 467 | ||
468 | AMAP_SET_BITS(struct amap_eq_context, func, req->context, | ||
469 | be_pci_func(adapter)); | ||
470 | AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); | 468 | AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); |
471 | /* 4byte eqe*/ | 469 | /* 4byte eqe*/ |
472 | AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); | 470 | AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); |
@@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
629 | AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); | 627 | AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); |
630 | AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); | 628 | AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); |
631 | AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); | 629 | AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); |
632 | AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter)); | ||
633 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); | 630 | be_dws_cpu_to_le(ctxt, sizeof(req->context)); |
634 | 631 | ||
635 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | 632 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
@@ -678,7 +675,6 @@ int be_cmd_mccq_create(struct be_adapter *adapter, | |||
678 | 675 | ||
679 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); | 676 | req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); |
680 | 677 | ||
681 | AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter)); | ||
682 | AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); | 678 | AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); |
683 | AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, | 679 | AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, |
684 | be_encoded_q_len(mccq->len)); | 680 | be_encoded_q_len(mccq->len)); |
@@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
727 | 723 | ||
728 | AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, | 724 | AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, |
729 | be_encoded_q_len(txq->len)); | 725 | be_encoded_q_len(txq->len)); |
730 | AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, | ||
731 | be_pci_func(adapter)); | ||
732 | AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); | 726 | AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); |
733 | AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); | 727 | AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); |
734 | 728 | ||
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 5ffb149181ad..2d4a4b827637 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -114,8 +114,7 @@ | |||
114 | #define IMG_TYPE_ISCSI_BACKUP 9 | 114 | #define IMG_TYPE_ISCSI_BACKUP 9 |
115 | #define IMG_TYPE_FCOE_FW_ACTIVE 10 | 115 | #define IMG_TYPE_FCOE_FW_ACTIVE 10 |
116 | #define IMG_TYPE_FCOE_FW_BACKUP 11 | 116 | #define IMG_TYPE_FCOE_FW_BACKUP 11 |
117 | #define IMG_TYPE_NCSI_BITFILE 13 | 117 | #define IMG_TYPE_NCSI_FW 13 |
118 | #define IMG_TYPE_NCSI_8051 14 | ||
119 | 118 | ||
120 | #define FLASHROM_OPER_FLASH 1 | 119 | #define FLASHROM_OPER_FLASH 1 |
121 | #define FLASHROM_OPER_SAVE 2 | 120 | #define FLASHROM_OPER_SAVE 2 |
@@ -127,6 +126,7 @@ | |||
127 | #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ | 126 | #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ |
128 | #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ | 127 | #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ |
129 | #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ | 128 | #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ |
129 | #define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */ | ||
130 | 130 | ||
131 | #define FLASH_NCSI_MAGIC (0x16032009) | 131 | #define FLASH_NCSI_MAGIC (0x16032009) |
132 | #define FLASH_NCSI_DISABLED (0) | 132 | #define FLASH_NCSI_DISABLED (0) |
@@ -144,6 +144,7 @@ | |||
144 | #define FLASH_FCoE_BIOS_START_g2 (524288) | 144 | #define FLASH_FCoE_BIOS_START_g2 (524288) |
145 | #define FLASH_REDBOOT_START_g2 (0) | 145 | #define FLASH_REDBOOT_START_g2 (0) |
146 | 146 | ||
147 | #define FLASH_NCSI_START_g3 (15990784) | ||
147 | #define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152) | 148 | #define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152) |
148 | #define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304) | 149 | #define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304) |
149 | #define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456) | 150 | #define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456) |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a703ed8e24fe..43e8032f9236 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1382,7 +1382,7 @@ rx_eq_free: | |||
1382 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ | 1382 | /* There are 8 evt ids per func. Retruns the evt id's bit number */ |
1383 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) | 1383 | static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) |
1384 | { | 1384 | { |
1385 | return eq_id - 8 * be_pci_func(adapter); | 1385 | return eq_id % 8; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | static irqreturn_t be_intx(int irq, void *dev) | 1388 | static irqreturn_t be_intx(int irq, void *dev) |
@@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter, | |||
1880 | const u8 *p = fw->data; | 1880 | const u8 *p = fw->data; |
1881 | struct be_cmd_write_flashrom *req = flash_cmd->va; | 1881 | struct be_cmd_write_flashrom *req = flash_cmd->va; |
1882 | struct flash_comp *pflashcomp; | 1882 | struct flash_comp *pflashcomp; |
1883 | int num_comp; | ||
1883 | 1884 | ||
1884 | struct flash_comp gen3_flash_types[8] = { | 1885 | struct flash_comp gen3_flash_types[9] = { |
1885 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, | 1886 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, |
1886 | FLASH_IMAGE_MAX_SIZE_g3}, | 1887 | FLASH_IMAGE_MAX_SIZE_g3}, |
1887 | { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, | 1888 | { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, |
@@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter, | |||
1897 | { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, | 1898 | { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, |
1898 | FLASH_IMAGE_MAX_SIZE_g3}, | 1899 | FLASH_IMAGE_MAX_SIZE_g3}, |
1899 | { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, | 1900 | { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, |
1900 | FLASH_IMAGE_MAX_SIZE_g3} | 1901 | FLASH_IMAGE_MAX_SIZE_g3}, |
1902 | { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, | ||
1903 | FLASH_NCSI_IMAGE_MAX_SIZE_g3} | ||
1901 | }; | 1904 | }; |
1902 | struct flash_comp gen2_flash_types[8] = { | 1905 | struct flash_comp gen2_flash_types[8] = { |
1903 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, | 1906 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, |
@@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter, | |||
1921 | if (adapter->generation == BE_GEN3) { | 1924 | if (adapter->generation == BE_GEN3) { |
1922 | pflashcomp = gen3_flash_types; | 1925 | pflashcomp = gen3_flash_types; |
1923 | filehdr_size = sizeof(struct flash_file_hdr_g3); | 1926 | filehdr_size = sizeof(struct flash_file_hdr_g3); |
1927 | num_comp = 9; | ||
1924 | } else { | 1928 | } else { |
1925 | pflashcomp = gen2_flash_types; | 1929 | pflashcomp = gen2_flash_types; |
1926 | filehdr_size = sizeof(struct flash_file_hdr_g2); | 1930 | filehdr_size = sizeof(struct flash_file_hdr_g2); |
1931 | num_comp = 8; | ||
1927 | } | 1932 | } |
1928 | for (i = 0; i < 8; i++) { | 1933 | for (i = 0; i < num_comp; i++) { |
1934 | if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && | ||
1935 | memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) | ||
1936 | continue; | ||
1929 | if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && | 1937 | if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && |
1930 | (!be_flash_redboot(adapter, fw->data, | 1938 | (!be_flash_redboot(adapter, fw->data, |
1931 | pflashcomp[i].offset, pflashcomp[i].size, | 1939 | pflashcomp[i].offset, pflashcomp[i].size, |
@@ -1985,16 +1993,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
1985 | struct be_dma_mem flash_cmd; | 1993 | struct be_dma_mem flash_cmd; |
1986 | int status, i = 0; | 1994 | int status, i = 0; |
1987 | const u8 *p; | 1995 | const u8 *p; |
1988 | char fw_ver[FW_VER_LEN]; | ||
1989 | char fw_cfg; | ||
1990 | |||
1991 | status = be_cmd_get_fw_ver(adapter, fw_ver); | ||
1992 | if (status) | ||
1993 | return status; | ||
1994 | 1996 | ||
1995 | fw_cfg = *(fw_ver + 2); | ||
1996 | if (fw_cfg == '0') | ||
1997 | fw_cfg = '1'; | ||
1998 | strcpy(fw_file, func); | 1997 | strcpy(fw_file, func); |
1999 | 1998 | ||
2000 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); | 1999 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5acd557cea9b..b8bec086daa1 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -51,7 +51,9 @@ | |||
51 | * "show" function for the bond_masters attribute. | 51 | * "show" function for the bond_masters attribute. |
52 | * The class parameter is ignored. | 52 | * The class parameter is ignored. |
53 | */ | 53 | */ |
54 | static ssize_t bonding_show_bonds(struct class *cls, char *buf) | 54 | static ssize_t bonding_show_bonds(struct class *cls, |
55 | struct class_attribute *attr, | ||
56 | char *buf) | ||
55 | { | 57 | { |
56 | struct net *net = current->nsproxy->net_ns; | 58 | struct net *net = current->nsproxy->net_ns; |
57 | struct bond_net *bn = net_generic(net, bond_net_id); | 59 | struct bond_net *bn = net_generic(net, bond_net_id); |
@@ -98,6 +100,7 @@ static struct net_device *bond_get_by_name(struct net *net, const char *ifname) | |||
98 | */ | 100 | */ |
99 | 101 | ||
100 | static ssize_t bonding_store_bonds(struct class *cls, | 102 | static ssize_t bonding_store_bonds(struct class *cls, |
103 | struct class_attribute *attr, | ||
101 | const char *buffer, size_t count) | 104 | const char *buffer, size_t count) |
102 | { | 105 | { |
103 | struct net *net = current->nsproxy->net_ns; | 106 | struct net *net = current->nsproxy->net_ns; |
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index bf7f9ba2d903..866905fa4119 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #define DRV_NAME "bfin_can" | 27 | #define DRV_NAME "bfin_can" |
28 | #define BFIN_CAN_TIMEOUT 100 | 28 | #define BFIN_CAN_TIMEOUT 100 |
29 | #define TX_ECHO_SKB_MAX 1 | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | * transmit and receive channels | 32 | * transmit and receive channels |
@@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void) | |||
593 | struct net_device *dev; | 594 | struct net_device *dev; |
594 | struct bfin_can_priv *priv; | 595 | struct bfin_can_priv *priv; |
595 | 596 | ||
596 | dev = alloc_candev(sizeof(*priv)); | 597 | dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); |
597 | if (!dev) | 598 | if (!dev) |
598 | return NULL; | 599 | return NULL; |
599 | 600 | ||
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 11c87840cc00..33451092b8e8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
@@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne | |||
876 | return NETDEV_TX_OK; | 876 | return NETDEV_TX_OK; |
877 | 877 | ||
878 | nomem: | 878 | nomem: |
879 | if (skb) | 879 | dev_kfree_skb(skb); |
880 | dev_kfree_skb(skb); | ||
881 | |||
882 | stats->tx_dropped++; | 880 | stats->tx_dropped++; |
883 | 881 | ||
884 | return NETDEV_TX_OK; | 882 | return NETDEV_TX_OK; |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7cbcfb0ade1c..9bd155e4111c 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, | |||
5072 | INIT_WORK(&cp->reset_task, cas_reset_task); | 5072 | INIT_WORK(&cp->reset_task, cas_reset_task); |
5073 | 5073 | ||
5074 | /* Default link parameters */ | 5074 | /* Default link parameters */ |
5075 | if (link_mode >= 0 && link_mode <= 6) | 5075 | if (link_mode >= 0 && link_mode < 6) |
5076 | cp->link_cntl = link_modes[link_mode]; | 5076 | cp->link_cntl = link_modes[link_mode]; |
5077 | else | 5077 | else |
5078 | cp->link_cntl = BMCR_ANENABLE; | 5078 | cp->link_cntl = BMCR_ANENABLE; |
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 71384114a4ed..55d99ca82f8a 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c | |||
@@ -248,7 +248,7 @@ static void restart_sched(unsigned long); | |||
248 | * | 248 | * |
249 | * Interrupts are handled by a single CPU and it is likely that on a MP system | 249 | * Interrupts are handled by a single CPU and it is likely that on a MP system |
250 | * the application is migrated to another CPU. In that scenario, we try to | 250 | * the application is migrated to another CPU. In that scenario, we try to |
251 | * seperate the RX(in irq context) and TX state in order to decrease memory | 251 | * separate the RX(in irq context) and TX state in order to decrease memory |
252 | * contention. | 252 | * contention. |
253 | */ | 253 | */ |
254 | struct sge { | 254 | struct sge { |
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index b85c81f60d10..60777fd90b33 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | 29 | ||
30 | #include <linux/netdevice.h> | 30 | #include <linux/netdevice.h> |
31 | #include <linux/if_vlan.h> | ||
31 | #include <linux/etherdevice.h> | 32 | #include <linux/etherdevice.h> |
32 | #include <linux/ethtool.h> | 33 | #include <linux/ethtool.h> |
33 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
@@ -55,9 +56,9 @@ module_param(dumb_switch, int, 0444); | |||
55 | MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); | 56 | MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); |
56 | MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); | 57 | MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); |
57 | 58 | ||
58 | #define CPMAC_VERSION "0.5.1" | 59 | #define CPMAC_VERSION "0.5.2" |
59 | /* frame size + 802.1q tag */ | 60 | /* frame size + 802.1q tag + FCS size */ |
60 | #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) | 61 | #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) |
61 | #define CPMAC_QUEUES 8 | 62 | #define CPMAC_QUEUES 8 |
62 | 63 | ||
63 | /* Ethernet registers */ | 64 | /* Ethernet registers */ |
@@ -1136,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1136 | } | 1137 | } |
1137 | 1138 | ||
1138 | if (phy_id == PHY_MAX_ADDR) { | 1139 | if (phy_id == PHY_MAX_ADDR) { |
1139 | dev_err(&pdev->dev, "no PHY present\n"); | 1140 | dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); |
1140 | return -ENODEV; | 1141 | strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ |
1142 | phy_id = pdev->id; | ||
1141 | } | 1143 | } |
1142 | 1144 | ||
1143 | dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); | 1145 | dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); |
@@ -1290,8 +1292,8 @@ void __devexit cpmac_exit(void) | |||
1290 | { | 1292 | { |
1291 | platform_driver_unregister(&cpmac_driver); | 1293 | platform_driver_unregister(&cpmac_driver); |
1292 | mdiobus_unregister(cpmac_mii); | 1294 | mdiobus_unregister(cpmac_mii); |
1293 | mdiobus_free(cpmac_mii); | ||
1294 | iounmap(cpmac_mii->priv); | 1295 | iounmap(cpmac_mii->priv); |
1296 | mdiobus_free(cpmac_mii); | ||
1295 | } | 1297 | } |
1296 | 1298 | ||
1297 | module_init(cpmac_init); | 1299 | module_init(cpmac_init); |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 14624019ce71..b0208e474f7e 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -580,7 +580,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) | |||
580 | } | 580 | } |
581 | 581 | ||
582 | #ifdef CONFIG_SH_HICOSH4 | 582 | #ifdef CONFIG_SH_HICOSH4 |
583 | /* truely reset the chip */ | 583 | /* truly reset the chip */ |
584 | writeword(ioaddr, ADD_PORT, 0x0114); | 584 | writeword(ioaddr, ADD_PORT, 0x0114); |
585 | writeword(ioaddr, DATA_PORT, 0x0040); | 585 | writeword(ioaddr, DATA_PORT, 0x0040); |
586 | #endif | 586 | #endif |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 3e453e1d97e7..9e3e8750b46a 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -1294,6 +1294,7 @@ static void cxgb_down(struct adapter *adapter) | |||
1294 | 1294 | ||
1295 | free_irq_resources(adapter); | 1295 | free_irq_resources(adapter); |
1296 | quiesce_rx(adapter); | 1296 | quiesce_rx(adapter); |
1297 | t3_sge_stop(adapter); | ||
1297 | flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ | 1298 | flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ |
1298 | } | 1299 | } |
1299 | 1300 | ||
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 78e265b484b6..67e61b2a8c42 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -197,13 +197,13 @@ static inline void refill_rspq(struct adapter *adapter, | |||
197 | /** | 197 | /** |
198 | * need_skb_unmap - does the platform need unmapping of sk_buffs? | 198 | * need_skb_unmap - does the platform need unmapping of sk_buffs? |
199 | * | 199 | * |
200 | * Returns true if the platfrom needs sk_buff unmapping. The compiler | 200 | * Returns true if the platform needs sk_buff unmapping. The compiler |
201 | * optimizes away unecessary code if this returns true. | 201 | * optimizes away unecessary code if this returns true. |
202 | */ | 202 | */ |
203 | static inline int need_skb_unmap(void) | 203 | static inline int need_skb_unmap(void) |
204 | { | 204 | { |
205 | /* | 205 | /* |
206 | * This structure is used to tell if the platfrom needs buffer | 206 | * This structure is used to tell if the platform needs buffer |
207 | * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything. | 207 | * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything. |
208 | */ | 208 | */ |
209 | struct dummy { | 209 | struct dummy { |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 1ac9440eb3fb..8bd086aee56d 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -2385,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev) | |||
2385 | struct emac_priv *priv = netdev_priv(ndev); | 2385 | struct emac_priv *priv = netdev_priv(ndev); |
2386 | 2386 | ||
2387 | netif_carrier_off(ndev); | 2387 | netif_carrier_off(ndev); |
2388 | for (cnt = 0; cnt <= ETH_ALEN; cnt++) | 2388 | for (cnt = 0; cnt < ETH_ALEN; cnt++) |
2389 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; | 2389 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; |
2390 | 2390 | ||
2391 | /* Configuration items */ | 2391 | /* Configuration items */ |
@@ -2658,7 +2658,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2658 | 2658 | ||
2659 | pdata = pdev->dev.platform_data; | 2659 | pdata = pdev->dev.platform_data; |
2660 | if (!pdata) { | 2660 | if (!pdata) { |
2661 | printk(KERN_ERR "DaVinci EMAC: No platfrom data\n"); | 2661 | printk(KERN_ERR "DaVinci EMAC: No platform data\n"); |
2662 | return -ENODEV; | 2662 | return -ENODEV; |
2663 | } | 2663 | } |
2664 | 2664 | ||
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 3c95acb3a87d..712ccc66ba25 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -1346,7 +1346,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) | |||
1346 | * | 1346 | * |
1347 | * 1) down | 1347 | * 1) down |
1348 | * 2) autoneg_progress | 1348 | * 2) autoneg_progress |
1349 | * 3) autoneg_complete (the link sucessfully autonegotiated) | 1349 | * 3) autoneg_complete (the link successfully autonegotiated) |
1350 | * 4) forced_up (the link has been forced up, it did not autonegotiate) | 1350 | * 4) forced_up (the link has been forced up, it did not autonegotiate) |
1351 | * | 1351 | * |
1352 | **/ | 1352 | **/ |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index db05ec355749..e301e26d6897 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -320,6 +320,8 @@ | |||
320 | #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ | 320 | #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ |
321 | 321 | ||
322 | /* Header split receive */ | 322 | /* Header split receive */ |
323 | #define E1000_RFCTL_NFSW_DIS 0x00000040 | ||
324 | #define E1000_RFCTL_NFSR_DIS 0x00000080 | ||
323 | #define E1000_RFCTL_ACK_DIS 0x00001000 | 325 | #define E1000_RFCTL_ACK_DIS 0x00001000 |
324 | #define E1000_RFCTL_EXTEN 0x00008000 | 326 | #define E1000_RFCTL_EXTEN 0x00008000 |
325 | #define E1000_RFCTL_IPV6_EX_DIS 0x00010000 | 327 | #define E1000_RFCTL_IPV6_EX_DIS 0x00010000 |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 54d03a0ce3ce..8b5e157e9c87 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) | |||
2740 | reg &= ~(1 << 31); | 2740 | reg &= ~(1 << 31); |
2741 | ew32(STATUS, reg); | 2741 | ew32(STATUS, reg); |
2742 | } | 2742 | } |
2743 | |||
2744 | /* | ||
2745 | * work-around descriptor data corruption issue during nfs v2 udp | ||
2746 | * traffic, just disable the nfs filtering capability | ||
2747 | */ | ||
2748 | reg = er32(RFCTL); | ||
2749 | reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); | ||
2750 | ew32(RFCTL, reg); | ||
2751 | |||
2752 | return; | ||
2743 | } | 2753 | } |
2744 | 2754 | ||
2745 | /** | 2755 | /** |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 2425ed11d5cc..a8b2c0de27c4 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -647,7 +647,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) | |||
647 | if (!(rxcw & E1000_RXCW_IV)) { | 647 | if (!(rxcw & E1000_RXCW_IV)) { |
648 | mac->serdes_has_link = true; | 648 | mac->serdes_has_link = true; |
649 | e_dbg("SERDES: Link up - autoneg " | 649 | e_dbg("SERDES: Link up - autoneg " |
650 | "completed sucessfully.\n"); | 650 | "completed successfully.\n"); |
651 | } else { | 651 | } else { |
652 | mac->serdes_has_link = false; | 652 | mac->serdes_has_link = false; |
653 | e_dbg("SERDES: Link down - invalid" | 653 | e_dbg("SERDES: Link down - invalid" |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 61a7b4351e78..b6715553cf17 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2021 | } | 2021 | } |
2022 | 2022 | ||
2023 | /* setup the TxBD length and buffer pointer for the first BD */ | 2023 | /* setup the TxBD length and buffer pointer for the first BD */ |
2024 | tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; | ||
2025 | txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, | 2024 | txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, |
2026 | skb_headlen(skb), DMA_TO_DEVICE); | 2025 | skb_headlen(skb), DMA_TO_DEVICE); |
2027 | 2026 | ||
@@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2053 | 2052 | ||
2054 | txbdp_start->lstatus = lstatus; | 2053 | txbdp_start->lstatus = lstatus; |
2055 | 2054 | ||
2055 | eieio(); /* force lstatus write before tx_skbuff */ | ||
2056 | |||
2057 | tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; | ||
2058 | |||
2056 | /* Update the current skb pointer to the next entry we will use | 2059 | /* Update the current skb pointer to the next entry we will use |
2057 | * (wrapping if necessary) */ | 2060 | * (wrapping if necessary) */ |
2058 | tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & | 2061 | tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index f2b937966950..0bc777bac9b4 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1577,7 +1577,7 @@ static struct attribute * veth_pool_attrs[] = { | |||
1577 | NULL, | 1577 | NULL, |
1578 | }; | 1578 | }; |
1579 | 1579 | ||
1580 | static struct sysfs_ops veth_pool_ops = { | 1580 | static const struct sysfs_ops veth_pool_ops = { |
1581 | .show = veth_pool_show, | 1581 | .show = veth_pool_show, |
1582 | .store = veth_pool_store, | 1582 | .store = veth_pool_store, |
1583 | }; | 1583 | }; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 583a21c1def3..0ed25f059a00 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -688,7 +688,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter) | |||
688 | /* start with one vector for every rx queue */ | 688 | /* start with one vector for every rx queue */ |
689 | numvecs = adapter->num_rx_queues; | 689 | numvecs = adapter->num_rx_queues; |
690 | 690 | ||
691 | /* if tx handler is seperate add 1 for every tx queue */ | 691 | /* if tx handler is separate add 1 for every tx queue */ |
692 | if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) | 692 | if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) |
693 | numvecs += adapter->num_tx_queues; | 693 | numvecs += adapter->num_tx_queues; |
694 | 694 | ||
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index e8e33bb9d876..2c9b3af16612 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf, | |||
1651 | 1651 | ||
1652 | self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), | 1652 | self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), |
1653 | GFP_KERNEL); | 1653 | GFP_KERNEL); |
1654 | if (!self->rx_urb) | ||
1655 | goto err_free_net; | ||
1654 | 1656 | ||
1655 | for (i = 0; i < self->max_rx_urb; i++) { | 1657 | for (i = 0; i < self->max_rx_urb; i++) { |
1656 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); | 1658 | self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); |
@@ -1783,6 +1785,8 @@ err_out_2: | |||
1783 | err_out_1: | 1785 | err_out_1: |
1784 | for (i = 0; i < self->max_rx_urb; i++) | 1786 | for (i = 0; i < self->max_rx_urb; i++) |
1785 | usb_free_urb(self->rx_urb[i]); | 1787 | usb_free_urb(self->rx_urb[i]); |
1788 | kfree(self->rx_urb); | ||
1789 | err_free_net: | ||
1786 | free_netdev(net); | 1790 | free_netdev(net); |
1787 | err_out: | 1791 | err_out: |
1788 | return ret; | 1792 | return ret; |
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index c412e8026173..1dcdce0631aa 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c | |||
@@ -331,7 +331,7 @@ static int sa1100_irda_resume(struct platform_device *pdev) | |||
331 | * If we missed a speed change, initialise at the new speed | 331 | * If we missed a speed change, initialise at the new speed |
332 | * directly. It is debatable whether this is actually | 332 | * directly. It is debatable whether this is actually |
333 | * required, but in the interests of continuing from where | 333 | * required, but in the interests of continuing from where |
334 | * we left off it is desireable. The converse argument is | 334 | * we left off it is desirable. The converse argument is |
335 | * that we should re-negotiate at 9600 baud again. | 335 | * that we should re-negotiate at 9600 baud again. |
336 | */ | 336 | */ |
337 | if (si->newspeed) { | 337 | if (si->newspeed) { |
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 966de5d69521..e6e972d9b7ca 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -384,7 +384,7 @@ static struct attribute *veth_cnx_default_attrs[] = { | |||
384 | NULL | 384 | NULL |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static struct sysfs_ops veth_cnx_sysfs_ops = { | 387 | static const struct sysfs_ops veth_cnx_sysfs_ops = { |
388 | .show = veth_cnx_attribute_show | 388 | .show = veth_cnx_attribute_show |
389 | }; | 389 | }; |
390 | 390 | ||
@@ -441,7 +441,7 @@ static struct attribute *veth_port_default_attrs[] = { | |||
441 | NULL | 441 | NULL |
442 | }; | 442 | }; |
443 | 443 | ||
444 | static struct sysfs_ops veth_port_sysfs_ops = { | 444 | static const struct sysfs_ops veth_port_sysfs_ops = { |
445 | .show = veth_port_attribute_show | 445 | .show = veth_port_attribute_show |
446 | }; | 446 | }; |
447 | 447 | ||
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index b5219cce12ed..0573e0bb4444 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c | |||
@@ -407,7 +407,7 @@ static irqreturn_t ks8851_irq(int irq, void *pw) | |||
407 | * @buff: The buffer address | 407 | * @buff: The buffer address |
408 | * @len: The length of the data to read | 408 | * @len: The length of the data to read |
409 | * | 409 | * |
410 | * Issue an RXQ FIFO read command and read the @len ammount of data from | 410 | * Issue an RXQ FIFO read command and read the @len amount of data from |
411 | * the FIFO into the buffer specified by @buff. | 411 | * the FIFO into the buffer specified by @buff. |
412 | */ | 412 | */ |
413 | static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) | 413 | static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) |
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index b40a851ec7d1..0da94b208db1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -423,6 +423,11 @@ struct qlcnic_adapter_stats { | |||
423 | u64 lro_pkts; | 423 | u64 lro_pkts; |
424 | u64 rxbytes; | 424 | u64 rxbytes; |
425 | u64 txbytes; | 425 | u64 txbytes; |
426 | u64 lrobytes; | ||
427 | u64 lso_frames; | ||
428 | u64 xmit_on; | ||
429 | u64 xmit_off; | ||
430 | u64 skb_alloc_failure; | ||
426 | }; | 431 | }; |
427 | 432 | ||
428 | /* | 433 | /* |
@@ -1095,11 +1100,11 @@ struct qlcnic_brdinfo { | |||
1095 | 1100 | ||
1096 | static const struct qlcnic_brdinfo qlcnic_boards[] = { | 1101 | static const struct qlcnic_brdinfo qlcnic_boards[] = { |
1097 | {0x1077, 0x8020, 0x1077, 0x203, | 1102 | {0x1077, 0x8020, 0x1077, 0x203, |
1098 | "8200 Series Single Port 10GbE Converged Network Adapter \ | 1103 | "8200 Series Single Port 10GbE Converged Network Adapter " |
1099 | (TCP/IP Networking)"}, | 1104 | "(TCP/IP Networking)"}, |
1100 | {0x1077, 0x8020, 0x1077, 0x207, | 1105 | {0x1077, 0x8020, 0x1077, 0x207, |
1101 | "8200 Series Dual Port 10GbE Converged Network Adapter \ | 1106 | "8200 Series Dual Port 10GbE Converged Network Adapter " |
1102 | (TCP/IP Networking)"}, | 1107 | "(TCP/IP Networking)"}, |
1103 | {0x1077, 0x8020, 0x1077, 0x20b, | 1108 | {0x1077, 0x8020, 0x1077, 0x20b, |
1104 | "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, | 1109 | "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, |
1105 | {0x1077, 0x8020, 0x1077, 0x20c, | 1110 | {0x1077, 0x8020, 0x1077, 0x20c, |
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 8da6ec8c13b9..f83e15fe3e1b 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c | |||
@@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { | |||
59 | QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, | 59 | QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, |
60 | {"tx_bytes", | 60 | {"tx_bytes", |
61 | QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, | 61 | QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, |
62 | {"lrobytes", | ||
63 | QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)}, | ||
64 | {"lso_frames", | ||
65 | QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)}, | ||
66 | {"xmit_on", | ||
67 | QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)}, | ||
68 | {"xmit_off", | ||
69 | QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)}, | ||
70 | {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), | ||
71 | QLC_OFF(stats.skb_alloc_failure)}, | ||
72 | |||
62 | }; | 73 | }; |
63 | 74 | ||
64 | #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) | 75 | #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) |
@@ -785,6 +796,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev, | |||
785 | } | 796 | } |
786 | } | 797 | } |
787 | 798 | ||
799 | static u32 qlcnic_get_tx_csum(struct net_device *dev) | ||
800 | { | ||
801 | return dev->features & NETIF_F_IP_CSUM; | ||
802 | } | ||
803 | |||
788 | static u32 qlcnic_get_rx_csum(struct net_device *dev) | 804 | static u32 qlcnic_get_rx_csum(struct net_device *dev) |
789 | { | 805 | { |
790 | struct qlcnic_adapter *adapter = netdev_priv(dev); | 806 | struct qlcnic_adapter *adapter = netdev_priv(dev); |
@@ -995,6 +1011,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { | |||
995 | .set_ringparam = qlcnic_set_ringparam, | 1011 | .set_ringparam = qlcnic_set_ringparam, |
996 | .get_pauseparam = qlcnic_get_pauseparam, | 1012 | .get_pauseparam = qlcnic_get_pauseparam, |
997 | .set_pauseparam = qlcnic_set_pauseparam, | 1013 | .set_pauseparam = qlcnic_set_pauseparam, |
1014 | .get_tx_csum = qlcnic_get_tx_csum, | ||
998 | .set_tx_csum = ethtool_op_set_tx_csum, | 1015 | .set_tx_csum = ethtool_op_set_tx_csum, |
999 | .set_sg = ethtool_op_set_sg, | 1016 | .set_sg = ethtool_op_set_sg, |
1000 | .get_tso = qlcnic_get_tso, | 1017 | .get_tso = qlcnic_get_tso, |
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 99a4d1379d00..da00e162b6d3 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, | |||
349 | if (nr_desc >= qlcnic_tx_avail(tx_ring)) { | 349 | if (nr_desc >= qlcnic_tx_avail(tx_ring)) { |
350 | netif_tx_stop_queue(tx_ring->txq); | 350 | netif_tx_stop_queue(tx_ring->txq); |
351 | __netif_tx_unlock_bh(tx_ring->txq); | 351 | __netif_tx_unlock_bh(tx_ring->txq); |
352 | adapter->stats.xmit_off++; | ||
352 | return -EBUSY; | 353 | return -EBUSY; |
353 | } | 354 | } |
354 | 355 | ||
@@ -397,20 +398,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | |||
397 | return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | 398 | return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
398 | } | 399 | } |
399 | 400 | ||
400 | static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, | 401 | static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) |
401 | u8 *addr, struct list_head *del_list) | ||
402 | { | 402 | { |
403 | struct list_head *head; | 403 | struct list_head *head; |
404 | struct qlcnic_mac_list_s *cur; | 404 | struct qlcnic_mac_list_s *cur; |
405 | 405 | ||
406 | /* look up if already exists */ | 406 | /* look up if already exists */ |
407 | list_for_each(head, del_list) { | 407 | list_for_each(head, &adapter->mac_list) { |
408 | cur = list_entry(head, struct qlcnic_mac_list_s, list); | 408 | cur = list_entry(head, struct qlcnic_mac_list_s, list); |
409 | 409 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) | |
410 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { | ||
411 | list_move_tail(head, &adapter->mac_list); | ||
412 | return 0; | 410 | return 0; |
413 | } | ||
414 | } | 411 | } |
415 | 412 | ||
416 | cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); | 413 | cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); |
@@ -432,14 +429,9 @@ void qlcnic_set_multi(struct net_device *netdev) | |||
432 | struct dev_mc_list *mc_ptr; | 429 | struct dev_mc_list *mc_ptr; |
433 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 430 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
434 | u32 mode = VPORT_MISS_MODE_DROP; | 431 | u32 mode = VPORT_MISS_MODE_DROP; |
435 | LIST_HEAD(del_list); | ||
436 | struct list_head *head; | ||
437 | struct qlcnic_mac_list_s *cur; | ||
438 | 432 | ||
439 | list_splice_tail_init(&adapter->mac_list, &del_list); | 433 | qlcnic_nic_add_mac(adapter, adapter->mac_addr); |
440 | 434 | qlcnic_nic_add_mac(adapter, bcast_addr); | |
441 | qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list); | ||
442 | qlcnic_nic_add_mac(adapter, bcast_addr, &del_list); | ||
443 | 435 | ||
444 | if (netdev->flags & IFF_PROMISC) { | 436 | if (netdev->flags & IFF_PROMISC) { |
445 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | 437 | mode = VPORT_MISS_MODE_ACCEPT_ALL; |
@@ -454,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev) | |||
454 | 446 | ||
455 | if (!netdev_mc_empty(netdev)) { | 447 | if (!netdev_mc_empty(netdev)) { |
456 | netdev_for_each_mc_addr(mc_ptr, netdev) { | 448 | netdev_for_each_mc_addr(mc_ptr, netdev) { |
457 | qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr, | 449 | qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr); |
458 | &del_list); | ||
459 | } | 450 | } |
460 | } | 451 | } |
461 | 452 | ||
462 | send_fw_cmd: | 453 | send_fw_cmd: |
463 | qlcnic_nic_set_promisc(adapter, mode); | 454 | qlcnic_nic_set_promisc(adapter, mode); |
464 | head = &del_list; | ||
465 | while (!list_empty(head)) { | ||
466 | cur = list_entry(head->next, struct qlcnic_mac_list_s, list); | ||
467 | |||
468 | qlcnic_sre_macaddr_change(adapter, | ||
469 | cur->mac_addr, QLCNIC_MAC_DEL); | ||
470 | list_del(&cur->list); | ||
471 | kfree(cur); | ||
472 | } | ||
473 | } | 455 | } |
474 | 456 | ||
475 | int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | 457 | int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) |
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index ea00ab4d4feb..7c34e4e29b3f 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section) | |||
568 | return NULL; | 568 | return NULL; |
569 | } | 569 | } |
570 | 570 | ||
571 | #define FILEHEADER_SIZE (14 * 4) | ||
572 | |||
571 | static int | 573 | static int |
572 | qlcnic_set_product_offs(struct qlcnic_adapter *adapter) | 574 | qlcnic_validate_header(struct qlcnic_adapter *adapter) |
573 | { | 575 | { |
574 | struct uni_table_desc *ptab_descr; | ||
575 | const u8 *unirom = adapter->fw->data; | 576 | const u8 *unirom = adapter->fw->data; |
576 | u32 i; | 577 | struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; |
578 | __le32 fw_file_size = adapter->fw->size; | ||
577 | __le32 entries; | 579 | __le32 entries; |
580 | __le32 entry_size; | ||
581 | __le32 tab_size; | ||
582 | |||
583 | if (fw_file_size < FILEHEADER_SIZE) | ||
584 | return -EINVAL; | ||
585 | |||
586 | entries = cpu_to_le32(directory->num_entries); | ||
587 | entry_size = cpu_to_le32(directory->entry_size); | ||
588 | tab_size = cpu_to_le32(directory->findex) + (entries * entry_size); | ||
589 | |||
590 | if (fw_file_size < tab_size) | ||
591 | return -EINVAL; | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int | ||
597 | qlcnic_validate_bootld(struct qlcnic_adapter *adapter) | ||
598 | { | ||
599 | struct uni_table_desc *tab_desc; | ||
600 | struct uni_data_desc *descr; | ||
601 | const u8 *unirom = adapter->fw->data; | ||
602 | int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + | ||
603 | QLCNIC_UNI_BOOTLD_IDX_OFF)); | ||
604 | __le32 offs; | ||
605 | __le32 tab_size; | ||
606 | __le32 data_size; | ||
607 | |||
608 | tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD); | ||
609 | |||
610 | if (!tab_desc) | ||
611 | return -EINVAL; | ||
612 | |||
613 | tab_size = cpu_to_le32(tab_desc->findex) + | ||
614 | (cpu_to_le32(tab_desc->entry_size * (idx + 1))); | ||
615 | |||
616 | if (adapter->fw->size < tab_size) | ||
617 | return -EINVAL; | ||
618 | |||
619 | offs = cpu_to_le32(tab_desc->findex) + | ||
620 | (cpu_to_le32(tab_desc->entry_size) * (idx)); | ||
621 | descr = (struct uni_data_desc *)&unirom[offs]; | ||
622 | |||
623 | data_size = descr->findex + cpu_to_le32(descr->size); | ||
624 | |||
625 | if (adapter->fw->size < data_size) | ||
626 | return -EINVAL; | ||
627 | |||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static int | ||
632 | qlcnic_validate_fw(struct qlcnic_adapter *adapter) | ||
633 | { | ||
634 | struct uni_table_desc *tab_desc; | ||
635 | struct uni_data_desc *descr; | ||
636 | const u8 *unirom = adapter->fw->data; | ||
637 | int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + | ||
638 | QLCNIC_UNI_FIRMWARE_IDX_OFF)); | ||
639 | __le32 offs; | ||
640 | __le32 tab_size; | ||
641 | __le32 data_size; | ||
642 | |||
643 | tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW); | ||
644 | |||
645 | if (!tab_desc) | ||
646 | return -EINVAL; | ||
647 | |||
648 | tab_size = cpu_to_le32(tab_desc->findex) + | ||
649 | (cpu_to_le32(tab_desc->entry_size * (idx + 1))); | ||
650 | |||
651 | if (adapter->fw->size < tab_size) | ||
652 | return -EINVAL; | ||
653 | |||
654 | offs = cpu_to_le32(tab_desc->findex) + | ||
655 | (cpu_to_le32(tab_desc->entry_size) * (idx)); | ||
656 | descr = (struct uni_data_desc *)&unirom[offs]; | ||
657 | data_size = descr->findex + cpu_to_le32(descr->size); | ||
658 | |||
659 | if (adapter->fw->size < data_size) | ||
660 | return -EINVAL; | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static int | ||
666 | qlcnic_validate_product_offs(struct qlcnic_adapter *adapter) | ||
667 | { | ||
668 | struct uni_table_desc *ptab_descr; | ||
669 | const u8 *unirom = adapter->fw->data; | ||
578 | int mn_present = qlcnic_has_mn(adapter); | 670 | int mn_present = qlcnic_has_mn(adapter); |
671 | __le32 entries; | ||
672 | __le32 entry_size; | ||
673 | __le32 tab_size; | ||
674 | u32 i; | ||
579 | 675 | ||
580 | ptab_descr = qlcnic_get_table_desc(unirom, | 676 | ptab_descr = qlcnic_get_table_desc(unirom, |
581 | QLCNIC_UNI_DIR_SECT_PRODUCT_TBL); | 677 | QLCNIC_UNI_DIR_SECT_PRODUCT_TBL); |
582 | if (ptab_descr == NULL) | 678 | if (!ptab_descr) |
583 | return -1; | 679 | return -EINVAL; |
584 | 680 | ||
585 | entries = cpu_to_le32(ptab_descr->num_entries); | 681 | entries = cpu_to_le32(ptab_descr->num_entries); |
682 | entry_size = cpu_to_le32(ptab_descr->entry_size); | ||
683 | tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size); | ||
684 | |||
685 | if (adapter->fw->size < tab_size) | ||
686 | return -EINVAL; | ||
687 | |||
586 | nomn: | 688 | nomn: |
587 | for (i = 0; i < entries; i++) { | 689 | for (i = 0; i < entries; i++) { |
588 | 690 | ||
@@ -609,7 +711,37 @@ nomn: | |||
609 | mn_present = 0; | 711 | mn_present = 0; |
610 | goto nomn; | 712 | goto nomn; |
611 | } | 713 | } |
612 | return -1; | 714 | return -EINVAL; |
715 | } | ||
716 | |||
717 | static int | ||
718 | qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter) | ||
719 | { | ||
720 | if (qlcnic_validate_header(adapter)) { | ||
721 | dev_err(&adapter->pdev->dev, | ||
722 | "unified image: header validation failed\n"); | ||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | if (qlcnic_validate_product_offs(adapter)) { | ||
727 | dev_err(&adapter->pdev->dev, | ||
728 | "unified image: product validation failed\n"); | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | |||
732 | if (qlcnic_validate_bootld(adapter)) { | ||
733 | dev_err(&adapter->pdev->dev, | ||
734 | "unified image: bootld validation failed\n"); | ||
735 | return -EINVAL; | ||
736 | } | ||
737 | |||
738 | if (qlcnic_validate_fw(adapter)) { | ||
739 | dev_err(&adapter->pdev->dev, | ||
740 | "unified image: firmware validation failed\n"); | ||
741 | return -EINVAL; | ||
742 | } | ||
743 | |||
744 | return 0; | ||
613 | } | 745 | } |
614 | 746 | ||
615 | static | 747 | static |
@@ -715,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) | |||
715 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) | 847 | bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) |
716 | + QLCNIC_UNI_BIOS_VERSION_OFF)); | 848 | + QLCNIC_UNI_BIOS_VERSION_OFF)); |
717 | 849 | ||
718 | return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); | 850 | return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); |
719 | } | 851 | } |
720 | 852 | ||
721 | int | 853 | int |
@@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) | |||
858 | u8 fw_type = adapter->fw_type; | 990 | u8 fw_type = adapter->fw_type; |
859 | 991 | ||
860 | if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) { | 992 | if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) { |
861 | if (qlcnic_set_product_offs(adapter)) | 993 | if (qlcnic_validate_unified_romimage(adapter)) |
862 | return -EINVAL; | 994 | return -EINVAL; |
863 | 995 | ||
864 | min_size = QLCNIC_UNI_FW_MIN_SIZE; | 996 | min_size = QLCNIC_UNI_FW_MIN_SIZE; |
@@ -1114,8 +1246,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, | |||
1114 | struct pci_dev *pdev = adapter->pdev; | 1246 | struct pci_dev *pdev = adapter->pdev; |
1115 | 1247 | ||
1116 | buffer->skb = dev_alloc_skb(rds_ring->skb_size); | 1248 | buffer->skb = dev_alloc_skb(rds_ring->skb_size); |
1117 | if (!buffer->skb) | 1249 | if (!buffer->skb) { |
1250 | adapter->stats.skb_alloc_failure++; | ||
1118 | return -ENOMEM; | 1251 | return -ENOMEM; |
1252 | } | ||
1119 | 1253 | ||
1120 | skb = buffer->skb; | 1254 | skb = buffer->skb; |
1121 | 1255 | ||
@@ -1289,7 +1423,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1289 | netif_receive_skb(skb); | 1423 | netif_receive_skb(skb); |
1290 | 1424 | ||
1291 | adapter->stats.lro_pkts++; | 1425 | adapter->stats.lro_pkts++; |
1292 | adapter->stats.rxbytes += length; | 1426 | adapter->stats.lrobytes += length; |
1293 | 1427 | ||
1294 | return buffer; | 1428 | return buffer; |
1295 | } | 1429 | } |
@@ -1505,6 +1639,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, | |||
1505 | adapter->diag_cnt++; | 1639 | adapter->diag_cnt++; |
1506 | 1640 | ||
1507 | dev_kfree_skb_any(skb); | 1641 | dev_kfree_skb_any(skb); |
1642 | adapter->stats.rx_pkts++; | ||
1643 | adapter->stats.rxbytes += length; | ||
1508 | 1644 | ||
1509 | return buffer; | 1645 | return buffer; |
1510 | } | 1646 | } |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 665e8e56b6a8..fc721564e69e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, | |||
118 | if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { | 118 | if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { |
119 | netif_stop_queue(adapter->netdev); | 119 | netif_stop_queue(adapter->netdev); |
120 | smp_mb(); | 120 | smp_mb(); |
121 | adapter->stats.xmit_off++; | ||
121 | } | 122 | } |
122 | } | 123 | } |
123 | 124 | ||
@@ -1385,6 +1386,7 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1385 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | 1386 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; |
1386 | struct cmd_desc_type0 *hwdesc; | 1387 | struct cmd_desc_type0 *hwdesc; |
1387 | struct vlan_ethhdr *vh; | 1388 | struct vlan_ethhdr *vh; |
1389 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1388 | 1390 | ||
1389 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | 1391 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { |
1390 | 1392 | ||
@@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1494 | 1496 | ||
1495 | tx_ring->producer = producer; | 1497 | tx_ring->producer = producer; |
1496 | barrier(); | 1498 | barrier(); |
1499 | adapter->stats.lso_frames++; | ||
1497 | } | 1500 | } |
1498 | 1501 | ||
1499 | static int | 1502 | static int |
@@ -1573,6 +1576,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1573 | 1576 | ||
1574 | if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { | 1577 | if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { |
1575 | netif_stop_queue(netdev); | 1578 | netif_stop_queue(netdev); |
1579 | adapter->stats.xmit_off++; | ||
1576 | return NETDEV_TX_BUSY; | 1580 | return NETDEV_TX_BUSY; |
1577 | } | 1581 | } |
1578 | 1582 | ||
@@ -1880,6 +1884,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) | |||
1880 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { | 1884 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { |
1881 | netif_wake_queue(netdev); | 1885 | netif_wake_queue(netdev); |
1882 | adapter->tx_timeo_cnt = 0; | 1886 | adapter->tx_timeo_cnt = 0; |
1887 | adapter->stats.xmit_on++; | ||
1883 | } | 1888 | } |
1884 | __netif_tx_unlock(tx_ring->txq); | 1889 | __netif_tx_unlock(tx_ring->txq); |
1885 | } | 1890 | } |
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 05b8bde9980d..7dbff87480dc 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c | |||
@@ -405,7 +405,7 @@ static int ql_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) | |||
405 | u32 wol = 0; | 405 | u32 wol = 0; |
406 | status = ql_mb_wol_mode(qdev, wol); | 406 | status = ql_mb_wol_mode(qdev, wol); |
407 | netif_err(qdev, drv, qdev->ndev, "WOL %s (wol code 0x%x)\n", | 407 | netif_err(qdev, drv, qdev->ndev, "WOL %s (wol code 0x%x)\n", |
408 | status == 0 ? "cleared sucessfully" : "clear failed", | 408 | status == 0 ? "cleared successfully" : "clear failed", |
409 | wol); | 409 | wol); |
410 | } | 410 | } |
411 | 411 | ||
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index c26ec5d740f6..fd34f266c0a8 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -3855,7 +3855,7 @@ int ql_wol(struct ql_adapter *qdev) | |||
3855 | status = ql_mb_wol_mode(qdev, wol); | 3855 | status = ql_mb_wol_mode(qdev, wol); |
3856 | netif_err(qdev, drv, qdev->ndev, | 3856 | netif_err(qdev, drv, qdev->ndev, |
3857 | "WOL %s (wol code 0x%x) on %s\n", | 3857 | "WOL %s (wol code 0x%x) on %s\n", |
3858 | (status == 0) ? "Sucessfully set" : "Failed", | 3858 | (status == 0) ? "Successfully set" : "Failed", |
3859 | wol, qdev->ndev->name); | 3859 | wol, qdev->ndev->name); |
3860 | } | 3860 | } |
3861 | 3861 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index dfc3573c91bb..9d3ebf3e975e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
4270 | 4270 | ||
4271 | tp->cur_tx += frags + 1; | 4271 | tp->cur_tx += frags + 1; |
4272 | 4272 | ||
4273 | smp_wmb(); | 4273 | wmb(); |
4274 | 4274 | ||
4275 | RTL_W8(TxPoll, NPQ); /* set polling bit */ | 4275 | RTL_W8(TxPoll, NPQ); /* set polling bit */ |
4276 | 4276 | ||
@@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) | |||
4621 | * until it does. | 4621 | * until it does. |
4622 | */ | 4622 | */ |
4623 | tp->intr_mask = 0xffff; | 4623 | tp->intr_mask = 0xffff; |
4624 | smp_wmb(); | 4624 | wmb(); |
4625 | RTL_W16(IntrMask, tp->intr_event); | 4625 | RTL_W16(IntrMask, tp->intr_event); |
4626 | } | 4626 | } |
4627 | 4627 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 43bc66aa8405..df70657260dd 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
923 | tmp_v_addr = mac_control->stats_mem; | 923 | tmp_v_addr = mac_control->stats_mem; |
924 | mac_control->stats_info = (struct stat_block *)tmp_v_addr; | 924 | mac_control->stats_info = (struct stat_block *)tmp_v_addr; |
925 | memset(tmp_v_addr, 0, size); | 925 | memset(tmp_v_addr, 0, size); |
926 | DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name, | 926 | DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", |
927 | (unsigned long long)tmp_p_addr); | 927 | dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr); |
928 | mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; | 928 | mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; |
929 | return SUCCESS; | 929 | return SUCCESS; |
930 | } | 930 | } |
@@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp) | |||
3480 | struct swStat *swstats; | 3480 | struct swStat *swstats; |
3481 | 3481 | ||
3482 | DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n", | 3482 | DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n", |
3483 | __func__, sp->dev->name); | 3483 | __func__, pci_name(sp->pdev)); |
3484 | 3484 | ||
3485 | /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ | 3485 | /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ |
3486 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); | 3486 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); |
diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 89d606fe9248..18a3be428348 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h | |||
@@ -95,7 +95,7 @@ | |||
95 | #define FRF_AA_INT_ACK_KER_FIELD_LBN 0 | 95 | #define FRF_AA_INT_ACK_KER_FIELD_LBN 0 |
96 | #define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32 | 96 | #define FRF_AA_INT_ACK_KER_FIELD_WIDTH 32 |
97 | 97 | ||
98 | /* INT_ISR0_REG: Function 0 Interrupt Acknowlege Status register */ | 98 | /* INT_ISR0_REG: Function 0 Interrupt Acknowledge Status register */ |
99 | #define FR_BZ_INT_ISR0 0x00000090 | 99 | #define FR_BZ_INT_ISR0 0x00000090 |
100 | #define FRF_BZ_INT_ISR_REG_LBN 0 | 100 | #define FRF_BZ_INT_ISR_REG_LBN 0 |
101 | #define FRF_BZ_INT_ISR_REG_WIDTH 64 | 101 | #define FRF_BZ_INT_ISR_REG_WIDTH 64 |
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c index a85efcfd9d0e..e8387d25f24a 100644 --- a/drivers/net/skfp/ess.c +++ b/drivers/net/skfp/ess.c | |||
@@ -557,7 +557,7 @@ static void ess_send_alc_req(struct s_smc *smc) | |||
557 | 557 | ||
558 | /* | 558 | /* |
559 | * send never allocation request where the requested payload and | 559 | * send never allocation request where the requested payload and |
560 | * overhead is zero or deallocate bandwidht when no bandwidth is | 560 | * overhead is zero or deallocate bandwidth when no bandwidth is |
561 | * parsed | 561 | * parsed |
562 | */ | 562 | */ |
563 | if (!smc->mib.fddiESSPayload) { | 563 | if (!smc->mib.fddiESSPayload) { |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 653bdd76ef46..d8ec4c11fd49 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -4863,6 +4863,7 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4863 | if (!hw) | 4863 | if (!hw) |
4864 | return 0; | 4864 | return 0; |
4865 | 4865 | ||
4866 | rtnl_lock(); | ||
4866 | err = pci_set_power_state(pdev, PCI_D0); | 4867 | err = pci_set_power_state(pdev, PCI_D0); |
4867 | if (err) | 4868 | if (err) |
4868 | goto out; | 4869 | goto out; |
@@ -4884,7 +4885,6 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4884 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 4885 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
4885 | napi_enable(&hw->napi); | 4886 | napi_enable(&hw->napi); |
4886 | 4887 | ||
4887 | rtnl_lock(); | ||
4888 | for (i = 0; i < hw->ports; i++) { | 4888 | for (i = 0; i < hw->ports; i++) { |
4889 | err = sky2_reattach(hw->dev[i]); | 4889 | err = sky2_reattach(hw->dev[i]); |
4890 | if (err) | 4890 | if (err) |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 54799544bda3..8d2772cc42f2 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -330,6 +330,48 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, | |||
330 | 330 | ||
331 | #include <unit/smc91111.h> | 331 | #include <unit/smc91111.h> |
332 | 332 | ||
333 | #elif defined(CONFIG_ARCH_MSM) | ||
334 | |||
335 | #define SMC_CAN_USE_8BIT 0 | ||
336 | #define SMC_CAN_USE_16BIT 1 | ||
337 | #define SMC_CAN_USE_32BIT 0 | ||
338 | #define SMC_NOWAIT 1 | ||
339 | |||
340 | #define SMC_inw(a, r) readw((a) + (r)) | ||
341 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | ||
342 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | ||
343 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | ||
344 | |||
345 | #define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH | ||
346 | |||
347 | #elif defined(CONFIG_COLDFIRE) | ||
348 | |||
349 | #define SMC_CAN_USE_8BIT 0 | ||
350 | #define SMC_CAN_USE_16BIT 1 | ||
351 | #define SMC_CAN_USE_32BIT 0 | ||
352 | #define SMC_NOWAIT 1 | ||
353 | |||
354 | static inline void mcf_insw(void *a, unsigned char *p, int l) | ||
355 | { | ||
356 | u16 *wp = (u16 *) p; | ||
357 | while (l-- > 0) | ||
358 | *wp++ = readw(a); | ||
359 | } | ||
360 | |||
361 | static inline void mcf_outsw(void *a, unsigned char *p, int l) | ||
362 | { | ||
363 | u16 *wp = (u16 *) p; | ||
364 | while (l-- > 0) | ||
365 | writew(*wp++, a); | ||
366 | } | ||
367 | |||
368 | #define SMC_inw(a, r) _swapw(readw((a) + (r))) | ||
369 | #define SMC_outw(v, a, r) writew(_swapw(v), (a) + (r)) | ||
370 | #define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l) | ||
371 | #define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l) | ||
372 | |||
373 | #define SMC_IRQ_FLAGS (IRQF_DISABLED) | ||
374 | |||
333 | #else | 375 | #else |
334 | 376 | ||
335 | /* | 377 | /* |
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 30110a11d737..34fa10d8ad40 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c | |||
@@ -1347,7 +1347,7 @@ static int smsc9420_open(struct net_device *dev) | |||
1347 | 1347 | ||
1348 | netif_carrier_off(dev); | 1348 | netif_carrier_off(dev); |
1349 | 1349 | ||
1350 | /* disable, mask and acknowlege all interrupts */ | 1350 | /* disable, mask and acknowledge all interrupts */ |
1351 | spin_lock_irqsave(&pd->int_lock, flags); | 1351 | spin_lock_irqsave(&pd->int_lock, flags); |
1352 | int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_); | 1352 | int_cfg = smsc9420_reg_read(pd, INT_CFG) & (~INT_CFG_IRQ_EN_); |
1353 | smsc9420_reg_write(pd, INT_CFG, int_cfg); | 1353 | smsc9420_reg_write(pd, INT_CFG, int_cfg); |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 2f8a8c32021e..5ba9d989f8fc 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -474,7 +474,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
474 | * spider_net_enable_rxchtails - sets RX dmac chain tail addresses | 474 | * spider_net_enable_rxchtails - sets RX dmac chain tail addresses |
475 | * @card: card structure | 475 | * @card: card structure |
476 | * | 476 | * |
477 | * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the | 477 | * spider_net_enable_rxchtails sets the RX DMAC chain tail addresses in the |
478 | * chip by writing to the appropriate register. DMA is enabled in | 478 | * chip by writing to the appropriate register. DMA is enabled in |
479 | * spider_net_enable_rxdmac. | 479 | * spider_net_enable_rxdmac. |
480 | */ | 480 | */ |
@@ -1820,7 +1820,7 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1820 | 1820 | ||
1821 | spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); | 1821 | spider_net_write_reg(card, SPIDER_NET_ECMODE, SPIDER_NET_ECMODE_VALUE); |
1822 | 1822 | ||
1823 | /* set chain tail adress for RX chains and | 1823 | /* set chain tail address for RX chains and |
1824 | * enable DMA */ | 1824 | * enable DMA */ |
1825 | spider_net_enable_rxchtails(card); | 1825 | spider_net_enable_rxchtails(card); |
1826 | spider_net_enable_rxdmac(card); | 1826 | spider_net_enable_rxdmac(card); |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 4344017bfaef..70196bc5fe61 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -782,7 +782,7 @@ static int gem_rx(struct gem *gp, int work_to_do) | |||
782 | break; | 782 | break; |
783 | 783 | ||
784 | /* When writing back RX descriptor, GEM writes status | 784 | /* When writing back RX descriptor, GEM writes status |
785 | * then buffer address, possibly in seperate transactions. | 785 | * then buffer address, possibly in separate transactions. |
786 | * If we don't wait for the chip to write both, we could | 786 | * If we don't wait for the chip to write both, we could |
787 | * post a new buffer to this descriptor then have GEM spam | 787 | * post a new buffer to this descriptor then have GEM spam |
788 | * on the buffer address. We sync on the RX completion | 788 | * on the buffer address. We sync on the RX completion |
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 0c9780217c87..f5493092521a 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c | |||
@@ -1851,7 +1851,7 @@ static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size) | |||
1851 | * @data - desc's data | 1851 | * @data - desc's data |
1852 | * @size - desc's size | 1852 | * @size - desc's size |
1853 | * | 1853 | * |
1854 | * NOTE: this func does check for available space and, if neccessary, waits for | 1854 | * NOTE: this func does check for available space and, if necessary, waits for |
1855 | * NIC to read existing data before writing new one. | 1855 | * NIC to read existing data before writing new one. |
1856 | */ | 1856 | */ |
1857 | static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) | 1857 | static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0fa7688ab483..22cf1c446de3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5279,7 +5279,7 @@ static void tg3_poll_controller(struct net_device *dev) | |||
5279 | struct tg3 *tp = netdev_priv(dev); | 5279 | struct tg3 *tp = netdev_priv(dev); |
5280 | 5280 | ||
5281 | for (i = 0; i < tp->irq_cnt; i++) | 5281 | for (i = 0; i < tp->irq_cnt; i++) |
5282 | tg3_interrupt(tp->napi[i].irq_vec, dev); | 5282 | tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); |
5283 | } | 5283 | } |
5284 | #endif | 5284 | #endif |
5285 | 5285 | ||
@@ -9776,7 +9776,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
9776 | ADVERTISED_Pause | | 9776 | ADVERTISED_Pause | |
9777 | ADVERTISED_Asym_Pause; | 9777 | ADVERTISED_Asym_Pause; |
9778 | 9778 | ||
9779 | if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) | 9779 | if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) |
9780 | mask |= ADVERTISED_1000baseT_Half | | 9780 | mask |= ADVERTISED_1000baseT_Half | |
9781 | ADVERTISED_1000baseT_Full; | 9781 | ADVERTISED_1000baseT_Full; |
9782 | 9782 | ||
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 21a01753312a..ee71bcfb3753 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c | |||
@@ -693,7 +693,7 @@ static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb, | |||
693 | * NOTE: This function should be used whenever the status of any TPL must be | 693 | * NOTE: This function should be used whenever the status of any TPL must be |
694 | * modified by the driver, because the compiler may otherwise change the | 694 | * modified by the driver, because the compiler may otherwise change the |
695 | * order of instructions such that writing the TPL status may be executed at | 695 | * order of instructions such that writing the TPL status may be executed at |
696 | * an undesireable time. When this function is used, the status is always | 696 | * an undesirable time. When this function is used, the status is always |
697 | * written when the function is called. | 697 | * written when the function is called. |
698 | */ | 698 | */ |
699 | static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status) | 699 | static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status) |
@@ -2264,7 +2264,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) | |||
2264 | * This function should be used whenever the status of any RPL must be | 2264 | * This function should be used whenever the status of any RPL must be |
2265 | * modified by the driver, because the compiler may otherwise change the | 2265 | * modified by the driver, because the compiler may otherwise change the |
2266 | * order of instructions such that writing the RPL status may be executed | 2266 | * order of instructions such that writing the RPL status may be executed |
2267 | * at an undesireable time. When this function is used, the status is | 2267 | * at an undesirable time. When this function is used, the status is |
2268 | * always written when the function is called. | 2268 | * always written when the function is called. |
2269 | */ | 2269 | */ |
2270 | static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status) | 2270 | static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status) |
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 93f4e8309f81..49f05d1431f5 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c | |||
@@ -143,6 +143,12 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp) | |||
143 | 143 | ||
144 | void __devinit tulip_parse_eeprom(struct net_device *dev) | 144 | void __devinit tulip_parse_eeprom(struct net_device *dev) |
145 | { | 145 | { |
146 | /* | ||
147 | dev is not registered at this point, so logging messages can't | ||
148 | use dev_<level> or netdev_<level> but dev->name is good via a | ||
149 | hack in the caller | ||
150 | */ | ||
151 | |||
146 | /* The last media info list parsed, for multiport boards. */ | 152 | /* The last media info list parsed, for multiport boards. */ |
147 | static struct mediatable *last_mediatable; | 153 | static struct mediatable *last_mediatable; |
148 | static unsigned char *last_ee_data; | 154 | static unsigned char *last_ee_data; |
@@ -161,15 +167,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev) | |||
161 | if (ee_data[0] == 0xff) { | 167 | if (ee_data[0] == 0xff) { |
162 | if (last_mediatable) { | 168 | if (last_mediatable) { |
163 | controller_index++; | 169 | controller_index++; |
164 | dev_info(&dev->dev, | 170 | pr_info("%s: Controller %d of multiport board\n", |
165 | "Controller %d of multiport board\n", | 171 | dev->name, controller_index); |
166 | controller_index); | ||
167 | tp->mtable = last_mediatable; | 172 | tp->mtable = last_mediatable; |
168 | ee_data = last_ee_data; | 173 | ee_data = last_ee_data; |
169 | goto subsequent_board; | 174 | goto subsequent_board; |
170 | } else | 175 | } else |
171 | dev_info(&dev->dev, | 176 | pr_info("%s: Missing EEPROM, this interface may not work correctly!\n", |
172 | "Missing EEPROM, this interface may not work correctly!\n"); | 177 | dev->name); |
173 | return; | 178 | return; |
174 | } | 179 | } |
175 | /* Do a fix-up based on the vendor half of the station address prefix. */ | 180 | /* Do a fix-up based on the vendor half of the station address prefix. */ |
@@ -181,15 +186,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev) | |||
181 | i++; /* An Accton EN1207, not an outlaw Maxtech. */ | 186 | i++; /* An Accton EN1207, not an outlaw Maxtech. */ |
182 | memcpy(ee_data + 26, eeprom_fixups[i].newtable, | 187 | memcpy(ee_data + 26, eeprom_fixups[i].newtable, |
183 | sizeof(eeprom_fixups[i].newtable)); | 188 | sizeof(eeprom_fixups[i].newtable)); |
184 | dev_info(&dev->dev, | 189 | pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n", |
185 | "Old format EEPROM on '%s' board. Using substitute media control info\n", | 190 | dev->name, eeprom_fixups[i].name); |
186 | eeprom_fixups[i].name); | ||
187 | break; | 191 | break; |
188 | } | 192 | } |
189 | } | 193 | } |
190 | if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ | 194 | if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ |
191 | dev_info(&dev->dev, | 195 | pr_info("%s: Old style EEPROM with no media selection information\n", |
192 | "Old style EEPROM with no media selection information\n"); | 196 | dev->name); |
193 | return; | 197 | return; |
194 | } | 198 | } |
195 | } | 199 | } |
@@ -217,8 +221,8 @@ subsequent_board: | |||
217 | /* there is no phy information, don't even try to build mtable */ | 221 | /* there is no phy information, don't even try to build mtable */ |
218 | if (count == 0) { | 222 | if (count == 0) { |
219 | if (tulip_debug > 0) | 223 | if (tulip_debug > 0) |
220 | dev_warn(&dev->dev, | 224 | pr_warning("%s: no phy info, aborting mtable build\n", |
221 | "no phy info, aborting mtable build\n"); | 225 | dev->name); |
222 | return; | 226 | return; |
223 | } | 227 | } |
224 | 228 | ||
@@ -234,8 +238,10 @@ subsequent_board: | |||
234 | mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; | 238 | mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; |
235 | mtable->csr15dir = mtable->csr15val = 0; | 239 | mtable->csr15dir = mtable->csr15val = 0; |
236 | 240 | ||
237 | dev_info(&dev->dev, "EEPROM default media type %s\n", | 241 | pr_info("%s: EEPROM default media type %s\n", |
238 | media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); | 242 | dev->name, |
243 | media & 0x0800 ? "Autosense" | ||
244 | : medianame[media & MEDIA_MASK]); | ||
239 | for (i = 0; i < count; i++) { | 245 | for (i = 0; i < count; i++) { |
240 | struct medialeaf *leaf = &mtable->mleaf[i]; | 246 | struct medialeaf *leaf = &mtable->mleaf[i]; |
241 | 247 | ||
@@ -298,17 +304,17 @@ subsequent_board: | |||
298 | } | 304 | } |
299 | if (tulip_debug > 1 && leaf->media == 11) { | 305 | if (tulip_debug > 1 && leaf->media == 11) { |
300 | unsigned char *bp = leaf->leafdata; | 306 | unsigned char *bp = leaf->leafdata; |
301 | dev_info(&dev->dev, | 307 | pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n", |
302 | "MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n", | 308 | dev->name, |
303 | bp[0], bp[1], bp[2 + bp[1]*2], | 309 | bp[0], bp[1], bp[2 + bp[1]*2], |
304 | bp[5 + bp[2 + bp[1]*2]*2], | 310 | bp[5 + bp[2 + bp[1]*2]*2], |
305 | bp[4 + bp[2 + bp[1]*2]*2]); | 311 | bp[4 + bp[2 + bp[1]*2]*2]); |
306 | } | 312 | } |
307 | dev_info(&dev->dev, | 313 | pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n", |
308 | "Index #%d - Media %s (#%d) described by a %s (%d) block\n", | 314 | dev->name, |
309 | i, medianame[leaf->media & 15], leaf->media, | 315 | i, medianame[leaf->media & 15], leaf->media, |
310 | leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>", | 316 | leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>", |
311 | leaf->type); | 317 | leaf->type); |
312 | } | 318 | } |
313 | if (new_advertise) | 319 | if (new_advertise) |
314 | tp->sym_advertise = new_advertise; | 320 | tp->sym_advertise = new_advertise; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ce1efa4c0b0d..96c39bddc78c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1437,7 +1437,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) | |||
1437 | 1437 | ||
1438 | __tun_detach(tun); | 1438 | __tun_detach(tun); |
1439 | 1439 | ||
1440 | /* If desireable, unregister the netdevice. */ | 1440 | /* If desirable, unregister the netdevice. */ |
1441 | if (!(tun->flags & TUN_PERSIST)) { | 1441 | if (!(tun->flags & TUN_PERSIST)) { |
1442 | rtnl_lock(); | 1442 | rtnl_lock(); |
1443 | if (dev->reg_state == NETREG_REGISTERED) | 1443 | if (dev->reg_state == NETREG_REGISTERED) |
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index e3ddcb8f29df..cd24e5f2b2a2 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp) | |||
480 | typhoon_inc_cmd_index(&ring->lastWrite, 1); | 480 | typhoon_inc_cmd_index(&ring->lastWrite, 1); |
481 | 481 | ||
482 | INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); | 482 | INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); |
483 | smp_wmb(); | 483 | wmb(); |
484 | iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); | 484 | iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); |
485 | spin_unlock(&tp->command_lock); | 485 | spin_unlock(&tp->command_lock); |
486 | } | 486 | } |
@@ -1311,13 +1311,15 @@ typhoon_init_interface(struct typhoon *tp) | |||
1311 | 1311 | ||
1312 | tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); | 1312 | tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); |
1313 | tp->card_state = Sleeping; | 1313 | tp->card_state = Sleeping; |
1314 | smp_wmb(); | ||
1315 | 1314 | ||
1316 | tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; | 1315 | tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; |
1317 | tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; | 1316 | tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; |
1318 | 1317 | ||
1319 | spin_lock_init(&tp->command_lock); | 1318 | spin_lock_init(&tp->command_lock); |
1320 | spin_lock_init(&tp->state_lock); | 1319 | spin_lock_init(&tp->state_lock); |
1320 | |||
1321 | /* Force the writes to the shared memory area out before continuing. */ | ||
1322 | wmb(); | ||
1321 | } | 1323 | } |
1322 | 1324 | ||
1323 | static void | 1325 | static void |
@@ -2096,7 +2098,7 @@ typhoon_tx_timeout(struct net_device *dev) | |||
2096 | 2098 | ||
2097 | if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { | 2099 | if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { |
2098 | netdev_warn(dev, "could not reset in tx timeout\n"); | 2100 | netdev_warn(dev, "could not reset in tx timeout\n"); |
2099 | goto truely_dead; | 2101 | goto truly_dead; |
2100 | } | 2102 | } |
2101 | 2103 | ||
2102 | /* If we ever start using the Hi ring, it will need cleaning too */ | 2104 | /* If we ever start using the Hi ring, it will need cleaning too */ |
@@ -2105,13 +2107,13 @@ typhoon_tx_timeout(struct net_device *dev) | |||
2105 | 2107 | ||
2106 | if(typhoon_start_runtime(tp) < 0) { | 2108 | if(typhoon_start_runtime(tp) < 0) { |
2107 | netdev_err(dev, "could not start runtime in tx timeout\n"); | 2109 | netdev_err(dev, "could not start runtime in tx timeout\n"); |
2108 | goto truely_dead; | 2110 | goto truly_dead; |
2109 | } | 2111 | } |
2110 | 2112 | ||
2111 | netif_wake_queue(dev); | 2113 | netif_wake_queue(dev); |
2112 | return; | 2114 | return; |
2113 | 2115 | ||
2114 | truely_dead: | 2116 | truly_dead: |
2115 | /* Reset the hardware, and turn off carrier to avoid more timeouts */ | 2117 | /* Reset the hardware, and turn off carrier to avoid more timeouts */ |
2116 | typhoon_reset(tp->ioaddr, NoWait); | 2118 | typhoon_reset(tp->ioaddr, NoWait); |
2117 | netif_carrier_off(dev); | 2119 | netif_carrier_off(dev); |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 23a97518bc1f..1b0aef37e495 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -430,7 +430,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | |||
430 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | 430 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); |
431 | 431 | ||
432 | /* Ethernet frames are defined in Little Endian mode, | 432 | /* Ethernet frames are defined in Little Endian mode, |
433 | therefor to insert */ | 433 | therefore to insert */ |
434 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ | 434 | /* the address to the hash (Big Endian mode), we reverse the bytes.*/ |
435 | 435 | ||
436 | set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); | 436 | set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr); |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 20e34608fa4a..9e05639435f2 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -54,6 +54,7 @@ static const char driver_name [] = "asix"; | |||
54 | #define AX_CMD_WRITE_IPG0 0x12 | 54 | #define AX_CMD_WRITE_IPG0 0x12 |
55 | #define AX_CMD_WRITE_IPG1 0x13 | 55 | #define AX_CMD_WRITE_IPG1 0x13 |
56 | #define AX_CMD_READ_NODE_ID 0x13 | 56 | #define AX_CMD_READ_NODE_ID 0x13 |
57 | #define AX_CMD_WRITE_NODE_ID 0x14 | ||
57 | #define AX_CMD_WRITE_IPG2 0x14 | 58 | #define AX_CMD_WRITE_IPG2 0x14 |
58 | #define AX_CMD_WRITE_MULTI_FILTER 0x16 | 59 | #define AX_CMD_WRITE_MULTI_FILTER 0x16 |
59 | #define AX88172_CMD_READ_NODE_ID 0x17 | 60 | #define AX88172_CMD_READ_NODE_ID 0x17 |
@@ -165,6 +166,7 @@ static const char driver_name [] = "asix"; | |||
165 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | 166 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ |
166 | struct asix_data { | 167 | struct asix_data { |
167 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; | 168 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; |
169 | u8 mac_addr[ETH_ALEN]; | ||
168 | u8 phymode; | 170 | u8 phymode; |
169 | u8 ledmode; | 171 | u8 ledmode; |
170 | u8 eeprom_len; | 172 | u8 eeprom_len; |
@@ -732,6 +734,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) | |||
732 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | 734 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); |
733 | } | 735 | } |
734 | 736 | ||
737 | static int asix_set_mac_address(struct net_device *net, void *p) | ||
738 | { | ||
739 | struct usbnet *dev = netdev_priv(net); | ||
740 | struct asix_data *data = (struct asix_data *)&dev->data; | ||
741 | struct sockaddr *addr = p; | ||
742 | |||
743 | if (netif_running(net)) | ||
744 | return -EBUSY; | ||
745 | if (!is_valid_ether_addr(addr->sa_data)) | ||
746 | return -EADDRNOTAVAIL; | ||
747 | |||
748 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
749 | |||
750 | /* We use the 20 byte dev->data | ||
751 | * for our 6 byte mac buffer | ||
752 | * to avoid allocating memory that | ||
753 | * is tricky to free later */ | ||
754 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
755 | asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
756 | data->mac_addr); | ||
757 | |||
758 | return 0; | ||
759 | } | ||
760 | |||
735 | /* We need to override some ethtool_ops so we require our | 761 | /* We need to override some ethtool_ops so we require our |
736 | own structure so we don't interfere with other usbnet | 762 | own structure so we don't interfere with other usbnet |
737 | devices that may be connected at the same time. */ | 763 | devices that may be connected at the same time. */ |
@@ -919,7 +945,7 @@ static const struct net_device_ops ax88772_netdev_ops = { | |||
919 | .ndo_start_xmit = usbnet_start_xmit, | 945 | .ndo_start_xmit = usbnet_start_xmit, |
920 | .ndo_tx_timeout = usbnet_tx_timeout, | 946 | .ndo_tx_timeout = usbnet_tx_timeout, |
921 | .ndo_change_mtu = usbnet_change_mtu, | 947 | .ndo_change_mtu = usbnet_change_mtu, |
922 | .ndo_set_mac_address = eth_mac_addr, | 948 | .ndo_set_mac_address = asix_set_mac_address, |
923 | .ndo_validate_addr = eth_validate_addr, | 949 | .ndo_validate_addr = eth_validate_addr, |
924 | .ndo_do_ioctl = asix_ioctl, | 950 | .ndo_do_ioctl = asix_ioctl, |
925 | .ndo_set_multicast_list = asix_set_multicast, | 951 | .ndo_set_multicast_list = asix_set_multicast, |
@@ -1213,7 +1239,7 @@ static const struct net_device_ops ax88178_netdev_ops = { | |||
1213 | .ndo_stop = usbnet_stop, | 1239 | .ndo_stop = usbnet_stop, |
1214 | .ndo_start_xmit = usbnet_start_xmit, | 1240 | .ndo_start_xmit = usbnet_start_xmit, |
1215 | .ndo_tx_timeout = usbnet_tx_timeout, | 1241 | .ndo_tx_timeout = usbnet_tx_timeout, |
1216 | .ndo_set_mac_address = eth_mac_addr, | 1242 | .ndo_set_mac_address = asix_set_mac_address, |
1217 | .ndo_validate_addr = eth_validate_addr, | 1243 | .ndo_validate_addr = eth_validate_addr, |
1218 | .ndo_set_multicast_list = asix_set_multicast, | 1244 | .ndo_set_multicast_list = asix_set_multicast, |
1219 | .ndo_do_ioctl = asix_ioctl, | 1245 | .ndo_do_ioctl = asix_ioctl, |
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h index 5d02f0200737..b90d8766ab74 100644 --- a/drivers/net/usb/pegasus.h +++ b/drivers/net/usb/pegasus.h | |||
@@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c, | |||
177 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, | 177 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, |
178 | DEFAULT_GPIO_RESET ) | 178 | DEFAULT_GPIO_RESET ) |
179 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, | 179 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, |
180 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 180 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
181 | PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, | 181 | PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, |
182 | DEFAULT_GPIO_RESET ) | 182 | DEFAULT_GPIO_RESET ) |
183 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, | 183 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, |
@@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, | |||
208 | */ | 208 | */ |
209 | PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, | 209 | PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, |
210 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 210 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
211 | PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122, | ||
212 | DEFAULT_GPIO_RESET | PEGASUS_II ) | ||
211 | PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, | 213 | PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, |
212 | DEFAULT_GPIO_RESET ) | 214 | DEFAULT_GPIO_RESET ) |
213 | PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, | 215 | PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, |
@@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002, | |||
249 | PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, | 251 | PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, |
250 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 252 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
251 | PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, | 253 | PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, |
252 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 254 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
253 | PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, | 255 | PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, |
254 | DEFAULT_GPIO_RESET ) | 256 | DEFAULT_GPIO_RESET ) |
255 | PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, | 257 | PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index b36bf96eb502..f0bd70fb650c 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -811,7 +811,7 @@ static ssize_t cosa_read(struct file *file, | |||
811 | cosa_enable_rx(chan); | 811 | cosa_enable_rx(chan); |
812 | spin_lock_irqsave(&cosa->lock, flags); | 812 | spin_lock_irqsave(&cosa->lock, flags); |
813 | add_wait_queue(&chan->rxwaitq, &wait); | 813 | add_wait_queue(&chan->rxwaitq, &wait); |
814 | while(!chan->rx_status) { | 814 | while (!chan->rx_status) { |
815 | current->state = TASK_INTERRUPTIBLE; | 815 | current->state = TASK_INTERRUPTIBLE; |
816 | spin_unlock_irqrestore(&cosa->lock, flags); | 816 | spin_unlock_irqrestore(&cosa->lock, flags); |
817 | schedule(); | 817 | schedule(); |
@@ -896,7 +896,7 @@ static ssize_t cosa_write(struct file *file, | |||
896 | 896 | ||
897 | spin_lock_irqsave(&cosa->lock, flags); | 897 | spin_lock_irqsave(&cosa->lock, flags); |
898 | add_wait_queue(&chan->txwaitq, &wait); | 898 | add_wait_queue(&chan->txwaitq, &wait); |
899 | while(!chan->tx_status) { | 899 | while (!chan->tx_status) { |
900 | current->state = TASK_INTERRUPTIBLE; | 900 | current->state = TASK_INTERRUPTIBLE; |
901 | spin_unlock_irqrestore(&cosa->lock, flags); | 901 | spin_unlock_irqrestore(&cosa->lock, flags); |
902 | schedule(); | 902 | schedule(); |
@@ -1153,7 +1153,7 @@ static int cosa_ioctl_common(struct cosa_data *cosa, | |||
1153 | struct channel_data *channel, unsigned int cmd, unsigned long arg) | 1153 | struct channel_data *channel, unsigned int cmd, unsigned long arg) |
1154 | { | 1154 | { |
1155 | void __user *argp = (void __user *)arg; | 1155 | void __user *argp = (void __user *)arg; |
1156 | switch(cmd) { | 1156 | switch (cmd) { |
1157 | case COSAIORSET: /* Reset the device */ | 1157 | case COSAIORSET: /* Reset the device */ |
1158 | if (!capable(CAP_NET_ADMIN)) | 1158 | if (!capable(CAP_NET_ADMIN)) |
1159 | return -EACCES; | 1159 | return -EACCES; |
@@ -1704,7 +1704,7 @@ static inline void tx_interrupt(struct cosa_data *cosa, int status) | |||
1704 | spin_unlock_irqrestore(&cosa->lock, flags); | 1704 | spin_unlock_irqrestore(&cosa->lock, flags); |
1705 | return; | 1705 | return; |
1706 | } | 1706 | } |
1707 | while(1) { | 1707 | while (1) { |
1708 | cosa->txchan++; | 1708 | cosa->txchan++; |
1709 | i++; | 1709 | i++; |
1710 | if (cosa->txchan >= cosa->nchannels) | 1710 | if (cosa->txchan >= cosa->nchannels) |
@@ -2010,7 +2010,7 @@ again: | |||
2010 | static void debug_status_in(struct cosa_data *cosa, int status) | 2010 | static void debug_status_in(struct cosa_data *cosa, int status) |
2011 | { | 2011 | { |
2012 | char *s; | 2012 | char *s; |
2013 | switch(status & SR_CMD_FROM_SRP_MASK) { | 2013 | switch (status & SR_CMD_FROM_SRP_MASK) { |
2014 | case SR_UP_REQUEST: | 2014 | case SR_UP_REQUEST: |
2015 | s = "RX_REQ"; | 2015 | s = "RX_REQ"; |
2016 | break; | 2016 | break; |
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index f1bff98acd1f..1ceccf1ca6c7 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c | |||
@@ -141,7 +141,7 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
141 | data->address != CISCO_UNICAST) | 141 | data->address != CISCO_UNICAST) |
142 | return cpu_to_be16(ETH_P_HDLC); | 142 | return cpu_to_be16(ETH_P_HDLC); |
143 | 143 | ||
144 | switch(data->protocol) { | 144 | switch (data->protocol) { |
145 | case cpu_to_be16(ETH_P_IP): | 145 | case cpu_to_be16(ETH_P_IP): |
146 | case cpu_to_be16(ETH_P_IPX): | 146 | case cpu_to_be16(ETH_P_IPX): |
147 | case cpu_to_be16(ETH_P_IPV6): | 147 | case cpu_to_be16(ETH_P_IPV6): |
@@ -190,7 +190,7 @@ static int cisco_rx(struct sk_buff *skb) | |||
190 | cisco_data = (struct cisco_packet*)(skb->data + sizeof | 190 | cisco_data = (struct cisco_packet*)(skb->data + sizeof |
191 | (struct hdlc_header)); | 191 | (struct hdlc_header)); |
192 | 192 | ||
193 | switch(ntohl (cisco_data->type)) { | 193 | switch (ntohl (cisco_data->type)) { |
194 | case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ | 194 | case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ |
195 | in_dev = dev->ip_ptr; | 195 | in_dev = dev->ip_ptr; |
196 | addr = 0; | 196 | addr = 0; |
@@ -245,8 +245,8 @@ static int cisco_rx(struct sk_buff *skb) | |||
245 | 245 | ||
246 | dev_kfree_skb_any(skb); | 246 | dev_kfree_skb_any(skb); |
247 | return NET_RX_SUCCESS; | 247 | return NET_RX_SUCCESS; |
248 | } /* switch(keepalive type) */ | 248 | } /* switch (keepalive type) */ |
249 | } /* switch(protocol) */ | 249 | } /* switch (protocol) */ |
250 | 250 | ||
251 | printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, | 251 | printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name, |
252 | ntohs(data->protocol)); | 252 | ntohs(data->protocol)); |
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index aa9248f8eb1a..6e1ca256effd 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c | |||
@@ -202,10 +202,10 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
202 | return 0; /* return protocol only, no settable parameters */ | 202 | return 0; /* return protocol only, no settable parameters */ |
203 | 203 | ||
204 | case IF_PROTO_X25: | 204 | case IF_PROTO_X25: |
205 | if(!capable(CAP_NET_ADMIN)) | 205 | if (!capable(CAP_NET_ADMIN)) |
206 | return -EPERM; | 206 | return -EPERM; |
207 | 207 | ||
208 | if(dev->flags & IFF_UP) | 208 | if (dev->flags & IFF_UP) |
209 | return -EBUSY; | 209 | return -EBUSY; |
210 | 210 | ||
211 | result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); | 211 | result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); |
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index e803a7dc6502..25c24f0368d8 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c | |||
@@ -612,7 +612,7 @@ ssize_t i2400m_bm_cmd(struct i2400m *i2400m, | |||
612 | goto error_wait_for_ack; | 612 | goto error_wait_for_ack; |
613 | } | 613 | } |
614 | rx_bytes = result; | 614 | rx_bytes = result; |
615 | /* verify the ack and read more if neccessary [result is the | 615 | /* verify the ack and read more if necessary [result is the |
616 | * final amount of bytes we get in the ack] */ | 616 | * final amount of bytes we get in the ack] */ |
617 | result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags); | 617 | result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags); |
618 | if (result < 0) | 618 | if (result < 0) |
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 04df9bbe340f..820b128705ec 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h | |||
@@ -627,7 +627,7 @@ enum i2400m_bm_cmd_flags { | |||
627 | * @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed | 627 | * @I2400M_BRI_NO_REBOOT: Do not reboot the device and proceed |
628 | * directly to wait for a reboot barker from the device. | 628 | * directly to wait for a reboot barker from the device. |
629 | * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot | 629 | * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot |
630 | * rom after reading the MAC adress. This is quite a dirty hack, | 630 | * rom after reading the MAC address. This is quite a dirty hack, |
631 | * if you ask me -- the device requires the bootrom to be | 631 | * if you ask me -- the device requires the bootrom to be |
632 | * intialized after reading the MAC address. | 632 | * intialized after reading the MAC address. |
633 | */ | 633 | */ |
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c index 76a50ac02ebb..14f876b1358b 100644 --- a/drivers/net/wimax/i2400m/sdio.c +++ b/drivers/net/wimax/i2400m/sdio.c | |||
@@ -304,7 +304,7 @@ error_kzalloc: | |||
304 | * | 304 | * |
305 | * The device will be fully reset internally, but won't be | 305 | * The device will be fully reset internally, but won't be |
306 | * disconnected from the bus (so no reenumeration will | 306 | * disconnected from the bus (so no reenumeration will |
307 | * happen). Firmware upload will be neccessary. | 307 | * happen). Firmware upload will be necessary. |
308 | * | 308 | * |
309 | * The device will send a reboot barker that will trigger the driver | 309 | * The device will send a reboot barker that will trigger the driver |
310 | * to reinitialize the state via __i2400m_dev_reset_handle. | 310 | * to reinitialize the state via __i2400m_dev_reset_handle. |
@@ -314,7 +314,7 @@ error_kzalloc: | |||
314 | * | 314 | * |
315 | * The device will be fully reset internally, disconnected from the | 315 | * The device will be fully reset internally, disconnected from the |
316 | * bus an a reenumeration will happen. Firmware upload will be | 316 | * bus an a reenumeration will happen. Firmware upload will be |
317 | * neccessary. Thus, we don't do any locking or struct | 317 | * necessary. Thus, we don't do any locking or struct |
318 | * reinitialization, as we are going to be fully disconnected and | 318 | * reinitialization, as we are going to be fully disconnected and |
319 | * reenumerated. | 319 | * reenumerated. |
320 | * | 320 | * |
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 98f4f8c5fb68..99f04c475898 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c | |||
@@ -246,7 +246,7 @@ error_kzalloc: | |||
246 | * | 246 | * |
247 | * The device will be fully reset internally, but won't be | 247 | * The device will be fully reset internally, but won't be |
248 | * disconnected from the USB bus (so no reenumeration will | 248 | * disconnected from the USB bus (so no reenumeration will |
249 | * happen). Firmware upload will be neccessary. | 249 | * happen). Firmware upload will be necessary. |
250 | * | 250 | * |
251 | * The device will send a reboot barker in the notification endpoint | 251 | * The device will send a reboot barker in the notification endpoint |
252 | * that will trigger the driver to reinitialize the state | 252 | * that will trigger the driver to reinitialize the state |
@@ -257,7 +257,7 @@ error_kzalloc: | |||
257 | * | 257 | * |
258 | * The device will be fully reset internally, disconnected from the | 258 | * The device will be fully reset internally, disconnected from the |
259 | * USB bus an a reenumeration will happen. Firmware upload will be | 259 | * USB bus an a reenumeration will happen. Firmware upload will be |
260 | * neccessary. Thus, we don't do any locking or struct | 260 | * necessary. Thus, we don't do any locking or struct |
261 | * reinitialization, as we are going to be fully disconnected and | 261 | * reinitialization, as we are going to be fully disconnected and |
262 | * reenumerated. | 262 | * reenumerated. |
263 | * | 263 | * |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 698d5672a070..dc5018a6d9ed 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key, | |||
5255 | WepKeyRid wkr; | 5255 | WepKeyRid wkr; |
5256 | int rc; | 5256 | int rc; |
5257 | 5257 | ||
5258 | WARN_ON(keylen == 0); | 5258 | if (WARN_ON(keylen == 0)) |
5259 | return -1; | ||
5259 | 5260 | ||
5260 | memset(&wkr, 0, sizeof(wkr)); | 5261 | memset(&wkr, 0, sizeof(wkr)); |
5261 | wkr.len = cpu_to_le16(sizeof(wkr)); | 5262 | wkr.len = cpu_to_le16(sizeof(wkr)); |
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 8c8ce67971e9..dc662b76a1c8 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -166,6 +166,7 @@ struct ar9170 { | |||
166 | struct ath_common common; | 166 | struct ath_common common; |
167 | struct mutex mutex; | 167 | struct mutex mutex; |
168 | enum ar9170_device_state state; | 168 | enum ar9170_device_state state; |
169 | bool registered; | ||
169 | unsigned long bad_hw_nagger; | 170 | unsigned long bad_hw_nagger; |
170 | 171 | ||
171 | int (*open)(struct ar9170 *); | 172 | int (*open)(struct ar9170 *); |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index a6452af9c6c5..257c734733d1 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -2512,7 +2512,7 @@ void *ar9170_alloc(size_t priv_size) | |||
2512 | /* | 2512 | /* |
2513 | * this buffer is used for rx stream reconstruction. | 2513 | * this buffer is used for rx stream reconstruction. |
2514 | * Under heavy load this device (or the transport layer?) | 2514 | * Under heavy load this device (or the transport layer?) |
2515 | * tends to split the streams into seperate rx descriptors. | 2515 | * tends to split the streams into separate rx descriptors. |
2516 | */ | 2516 | */ |
2517 | 2517 | ||
2518 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); | 2518 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); |
@@ -2701,7 +2701,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev) | |||
2701 | dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", | 2701 | dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", |
2702 | wiphy_name(ar->hw->wiphy)); | 2702 | wiphy_name(ar->hw->wiphy)); |
2703 | 2703 | ||
2704 | return err; | 2704 | ar->registered = true; |
2705 | return 0; | ||
2705 | 2706 | ||
2706 | err_unreg: | 2707 | err_unreg: |
2707 | ieee80211_unregister_hw(ar->hw); | 2708 | ieee80211_unregister_hw(ar->hw); |
@@ -2712,11 +2713,14 @@ err_out: | |||
2712 | 2713 | ||
2713 | void ar9170_unregister(struct ar9170 *ar) | 2714 | void ar9170_unregister(struct ar9170 *ar) |
2714 | { | 2715 | { |
2716 | if (ar->registered) { | ||
2715 | #ifdef CONFIG_AR9170_LEDS | 2717 | #ifdef CONFIG_AR9170_LEDS |
2716 | ar9170_unregister_leds(ar); | 2718 | ar9170_unregister_leds(ar); |
2717 | #endif /* CONFIG_AR9170_LEDS */ | 2719 | #endif /* CONFIG_AR9170_LEDS */ |
2718 | 2720 | ||
2719 | kfree_skb(ar->rx_failover); | ||
2720 | ieee80211_unregister_hw(ar->hw); | 2721 | ieee80211_unregister_hw(ar->hw); |
2722 | } | ||
2723 | |||
2724 | kfree_skb(ar->rx_failover); | ||
2721 | mutex_destroy(&ar->mutex); | 2725 | mutex_destroy(&ar->mutex); |
2722 | } | 2726 | } |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 0f361186b78f..4e30197afff6 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -582,43 +582,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data, | |||
582 | return 0; | 582 | return 0; |
583 | } | 583 | } |
584 | 584 | ||
585 | static int ar9170_usb_request_firmware(struct ar9170_usb *aru) | ||
586 | { | ||
587 | int err = 0; | ||
588 | |||
589 | err = request_firmware(&aru->firmware, "ar9170.fw", | ||
590 | &aru->udev->dev); | ||
591 | if (!err) { | ||
592 | aru->init_values = NULL; | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | if (aru->req_one_stage_fw) { | ||
597 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
598 | "not found and is required for this device\n"); | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | |||
602 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
603 | "not found, trying old firmware...\n"); | ||
604 | |||
605 | err = request_firmware(&aru->init_values, "ar9170-1.fw", | ||
606 | &aru->udev->dev); | ||
607 | if (err) { | ||
608 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | ||
609 | return err; | ||
610 | } | ||
611 | |||
612 | err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); | ||
613 | if (err) { | ||
614 | release_firmware(aru->init_values); | ||
615 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | ||
616 | return err; | ||
617 | } | ||
618 | |||
619 | return err; | ||
620 | } | ||
621 | |||
622 | static int ar9170_usb_reset(struct ar9170_usb *aru) | 585 | static int ar9170_usb_reset(struct ar9170_usb *aru) |
623 | { | 586 | { |
624 | int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); | 587 | int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); |
@@ -757,6 +720,103 @@ err_out: | |||
757 | return err; | 720 | return err; |
758 | } | 721 | } |
759 | 722 | ||
723 | static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) | ||
724 | { | ||
725 | struct device *parent = aru->udev->dev.parent; | ||
726 | |||
727 | /* unbind anything failed */ | ||
728 | if (parent) | ||
729 | down(&parent->sem); | ||
730 | device_release_driver(&aru->udev->dev); | ||
731 | if (parent) | ||
732 | up(&parent->sem); | ||
733 | } | ||
734 | |||
735 | static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) | ||
736 | { | ||
737 | struct ar9170_usb *aru = context; | ||
738 | int err; | ||
739 | |||
740 | aru->firmware = fw; | ||
741 | |||
742 | if (!fw) { | ||
743 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | ||
744 | goto err_freefw; | ||
745 | } | ||
746 | |||
747 | err = ar9170_usb_init_device(aru); | ||
748 | if (err) | ||
749 | goto err_freefw; | ||
750 | |||
751 | err = ar9170_usb_open(&aru->common); | ||
752 | if (err) | ||
753 | goto err_unrx; | ||
754 | |||
755 | err = ar9170_register(&aru->common, &aru->udev->dev); | ||
756 | |||
757 | ar9170_usb_stop(&aru->common); | ||
758 | if (err) | ||
759 | goto err_unrx; | ||
760 | |||
761 | return; | ||
762 | |||
763 | err_unrx: | ||
764 | ar9170_usb_cancel_urbs(aru); | ||
765 | |||
766 | err_freefw: | ||
767 | ar9170_usb_firmware_failed(aru); | ||
768 | } | ||
769 | |||
770 | static void ar9170_usb_firmware_inits(const struct firmware *fw, | ||
771 | void *context) | ||
772 | { | ||
773 | struct ar9170_usb *aru = context; | ||
774 | int err; | ||
775 | |||
776 | if (!fw) { | ||
777 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | ||
778 | ar9170_usb_firmware_failed(aru); | ||
779 | return; | ||
780 | } | ||
781 | |||
782 | aru->init_values = fw; | ||
783 | |||
784 | /* ok so we have the init values -- get code for two-stage */ | ||
785 | |||
786 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw", | ||
787 | &aru->udev->dev, GFP_KERNEL, aru, | ||
788 | ar9170_usb_firmware_finish); | ||
789 | if (err) | ||
790 | ar9170_usb_firmware_failed(aru); | ||
791 | } | ||
792 | |||
793 | static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context) | ||
794 | { | ||
795 | struct ar9170_usb *aru = context; | ||
796 | int err; | ||
797 | |||
798 | if (fw) { | ||
799 | ar9170_usb_firmware_finish(fw, context); | ||
800 | return; | ||
801 | } | ||
802 | |||
803 | if (aru->req_one_stage_fw) { | ||
804 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
805 | "not found and is required for this device\n"); | ||
806 | ar9170_usb_firmware_failed(aru); | ||
807 | return; | ||
808 | } | ||
809 | |||
810 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
811 | "not found, trying old firmware...\n"); | ||
812 | |||
813 | err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw", | ||
814 | &aru->udev->dev, GFP_KERNEL, aru, | ||
815 | ar9170_usb_firmware_inits); | ||
816 | if (err) | ||
817 | ar9170_usb_firmware_failed(aru); | ||
818 | } | ||
819 | |||
760 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) | 820 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) |
761 | { | 821 | { |
762 | if (!id->driver_info) | 822 | if (!id->driver_info) |
@@ -814,33 +874,9 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
814 | if (err) | 874 | if (err) |
815 | goto err_freehw; | 875 | goto err_freehw; |
816 | 876 | ||
817 | err = ar9170_usb_request_firmware(aru); | 877 | return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", |
818 | if (err) | 878 | &aru->udev->dev, GFP_KERNEL, aru, |
819 | goto err_freehw; | 879 | ar9170_usb_firmware_step2); |
820 | |||
821 | err = ar9170_usb_init_device(aru); | ||
822 | if (err) | ||
823 | goto err_freefw; | ||
824 | |||
825 | err = ar9170_usb_open(ar); | ||
826 | if (err) | ||
827 | goto err_unrx; | ||
828 | |||
829 | err = ar9170_register(ar, &udev->dev); | ||
830 | |||
831 | ar9170_usb_stop(ar); | ||
832 | if (err) | ||
833 | goto err_unrx; | ||
834 | |||
835 | return 0; | ||
836 | |||
837 | err_unrx: | ||
838 | ar9170_usb_cancel_urbs(aru); | ||
839 | |||
840 | err_freefw: | ||
841 | release_firmware(aru->init_values); | ||
842 | release_firmware(aru->firmware); | ||
843 | |||
844 | err_freehw: | 880 | err_freehw: |
845 | usb_set_intfdata(intf, NULL); | 881 | usb_set_intfdata(intf, NULL); |
846 | usb_put_dev(udev); | 882 | usb_put_dev(udev); |
@@ -860,12 +896,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf) | |||
860 | ar9170_unregister(&aru->common); | 896 | ar9170_unregister(&aru->common); |
861 | ar9170_usb_cancel_urbs(aru); | 897 | ar9170_usb_cancel_urbs(aru); |
862 | 898 | ||
863 | release_firmware(aru->init_values); | ||
864 | release_firmware(aru->firmware); | ||
865 | |||
866 | usb_put_dev(aru->udev); | 899 | usb_put_dev(aru->udev); |
867 | usb_set_intfdata(intf, NULL); | 900 | usb_set_intfdata(intf, NULL); |
868 | ieee80211_free_hw(aru->common.hw); | 901 | ieee80211_free_hw(aru->common.hw); |
902 | |||
903 | release_firmware(aru->init_values); | ||
904 | release_firmware(aru->firmware); | ||
869 | } | 905 | } |
870 | 906 | ||
871 | #ifdef CONFIG_PM | 907 | #ifdef CONFIG_PM |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 6a3f4da7fb48..10b52262b232 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -429,8 +429,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
429 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | 429 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; |
430 | 430 | ||
431 | AR5K_EEPROM_READ(o++, val); | 431 | AR5K_EEPROM_READ(o++, val); |
432 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | 432 | ee->ee_i_cal[mode] = (val >> 5) & 0x3f; |
433 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | 433 | ee->ee_q_cal[mode] = val & 0x1f; |
434 | 434 | ||
435 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { | 435 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { |
436 | AR5K_EEPROM_READ(o++, val); | 436 | AR5K_EEPROM_READ(o++, val); |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 72474c0ccaff..eff3323efb4b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1386 | goto done; | 1386 | goto done; |
1387 | 1387 | ||
1388 | /* Calibration has finished, get the results and re-run */ | 1388 | /* Calibration has finished, get the results and re-run */ |
1389 | |||
1390 | /* work around empty results which can apparently happen on 5212 */ | ||
1389 | for (i = 0; i <= 10; i++) { | 1391 | for (i = 0; i <= 10; i++) { |
1390 | iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); | 1392 | iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); |
1391 | i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); | 1393 | i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); |
1392 | q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); | 1394 | q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); |
1395 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, | ||
1396 | "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr); | ||
1397 | if (i_pwr && q_pwr) | ||
1398 | break; | ||
1393 | } | 1399 | } |
1394 | 1400 | ||
1395 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; | 1401 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; |
1396 | q_coffd = q_pwr >> 7; | 1402 | q_coffd = q_pwr >> 7; |
1397 | 1403 | ||
1398 | /* No correction */ | 1404 | /* protect against divide by 0 and loss of sign bits */ |
1399 | if (i_coffd == 0 || q_coffd == 0) | 1405 | if (i_coffd == 0 || q_coffd < 2) |
1400 | goto done; | 1406 | goto done; |
1401 | 1407 | ||
1402 | i_coff = ((-iq_corr) / i_coffd); | 1408 | i_coff = (-iq_corr) / i_coffd; |
1403 | 1409 | i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ | |
1404 | /* Boundary check */ | ||
1405 | if (i_coff > 31) | ||
1406 | i_coff = 31; | ||
1407 | if (i_coff < -32) | ||
1408 | i_coff = -32; | ||
1409 | 1410 | ||
1410 | q_coff = (((s32)i_pwr / q_coffd) - 128); | 1411 | q_coff = (i_pwr / q_coffd) - 128; |
1412 | q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ | ||
1411 | 1413 | ||
1412 | /* Boundary check */ | 1414 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, |
1413 | if (q_coff > 15) | 1415 | "new I:%d Q:%d (i_coffd:%x q_coffd:%x)", |
1414 | q_coff = 15; | 1416 | i_coff, q_coff, i_coffd, q_coffd); |
1415 | if (q_coff < -16) | ||
1416 | q_coff = -16; | ||
1417 | 1417 | ||
1418 | /* Commit new I/Q value */ | 1418 | /* Commit new I/Q values (set enable bit last to match HAL sources) */ |
1419 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | | 1419 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff); |
1420 | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); | 1420 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff); |
1421 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); | ||
1421 | 1422 | ||
1422 | /* Re-enable calibration -if we don't we'll commit | 1423 | /* Re-enable calibration -if we don't we'll commit |
1423 | * the same values again and again */ | 1424 | * the same values again and again */ |
@@ -1873,7 +1874,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1873 | break; | 1874 | break; |
1874 | case AR5K_ANTMODE_FIXED_A: | 1875 | case AR5K_ANTMODE_FIXED_A: |
1875 | def_ant = 1; | 1876 | def_ant = 1; |
1876 | tx_ant = 0; | 1877 | tx_ant = 1; |
1877 | use_def_for_tx = true; | 1878 | use_def_for_tx = true; |
1878 | update_def_on_tx = false; | 1879 | update_def_on_tx = false; |
1879 | use_def_for_rts = true; | 1880 | use_def_for_rts = true; |
@@ -1882,7 +1883,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1882 | break; | 1883 | break; |
1883 | case AR5K_ANTMODE_FIXED_B: | 1884 | case AR5K_ANTMODE_FIXED_B: |
1884 | def_ant = 2; | 1885 | def_ant = 2; |
1885 | tx_ant = 0; | 1886 | tx_ant = 2; |
1886 | use_def_for_tx = true; | 1887 | use_def_for_tx = true; |
1887 | update_def_on_tx = false; | 1888 | update_def_on_tx = false; |
1888 | use_def_for_rts = true; | 1889 | use_def_for_rts = true; |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 4cb9c5df9f46..1464f89b249c 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -2187,6 +2187,7 @@ | |||
2187 | */ | 2187 | */ |
2188 | #define AR5K_PHY_IQ 0x9920 /* Register Address */ | 2188 | #define AR5K_PHY_IQ 0x9920 /* Register Address */ |
2189 | #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ | 2189 | #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ |
2190 | #define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0 | ||
2190 | #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ | 2191 | #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ |
2191 | #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 | 2192 | #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 |
2192 | #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ | 2193 | #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index a35a7db0fc4c..cbf28e379843 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, | |||
851 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, | 851 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, |
852 | AR5K_INIT_CYCRSSI_THR1); | 852 | AR5K_INIT_CYCRSSI_THR1); |
853 | 853 | ||
854 | /* I/Q correction | 854 | /* I/Q correction (set enable bit last to match HAL sources) */ |
855 | * TODO: Per channel i/q infos ? */ | 855 | /* TODO: Per channel i/q infos ? */ |
856 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | 856 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { |
857 | AR5K_PHY_IQ_CORR_ENABLE | | 857 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, |
858 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | 858 | ee->ee_i_cal[ee_mode]); |
859 | ee->ee_q_cal[ee_mode]); | 859 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, |
860 | ee->ee_q_cal[ee_mode]); | ||
861 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); | ||
862 | } | ||
860 | 863 | ||
861 | /* Heavy clipping -disable for now */ | 864 | /* Heavy clipping -disable for now */ |
862 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) | 865 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) |
@@ -1379,11 +1382,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1379 | ath5k_hw_set_sleep_clock(ah, true); | 1382 | ath5k_hw_set_sleep_clock(ah, true); |
1380 | 1383 | ||
1381 | /* | 1384 | /* |
1382 | * Disable beacons and reset the register | 1385 | * Disable beacons and reset the TSF |
1383 | */ | 1386 | */ |
1384 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | | 1387 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); |
1385 | AR5K_BEACON_RESET_TSF); | 1388 | ath5k_hw_reset_tsf(ah); |
1386 | |||
1387 | return 0; | 1389 | return 0; |
1388 | } | 1390 | } |
1389 | 1391 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ac34a055c713..0e79e58cf4c9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
1323 | 1323 | ||
1324 | static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | 1324 | static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, |
1325 | struct ieee80211_sta *sta, void *priv_sta, | 1325 | struct ieee80211_sta *sta, void *priv_sta, |
1326 | u32 changed) | 1326 | u32 changed, enum nl80211_channel_type oper_chan_type) |
1327 | { | 1327 | { |
1328 | struct ath_softc *sc = priv; | 1328 | struct ath_softc *sc = priv; |
1329 | struct ath_rate_priv *ath_rc_priv = priv_sta; | 1329 | struct ath_rate_priv *ath_rc_priv = priv_sta; |
@@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1340 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | 1340 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) |
1341 | return; | 1341 | return; |
1342 | 1342 | ||
1343 | if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || | 1343 | if (oper_chan_type == NL80211_CHAN_HT40MINUS || |
1344 | sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) | 1344 | oper_chan_type == NL80211_CHAN_HT40PLUS) |
1345 | oper_cw40 = true; | 1345 | oper_cw40 = true; |
1346 | 1346 | ||
1347 | oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | 1347 | oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 47294f90bbe5..b2c8207f7bc1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2258,7 +2258,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2258 | if (ATH_TXQ_SETUP(sc, i)) { | 2258 | if (ATH_TXQ_SETUP(sc, i)) { |
2259 | txq = &sc->tx.txq[i]; | 2259 | txq = &sc->tx.txq[i]; |
2260 | 2260 | ||
2261 | spin_lock(&txq->axq_lock); | 2261 | spin_lock_bh(&txq->axq_lock); |
2262 | 2262 | ||
2263 | list_for_each_entry_safe(ac, | 2263 | list_for_each_entry_safe(ac, |
2264 | ac_tmp, &txq->axq_acq, list) { | 2264 | ac_tmp, &txq->axq_acq, list) { |
@@ -2279,7 +2279,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2279 | } | 2279 | } |
2280 | } | 2280 | } |
2281 | 2281 | ||
2282 | spin_unlock(&txq->axq_lock); | 2282 | spin_unlock_bh(&txq->axq_lock); |
2283 | } | 2283 | } |
2284 | } | 2284 | } |
2285 | } | 2285 | } |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 63c2a7ade5fb..5c7aa1b1eb56 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -3177,14 +3177,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) | |||
3177 | int total_nr = 0; | 3177 | int total_nr = 0; |
3178 | int i; | 3178 | int i; |
3179 | struct pci_pool *pool; | 3179 | struct pci_pool *pool; |
3180 | u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; | 3180 | void **virts; |
3181 | dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; | 3181 | dma_addr_t *phys; |
3182 | 3182 | ||
3183 | IPW_DEBUG_TRACE("<< : \n"); | 3183 | IPW_DEBUG_TRACE("<< : \n"); |
3184 | 3184 | ||
3185 | virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, | ||
3186 | GFP_KERNEL); | ||
3187 | if (!virts) | ||
3188 | return -ENOMEM; | ||
3189 | |||
3190 | phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL, | ||
3191 | GFP_KERNEL); | ||
3192 | if (!phys) { | ||
3193 | kfree(virts); | ||
3194 | return -ENOMEM; | ||
3195 | } | ||
3185 | pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); | 3196 | pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); |
3186 | if (!pool) { | 3197 | if (!pool) { |
3187 | IPW_ERROR("pci_pool_create failed\n"); | 3198 | IPW_ERROR("pci_pool_create failed\n"); |
3199 | kfree(phys); | ||
3200 | kfree(virts); | ||
3188 | return -ENOMEM; | 3201 | return -ENOMEM; |
3189 | } | 3202 | } |
3190 | 3203 | ||
@@ -3254,6 +3267,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) | |||
3254 | pci_pool_free(pool, virts[i], phys[i]); | 3267 | pci_pool_free(pool, virts[i], phys[i]); |
3255 | 3268 | ||
3256 | pci_pool_destroy(pool); | 3269 | pci_pool_destroy(pool); |
3270 | kfree(phys); | ||
3271 | kfree(virts); | ||
3257 | 3272 | ||
3258 | return ret; | 3273 | return ret; |
3259 | } | 3274 | } |
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391172f3..a6d5e42647e4 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -797,7 +797,7 @@ struct libipw_device { | |||
797 | /* Probe / Beacon management */ | 797 | /* Probe / Beacon management */ |
798 | struct list_head network_free_list; | 798 | struct list_head network_free_list; |
799 | struct list_head network_list; | 799 | struct list_head network_list; |
800 | struct libipw_network *networks; | 800 | struct libipw_network *networks[MAX_NETWORK_COUNT]; |
801 | int scans; | 801 | int scans; |
802 | int scan_age; | 802 | int scan_age; |
803 | 803 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 1ae0b2b02c38..2fa55867bd8b 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid; | |||
67 | 67 | ||
68 | static int libipw_networks_allocate(struct libipw_device *ieee) | 68 | static int libipw_networks_allocate(struct libipw_device *ieee) |
69 | { | 69 | { |
70 | if (ieee->networks) | 70 | int i, j; |
71 | return 0; | 71 | |
72 | 72 | for (i = 0; i < MAX_NETWORK_COUNT; i++) { | |
73 | ieee->networks = | 73 | ieee->networks[i] = kzalloc(sizeof(struct libipw_network), |
74 | kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), | 74 | GFP_KERNEL); |
75 | GFP_KERNEL); | 75 | if (!ieee->networks[i]) { |
76 | if (!ieee->networks) { | 76 | LIBIPW_ERROR("Out of memory allocating beacons\n"); |
77 | printk(KERN_WARNING "%s: Out of memory allocating beacons\n", | 77 | for (j = 0; j < i; j++) |
78 | ieee->dev->name); | 78 | kfree(ieee->networks[j]); |
79 | return -ENOMEM; | 79 | return -ENOMEM; |
80 | } | ||
80 | } | 81 | } |
81 | 82 | ||
82 | return 0; | 83 | return 0; |
@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee) | |||
97 | { | 98 | { |
98 | int i; | 99 | int i; |
99 | 100 | ||
100 | if (!ieee->networks) | 101 | for (i = 0; i < MAX_NETWORK_COUNT; i++) { |
101 | return; | 102 | if (ieee->networks[i]->ibss_dfs) |
102 | 103 | kfree(ieee->networks[i]->ibss_dfs); | |
103 | for (i = 0; i < MAX_NETWORK_COUNT; i++) | 104 | kfree(ieee->networks[i]); |
104 | if (ieee->networks[i].ibss_dfs) | 105 | } |
105 | kfree(ieee->networks[i].ibss_dfs); | ||
106 | |||
107 | kfree(ieee->networks); | ||
108 | ieee->networks = NULL; | ||
109 | } | 106 | } |
110 | 107 | ||
111 | void libipw_networks_age(struct libipw_device *ieee, | 108 | void libipw_networks_age(struct libipw_device *ieee, |
@@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee) | |||
130 | INIT_LIST_HEAD(&ieee->network_free_list); | 127 | INIT_LIST_HEAD(&ieee->network_free_list); |
131 | INIT_LIST_HEAD(&ieee->network_list); | 128 | INIT_LIST_HEAD(&ieee->network_list); |
132 | for (i = 0; i < MAX_NETWORK_COUNT; i++) | 129 | for (i = 0; i < MAX_NETWORK_COUNT; i++) |
133 | list_add_tail(&ieee->networks[i].list, | 130 | list_add_tail(&ieee->networks[i]->list, |
134 | &ieee->network_free_list); | 131 | &ieee->network_free_list); |
135 | } | 132 | } |
136 | 133 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 303cc8193adc..e0678d921055 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
184 | { | 184 | { |
185 | int idx; | 185 | int idx; |
186 | 186 | ||
187 | for (idx = 0; idx < IWL_RATE_COUNT; idx++) | 187 | for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) |
188 | if (iwl3945_rates[idx].plcp == plcp) | 188 | if (iwl3945_rates[idx].plcp == plcp) |
189 | return idx; | 189 | return idx; |
190 | return -1; | 190 | return -1; |
@@ -805,7 +805,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
805 | int sta_id, int tx_id) | 805 | int sta_id, int tx_id) |
806 | { | 806 | { |
807 | u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; | 807 | u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; |
808 | u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); | 808 | u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); |
809 | u16 rate_mask; | 809 | u16 rate_mask; |
810 | int rate; | 810 | int rate; |
811 | u8 rts_retry_limit; | 811 | u8 rts_retry_limit; |
@@ -2146,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) | |||
2146 | 2146 | ||
2147 | /* fill in channel group's nominal powers for each rate */ | 2147 | /* fill in channel group's nominal powers for each rate */ |
2148 | for (rate_index = 0; | 2148 | for (rate_index = 0; |
2149 | rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { | 2149 | rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { |
2150 | switch (rate_index) { | 2150 | switch (rate_index) { |
2151 | case IWL_RATE_36M_INDEX_TABLE: | 2151 | case IWL_RATE_36M_INDEX_TABLE: |
2152 | if (i == 0) /* B/G */ | 2152 | if (i == 0) /* B/G */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6aeb82b6992f..818367b57bab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1463,59 +1463,66 @@ static void iwl_nic_start(struct iwl_priv *priv) | |||
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | 1465 | ||
1466 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
1467 | static int iwl_mac_setup_register(struct iwl_priv *priv); | ||
1468 | |||
1469 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | ||
1470 | { | ||
1471 | const char *name_pre = priv->cfg->fw_name_pre; | ||
1472 | |||
1473 | if (first) | ||
1474 | priv->fw_index = priv->cfg->ucode_api_max; | ||
1475 | else | ||
1476 | priv->fw_index--; | ||
1477 | |||
1478 | if (priv->fw_index < priv->cfg->ucode_api_min) { | ||
1479 | IWL_ERR(priv, "no suitable firmware found!\n"); | ||
1480 | return -ENOENT; | ||
1481 | } | ||
1482 | |||
1483 | sprintf(priv->firmware_name, "%s%d%s", | ||
1484 | name_pre, priv->fw_index, ".ucode"); | ||
1485 | |||
1486 | IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", | ||
1487 | priv->firmware_name); | ||
1488 | |||
1489 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | ||
1490 | &priv->pci_dev->dev, GFP_KERNEL, priv, | ||
1491 | iwl_ucode_callback); | ||
1492 | } | ||
1493 | |||
1466 | /** | 1494 | /** |
1467 | * iwl_read_ucode - Read uCode images from disk file. | 1495 | * iwl_ucode_callback - callback when firmware was loaded |
1468 | * | 1496 | * |
1469 | * Copy into buffers for card to fetch via bus-mastering | 1497 | * If loaded successfully, copies the firmware into buffers |
1498 | * for the card to fetch (via DMA). | ||
1470 | */ | 1499 | */ |
1471 | static int iwl_read_ucode(struct iwl_priv *priv) | 1500 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) |
1472 | { | 1501 | { |
1502 | struct iwl_priv *priv = context; | ||
1473 | struct iwl_ucode_header *ucode; | 1503 | struct iwl_ucode_header *ucode; |
1474 | int ret = -EINVAL, index; | ||
1475 | const struct firmware *ucode_raw; | ||
1476 | const char *name_pre = priv->cfg->fw_name_pre; | ||
1477 | const unsigned int api_max = priv->cfg->ucode_api_max; | 1504 | const unsigned int api_max = priv->cfg->ucode_api_max; |
1478 | const unsigned int api_min = priv->cfg->ucode_api_min; | 1505 | const unsigned int api_min = priv->cfg->ucode_api_min; |
1479 | char buf[25]; | ||
1480 | u8 *src; | 1506 | u8 *src; |
1481 | size_t len; | 1507 | size_t len; |
1482 | u32 api_ver, build; | 1508 | u32 api_ver, build; |
1483 | u32 inst_size, data_size, init_size, init_data_size, boot_size; | 1509 | u32 inst_size, data_size, init_size, init_data_size, boot_size; |
1510 | int err; | ||
1484 | u16 eeprom_ver; | 1511 | u16 eeprom_ver; |
1485 | 1512 | ||
1486 | /* Ask kernel firmware_class module to get the boot firmware off disk. | 1513 | if (!ucode_raw) { |
1487 | * request_firmware() is synchronous, file is in memory on return. */ | 1514 | IWL_ERR(priv, "request for firmware file '%s' failed.\n", |
1488 | for (index = api_max; index >= api_min; index--) { | 1515 | priv->firmware_name); |
1489 | sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); | 1516 | goto try_again; |
1490 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); | ||
1491 | if (ret < 0) { | ||
1492 | IWL_ERR(priv, "%s firmware file req failed: %d\n", | ||
1493 | buf, ret); | ||
1494 | if (ret == -ENOENT) | ||
1495 | continue; | ||
1496 | else | ||
1497 | goto error; | ||
1498 | } else { | ||
1499 | if (index < api_max) | ||
1500 | IWL_ERR(priv, "Loaded firmware %s, " | ||
1501 | "which is deprecated. " | ||
1502 | "Please use API v%u instead.\n", | ||
1503 | buf, api_max); | ||
1504 | |||
1505 | IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n", | ||
1506 | buf, ucode_raw->size); | ||
1507 | break; | ||
1508 | } | ||
1509 | } | 1517 | } |
1510 | 1518 | ||
1511 | if (ret < 0) | 1519 | IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", |
1512 | goto error; | 1520 | priv->firmware_name, ucode_raw->size); |
1513 | 1521 | ||
1514 | /* Make sure that we got at least the v1 header! */ | 1522 | /* Make sure that we got at least the v1 header! */ |
1515 | if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { | 1523 | if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { |
1516 | IWL_ERR(priv, "File size way too small!\n"); | 1524 | IWL_ERR(priv, "File size way too small!\n"); |
1517 | ret = -EINVAL; | 1525 | goto try_again; |
1518 | goto err_release; | ||
1519 | } | 1526 | } |
1520 | 1527 | ||
1521 | /* Data from ucode file: header followed by uCode images */ | 1528 | /* Data from ucode file: header followed by uCode images */ |
@@ -1540,10 +1547,9 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1540 | IWL_ERR(priv, "Driver unable to support your firmware API. " | 1547 | IWL_ERR(priv, "Driver unable to support your firmware API. " |
1541 | "Driver supports v%u, firmware is v%u.\n", | 1548 | "Driver supports v%u, firmware is v%u.\n", |
1542 | api_max, api_ver); | 1549 | api_max, api_ver); |
1543 | priv->ucode_ver = 0; | 1550 | goto try_again; |
1544 | ret = -EINVAL; | ||
1545 | goto err_release; | ||
1546 | } | 1551 | } |
1552 | |||
1547 | if (api_ver != api_max) | 1553 | if (api_ver != api_max) |
1548 | IWL_ERR(priv, "Firmware has old API version. Expected v%u, " | 1554 | IWL_ERR(priv, "Firmware has old API version. Expected v%u, " |
1549 | "got v%u. New firmware can be obtained " | 1555 | "got v%u. New firmware can be obtained " |
@@ -1585,6 +1591,12 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1585 | IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", | 1591 | IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", |
1586 | boot_size); | 1592 | boot_size); |
1587 | 1593 | ||
1594 | /* | ||
1595 | * For any of the failures below (before allocating pci memory) | ||
1596 | * we will try to load a version with a smaller API -- maybe the | ||
1597 | * user just got a corrupted version of the latest API. | ||
1598 | */ | ||
1599 | |||
1588 | /* Verify size of file vs. image size info in file's header */ | 1600 | /* Verify size of file vs. image size info in file's header */ |
1589 | if (ucode_raw->size != | 1601 | if (ucode_raw->size != |
1590 | priv->cfg->ops->ucode->get_header_size(api_ver) + | 1602 | priv->cfg->ops->ucode->get_header_size(api_ver) + |
@@ -1594,41 +1606,35 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1594 | IWL_DEBUG_INFO(priv, | 1606 | IWL_DEBUG_INFO(priv, |
1595 | "uCode file size %d does not match expected size\n", | 1607 | "uCode file size %d does not match expected size\n", |
1596 | (int)ucode_raw->size); | 1608 | (int)ucode_raw->size); |
1597 | ret = -EINVAL; | 1609 | goto try_again; |
1598 | goto err_release; | ||
1599 | } | 1610 | } |
1600 | 1611 | ||
1601 | /* Verify that uCode images will fit in card's SRAM */ | 1612 | /* Verify that uCode images will fit in card's SRAM */ |
1602 | if (inst_size > priv->hw_params.max_inst_size) { | 1613 | if (inst_size > priv->hw_params.max_inst_size) { |
1603 | IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", | 1614 | IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", |
1604 | inst_size); | 1615 | inst_size); |
1605 | ret = -EINVAL; | 1616 | goto try_again; |
1606 | goto err_release; | ||
1607 | } | 1617 | } |
1608 | 1618 | ||
1609 | if (data_size > priv->hw_params.max_data_size) { | 1619 | if (data_size > priv->hw_params.max_data_size) { |
1610 | IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", | 1620 | IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", |
1611 | data_size); | 1621 | data_size); |
1612 | ret = -EINVAL; | 1622 | goto try_again; |
1613 | goto err_release; | ||
1614 | } | 1623 | } |
1615 | if (init_size > priv->hw_params.max_inst_size) { | 1624 | if (init_size > priv->hw_params.max_inst_size) { |
1616 | IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", | 1625 | IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", |
1617 | init_size); | 1626 | init_size); |
1618 | ret = -EINVAL; | 1627 | goto try_again; |
1619 | goto err_release; | ||
1620 | } | 1628 | } |
1621 | if (init_data_size > priv->hw_params.max_data_size) { | 1629 | if (init_data_size > priv->hw_params.max_data_size) { |
1622 | IWL_INFO(priv, "uCode init data len %d too large to fit in\n", | 1630 | IWL_INFO(priv, "uCode init data len %d too large to fit in\n", |
1623 | init_data_size); | 1631 | init_data_size); |
1624 | ret = -EINVAL; | 1632 | goto try_again; |
1625 | goto err_release; | ||
1626 | } | 1633 | } |
1627 | if (boot_size > priv->hw_params.max_bsm_size) { | 1634 | if (boot_size > priv->hw_params.max_bsm_size) { |
1628 | IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", | 1635 | IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", |
1629 | boot_size); | 1636 | boot_size); |
1630 | ret = -EINVAL; | 1637 | goto try_again; |
1631 | goto err_release; | ||
1632 | } | 1638 | } |
1633 | 1639 | ||
1634 | /* Allocate ucode buffers for card's bus-master loading ... */ | 1640 | /* Allocate ucode buffers for card's bus-master loading ... */ |
@@ -1712,20 +1718,36 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1712 | IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); | 1718 | IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); |
1713 | memcpy(priv->ucode_boot.v_addr, src, len); | 1719 | memcpy(priv->ucode_boot.v_addr, src, len); |
1714 | 1720 | ||
1721 | /************************************************** | ||
1722 | * This is still part of probe() in a sense... | ||
1723 | * | ||
1724 | * 9. Setup and register with mac80211 and debugfs | ||
1725 | **************************************************/ | ||
1726 | err = iwl_mac_setup_register(priv); | ||
1727 | if (err) | ||
1728 | goto out_unbind; | ||
1729 | |||
1730 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
1731 | if (err) | ||
1732 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
1733 | |||
1715 | /* We have our copies now, allow OS release its copies */ | 1734 | /* We have our copies now, allow OS release its copies */ |
1716 | release_firmware(ucode_raw); | 1735 | release_firmware(ucode_raw); |
1717 | return 0; | 1736 | return; |
1737 | |||
1738 | try_again: | ||
1739 | /* try next, if any */ | ||
1740 | if (iwl_request_firmware(priv, false)) | ||
1741 | goto out_unbind; | ||
1742 | release_firmware(ucode_raw); | ||
1743 | return; | ||
1718 | 1744 | ||
1719 | err_pci_alloc: | 1745 | err_pci_alloc: |
1720 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1746 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1721 | ret = -ENOMEM; | ||
1722 | iwl_dealloc_ucode_pci(priv); | 1747 | iwl_dealloc_ucode_pci(priv); |
1723 | 1748 | out_unbind: | |
1724 | err_release: | 1749 | device_release_driver(&priv->pci_dev->dev); |
1725 | release_firmware(ucode_raw); | 1750 | release_firmware(ucode_raw); |
1726 | |||
1727 | error: | ||
1728 | return ret; | ||
1729 | } | 1751 | } |
1730 | 1752 | ||
1731 | static const char *desc_lookup_text[] = { | 1753 | static const char *desc_lookup_text[] = { |
@@ -2631,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) | |||
2631 | */ | 2653 | */ |
2632 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 2654 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
2633 | 2655 | ||
2634 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1; | 2656 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; |
2635 | /* we create the 802.11 header and a zero-length SSID element */ | 2657 | /* we create the 802.11 header and a zero-length SSID element */ |
2636 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; | 2658 | hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; |
2637 | 2659 | ||
@@ -2667,21 +2689,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2667 | 2689 | ||
2668 | /* we should be verifying the device is ready to be opened */ | 2690 | /* we should be verifying the device is ready to be opened */ |
2669 | mutex_lock(&priv->mutex); | 2691 | mutex_lock(&priv->mutex); |
2670 | |||
2671 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | ||
2672 | * ucode filename and max sizes are card-specific. */ | ||
2673 | |||
2674 | if (!priv->ucode_code.len) { | ||
2675 | ret = iwl_read_ucode(priv); | ||
2676 | if (ret) { | ||
2677 | IWL_ERR(priv, "Could not read microcode: %d\n", ret); | ||
2678 | mutex_unlock(&priv->mutex); | ||
2679 | return ret; | ||
2680 | } | ||
2681 | } | ||
2682 | |||
2683 | ret = __iwl_up(priv); | 2692 | ret = __iwl_up(priv); |
2684 | |||
2685 | mutex_unlock(&priv->mutex); | 2693 | mutex_unlock(&priv->mutex); |
2686 | 2694 | ||
2687 | if (ret) | 2695 | if (ret) |
@@ -3654,17 +3662,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3654 | iwl_power_initialize(priv); | 3662 | iwl_power_initialize(priv); |
3655 | iwl_tt_initialize(priv); | 3663 | iwl_tt_initialize(priv); |
3656 | 3664 | ||
3657 | /************************************************** | 3665 | err = iwl_request_firmware(priv, true); |
3658 | * 9. Setup and register with mac80211 and debugfs | ||
3659 | **************************************************/ | ||
3660 | err = iwl_mac_setup_register(priv); | ||
3661 | if (err) | 3666 | if (err) |
3662 | goto out_remove_sysfs; | 3667 | goto out_remove_sysfs; |
3663 | 3668 | ||
3664 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
3665 | if (err) | ||
3666 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
3667 | |||
3668 | return 0; | 3669 | return 0; |
3669 | 3670 | ||
3670 | out_remove_sysfs: | 3671 | out_remove_sysfs: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ab891b958042..6054c5fba0c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1132,6 +1132,7 @@ struct iwl_priv { | |||
1132 | u8 rev_id; | 1132 | u8 rev_id; |
1133 | 1133 | ||
1134 | /* uCode images, save to reload in case of failure */ | 1134 | /* uCode images, save to reload in case of failure */ |
1135 | int fw_index; /* firmware we're trying to load */ | ||
1135 | u32 ucode_ver; /* version of ucode, copy of | 1136 | u32 ucode_ver; /* version of ucode, copy of |
1136 | iwl_ucode.ver */ | 1137 | iwl_ucode.ver */ |
1137 | struct fw_desc ucode_code; /* runtime inst */ | 1138 | struct fw_desc ucode_code; /* runtime inst */ |
@@ -1142,6 +1143,7 @@ struct iwl_priv { | |||
1142 | struct fw_desc ucode_boot; /* bootstrap inst */ | 1143 | struct fw_desc ucode_boot; /* bootstrap inst */ |
1143 | enum ucode_type ucode_type; | 1144 | enum ucode_type ucode_type; |
1144 | u8 ucode_write_complete; /* the image write is complete */ | 1145 | u8 ucode_write_complete; /* the image write is complete */ |
1146 | char firmware_name[25]; | ||
1145 | 1147 | ||
1146 | 1148 | ||
1147 | struct iwl_rxon_time_cmd rxon_timing; | 1149 | struct iwl_rxon_time_cmd rxon_timing; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dd9ff2ed645a..bd2f7c420563 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -638,20 +638,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | |||
638 | if (left < 0) | 638 | if (left < 0) |
639 | return 0; | 639 | return 0; |
640 | *pos++ = WLAN_EID_SSID; | 640 | *pos++ = WLAN_EID_SSID; |
641 | if (!priv->is_internal_short_scan && | 641 | *pos++ = 0; |
642 | priv->scan_request->n_ssids) { | 642 | |
643 | struct cfg80211_ssid *ssid = | 643 | len += 2; |
644 | priv->scan_request->ssids; | ||
645 | |||
646 | /* Broadcast if ssid_len is 0 */ | ||
647 | *pos++ = ssid->ssid_len; | ||
648 | memcpy(pos, ssid->ssid, ssid->ssid_len); | ||
649 | pos += ssid->ssid_len; | ||
650 | len += 2 + ssid->ssid_len; | ||
651 | } else { | ||
652 | *pos++ = 0; | ||
653 | len += 2; | ||
654 | } | ||
655 | 644 | ||
656 | if (WARN_ON(left < ie_len)) | 645 | if (WARN_ON(left < ie_len)) |
657 | return len; | 646 | return len; |
@@ -780,26 +769,20 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
780 | if (priv->is_internal_short_scan) { | 769 | if (priv->is_internal_short_scan) { |
781 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); | 770 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); |
782 | } else if (priv->scan_request->n_ssids) { | 771 | } else if (priv->scan_request->n_ssids) { |
772 | int i, p = 0; | ||
783 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); | 773 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
784 | /* | 774 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
785 | * The first SSID to scan is stuffed into the probe request | 775 | /* always does wildcard anyway */ |
786 | * template and the remaining ones are handled through the | 776 | if (!priv->scan_request->ssids[i].ssid_len) |
787 | * direct_scan array. | 777 | continue; |
788 | */ | 778 | scan->direct_scan[p].id = WLAN_EID_SSID; |
789 | if (priv->scan_request->n_ssids > 1) { | 779 | scan->direct_scan[p].len = |
790 | int i, p = 0; | 780 | priv->scan_request->ssids[i].ssid_len; |
791 | for (i = 1; i < priv->scan_request->n_ssids; i++) { | 781 | memcpy(scan->direct_scan[p].ssid, |
792 | if (!priv->scan_request->ssids[i].ssid_len) | 782 | priv->scan_request->ssids[i].ssid, |
793 | continue; | 783 | priv->scan_request->ssids[i].ssid_len); |
794 | scan->direct_scan[p].id = WLAN_EID_SSID; | 784 | n_probes++; |
795 | scan->direct_scan[p].len = | 785 | p++; |
796 | priv->scan_request->ssids[i].ssid_len; | ||
797 | memcpy(scan->direct_scan[p].ssid, | ||
798 | priv->scan_request->ssids[i].ssid, | ||
799 | priv->scan_request->ssids[i].ssid_len); | ||
800 | n_probes++; | ||
801 | p++; | ||
802 | } | ||
803 | } | 786 | } |
804 | is_active = true; | 787 | is_active = true; |
805 | } else | 788 | } else |
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h index a3a79b5e2898..a855a99e49b8 100644 --- a/drivers/net/wireless/iwmc3200wifi/lmac.h +++ b/drivers/net/wireless/iwmc3200wifi/lmac.h | |||
@@ -262,7 +262,7 @@ struct iwm_ct_kill_cfg_cmd { | |||
262 | 262 | ||
263 | /* Power Management */ | 263 | /* Power Management */ |
264 | #define POWER_TABLE_CMD 0x77 | 264 | #define POWER_TABLE_CMD 0x77 |
265 | #define SAVE_RESTORE_ADRESS_CMD 0x78 | 265 | #define SAVE_RESTORE_ADDRESS_CMD 0x78 |
266 | #define REPLY_WATERMARK_CMD 0x79 | 266 | #define REPLY_WATERMARK_CMD 0x79 |
267 | #define PM_DEBUG_STATISTIC_NOTIFIC 0x7B | 267 | #define PM_DEBUG_STATISTIC_NOTIFIC 0x7B |
268 | #define PD_FLUSH_N_NOTIFICATION 0x7C | 268 | #define PD_FLUSH_N_NOTIFICATION 0x7C |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9f6d6bf06b8e..2887047069f2 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev) | |||
1496 | { | 1496 | { |
1497 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1497 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1498 | struct dev_mc_list *mclist; | 1498 | struct dev_mc_list *mclist; |
1499 | __le32 filter; | 1499 | __le32 filter, basefilter; |
1500 | int ret, i, size; | 1500 | int ret; |
1501 | char *buf; | 1501 | char *mc_addrs = NULL; |
1502 | int mc_count; | ||
1502 | 1503 | ||
1503 | filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; | 1504 | basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED | |
1505 | RNDIS_PACKET_TYPE_BROADCAST; | ||
1504 | 1506 | ||
1505 | netif_addr_lock_bh(usbdev->net); | ||
1506 | if (usbdev->net->flags & IFF_PROMISC) { | 1507 | if (usbdev->net->flags & IFF_PROMISC) { |
1507 | filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | | 1508 | filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | |
1508 | RNDIS_PACKET_TYPE_ALL_LOCAL; | 1509 | RNDIS_PACKET_TYPE_ALL_LOCAL; |
1509 | } else if (usbdev->net->flags & IFF_ALLMULTI || | 1510 | } else if (usbdev->net->flags & IFF_ALLMULTI) { |
1510 | netdev_mc_count(usbdev->net) > priv->multicast_size) { | 1511 | filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; |
1512 | } | ||
1513 | |||
1514 | if (filter != basefilter) | ||
1515 | goto set_filter; | ||
1516 | |||
1517 | /* | ||
1518 | * mc_list should be accessed holding the lock, so copy addresses to | ||
1519 | * local buffer first. | ||
1520 | */ | ||
1521 | netif_addr_lock_bh(usbdev->net); | ||
1522 | mc_count = netdev_mc_count(usbdev->net); | ||
1523 | if (mc_count > priv->multicast_size) { | ||
1511 | filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; | 1524 | filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; |
1512 | } else if (!netdev_mc_empty(usbdev->net)) { | 1525 | } else if (mc_count) { |
1513 | size = min(priv->multicast_size, netdev_mc_count(usbdev->net)); | 1526 | int i = 0; |
1514 | buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); | 1527 | |
1515 | if (!buf) { | 1528 | mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); |
1529 | if (!mc_addrs) { | ||
1516 | netdev_warn(usbdev->net, | 1530 | netdev_warn(usbdev->net, |
1517 | "couldn't alloc %d bytes of memory\n", | 1531 | "couldn't alloc %d bytes of memory\n", |
1518 | size * ETH_ALEN); | 1532 | mc_count * ETH_ALEN); |
1519 | netif_addr_unlock_bh(usbdev->net); | 1533 | netif_addr_unlock_bh(usbdev->net); |
1520 | return; | 1534 | return; |
1521 | } | 1535 | } |
1522 | 1536 | ||
1523 | i = 0; | 1537 | netdev_for_each_mc_addr(mclist, usbdev->net) |
1524 | netdev_for_each_mc_addr(mclist, usbdev->net) { | 1538 | memcpy(mc_addrs + i++ * ETH_ALEN, |
1525 | if (i == size) | 1539 | mclist->dmi_addr, ETH_ALEN); |
1526 | break; | 1540 | } |
1527 | memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); | 1541 | netif_addr_unlock_bh(usbdev->net); |
1528 | } | ||
1529 | 1542 | ||
1530 | ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, | 1543 | if (filter != basefilter) |
1531 | i * ETH_ALEN); | 1544 | goto set_filter; |
1532 | if (ret == 0 && i > 0) | 1545 | |
1546 | if (mc_count) { | ||
1547 | ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs, | ||
1548 | mc_count * ETH_ALEN); | ||
1549 | kfree(mc_addrs); | ||
1550 | if (ret == 0) | ||
1533 | filter |= RNDIS_PACKET_TYPE_MULTICAST; | 1551 | filter |= RNDIS_PACKET_TYPE_MULTICAST; |
1534 | else | 1552 | else |
1535 | filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; | 1553 | filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; |
1536 | 1554 | ||
1537 | netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", | 1555 | netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", |
1538 | i, priv->multicast_size, ret); | 1556 | mc_count, priv->multicast_size, ret); |
1539 | |||
1540 | kfree(buf); | ||
1541 | } | 1557 | } |
1542 | netif_addr_unlock_bh(usbdev->net); | ||
1543 | 1558 | ||
1559 | set_filter: | ||
1544 | ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, | 1560 | ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, |
1545 | sizeof(filter)); | 1561 | sizeof(filter)); |
1546 | if (ret < 0) { | 1562 | if (ret < 0) { |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index ee34c137e7cd..9b04964deced 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -368,7 +368,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
368 | 368 | ||
369 | /* | 369 | /* |
370 | * The encryption key doesn't fit within the CSR cache, | 370 | * The encryption key doesn't fit within the CSR cache, |
371 | * this means we should allocate it seperately and use | 371 | * this means we should allocate it separately and use |
372 | * rt2x00usb_vendor_request() to send the key to the hardware. | 372 | * rt2x00usb_vendor_request() to send the key to the hardware. |
373 | */ | 373 | */ |
374 | reg = KEY_ENTRY(key->hw_key_idx); | 374 | reg = KEY_ENTRY(key->hw_key_idx); |
@@ -382,7 +382,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
382 | /* | 382 | /* |
383 | * The driver does not support the IV/EIV generation | 383 | * The driver does not support the IV/EIV generation |
384 | * in hardware. However it demands the data to be provided | 384 | * in hardware. However it demands the data to be provided |
385 | * both seperately as well as inside the frame. | 385 | * both separately as well as inside the frame. |
386 | * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib | 386 | * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib |
387 | * to ensure rt2x00lib will not strip the data from the | 387 | * to ensure rt2x00lib will not strip the data from the |
388 | * frame after the copy, now we must tell mac80211 | 388 | * frame after the copy, now we must tell mac80211 |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index aca8c124f434..91cce2d0f6db 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1225,7 +1225,7 @@ MODULE_LICENSE("GPL"); | |||
1225 | #ifdef CONFIG_RT2800PCI_SOC | 1225 | #ifdef CONFIG_RT2800PCI_SOC |
1226 | static int rt2800soc_probe(struct platform_device *pdev) | 1226 | static int rt2800soc_probe(struct platform_device *pdev) |
1227 | { | 1227 | { |
1228 | return rt2x00soc_probe(pdev, rt2800pci_ops); | 1228 | return rt2x00soc_probe(pdev, &rt2800pci_ops); |
1229 | } | 1229 | } |
1230 | 1230 | ||
1231 | static struct platform_driver rt2800soc_driver = { | 1231 | static struct platform_driver rt2800soc_driver = { |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5e4ee2023fcf..d27d7d5d850c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -99,7 +99,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, | |||
99 | * There are 2 variations of the rt2870 firmware. | 99 | * There are 2 variations of the rt2870 firmware. |
100 | * a) size: 4kb | 100 | * a) size: 4kb |
101 | * b) size: 8kb | 101 | * b) size: 8kb |
102 | * Note that (b) contains 2 seperate firmware blobs of 4k | 102 | * Note that (b) contains 2 separate firmware blobs of 4k |
103 | * within the file. The first blob is the same firmware as (a), | 103 | * within the file. The first blob is the same firmware as (a), |
104 | * but the second blob is for the additional chipsets. | 104 | * but the second blob is for the additional chipsets. |
105 | */ | 105 | */ |
@@ -117,7 +117,7 @@ static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, | |||
117 | 117 | ||
118 | /* | 118 | /* |
119 | * 8kb firmware files must be checked as if it were | 119 | * 8kb firmware files must be checked as if it were |
120 | * 2 seperate firmware files. | 120 | * 2 separate firmware files. |
121 | */ | 121 | */ |
122 | while (offset < len) { | 122 | while (offset < len) { |
123 | if (!rt2800usb_check_crc(data + offset, 4096)) | 123 | if (!rt2800usb_check_crc(data + offset, 4096)) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 70c04c282efc..28a1c46ec4eb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -109,7 +109,7 @@ struct rt2x00debug_intf { | |||
109 | 109 | ||
110 | /* | 110 | /* |
111 | * HW crypto statistics. | 111 | * HW crypto statistics. |
112 | * All statistics are stored seperately per cipher type. | 112 | * All statistics are stored separately per cipher type. |
113 | */ | 113 | */ |
114 | struct rt2x00debug_crypto crypto_stats[CIPHER_MAX]; | 114 | struct rt2x00debug_crypto crypto_stats[CIPHER_MAX]; |
115 | 115 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b93731b79903..dd5ab8fe2321 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -394,7 +394,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
394 | /* | 394 | /* |
395 | * Hardware might have stripped the IV/EIV/ICV data, | 395 | * Hardware might have stripped the IV/EIV/ICV data, |
396 | * in that case it is possible that the data was | 396 | * in that case it is possible that the data was |
397 | * provided seperately (through hardware descriptor) | 397 | * provided separately (through hardware descriptor) |
398 | * in which case we should reinsert the data into the frame. | 398 | * in which case we should reinsert the data into the frame. |
399 | */ | 399 | */ |
400 | if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && | 400 | if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 0b4801a14601..5b6b789cad3d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -497,7 +497,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
497 | /* | 497 | /* |
498 | * When hardware encryption is supported, and this frame | 498 | * When hardware encryption is supported, and this frame |
499 | * is to be encrypted, we should strip the IV/EIV data from | 499 | * is to be encrypted, we should strip the IV/EIV data from |
500 | * the frame so we can provide it to the driver seperately. | 500 | * the frame so we can provide it to the driver separately. |
501 | */ | 501 | */ |
502 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && | 502 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && |
503 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { | 503 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index 4efdc96010f6..111c0ff5c6c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c | |||
@@ -112,6 +112,7 @@ exit_free_device: | |||
112 | 112 | ||
113 | return retval; | 113 | return retval; |
114 | } | 114 | } |
115 | EXPORT_SYMBOL_GPL(rt2x00soc_probe); | ||
115 | 116 | ||
116 | int rt2x00soc_remove(struct platform_device *pdev) | 117 | int rt2x00soc_remove(struct platform_device *pdev) |
117 | { | 118 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h index 4739edfe2f00..474cbfc1efc7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.h +++ b/drivers/net/wireless/rt2x00/rt2x00soc.h | |||
@@ -26,8 +26,6 @@ | |||
26 | #ifndef RT2X00SOC_H | 26 | #ifndef RT2X00SOC_H |
27 | #define RT2X00SOC_H | 27 | #define RT2X00SOC_H |
28 | 28 | ||
29 | #define KSEG1ADDR(__ptr) __ptr | ||
30 | |||
31 | /* | 29 | /* |
32 | * SoC driver handlers. | 30 | * SoC driver handlers. |
33 | */ | 31 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e2da928dd9f0..177472742172 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -476,7 +476,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
476 | * The driver does not support the IV/EIV generation | 476 | * The driver does not support the IV/EIV generation |
477 | * in hardware. However it doesn't support the IV/EIV | 477 | * in hardware. However it doesn't support the IV/EIV |
478 | * inside the ieee80211 frame either, but requires it | 478 | * inside the ieee80211 frame either, but requires it |
479 | * to be provided seperately for the descriptor. | 479 | * to be provided separately for the descriptor. |
480 | * rt2x00lib will cut the IV/EIV data out of all frames | 480 | * rt2x00lib will cut the IV/EIV data out of all frames |
481 | * given to us by mac80211, but we must tell mac80211 | 481 | * given to us by mac80211, but we must tell mac80211 |
482 | * to generate the IV/EIV data. | 482 | * to generate the IV/EIV data. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f39a8ed17841..290d70bc5d22 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -339,7 +339,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
339 | * The driver does not support the IV/EIV generation | 339 | * The driver does not support the IV/EIV generation |
340 | * in hardware. However it doesn't support the IV/EIV | 340 | * in hardware. However it doesn't support the IV/EIV |
341 | * inside the ieee80211 frame either, but requires it | 341 | * inside the ieee80211 frame either, but requires it |
342 | * to be provided seperately for the descriptor. | 342 | * to be provided separately for the descriptor. |
343 | * rt2x00lib will cut the IV/EIV data out of all frames | 343 | * rt2x00lib will cut the IV/EIV data out of all frames |
344 | * given to us by mac80211, but we must tell mac80211 | 344 | * given to us by mac80211, but we must tell mac80211 |
345 | * to generate the IV/EIV data. | 345 | * to generate the IV/EIV data. |
@@ -439,7 +439,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
439 | * The driver does not support the IV/EIV generation | 439 | * The driver does not support the IV/EIV generation |
440 | * in hardware. However it doesn't support the IV/EIV | 440 | * in hardware. However it doesn't support the IV/EIV |
441 | * inside the ieee80211 frame either, but requires it | 441 | * inside the ieee80211 frame either, but requires it |
442 | * to be provided seperately for the descriptor. | 442 | * to be provided separately for the descriptor. |
443 | * rt2x00lib will cut the IV/EIV data out of all frames | 443 | * rt2x00lib will cut the IV/EIV data out of all frames |
444 | * given to us by mac80211, but we must tell mac80211 | 444 | * given to us by mac80211, but we must tell mac80211 |
445 | * to generate the IV/EIV data. | 445 | * to generate the IV/EIV data. |
@@ -1661,7 +1661,7 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1661 | 1661 | ||
1662 | /* | 1662 | /* |
1663 | * Hardware has stripped IV/EIV data from 802.11 frame during | 1663 | * Hardware has stripped IV/EIV data from 802.11 frame during |
1664 | * decryption. It has provided the data seperately but rt2x00lib | 1664 | * decryption. It has provided the data separately but rt2x00lib |
1665 | * should decide if it should be reinserted. | 1665 | * should decide if it should be reinserted. |
1666 | */ | 1666 | */ |
1667 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | 1667 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; |
@@ -2352,6 +2352,8 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2352 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | 2352 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, |
2353 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, | 2353 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, |
2354 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, | 2354 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, |
2355 | /* CEIVA */ | ||
2356 | { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2355 | /* CNet */ | 2357 | /* CNet */ |
2356 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, | 2358 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, |
2357 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2359 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 2d555cc30508..00e09e26c826 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -350,7 +350,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
350 | first_idx = info->status.rates[0].idx; | 350 | first_idx = info->status.rates[0].idx; |
351 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); | 351 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); |
352 | retries = &zd_retry_rates[first_idx]; | 352 | retries = &zd_retry_rates[first_idx]; |
353 | ZD_ASSERT(0<=retry && retry<=retries->count); | 353 | ZD_ASSERT(1 <= retry && retry <= retries->count); |
354 | 354 | ||
355 | info->status.rates[0].idx = retries->rate[0]; | 355 | info->status.rates[0].idx = retries->rate[0]; |
356 | info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); | 356 | info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); |
@@ -360,7 +360,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
360 | info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); | 360 | info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); |
361 | } | 361 | } |
362 | for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) { | 362 | for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) { |
363 | info->status.rates[i].idx = retries->rate[retry-1]; | 363 | info->status.rates[i].idx = retries->rate[retry - 1]; |
364 | info->status.rates[i].count = 1; // (success ? 1:2); | 364 | info->status.rates[i].count = 1; // (success ? 1:2); |
365 | } | 365 | } |
366 | if (i<IEEE80211_TX_MAX_RATES) | 366 | if (i<IEEE80211_TX_MAX_RATES) |
@@ -374,7 +374,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
374 | * zd_mac_tx_failed - callback for failed frames | 374 | * zd_mac_tx_failed - callback for failed frames |
375 | * @dev: the mac80211 wireless device | 375 | * @dev: the mac80211 wireless device |
376 | * | 376 | * |
377 | * This function is called if a frame couldn't be successfully be | 377 | * This function is called if a frame couldn't be successfully |
378 | * transferred. The first frame from the tx queue, will be selected and | 378 | * transferred. The first frame from the tx queue, will be selected and |
379 | * reported as error to the upper layers. | 379 | * reported as error to the upper layers. |
380 | */ | 380 | */ |
@@ -424,12 +424,10 @@ void zd_mac_tx_failed(struct urb *urb) | |||
424 | first_idx = info->status.rates[0].idx; | 424 | first_idx = info->status.rates[0].idx; |
425 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); | 425 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); |
426 | retries = &zd_retry_rates[first_idx]; | 426 | retries = &zd_retry_rates[first_idx]; |
427 | if (retry < 0 || retry > retries->count) { | 427 | if (retry <= 0 || retry > retries->count) |
428 | continue; | 428 | continue; |
429 | } | ||
430 | 429 | ||
431 | ZD_ASSERT(0<=retry && retry<=retries->count); | 430 | final_idx = retries->rate[retry - 1]; |
432 | final_idx = retries->rate[retry-1]; | ||
433 | final_rate = zd_rates[final_idx].hw_value; | 431 | final_rate = zd_rates[final_idx].hw_value; |
434 | 432 | ||
435 | if (final_rate != tx_status->rate) { | 433 | if (final_rate != tx_status->rate) { |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 0bc5d474b168..1062b8ffe244 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr, | |||
481 | return ret; | 481 | return ret; |
482 | } | 482 | } |
483 | 483 | ||
484 | static struct sysfs_ops pdcspath_attr_ops = { | 484 | static const struct sysfs_ops pdcspath_attr_ops = { |
485 | .show = pdcspath_attr_show, | 485 | .show = pdcspath_attr_show, |
486 | .store = pdcspath_attr_store, | 486 | .store = pdcspath_attr_store, |
487 | }; | 487 | }; |
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog deleted file mode 100644 index 8565bbbeb6ec..000000000000 --- a/drivers/parport/ChangeLog +++ /dev/null | |||
@@ -1,583 +0,0 @@ | |||
1 | 2001-10-11 Tim Waugh <twaugh@redhat.com> | ||
2 | * parport_pc.c, parport_serial.c: Support for NetMos cards. | ||
3 | + Patch originally from Michael Reinelt <reinelt@eunet.at>. | ||
4 | |||
5 | 2002-04-25 Tim Waugh <twaugh@redhat.com> | ||
6 | |||
7 | * parport_serial.c, parport_pc.c: Move some SIIG cards around. | ||
8 | Patch from Andrey Panin. | ||
9 | |||
10 | 2002-01-20 Tim Waugh <twaugh@redhat.com> | ||
11 | |||
12 | * parport_pc.c (parport_pc_compat_write_block_pio, | ||
13 | parport_pc_ecp_write_block_pio, parport_pc_ecp_read_block_pio): | ||
14 | Use the default implementations if the caller wants to use | ||
15 | O_NONBLOCK. | ||
16 | |||
17 | 2002-02-25 Tim Waugh <twaugh@redhat.com> | ||
18 | |||
19 | * parport_pc.c: Make sure that priv->ctr_writable includes IntEn | ||
20 | even if IRQ is given as a parameter. | ||
21 | |||
22 | 2002-01-21 Tim Waugh <twaugh@redhat.com> | ||
23 | |||
24 | * daisy.c: Apply patch from Max Vorobiev to make parport_daisy_select | ||
25 | work for ECP/EPP modes. | ||
26 | |||
27 | 2002-01-13 Niels Kristian Bech Jensen <nkbj@image.dk> | ||
28 | |||
29 | * parport_pc.c: Change some occurrences of frob_set_mode to | ||
30 | ECR_WRITE. This fixes PLIP. | ||
31 | |||
32 | 2002-01-04 Tim Waugh <twaugh@redhat.com> | ||
33 | |||
34 | * share.c (parport_claim_or_block): Sleep interruptibly to prevent | ||
35 | a possible deadlock. | ||
36 | |||
37 | 2001-12-07 Damian Gruszka <damian.gruszka@VisionSystems.de> | ||
38 | |||
39 | * parport_pc.c (ECR_WRITE): Define. If there are forbidden bits | ||
40 | in the ECR register for some chips, this will be a useful place to | ||
41 | put that knowledge. | ||
42 | (change_mode): Use ECR_WRITE. | ||
43 | (parport_pc_restore_state): Likewise. | ||
44 | (parport_ECPPS2_supported): Likewise. | ||
45 | (parport_ECPEPP_supported): Likewise. | ||
46 | (irq_probe_EPP): Likewise. | ||
47 | (programmable_irq_support): Likewise. | ||
48 | (programmable_dma_support): Likewise. | ||
49 | (parport_pc_probe_port): Likewise. | ||
50 | |||
51 | (frob_set_mode): New function. Set the mode bits of the ECR. | ||
52 | (get_fifo_residue): Use frob_set_mode. | ||
53 | (parport_pc_ecpepp_read_data): Likewise. | ||
54 | (parport_pc_ecpepp_write_data): Likewise. | ||
55 | (parport_pc_ecpepp_read_addr): Likewise. | ||
56 | (parport_pc_ecpepp_write_addr): Likewise. | ||
57 | (parport_pc_compat_write_block_pio): Likewise. | ||
58 | (parport_pc_ecp_write_block_pio): Likewise. | ||
59 | (parport_ECR_present): Likewise. | ||
60 | (parport_ECP_supported): Likewise. | ||
61 | (parport_EPP_supported): Likewise. | ||
62 | (parport_ECPEPP_supported): Likewise. | ||
63 | (programmable_irq_support): Likewise. | ||
64 | (irq_probe_ECP): Likewise. | ||
65 | (programmable_dma_support): Likewise. | ||
66 | |||
67 | (parport_pc_enable_irq): Only enable interrupts if we know which | ||
68 | IRQ line they will come from. | ||
69 | (parport_pc_init_state): Set nErrIntrEn at initialisation. | ||
70 | (parport_pc_restore_state): Only write writable bits of CTR. | ||
71 | (parport_irq_probe): If no IRQ is found, take ackIntEn out of the | ||
72 | writable bit set. | ||
73 | |||
74 | 2001-12-07 Tim Waugh <twaugh@redhat.com> | ||
75 | |||
76 | * parport_pc.c (parport_pc_fifo_write_block_pio): Correct typo. | ||
77 | (parport_pc_init_state): Only set ackIntEn if we know which IRQ | ||
78 | line the interrupts will come from. | ||
79 | |||
80 | 2001-12-07 Tim Waugh <twaugh@redhat.com> | ||
81 | |||
82 | * ieee1284_ops.c (parport_ieee1284_epp_write_addr, | ||
83 | parport_ieee1284_epp_read_addr): Actually do something useful. | ||
84 | |||
85 | 2001-12-07 Tim Waugh <twaugh@redhat.com> | ||
86 | |||
87 | * parport_pc.c (dmaval): Don't use DMA by default. It seems to be | ||
88 | too buggy at the moment. Use 'dma=auto' to restore the previous | ||
89 | behaviour. | ||
90 | |||
91 | 2001-12-07 Tim Waugh <twaugh@redhat.com> | ||
92 | |||
93 | * daisy.c (DEBUG): Undefine. | ||
94 | |||
95 | 2001-12-06 Tim Waugh <twaugh@redhat.com> | ||
96 | |||
97 | * ieee1284_ops.c (parport_ieee1284_ecp_read_data): Mask off | ||
98 | PARPORT_CONTROL_AUTOFD as well. Bug spotted by Joe | ||
99 | <joeja@mindspring.com>. | ||
100 | |||
101 | 2001-12-03 Rich Liu <Rich.Liu@ite.com.tw> | ||
102 | |||
103 | * parport_pc.c (sio_ite_8872_probe): ITE8873 is a single-port | ||
104 | serial board, not a serial+parallel. | ||
105 | |||
106 | 2001-11-30 Niels Kristian Bech Jensen <nkbj@image.dk> | ||
107 | |||
108 | * parport_pc.c: Fix compiler warning. | ||
109 | |||
110 | 2001-11-14 Tim Waugh <twaugh@redhat.com> | ||
111 | |||
112 | * parport_pc.c (parport_pc_pci_probe): Hooks for PCI cards before | ||
113 | and after probing for ports. | ||
114 | * parport_serial.c (parport_register): Likewise. | ||
115 | |||
116 | 2001-11-12 Tim Waugh <twaugh@redhat.com> | ||
117 | |||
118 | * parport_pc.c (init_module): Warn when parameters are ignored. | ||
119 | |||
120 | 2001-11-01 Damian Gruszka <damian.gruszka@VisionSystems.de> | ||
121 | |||
122 | * parport_serial.c (serial_register): Set base_baud before | ||
123 | calling register_serial. | ||
124 | |||
125 | 2001-10-26 Tim Waugh <twaugh@redhat.com> | ||
126 | |||
127 | * parport_pc.c (parport_irq_probe): When ECR programmable IRQ | ||
128 | support fails, generate interrupts using the FIFO even if we don't | ||
129 | want to use the FIFO for real data transfers. | ||
130 | (parport_pc_probe_port): Display the ECR address if we have an | ||
131 | ECR, not just if we will use the FIFO. | ||
132 | |||
133 | 2001-10-24 Dave Strauss <D.Strauss@motorola.com> | ||
134 | |||
135 | * parport_pc.c (parport_pc_compat_write_block_pio, | ||
136 | parport_pc_ecp_write_block_pio): Allow a few seconds for an ECP | ||
137 | transfer to finish up. | ||
138 | |||
139 | 2001-10-11 Tim Waugh <twaugh@redhat.com> | ||
140 | |||
141 | * parport_pc (sio_ite_8872_probe): New function, submitted by Rich | ||
142 | Liu from ITE. Cleaned up, removed bogus phys_to_virt calls. | ||
143 | |||
144 | 2001-10-24 Tim Waugh <twaugh@redhat.com> | ||
145 | |||
146 | * parport_pc.c: Support for AKS AladdinCARD. Patch from | ||
147 | Aladdin Knowledge Systems (Christian Groessler). | ||
148 | |||
149 | 2001-10-24 Tim Waugh <twaugh@redhat.com> | ||
150 | |||
151 | * ieee1284_ops.c (parport_ieee1284_ecp_read_data): Try to minimise | ||
152 | turnaround time. | ||
153 | |||
154 | * ieee1284.c (parport_poll_peripheral): Try a couple of times | ||
155 | first without delaying. | ||
156 | |||
157 | 2001-10-10 Tim Waugh <twaugh@redhat.com> | ||
158 | |||
159 | * parport_pc.c: Support for OX16PCI954 PCI card. | ||
160 | |||
161 | 2001-10-10 Tim Waugh <twaugh@redhat.com> | ||
162 | |||
163 | * parport_pc.c: Support for OX12PCI840 PCI card (reported by | ||
164 | mk@daveg.com). Lock-ups diagnosed by Ronnie Arosa (and now we | ||
165 | just don't trust its ECR). | ||
166 | |||
167 | 2001-10-10 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
168 | |||
169 | * parport_pc.c: Support for AVLAB cards. | ||
170 | |||
171 | 2001-10-10 Tim Waugh <twaugh@redhat.com> | ||
172 | |||
173 | * ieee1284_ops.c (ecp_forward_to_reverse, ecp_reverse_to_forward): | ||
174 | Remember to retry direction switch if it fails. Patch from David | ||
175 | Lambert. | ||
176 | |||
177 | 2001-10-08 David C. Hansen <haveblue@us.ibm.com> | ||
178 | |||
179 | * share.c: Make driverlist_lock and parportlist_lock static. | ||
180 | |||
181 | 2001-10-08 Philip Blundell <philb@gnu.org> | ||
182 | |||
183 | * parport_pc.c: New modular parameter verbose_logging. | ||
184 | Make port->modes indicate the modes that we are prepared to use, | ||
185 | rather than the modes that are available. | ||
186 | |||
187 | 2001-10-07 Tim Waugh <twaugh@redhat.com> | ||
188 | |||
189 | * parport_pc.c (parport_pc_probe_port): Fix memory leak spotted by | ||
190 | Kipp Cannon. | ||
191 | |||
192 | 2001-10-07 Tim Waugh <twaugh@redhat.com> | ||
193 | |||
194 | * parport_serial.c: Remove NetMos support, since it causes problems | ||
195 | for some people. | ||
196 | |||
197 | 2001-08-30 Tim Waugh <twaugh@redhat.com> | ||
198 | |||
199 | * parport_serial.c (parport_serial_pci_probe): Clean-up on partial | ||
200 | registration failure. | ||
201 | |||
202 | 2001-08-14 Tim Waugh <twaugh@redhat.com> | ||
203 | |||
204 | * parport_pc.c (parport_pc_init_superio): Allow for more than one | ||
205 | SuperIO device. Patch from Rich Lio (ITE). | ||
206 | |||
207 | 2001-08-11 Tim Waugh <twaugh@redhat.com> | ||
208 | |||
209 | * parport_pc.c: Support for Titan Electronics cards. | ||
210 | |||
211 | 2001-08-08 Tim Waugh <twaugh@redhat.com> | ||
212 | |||
213 | * share.c (parport_unregister_device): Remove device from wait list | ||
214 | too. | ||
215 | |||
216 | 2001-06-20 Tim Waugh <twaugh@redhat.com> | ||
217 | |||
218 | * parport_pc.c: Make 'io_hi=0' work. | ||
219 | |||
220 | 2001-05-31 Tim Waugh <twaugh@redhat.com> | ||
221 | |||
222 | * parport_serial.c: New file. | ||
223 | |||
224 | 2001-06-05 Tim Waugh <twaugh@redhat.com> | ||
225 | |||
226 | * parport_pc.c (parport_pc_unregister_port): New exported function. | ||
227 | Do the opposite of parport_pc_probe_port. | ||
228 | (cleanup_module): Use it. | ||
229 | |||
230 | 2001-05-22 Juan Quintela <quintela@mandrakesoft.com> | ||
231 | |||
232 | * parport_amiga.c: Set printk levels. | ||
233 | * parport_gsc.c: Likewise. | ||
234 | * parport_mfc3.c: Likewise. | ||
235 | * parport_pc.c: Likewise. | ||
236 | * parport_sunbpp.c: Likewise. | ||
237 | * probe.c: Likewise. | ||
238 | * share.c: Likewise. | ||
239 | |||
240 | 2001-05-10 Fred Barnes <frmb2@ukc.ac.uk> | ||
241 | |||
242 | * parport_pc.c (parport_pc_epp_read_data): added support for | ||
243 | reading from a w91284pic peripheral, flag is PARPORT_W91284PIC. | ||
244 | |||
245 | 2001-05-07 Fred Barnes <frmb2@ukc.ac.uk> | ||
246 | |||
247 | * parport_pc.c (parport_pc_epp_read_data, | ||
248 | parport_pc_epp_write_data, parport_pc_epp_read_addr, | ||
249 | parport_pc_epp_write_addr): support for fast reads/writes using | ||
250 | the PARPORT_EPP_FAST flag. | ||
251 | |||
252 | * ieee1284.c (parport_read, parport_write): added code to handle | ||
253 | software EPP mode (IEEE1284_MODE_EPPSWE). Added code to allow | ||
254 | BYTE mode reverse transfers (previously always went for NIBBLE | ||
255 | mode). | ||
256 | |||
257 | * ieee1284_ops.c (parport_ieee1284_epp_read_data, | ||
258 | parport_ieee1284_epp_write_data): fixed various polarity problems. | ||
259 | Also (theoretically) fixed address versions (.._addr), but no | ||
260 | hardware to test this on. | ||
261 | |||
262 | * parport_pc.h: added parport_dump_state() function for debugging. | ||
263 | Needs to have DEBUG_PARPORT to be defined for it to be included. | ||
264 | |||
265 | 2001-05-03 Tim Waugh <twaugh@redhat.com> | ||
266 | |||
267 | * parport_pc.c: Fix the compile problem I introduce from the last | ||
268 | change. | ||
269 | |||
270 | 2001-04-20 Paul Gortmaker <p_gortmaker@yahoo.com> | ||
271 | |||
272 | * parport_pc.c: Cut down the size quite a bit (more than 4k off | ||
273 | the object, about 1k off the zImage) for the older non-PCI | ||
274 | machines which are typically resource starved anyway... | ||
275 | |||
276 | 2001-03-26 R Horn <rjh@world.std.com> | ||
277 | |||
278 | * parport_pc.c: Some commentary changes. | ||
279 | |||
280 | 2001-04-19 Tim Waugh <twaugh@redhat.com> | ||
281 | |||
282 | * parport_pc.c (parport_pc_probe_port): Remove __devinit | ||
283 | attribute. Export unconditionally. | ||
284 | |||
285 | 2001-04-14 Jeff Garzik <jgarzik@pobox.com> | ||
286 | |||
287 | Merged: 2001-03-30 Tim Waugh <twaugh@redhat.com> | ||
288 | |||
289 | * drivers/parport/parport_pc.c: Make Via SuperIO chipsets behave | ||
290 | like everything else with respect to irq= and dma= parameters. | ||
291 | |||
292 | 2001-04-08 Tim Waugh <twaugh@redhat.com> | ||
293 | |||
294 | * parport_pc.c (parport_pc_save_state): Read from the soft copy of | ||
295 | the control port. | ||
296 | (parport_pc_restore_state): Update the soft copy of the control | ||
297 | port. | ||
298 | |||
299 | 2001-03-26 Tim Waugh <twaugh@redhat.com> | ||
300 | |||
301 | * share.c (parport_find_number, parport_find_base): Trigger | ||
302 | a lowlevel driver load if there are no ports yet. | ||
303 | |||
304 | 2001-03-26 Tim Waugh <twaugh@redhat.com> | ||
305 | |||
306 | * parport_pc.c (parport_ECP_supported): Remove the IRQ conflict | ||
307 | check since it seems totally unreliable. | ||
308 | |||
309 | 2001-03-02 Tim Waugh <twaugh@redhat.com> | ||
310 | |||
311 | * ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd | ||
312 | on timeout. Matches 2.2.x behaviour. | ||
313 | |||
314 | 2001-03-02 Andrew Morton | ||
315 | |||
316 | * parport_pc.c (registered_parport): New static variable. | ||
317 | (parport_pc_find_ports): Set it when we register PCI driver. | ||
318 | (init_module): Unregister PCI driver if necessary when we | ||
319 | fail. | ||
320 | |||
321 | 2001-03-02 Tim Waugh <twaugh@redhat.com> | ||
322 | |||
323 | * ieee1284_ops.c (parport_ieee1284_write_compat): Don't use | ||
324 | down_trylock to reset the IRQ count. Don't even use sema_init, | ||
325 | because it's not even necessary to reset the count. I can't | ||
326 | remember why we ever did. | ||
327 | |||
328 | 2001-01-04 Peter Osterlund <peter.osterlund@mailbox.swipnet.se> | ||
329 | |||
330 | * ieee1284.c (parport_negotiate): Fix missing printk argument. | ||
331 | |||
332 | 2001-01-03 Paul Schleger <Paul.Schleger@t-online.de> | ||
333 | |||
334 | * probe.c (parse_data): Get rid of trailing blanks in values. | ||
335 | Needed for XEROX XJ8C printer. | ||
336 | |||
337 | 2001-01-03 Tim Waugh <twaugh@redhat.com> | ||
338 | |||
339 | * parport_pc.c (parport_pc_probe_port): Say something when probes | ||
340 | are omitted. | ||
341 | |||
342 | 2001-01-03 Tim Waugh <twaugh@redhat.com> | ||
343 | |||
344 | * parport_pc.c (sio_via_686a_probe): Correct dma=255 fix. | ||
345 | |||
346 | 2000-11-21 Tim Waugh <twaugh@redhat.com> | ||
347 | |||
348 | * parport_pc.c (parport_pc_ecp_write_block_pio): Fix | ||
349 | reverse-to-forward logic. Spotted by Roland Kuck | ||
350 | <rci@cityweb.de>. | ||
351 | |||
352 | 2000-09-16 Cesar Eduardo Barros <cesarb@nitnet.com.br> | ||
353 | |||
354 | * parport_pc.c (sio_via_686a_probe): Handle case | ||
355 | where hardware returns 255 for IRQ or DMA. | ||
356 | |||
357 | 2000-07-20 Eddie C. Dost <ecd@skynet.be> | ||
358 | |||
359 | * share.c (attach_driver_chain): attach[i](port) needs to be | ||
360 | replaced by attach[count](port). | ||
361 | |||
362 | 2000-07-20 Eddie C. Dost <ecd@skynet.be> | ||
363 | |||
364 | * daisy.c (add_dev): kmalloc args are in wrong order. | ||
365 | |||
366 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
367 | |||
368 | * share.c: Documentation for parport_{get,port}_port, | ||
369 | parport_find_{number,base}. | ||
370 | |||
371 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
372 | |||
373 | * share.c (parport_unregister_device): Remove unneeded locking | ||
374 | (test cad==dev). | ||
375 | (parport_claim): Likewise. | ||
376 | (parport_find_number): New function. | ||
377 | |||
378 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
379 | |||
380 | * share.c (parport_register_port): Hold the parportlist_lock while | ||
381 | looking for a free parport number. | ||
382 | (parport_register_driver): Make sure that attach can block. | ||
383 | (attach_driver_chain): Likewise. | ||
384 | |||
385 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
386 | |||
387 | * share.c (call_driver_chain): Do reference counting things. | ||
388 | (parport_get_port): New function. | ||
389 | (parport_put_port): New function. | ||
390 | (parport_register_port): Initialise reference count to zero. | ||
391 | (parport_unregister_port): Check reference count rather than | ||
392 | driver list to see if we can free the port. | ||
393 | |||
394 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
395 | |||
396 | * share.c: Clarifications in doc comments. | ||
397 | |||
398 | 2000-07-12 Tim Waugh <twaugh@redhat.com> | ||
399 | |||
400 | * share.c (parport_unregister_port): Fix typo in comment. | ||
401 | |||
402 | 2000-07-11 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
403 | |||
404 | * parport_pc.c: Support for the full range of Timedia cards. | ||
405 | |||
406 | 2000-07-08 Tim Waugh <twaugh@redhat.com> | ||
407 | |||
408 | * daisy.c: License block comments as part of parportbook. | ||
409 | * ieee1284.c: Likewise. | ||
410 | * share.c: Likewise. | ||
411 | |||
412 | 2000-06-30 Petr Vandrovec <vandrove@vc.cvut.cz> | ||
413 | |||
414 | * procfs.c (do_hardware_modes): Generated string can be up to 34 | ||
415 | chars long. | ||
416 | |||
417 | 2000-06-20 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
418 | |||
419 | * parport_pc.c (parport_pc_compat_write_block_pio): Warn about | ||
420 | change_mode failures. | ||
421 | (parport_pc_ecp_write_block_pio): Likewise. | ||
422 | (parport_pc_ecp_read_block_pio): Likewise. | ||
423 | |||
424 | 2000-06-20 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
425 | |||
426 | * parport_pc.c (parport_SPP_supported): Warn more about possibly | ||
427 | incorrect parameters. | ||
428 | |||
429 | 2000-06-15 Tim Waugh <twaugh@redhat.com> | ||
430 | |||
431 | * parport_pc.c (parport_ECP_supported): Set PARPORT_MODE_COMPAT | ||
432 | for ECP ports, since they can all do hardware accelerated | ||
433 | compatibility mode (I assume). | ||
434 | |||
435 | 2000-06-13 Tim Waugh <twaugh@redhat.com> | ||
436 | |||
437 | * parport_pc.c (cleanup_module): Remark about possible bugs. | ||
438 | |||
439 | 2000-06-13 Tim Waugh <twaugh@redhat.com> | ||
440 | |||
441 | * procfs.c: Break 'hardware' out into separate files. | ||
442 | |||
443 | 2000-05-28 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
444 | |||
445 | * Fix PCI ID printk for non-superio PCI cards. | ||
446 | |||
447 | 2000-05-28 Tim Waugh <twaugh@redhat.com> | ||
448 | |||
449 | * share.c (call_driver_chain): Get the driverlist_lock. | ||
450 | (parport_register_device): Make sure that port->devices always | ||
451 | looks consistent. | ||
452 | (parport_register_driver): Ensure that parport drivers are given | ||
453 | parameters that are valid for the duration of the callback by | ||
454 | locking the portlist against changes. | ||
455 | (parport_unregister_driver): Likewise. | ||
456 | (parport_claim): Don't overwrite flags. | ||
457 | |||
458 | 2000-05-28 Tim Waugh <twaugh@redhat.com> | ||
459 | |||
460 | * daisy.c (assign_addrs): Avoid double-probing daisy-chain devices | ||
461 | if the first probe succeeds. | ||
462 | |||
463 | 2000-05-16 Tim Waugh <twaugh@redhat.com> | ||
464 | |||
465 | * share.c (parport_claim): Fix SMP race. | ||
466 | |||
467 | 2000-05-15 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
468 | |||
469 | * parport_pc.c (parport_pc_compat_write_block_pio): Check for | ||
470 | timeouts. | ||
471 | (parport_pc_ecp_write_block_pio): Likewise. | ||
472 | (parport_pc_ecp_read_block_pio): Likewise. | ||
473 | |||
474 | 2000-05-02 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
475 | |||
476 | * parport_pc.c: PCI SYBA patch and verbose PCI detection. | ||
477 | |||
478 | 2000-05-02 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de> | ||
479 | |||
480 | * parport_pc.c (decode_smsc): Fix SMSC 665/666 identification. | ||
481 | |||
482 | 2000-04-28 Tim Waugh <twaugh@redhat.com> | ||
483 | |||
484 | * ieee1284.c: Short function descriptions can't be multiline. | ||
485 | |||
486 | * daisy.c: Short function descriptions can't be multiline. | ||
487 | |||
488 | 2000-04-19 Tim Waugh <twaugh@redhat.com> | ||
489 | |||
490 | * parport_pc.c (parport_pc_fifo_write_block_dma): Make maxlen | ||
491 | calculation a bit clearer. | ||
492 | |||
493 | * ieee1284.c (parport_negotiate): Turn on data line drivers. | ||
494 | |||
495 | * ieee1284_ops.c (parport_ieee1284_read_byte): Turn off data line | ||
496 | drivers. | ||
497 | (parport_ieee1284_write_compat): Turn on data line drivers. | ||
498 | |||
499 | * daisy.c (assign_addrs): Turn on data line drivers. | ||
500 | (cpp_mux): Likewise. | ||
501 | (cpp_daisy): Likewise. | ||
502 | |||
503 | 2000-04-04 Tim Waugh <twaugh@redhat.com> | ||
504 | |||
505 | * parport_pc.c: Add support for another PCI card. | ||
506 | |||
507 | 2000-04-04 Tim Waugh <twaugh@redhat.com> | ||
508 | |||
509 | * daisy.c: Documentation in kernel-doc format. | ||
510 | |||
511 | * ieee1284.c: Likewise. | ||
512 | |||
513 | * share.c: Likewise. | ||
514 | |||
515 | 2000-04-01 Tim Waugh <twaugh@redhat.com> | ||
516 | |||
517 | * share.c (parport_register_device): Need to hold the module | ||
518 | reference counts before sleeping. | ||
519 | |||
520 | 2000-03-27 Tim Waugh <twaugh@redhat.com> | ||
521 | |||
522 | * parport_pc.c (parport_pc_ecp_read_block_pio): Correct operation | ||
523 | when peripheral is trying to send data when we stop listening. | ||
524 | |||
525 | 2000-03-22 Tim Waugh <twaugh@redhat.com> | ||
526 | |||
527 | * init.c (parport_setup): Fix return value. | ||
528 | |||
529 | 2000-03-21 Tim Waugh <twaugh@redhat.com> | ||
530 | |||
531 | * parport_pc.c (parport_pc_pci_probe): Fix return value; call | ||
532 | pci_enable_device. | ||
533 | |||
534 | 2000-03-16 Tim Waugh <twaugh@redhat.com> | ||
535 | |||
536 | * parport_pc.c (parport_ECP_supported): This seems to trigger on | ||
537 | machines that don't have an IRQ conflict; toned down the warning | ||
538 | message accordingly. | ||
539 | |||
540 | 2000-03-16 Gunther Mayer <gunther.mayer@braunschweig.netsurf.de> | ||
541 | |||
542 | * parport_pc.c (show_parconfig_smsc37c669): Fix typo. | ||
543 | (decode_winbond): More IDs. | ||
544 | (winbond_check): Protect against false positives. | ||
545 | (winbond_check2): Likewise. | ||
546 | (smsc_check): Likewise. | ||
547 | |||
548 | 2000-03-15 Tim Waugh <twaugh@redhat.com> | ||
549 | |||
550 | * parport_pc.c (cleanup_module): Don't call pci_unregister_driver | ||
551 | if we didn't call pci_register_driver first. | ||
552 | |||
553 | 2000-03-13 Tim Waugh <twaugh@redhat.com> | ||
554 | |||
555 | * parport_pc.c (parport_pc_init): Moved from asm/parport.h. | ||
556 | |||
557 | * Config.in: CONFIG_PARPORT_PC_SUPERIO: new option. | ||
558 | |||
559 | * parport_pc.c (show_parconfig_smsc37c669): Make __devinit. | ||
560 | (show_parconfig_winbond): Likewise. | ||
561 | (decode_winbond): Likewise. | ||
562 | (decode_smsc): Likewise. | ||
563 | (winbond_check): Likewise. | ||
564 | (winbond_check2): Likewise. | ||
565 | (smsc_check): Likewise. | ||
566 | (detect_and_report_winbond): Likewise. | ||
567 | (detect_and_report_smsc): Likewise. | ||
568 | (get_superio_dma): Likewise. | ||
569 | (get_superio_irq): Likewise. | ||
570 | (parport_pc_find_isa_ports): New function. | ||
571 | (parport_pc_find_ports): New function. | ||
572 | (init_module): Make superio a config option, not a parameter. | ||
573 | |||
574 | 2000-03-10 Tim Waugh <twaugh@redhat.com> | ||
575 | |||
576 | * parport_pc.c (decode_winbond): Use correct 83877ATF chip ID. | ||
577 | (decode_winbond): Fix typo. | ||
578 | |||
579 | 2000-03-09 Tim Waugh <twaugh@redhat.com> | ||
580 | |||
581 | * parport_pc.c: Integrate SuperIO PCI probe with normal PCI card | ||
582 | probe, so that the MODULE_DEVICE_TABLE is complete. | ||
583 | |||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 712250f5874a..26301cb25e7f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -288,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
288 | next = dev->bus_list.next; | 288 | next = dev->bus_list.next; |
289 | 289 | ||
290 | /* Run device routines with the device locked */ | 290 | /* Run device routines with the device locked */ |
291 | down(&dev->dev.sem); | 291 | device_lock(&dev->dev); |
292 | retval = cb(dev, userdata); | 292 | retval = cb(dev, userdata); |
293 | up(&dev->dev.sem); | 293 | device_unlock(&dev->dev); |
294 | if (retval) | 294 | if (retval) |
295 | break; | 295 | break; |
296 | } | 296 | } |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cb2fd01eddae..b5dad9f37453 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -749,6 +749,24 @@ static int acpiphp_bus_trim(acpi_handle handle) | |||
749 | return retval; | 749 | return retval; |
750 | } | 750 | } |
751 | 751 | ||
752 | static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | ||
753 | { | ||
754 | struct acpiphp_func *func; | ||
755 | union acpi_object params[2]; | ||
756 | struct acpi_object_list arg_list; | ||
757 | |||
758 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
759 | arg_list.count = 2; | ||
760 | arg_list.pointer = params; | ||
761 | params[0].type = ACPI_TYPE_INTEGER; | ||
762 | params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; | ||
763 | params[1].type = ACPI_TYPE_INTEGER; | ||
764 | params[1].integer.value = 1; | ||
765 | /* _REG is optional, we don't care about if there is failure */ | ||
766 | acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); | ||
767 | } | ||
768 | } | ||
769 | |||
752 | /** | 770 | /** |
753 | * enable_device - enable, configure a slot | 771 | * enable_device - enable, configure a slot |
754 | * @slot: slot to be enabled | 772 | * @slot: slot to be enabled |
@@ -805,6 +823,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
805 | pci_bus_assign_resources(bus); | 823 | pci_bus_assign_resources(bus); |
806 | acpiphp_sanitize_bus(bus); | 824 | acpiphp_sanitize_bus(bus); |
807 | acpiphp_set_hpp_values(bus); | 825 | acpiphp_set_hpp_values(bus); |
826 | acpiphp_set_acpi_region(slot); | ||
808 | pci_enable_bridges(bus); | 827 | pci_enable_bridges(bus); |
809 | pci_bus_add_devices(bus); | 828 | pci_bus_add_devices(bus); |
810 | 829 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..0a894efd4b9b 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | static struct kobj_type legacy_ktype = { | 75 | static struct kobj_type legacy_ktype = { |
76 | .sysfs_ops = &(struct sysfs_ops){ | 76 | .sysfs_ops = &(const struct sysfs_ops){ |
77 | .store = legacy_store, .show = legacy_show | 77 | .store = legacy_store, .show = legacy_show |
78 | }, | 78 | }, |
79 | .release = &legacy_release, | 79 | .release = &legacy_release, |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 807224ec8351..de296452c957 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -642,6 +642,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
642 | if (!b->legacy_io) | 642 | if (!b->legacy_io) |
643 | goto kzalloc_err; | 643 | goto kzalloc_err; |
644 | 644 | ||
645 | sysfs_bin_attr_init(b->legacy_io); | ||
645 | b->legacy_io->attr.name = "legacy_io"; | 646 | b->legacy_io->attr.name = "legacy_io"; |
646 | b->legacy_io->size = 0xffff; | 647 | b->legacy_io->size = 0xffff; |
647 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | 648 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; |
@@ -654,6 +655,7 @@ void pci_create_legacy_files(struct pci_bus *b) | |||
654 | goto legacy_io_err; | 655 | goto legacy_io_err; |
655 | 656 | ||
656 | /* Allocated above after the legacy_io struct */ | 657 | /* Allocated above after the legacy_io struct */ |
658 | sysfs_bin_attr_init(b->legacy_mem); | ||
657 | b->legacy_mem = b->legacy_io + 1; | 659 | b->legacy_mem = b->legacy_io + 1; |
658 | b->legacy_mem->attr.name = "legacy_mem"; | 660 | b->legacy_mem->attr.name = "legacy_mem"; |
659 | b->legacy_mem->size = 1024*1024; | 661 | b->legacy_mem->size = 1024*1024; |
@@ -800,6 +802,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) | |||
800 | if (res_attr) { | 802 | if (res_attr) { |
801 | char *res_attr_name = (char *)(res_attr + 1); | 803 | char *res_attr_name = (char *)(res_attr + 1); |
802 | 804 | ||
805 | sysfs_bin_attr_init(res_attr); | ||
803 | if (write_combine) { | 806 | if (write_combine) { |
804 | pdev->res_attr_wc[num] = res_attr; | 807 | pdev->res_attr_wc[num] = res_attr; |
805 | sprintf(res_attr_name, "resource%d_wc", num); | 808 | sprintf(res_attr_name, "resource%d_wc", num); |
@@ -972,6 +975,7 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev) | |||
972 | if (!attr) | 975 | if (!attr) |
973 | return -ENOMEM; | 976 | return -ENOMEM; |
974 | 977 | ||
978 | sysfs_bin_attr_init(attr); | ||
975 | attr->size = dev->vpd->len; | 979 | attr->size = dev->vpd->len; |
976 | attr->attr.name = "vpd"; | 980 | attr->attr.name = "vpd"; |
977 | attr->attr.mode = S_IRUSR | S_IWUSR; | 981 | attr->attr.mode = S_IRUSR | S_IWUSR; |
@@ -1038,6 +1042,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
1038 | retval = -ENOMEM; | 1042 | retval = -ENOMEM; |
1039 | goto err_resource_files; | 1043 | goto err_resource_files; |
1040 | } | 1044 | } |
1045 | sysfs_bin_attr_init(attr); | ||
1041 | attr->size = rom_size; | 1046 | attr->size = rom_size; |
1042 | attr->attr.name = "rom"; | 1047 | attr->attr.name = "rom"; |
1043 | attr->attr.mode = S_IRUSR; | 1048 | attr->attr.mode = S_IRUSR; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 77b493b3d97b..cb1dd5f4988c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1583,8 +1583,10 @@ void pci_pm_init(struct pci_dev *dev) | |||
1583 | int pm; | 1583 | int pm; |
1584 | u16 pmc; | 1584 | u16 pmc; |
1585 | 1585 | ||
1586 | pm_runtime_forbid(&dev->dev); | ||
1586 | device_enable_async_suspend(&dev->dev); | 1587 | device_enable_async_suspend(&dev->dev); |
1587 | dev->wakeup_prepared = false; | 1588 | dev->wakeup_prepared = false; |
1589 | |||
1588 | dev->pm_cap = 0; | 1590 | dev->pm_cap = 0; |
1589 | 1591 | ||
1590 | /* find PCI PM capability in list */ | 1592 | /* find PCI PM capability in list */ |
@@ -2296,35 +2298,6 @@ void pci_msi_off(struct pci_dev *dev) | |||
2296 | } | 2298 | } |
2297 | } | 2299 | } |
2298 | 2300 | ||
2299 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | ||
2300 | /* | ||
2301 | * These can be overridden by arch-specific implementations | ||
2302 | */ | ||
2303 | int | ||
2304 | pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
2305 | { | ||
2306 | if (!pci_dma_supported(dev, mask)) | ||
2307 | return -EIO; | ||
2308 | |||
2309 | dev->dma_mask = mask; | ||
2310 | dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask)); | ||
2311 | |||
2312 | return 0; | ||
2313 | } | ||
2314 | |||
2315 | int | ||
2316 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | ||
2317 | { | ||
2318 | if (!pci_dma_supported(dev, mask)) | ||
2319 | return -EIO; | ||
2320 | |||
2321 | dev->dev.coherent_dma_mask = mask; | ||
2322 | dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask)); | ||
2323 | |||
2324 | return 0; | ||
2325 | } | ||
2326 | #endif | ||
2327 | |||
2328 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE | 2301 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE |
2329 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) | 2302 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) |
2330 | { | 2303 | { |
@@ -2486,7 +2459,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2486 | if (!probe) { | 2459 | if (!probe) { |
2487 | pci_block_user_cfg_access(dev); | 2460 | pci_block_user_cfg_access(dev); |
2488 | /* block PM suspend, driver probe, etc. */ | 2461 | /* block PM suspend, driver probe, etc. */ |
2489 | down(&dev->dev.sem); | 2462 | device_lock(&dev->dev); |
2490 | } | 2463 | } |
2491 | 2464 | ||
2492 | rc = pci_dev_specific_reset(dev, probe); | 2465 | rc = pci_dev_specific_reset(dev, probe); |
@@ -2508,7 +2481,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) | |||
2508 | rc = pci_parent_bus_reset(dev, probe); | 2481 | rc = pci_parent_bus_reset(dev, probe); |
2509 | done: | 2482 | done: |
2510 | if (!probe) { | 2483 | if (!probe) { |
2511 | up(&dev->dev.sem); | 2484 | device_unlock(&dev->dev); |
2512 | pci_unblock_user_cfg_access(dev); | 2485 | pci_unblock_user_cfg_access(dev); |
2513 | } | 2486 | } |
2514 | 2487 | ||
@@ -3066,8 +3039,6 @@ EXPORT_SYMBOL(pci_set_mwi); | |||
3066 | EXPORT_SYMBOL(pci_try_set_mwi); | 3039 | EXPORT_SYMBOL(pci_try_set_mwi); |
3067 | EXPORT_SYMBOL(pci_clear_mwi); | 3040 | EXPORT_SYMBOL(pci_clear_mwi); |
3068 | EXPORT_SYMBOL_GPL(pci_intx); | 3041 | EXPORT_SYMBOL_GPL(pci_intx); |
3069 | EXPORT_SYMBOL(pci_set_dma_mask); | ||
3070 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | ||
3071 | EXPORT_SYMBOL(pci_assign_resource); | 3042 | EXPORT_SYMBOL(pci_assign_resource); |
3072 | EXPORT_SYMBOL(pci_find_parent_resource); | 3043 | EXPORT_SYMBOL(pci_find_parent_resource); |
3073 | EXPORT_SYMBOL(pci_select_bars); | 3044 | EXPORT_SYMBOL(pci_select_bars); |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 49c9e6c9779a..f75a44d37fbe 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj, | |||
29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; | 29 | return attribute->store ? attribute->store(slot, buf, len) : -EIO; |
30 | } | 30 | } |
31 | 31 | ||
32 | static struct sysfs_ops pci_slot_sysfs_ops = { | 32 | static const struct sysfs_ops pci_slot_sysfs_ops = { |
33 | .show = pci_slot_attr_show, | 33 | .show = pci_slot_attr_show, |
34 | .store = pci_slot_attr_store, | 34 | .store = pci_slot_attr_store, |
35 | }; | 35 | }; |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0f98be4450b7..ad93ebd7b2a2 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -971,9 +971,9 @@ static int runtime_suspend(struct device *dev) | |||
971 | { | 971 | { |
972 | int rc; | 972 | int rc; |
973 | 973 | ||
974 | down(&dev->sem); | 974 | device_lock(dev); |
975 | rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); | 975 | rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); |
976 | up(&dev->sem); | 976 | device_unlock(dev); |
977 | return rc; | 977 | return rc; |
978 | } | 978 | } |
979 | 979 | ||
@@ -981,9 +981,9 @@ static int runtime_resume(struct device *dev) | |||
981 | { | 981 | { |
982 | int rc; | 982 | int rc; |
983 | 983 | ||
984 | down(&dev->sem); | 984 | device_lock(dev); |
985 | rc = pcmcia_dev_resume(dev); | 985 | rc = pcmcia_dev_resume(dev); |
986 | up(&dev->sem); | 986 | device_unlock(dev); |
987 | return rc; | 987 | return rc; |
988 | } | 988 | } |
989 | 989 | ||
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index de6bc333d299..db79ca61cf96 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -21,11 +21,18 @@ | |||
21 | 21 | ||
22 | #include "sa1111_generic.h" | 22 | #include "sa1111_generic.h" |
23 | 23 | ||
24 | #define IDX_IRQ_S0_READY_NINT (0) | ||
25 | #define IDX_IRQ_S0_CD_VALID (1) | ||
26 | #define IDX_IRQ_S0_BVD1_STSCHG (2) | ||
27 | #define IDX_IRQ_S1_READY_NINT (3) | ||
28 | #define IDX_IRQ_S1_CD_VALID (4) | ||
29 | #define IDX_IRQ_S1_BVD1_STSCHG (5) | ||
30 | |||
24 | static struct pcmcia_irqs irqs[] = { | 31 | static struct pcmcia_irqs irqs[] = { |
25 | { 0, IRQ_S0_CD_VALID, "SA1111 PCMCIA card detect" }, | 32 | { 0, NO_IRQ, "SA1111 PCMCIA card detect" }, |
26 | { 0, IRQ_S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" }, | 33 | { 0, NO_IRQ, "SA1111 PCMCIA BVD1" }, |
27 | { 1, IRQ_S1_CD_VALID, "SA1111 CF card detect" }, | 34 | { 1, NO_IRQ, "SA1111 CF card detect" }, |
28 | { 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1" }, | 35 | { 1, NO_IRQ, "SA1111 CF BVD1" }, |
29 | }; | 36 | }; |
30 | 37 | ||
31 | static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 38 | static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -136,7 +143,9 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
136 | s->soc.ops = ops; | 143 | s->soc.ops = ops; |
137 | s->soc.socket.owner = ops->owner; | 144 | s->soc.socket.owner = ops->owner; |
138 | s->soc.socket.dev.parent = &dev->dev; | 145 | s->soc.socket.dev.parent = &dev->dev; |
139 | s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT; | 146 | s->soc.socket.pci_irq = s->soc.nr ? |
147 | dev->irq[IDX_IRQ_S0_READY_NINT] : | ||
148 | dev->irq[IDX_IRQ_S1_READY_NINT]; | ||
140 | s->dev = dev; | 149 | s->dev = dev; |
141 | 150 | ||
142 | ret = add(&s->soc); | 151 | ret = add(&s->soc); |
@@ -162,6 +171,12 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
162 | 171 | ||
163 | base = dev->mapbase; | 172 | base = dev->mapbase; |
164 | 173 | ||
174 | /* Initialize PCMCIA IRQs */ | ||
175 | irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; | ||
176 | irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; | ||
177 | irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; | ||
178 | irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; | ||
179 | |||
165 | /* | 180 | /* |
166 | * Initialise the suspend state. | 181 | * Initialise the suspend state. |
167 | */ | 182 | */ |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index cd2ee6fce1b4..e631dbeafd79 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -150,6 +150,7 @@ config MSI_LAPTOP | |||
150 | tristate "MSI Laptop Extras" | 150 | tristate "MSI Laptop Extras" |
151 | depends on ACPI | 151 | depends on ACPI |
152 | depends on BACKLIGHT_CLASS_DEVICE | 152 | depends on BACKLIGHT_CLASS_DEVICE |
153 | depends on RFKILL | ||
153 | ---help--- | 154 | ---help--- |
154 | This is a driver for laptops built by MSI (MICRO-STAR | 155 | This is a driver for laptops built by MSI (MICRO-STAR |
155 | INTERNATIONAL): | 156 | INTERNATIONAL): |
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 1b1dddbd5744..bed764e3ea2a 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
@@ -142,7 +142,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap; | |||
142 | 142 | ||
143 | static struct input_dev *dell_wmi_input_dev; | 143 | static struct input_dev *dell_wmi_input_dev; |
144 | 144 | ||
145 | static struct key_entry *dell_wmi_get_entry_by_scancode(int code) | 145 | static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code) |
146 | { | 146 | { |
147 | struct key_entry *key; | 147 | struct key_entry *key; |
148 | 148 | ||
@@ -153,7 +153,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code) | |||
153 | return NULL; | 153 | return NULL; |
154 | } | 154 | } |
155 | 155 | ||
156 | static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) | 156 | static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode) |
157 | { | 157 | { |
158 | struct key_entry *key; | 158 | struct key_entry *key; |
159 | 159 | ||
@@ -164,8 +164,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) | |||
164 | return NULL; | 164 | return NULL; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, | 167 | static int dell_wmi_getkeycode(struct input_dev *dev, |
168 | int *keycode) | 168 | unsigned int scancode, unsigned int *keycode) |
169 | { | 169 | { |
170 | struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode); | 170 | struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode); |
171 | 171 | ||
@@ -177,13 +177,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, | |||
177 | return -EINVAL; | 177 | return -EINVAL; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) | 180 | static int dell_wmi_setkeycode(struct input_dev *dev, |
181 | unsigned int scancode, unsigned int keycode) | ||
181 | { | 182 | { |
182 | struct key_entry *key; | 183 | struct key_entry *key; |
183 | int old_keycode; | 184 | unsigned int old_keycode; |
184 | |||
185 | if (keycode < 0 || keycode > KEY_MAX) | ||
186 | return -EINVAL; | ||
187 | 185 | ||
188 | key = dell_wmi_get_entry_by_scancode(scancode); | 186 | key = dell_wmi_get_entry_by_scancode(scancode); |
189 | if (key && key->type == KE_KEY) { | 187 | if (key && key->type == KE_KEY) { |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 3aa57da8b43b..56086363becc 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -57,7 +57,7 @@ enum hp_wmi_radio { | |||
57 | HPWMI_WWAN = 2, | 57 | HPWMI_WWAN = 2, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static int __init hp_wmi_bios_setup(struct platform_device *device); | 60 | static int __devinit hp_wmi_bios_setup(struct platform_device *device); |
61 | static int __exit hp_wmi_bios_remove(struct platform_device *device); | 61 | static int __exit hp_wmi_bios_remove(struct platform_device *device); |
62 | static int hp_wmi_resume_handler(struct device *device); | 62 | static int hp_wmi_resume_handler(struct device *device); |
63 | 63 | ||
@@ -278,7 +278,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); | |||
278 | static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); | 278 | static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); |
279 | static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); | 279 | static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); |
280 | 280 | ||
281 | static struct key_entry *hp_wmi_get_entry_by_scancode(int code) | 281 | static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code) |
282 | { | 282 | { |
283 | struct key_entry *key; | 283 | struct key_entry *key; |
284 | 284 | ||
@@ -289,7 +289,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code) | |||
289 | return NULL; | 289 | return NULL; |
290 | } | 290 | } |
291 | 291 | ||
292 | static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) | 292 | static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode) |
293 | { | 293 | { |
294 | struct key_entry *key; | 294 | struct key_entry *key; |
295 | 295 | ||
@@ -300,7 +300,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) | |||
300 | return NULL; | 300 | return NULL; |
301 | } | 301 | } |
302 | 302 | ||
303 | static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 303 | static int hp_wmi_getkeycode(struct input_dev *dev, |
304 | unsigned int scancode, unsigned int *keycode) | ||
304 | { | 305 | { |
305 | struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode); | 306 | struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode); |
306 | 307 | ||
@@ -312,13 +313,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) | |||
312 | return -EINVAL; | 313 | return -EINVAL; |
313 | } | 314 | } |
314 | 315 | ||
315 | static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) | 316 | static int hp_wmi_setkeycode(struct input_dev *dev, |
317 | unsigned int scancode, unsigned int keycode) | ||
316 | { | 318 | { |
317 | struct key_entry *key; | 319 | struct key_entry *key; |
318 | int old_keycode; | 320 | unsigned int old_keycode; |
319 | |||
320 | if (keycode < 0 || keycode > KEY_MAX) | ||
321 | return -EINVAL; | ||
322 | 321 | ||
323 | key = hp_wmi_get_entry_by_scancode(scancode); | 322 | key = hp_wmi_get_entry_by_scancode(scancode); |
324 | if (key && key->type == KE_KEY) { | 323 | if (key && key->type == KE_KEY) { |
@@ -447,7 +446,7 @@ static void cleanup_sysfs(struct platform_device *device) | |||
447 | device_remove_file(&device->dev, &dev_attr_tablet); | 446 | device_remove_file(&device->dev, &dev_attr_tablet); |
448 | } | 447 | } |
449 | 448 | ||
450 | static int __init hp_wmi_bios_setup(struct platform_device *device) | 449 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) |
451 | { | 450 | { |
452 | int err; | 451 | int err; |
453 | int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); | 452 | int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); |
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 759763d18e4c..c2b05da4289a 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/dmi.h> | 58 | #include <linux/dmi.h> |
59 | #include <linux/backlight.h> | 59 | #include <linux/backlight.h> |
60 | #include <linux/platform_device.h> | 60 | #include <linux/platform_device.h> |
61 | #include <linux/rfkill.h> | ||
61 | 62 | ||
62 | #define MSI_DRIVER_VERSION "0.5" | 63 | #define MSI_DRIVER_VERSION "0.5" |
63 | 64 | ||
@@ -66,6 +67,20 @@ | |||
66 | #define MSI_EC_COMMAND_WIRELESS 0x10 | 67 | #define MSI_EC_COMMAND_WIRELESS 0x10 |
67 | #define MSI_EC_COMMAND_LCD_LEVEL 0x11 | 68 | #define MSI_EC_COMMAND_LCD_LEVEL 0x11 |
68 | 69 | ||
70 | #define MSI_STANDARD_EC_COMMAND_ADDRESS 0x2e | ||
71 | #define MSI_STANDARD_EC_BLUETOOTH_MASK (1 << 0) | ||
72 | #define MSI_STANDARD_EC_WEBCAM_MASK (1 << 1) | ||
73 | #define MSI_STANDARD_EC_WLAN_MASK (1 << 3) | ||
74 | #define MSI_STANDARD_EC_3G_MASK (1 << 4) | ||
75 | |||
76 | /* For set SCM load flag to disable BIOS fn key */ | ||
77 | #define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d | ||
78 | #define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0) | ||
79 | |||
80 | static int msi_laptop_resume(struct platform_device *device); | ||
81 | |||
82 | #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f | ||
83 | |||
69 | static int force; | 84 | static int force; |
70 | module_param(force, bool, 0); | 85 | module_param(force, bool, 0); |
71 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | 86 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); |
@@ -74,6 +89,23 @@ static int auto_brightness; | |||
74 | module_param(auto_brightness, int, 0); | 89 | module_param(auto_brightness, int, 0); |
75 | MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); | 90 | MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); |
76 | 91 | ||
92 | static bool old_ec_model; | ||
93 | static int wlan_s, bluetooth_s, threeg_s; | ||
94 | static int threeg_exists; | ||
95 | |||
96 | /* Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G, | ||
97 | * those netbook will load the SCM (windows app) to disable the original | ||
98 | * Wlan/Bluetooth control by BIOS when user press fn key, then control | ||
99 | * Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user | ||
100 | * cann't on/off 3G module on those 3G netbook. | ||
101 | * On Linux, msi-laptop driver will do the same thing to disable the | ||
102 | * original BIOS control, then might need use HAL or other userland | ||
103 | * application to do the software control that simulate with SCM. | ||
104 | * e.g. MSI N034 netbook | ||
105 | */ | ||
106 | static bool load_scm_model; | ||
107 | static struct rfkill *rfk_wlan, *rfk_bluetooth, *rfk_threeg; | ||
108 | |||
77 | /* Hardware access */ | 109 | /* Hardware access */ |
78 | 110 | ||
79 | static int set_lcd_level(int level) | 111 | static int set_lcd_level(int level) |
@@ -130,6 +162,35 @@ static int set_auto_brightness(int enable) | |||
130 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1); | 162 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1); |
131 | } | 163 | } |
132 | 164 | ||
165 | static ssize_t set_device_state(const char *buf, size_t count, u8 mask) | ||
166 | { | ||
167 | int status; | ||
168 | u8 wdata = 0, rdata; | ||
169 | int result; | ||
170 | |||
171 | if (sscanf(buf, "%i", &status) != 1 || (status < 0 || status > 1)) | ||
172 | return -EINVAL; | ||
173 | |||
174 | /* read current device state */ | ||
175 | result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); | ||
176 | if (result < 0) | ||
177 | return -EINVAL; | ||
178 | |||
179 | if (!!(rdata & mask) != status) { | ||
180 | /* reverse device bit */ | ||
181 | if (rdata & mask) | ||
182 | wdata = rdata & ~mask; | ||
183 | else | ||
184 | wdata = rdata | mask; | ||
185 | |||
186 | result = ec_write(MSI_STANDARD_EC_COMMAND_ADDRESS, wdata); | ||
187 | if (result < 0) | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | return count; | ||
192 | } | ||
193 | |||
133 | static int get_wireless_state(int *wlan, int *bluetooth) | 194 | static int get_wireless_state(int *wlan, int *bluetooth) |
134 | { | 195 | { |
135 | u8 wdata = 0, rdata; | 196 | u8 wdata = 0, rdata; |
@@ -148,6 +209,38 @@ static int get_wireless_state(int *wlan, int *bluetooth) | |||
148 | return 0; | 209 | return 0; |
149 | } | 210 | } |
150 | 211 | ||
212 | static int get_wireless_state_ec_standard(void) | ||
213 | { | ||
214 | u8 rdata; | ||
215 | int result; | ||
216 | |||
217 | result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); | ||
218 | if (result < 0) | ||
219 | return -1; | ||
220 | |||
221 | wlan_s = !!(rdata & MSI_STANDARD_EC_WLAN_MASK); | ||
222 | |||
223 | bluetooth_s = !!(rdata & MSI_STANDARD_EC_BLUETOOTH_MASK); | ||
224 | |||
225 | threeg_s = !!(rdata & MSI_STANDARD_EC_3G_MASK); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int get_threeg_exists(void) | ||
231 | { | ||
232 | u8 rdata; | ||
233 | int result; | ||
234 | |||
235 | result = ec_read(MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS, &rdata); | ||
236 | if (result < 0) | ||
237 | return -1; | ||
238 | |||
239 | threeg_exists = !!(rdata & MSI_STANDARD_EC_3G_MASK); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
151 | /* Backlight device stuff */ | 244 | /* Backlight device stuff */ |
152 | 245 | ||
153 | static int bl_get_brightness(struct backlight_device *b) | 246 | static int bl_get_brightness(struct backlight_device *b) |
@@ -176,26 +269,71 @@ static ssize_t show_wlan(struct device *dev, | |||
176 | 269 | ||
177 | int ret, enabled; | 270 | int ret, enabled; |
178 | 271 | ||
179 | ret = get_wireless_state(&enabled, NULL); | 272 | if (old_ec_model) { |
273 | ret = get_wireless_state(&enabled, NULL); | ||
274 | } else { | ||
275 | ret = get_wireless_state_ec_standard(); | ||
276 | enabled = wlan_s; | ||
277 | } | ||
180 | if (ret < 0) | 278 | if (ret < 0) |
181 | return ret; | 279 | return ret; |
182 | 280 | ||
183 | return sprintf(buf, "%i\n", enabled); | 281 | return sprintf(buf, "%i\n", enabled); |
184 | } | 282 | } |
185 | 283 | ||
284 | static ssize_t store_wlan(struct device *dev, | ||
285 | struct device_attribute *attr, const char *buf, size_t count) | ||
286 | { | ||
287 | return set_device_state(buf, count, MSI_STANDARD_EC_WLAN_MASK); | ||
288 | } | ||
289 | |||
186 | static ssize_t show_bluetooth(struct device *dev, | 290 | static ssize_t show_bluetooth(struct device *dev, |
187 | struct device_attribute *attr, char *buf) | 291 | struct device_attribute *attr, char *buf) |
188 | { | 292 | { |
189 | 293 | ||
190 | int ret, enabled; | 294 | int ret, enabled; |
191 | 295 | ||
192 | ret = get_wireless_state(NULL, &enabled); | 296 | if (old_ec_model) { |
297 | ret = get_wireless_state(NULL, &enabled); | ||
298 | } else { | ||
299 | ret = get_wireless_state_ec_standard(); | ||
300 | enabled = bluetooth_s; | ||
301 | } | ||
193 | if (ret < 0) | 302 | if (ret < 0) |
194 | return ret; | 303 | return ret; |
195 | 304 | ||
196 | return sprintf(buf, "%i\n", enabled); | 305 | return sprintf(buf, "%i\n", enabled); |
197 | } | 306 | } |
198 | 307 | ||
308 | static ssize_t store_bluetooth(struct device *dev, | ||
309 | struct device_attribute *attr, const char *buf, size_t count) | ||
310 | { | ||
311 | return set_device_state(buf, count, MSI_STANDARD_EC_BLUETOOTH_MASK); | ||
312 | } | ||
313 | |||
314 | static ssize_t show_threeg(struct device *dev, | ||
315 | struct device_attribute *attr, char *buf) | ||
316 | { | ||
317 | |||
318 | int ret; | ||
319 | |||
320 | /* old msi ec not support 3G */ | ||
321 | if (old_ec_model) | ||
322 | return -1; | ||
323 | |||
324 | ret = get_wireless_state_ec_standard(); | ||
325 | if (ret < 0) | ||
326 | return ret; | ||
327 | |||
328 | return sprintf(buf, "%i\n", threeg_s); | ||
329 | } | ||
330 | |||
331 | static ssize_t store_threeg(struct device *dev, | ||
332 | struct device_attribute *attr, const char *buf, size_t count) | ||
333 | { | ||
334 | return set_device_state(buf, count, MSI_STANDARD_EC_3G_MASK); | ||
335 | } | ||
336 | |||
199 | static ssize_t show_lcd_level(struct device *dev, | 337 | static ssize_t show_lcd_level(struct device *dev, |
200 | struct device_attribute *attr, char *buf) | 338 | struct device_attribute *attr, char *buf) |
201 | { | 339 | { |
@@ -258,6 +396,7 @@ static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); | |||
258 | static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); | 396 | static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); |
259 | static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); | 397 | static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); |
260 | static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); | 398 | static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); |
399 | static DEVICE_ATTR(threeg, 0444, show_threeg, NULL); | ||
261 | 400 | ||
262 | static struct attribute *msipf_attributes[] = { | 401 | static struct attribute *msipf_attributes[] = { |
263 | &dev_attr_lcd_level.attr, | 402 | &dev_attr_lcd_level.attr, |
@@ -275,7 +414,8 @@ static struct platform_driver msipf_driver = { | |||
275 | .driver = { | 414 | .driver = { |
276 | .name = "msi-laptop-pf", | 415 | .name = "msi-laptop-pf", |
277 | .owner = THIS_MODULE, | 416 | .owner = THIS_MODULE, |
278 | } | 417 | }, |
418 | .resume = msi_laptop_resume, | ||
279 | }; | 419 | }; |
280 | 420 | ||
281 | static struct platform_device *msipf_device; | 421 | static struct platform_device *msipf_device; |
@@ -332,6 +472,192 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { | |||
332 | { } | 472 | { } |
333 | }; | 473 | }; |
334 | 474 | ||
475 | static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = { | ||
476 | { | ||
477 | .ident = "MSI N034", | ||
478 | .matches = { | ||
479 | DMI_MATCH(DMI_SYS_VENDOR, | ||
480 | "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
481 | DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"), | ||
482 | DMI_MATCH(DMI_CHASSIS_VENDOR, | ||
483 | "MICRO-STAR INTERNATIONAL CO., LTD") | ||
484 | }, | ||
485 | .callback = dmi_check_cb | ||
486 | }, | ||
487 | { } | ||
488 | }; | ||
489 | |||
490 | static int rfkill_bluetooth_set(void *data, bool blocked) | ||
491 | { | ||
492 | /* Do something with blocked...*/ | ||
493 | /* | ||
494 | * blocked == false is on | ||
495 | * blocked == true is off | ||
496 | */ | ||
497 | if (blocked) | ||
498 | set_device_state("0", 0, MSI_STANDARD_EC_BLUETOOTH_MASK); | ||
499 | else | ||
500 | set_device_state("1", 0, MSI_STANDARD_EC_BLUETOOTH_MASK); | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static int rfkill_wlan_set(void *data, bool blocked) | ||
506 | { | ||
507 | if (blocked) | ||
508 | set_device_state("0", 0, MSI_STANDARD_EC_WLAN_MASK); | ||
509 | else | ||
510 | set_device_state("1", 0, MSI_STANDARD_EC_WLAN_MASK); | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static int rfkill_threeg_set(void *data, bool blocked) | ||
516 | { | ||
517 | if (blocked) | ||
518 | set_device_state("0", 0, MSI_STANDARD_EC_3G_MASK); | ||
519 | else | ||
520 | set_device_state("1", 0, MSI_STANDARD_EC_3G_MASK); | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static struct rfkill_ops rfkill_bluetooth_ops = { | ||
526 | .set_block = rfkill_bluetooth_set | ||
527 | }; | ||
528 | |||
529 | static struct rfkill_ops rfkill_wlan_ops = { | ||
530 | .set_block = rfkill_wlan_set | ||
531 | }; | ||
532 | |||
533 | static struct rfkill_ops rfkill_threeg_ops = { | ||
534 | .set_block = rfkill_threeg_set | ||
535 | }; | ||
536 | |||
537 | static void rfkill_cleanup(void) | ||
538 | { | ||
539 | if (rfk_bluetooth) { | ||
540 | rfkill_unregister(rfk_bluetooth); | ||
541 | rfkill_destroy(rfk_bluetooth); | ||
542 | } | ||
543 | |||
544 | if (rfk_threeg) { | ||
545 | rfkill_unregister(rfk_threeg); | ||
546 | rfkill_destroy(rfk_threeg); | ||
547 | } | ||
548 | |||
549 | if (rfk_wlan) { | ||
550 | rfkill_unregister(rfk_wlan); | ||
551 | rfkill_destroy(rfk_wlan); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static int rfkill_init(struct platform_device *sdev) | ||
556 | { | ||
557 | /* add rfkill */ | ||
558 | int retval; | ||
559 | |||
560 | rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev, | ||
561 | RFKILL_TYPE_BLUETOOTH, | ||
562 | &rfkill_bluetooth_ops, NULL); | ||
563 | if (!rfk_bluetooth) { | ||
564 | retval = -ENOMEM; | ||
565 | goto err_bluetooth; | ||
566 | } | ||
567 | retval = rfkill_register(rfk_bluetooth); | ||
568 | if (retval) | ||
569 | goto err_bluetooth; | ||
570 | |||
571 | rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN, | ||
572 | &rfkill_wlan_ops, NULL); | ||
573 | if (!rfk_wlan) { | ||
574 | retval = -ENOMEM; | ||
575 | goto err_wlan; | ||
576 | } | ||
577 | retval = rfkill_register(rfk_wlan); | ||
578 | if (retval) | ||
579 | goto err_wlan; | ||
580 | |||
581 | if (threeg_exists) { | ||
582 | rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev, | ||
583 | RFKILL_TYPE_WWAN, &rfkill_threeg_ops, NULL); | ||
584 | if (!rfk_threeg) { | ||
585 | retval = -ENOMEM; | ||
586 | goto err_threeg; | ||
587 | } | ||
588 | retval = rfkill_register(rfk_threeg); | ||
589 | if (retval) | ||
590 | goto err_threeg; | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | |||
595 | err_threeg: | ||
596 | rfkill_destroy(rfk_threeg); | ||
597 | if (rfk_wlan) | ||
598 | rfkill_unregister(rfk_wlan); | ||
599 | err_wlan: | ||
600 | rfkill_destroy(rfk_wlan); | ||
601 | if (rfk_bluetooth) | ||
602 | rfkill_unregister(rfk_bluetooth); | ||
603 | err_bluetooth: | ||
604 | rfkill_destroy(rfk_bluetooth); | ||
605 | |||
606 | return retval; | ||
607 | } | ||
608 | |||
609 | static int msi_laptop_resume(struct platform_device *device) | ||
610 | { | ||
611 | u8 data; | ||
612 | int result; | ||
613 | |||
614 | if (!load_scm_model) | ||
615 | return 0; | ||
616 | |||
617 | /* set load SCM to disable hardware control by fn key */ | ||
618 | result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data); | ||
619 | if (result < 0) | ||
620 | return result; | ||
621 | |||
622 | result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, | ||
623 | data | MSI_STANDARD_EC_SCM_LOAD_MASK); | ||
624 | if (result < 0) | ||
625 | return result; | ||
626 | |||
627 | return 0; | ||
628 | } | ||
629 | |||
630 | static int load_scm_model_init(struct platform_device *sdev) | ||
631 | { | ||
632 | u8 data; | ||
633 | int result; | ||
634 | |||
635 | /* allow userland write sysfs file */ | ||
636 | dev_attr_bluetooth.store = store_bluetooth; | ||
637 | dev_attr_wlan.store = store_wlan; | ||
638 | dev_attr_threeg.store = store_threeg; | ||
639 | dev_attr_bluetooth.attr.mode |= S_IWUSR; | ||
640 | dev_attr_wlan.attr.mode |= S_IWUSR; | ||
641 | dev_attr_threeg.attr.mode |= S_IWUSR; | ||
642 | |||
643 | /* disable hardware control by fn key */ | ||
644 | result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data); | ||
645 | if (result < 0) | ||
646 | return result; | ||
647 | |||
648 | result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, | ||
649 | data | MSI_STANDARD_EC_SCM_LOAD_MASK); | ||
650 | if (result < 0) | ||
651 | return result; | ||
652 | |||
653 | /* initial rfkill */ | ||
654 | result = rfkill_init(sdev); | ||
655 | if (result < 0) | ||
656 | return result; | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
335 | static int __init msi_init(void) | 661 | static int __init msi_init(void) |
336 | { | 662 | { |
337 | int ret; | 663 | int ret; |
@@ -339,8 +665,14 @@ static int __init msi_init(void) | |||
339 | if (acpi_disabled) | 665 | if (acpi_disabled) |
340 | return -ENODEV; | 666 | return -ENODEV; |
341 | 667 | ||
342 | if (!force && !dmi_check_system(msi_dmi_table)) | 668 | if (force || dmi_check_system(msi_dmi_table)) |
343 | return -ENODEV; | 669 | old_ec_model = 1; |
670 | |||
671 | if (!old_ec_model) | ||
672 | get_threeg_exists(); | ||
673 | |||
674 | if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table)) | ||
675 | load_scm_model = 1; | ||
344 | 676 | ||
345 | if (auto_brightness < 0 || auto_brightness > 2) | 677 | if (auto_brightness < 0 || auto_brightness > 2) |
346 | return -EINVAL; | 678 | return -EINVAL; |
@@ -374,10 +706,23 @@ static int __init msi_init(void) | |||
374 | if (ret) | 706 | if (ret) |
375 | goto fail_platform_device1; | 707 | goto fail_platform_device1; |
376 | 708 | ||
709 | if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) { | ||
710 | ret = -EINVAL; | ||
711 | goto fail_platform_device1; | ||
712 | } | ||
713 | |||
377 | ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); | 714 | ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); |
378 | if (ret) | 715 | if (ret) |
379 | goto fail_platform_device2; | 716 | goto fail_platform_device2; |
380 | 717 | ||
718 | if (!old_ec_model) { | ||
719 | if (threeg_exists) | ||
720 | ret = device_create_file(&msipf_device->dev, | ||
721 | &dev_attr_threeg); | ||
722 | if (ret) | ||
723 | goto fail_platform_device2; | ||
724 | } | ||
725 | |||
381 | /* Disable automatic brightness control by default because | 726 | /* Disable automatic brightness control by default because |
382 | * this module was probably loaded to do brightness control in | 727 | * this module was probably loaded to do brightness control in |
383 | * software. */ | 728 | * software. */ |
@@ -412,10 +757,14 @@ static void __exit msi_cleanup(void) | |||
412 | { | 757 | { |
413 | 758 | ||
414 | sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); | 759 | sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); |
760 | if (!old_ec_model && threeg_exists) | ||
761 | device_remove_file(&msipf_device->dev, &dev_attr_threeg); | ||
415 | platform_device_unregister(msipf_device); | 762 | platform_device_unregister(msipf_device); |
416 | platform_driver_unregister(&msipf_driver); | 763 | platform_driver_unregister(&msipf_driver); |
417 | backlight_device_unregister(msibl_device); | 764 | backlight_device_unregister(msibl_device); |
418 | 765 | ||
766 | rfkill_cleanup(); | ||
767 | |||
419 | /* Enable automatic brightness control again */ | 768 | /* Enable automatic brightness control again */ |
420 | if (auto_brightness != 2) | 769 | if (auto_brightness != 2) |
421 | set_auto_brightness(1); | 770 | set_auto_brightness(1); |
@@ -435,3 +784,4 @@ MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARIN | |||
435 | MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*"); | 784 | MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*"); |
436 | MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); | 785 | MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); |
437 | MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); | 786 | MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); |
787 | MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*"); | ||
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index fe7cf0188acc..c9fc479fc290 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -200,7 +200,7 @@ static struct acpi_driver acpi_pcc_driver = { | |||
200 | }; | 200 | }; |
201 | 201 | ||
202 | #define KEYMAP_SIZE 11 | 202 | #define KEYMAP_SIZE 11 |
203 | static const int initial_keymap[KEYMAP_SIZE] = { | 203 | static const unsigned int initial_keymap[KEYMAP_SIZE] = { |
204 | /* 0 */ KEY_RESERVED, | 204 | /* 0 */ KEY_RESERVED, |
205 | /* 1 */ KEY_BRIGHTNESSDOWN, | 205 | /* 1 */ KEY_BRIGHTNESSDOWN, |
206 | /* 2 */ KEY_BRIGHTNESSUP, | 206 | /* 2 */ KEY_BRIGHTNESSUP, |
@@ -222,7 +222,7 @@ struct pcc_acpi { | |||
222 | struct acpi_device *device; | 222 | struct acpi_device *device; |
223 | struct input_dev *input_dev; | 223 | struct input_dev *input_dev; |
224 | struct backlight_device *backlight; | 224 | struct backlight_device *backlight; |
225 | int keymap[KEYMAP_SIZE]; | 225 | unsigned int keymap[KEYMAP_SIZE]; |
226 | }; | 226 | }; |
227 | 227 | ||
228 | struct pcc_keyinput { | 228 | struct pcc_keyinput { |
@@ -445,7 +445,8 @@ static struct attribute_group pcc_attr_group = { | |||
445 | 445 | ||
446 | /* hotkey input device driver */ | 446 | /* hotkey input device driver */ |
447 | 447 | ||
448 | static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 448 | static int pcc_getkeycode(struct input_dev *dev, |
449 | unsigned int scancode, unsigned int *keycode) | ||
449 | { | 450 | { |
450 | struct pcc_acpi *pcc = input_get_drvdata(dev); | 451 | struct pcc_acpi *pcc = input_get_drvdata(dev); |
451 | 452 | ||
@@ -457,7 +458,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) | |||
457 | return 0; | 458 | return 0; |
458 | } | 459 | } |
459 | 460 | ||
460 | static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) | 461 | static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode) |
461 | { | 462 | { |
462 | int i; | 463 | int i; |
463 | 464 | ||
@@ -469,7 +470,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) | |||
469 | return 0; | 470 | return 0; |
470 | } | 471 | } |
471 | 472 | ||
472 | static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) | 473 | static int pcc_setkeycode(struct input_dev *dev, |
474 | unsigned int scancode, unsigned int keycode) | ||
473 | { | 475 | { |
474 | struct pcc_acpi *pcc = input_get_drvdata(dev); | 476 | struct pcc_acpi *pcc = input_get_drvdata(dev); |
475 | int oldkeycode; | 477 | int oldkeycode; |
@@ -477,9 +479,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) | |||
477 | if (scancode >= ARRAY_SIZE(pcc->keymap)) | 479 | if (scancode >= ARRAY_SIZE(pcc->keymap)) |
478 | return -EINVAL; | 480 | return -EINVAL; |
479 | 481 | ||
480 | if (keycode < 0 || keycode > KEY_MAX) | ||
481 | return -EINVAL; | ||
482 | |||
483 | oldkeycode = pcc->keymap[scancode]; | 482 | oldkeycode = pcc->keymap[scancode]; |
484 | pcc->keymap[scancode] = keycode; | 483 | pcc->keymap[scancode] = keycode; |
485 | 484 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 3f71a605a492..5a3d8514c66d 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -145,7 +145,7 @@ struct sony_laptop_input_s { | |||
145 | struct input_dev *key_dev; | 145 | struct input_dev *key_dev; |
146 | struct kfifo fifo; | 146 | struct kfifo fifo; |
147 | spinlock_t fifo_lock; | 147 | spinlock_t fifo_lock; |
148 | struct workqueue_struct *wq; | 148 | struct timer_list release_key_timer; |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct sony_laptop_input_s sony_laptop_input = { | 151 | static struct sony_laptop_input_s sony_laptop_input = { |
@@ -299,20 +299,26 @@ static int sony_laptop_input_keycode_map[] = { | |||
299 | }; | 299 | }; |
300 | 300 | ||
301 | /* release buttons after a short delay if pressed */ | 301 | /* release buttons after a short delay if pressed */ |
302 | static void do_sony_laptop_release_key(struct work_struct *work) | 302 | static void do_sony_laptop_release_key(unsigned long unused) |
303 | { | 303 | { |
304 | struct sony_laptop_keypress kp; | 304 | struct sony_laptop_keypress kp; |
305 | unsigned long flags; | ||
306 | |||
307 | spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags); | ||
305 | 308 | ||
306 | while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, | 309 | if (kfifo_out(&sony_laptop_input.fifo, |
307 | sizeof(kp), &sony_laptop_input.fifo_lock) | 310 | (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { |
308 | == sizeof(kp)) { | ||
309 | msleep(10); | ||
310 | input_report_key(kp.dev, kp.key, 0); | 311 | input_report_key(kp.dev, kp.key, 0); |
311 | input_sync(kp.dev); | 312 | input_sync(kp.dev); |
312 | } | 313 | } |
314 | |||
315 | /* If there is something in the fifo schedule next release. */ | ||
316 | if (kfifo_len(&sony_laptop_input.fifo) != 0) | ||
317 | mod_timer(&sony_laptop_input.release_key_timer, | ||
318 | jiffies + msecs_to_jiffies(10)); | ||
319 | |||
320 | spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags); | ||
313 | } | 321 | } |
314 | static DECLARE_WORK(sony_laptop_release_key_work, | ||
315 | do_sony_laptop_release_key); | ||
316 | 322 | ||
317 | /* forward event to the input subsystem */ | 323 | /* forward event to the input subsystem */ |
318 | static void sony_laptop_report_input_event(u8 event) | 324 | static void sony_laptop_report_input_event(u8 event) |
@@ -366,13 +372,13 @@ static void sony_laptop_report_input_event(u8 event) | |||
366 | /* we emit the scancode so we can always remap the key */ | 372 | /* we emit the scancode so we can always remap the key */ |
367 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | 373 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); |
368 | input_sync(kp.dev); | 374 | input_sync(kp.dev); |
369 | kfifo_in_locked(&sony_laptop_input.fifo, | ||
370 | (unsigned char *)&kp, sizeof(kp), | ||
371 | &sony_laptop_input.fifo_lock); | ||
372 | 375 | ||
373 | if (!work_pending(&sony_laptop_release_key_work)) | 376 | /* schedule key release */ |
374 | queue_work(sony_laptop_input.wq, | 377 | kfifo_in_locked(&sony_laptop_input.fifo, |
375 | &sony_laptop_release_key_work); | 378 | (unsigned char *)&kp, sizeof(kp), |
379 | &sony_laptop_input.fifo_lock); | ||
380 | mod_timer(&sony_laptop_input.release_key_timer, | ||
381 | jiffies + msecs_to_jiffies(10)); | ||
376 | } else | 382 | } else |
377 | dprintk("unknown input event %.2x\n", event); | 383 | dprintk("unknown input event %.2x\n", event); |
378 | } | 384 | } |
@@ -390,27 +396,21 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
390 | 396 | ||
391 | /* kfifo */ | 397 | /* kfifo */ |
392 | spin_lock_init(&sony_laptop_input.fifo_lock); | 398 | spin_lock_init(&sony_laptop_input.fifo_lock); |
393 | error = | 399 | error = kfifo_alloc(&sony_laptop_input.fifo, |
394 | kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); | 400 | SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
395 | if (error) { | 401 | if (error) { |
396 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); | 402 | printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); |
397 | goto err_dec_users; | 403 | goto err_dec_users; |
398 | } | 404 | } |
399 | 405 | ||
400 | /* init workqueue */ | 406 | setup_timer(&sony_laptop_input.release_key_timer, |
401 | sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop"); | 407 | do_sony_laptop_release_key, 0); |
402 | if (!sony_laptop_input.wq) { | ||
403 | printk(KERN_ERR DRV_PFX | ||
404 | "Unable to create workqueue.\n"); | ||
405 | error = -ENXIO; | ||
406 | goto err_free_kfifo; | ||
407 | } | ||
408 | 408 | ||
409 | /* input keys */ | 409 | /* input keys */ |
410 | key_dev = input_allocate_device(); | 410 | key_dev = input_allocate_device(); |
411 | if (!key_dev) { | 411 | if (!key_dev) { |
412 | error = -ENOMEM; | 412 | error = -ENOMEM; |
413 | goto err_destroy_wq; | 413 | goto err_free_kfifo; |
414 | } | 414 | } |
415 | 415 | ||
416 | key_dev->name = "Sony Vaio Keys"; | 416 | key_dev->name = "Sony Vaio Keys"; |
@@ -419,18 +419,15 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
419 | key_dev->dev.parent = &acpi_device->dev; | 419 | key_dev->dev.parent = &acpi_device->dev; |
420 | 420 | ||
421 | /* Initialize the Input Drivers: special keys */ | 421 | /* Initialize the Input Drivers: special keys */ |
422 | set_bit(EV_KEY, key_dev->evbit); | 422 | input_set_capability(key_dev, EV_MSC, MSC_SCAN); |
423 | set_bit(EV_MSC, key_dev->evbit); | 423 | |
424 | set_bit(MSC_SCAN, key_dev->mscbit); | 424 | __set_bit(EV_KEY, key_dev->evbit); |
425 | key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); | 425 | key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); |
426 | key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); | 426 | key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); |
427 | key_dev->keycode = &sony_laptop_input_keycode_map; | 427 | key_dev->keycode = &sony_laptop_input_keycode_map; |
428 | for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { | 428 | for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) |
429 | if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { | 429 | __set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit); |
430 | set_bit(sony_laptop_input_keycode_map[i], | 430 | __clear_bit(KEY_RESERVED, key_dev->keybit); |
431 | key_dev->keybit); | ||
432 | } | ||
433 | } | ||
434 | 431 | ||
435 | error = input_register_device(key_dev); | 432 | error = input_register_device(key_dev); |
436 | if (error) | 433 | if (error) |
@@ -450,9 +447,8 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
450 | jog_dev->id.vendor = PCI_VENDOR_ID_SONY; | 447 | jog_dev->id.vendor = PCI_VENDOR_ID_SONY; |
451 | key_dev->dev.parent = &acpi_device->dev; | 448 | key_dev->dev.parent = &acpi_device->dev; |
452 | 449 | ||
453 | jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 450 | input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE); |
454 | jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE); | 451 | input_set_capability(jog_dev, EV_REL, REL_WHEEL); |
455 | jog_dev->relbit[0] = BIT_MASK(REL_WHEEL); | ||
456 | 452 | ||
457 | error = input_register_device(jog_dev); | 453 | error = input_register_device(jog_dev); |
458 | if (error) | 454 | if (error) |
@@ -473,9 +469,6 @@ err_unregister_keydev: | |||
473 | err_free_keydev: | 469 | err_free_keydev: |
474 | input_free_device(key_dev); | 470 | input_free_device(key_dev); |
475 | 471 | ||
476 | err_destroy_wq: | ||
477 | destroy_workqueue(sony_laptop_input.wq); | ||
478 | |||
479 | err_free_kfifo: | 472 | err_free_kfifo: |
480 | kfifo_free(&sony_laptop_input.fifo); | 473 | kfifo_free(&sony_laptop_input.fifo); |
481 | 474 | ||
@@ -486,12 +479,23 @@ err_dec_users: | |||
486 | 479 | ||
487 | static void sony_laptop_remove_input(void) | 480 | static void sony_laptop_remove_input(void) |
488 | { | 481 | { |
489 | /* cleanup only after the last user has gone */ | 482 | struct sony_laptop_keypress kp = { NULL }; |
483 | |||
484 | /* Cleanup only after the last user has gone */ | ||
490 | if (!atomic_dec_and_test(&sony_laptop_input.users)) | 485 | if (!atomic_dec_and_test(&sony_laptop_input.users)) |
491 | return; | 486 | return; |
492 | 487 | ||
493 | /* flush workqueue first */ | 488 | del_timer_sync(&sony_laptop_input.release_key_timer); |
494 | flush_workqueue(sony_laptop_input.wq); | 489 | |
490 | /* | ||
491 | * Generate key-up events for remaining keys. Note that we don't | ||
492 | * need locking since nobody is adding new events to the kfifo. | ||
493 | */ | ||
494 | while (kfifo_out(&sony_laptop_input.fifo, | ||
495 | (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { | ||
496 | input_report_key(kp.dev, kp.key, 0); | ||
497 | input_sync(kp.dev); | ||
498 | } | ||
495 | 499 | ||
496 | /* destroy input devs */ | 500 | /* destroy input devs */ |
497 | input_unregister_device(sony_laptop_input.key_dev); | 501 | input_unregister_device(sony_laptop_input.key_dev); |
@@ -502,7 +506,6 @@ static void sony_laptop_remove_input(void) | |||
502 | sony_laptop_input.jog_dev = NULL; | 506 | sony_laptop_input.jog_dev = NULL; |
503 | } | 507 | } |
504 | 508 | ||
505 | destroy_workqueue(sony_laptop_input.wq); | ||
506 | kfifo_free(&sony_laptop_input.fifo); | 509 | kfifo_free(&sony_laptop_input.fifo); |
507 | } | 510 | } |
508 | 511 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e7b0c3bcef89..c64e3528889b 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1668,7 +1668,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
1668 | * Table of recommended minimum BIOS versions | 1668 | * Table of recommended minimum BIOS versions |
1669 | * | 1669 | * |
1670 | * Reasons for listing: | 1670 | * Reasons for listing: |
1671 | * 1. Stable BIOS, listed because the unknown ammount of | 1671 | * 1. Stable BIOS, listed because the unknown amount of |
1672 | * bugs and bad ACPI behaviour on older versions | 1672 | * bugs and bad ACPI behaviour on older versions |
1673 | * | 1673 | * |
1674 | * 2. BIOS or EC fw with known bugs that trigger on Linux | 1674 | * 2. BIOS or EC fw with known bugs that trigger on Linux |
@@ -7108,7 +7108,7 @@ static struct ibm_struct volume_driver_data = { | |||
7108 | * | 7108 | * |
7109 | * Fan speed changes of any sort (including those caused by the | 7109 | * Fan speed changes of any sort (including those caused by the |
7110 | * disengaged mode) are usually done slowly by the firmware as the | 7110 | * disengaged mode) are usually done slowly by the firmware as the |
7111 | * maximum ammount of fan duty cycle change per second seems to be | 7111 | * maximum amount of fan duty cycle change per second seems to be |
7112 | * limited. | 7112 | * limited. |
7113 | * | 7113 | * |
7114 | * Reading is not available if GFAN exists. | 7114 | * Reading is not available if GFAN exists. |
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 02f3d4e9e666..4d6516fded7e 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -46,7 +46,7 @@ static struct tps_key_entry topstar_keymap[] = { | |||
46 | { } | 46 | { } |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct tps_key_entry *tps_get_key_by_scancode(int code) | 49 | static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code) |
50 | { | 50 | { |
51 | struct tps_key_entry *key; | 51 | struct tps_key_entry *key; |
52 | 52 | ||
@@ -57,7 +57,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code) | |||
57 | return NULL; | 57 | return NULL; |
58 | } | 58 | } |
59 | 59 | ||
60 | static struct tps_key_entry *tps_get_key_by_keycode(int code) | 60 | static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code) |
61 | { | 61 | { |
62 | struct tps_key_entry *key; | 62 | struct tps_key_entry *key; |
63 | 63 | ||
@@ -126,7 +126,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) | |||
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 129 | static int topstar_getkeycode(struct input_dev *dev, |
130 | unsigned int scancode, unsigned int *keycode) | ||
130 | { | 131 | { |
131 | struct tps_key_entry *key = tps_get_key_by_scancode(scancode); | 132 | struct tps_key_entry *key = tps_get_key_by_scancode(scancode); |
132 | 133 | ||
@@ -137,14 +138,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) | |||
137 | return 0; | 138 | return 0; |
138 | } | 139 | } |
139 | 140 | ||
140 | static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode) | 141 | static int topstar_setkeycode(struct input_dev *dev, |
142 | unsigned int scancode, unsigned int keycode) | ||
141 | { | 143 | { |
142 | struct tps_key_entry *key; | 144 | struct tps_key_entry *key; |
143 | int old_keycode; | 145 | int old_keycode; |
144 | 146 | ||
145 | if (keycode < 0 || keycode > KEY_MAX) | ||
146 | return -EINVAL; | ||
147 | |||
148 | key = tps_get_key_by_scancode(scancode); | 147 | key = tps_get_key_by_scancode(scancode); |
149 | 148 | ||
150 | if (!key) | 149 | if (!key) |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 405b969734d6..789240d1b577 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -745,7 +745,7 @@ static struct backlight_ops toshiba_backlight_data = { | |||
745 | .update_status = set_lcd_status, | 745 | .update_status = set_lcd_status, |
746 | }; | 746 | }; |
747 | 747 | ||
748 | static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) | 748 | static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code) |
749 | { | 749 | { |
750 | struct key_entry *key; | 750 | struct key_entry *key; |
751 | 751 | ||
@@ -756,7 +756,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) | |||
756 | return NULL; | 756 | return NULL; |
757 | } | 757 | } |
758 | 758 | ||
759 | static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) | 759 | static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code) |
760 | { | 760 | { |
761 | struct key_entry *key; | 761 | struct key_entry *key; |
762 | 762 | ||
@@ -767,8 +767,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) | |||
767 | return NULL; | 767 | return NULL; |
768 | } | 768 | } |
769 | 769 | ||
770 | static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, | 770 | static int toshiba_acpi_getkeycode(struct input_dev *dev, |
771 | int *keycode) | 771 | unsigned int scancode, unsigned int *keycode) |
772 | { | 772 | { |
773 | struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); | 773 | struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); |
774 | 774 | ||
@@ -780,14 +780,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, | |||
780 | return -EINVAL; | 780 | return -EINVAL; |
781 | } | 781 | } |
782 | 782 | ||
783 | static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode, | 783 | static int toshiba_acpi_setkeycode(struct input_dev *dev, |
784 | int keycode) | 784 | unsigned int scancode, unsigned int keycode) |
785 | { | 785 | { |
786 | struct key_entry *key; | 786 | struct key_entry *key; |
787 | int old_keycode; | 787 | unsigned int old_keycode; |
788 | |||
789 | if (keycode < 0 || keycode > KEY_MAX) | ||
790 | return -EINVAL; | ||
791 | 788 | ||
792 | key = toshiba_acpi_get_entry_by_scancode(scancode); | 789 | key = toshiba_acpi_get_entry_by_scancode(scancode); |
793 | if (key && key->type == KE_KEY) { | 790 | if (key && key->type == KE_KEY) { |
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 0b8d14050efa..0bab84ebb15d 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
@@ -166,6 +166,9 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | |||
166 | struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | 166 | struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, |
167 | resource_size_t start, | 167 | resource_size_t start, |
168 | resource_size_t end, int flags); | 168 | resource_size_t end, int flags); |
169 | struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, | ||
170 | resource_size_t start, | ||
171 | resource_size_t end); | ||
169 | 172 | ||
170 | extern int pnp_debug; | 173 | extern int pnp_debug; |
171 | 174 | ||
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 68b0c04987e4..cfaf5b73540b 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -278,9 +278,12 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
278 | switch (pnp_resource_type(res)) { | 278 | switch (pnp_resource_type(res)) { |
279 | case IORESOURCE_IO: | 279 | case IORESOURCE_IO: |
280 | case IORESOURCE_MEM: | 280 | case IORESOURCE_MEM: |
281 | pnp_printf(buffer, " %#llx-%#llx\n", | 281 | case IORESOURCE_BUS: |
282 | pnp_printf(buffer, " %#llx-%#llx%s\n", | ||
282 | (unsigned long long) res->start, | 283 | (unsigned long long) res->start, |
283 | (unsigned long long) res->end); | 284 | (unsigned long long) res->end, |
285 | res->flags & IORESOURCE_WINDOW ? | ||
286 | " window" : ""); | ||
284 | break; | 287 | break; |
285 | case IORESOURCE_IRQ: | 288 | case IORESOURCE_IRQ: |
286 | case IORESOURCE_DMA: | 289 | case IORESOURCE_DMA: |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 5702b2c8691f..54514aa35b09 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -177,7 +177,8 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master, | |||
177 | } | 177 | } |
178 | 178 | ||
179 | static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, | 179 | static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, |
180 | u64 len, int io_decode) | 180 | u64 len, int io_decode, |
181 | int window) | ||
181 | { | 182 | { |
182 | int flags = 0; | 183 | int flags = 0; |
183 | u64 end = start + len - 1; | 184 | u64 end = start + len - 1; |
@@ -186,6 +187,8 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, | |||
186 | flags |= IORESOURCE_IO_16BIT_ADDR; | 187 | flags |= IORESOURCE_IO_16BIT_ADDR; |
187 | if (len == 0 || end >= 0x10003) | 188 | if (len == 0 || end >= 0x10003) |
188 | flags |= IORESOURCE_DISABLED; | 189 | flags |= IORESOURCE_DISABLED; |
190 | if (window) | ||
191 | flags |= IORESOURCE_WINDOW; | ||
189 | 192 | ||
190 | pnp_add_io_resource(dev, start, end, flags); | 193 | pnp_add_io_resource(dev, start, end, flags); |
191 | } | 194 | } |
@@ -247,7 +250,7 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, | |||
247 | 250 | ||
248 | static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, | 251 | static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, |
249 | u64 start, u64 len, | 252 | u64 start, u64 len, |
250 | int write_protect) | 253 | int write_protect, int window) |
251 | { | 254 | { |
252 | int flags = 0; | 255 | int flags = 0; |
253 | u64 end = start + len - 1; | 256 | u64 end = start + len - 1; |
@@ -256,15 +259,26 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, | |||
256 | flags |= IORESOURCE_DISABLED; | 259 | flags |= IORESOURCE_DISABLED; |
257 | if (write_protect == ACPI_READ_WRITE_MEMORY) | 260 | if (write_protect == ACPI_READ_WRITE_MEMORY) |
258 | flags |= IORESOURCE_MEM_WRITEABLE; | 261 | flags |= IORESOURCE_MEM_WRITEABLE; |
262 | if (window) | ||
263 | flags |= IORESOURCE_WINDOW; | ||
259 | 264 | ||
260 | pnp_add_mem_resource(dev, start, end, flags); | 265 | pnp_add_mem_resource(dev, start, end, flags); |
261 | } | 266 | } |
262 | 267 | ||
268 | static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev, | ||
269 | u64 start, u64 len) | ||
270 | { | ||
271 | u64 end = start + len - 1; | ||
272 | |||
273 | pnp_add_bus_resource(dev, start, end); | ||
274 | } | ||
275 | |||
263 | static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, | 276 | static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, |
264 | struct acpi_resource *res) | 277 | struct acpi_resource *res) |
265 | { | 278 | { |
266 | struct acpi_resource_address64 addr, *p = &addr; | 279 | struct acpi_resource_address64 addr, *p = &addr; |
267 | acpi_status status; | 280 | acpi_status status; |
281 | int window; | ||
268 | 282 | ||
269 | status = acpi_resource_to_address64(res, p); | 283 | status = acpi_resource_to_address64(res, p); |
270 | if (!ACPI_SUCCESS(status)) { | 284 | if (!ACPI_SUCCESS(status)) { |
@@ -273,37 +287,42 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, | |||
273 | return; | 287 | return; |
274 | } | 288 | } |
275 | 289 | ||
276 | if (p->producer_consumer == ACPI_PRODUCER) | 290 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; |
277 | return; | ||
278 | 291 | ||
279 | if (p->resource_type == ACPI_MEMORY_RANGE) | 292 | if (p->resource_type == ACPI_MEMORY_RANGE) |
280 | pnpacpi_parse_allocated_memresource(dev, | 293 | pnpacpi_parse_allocated_memresource(dev, |
281 | p->minimum, p->address_length, | 294 | p->minimum, p->address_length, |
282 | p->info.mem.write_protect); | 295 | p->info.mem.write_protect, window); |
283 | else if (p->resource_type == ACPI_IO_RANGE) | 296 | else if (p->resource_type == ACPI_IO_RANGE) |
284 | pnpacpi_parse_allocated_ioresource(dev, | 297 | pnpacpi_parse_allocated_ioresource(dev, |
285 | p->minimum, p->address_length, | 298 | p->minimum, p->address_length, |
286 | p->granularity == 0xfff ? ACPI_DECODE_10 : | 299 | p->granularity == 0xfff ? ACPI_DECODE_10 : |
287 | ACPI_DECODE_16); | 300 | ACPI_DECODE_16, window); |
301 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) | ||
302 | pnpacpi_parse_allocated_busresource(dev, p->minimum, | ||
303 | p->address_length); | ||
288 | } | 304 | } |
289 | 305 | ||
290 | static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, | 306 | static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, |
291 | struct acpi_resource *res) | 307 | struct acpi_resource *res) |
292 | { | 308 | { |
293 | struct acpi_resource_extended_address64 *p = &res->data.ext_address64; | 309 | struct acpi_resource_extended_address64 *p = &res->data.ext_address64; |
310 | int window; | ||
294 | 311 | ||
295 | if (p->producer_consumer == ACPI_PRODUCER) | 312 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; |
296 | return; | ||
297 | 313 | ||
298 | if (p->resource_type == ACPI_MEMORY_RANGE) | 314 | if (p->resource_type == ACPI_MEMORY_RANGE) |
299 | pnpacpi_parse_allocated_memresource(dev, | 315 | pnpacpi_parse_allocated_memresource(dev, |
300 | p->minimum, p->address_length, | 316 | p->minimum, p->address_length, |
301 | p->info.mem.write_protect); | 317 | p->info.mem.write_protect, window); |
302 | else if (p->resource_type == ACPI_IO_RANGE) | 318 | else if (p->resource_type == ACPI_IO_RANGE) |
303 | pnpacpi_parse_allocated_ioresource(dev, | 319 | pnpacpi_parse_allocated_ioresource(dev, |
304 | p->minimum, p->address_length, | 320 | p->minimum, p->address_length, |
305 | p->granularity == 0xfff ? ACPI_DECODE_10 : | 321 | p->granularity == 0xfff ? ACPI_DECODE_10 : |
306 | ACPI_DECODE_16); | 322 | ACPI_DECODE_16, window); |
323 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) | ||
324 | pnpacpi_parse_allocated_busresource(dev, p->minimum, | ||
325 | p->address_length); | ||
307 | } | 326 | } |
308 | 327 | ||
309 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | 328 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, |
@@ -368,7 +387,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
368 | pnpacpi_parse_allocated_ioresource(dev, | 387 | pnpacpi_parse_allocated_ioresource(dev, |
369 | io->minimum, | 388 | io->minimum, |
370 | io->address_length, | 389 | io->address_length, |
371 | io->io_decode); | 390 | io->io_decode, 0); |
372 | break; | 391 | break; |
373 | 392 | ||
374 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 393 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
@@ -380,7 +399,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
380 | pnpacpi_parse_allocated_ioresource(dev, | 399 | pnpacpi_parse_allocated_ioresource(dev, |
381 | fixed_io->address, | 400 | fixed_io->address, |
382 | fixed_io->address_length, | 401 | fixed_io->address_length, |
383 | ACPI_DECODE_10); | 402 | ACPI_DECODE_10, 0); |
384 | break; | 403 | break; |
385 | 404 | ||
386 | case ACPI_RESOURCE_TYPE_VENDOR: | 405 | case ACPI_RESOURCE_TYPE_VENDOR: |
@@ -396,21 +415,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
396 | pnpacpi_parse_allocated_memresource(dev, | 415 | pnpacpi_parse_allocated_memresource(dev, |
397 | memory24->minimum, | 416 | memory24->minimum, |
398 | memory24->address_length, | 417 | memory24->address_length, |
399 | memory24->write_protect); | 418 | memory24->write_protect, 0); |
400 | break; | 419 | break; |
401 | case ACPI_RESOURCE_TYPE_MEMORY32: | 420 | case ACPI_RESOURCE_TYPE_MEMORY32: |
402 | memory32 = &res->data.memory32; | 421 | memory32 = &res->data.memory32; |
403 | pnpacpi_parse_allocated_memresource(dev, | 422 | pnpacpi_parse_allocated_memresource(dev, |
404 | memory32->minimum, | 423 | memory32->minimum, |
405 | memory32->address_length, | 424 | memory32->address_length, |
406 | memory32->write_protect); | 425 | memory32->write_protect, 0); |
407 | break; | 426 | break; |
408 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 427 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
409 | fixed_memory32 = &res->data.fixed_memory32; | 428 | fixed_memory32 = &res->data.fixed_memory32; |
410 | pnpacpi_parse_allocated_memresource(dev, | 429 | pnpacpi_parse_allocated_memresource(dev, |
411 | fixed_memory32->address, | 430 | fixed_memory32->address, |
412 | fixed_memory32->address_length, | 431 | fixed_memory32->address_length, |
413 | fixed_memory32->write_protect); | 432 | fixed_memory32->write_protect, 0); |
414 | break; | 433 | break; |
415 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 434 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
416 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 435 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 64d0596bafb5..5b277dbaacde 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -470,7 +470,8 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) | |||
470 | unsigned long pnp_resource_type(struct resource *res) | 470 | unsigned long pnp_resource_type(struct resource *res) |
471 | { | 471 | { |
472 | return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | | 472 | return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | |
473 | IORESOURCE_IRQ | IORESOURCE_DMA); | 473 | IORESOURCE_IRQ | IORESOURCE_DMA | |
474 | IORESOURCE_BUS); | ||
474 | } | 475 | } |
475 | 476 | ||
476 | struct resource *pnp_get_resource(struct pnp_dev *dev, | 477 | struct resource *pnp_get_resource(struct pnp_dev *dev, |
@@ -590,6 +591,30 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | |||
590 | return pnp_res; | 591 | return pnp_res; |
591 | } | 592 | } |
592 | 593 | ||
594 | struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, | ||
595 | resource_size_t start, | ||
596 | resource_size_t end) | ||
597 | { | ||
598 | struct pnp_resource *pnp_res; | ||
599 | struct resource *res; | ||
600 | |||
601 | pnp_res = pnp_new_resource(dev); | ||
602 | if (!pnp_res) { | ||
603 | dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", | ||
604 | (unsigned long long) start, | ||
605 | (unsigned long long) end); | ||
606 | return NULL; | ||
607 | } | ||
608 | |||
609 | res = &pnp_res->res; | ||
610 | res->flags = IORESOURCE_BUS; | ||
611 | res->start = start; | ||
612 | res->end = end; | ||
613 | |||
614 | pnp_dbg(&dev->dev, " add %pr\n", res); | ||
615 | return pnp_res; | ||
616 | } | ||
617 | |||
593 | /* | 618 | /* |
594 | * Determine whether the specified resource is a possible configuration | 619 | * Determine whether the specified resource is a possible configuration |
595 | * for this device. | 620 | * for this device. |
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 9585c1c1cc36..f5beb24d036a 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
@@ -69,8 +69,10 @@ char *pnp_resource_type_name(struct resource *res) | |||
69 | return "irq"; | 69 | return "irq"; |
70 | case IORESOURCE_DMA: | 70 | case IORESOURCE_DMA: |
71 | return "dma"; | 71 | return "dma"; |
72 | case IORESOURCE_BUS: | ||
73 | return "bus"; | ||
72 | } | 74 | } |
73 | return NULL; | 75 | return "unknown"; |
74 | } | 76 | } |
75 | 77 | ||
76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | 78 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) |
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index c790e0c77d4b..ff05e6189768 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -99,6 +99,7 @@ static struct device_attribute power_supply_attrs[] = { | |||
99 | POWER_SUPPLY_ATTR(present), | 99 | POWER_SUPPLY_ATTR(present), |
100 | POWER_SUPPLY_ATTR(online), | 100 | POWER_SUPPLY_ATTR(online), |
101 | POWER_SUPPLY_ATTR(technology), | 101 | POWER_SUPPLY_ATTR(technology), |
102 | POWER_SUPPLY_ATTR(cycle_count), | ||
102 | POWER_SUPPLY_ATTR(voltage_max), | 103 | POWER_SUPPLY_ATTR(voltage_max), |
103 | POWER_SUPPLY_ATTR(voltage_min), | 104 | POWER_SUPPLY_ATTR(voltage_min), |
104 | POWER_SUPPLY_ATTR(voltage_max_design), | 105 | POWER_SUPPLY_ATTR(voltage_max_design), |
diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig index cc2eb8edb514..1afe4e03440f 100644 --- a/drivers/pps/Kconfig +++ b/drivers/pps/Kconfig | |||
@@ -30,4 +30,6 @@ config PPS_DEBUG | |||
30 | messages to the system log. Select this if you are having a | 30 | messages to the system log. Select this if you are having a |
31 | problem with PPS support and want to see more of what is going on. | 31 | problem with PPS support and want to see more of what is going on. |
32 | 32 | ||
33 | source drivers/pps/clients/Kconfig | ||
34 | |||
33 | endmenu | 35 | endmenu |
diff --git a/drivers/pps/Makefile b/drivers/pps/Makefile index 19ea582f431d..98960ddd3188 100644 --- a/drivers/pps/Makefile +++ b/drivers/pps/Makefile | |||
@@ -4,5 +4,6 @@ | |||
4 | 4 | ||
5 | pps_core-y := pps.o kapi.o sysfs.o | 5 | pps_core-y := pps.o kapi.o sysfs.o |
6 | obj-$(CONFIG_PPS) := pps_core.o | 6 | obj-$(CONFIG_PPS) := pps_core.o |
7 | obj-y += clients/ | ||
7 | 8 | ||
8 | ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG | 9 | ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG |
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig new file mode 100644 index 000000000000..4e801bd7254f --- /dev/null +++ b/drivers/pps/clients/Kconfig | |||
@@ -0,0 +1,25 @@ | |||
1 | # | ||
2 | # PPS clients configuration | ||
3 | # | ||
4 | |||
5 | if PPS | ||
6 | |||
7 | comment "PPS clients support" | ||
8 | |||
9 | config PPS_CLIENT_KTIMER | ||
10 | tristate "Kernel timer client (Testing client, use for debug)" | ||
11 | help | ||
12 | If you say yes here you get support for a PPS debugging client | ||
13 | which uses a kernel timer to generate the PPS signal. | ||
14 | |||
15 | This driver can also be built as a module. If so, the module | ||
16 | will be called pps-ktimer. | ||
17 | |||
18 | config PPS_CLIENT_LDISC | ||
19 | tristate "PPS line discipline" | ||
20 | depends on PPS | ||
21 | help | ||
22 | If you say yes here you get support for a PPS source connected | ||
23 | with the CD (Carrier Detect) pin of your serial port. | ||
24 | |||
25 | endif | ||
diff --git a/drivers/pps/clients/Makefile b/drivers/pps/clients/Makefile new file mode 100644 index 000000000000..812c9b19b430 --- /dev/null +++ b/drivers/pps/clients/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for PPS clients. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PPS_CLIENT_KTIMER) += pps-ktimer.o | ||
6 | obj-$(CONFIG_PPS_CLIENT_LDISC) += pps-ldisc.o | ||
7 | |||
8 | ifeq ($(CONFIG_PPS_DEBUG),y) | ||
9 | EXTRA_CFLAGS += -DDEBUG | ||
10 | endif | ||
diff --git a/drivers/pps/clients/pps-ktimer.c b/drivers/pps/clients/pps-ktimer.c new file mode 100644 index 000000000000..e7ef5b8186d0 --- /dev/null +++ b/drivers/pps/clients/pps-ktimer.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * pps-ktimer.c -- kernel timer test client | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2005-2006 Rodolfo Giometti <giometti@linux.it> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/time.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/pps_kernel.h> | ||
29 | |||
30 | /* | ||
31 | * Global variables | ||
32 | */ | ||
33 | |||
34 | static int source; | ||
35 | static struct timer_list ktimer; | ||
36 | |||
37 | /* | ||
38 | * The kernel timer | ||
39 | */ | ||
40 | |||
41 | static void pps_ktimer_event(unsigned long ptr) | ||
42 | { | ||
43 | struct timespec __ts; | ||
44 | struct pps_ktime ts; | ||
45 | |||
46 | /* First of all we get the time stamp... */ | ||
47 | getnstimeofday(&__ts); | ||
48 | |||
49 | pr_info("PPS event at %lu\n", jiffies); | ||
50 | |||
51 | /* ... and translate it to PPS time data struct */ | ||
52 | ts.sec = __ts.tv_sec; | ||
53 | ts.nsec = __ts.tv_nsec; | ||
54 | |||
55 | pps_event(source, &ts, PPS_CAPTUREASSERT, NULL); | ||
56 | |||
57 | mod_timer(&ktimer, jiffies + HZ); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * The echo function | ||
62 | */ | ||
63 | |||
64 | static void pps_ktimer_echo(int source, int event, void *data) | ||
65 | { | ||
66 | pr_info("echo %s %s for source %d\n", | ||
67 | event & PPS_CAPTUREASSERT ? "assert" : "", | ||
68 | event & PPS_CAPTURECLEAR ? "clear" : "", | ||
69 | source); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * The PPS info struct | ||
74 | */ | ||
75 | |||
76 | static struct pps_source_info pps_ktimer_info = { | ||
77 | .name = "ktimer", | ||
78 | .path = "", | ||
79 | .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | | ||
80 | PPS_ECHOASSERT | | ||
81 | PPS_CANWAIT | PPS_TSFMT_TSPEC, | ||
82 | .echo = pps_ktimer_echo, | ||
83 | .owner = THIS_MODULE, | ||
84 | }; | ||
85 | |||
86 | /* | ||
87 | * Module staff | ||
88 | */ | ||
89 | |||
90 | static void __exit pps_ktimer_exit(void) | ||
91 | { | ||
92 | del_timer_sync(&ktimer); | ||
93 | pps_unregister_source(source); | ||
94 | |||
95 | pr_info("ktimer PPS source unregistered\n"); | ||
96 | } | ||
97 | |||
98 | static int __init pps_ktimer_init(void) | ||
99 | { | ||
100 | int ret; | ||
101 | |||
102 | ret = pps_register_source(&pps_ktimer_info, | ||
103 | PPS_CAPTUREASSERT | PPS_OFFSETASSERT); | ||
104 | if (ret < 0) { | ||
105 | printk(KERN_ERR "cannot register ktimer source\n"); | ||
106 | return ret; | ||
107 | } | ||
108 | source = ret; | ||
109 | |||
110 | setup_timer(&ktimer, pps_ktimer_event, 0); | ||
111 | mod_timer(&ktimer, jiffies + HZ); | ||
112 | |||
113 | pr_info("ktimer PPS source registered at %d\n", source); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | module_init(pps_ktimer_init); | ||
119 | module_exit(pps_ktimer_exit); | ||
120 | |||
121 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
122 | MODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)"); | ||
123 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c new file mode 100644 index 000000000000..8e1932d29fd4 --- /dev/null +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | * pps-ldisc.c -- PPS line discipline | ||
3 | * | ||
4 | * | ||
5 | * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/serial_core.h> | ||
24 | #include <linux/tty.h> | ||
25 | #include <linux/pps_kernel.h> | ||
26 | |||
27 | #define PPS_TTY_MAGIC 0x0001 | ||
28 | |||
29 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | ||
30 | struct timespec *ts) | ||
31 | { | ||
32 | int id = (long)tty->disc_data; | ||
33 | struct timespec __ts; | ||
34 | struct pps_ktime pps_ts; | ||
35 | |||
36 | /* First of all we get the time stamp... */ | ||
37 | getnstimeofday(&__ts); | ||
38 | |||
39 | /* Does caller give us a timestamp? */ | ||
40 | if (ts) { /* Yes. Let's use it! */ | ||
41 | pps_ts.sec = ts->tv_sec; | ||
42 | pps_ts.nsec = ts->tv_nsec; | ||
43 | } else { /* No. Do it ourself! */ | ||
44 | pps_ts.sec = __ts.tv_sec; | ||
45 | pps_ts.nsec = __ts.tv_nsec; | ||
46 | } | ||
47 | |||
48 | /* Now do the PPS event report */ | ||
49 | pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR, | ||
50 | NULL); | ||
51 | |||
52 | pr_debug("PPS %s at %lu on source #%d\n", | ||
53 | status ? "assert" : "clear", jiffies, id); | ||
54 | } | ||
55 | |||
56 | static int (*alias_n_tty_open)(struct tty_struct *tty); | ||
57 | |||
58 | static int pps_tty_open(struct tty_struct *tty) | ||
59 | { | ||
60 | struct pps_source_info info; | ||
61 | struct tty_driver *drv = tty->driver; | ||
62 | int index = tty->index + drv->name_base; | ||
63 | int ret; | ||
64 | |||
65 | info.owner = THIS_MODULE; | ||
66 | info.dev = NULL; | ||
67 | snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index); | ||
68 | snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index); | ||
69 | info.mode = PPS_CAPTUREBOTH | \ | ||
70 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ | ||
71 | PPS_CANWAIT | PPS_TSFMT_TSPEC; | ||
72 | |||
73 | ret = pps_register_source(&info, PPS_CAPTUREBOTH | \ | ||
74 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); | ||
75 | if (ret < 0) { | ||
76 | pr_err("cannot register PPS source \"%s\"\n", info.path); | ||
77 | return ret; | ||
78 | } | ||
79 | tty->disc_data = (void *)(long)ret; | ||
80 | |||
81 | /* Should open N_TTY ldisc too */ | ||
82 | ret = alias_n_tty_open(tty); | ||
83 | if (ret < 0) | ||
84 | pps_unregister_source((long)tty->disc_data); | ||
85 | |||
86 | pr_info("PPS source #%d \"%s\" added\n", ret, info.path); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static void (*alias_n_tty_close)(struct tty_struct *tty); | ||
92 | |||
93 | static void pps_tty_close(struct tty_struct *tty) | ||
94 | { | ||
95 | int id = (long)tty->disc_data; | ||
96 | |||
97 | pps_unregister_source(id); | ||
98 | alias_n_tty_close(tty); | ||
99 | |||
100 | pr_info("PPS source #%d removed\n", id); | ||
101 | } | ||
102 | |||
103 | static struct tty_ldisc_ops pps_ldisc_ops; | ||
104 | |||
105 | /* | ||
106 | * Module stuff | ||
107 | */ | ||
108 | |||
109 | static int __init pps_tty_init(void) | ||
110 | { | ||
111 | int err; | ||
112 | |||
113 | /* Inherit the N_TTY's ops */ | ||
114 | n_tty_inherit_ops(&pps_ldisc_ops); | ||
115 | |||
116 | /* Save N_TTY's open()/close() methods */ | ||
117 | alias_n_tty_open = pps_ldisc_ops.open; | ||
118 | alias_n_tty_close = pps_ldisc_ops.close; | ||
119 | |||
120 | /* Init PPS_TTY data */ | ||
121 | pps_ldisc_ops.owner = THIS_MODULE; | ||
122 | pps_ldisc_ops.magic = PPS_TTY_MAGIC; | ||
123 | pps_ldisc_ops.name = "pps_tty"; | ||
124 | pps_ldisc_ops.dcd_change = pps_tty_dcd_change; | ||
125 | pps_ldisc_ops.open = pps_tty_open; | ||
126 | pps_ldisc_ops.close = pps_tty_close; | ||
127 | |||
128 | err = tty_register_ldisc(N_PPS, &pps_ldisc_ops); | ||
129 | if (err) | ||
130 | pr_err("can't register PPS line discipline\n"); | ||
131 | else | ||
132 | pr_info("PPS line discipline registered\n"); | ||
133 | |||
134 | return err; | ||
135 | } | ||
136 | |||
137 | static void __exit pps_tty_cleanup(void) | ||
138 | { | ||
139 | int err; | ||
140 | |||
141 | err = tty_unregister_ldisc(N_PPS); | ||
142 | if (err) | ||
143 | pr_err("can't unregister PPS line discipline\n"); | ||
144 | else | ||
145 | pr_info("PPS line discipline removed\n"); | ||
146 | } | ||
147 | |||
148 | module_init(pps_tty_init); | ||
149 | module_exit(pps_tty_cleanup); | ||
150 | |||
151 | MODULE_ALIAS_LDISC(N_PPS); | ||
152 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
153 | MODULE_DESCRIPTION("PPS TTY device driver"); | ||
154 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 33c0e98243ee..bc90b091f195 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c | |||
@@ -22,48 +22,57 @@ | |||
22 | * the best guess is to add 0.5s. | 22 | * the best guess is to add 0.5s. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | int rtc_hctosys_ret = -ENODEV; | ||
26 | |||
25 | static int __init rtc_hctosys(void) | 27 | static int __init rtc_hctosys(void) |
26 | { | 28 | { |
27 | int err; | 29 | int err = -ENODEV; |
28 | struct rtc_time tm; | 30 | struct rtc_time tm; |
31 | struct timespec tv = { | ||
32 | .tv_nsec = NSEC_PER_SEC >> 1, | ||
33 | }; | ||
29 | struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | 34 | struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
30 | 35 | ||
31 | if (rtc == NULL) { | 36 | if (rtc == NULL) { |
32 | printk("%s: unable to open rtc device (%s)\n", | 37 | pr_err("%s: unable to open rtc device (%s)\n", |
33 | __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); | 38 | __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); |
34 | return -ENODEV; | 39 | goto err_open; |
35 | } | 40 | } |
36 | 41 | ||
37 | err = rtc_read_time(rtc, &tm); | 42 | err = rtc_read_time(rtc, &tm); |
38 | if (err == 0) { | 43 | if (err) { |
39 | err = rtc_valid_tm(&tm); | 44 | dev_err(rtc->dev.parent, |
40 | if (err == 0) { | 45 | "hctosys: unable to read the hardware clock\n"); |
41 | struct timespec tv; | 46 | goto err_read; |
42 | 47 | ||
43 | tv.tv_nsec = NSEC_PER_SEC >> 1; | 48 | } |
44 | 49 | ||
45 | rtc_tm_to_time(&tm, &tv.tv_sec); | 50 | err = rtc_valid_tm(&tm); |
51 | if (err) { | ||
52 | dev_err(rtc->dev.parent, | ||
53 | "hctosys: invalid date/time\n"); | ||
54 | goto err_invalid; | ||
55 | } | ||
46 | 56 | ||
47 | do_settimeofday(&tv); | 57 | rtc_tm_to_time(&tm, &tv.tv_sec); |
48 | 58 | ||
49 | dev_info(rtc->dev.parent, | 59 | do_settimeofday(&tv); |
50 | "setting system clock to " | ||
51 | "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", | ||
52 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | ||
53 | tm.tm_hour, tm.tm_min, tm.tm_sec, | ||
54 | (unsigned int) tv.tv_sec); | ||
55 | } | ||
56 | else | ||
57 | dev_err(rtc->dev.parent, | ||
58 | "hctosys: invalid date/time\n"); | ||
59 | } | ||
60 | else | ||
61 | dev_err(rtc->dev.parent, | ||
62 | "hctosys: unable to read the hardware clock\n"); | ||
63 | 60 | ||
61 | dev_info(rtc->dev.parent, | ||
62 | "setting system clock to " | ||
63 | "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", | ||
64 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | ||
65 | tm.tm_hour, tm.tm_min, tm.tm_sec, | ||
66 | (unsigned int) tv.tv_sec); | ||
67 | |||
68 | err_invalid: | ||
69 | err_read: | ||
64 | rtc_class_close(rtc); | 70 | rtc_class_close(rtc); |
65 | 71 | ||
66 | return 0; | 72 | err_open: |
73 | rtc_hctosys_ret = err; | ||
74 | |||
75 | return err; | ||
67 | } | 76 | } |
68 | 77 | ||
69 | late_initcall(rtc_hctosys); | 78 | late_initcall(rtc_hctosys); |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index a1273360a44e..cad9ceb89baf 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -184,6 +184,7 @@ static int __devinit ds1742_rtc_probe(struct platform_device *pdev) | |||
184 | pdata->size_nvram = pdata->size - RTC_SIZE; | 184 | pdata->size_nvram = pdata->size - RTC_SIZE; |
185 | pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; | 185 | pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; |
186 | 186 | ||
187 | sysfs_bin_attr_init(&pdata->nvram_attr); | ||
187 | pdata->nvram_attr.attr.name = "nvram"; | 188 | pdata->nvram_attr.attr.name = "nvram"; |
188 | pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; | 189 | pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; |
189 | pdata->nvram_attr.read = ds1742_nvram_read; | 190 | pdata->nvram_attr.read = ds1742_nvram_read; |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 7dd23a6fc825..380083ca572f 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -107,8 +107,9 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, | |||
107 | char *buf) | 107 | char *buf) |
108 | { | 108 | { |
109 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE | 109 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE |
110 | if (strcmp(dev_name(&to_rtc_device(dev)->dev), | 110 | if (rtc_hctosys_ret == 0 && |
111 | CONFIG_RTC_HCTOSYS_DEVICE) == 0) | 111 | strcmp(dev_name(&to_rtc_device(dev)->dev), |
112 | CONFIG_RTC_HCTOSYS_DEVICE) == 0) | ||
112 | return sprintf(buf, "1\n"); | 113 | return sprintf(buf, "1\n"); |
113 | else | 114 | else |
114 | #endif | 115 | #endif |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4951aa82e9f5..bbea90baf98f 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/ebcdic.h> | 26 | #include <asm/ebcdic.h> |
27 | #include <asm/idals.h> | 27 | #include <asm/idals.h> |
28 | #include <asm/itcw.h> | 28 | #include <asm/itcw.h> |
29 | #include <asm/diag.h> | ||
29 | 30 | ||
30 | /* This is ugly... */ | 31 | /* This is ugly... */ |
31 | #define PRINTK_HEADER "dasd:" | 32 | #define PRINTK_HEADER "dasd:" |
@@ -2212,6 +2213,13 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) | |||
2212 | goto out; | 2213 | goto out; |
2213 | } | 2214 | } |
2214 | 2215 | ||
2216 | if ((mode & FMODE_WRITE) && | ||
2217 | (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) || | ||
2218 | (base->features & DASD_FEATURE_READONLY))) { | ||
2219 | rc = -EROFS; | ||
2220 | goto out; | ||
2221 | } | ||
2222 | |||
2215 | return 0; | 2223 | return 0; |
2216 | 2224 | ||
2217 | out: | 2225 | out: |
@@ -2289,6 +2297,34 @@ dasd_exit(void) | |||
2289 | * SECTION: common functions for ccw_driver use | 2297 | * SECTION: common functions for ccw_driver use |
2290 | */ | 2298 | */ |
2291 | 2299 | ||
2300 | /* | ||
2301 | * Is the device read-only? | ||
2302 | * Note that this function does not report the setting of the | ||
2303 | * readonly device attribute, but how it is configured in z/VM. | ||
2304 | */ | ||
2305 | int dasd_device_is_ro(struct dasd_device *device) | ||
2306 | { | ||
2307 | struct ccw_dev_id dev_id; | ||
2308 | struct diag210 diag_data; | ||
2309 | int rc; | ||
2310 | |||
2311 | if (!MACHINE_IS_VM) | ||
2312 | return 0; | ||
2313 | ccw_device_get_id(device->cdev, &dev_id); | ||
2314 | memset(&diag_data, 0, sizeof(diag_data)); | ||
2315 | diag_data.vrdcdvno = dev_id.devno; | ||
2316 | diag_data.vrdclen = sizeof(diag_data); | ||
2317 | rc = diag210(&diag_data); | ||
2318 | if (rc == 0 || rc == 2) { | ||
2319 | return diag_data.vrdcvfla & 0x80; | ||
2320 | } else { | ||
2321 | DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d", | ||
2322 | dev_id.devno, rc); | ||
2323 | return 0; | ||
2324 | } | ||
2325 | } | ||
2326 | EXPORT_SYMBOL_GPL(dasd_device_is_ro); | ||
2327 | |||
2292 | static void dasd_generic_auto_online(void *data, async_cookie_t cookie) | 2328 | static void dasd_generic_auto_online(void *data, async_cookie_t cookie) |
2293 | { | 2329 | { |
2294 | struct ccw_device *cdev = data; | 2330 | struct ccw_device *cdev = data; |
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 44796ba4eb9b..51224f76b980 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -1045,6 +1045,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) | |||
1045 | 1045 | ||
1046 | erp->retries = 5; | 1046 | erp->retries = 5; |
1047 | 1047 | ||
1048 | } else if (sense[1] & SNS1_WRITE_INHIBITED) { | ||
1049 | dev_err(&device->cdev->dev, "An I/O request was rejected" | ||
1050 | " because writing is inhibited\n"); | ||
1051 | erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); | ||
1048 | } else { | 1052 | } else { |
1049 | /* fatal error - set status to FAILED | 1053 | /* fatal error - set status to FAILED |
1050 | internal error 09 - Command Reject */ | 1054 | internal error 09 - Command Reject */ |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index d49766f3b940..8e23919c8704 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -742,6 +742,7 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, | |||
742 | const char *buf, size_t count) | 742 | const char *buf, size_t count) |
743 | { | 743 | { |
744 | struct dasd_devmap *devmap; | 744 | struct dasd_devmap *devmap; |
745 | struct dasd_device *device; | ||
745 | int val; | 746 | int val; |
746 | char *endp; | 747 | char *endp; |
747 | 748 | ||
@@ -758,12 +759,14 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, | |||
758 | devmap->features |= DASD_FEATURE_READONLY; | 759 | devmap->features |= DASD_FEATURE_READONLY; |
759 | else | 760 | else |
760 | devmap->features &= ~DASD_FEATURE_READONLY; | 761 | devmap->features &= ~DASD_FEATURE_READONLY; |
761 | if (devmap->device) | 762 | device = devmap->device; |
762 | devmap->device->features = devmap->features; | 763 | if (device) { |
763 | if (devmap->device && devmap->device->block | 764 | device->features = devmap->features; |
764 | && devmap->device->block->gdp) | 765 | val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags); |
765 | set_disk_ro(devmap->device->block->gdp, val); | 766 | } |
766 | spin_unlock(&dasd_devmap_lock); | 767 | spin_unlock(&dasd_devmap_lock); |
768 | if (device && device->block && device->block->gdp) | ||
769 | set_disk_ro(device->block->gdp, val); | ||
767 | return count; | 770 | return count; |
768 | } | 771 | } |
769 | 772 | ||
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 6e14863f5c70..687f323cdc38 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device) | |||
145 | mdsk_term_io(device); | 145 | mdsk_term_io(device); |
146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); | 146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); |
147 | if (rc == 4) { | 147 | if (rc == 4) { |
148 | if (!(device->features & DASD_FEATURE_READONLY)) { | 148 | if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags))) |
149 | pr_warning("%s: The access mode of a DIAG device " | 149 | pr_warning("%s: The access mode of a DIAG device " |
150 | "changed to read-only\n", | 150 | "changed to read-only\n", |
151 | dev_name(&device->cdev->dev)); | 151 | dev_name(&device->cdev->dev)); |
152 | device->features |= DASD_FEATURE_READONLY; | ||
153 | } | ||
154 | rc = 0; | 152 | rc = 0; |
155 | } | 153 | } |
156 | if (rc) | 154 | if (rc) |
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_device *device) | |||
449 | rc = -EIO; | 447 | rc = -EIO; |
450 | } else { | 448 | } else { |
451 | if (rc == 4) | 449 | if (rc == 4) |
452 | device->features |= DASD_FEATURE_READONLY; | 450 | set_bit(DASD_FLAG_DEVICE_RO, &device->flags); |
453 | pr_info("%s: New DASD with %ld byte/block, total size %ld " | 451 | pr_info("%s: New DASD with %ld byte/block, total size %ld " |
454 | "KB%s\n", dev_name(&device->cdev->dev), | 452 | "KB%s\n", dev_name(&device->cdev->dev), |
455 | (unsigned long) block->bp_block, | 453 | (unsigned long) block->bp_block, |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 1cca21aafaba..01f4e7a34aa8 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1089 | struct dasd_eckd_private *private; | 1089 | struct dasd_eckd_private *private; |
1090 | struct dasd_block *block; | 1090 | struct dasd_block *block; |
1091 | int is_known, rc; | 1091 | int is_known, rc; |
1092 | int readonly; | ||
1092 | 1093 | ||
1093 | if (!ccw_device_is_pathgroup(device->cdev)) { | 1094 | if (!ccw_device_is_pathgroup(device->cdev)) { |
1094 | dev_warn(&device->cdev->dev, | 1095 | dev_warn(&device->cdev->dev, |
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1182 | else | 1183 | else |
1183 | private->real_cyl = private->rdc_data.no_cyl; | 1184 | private->real_cyl = private->rdc_data.no_cyl; |
1184 | 1185 | ||
1186 | readonly = dasd_device_is_ro(device); | ||
1187 | if (readonly) | ||
1188 | set_bit(DASD_FLAG_DEVICE_RO, &device->flags); | ||
1189 | |||
1185 | dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " | 1190 | dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " |
1186 | "with %d cylinders, %d heads, %d sectors\n", | 1191 | "with %d cylinders, %d heads, %d sectors%s\n", |
1187 | private->rdc_data.dev_type, | 1192 | private->rdc_data.dev_type, |
1188 | private->rdc_data.dev_model, | 1193 | private->rdc_data.dev_model, |
1189 | private->rdc_data.cu_type, | 1194 | private->rdc_data.cu_type, |
1190 | private->rdc_data.cu_model.model, | 1195 | private->rdc_data.cu_model.model, |
1191 | private->real_cyl, | 1196 | private->real_cyl, |
1192 | private->rdc_data.trk_per_cyl, | 1197 | private->rdc_data.trk_per_cyl, |
1193 | private->rdc_data.sec_per_trk); | 1198 | private->rdc_data.sec_per_trk, |
1199 | readonly ? ", read-only device" : ""); | ||
1194 | return 0; | 1200 | return 0; |
1195 | 1201 | ||
1196 | out_err3: | 1202 | out_err3: |
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp) | |||
2839 | char *psf_data, *rssd_result; | 2845 | char *psf_data, *rssd_result; |
2840 | struct dasd_ccw_req *cqr; | 2846 | struct dasd_ccw_req *cqr; |
2841 | struct ccw1 *ccw; | 2847 | struct ccw1 *ccw; |
2848 | char psf0, psf1; | ||
2842 | int rc; | 2849 | int rc; |
2843 | 2850 | ||
2851 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) | ||
2852 | return -EACCES; | ||
2853 | psf0 = psf1 = 0; | ||
2854 | |||
2844 | /* Copy parms from caller */ | 2855 | /* Copy parms from caller */ |
2845 | rc = -EFAULT; | 2856 | rc = -EFAULT; |
2846 | if (copy_from_user(&usrparm, argp, sizeof(usrparm))) | 2857 | if (copy_from_user(&usrparm, argp, sizeof(usrparm))) |
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp) | |||
2869 | (void __user *)(unsigned long) usrparm.psf_data, | 2880 | (void __user *)(unsigned long) usrparm.psf_data, |
2870 | usrparm.psf_data_len)) | 2881 | usrparm.psf_data_len)) |
2871 | goto out_free; | 2882 | goto out_free; |
2872 | 2883 | psf0 = psf_data[0]; | |
2873 | /* sanity check on syscall header */ | 2884 | psf1 = psf_data[1]; |
2874 | if (psf_data[0] != 0x17 && psf_data[1] != 0xce) { | ||
2875 | rc = -EINVAL; | ||
2876 | goto out_free; | ||
2877 | } | ||
2878 | 2885 | ||
2879 | /* setup CCWs for PSF + RSSD */ | 2886 | /* setup CCWs for PSF + RSSD */ |
2880 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); | 2887 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); |
@@ -2925,7 +2932,9 @@ out_free: | |||
2925 | kfree(rssd_result); | 2932 | kfree(rssd_result); |
2926 | kfree(psf_data); | 2933 | kfree(psf_data); |
2927 | out: | 2934 | out: |
2928 | DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc); | 2935 | DBF_DEV_EVENT(DBF_WARNING, device, |
2936 | "Symmetrix ioctl (0x%02x 0x%02x): rc=%d", | ||
2937 | (int) psf0, (int) psf1, rc); | ||
2929 | return rc; | 2938 | return rc; |
2930 | } | 2939 | } |
2931 | 2940 | ||
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 0f152444ac77..37282b90eecc 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
124 | struct dasd_fba_private *private; | 124 | struct dasd_fba_private *private; |
125 | struct ccw_device *cdev = device->cdev; | 125 | struct ccw_device *cdev = device->cdev; |
126 | int rc; | 126 | int rc; |
127 | int readonly; | ||
127 | 128 | ||
128 | private = (struct dasd_fba_private *) device->private; | 129 | private = (struct dasd_fba_private *) device->private; |
129 | if (!private) { | 130 | if (!private) { |
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
162 | return rc; | 163 | return rc; |
163 | } | 164 | } |
164 | 165 | ||
166 | readonly = dasd_device_is_ro(device); | ||
167 | if (readonly) | ||
168 | set_bit(DASD_FLAG_DEVICE_RO, &device->flags); | ||
169 | |||
165 | dev_info(&device->cdev->dev, | 170 | dev_info(&device->cdev->dev, |
166 | "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " | 171 | "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " |
167 | "and %d B/blk\n", | 172 | "and %d B/blk%s\n", |
168 | cdev->id.dev_type, | 173 | cdev->id.dev_type, |
169 | cdev->id.dev_model, | 174 | cdev->id.dev_model, |
170 | cdev->id.cu_type, | 175 | cdev->id.cu_type, |
171 | cdev->id.cu_model, | 176 | cdev->id.cu_model, |
172 | ((private->rdc_data.blk_bdsa * | 177 | ((private->rdc_data.blk_bdsa * |
173 | (private->rdc_data.blk_size >> 9)) >> 11), | 178 | (private->rdc_data.blk_size >> 9)) >> 11), |
174 | private->rdc_data.blk_size); | 179 | private->rdc_data.blk_size, |
180 | readonly ? ", read-only device" : ""); | ||
175 | return 0; | 181 | return 0; |
176 | } | 182 | } |
177 | 183 | ||
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 94f92a1247f2..30a1ca3d08b7 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block *block) | |||
70 | } | 70 | } |
71 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); | 71 | len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); |
72 | 72 | ||
73 | if (block->base->features & DASD_FEATURE_READONLY) | 73 | if (base->features & DASD_FEATURE_READONLY || |
74 | test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) | ||
74 | set_disk_ro(gdp, 1); | 75 | set_disk_ro(gdp, 1); |
75 | gdp->private_data = block; | 76 | gdp->private_data = block; |
76 | gdp->queue = block->request_queue; | 77 | gdp->queue = block->request_queue; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index ed73ce550822..a91d4a97d4f2 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -436,6 +436,10 @@ struct dasd_block { | |||
436 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ | 436 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ |
437 | #define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ | 437 | #define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ |
438 | #define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ | 438 | #define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ |
439 | #define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't | ||
440 | * confuse this with the user specified | ||
441 | * read-only feature. | ||
442 | */ | ||
439 | 443 | ||
440 | void dasd_put_device_wake(struct dasd_device *); | 444 | void dasd_put_device_wake(struct dasd_device *); |
441 | 445 | ||
@@ -609,6 +613,9 @@ char *dasd_get_sense(struct irb *); | |||
609 | void dasd_device_set_stop_bits(struct dasd_device *, int); | 613 | void dasd_device_set_stop_bits(struct dasd_device *, int); |
610 | void dasd_device_remove_stop_bits(struct dasd_device *, int); | 614 | void dasd_device_remove_stop_bits(struct dasd_device *, int); |
611 | 615 | ||
616 | int dasd_device_is_ro(struct dasd_device *); | ||
617 | |||
618 | |||
612 | /* externals in dasd_devmap.c */ | 619 | /* externals in dasd_devmap.c */ |
613 | extern int dasd_max_devindex; | 620 | extern int dasd_max_devindex; |
614 | extern int dasd_probeonly; | 621 | extern int dasd_probeonly; |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 7039d9cf0fb4..3479f8158a1b 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -199,7 +199,8 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp) | |||
199 | if (!argp) | 199 | if (!argp) |
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | 201 | ||
202 | if (block->base->features & DASD_FEATURE_READONLY) | 202 | if (block->base->features & DASD_FEATURE_READONLY || |
203 | test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | ||
203 | return -EROFS; | 204 | return -EROFS; |
204 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) | 205 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) |
205 | return -EFAULT; | 206 | return -EFAULT; |
@@ -349,7 +350,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | |||
349 | return -EINVAL; | 350 | return -EINVAL; |
350 | if (get_user(intval, (int __user *)argp)) | 351 | if (get_user(intval, (int __user *)argp)) |
351 | return -EFAULT; | 352 | return -EFAULT; |
352 | 353 | if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | |
354 | return -EROFS; | ||
353 | set_disk_ro(bdev->bd_disk, intval); | 355 | set_disk_ro(bdev->bd_disk, intval); |
354 | return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); | 356 | return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); |
355 | } | 357 | } |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 62ddf5202b79..2a4c566456e7 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -373,7 +373,7 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
373 | rq->rc = ccw_device_start(rp->cdev, &rq->ccw, | 373 | rq->rc = ccw_device_start(rp->cdev, &rq->ccw, |
374 | (unsigned long) rq, 0, 0); | 374 | (unsigned long) rq, 0, 0); |
375 | if (rq->rc == 0) | 375 | if (rq->rc == 0) |
376 | return; /* Sucessfully restarted. */ | 376 | return; /* Successfully restarted. */ |
377 | break; | 377 | break; |
378 | case RAW3270_IO_STOP: | 378 | case RAW3270_IO_STOP: |
379 | if (!rq) | 379 | if (!rq) |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index ec88c59842e3..f6d72e1f2a38 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -196,7 +196,7 @@ __sclp_start_request(struct sclp_req *req) | |||
196 | req->start_count++; | 196 | req->start_count++; |
197 | 197 | ||
198 | if (rc == 0) { | 198 | if (rc == 0) { |
199 | /* Sucessfully started request */ | 199 | /* Successfully started request */ |
200 | req->status = SCLP_REQ_RUNNING; | 200 | req->status = SCLP_REQ_RUNNING; |
201 | sclp_running_state = sclp_running_state_running; | 201 | sclp_running_state = sclp_running_state_running; |
202 | __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ, | 202 | __sclp_set_request_timer(SCLP_RETRY_INTERVAL * HZ, |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index c6abb75c4615..6d229f3523a0 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -764,7 +764,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch) | |||
764 | static void io_subchannel_register(struct ccw_device *cdev) | 764 | static void io_subchannel_register(struct ccw_device *cdev) |
765 | { | 765 | { |
766 | struct subchannel *sch; | 766 | struct subchannel *sch; |
767 | int ret; | 767 | int ret, adjust_init_count = 1; |
768 | unsigned long flags; | 768 | unsigned long flags; |
769 | 769 | ||
770 | sch = to_subchannel(cdev->dev.parent); | 770 | sch = to_subchannel(cdev->dev.parent); |
@@ -793,6 +793,7 @@ static void io_subchannel_register(struct ccw_device *cdev) | |||
793 | cdev->private->dev_id.ssid, | 793 | cdev->private->dev_id.ssid, |
794 | cdev->private->dev_id.devno); | 794 | cdev->private->dev_id.devno); |
795 | } | 795 | } |
796 | adjust_init_count = 0; | ||
796 | goto out; | 797 | goto out; |
797 | } | 798 | } |
798 | /* | 799 | /* |
@@ -818,7 +819,7 @@ out: | |||
818 | cdev->private->flags.recog_done = 1; | 819 | cdev->private->flags.recog_done = 1; |
819 | wake_up(&cdev->private->wait_q); | 820 | wake_up(&cdev->private->wait_q); |
820 | out_err: | 821 | out_err: |
821 | if (atomic_dec_and_test(&ccw_device_init_count)) | 822 | if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count)) |
822 | wake_up(&ccw_device_init_wq); | 823 | wake_up(&ccw_device_init_wq); |
823 | } | 824 | } |
824 | 825 | ||
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index c94eb2a0fa2e..6ce83f56d537 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data, | |||
33 | DBF_HEX(&init_data->input_handler, sizeof(void *)); | 33 | DBF_HEX(&init_data->input_handler, sizeof(void *)); |
34 | DBF_HEX(&init_data->output_handler, sizeof(void *)); | 34 | DBF_HEX(&init_data->output_handler, sizeof(void *)); |
35 | DBF_HEX(&init_data->int_parm, sizeof(long)); | 35 | DBF_HEX(&init_data->int_parm, sizeof(long)); |
36 | DBF_HEX(&init_data->flags, sizeof(long)); | ||
37 | DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); | 36 | DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); |
38 | DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); | 37 | DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); |
39 | DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); | 38 | DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 232ef047ba34..4f8f74311778 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -588,10 +588,11 @@ static void qdio_kick_handler(struct qdio_q *q) | |||
588 | if (q->is_input_q) { | 588 | if (q->is_input_q) { |
589 | qperf_inc(q, inbound_handler); | 589 | qperf_inc(q, inbound_handler); |
590 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); | 590 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); |
591 | } else | 591 | } else { |
592 | qperf_inc(q, outbound_handler); | 592 | qperf_inc(q, outbound_handler); |
593 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", | 593 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", |
594 | start, count); | 594 | start, count); |
595 | } | ||
595 | 596 | ||
596 | q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, | 597 | q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, |
597 | q->irq_ptr->int_parm); | 598 | q->irq_ptr->int_parm); |
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index cb909a5b5047..977bb4d4ed15 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig | |||
@@ -43,6 +43,16 @@ config SMSGIUCV | |||
43 | Select this option if you want to be able to receive SMSG messages | 43 | Select this option if you want to be able to receive SMSG messages |
44 | from other VM guest systems. | 44 | from other VM guest systems. |
45 | 45 | ||
46 | config SMSGIUCV_EVENT | ||
47 | tristate "Deliver IUCV special messages as uevents (VM only)" | ||
48 | depends on SMSGIUCV | ||
49 | help | ||
50 | Select this option to deliver CP special messages (SMSGs) as | ||
51 | uevents. The driver handles only those special messages that | ||
52 | start with "APP". | ||
53 | |||
54 | To compile as a module, choose M. The module name is "smsgiucv_app". | ||
55 | |||
46 | config CLAW | 56 | config CLAW |
47 | tristate "CLAW device support" | 57 | tristate "CLAW device support" |
48 | depends on CCW && NETDEVICES | 58 | depends on CCW && NETDEVICES |
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 6cab5a62f99e..4dfe8c1092da 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile | |||
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o | |||
6 | obj-$(CONFIG_CTCM) += ctcm.o fsm.o | 6 | obj-$(CONFIG_CTCM) += ctcm.o fsm.o |
7 | obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o | 7 | obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o |
8 | obj-$(CONFIG_SMSGIUCV) += smsgiucv.o | 8 | obj-$(CONFIG_SMSGIUCV) += smsgiucv.o |
9 | obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o | ||
9 | obj-$(CONFIG_LCS) += lcs.o | 10 | obj-$(CONFIG_LCS) += lcs.o |
10 | obj-$(CONFIG_CLAW) += claw.o | 11 | obj-$(CONFIG_CLAW) += claw.o |
11 | qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o | 12 | qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index a3ac4456e0b1..fcd005aad989 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -763,7 +763,8 @@ static inline int qeth_get_micros(void) | |||
763 | 763 | ||
764 | static inline int qeth_get_ip_version(struct sk_buff *skb) | 764 | static inline int qeth_get_ip_version(struct sk_buff *skb) |
765 | { | 765 | { |
766 | switch (skb->protocol) { | 766 | struct ethhdr *ehdr = (struct ethhdr *)skb->data; |
767 | switch (ehdr->h_proto) { | ||
767 | case ETH_P_IPV6: | 768 | case ETH_P_IPV6: |
768 | return 6; | 769 | return 6; |
769 | case ETH_P_IP: | 770 | case ETH_P_IP: |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fa8a519218ac..3bd4206f3470 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -537,7 +537,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel, | |||
537 | dev_err(&card->gdev->dev, | 537 | dev_err(&card->gdev->dev, |
538 | "The qeth device is not configured " | 538 | "The qeth device is not configured " |
539 | "for the OSI layer required by z/VM\n"); | 539 | "for the OSI layer required by z/VM\n"); |
540 | qeth_schedule_recovery(card); | 540 | else |
541 | qeth_schedule_recovery(card); | ||
541 | goto out; | 542 | goto out; |
542 | } | 543 | } |
543 | 544 | ||
@@ -1113,8 +1114,6 @@ static int qeth_setup_card(struct qeth_card *card) | |||
1113 | card->ipato.enabled = 0; | 1114 | card->ipato.enabled = 0; |
1114 | card->ipato.invert4 = 0; | 1115 | card->ipato.invert4 = 0; |
1115 | card->ipato.invert6 = 0; | 1116 | card->ipato.invert6 = 0; |
1116 | if (card->info.type == QETH_CARD_TYPE_IQD) | ||
1117 | card->options.checksum_type = NO_CHECKSUMMING; | ||
1118 | /* init QDIO stuff */ | 1117 | /* init QDIO stuff */ |
1119 | qeth_init_qdio_info(card); | 1118 | qeth_init_qdio_info(card); |
1120 | return 0; | 1119 | return 0; |
@@ -3805,9 +3804,6 @@ static int qeth_qdio_establish(struct qeth_card *card) | |||
3805 | init_data.input_handler = card->discipline.input_handler; | 3804 | init_data.input_handler = card->discipline.input_handler; |
3806 | init_data.output_handler = card->discipline.output_handler; | 3805 | init_data.output_handler = card->discipline.output_handler; |
3807 | init_data.int_parm = (unsigned long) card; | 3806 | init_data.int_parm = (unsigned long) card; |
3808 | init_data.flags = QDIO_INBOUND_0COPY_SBALS | | ||
3809 | QDIO_OUTBOUND_0COPY_SBALS | | ||
3810 | QDIO_USE_OUTBOUND_PCIS; | ||
3811 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; | 3807 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; |
3812 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; | 3808 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; |
3813 | 3809 | ||
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 88ae4357136a..25dfd5abd19b 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -8,6 +8,9 @@ | |||
8 | * Frank Blaschka <frank.blaschka@de.ibm.com> | 8 | * Frank Blaschka <frank.blaschka@de.ibm.com> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "qeth" | ||
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
13 | |||
11 | #include <linux/list.h> | 14 | #include <linux/list.h> |
12 | #include <linux/rwsem.h> | 15 | #include <linux/rwsem.h> |
13 | #include <asm/ebcdic.h> | 16 | #include <asm/ebcdic.h> |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 51fde6f2e0b8..6f1e3036bafd 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -1071,11 +1071,9 @@ static int qeth_l2_recover(void *ptr) | |||
1071 | dev_info(&card->gdev->dev, | 1071 | dev_info(&card->gdev->dev, |
1072 | "Device successfully recovered!\n"); | 1072 | "Device successfully recovered!\n"); |
1073 | else { | 1073 | else { |
1074 | if (card->dev) { | 1074 | rtnl_lock(); |
1075 | rtnl_lock(); | 1075 | dev_close(card->dev); |
1076 | dev_close(card->dev); | 1076 | rtnl_unlock(); |
1077 | rtnl_unlock(); | ||
1078 | } | ||
1079 | dev_warn(&card->gdev->dev, "The qeth device driver " | 1077 | dev_warn(&card->gdev->dev, "The qeth device driver " |
1080 | "failed to recover an error on the device\n"); | 1078 | "failed to recover an error on the device\n"); |
1081 | } | 1079 | } |
@@ -1129,11 +1127,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) | |||
1129 | if (card->state == CARD_STATE_RECOVER) { | 1127 | if (card->state == CARD_STATE_RECOVER) { |
1130 | rc = __qeth_l2_set_online(card->gdev, 1); | 1128 | rc = __qeth_l2_set_online(card->gdev, 1); |
1131 | if (rc) { | 1129 | if (rc) { |
1132 | if (card->dev) { | 1130 | rtnl_lock(); |
1133 | rtnl_lock(); | 1131 | dev_close(card->dev); |
1134 | dev_close(card->dev); | 1132 | rtnl_unlock(); |
1135 | rtnl_unlock(); | ||
1136 | } | ||
1137 | } | 1133 | } |
1138 | } else | 1134 | } else |
1139 | rc = __qeth_l2_set_online(card->gdev, 0); | 1135 | rc = __qeth_l2_set_online(card->gdev, 0); |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 5475834ab916..b3b6e872d806 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -1691,39 +1691,43 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply, | |||
1691 | 1691 | ||
1692 | cmd = (struct qeth_ipa_cmd *)data; | 1692 | cmd = (struct qeth_ipa_cmd *)data; |
1693 | rc = cmd->hdr.return_code; | 1693 | rc = cmd->hdr.return_code; |
1694 | if (rc) { | 1694 | if (rc) |
1695 | QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc); | 1695 | QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc); |
1696 | if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) { | ||
1697 | switch (rc) { | ||
1698 | case IPA_RC_HARDWARE_AUTH_ERROR: | ||
1699 | dev_warn(&card->gdev->dev, "The device is not " | ||
1700 | "authorized to run as a HiperSockets " | ||
1701 | "network traffic analyzer\n"); | ||
1702 | break; | ||
1703 | case IPA_RC_TRACE_ALREADY_ACTIVE: | ||
1704 | dev_warn(&card->gdev->dev, "A HiperSockets " | ||
1705 | "network traffic analyzer is already " | ||
1706 | "active in the HiperSockets LAN\n"); | ||
1707 | break; | ||
1708 | default: | ||
1709 | break; | ||
1710 | } | ||
1711 | } | ||
1712 | return 0; | ||
1713 | } | ||
1714 | |||
1715 | switch (cmd->data.diagass.action) { | 1696 | switch (cmd->data.diagass.action) { |
1716 | case QETH_DIAGS_CMD_TRACE_QUERY: | 1697 | case QETH_DIAGS_CMD_TRACE_QUERY: |
1717 | break; | 1698 | break; |
1718 | case QETH_DIAGS_CMD_TRACE_DISABLE: | 1699 | case QETH_DIAGS_CMD_TRACE_DISABLE: |
1719 | card->info.promisc_mode = SET_PROMISC_MODE_OFF; | 1700 | switch (rc) { |
1720 | dev_info(&card->gdev->dev, "The HiperSockets network traffic " | 1701 | case 0: |
1721 | "analyzer is deactivated\n"); | 1702 | case IPA_RC_INVALID_SUBCMD: |
1703 | card->info.promisc_mode = SET_PROMISC_MODE_OFF; | ||
1704 | dev_info(&card->gdev->dev, "The HiperSockets network " | ||
1705 | "traffic analyzer is deactivated\n"); | ||
1706 | break; | ||
1707 | default: | ||
1708 | break; | ||
1709 | } | ||
1722 | break; | 1710 | break; |
1723 | case QETH_DIAGS_CMD_TRACE_ENABLE: | 1711 | case QETH_DIAGS_CMD_TRACE_ENABLE: |
1724 | card->info.promisc_mode = SET_PROMISC_MODE_ON; | 1712 | switch (rc) { |
1725 | dev_info(&card->gdev->dev, "The HiperSockets network traffic " | 1713 | case 0: |
1726 | "analyzer is activated\n"); | 1714 | card->info.promisc_mode = SET_PROMISC_MODE_ON; |
1715 | dev_info(&card->gdev->dev, "The HiperSockets network " | ||
1716 | "traffic analyzer is activated\n"); | ||
1717 | break; | ||
1718 | case IPA_RC_HARDWARE_AUTH_ERROR: | ||
1719 | dev_warn(&card->gdev->dev, "The device is not " | ||
1720 | "authorized to run as a HiperSockets network " | ||
1721 | "traffic analyzer\n"); | ||
1722 | break; | ||
1723 | case IPA_RC_TRACE_ALREADY_ACTIVE: | ||
1724 | dev_warn(&card->gdev->dev, "A HiperSockets " | ||
1725 | "network traffic analyzer is already " | ||
1726 | "active in the HiperSockets LAN\n"); | ||
1727 | break; | ||
1728 | default: | ||
1729 | break; | ||
1730 | } | ||
1727 | break; | 1731 | break; |
1728 | default: | 1732 | default: |
1729 | QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n", | 1733 | QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n", |
@@ -2215,11 +2219,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) | |||
2215 | if (recovery_mode) | 2219 | if (recovery_mode) |
2216 | qeth_l3_stop(card->dev); | 2220 | qeth_l3_stop(card->dev); |
2217 | else { | 2221 | else { |
2218 | if (card->dev) { | 2222 | rtnl_lock(); |
2219 | rtnl_lock(); | 2223 | dev_close(card->dev); |
2220 | dev_close(card->dev); | 2224 | rtnl_unlock(); |
2221 | rtnl_unlock(); | ||
2222 | } | ||
2223 | } | 2225 | } |
2224 | if (!card->use_hard_stop) { | 2226 | if (!card->use_hard_stop) { |
2225 | rc = qeth_send_stoplan(card); | 2227 | rc = qeth_send_stoplan(card); |
@@ -2900,10 +2902,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2900 | int data_offset = -1; | 2902 | int data_offset = -1; |
2901 | int nr_frags; | 2903 | int nr_frags; |
2902 | 2904 | ||
2903 | if ((card->info.type == QETH_CARD_TYPE_IQD) && | 2905 | if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) || |
2904 | (((skb->protocol != htons(ETH_P_IPV6)) && | 2906 | card->options.sniffer) |
2905 | (skb->protocol != htons(ETH_P_IP))) || | ||
2906 | card->options.sniffer)) | ||
2907 | goto tx_drop; | 2907 | goto tx_drop; |
2908 | 2908 | ||
2909 | if ((card->state != CARD_STATE_UP) || !card->lan_online) { | 2909 | if ((card->state != CARD_STATE_UP) || !card->lan_online) { |
@@ -2949,14 +2949,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2949 | if (data_offset < 0) | 2949 | if (data_offset < 0) |
2950 | skb_pull(new_skb, ETH_HLEN); | 2950 | skb_pull(new_skb, ETH_HLEN); |
2951 | } else { | 2951 | } else { |
2952 | if (new_skb->protocol == htons(ETH_P_IP)) { | 2952 | if (ipv == 4) { |
2953 | if (card->dev->type == ARPHRD_IEEE802_TR) | 2953 | if (card->dev->type == ARPHRD_IEEE802_TR) |
2954 | skb_pull(new_skb, TR_HLEN); | 2954 | skb_pull(new_skb, TR_HLEN); |
2955 | else | 2955 | else |
2956 | skb_pull(new_skb, ETH_HLEN); | 2956 | skb_pull(new_skb, ETH_HLEN); |
2957 | } | 2957 | } |
2958 | 2958 | ||
2959 | if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp && | 2959 | if (ipv == 6 && card->vlangrp && |
2960 | vlan_tx_tag_present(new_skb)) { | 2960 | vlan_tx_tag_present(new_skb)) { |
2961 | skb_push(new_skb, VLAN_HLEN); | 2961 | skb_push(new_skb, VLAN_HLEN); |
2962 | skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); | 2962 | skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); |
@@ -3534,11 +3534,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) | |||
3534 | if (card->state == CARD_STATE_RECOVER) { | 3534 | if (card->state == CARD_STATE_RECOVER) { |
3535 | rc = __qeth_l3_set_online(card->gdev, 1); | 3535 | rc = __qeth_l3_set_online(card->gdev, 1); |
3536 | if (rc) { | 3536 | if (rc) { |
3537 | if (card->dev) { | 3537 | rtnl_lock(); |
3538 | rtnl_lock(); | 3538 | dev_close(card->dev); |
3539 | dev_close(card->dev); | 3539 | rtnl_unlock(); |
3540 | rtnl_unlock(); | ||
3541 | } | ||
3542 | } | 3540 | } |
3543 | } else | 3541 | } else |
3544 | rc = __qeth_l3_set_online(card->gdev, 0); | 3542 | rc = __qeth_l3_set_online(card->gdev, 0); |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 67f2485d2372..ecef1edee701 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -31,9 +31,9 @@ | |||
31 | 31 | ||
32 | struct smsg_callback { | 32 | struct smsg_callback { |
33 | struct list_head list; | 33 | struct list_head list; |
34 | char *prefix; | 34 | const char *prefix; |
35 | int len; | 35 | int len; |
36 | void (*callback)(char *from, char *str); | 36 | void (*callback)(const char *from, char *str); |
37 | }; | 37 | }; |
38 | 38 | ||
39 | MODULE_AUTHOR | 39 | MODULE_AUTHOR |
@@ -100,8 +100,8 @@ static void smsg_message_pending(struct iucv_path *path, | |||
100 | kfree(buffer); | 100 | kfree(buffer); |
101 | } | 101 | } |
102 | 102 | ||
103 | int smsg_register_callback(char *prefix, | 103 | int smsg_register_callback(const char *prefix, |
104 | void (*callback)(char *from, char *str)) | 104 | void (*callback)(const char *from, char *str)) |
105 | { | 105 | { |
106 | struct smsg_callback *cb; | 106 | struct smsg_callback *cb; |
107 | 107 | ||
@@ -117,8 +117,9 @@ int smsg_register_callback(char *prefix, | |||
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | void smsg_unregister_callback(char *prefix, | 120 | void smsg_unregister_callback(const char *prefix, |
121 | void (*callback)(char *from, char *str)) | 121 | void (*callback)(const char *from, |
122 | char *str)) | ||
122 | { | 123 | { |
123 | struct smsg_callback *cb, *tmp; | 124 | struct smsg_callback *cb, *tmp; |
124 | 125 | ||
@@ -176,7 +177,7 @@ static const struct dev_pm_ops smsg_pm_ops = { | |||
176 | 177 | ||
177 | static struct device_driver smsg_driver = { | 178 | static struct device_driver smsg_driver = { |
178 | .owner = THIS_MODULE, | 179 | .owner = THIS_MODULE, |
179 | .name = "SMSGIUCV", | 180 | .name = SMSGIUCV_DRV_NAME, |
180 | .bus = &iucv_bus, | 181 | .bus = &iucv_bus, |
181 | .pm = &smsg_pm_ops, | 182 | .pm = &smsg_pm_ops, |
182 | }; | 183 | }; |
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h index 67f5d4f8378d..149a1151608d 100644 --- a/drivers/s390/net/smsgiucv.h +++ b/drivers/s390/net/smsgiucv.h | |||
@@ -5,6 +5,10 @@ | |||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | int smsg_register_callback(char *, void (*)(char *, char *)); | 8 | #define SMSGIUCV_DRV_NAME "SMSGIUCV" |
9 | void smsg_unregister_callback(char *, void (*)(char *, char *)); | 9 | |
10 | int smsg_register_callback(const char *, | ||
11 | void (*)(const char *, char *)); | ||
12 | void smsg_unregister_callback(const char *, | ||
13 | void (*)(const char *, char *)); | ||
10 | 14 | ||
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c new file mode 100644 index 000000000000..91579dc6a2b0 --- /dev/null +++ b/drivers/s390/net/smsgiucv_app.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * Deliver z/VM CP special messages (SMSG) as uevents. | ||
3 | * | ||
4 | * The driver registers for z/VM CP special messages with the | ||
5 | * "APP" prefix. Incoming messages are delivered to user space | ||
6 | * as uevents. | ||
7 | * | ||
8 | * Copyright IBM Corp. 2010 | ||
9 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | ||
10 | * | ||
11 | */ | ||
12 | #define KMSG_COMPONENT "smsgiucv_app" | ||
13 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
14 | |||
15 | #include <linux/ctype.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/kobject.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | #include <net/iucv/iucv.h> | ||
24 | #include "smsgiucv.h" | ||
25 | |||
26 | /* prefix used for SMSG registration */ | ||
27 | #define SMSG_PREFIX "APP" | ||
28 | |||
29 | /* SMSG related uevent environment variables */ | ||
30 | #define ENV_SENDER_STR "SMSG_SENDER=" | ||
31 | #define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1) | ||
32 | #define ENV_PREFIX_STR "SMSG_ID=" | ||
33 | #define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \ | ||
34 | strlen(SMSG_PREFIX) + 1) | ||
35 | #define ENV_TEXT_STR "SMSG_TEXT=" | ||
36 | #define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1) | ||
37 | |||
38 | /* z/VM user ID which is permitted to send SMSGs | ||
39 | * If the value is undefined or empty (""), special messages are | ||
40 | * accepted from any z/VM user ID. */ | ||
41 | static char *sender; | ||
42 | module_param(sender, charp, 0400); | ||
43 | MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted"); | ||
44 | |||
45 | /* SMSG device representation */ | ||
46 | static struct device *smsg_app_dev; | ||
47 | |||
48 | /* list element for queuing received messages for delivery */ | ||
49 | struct smsg_app_event { | ||
50 | struct list_head list; | ||
51 | char *buf; | ||
52 | char *envp[4]; | ||
53 | }; | ||
54 | |||
55 | /* queue for outgoing uevents */ | ||
56 | static LIST_HEAD(smsg_event_queue); | ||
57 | static DEFINE_SPINLOCK(smsg_event_queue_lock); | ||
58 | |||
59 | static void smsg_app_event_free(struct smsg_app_event *ev) | ||
60 | { | ||
61 | kfree(ev->buf); | ||
62 | kfree(ev); | ||
63 | } | ||
64 | |||
65 | static struct smsg_app_event *smsg_app_event_alloc(const char *from, | ||
66 | const char *msg) | ||
67 | { | ||
68 | struct smsg_app_event *ev; | ||
69 | |||
70 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | ||
71 | if (!ev) | ||
72 | return NULL; | ||
73 | |||
74 | ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN + | ||
75 | ENV_TEXT_LEN(msg), GFP_ATOMIC); | ||
76 | if (!ev->buf) { | ||
77 | kfree(ev); | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | /* setting up environment pointers into buf */ | ||
82 | ev->envp[0] = ev->buf; | ||
83 | ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN; | ||
84 | ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN; | ||
85 | ev->envp[3] = NULL; | ||
86 | |||
87 | /* setting up environment: sender, prefix name, and message text */ | ||
88 | snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from); | ||
89 | snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX); | ||
90 | snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg); | ||
91 | |||
92 | return ev; | ||
93 | } | ||
94 | |||
95 | static void smsg_event_work_fn(struct work_struct *work) | ||
96 | { | ||
97 | LIST_HEAD(event_queue); | ||
98 | struct smsg_app_event *p, *n; | ||
99 | struct device *dev; | ||
100 | |||
101 | dev = get_device(smsg_app_dev); | ||
102 | if (!dev) | ||
103 | return; | ||
104 | |||
105 | spin_lock_bh(&smsg_event_queue_lock); | ||
106 | list_splice_init(&smsg_event_queue, &event_queue); | ||
107 | spin_unlock_bh(&smsg_event_queue_lock); | ||
108 | |||
109 | list_for_each_entry_safe(p, n, &event_queue, list) { | ||
110 | list_del(&p->list); | ||
111 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp); | ||
112 | smsg_app_event_free(p); | ||
113 | } | ||
114 | |||
115 | put_device(dev); | ||
116 | } | ||
117 | static DECLARE_WORK(smsg_event_work, smsg_event_work_fn); | ||
118 | |||
119 | static void smsg_app_callback(const char *from, char *msg) | ||
120 | { | ||
121 | struct smsg_app_event *se; | ||
122 | |||
123 | /* check if the originating z/VM user ID matches | ||
124 | * the configured sender. */ | ||
125 | if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0) | ||
126 | return; | ||
127 | |||
128 | /* get start of message text (skip prefix and leading blanks) */ | ||
129 | msg += strlen(SMSG_PREFIX); | ||
130 | while (*msg && isspace(*msg)) | ||
131 | msg++; | ||
132 | if (*msg == '\0') | ||
133 | return; | ||
134 | |||
135 | /* allocate event list element and its environment */ | ||
136 | se = smsg_app_event_alloc(from, msg); | ||
137 | if (!se) | ||
138 | return; | ||
139 | |||
140 | /* queue event and schedule work function */ | ||
141 | spin_lock(&smsg_event_queue_lock); | ||
142 | list_add_tail(&se->list, &smsg_event_queue); | ||
143 | spin_unlock(&smsg_event_queue_lock); | ||
144 | |||
145 | schedule_work(&smsg_event_work); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | static int __init smsgiucv_app_init(void) | ||
150 | { | ||
151 | struct device_driver *smsgiucv_drv; | ||
152 | int rc; | ||
153 | |||
154 | if (!MACHINE_IS_VM) | ||
155 | return -ENODEV; | ||
156 | |||
157 | smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL); | ||
158 | if (!smsg_app_dev) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus); | ||
162 | if (!smsgiucv_drv) { | ||
163 | kfree(smsg_app_dev); | ||
164 | return -ENODEV; | ||
165 | } | ||
166 | |||
167 | rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); | ||
168 | if (rc) { | ||
169 | kfree(smsg_app_dev); | ||
170 | goto fail_put_driver; | ||
171 | } | ||
172 | smsg_app_dev->bus = &iucv_bus; | ||
173 | smsg_app_dev->parent = iucv_root; | ||
174 | smsg_app_dev->release = (void (*)(struct device *)) kfree; | ||
175 | smsg_app_dev->driver = smsgiucv_drv; | ||
176 | rc = device_register(smsg_app_dev); | ||
177 | if (rc) { | ||
178 | put_device(smsg_app_dev); | ||
179 | goto fail_put_driver; | ||
180 | } | ||
181 | |||
182 | /* register with the smsgiucv device driver */ | ||
183 | rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); | ||
184 | if (rc) { | ||
185 | device_unregister(smsg_app_dev); | ||
186 | goto fail_put_driver; | ||
187 | } | ||
188 | |||
189 | rc = 0; | ||
190 | fail_put_driver: | ||
191 | put_driver(smsgiucv_drv); | ||
192 | return rc; | ||
193 | } | ||
194 | module_init(smsgiucv_app_init); | ||
195 | |||
196 | static void __exit smsgiucv_app_exit(void) | ||
197 | { | ||
198 | /* unregister callback */ | ||
199 | smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback); | ||
200 | |||
201 | /* cancel pending work and flush any queued event work */ | ||
202 | cancel_work_sync(&smsg_event_work); | ||
203 | smsg_event_work_fn(&smsg_event_work); | ||
204 | |||
205 | device_unregister(smsg_app_dev); | ||
206 | } | ||
207 | module_exit(smsgiucv_app_exit); | ||
208 | |||
209 | MODULE_LICENSE("GPL v2"); | ||
210 | MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents"); | ||
211 | MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>"); | ||
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 71b97ff77cf0..6479273a3094 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -319,8 +319,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | |||
319 | id->input_handler = zfcp_qdio_int_resp; | 319 | id->input_handler = zfcp_qdio_int_resp; |
320 | id->output_handler = zfcp_qdio_int_req; | 320 | id->output_handler = zfcp_qdio_int_req; |
321 | id->int_parm = (unsigned long) qdio; | 321 | id->int_parm = (unsigned long) qdio; |
322 | id->flags = QDIO_INBOUND_0COPY_SBALS | | ||
323 | QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS; | ||
324 | id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); | 322 | id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); |
325 | id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); | 323 | id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); |
326 | 324 | ||
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 208d6df9ed59..ff5716d5f044 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c | |||
@@ -492,7 +492,7 @@ static void init_alloc_map(struct orc_host * host) | |||
492 | * init_orchid - initialise the host adapter | 492 | * init_orchid - initialise the host adapter |
493 | * @host:host adapter to initialise | 493 | * @host:host adapter to initialise |
494 | * | 494 | * |
495 | * Initialise the controller and if neccessary load the firmware. | 495 | * Initialise the controller and if necessary load the firmware. |
496 | * | 496 | * |
497 | * Returns -1 if the initialisation fails. | 497 | * Returns -1 if the initialisation fails. |
498 | */ | 498 | */ |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 89a59484be02..a7714160fbc3 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -531,7 +531,7 @@ static void initio_read_eeprom(unsigned long base) | |||
531 | * initio_stop_bm - stop bus master | 531 | * initio_stop_bm - stop bus master |
532 | * @host: InitIO we are stopping | 532 | * @host: InitIO we are stopping |
533 | * | 533 | * |
534 | * Stop any pending DMA operation, aborting the DMA if neccessary | 534 | * Stop any pending DMA operation, aborting the DMA if necessary |
535 | */ | 535 | */ |
536 | 536 | ||
537 | static void initio_stop_bm(struct initio_host * host) | 537 | static void initio_stop_bm(struct initio_host * host) |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 6fde2fabfd9b..774e7ac837a5 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -48,7 +48,7 @@ struct kmem_cache *scsi_pkt_cachep; | |||
48 | #define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */ | 48 | #define FC_SRB_CMD_SENT (1 << 0) /* cmd has been sent */ |
49 | #define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */ | 49 | #define FC_SRB_RCV_STATUS (1 << 1) /* response has arrived */ |
50 | #define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */ | 50 | #define FC_SRB_ABORT_PENDING (1 << 2) /* cmd abort sent to device */ |
51 | #define FC_SRB_ABORTED (1 << 3) /* abort acknowleged */ | 51 | #define FC_SRB_ABORTED (1 << 3) /* abort acknowledged */ |
52 | #define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */ | 52 | #define FC_SRB_DISCONTIG (1 << 4) /* non-sequential data recvd */ |
53 | #define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */ | 53 | #define FC_SRB_COMPL (1 << 5) /* fc_io_compl has been run */ |
54 | #define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */ | 54 | #define FC_SRB_FCP_PROCESSING_TMO (1 << 6) /* timer function processing */ |
@@ -519,7 +519,7 @@ crc_err: | |||
519 | * | 519 | * |
520 | * Called after receiving a Transfer Ready data descriptor. | 520 | * Called after receiving a Transfer Ready data descriptor. |
521 | * If the LLD is capable of sequence offload then send down the | 521 | * If the LLD is capable of sequence offload then send down the |
522 | * seq_blen ammount of data in single frame, otherwise send | 522 | * seq_blen amount of data in single frame, otherwise send |
523 | * multiple frames of the maximum frame payload supported by | 523 | * multiple frames of the maximum frame payload supported by |
524 | * the target port. | 524 | * the target port. |
525 | */ | 525 | */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 08b6634cb994..2a40a6eabf4d 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -981,7 +981,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
981 | * function returns, it does not guarantee all the IOCBs are actually aborted. | 981 | * function returns, it does not guarantee all the IOCBs are actually aborted. |
982 | * | 982 | * |
983 | * Return code | 983 | * Return code |
984 | * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0) | 984 | * 0 - Successfully issued abort iocb on all outstanding flogis (Always 0) |
985 | **/ | 985 | **/ |
986 | int | 986 | int |
987 | lpfc_els_abort_flogi(struct lpfc_hba *phba) | 987 | lpfc_els_abort_flogi(struct lpfc_hba *phba) |
@@ -3129,7 +3129,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3129 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | 3129 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
3130 | (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | 3130 | (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { |
3131 | /* A LS_RJT associated with Default RPI cleanup has its own | 3131 | /* A LS_RJT associated with Default RPI cleanup has its own |
3132 | * seperate code path. | 3132 | * separate code path. |
3133 | */ | 3133 | */ |
3134 | if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | 3134 | if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) |
3135 | ls_rjt = 1; | 3135 | ls_rjt = 1; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7f21b47db791..483fb74bc592 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1575,7 +1575,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, | |||
1575 | case LPFC_PG_TYPE_NO_DIF: | 1575 | case LPFC_PG_TYPE_NO_DIF: |
1576 | num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, | 1576 | num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, |
1577 | datasegcnt); | 1577 | datasegcnt); |
1578 | /* we shoud have 2 or more entries in buffer list */ | 1578 | /* we should have 2 or more entries in buffer list */ |
1579 | if (num_bde < 2) | 1579 | if (num_bde < 2) |
1580 | goto err; | 1580 | goto err; |
1581 | break; | 1581 | break; |
@@ -1612,7 +1612,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, | |||
1612 | 1612 | ||
1613 | num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, | 1613 | num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, |
1614 | datasegcnt, protsegcnt); | 1614 | datasegcnt, protsegcnt); |
1615 | /* we shoud have 3 or more entries in buffer list */ | 1615 | /* we should have 3 or more entries in buffer list */ |
1616 | if (num_bde < 3) | 1616 | if (num_bde < 3) |
1617 | goto err; | 1617 | goto err; |
1618 | break; | 1618 | break; |
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 7db28cd49446..8c61a4fe1db9 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -187,7 +187,7 @@ | |||
187 | #define S_IO BIT(1) /* Input/Output line from SCSI bus */ | 187 | #define S_IO BIT(1) /* Input/Output line from SCSI bus */ |
188 | #define S_CD BIT(2) /* Command/Data line from SCSI bus */ | 188 | #define S_CD BIT(2) /* Command/Data line from SCSI bus */ |
189 | #define S_BUSY BIT(3) /* Busy line from SCSI bus */ | 189 | #define S_BUSY BIT(3) /* Busy line from SCSI bus */ |
190 | #define S_ACK BIT(4) /* Acknowlege line from SCSI bus */ | 190 | #define S_ACK BIT(4) /* Acknowledge line from SCSI bus */ |
191 | #define S_REQUEST BIT(5) /* Request line from SCSI bus */ | 191 | #define S_REQUEST BIT(5) /* Request line from SCSI bus */ |
192 | #define S_SELECT BIT(6) /* */ | 192 | #define S_SELECT BIT(6) /* */ |
193 | #define S_ATN BIT(7) /* */ | 193 | #define S_ATN BIT(7) /* */ |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 9b44c6f1b10e..7985ae45d688 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -2924,7 +2924,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2924 | break; | 2924 | break; |
2925 | default: | 2925 | default: |
2926 | PM8001_MSG_DBG(pm8001_ha, | 2926 | PM8001_MSG_DBG(pm8001_ha, |
2927 | pm8001_printk("unkown device type(%x)\n", deviceType)); | 2927 | pm8001_printk("unknown device type(%x)\n", deviceType)); |
2928 | break; | 2928 | break; |
2929 | } | 2929 | } |
2930 | phy->phy_type |= PORT_TYPE_SAS; | 2930 | phy->phy_type |= PORT_TYPE_SAS; |
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 7f9c83a76390..3b2c98fba834 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c | |||
@@ -600,7 +600,7 @@ static void pm8001_free_dev(struct pm8001_device *pm8001_dev) | |||
600 | * by the command "OPC_INB_REG_DEV", after that the HBA will assign a | 600 | * by the command "OPC_INB_REG_DEV", after that the HBA will assign a |
601 | * device ID(according to device's sas address) and returned it to LLDD. From | 601 | * device ID(according to device's sas address) and returned it to LLDD. From |
602 | * now on, we communicate with HBA FW with the device ID which HBA assigned | 602 | * now on, we communicate with HBA FW with the device ID which HBA assigned |
603 | * rather than sas address. it is the neccessary step for our HBA but it is | 603 | * rather than sas address. it is the necessary step for our HBA but it is |
604 | * the optional for other HBA driver. | 604 | * the optional for other HBA driver. |
605 | */ | 605 | */ |
606 | static int pm8001_dev_found_notify(struct domain_device *dev) | 606 | static int pm8001_dev_found_notify(struct domain_device *dev) |
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 92f89d50850c..b8ad07c3449e 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h | |||
@@ -938,7 +938,7 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { | |||
938 | 938 | ||
939 | /* | 939 | /* |
940 | * pmcraid_ioctl_header - definition of header structure that preceeds all the | 940 | * pmcraid_ioctl_header - definition of header structure that preceeds all the |
941 | * buffers given as ioctl arguements. | 941 | * buffers given as ioctl arguments. |
942 | * | 942 | * |
943 | * .signature : always ASCII string, "PMCRAID" | 943 | * .signature : always ASCII string, "PMCRAID" |
944 | * .reserved : not used | 944 | * .reserved : not used |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index fa34b92850a6..1b8217076b0e 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
@@ -738,7 +738,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti) | |||
738 | * sanely maintain. | 738 | * sanely maintain. |
739 | */ | 739 | */ |
740 | if (request_irq(qpti->irq, qpti_intr, | 740 | if (request_irq(qpti->irq, qpti_intr, |
741 | IRQF_SHARED, "Qlogic/PTI", qpti)) | 741 | IRQF_SHARED, "QlogicPTI", qpti)) |
742 | goto fail; | 742 | goto fail; |
743 | 743 | ||
744 | printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq); | 744 | printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 466fae8ef770..a82ab3e2b4f7 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2111,7 +2111,7 @@ static int sd_revalidate_disk(struct gendisk *disk) | |||
2111 | * which is followed by sdaaa. | 2111 | * which is followed by sdaaa. |
2112 | * | 2112 | * |
2113 | * This is basically 26 base counting with one extra 'nil' entry | 2113 | * This is basically 26 base counting with one extra 'nil' entry |
2114 | * at the beggining from the second digit on and can be | 2114 | * at the beginning from the second digit on and can be |
2115 | * determined using similar method as 26 base conversion with the | 2115 | * determined using similar method as 26 base conversion with the |
2116 | * index shifted -1 after each digit is computed. | 2116 | * index shifted -1 after each digit is computed. |
2117 | * | 2117 | * |
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 1d7a8780e00c..0d9d6f7567f5 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -595,8 +595,6 @@ static int ses_intf_add(struct device *cdev, | |||
595 | ses_dev->page10_len = len; | 595 | ses_dev->page10_len = len; |
596 | buf = NULL; | 596 | buf = NULL; |
597 | } | 597 | } |
598 | kfree(hdr_buf); | ||
599 | |||
600 | scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); | 598 | scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); |
601 | if (!scomp) | 599 | if (!scomp) |
602 | goto err_free; | 600 | goto err_free; |
@@ -608,6 +606,8 @@ static int ses_intf_add(struct device *cdev, | |||
608 | goto err_free; | 606 | goto err_free; |
609 | } | 607 | } |
610 | 608 | ||
609 | kfree(hdr_buf); | ||
610 | |||
611 | edev->scratch = ses_dev; | 611 | edev->scratch = ses_dev; |
612 | for (i = 0; i < components; i++) | 612 | for (i = 0; i < components; i++) |
613 | edev->component[i].scratch = scomp + i; | 613 | edev->component[i].scratch = scomp + i; |
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 0807b260268b..fef0e3c75b16 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c | |||
@@ -226,7 +226,7 @@ static struct scsi_host_template sgiwd93_template = { | |||
226 | .use_clustering = DISABLE_CLUSTERING, | 226 | .use_clustering = DISABLE_CLUSTERING, |
227 | }; | 227 | }; |
228 | 228 | ||
229 | static int __init sgiwd93_probe(struct platform_device *pdev) | 229 | static int __devinit sgiwd93_probe(struct platform_device *pdev) |
230 | { | 230 | { |
231 | struct sgiwd93_platform_data *pd = pdev->dev.platform_data; | 231 | struct sgiwd93_platform_data *pd = pdev->dev.platform_data; |
232 | unsigned char *wdregs = pd->wdregs; | 232 | unsigned char *wdregs = pd->wdregs; |
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index 37b3359e863e..56cf0bb4ed1f 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c | |||
@@ -64,7 +64,7 @@ static struct scsi_host_template snirm710_template = { | |||
64 | .module = THIS_MODULE, | 64 | .module = THIS_MODULE, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static int __init snirm710_probe(struct platform_device *dev) | 67 | static int __devinit snirm710_probe(struct platform_device *dev) |
68 | { | 68 | { |
69 | unsigned long base; | 69 | unsigned long base; |
70 | struct NCR_700_Host_Parameters *hostdata; | 70 | struct NCR_700_Host_Parameters *hostdata; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 7c4ebe6ee18b..c3db16b7afa1 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -2408,6 +2408,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2408 | } | 2408 | } |
2409 | 2409 | ||
2410 | static void | 2410 | static void |
2411 | serial8250_set_ldisc(struct uart_port *port) | ||
2412 | { | ||
2413 | int line = port->line; | ||
2414 | |||
2415 | if (line >= port->state->port.tty->driver->num) | ||
2416 | return; | ||
2417 | |||
2418 | if (port->state->port.tty->ldisc->ops->num == N_PPS) { | ||
2419 | port->flags |= UPF_HARDPPS_CD; | ||
2420 | serial8250_enable_ms(port); | ||
2421 | } else | ||
2422 | port->flags &= ~UPF_HARDPPS_CD; | ||
2423 | } | ||
2424 | |||
2425 | static void | ||
2411 | serial8250_pm(struct uart_port *port, unsigned int state, | 2426 | serial8250_pm(struct uart_port *port, unsigned int state, |
2412 | unsigned int oldstate) | 2427 | unsigned int oldstate) |
2413 | { | 2428 | { |
@@ -2628,6 +2643,7 @@ static struct uart_ops serial8250_pops = { | |||
2628 | .startup = serial8250_startup, | 2643 | .startup = serial8250_startup, |
2629 | .shutdown = serial8250_shutdown, | 2644 | .shutdown = serial8250_shutdown, |
2630 | .set_termios = serial8250_set_termios, | 2645 | .set_termios = serial8250_set_termios, |
2646 | .set_ldisc = serial8250_set_ldisc, | ||
2631 | .pm = serial8250_pm, | 2647 | .pm = serial8250_pm, |
2632 | .type = serial8250_type, | 2648 | .type = serial8250_type, |
2633 | .release_port = serial8250_release_port, | 2649 | .release_port = serial8250_release_port, |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d6ff73395623..f55c49475a8c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -447,7 +447,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
447 | 447 | ||
448 | config SERIAL_SAMSUNG | 448 | config SERIAL_SAMSUNG |
449 | tristate "Samsung SoC serial support" | 449 | tristate "Samsung SoC serial support" |
450 | depends on ARM && PLAT_S3C | 450 | depends on ARM && PLAT_SAMSUNG |
451 | select SERIAL_CORE | 451 | select SERIAL_CORE |
452 | help | 452 | help |
453 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 453 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
@@ -455,11 +455,18 @@ config SERIAL_SAMSUNG | |||
455 | provide all of these ports, depending on how the serial port | 455 | provide all of these ports, depending on how the serial port |
456 | pins are configured. | 456 | pins are configured. |
457 | 457 | ||
458 | config SERIAL_SAMSUNG_UARTS_4 | ||
459 | bool | ||
460 | depends on ARM && PLAT_SAMSUNG | ||
461 | default y if CPU_S3C2443 | ||
462 | help | ||
463 | Internal node for the common case of 4 Samsung compatible UARTs | ||
464 | |||
458 | config SERIAL_SAMSUNG_UARTS | 465 | config SERIAL_SAMSUNG_UARTS |
459 | int | 466 | int |
460 | depends on ARM && PLAT_S3C | 467 | depends on ARM && PLAT_SAMSUNG |
461 | default 2 if ARCH_S3C2400 | 468 | default 2 if ARCH_S3C2400 |
462 | default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443 | 469 | default 4 if SERIAL_SAMSUNG_UARTS_4 |
463 | default 3 | 470 | default 3 |
464 | help | 471 | help |
465 | Select the number of available UART ports for the Samsung S3C | 472 | Select the number of available UART ports for the Samsung S3C |
@@ -526,20 +533,30 @@ config SERIAL_S3C24A0 | |||
526 | Serial port support for the Samsung S3C24A0 SoC | 533 | Serial port support for the Samsung S3C24A0 SoC |
527 | 534 | ||
528 | config SERIAL_S3C6400 | 535 | config SERIAL_S3C6400 |
529 | tristate "Samsung S3C6400/S3C6410 Serial port support" | 536 | tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support" |
530 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410) | 537 | depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440) |
538 | select SERIAL_SAMSUNG_UARTS_4 | ||
531 | default y | 539 | default y |
532 | help | 540 | help |
533 | Serial port support for the Samsung S3C6400 and S3C6410 | 541 | Serial port support for the Samsung S3C6400, S3C6410 and S5P6440 |
534 | SoCs | 542 | SoCs |
535 | 543 | ||
536 | config SERIAL_S5PC100 | 544 | config SERIAL_S5PC100 |
537 | tristate "Samsung S5PC100 Serial port support" | 545 | tristate "Samsung S5PC100 Serial port support" |
538 | depends on SERIAL_SAMSUNG && CPU_S5PC100 | 546 | depends on SERIAL_SAMSUNG && CPU_S5PC100 |
547 | select SERIAL_SAMSUNG_UARTS_4 | ||
539 | default y | 548 | default y |
540 | help | 549 | help |
541 | Serial port support for the Samsung S5PC100 SoCs | 550 | Serial port support for the Samsung S5PC100 SoCs |
542 | 551 | ||
552 | config SERIAL_S5PV210 | ||
553 | tristate "Samsung S5PV210 Serial port support" | ||
554 | depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442) | ||
555 | select SERIAL_SAMSUNG_UARTS_4 if CPU_S5PV210 | ||
556 | default y | ||
557 | help | ||
558 | Serial port support for Samsung's S5P Family of SoC's | ||
559 | |||
543 | config SERIAL_MAX3100 | 560 | config SERIAL_MAX3100 |
544 | tristate "MAX3100 support" | 561 | tristate "MAX3100 support" |
545 | depends on SPI | 562 | depends on SPI |
@@ -996,7 +1013,7 @@ config SERIAL_IP22_ZILOG_CONSOLE | |||
996 | 1013 | ||
997 | config SERIAL_SH_SCI | 1014 | config SERIAL_SH_SCI |
998 | tristate "SuperH SCI(F) serial port support" | 1015 | tristate "SuperH SCI(F) serial port support" |
999 | depends on HAVE_CLK && (SUPERH || H8300) | 1016 | depends on HAVE_CLK && (SUPERH || H8300 || ARCH_SHMOBILE) |
1000 | select SERIAL_CORE | 1017 | select SERIAL_CORE |
1001 | 1018 | ||
1002 | config SERIAL_SH_SCI_NR_UARTS | 1019 | config SERIAL_SH_SCI_NR_UARTS |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 5548fe7df61d..6aa4723b74ee 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o | |||
45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o | 45 | obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o |
46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o | 46 | obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o |
47 | obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o | 47 | obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o |
48 | obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o | ||
48 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 49 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
49 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 50 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
50 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 51 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 429a8ae86933..e4b3c2c88bb6 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -471,6 +471,20 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, | |||
471 | spin_unlock_irqrestore(&uap->port.lock, flags); | 471 | spin_unlock_irqrestore(&uap->port.lock, flags); |
472 | } | 472 | } |
473 | 473 | ||
474 | static void pl010_set_ldisc(struct uart_port *port) | ||
475 | { | ||
476 | int line = port->line; | ||
477 | |||
478 | if (line >= port->state->port.tty->driver->num) | ||
479 | return; | ||
480 | |||
481 | if (port->state->port.tty->ldisc->ops->num == N_PPS) { | ||
482 | port->flags |= UPF_HARDPPS_CD; | ||
483 | pl010_enable_ms(port); | ||
484 | } else | ||
485 | port->flags &= ~UPF_HARDPPS_CD; | ||
486 | } | ||
487 | |||
474 | static const char *pl010_type(struct uart_port *port) | 488 | static const char *pl010_type(struct uart_port *port) |
475 | { | 489 | { |
476 | return port->type == PORT_AMBA ? "AMBA" : NULL; | 490 | return port->type == PORT_AMBA ? "AMBA" : NULL; |
@@ -531,6 +545,7 @@ static struct uart_ops amba_pl010_pops = { | |||
531 | .startup = pl010_startup, | 545 | .startup = pl010_startup, |
532 | .shutdown = pl010_shutdown, | 546 | .shutdown = pl010_shutdown, |
533 | .set_termios = pl010_set_termios, | 547 | .set_termios = pl010_set_termios, |
548 | .set_ldisc = pl010_set_ldisc, | ||
534 | .type = pl010_type, | 549 | .type = pl010_type, |
535 | .release_port = pl010_release_port, | 550 | .release_port = pl010_release_port, |
536 | .request_port = pl010_request_port, | 551 | .request_port = pl010_request_port, |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index d00fcf8e6c70..e579d7a1807a 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -440,7 +440,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
440 | 440 | ||
441 | temp = readl(sport->port.membase + USR2); | 441 | temp = readl(sport->port.membase + USR2); |
442 | if (temp & USR2_BRCD) { | 442 | if (temp & USR2_BRCD) { |
443 | writel(temp | USR2_BRCD, sport->port.membase + USR2); | 443 | writel(USR2_BRCD, sport->port.membase + USR2); |
444 | if (uart_handle_break(&sport->port)) | 444 | if (uart_handle_break(&sport->port)) |
445 | continue; | 445 | continue; |
446 | } | 446 | } |
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c index ce75e28e36ef..1700b1a2fb7e 100644 --- a/drivers/serial/s3c2412.c +++ b/drivers/serial/s3c2412.c | |||
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = { | |||
102 | .name = "Samsung S3C2412 UART", | 102 | .name = "Samsung S3C2412 UART", |
103 | .type = PORT_S3C2412, | 103 | .type = PORT_S3C2412, |
104 | .fifosize = 64, | 104 | .fifosize = 64, |
105 | .has_divslot = 1, | ||
105 | .rx_fifomask = S3C2440_UFSTAT_RXMASK, | 106 | .rx_fifomask = S3C2440_UFSTAT_RXMASK, |
106 | .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, | 107 | .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, |
107 | .rx_fifofull = S3C2440_UFSTAT_RXFULL, | 108 | .rx_fifofull = S3C2440_UFSTAT_RXFULL, |
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c new file mode 100644 index 000000000000..8dc03837617b --- /dev/null +++ b/drivers/serial/s5pv210.c | |||
@@ -0,0 +1,154 @@ | |||
1 | /* linux/drivers/serial/s5pv210.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * Based on drivers/serial/s3c6400.c | ||
7 | * | ||
8 | * Driver for Samsung S5PV210 SoC UARTs. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/ioport.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/serial_core.h> | ||
21 | #include <linux/serial.h> | ||
22 | |||
23 | #include <asm/irq.h> | ||
24 | #include <mach/hardware.h> | ||
25 | #include <plat/regs-serial.h> | ||
26 | #include "samsung.h" | ||
27 | |||
28 | static int s5pv210_serial_setsource(struct uart_port *port, | ||
29 | struct s3c24xx_uart_clksrc *clk) | ||
30 | { | ||
31 | unsigned long ucon = rd_regl(port, S3C2410_UCON); | ||
32 | |||
33 | if (strcmp(clk->name, "pclk") == 0) | ||
34 | ucon &= ~S5PV210_UCON_CLKMASK; | ||
35 | else if (strcmp(clk->name, "uclk1") == 0) | ||
36 | ucon |= S5PV210_UCON_CLKMASK; | ||
37 | else { | ||
38 | printk(KERN_ERR "unknown clock source %s\n", clk->name); | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | |||
42 | wr_regl(port, S3C2410_UCON, ucon); | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | |||
47 | static int s5pv210_serial_getsource(struct uart_port *port, | ||
48 | struct s3c24xx_uart_clksrc *clk) | ||
49 | { | ||
50 | u32 ucon = rd_regl(port, S3C2410_UCON); | ||
51 | |||
52 | clk->divisor = 1; | ||
53 | |||
54 | switch (ucon & S5PV210_UCON_CLKMASK) { | ||
55 | case S5PV210_UCON_PCLK: | ||
56 | clk->name = "pclk"; | ||
57 | break; | ||
58 | case S5PV210_UCON_UCLK: | ||
59 | clk->name = "uclk1"; | ||
60 | break; | ||
61 | } | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int s5pv210_serial_resetport(struct uart_port *port, | ||
67 | struct s3c2410_uartcfg *cfg) | ||
68 | { | ||
69 | unsigned long ucon = rd_regl(port, S3C2410_UCON); | ||
70 | |||
71 | ucon &= S5PV210_UCON_CLKMASK; | ||
72 | wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); | ||
73 | wr_regl(port, S3C2410_ULCON, cfg->ulcon); | ||
74 | |||
75 | /* reset both fifos */ | ||
76 | wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); | ||
77 | wr_regl(port, S3C2410_UFCON, cfg->ufcon); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | #define S5PV210_UART_DEFAULT_INFO(fifo_size) \ | ||
83 | .name = "Samsung S5PV210 UART0", \ | ||
84 | .type = PORT_S3C6400, \ | ||
85 | .fifosize = fifo_size, \ | ||
86 | .has_divslot = 1, \ | ||
87 | .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ | ||
88 | .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ | ||
89 | .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ | ||
90 | .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ | ||
91 | .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ | ||
92 | .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ | ||
93 | .get_clksrc = s5pv210_serial_getsource, \ | ||
94 | .set_clksrc = s5pv210_serial_setsource, \ | ||
95 | .reset_port = s5pv210_serial_resetport | ||
96 | |||
97 | static struct s3c24xx_uart_info s5p_port_fifo256 = { | ||
98 | S5PV210_UART_DEFAULT_INFO(256), | ||
99 | }; | ||
100 | |||
101 | static struct s3c24xx_uart_info s5p_port_fifo64 = { | ||
102 | S5PV210_UART_DEFAULT_INFO(64), | ||
103 | }; | ||
104 | |||
105 | static struct s3c24xx_uart_info s5p_port_fifo16 = { | ||
106 | S5PV210_UART_DEFAULT_INFO(16), | ||
107 | }; | ||
108 | |||
109 | static struct s3c24xx_uart_info *s5p_uart_inf[] = { | ||
110 | [0] = &s5p_port_fifo256, | ||
111 | [1] = &s5p_port_fifo64, | ||
112 | [2] = &s5p_port_fifo16, | ||
113 | [3] = &s5p_port_fifo16, | ||
114 | }; | ||
115 | |||
116 | /* device management */ | ||
117 | static int s5p_serial_probe(struct platform_device *pdev) | ||
118 | { | ||
119 | return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); | ||
120 | } | ||
121 | |||
122 | static struct platform_driver s5p_serial_drv = { | ||
123 | .probe = s5p_serial_probe, | ||
124 | .remove = __devexit_p(s3c24xx_serial_remove), | ||
125 | .driver = { | ||
126 | .name = "s5pv210-uart", | ||
127 | .owner = THIS_MODULE, | ||
128 | }, | ||
129 | }; | ||
130 | |||
131 | static int __init s5pv210_serial_console_init(void) | ||
132 | { | ||
133 | return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf); | ||
134 | } | ||
135 | |||
136 | console_initcall(s5pv210_serial_console_init); | ||
137 | |||
138 | static int __init s5p_serial_init(void) | ||
139 | { | ||
140 | return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf); | ||
141 | } | ||
142 | |||
143 | static void __exit s5p_serial_exit(void) | ||
144 | { | ||
145 | platform_driver_unregister(&s5p_serial_drv); | ||
146 | } | ||
147 | |||
148 | module_init(s5p_serial_init); | ||
149 | module_exit(s5p_serial_exit); | ||
150 | |||
151 | MODULE_LICENSE("GPL"); | ||
152 | MODULE_ALIAS("platform:s5pv210-uart"); | ||
153 | MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support"); | ||
154 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); | ||
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index 52e3df113ec0..a9d6c5626a0a 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c | |||
@@ -1271,7 +1271,7 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) | |||
1271 | unsigned long ufstat, utrstat; | 1271 | unsigned long ufstat, utrstat; |
1272 | 1272 | ||
1273 | if (ufcon & S3C2410_UFCON_FIFOMODE) { | 1273 | if (ufcon & S3C2410_UFCON_FIFOMODE) { |
1274 | /* fifo mode - check ammount of data in fifo registers... */ | 1274 | /* fifo mode - check amount of data in fifo registers... */ |
1275 | 1275 | ||
1276 | ufstat = rd_regl(port, S3C2410_UFSTAT); | 1276 | ufstat = rd_regl(port, S3C2410_UFSTAT); |
1277 | return (ufstat & info->tx_fifofull) ? 0 : 1; | 1277 | return (ufstat & info->tx_fifofull) ? 0 : 1; |
@@ -1374,7 +1374,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, | |||
1374 | * data. | 1374 | * data. |
1375 | */ | 1375 | */ |
1376 | 1376 | ||
1377 | static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) | 1377 | static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info) |
1378 | { | 1378 | { |
1379 | struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; | 1379 | struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; |
1380 | struct platform_device **platdev_ptr; | 1380 | struct platform_device **platdev_ptr; |
@@ -1385,7 +1385,7 @@ static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info *info) | |||
1385 | platdev_ptr = s3c24xx_uart_devs; | 1385 | platdev_ptr = s3c24xx_uart_devs; |
1386 | 1386 | ||
1387 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { | 1387 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { |
1388 | s3c24xx_serial_init_port(ptr, info, *platdev_ptr); | 1388 | s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | return 0; | 1391 | return 0; |
@@ -1451,7 +1451,7 @@ static struct console s3c24xx_serial_console = { | |||
1451 | }; | 1451 | }; |
1452 | 1452 | ||
1453 | int s3c24xx_serial_initconsole(struct platform_driver *drv, | 1453 | int s3c24xx_serial_initconsole(struct platform_driver *drv, |
1454 | struct s3c24xx_uart_info *info) | 1454 | struct s3c24xx_uart_info **info) |
1455 | 1455 | ||
1456 | { | 1456 | { |
1457 | struct platform_device *dev = s3c24xx_uart_devs[0]; | 1457 | struct platform_device *dev = s3c24xx_uart_devs[0]; |
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h index 1fb22343df42..0ac06a07d25f 100644 --- a/drivers/serial/samsung.h +++ b/drivers/serial/samsung.h | |||
@@ -75,19 +75,24 @@ extern int s3c24xx_serial_probe(struct platform_device *dev, | |||
75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); | 75 | extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); |
76 | 76 | ||
77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, | 77 | extern int s3c24xx_serial_initconsole(struct platform_driver *drv, |
78 | struct s3c24xx_uart_info *uart); | 78 | struct s3c24xx_uart_info **uart); |
79 | 79 | ||
80 | extern int s3c24xx_serial_init(struct platform_driver *drv, | 80 | extern int s3c24xx_serial_init(struct platform_driver *drv, |
81 | struct s3c24xx_uart_info *info); | 81 | struct s3c24xx_uart_info *info); |
82 | 82 | ||
83 | #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE | 83 | #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE |
84 | 84 | ||
85 | #define s3c24xx_console_init(__drv, __inf) \ | 85 | #define s3c24xx_console_init(__drv, __inf) \ |
86 | static int __init s3c_serial_console_init(void) \ | 86 | static int __init s3c_serial_console_init(void) \ |
87 | { \ | 87 | { \ |
88 | return s3c24xx_serial_initconsole(__drv, __inf); \ | 88 | struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \ |
89 | } \ | 89 | int i; \ |
90 | \ | 90 | \ |
91 | for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \ | ||
92 | uinfo[i] = __inf; \ | ||
93 | return s3c24xx_serial_initconsole(__drv, uinfo); \ | ||
94 | } \ | ||
95 | \ | ||
91 | console_initcall(s3c_serial_console_init) | 96 | console_initcall(s3c_serial_console_init) |
92 | 97 | ||
93 | #else | 98 | #else |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index f7d2589926d2..fad67d33b0bd 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -30,7 +30,8 @@ | |||
30 | */ | 30 | */ |
31 | # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 | 31 | # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 |
32 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 32 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
33 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 33 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
34 | defined(CONFIG_ARCH_SHMOBILE) | ||
34 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ | 35 | # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ |
35 | # define PORT_PTCR 0xA405011EUL | 36 | # define PORT_PTCR 0xA405011EUL |
36 | # define PORT_PVCR 0xA4050122UL | 37 | # define PORT_PVCR 0xA4050122UL |
@@ -228,7 +229,8 @@ | |||
228 | 229 | ||
229 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 230 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
230 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 231 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
231 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 232 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
233 | defined(CONFIG_ARCH_SHMOBILE) | ||
232 | # define SCIF_ORER 0x0200 | 234 | # define SCIF_ORER 0x0200 |
233 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) | 235 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) |
234 | # define SCIF_RFDC_MASK 0x007f | 236 | # define SCIF_RFDC_MASK 0x007f |
@@ -261,7 +263,8 @@ | |||
261 | 263 | ||
262 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 264 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
263 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 265 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
264 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 266 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
267 | defined(CONFIG_ARCH_SHMOBILE) | ||
265 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) | 268 | # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) |
266 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) | 269 | # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) |
267 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) | 270 | # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) |
@@ -356,7 +359,7 @@ | |||
356 | SCI_OUT(sci_size, sci_offset, value); \ | 359 | SCI_OUT(sci_size, sci_offset, value); \ |
357 | } | 360 | } |
358 | 361 | ||
359 | #ifdef CONFIG_CPU_SH3 | 362 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_ARCH_SHMOBILE) |
360 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | 363 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) |
361 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | 364 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ |
362 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | 365 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ |
@@ -366,7 +369,8 @@ | |||
366 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | 369 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) |
367 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 370 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
368 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 371 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
369 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 372 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
373 | defined(CONFIG_ARCH_SHMOBILE) | ||
370 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 374 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
371 | CPU_SCIF_FNS(name, scif_offset, scif_size) | 375 | CPU_SCIF_FNS(name, scif_offset, scif_size) |
372 | #else | 376 | #else |
@@ -401,7 +405,8 @@ | |||
401 | 405 | ||
402 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 406 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
403 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 407 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
404 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 408 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
409 | defined(CONFIG_ARCH_SHMOBILE) | ||
405 | 410 | ||
406 | SCIF_FNS(SCSMR, 0x00, 16) | 411 | SCIF_FNS(SCSMR, 0x00, 16) |
407 | SCIF_FNS(SCBRR, 0x04, 8) | 412 | SCIF_FNS(SCBRR, 0x04, 8) |
@@ -413,7 +418,7 @@ SCIF_FNS(SCFCR, 0x18, 16) | |||
413 | SCIF_FNS(SCFDR, 0x1c, 16) | 418 | SCIF_FNS(SCFDR, 0x1c, 16) |
414 | SCIF_FNS(SCxTDR, 0x20, 8) | 419 | SCIF_FNS(SCxTDR, 0x20, 8) |
415 | SCIF_FNS(SCxRDR, 0x24, 8) | 420 | SCIF_FNS(SCxRDR, 0x24, 8) |
416 | SCIF_FNS(SCLSR, 0x24, 16) | 421 | SCIF_FNS(SCLSR, 0x00, 0) |
417 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | 422 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ |
418 | defined(CONFIG_CPU_SUBTYPE_SH7724) | 423 | defined(CONFIG_CPU_SUBTYPE_SH7724) |
419 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) | 424 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) |
@@ -583,7 +588,8 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
583 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) | 588 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) |
584 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 589 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
585 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 590 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
586 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 591 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
592 | defined(CONFIG_ARCH_SHMOBILE) | ||
587 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) | 593 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) |
588 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | 594 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ |
589 | defined(CONFIG_CPU_SUBTYPE_SH7724) | 595 | defined(CONFIG_CPU_SUBTYPE_SH7724) |
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 3a5a17db9474..c2750391fd34 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c | |||
@@ -762,6 +762,10 @@ static void __init intc_register_irq(struct intc_desc *desc, | |||
762 | 762 | ||
763 | if (desc->hw.ack_regs) | 763 | if (desc->hw.ack_regs) |
764 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); | 764 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); |
765 | |||
766 | #ifdef CONFIG_ARM | ||
767 | set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */ | ||
768 | #endif | ||
765 | } | 769 | } |
766 | 770 | ||
767 | static unsigned int __init save_reg(struct intc_desc_int *d, | 771 | static unsigned int __init save_reg(struct intc_desc_int *d, |
@@ -1024,8 +1028,12 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) | |||
1024 | out_unlock: | 1028 | out_unlock: |
1025 | spin_unlock_irqrestore(&vector_lock, flags); | 1029 | spin_unlock_irqrestore(&vector_lock, flags); |
1026 | 1030 | ||
1027 | if (irq > 0) | 1031 | if (irq > 0) { |
1028 | dynamic_irq_init(irq); | 1032 | dynamic_irq_init(irq); |
1033 | #ifdef CONFIG_ARM | ||
1034 | set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */ | ||
1035 | #endif | ||
1036 | } | ||
1029 | 1037 | ||
1030 | return irq; | 1038 | return irq; |
1031 | } | 1039 | } |
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index c010733877ae..1fabede9e061 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c | |||
@@ -275,7 +275,7 @@ static inline u32 ack_bit(unsigned int irq) | |||
275 | * Claim the FIQ handler (only one can be active at any one time) and | 275 | * Claim the FIQ handler (only one can be active at any one time) and |
276 | * then setup the correct transfer code for this transfer. | 276 | * then setup the correct transfer code for this transfer. |
277 | * | 277 | * |
278 | * This call updates all the necessary state information if sucessful, | 278 | * This call updates all the necessary state information if successful, |
279 | * so the caller does not need to do anything more than start the transfer | 279 | * so the caller does not need to do anything more than start the transfer |
280 | * as normal, since the IRQ will have been re-routed to the FIQ handler. | 280 | * as normal, since the IRQ will have been re-routed to the FIQ handler. |
281 | */ | 281 | */ |
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index cadb6f7321ad..7ebecc92c61b 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c | |||
@@ -770,13 +770,8 @@ static struct usb_driver oled_driver = { | |||
770 | .id_table = id_table, | 770 | .id_table = id_table, |
771 | }; | 771 | }; |
772 | 772 | ||
773 | static ssize_t version_show(struct class *dev, char *buf) | 773 | static CLASS_ATTR_STRING(version, S_IRUGO, |
774 | { | 774 | ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION); |
775 | return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n", | ||
776 | ASUS_OLED_VERSION); | ||
777 | } | ||
778 | |||
779 | static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | ||
780 | 775 | ||
781 | static int __init asus_oled_init(void) | 776 | static int __init asus_oled_init(void) |
782 | { | 777 | { |
@@ -788,7 +783,7 @@ static int __init asus_oled_init(void) | |||
788 | return PTR_ERR(oled_class); | 783 | return PTR_ERR(oled_class); |
789 | } | 784 | } |
790 | 785 | ||
791 | retval = class_create_file(oled_class, &class_attr_version); | 786 | retval = class_create_file(oled_class, &class_attr_version.attr); |
792 | if (retval) { | 787 | if (retval) { |
793 | err("Error creating class version file"); | 788 | err("Error creating class version file"); |
794 | goto error; | 789 | goto error; |
@@ -810,7 +805,7 @@ error: | |||
810 | 805 | ||
811 | static void __exit asus_oled_exit(void) | 806 | static void __exit asus_oled_exit(void) |
812 | { | 807 | { |
813 | class_remove_file(oled_class, &class_attr_version); | 808 | class_remove_file(oled_class, &class_attr_version.attr); |
814 | class_destroy(oled_class); | 809 | class_destroy(oled_class); |
815 | 810 | ||
816 | usb_deregister(&oled_driver); | 811 | usb_deregister(&oled_driver); |
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index 8aa1955f35ed..1da73ecd9799 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig | |||
@@ -44,17 +44,6 @@ config UIO_PDRV_GENIRQ | |||
44 | 44 | ||
45 | If you don't know what to do here, say N. | 45 | If you don't know what to do here, say N. |
46 | 46 | ||
47 | config UIO_SMX | ||
48 | tristate "SMX cryptengine UIO interface" | ||
49 | help | ||
50 | Userspace IO interface to the Cryptography engine found on the | ||
51 | Nias Digital SMX boards. These will be available from Q4 2008 | ||
52 | from http://www.niasdigital.com. The userspace part of this | ||
53 | driver will be released under the GPL at the same time as the | ||
54 | hardware and will be able to be downloaded from the same site. | ||
55 | |||
56 | If you compile this as a module, it will be called uio_smx. | ||
57 | |||
58 | config UIO_AEC | 47 | config UIO_AEC |
59 | tristate "AEC video timestamp device" | 48 | tristate "AEC video timestamp device" |
60 | depends on PCI | 49 | depends on PCI |
@@ -74,6 +63,7 @@ config UIO_AEC | |||
74 | 63 | ||
75 | config UIO_SERCOS3 | 64 | config UIO_SERCOS3 |
76 | tristate "Automata Sercos III PCI card driver" | 65 | tristate "Automata Sercos III PCI card driver" |
66 | depends on PCI | ||
77 | help | 67 | help |
78 | Userspace I/O interface for the Sercos III PCI card from | 68 | Userspace I/O interface for the Sercos III PCI card from |
79 | Automata GmbH. The userspace part of this driver will be | 69 | Automata GmbH. The userspace part of this driver will be |
@@ -87,11 +77,21 @@ config UIO_SERCOS3 | |||
87 | config UIO_PCI_GENERIC | 77 | config UIO_PCI_GENERIC |
88 | tristate "Generic driver for PCI 2.3 and PCI Express cards" | 78 | tristate "Generic driver for PCI 2.3 and PCI Express cards" |
89 | depends on PCI | 79 | depends on PCI |
90 | default n | ||
91 | help | 80 | help |
92 | Generic driver that you can bind, dynamically, to any | 81 | Generic driver that you can bind, dynamically, to any |
93 | PCI 2.3 compliant and PCI Express card. It is useful, | 82 | PCI 2.3 compliant and PCI Express card. It is useful, |
94 | primarily, for virtualization scenarios. | 83 | primarily, for virtualization scenarios. |
95 | If you compile this as a module, it will be called uio_pci_generic. | 84 | If you compile this as a module, it will be called uio_pci_generic. |
96 | 85 | ||
86 | config UIO_NETX | ||
87 | tristate "Hilscher NetX Card driver" | ||
88 | depends on PCI | ||
89 | help | ||
90 | Driver for Hilscher NetX based fieldbus cards (cifX, comX). | ||
91 | This driver requires a userspace component that comes with the card | ||
92 | or is available from Hilscher (http://www.hilscher.com). | ||
93 | |||
94 | To compile this driver as a module, choose M here; the module | ||
95 | will be called uio_netx. | ||
96 | |||
97 | endif | 97 | endif |
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index 73b2e7516729..18fd818c5b97 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile | |||
@@ -2,7 +2,7 @@ obj-$(CONFIG_UIO) += uio.o | |||
2 | obj-$(CONFIG_UIO_CIF) += uio_cif.o | 2 | obj-$(CONFIG_UIO_CIF) += uio_cif.o |
3 | obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o | 3 | obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o |
4 | obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o | 4 | obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o |
5 | obj-$(CONFIG_UIO_SMX) += uio_smx.o | ||
6 | obj-$(CONFIG_UIO_AEC) += uio_aec.o | 5 | obj-$(CONFIG_UIO_AEC) += uio_aec.o |
7 | obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o | 6 | obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o |
8 | obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o | 7 | obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o |
8 | obj-$(CONFIG_UIO_NETX) += uio_netx.o | ||
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index e941367dd28f..4de382acd8f2 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -129,7 +129,7 @@ static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr, | |||
129 | return entry->show(mem, buf); | 129 | return entry->show(mem, buf); |
130 | } | 130 | } |
131 | 131 | ||
132 | static struct sysfs_ops map_sysfs_ops = { | 132 | static const struct sysfs_ops map_sysfs_ops = { |
133 | .show = map_type_show, | 133 | .show = map_type_show, |
134 | }; | 134 | }; |
135 | 135 | ||
@@ -217,7 +217,7 @@ static ssize_t portio_type_show(struct kobject *kobj, struct attribute *attr, | |||
217 | return entry->show(port, buf); | 217 | return entry->show(port, buf); |
218 | } | 218 | } |
219 | 219 | ||
220 | static struct sysfs_ops portio_sysfs_ops = { | 220 | static const struct sysfs_ops portio_sysfs_ops = { |
221 | .show = portio_type_show, | 221 | .show = portio_type_show, |
222 | }; | 222 | }; |
223 | 223 | ||
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c new file mode 100644 index 000000000000..afbf0bd55cc9 --- /dev/null +++ b/drivers/uio/uio_netx.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * UIO driver for Hilscher NetX based fieldbus cards (cifX, comX). | ||
3 | * See http://www.hilscher.com for details. | ||
4 | * | ||
5 | * (C) 2007 Hans J. Koch <hjk@linutronix.de> | ||
6 | * (C) 2008 Manuel Traut <manut@linutronix.de> | ||
7 | * | ||
8 | * Licensed under GPL version 2 only. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/device.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/uio_driver.h> | ||
17 | |||
18 | #define PCI_VENDOR_ID_HILSCHER 0x15CF | ||
19 | #define PCI_DEVICE_ID_HILSCHER_NETX 0x0000 | ||
20 | #define PCI_SUBDEVICE_ID_NXSB_PCA 0x3235 | ||
21 | #define PCI_SUBDEVICE_ID_NXPCA 0x3335 | ||
22 | |||
23 | #define DPM_HOST_INT_EN0 0xfff0 | ||
24 | #define DPM_HOST_INT_STAT0 0xffe0 | ||
25 | |||
26 | #define DPM_HOST_INT_MASK 0xe600ffff | ||
27 | #define DPM_HOST_INT_GLOBAL_EN 0x80000000 | ||
28 | |||
29 | static irqreturn_t netx_handler(int irq, struct uio_info *dev_info) | ||
30 | { | ||
31 | void __iomem *int_enable_reg = dev_info->mem[0].internal_addr | ||
32 | + DPM_HOST_INT_EN0; | ||
33 | void __iomem *int_status_reg = dev_info->mem[0].internal_addr | ||
34 | + DPM_HOST_INT_STAT0; | ||
35 | |||
36 | /* Is one of our interrupts enabled and active ? */ | ||
37 | if (!(ioread32(int_enable_reg) & ioread32(int_status_reg) | ||
38 | & DPM_HOST_INT_MASK)) | ||
39 | return IRQ_NONE; | ||
40 | |||
41 | /* Disable interrupt */ | ||
42 | iowrite32(ioread32(int_enable_reg) & ~DPM_HOST_INT_GLOBAL_EN, | ||
43 | int_enable_reg); | ||
44 | return IRQ_HANDLED; | ||
45 | } | ||
46 | |||
47 | static int __devinit netx_pci_probe(struct pci_dev *dev, | ||
48 | const struct pci_device_id *id) | ||
49 | { | ||
50 | struct uio_info *info; | ||
51 | int bar; | ||
52 | |||
53 | info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); | ||
54 | if (!info) | ||
55 | return -ENOMEM; | ||
56 | |||
57 | if (pci_enable_device(dev)) | ||
58 | goto out_free; | ||
59 | |||
60 | if (pci_request_regions(dev, "netx")) | ||
61 | goto out_disable; | ||
62 | |||
63 | switch (id->device) { | ||
64 | case PCI_DEVICE_ID_HILSCHER_NETX: | ||
65 | bar = 0; | ||
66 | info->name = "netx"; | ||
67 | break; | ||
68 | default: | ||
69 | bar = 2; | ||
70 | info->name = "netx_plx"; | ||
71 | } | ||
72 | |||
73 | /* BAR0 or 2 points to the card's dual port memory */ | ||
74 | info->mem[0].addr = pci_resource_start(dev, bar); | ||
75 | if (!info->mem[0].addr) | ||
76 | goto out_release; | ||
77 | info->mem[0].internal_addr = ioremap(pci_resource_start(dev, bar), | ||
78 | pci_resource_len(dev, bar)); | ||
79 | |||
80 | if (!info->mem[0].internal_addr) | ||
81 | goto out_release; | ||
82 | |||
83 | info->mem[0].size = pci_resource_len(dev, bar); | ||
84 | info->mem[0].memtype = UIO_MEM_PHYS; | ||
85 | info->irq = dev->irq; | ||
86 | info->irq_flags = IRQF_SHARED; | ||
87 | info->handler = netx_handler; | ||
88 | info->version = "0.0.1"; | ||
89 | |||
90 | /* Make sure all interrupts are disabled */ | ||
91 | iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0); | ||
92 | |||
93 | if (uio_register_device(&dev->dev, info)) | ||
94 | goto out_unmap; | ||
95 | |||
96 | pci_set_drvdata(dev, info); | ||
97 | dev_info(&dev->dev, "Found %s card, registered UIO device.\n", | ||
98 | info->name); | ||
99 | |||
100 | return 0; | ||
101 | |||
102 | out_unmap: | ||
103 | iounmap(info->mem[0].internal_addr); | ||
104 | out_release: | ||
105 | pci_release_regions(dev); | ||
106 | out_disable: | ||
107 | pci_disable_device(dev); | ||
108 | out_free: | ||
109 | kfree(info); | ||
110 | return -ENODEV; | ||
111 | } | ||
112 | |||
113 | static void netx_pci_remove(struct pci_dev *dev) | ||
114 | { | ||
115 | struct uio_info *info = pci_get_drvdata(dev); | ||
116 | |||
117 | /* Disable all interrupts */ | ||
118 | iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0); | ||
119 | uio_unregister_device(info); | ||
120 | pci_release_regions(dev); | ||
121 | pci_disable_device(dev); | ||
122 | pci_set_drvdata(dev, NULL); | ||
123 | iounmap(info->mem[0].internal_addr); | ||
124 | |||
125 | kfree(info); | ||
126 | } | ||
127 | |||
128 | static struct pci_device_id netx_pci_ids[] = { | ||
129 | { | ||
130 | .vendor = PCI_VENDOR_ID_HILSCHER, | ||
131 | .device = PCI_DEVICE_ID_HILSCHER_NETX, | ||
132 | .subvendor = 0, | ||
133 | .subdevice = 0, | ||
134 | }, | ||
135 | { | ||
136 | .vendor = PCI_VENDOR_ID_PLX, | ||
137 | .device = PCI_DEVICE_ID_PLX_9030, | ||
138 | .subvendor = PCI_VENDOR_ID_PLX, | ||
139 | .subdevice = PCI_SUBDEVICE_ID_NXSB_PCA, | ||
140 | }, | ||
141 | { | ||
142 | .vendor = PCI_VENDOR_ID_PLX, | ||
143 | .device = PCI_DEVICE_ID_PLX_9030, | ||
144 | .subvendor = PCI_VENDOR_ID_PLX, | ||
145 | .subdevice = PCI_SUBDEVICE_ID_NXPCA, | ||
146 | }, | ||
147 | { 0, } | ||
148 | }; | ||
149 | |||
150 | static struct pci_driver netx_pci_driver = { | ||
151 | .name = "netx", | ||
152 | .id_table = netx_pci_ids, | ||
153 | .probe = netx_pci_probe, | ||
154 | .remove = netx_pci_remove, | ||
155 | }; | ||
156 | |||
157 | static int __init netx_init_module(void) | ||
158 | { | ||
159 | return pci_register_driver(&netx_pci_driver); | ||
160 | } | ||
161 | |||
162 | static void __exit netx_exit_module(void) | ||
163 | { | ||
164 | pci_unregister_driver(&netx_pci_driver); | ||
165 | } | ||
166 | |||
167 | module_init(netx_init_module); | ||
168 | module_exit(netx_exit_module); | ||
169 | |||
170 | MODULE_DEVICE_TABLE(pci, netx_pci_ids); | ||
171 | MODULE_LICENSE("GPL v2"); | ||
172 | MODULE_AUTHOR("Hans J. Koch, Manuel Traut"); | ||
diff --git a/drivers/uio/uio_smx.c b/drivers/uio/uio_smx.c deleted file mode 100644 index 44054a650a8a..000000000000 --- a/drivers/uio/uio_smx.c +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
1 | /* | ||
2 | * UIO SMX Cryptengine driver. | ||
3 | * | ||
4 | * (C) 2008 Nias Digital P/L <bn@niasdigital.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/device.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/uio_driver.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | #define DRV_NAME "smx-ce" | ||
19 | #define DRV_VERSION "0.03" | ||
20 | |||
21 | #define SMX_CSR 0x00000000 | ||
22 | #define SMX_EnD 0x00000001 | ||
23 | #define SMX_RUN 0x00000002 | ||
24 | #define SMX_DRDY 0x00000004 | ||
25 | #define SMX_ERR 0x00000008 | ||
26 | |||
27 | static irqreturn_t smx_handler(int irq, struct uio_info *dev_info) | ||
28 | { | ||
29 | void __iomem *csr = dev_info->mem[0].internal_addr + SMX_CSR; | ||
30 | |||
31 | u32 status = ioread32(csr); | ||
32 | |||
33 | if (!(status & SMX_DRDY)) | ||
34 | return IRQ_NONE; | ||
35 | |||
36 | /* Disable interrupt */ | ||
37 | iowrite32(status & ~SMX_DRDY, csr); | ||
38 | return IRQ_HANDLED; | ||
39 | } | ||
40 | |||
41 | static int __devinit smx_ce_probe(struct platform_device *dev) | ||
42 | { | ||
43 | |||
44 | int ret = -ENODEV; | ||
45 | struct uio_info *info; | ||
46 | struct resource *regs; | ||
47 | |||
48 | info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); | ||
49 | if (!info) | ||
50 | return -ENOMEM; | ||
51 | |||
52 | regs = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
53 | if (!regs) { | ||
54 | dev_err(&dev->dev, "No memory resource specified\n"); | ||
55 | goto out_free; | ||
56 | } | ||
57 | |||
58 | info->mem[0].addr = regs->start; | ||
59 | if (!info->mem[0].addr) { | ||
60 | dev_err(&dev->dev, "Invalid memory resource\n"); | ||
61 | goto out_free; | ||
62 | } | ||
63 | |||
64 | info->mem[0].size = regs->end - regs->start + 1; | ||
65 | info->mem[0].internal_addr = ioremap(regs->start, info->mem[0].size); | ||
66 | |||
67 | if (!info->mem[0].internal_addr) { | ||
68 | dev_err(&dev->dev, "Can't remap memory address range\n"); | ||
69 | goto out_free; | ||
70 | } | ||
71 | |||
72 | info->mem[0].memtype = UIO_MEM_PHYS; | ||
73 | |||
74 | info->name = "smx-ce"; | ||
75 | info->version = "0.03"; | ||
76 | |||
77 | info->irq = platform_get_irq(dev, 0); | ||
78 | if (info->irq < 0) { | ||
79 | ret = info->irq; | ||
80 | dev_err(&dev->dev, "No (or invalid) IRQ resource specified\n"); | ||
81 | goto out_unmap; | ||
82 | } | ||
83 | |||
84 | info->irq_flags = IRQF_SHARED; | ||
85 | info->handler = smx_handler; | ||
86 | |||
87 | platform_set_drvdata(dev, info); | ||
88 | |||
89 | ret = uio_register_device(&dev->dev, info); | ||
90 | |||
91 | if (ret) | ||
92 | goto out_unmap; | ||
93 | |||
94 | return 0; | ||
95 | |||
96 | out_unmap: | ||
97 | iounmap(info->mem[0].internal_addr); | ||
98 | out_free: | ||
99 | kfree(info); | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static int __devexit smx_ce_remove(struct platform_device *dev) | ||
105 | { | ||
106 | struct uio_info *info = platform_get_drvdata(dev); | ||
107 | |||
108 | uio_unregister_device(info); | ||
109 | platform_set_drvdata(dev, NULL); | ||
110 | iounmap(info->mem[0].internal_addr); | ||
111 | |||
112 | kfree(info); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static struct platform_driver smx_ce_driver = { | ||
118 | .probe = smx_ce_probe, | ||
119 | .remove = __devexit_p(smx_ce_remove), | ||
120 | .driver = { | ||
121 | .name = DRV_NAME, | ||
122 | .owner = THIS_MODULE, | ||
123 | }, | ||
124 | }; | ||
125 | |||
126 | static int __init smx_ce_init_module(void) | ||
127 | { | ||
128 | return platform_driver_register(&smx_ce_driver); | ||
129 | } | ||
130 | module_init(smx_ce_init_module); | ||
131 | |||
132 | static void __exit smx_ce_exit_module(void) | ||
133 | { | ||
134 | platform_driver_unregister(&smx_ce_driver); | ||
135 | } | ||
136 | module_exit(smx_ce_exit_module); | ||
137 | |||
138 | MODULE_LICENSE("GPL v2"); | ||
139 | MODULE_VERSION(DRV_VERSION); | ||
140 | MODULE_AUTHOR("Ben Nizette <bn@niasdigital.com>"); | ||
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index a7037bf81688..f3c233806fa3 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -489,10 +489,10 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
489 | if (device_is_registered(dev)) { | 489 | if (device_is_registered(dev)) { |
490 | device_release_driver(dev); | 490 | device_release_driver(dev); |
491 | } else { | 491 | } else { |
492 | down(&dev->sem); | 492 | device_lock(dev); |
493 | usb_unbind_interface(dev); | 493 | usb_unbind_interface(dev); |
494 | dev->driver = NULL; | 494 | dev->driver = NULL; |
495 | up(&dev->sem); | 495 | device_unlock(dev); |
496 | } | 496 | } |
497 | } | 497 | } |
498 | EXPORT_SYMBOL_GPL(usb_driver_release_interface); | 498 | EXPORT_SYMBOL_GPL(usb_driver_release_interface); |
diff --git a/drivers/usb/gadget/fsl_mx3_udc.c b/drivers/usb/gadget/fsl_mx3_udc.c index 4bc2bf3d602e..20a802ecaa15 100644 --- a/drivers/usb/gadget/fsl_mx3_udc.c +++ b/drivers/usb/gadget/fsl_mx3_udc.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/fsl_devices.h> | 17 | #include <linux/fsl_devices.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <mach/hardware.h> | ||
21 | |||
20 | static struct clk *mxc_ahb_clk; | 22 | static struct clk *mxc_ahb_clk; |
21 | static struct clk *mxc_usb_clk; | 23 | static struct clk *mxc_usb_clk; |
22 | 24 | ||
@@ -28,14 +30,16 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
28 | 30 | ||
29 | pdata = pdev->dev.platform_data; | 31 | pdata = pdev->dev.platform_data; |
30 | 32 | ||
31 | mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); | 33 | if (!cpu_is_mx35()) { |
32 | if (IS_ERR(mxc_ahb_clk)) | 34 | mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); |
33 | return PTR_ERR(mxc_ahb_clk); | 35 | if (IS_ERR(mxc_ahb_clk)) |
36 | return PTR_ERR(mxc_ahb_clk); | ||
34 | 37 | ||
35 | ret = clk_enable(mxc_ahb_clk); | 38 | ret = clk_enable(mxc_ahb_clk); |
36 | if (ret < 0) { | 39 | if (ret < 0) { |
37 | dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); | 40 | dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); |
38 | goto eenahb; | 41 | goto eenahb; |
42 | } | ||
39 | } | 43 | } |
40 | 44 | ||
41 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | 45 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ |
@@ -50,6 +54,7 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
50 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && | 54 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && |
51 | (freq < 59999000 || freq > 60001000)) { | 55 | (freq < 59999000 || freq > 60001000)) { |
52 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); | 56 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); |
57 | ret = -EINVAL; | ||
53 | goto eclkrate; | 58 | goto eclkrate; |
54 | } | 59 | } |
55 | 60 | ||
@@ -66,9 +71,11 @@ eclkrate: | |||
66 | clk_put(mxc_usb_clk); | 71 | clk_put(mxc_usb_clk); |
67 | mxc_usb_clk = NULL; | 72 | mxc_usb_clk = NULL; |
68 | egusb: | 73 | egusb: |
69 | clk_disable(mxc_ahb_clk); | 74 | if (!cpu_is_mx35()) |
75 | clk_disable(mxc_ahb_clk); | ||
70 | eenahb: | 76 | eenahb: |
71 | clk_put(mxc_ahb_clk); | 77 | if (!cpu_is_mx35()) |
78 | clk_put(mxc_ahb_clk); | ||
72 | return ret; | 79 | return ret; |
73 | } | 80 | } |
74 | 81 | ||
@@ -90,6 +97,8 @@ void fsl_udc_clk_release(void) | |||
90 | clk_disable(mxc_usb_clk); | 97 | clk_disable(mxc_usb_clk); |
91 | clk_put(mxc_usb_clk); | 98 | clk_put(mxc_usb_clk); |
92 | } | 99 | } |
93 | clk_disable(mxc_ahb_clk); | 100 | if (!cpu_is_mx35()) { |
94 | clk_put(mxc_ahb_clk); | 101 | clk_disable(mxc_ahb_clk); |
102 | clk_put(mxc_ahb_clk); | ||
103 | } | ||
95 | } | 104 | } |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index e6fedbd5a654..be5fb34d9602 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -65,6 +65,10 @@ | |||
65 | #include <mach/pxa25x-udc.h> | 65 | #include <mach/pxa25x-udc.h> |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #ifdef CONFIG_ARCH_LUBBOCK | ||
69 | #include <mach/lubbock.h> | ||
70 | #endif | ||
71 | |||
68 | #include <asm/mach/udc_pxa2xx.h> | 72 | #include <asm/mach/udc_pxa2xx.h> |
69 | 73 | ||
70 | 74 | ||
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 7e5bf593d386..f742c8e7397c 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include <plat/regs-usb-hsotg-phy.h> | 31 | #include <plat/regs-usb-hsotg-phy.h> |
32 | #include <plat/regs-usb-hsotg.h> | 32 | #include <plat/regs-usb-hsotg.h> |
33 | #include <plat/regs-sys.h> | 33 | #include <mach/regs-sys.h> |
34 | #include <plat/udc-hs.h> | 34 | #include <plat/udc-hs.h> |
35 | 35 | ||
36 | #define DMA_ADDR_INVALID (~((dma_addr_t)0)) | 36 | #define DMA_ADDR_INVALID (~((dma_addr_t)0)) |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 66913811af5e..a883f9dd3f8a 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -274,7 +274,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
274 | /* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through | 274 | /* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through |
275 | * the Mentor registers (except for setup), use the TI ones and EOI. | 275 | * the Mentor registers (except for setup), use the TI ones and EOI. |
276 | * | 276 | * |
277 | * Docs describe irq "vector" registers asociated with the CPPI and | 277 | * Docs describe irq "vector" registers associated with the CPPI and |
278 | * USB EOI registers. These hold a bitmask corresponding to the | 278 | * USB EOI registers. These hold a bitmask corresponding to the |
279 | * current IRQ, not an irq handler address. Would using those bits | 279 | * current IRQ, not an irq handler address. Would using those bits |
280 | * resolve some of the races observed in this dispatch code?? | 280 | * resolve some of the races observed in this dispatch code?? |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 292894a2c247..8d8062b10e2f 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -491,7 +491,7 @@ static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) | |||
491 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | 491 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ |
492 | (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) | 492 | (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) |
493 | 493 | ||
494 | /* Not implemented - HW has seperate Tx/Rx FIFO */ | 494 | /* Not implemented - HW has separate Tx/Rx FIFO */ |
495 | #define MUSB_TXCSR_MODE 0x0000 | 495 | #define MUSB_TXCSR_MODE 0x0000 |
496 | 496 | ||
497 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | 497 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index baf74b44e6ed..e23c77925e7a 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -152,7 +152,7 @@ struct cypress_private { | |||
152 | int isthrottled; /* if throttled, discard reads */ | 152 | int isthrottled; /* if throttled, discard reads */ |
153 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ | 153 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ |
154 | char prev_status, diff_status; /* used for TIOCMIWAIT */ | 154 | char prev_status, diff_status; /* used for TIOCMIWAIT */ |
155 | /* we pass a pointer to this as the arguement sent to | 155 | /* we pass a pointer to this as the argument sent to |
156 | cypress_set_termios old_termios */ | 156 | cypress_set_termios old_termios */ |
157 | struct ktermios tmp_termios; /* stores the old termios settings */ | 157 | struct ktermios tmp_termios; /* stores the old termios settings */ |
158 | }; | 158 | }; |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index f37476e22684..701452ae9197 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -115,7 +115,7 @@ static void opticon_bulk_callback(struct urb *urb) | |||
115 | } | 115 | } |
116 | } else { | 116 | } else { |
117 | dev_dbg(&priv->udev->dev, | 117 | dev_dbg(&priv->udev->dev, |
118 | "Improper ammount of data received from the device, " | 118 | "Improper amount of data received from the device, " |
119 | "%d bytes", urb->actual_length); | 119 | "%d bytes", urb->actual_length); |
120 | } | 120 | } |
121 | 121 | ||
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 72398888858f..ee190cc1757c 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -94,7 +94,7 @@ static void symbol_int_callback(struct urb *urb) | |||
94 | } | 94 | } |
95 | } else { | 95 | } else { |
96 | dev_dbg(&priv->udev->dev, | 96 | dev_dbg(&priv->udev->dev, |
97 | "Improper ammount of data received from the device, " | 97 | "Improper amount of data received from the device, " |
98 | "%d bytes", urb->actual_length); | 98 | "%d bytes", urb->actual_length); |
99 | } | 99 | } |
100 | 100 | ||
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index fd2fd4e277e1..759cda55f7c3 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h | |||
@@ -198,7 +198,7 @@ struct wusb_port { | |||
198 | * ports) this HC will take. Read-only. | 198 | * ports) this HC will take. Read-only. |
199 | * | 199 | * |
200 | * @port Array of port status for each fake root port. Guaranteed to | 200 | * @port Array of port status for each fake root port. Guaranteed to |
201 | * always be the same lenght during device existence | 201 | * always be the same length during device existence |
202 | * [this allows for some unlocked but referenced reading]. | 202 | * [this allows for some unlocked but referenced reading]. |
203 | * | 203 | * |
204 | * @mmcies_max Max number of Information Elements this HC can send | 204 | * @mmcies_max Max number of Information Elements this HC can send |
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c index da77e41de990..08bd6dbfd4a6 100644 --- a/drivers/uwb/driver.c +++ b/drivers/uwb/driver.c | |||
@@ -74,13 +74,16 @@ | |||
74 | unsigned long beacon_timeout_ms = 500; | 74 | unsigned long beacon_timeout_ms = 500; |
75 | 75 | ||
76 | static | 76 | static |
77 | ssize_t beacon_timeout_ms_show(struct class *class, char *buf) | 77 | ssize_t beacon_timeout_ms_show(struct class *class, |
78 | struct class_attribute *attr, | ||
79 | char *buf) | ||
78 | { | 80 | { |
79 | return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms); | 81 | return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms); |
80 | } | 82 | } |
81 | 83 | ||
82 | static | 84 | static |
83 | ssize_t beacon_timeout_ms_store(struct class *class, | 85 | ssize_t beacon_timeout_ms_store(struct class *class, |
86 | struct class_attribute *attr, | ||
84 | const char *buf, size_t size) | 87 | const char *buf, size_t size) |
85 | { | 88 | { |
86 | unsigned long bt; | 89 | unsigned long bt; |
diff --git a/drivers/uwb/i1480/i1480-est.c b/drivers/uwb/i1480/i1480-est.c index 7bf8c6febae7..f2eb4d8b76c9 100644 --- a/drivers/uwb/i1480/i1480-est.c +++ b/drivers/uwb/i1480/i1480-est.c | |||
@@ -54,7 +54,7 @@ static struct uwb_est_entry i1480_est_fd01[] = { | |||
54 | .size = sizeof(struct i1480_rceb) + 2 }, | 54 | .size = sizeof(struct i1480_rceb) + 2 }, |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static int i1480_est_init(void) | 57 | static int __init i1480_est_init(void) |
58 | { | 58 | { |
59 | int result = uwb_est_register(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b, | 59 | int result = uwb_est_register(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b, |
60 | i1480_est_fd00, | 60 | i1480_est_fd00, |
@@ -73,7 +73,7 @@ static int i1480_est_init(void) | |||
73 | } | 73 | } |
74 | module_init(i1480_est_init); | 74 | module_init(i1480_est_init); |
75 | 75 | ||
76 | static void i1480_est_exit(void) | 76 | static void __exit i1480_est_exit(void) |
77 | { | 77 | { |
78 | uwb_est_unregister(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b, | 78 | uwb_est_unregister(i1480_CET_VS1, 0x00, 0x8086, 0x0c3b, |
79 | i1480_est_fd00, ARRAY_SIZE(i1480_est_fd00)); | 79 | i1480_est_fd00, ARRAY_SIZE(i1480_est_fd00)); |
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c index cdd6c8efc9f8..5fad4e791b3e 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/uwb/umc-bus.c | |||
@@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev *umc) | |||
62 | struct device *parent = umc->dev.parent; | 62 | struct device *parent = umc->dev.parent; |
63 | int ret = 0; | 63 | int ret = 0; |
64 | 64 | ||
65 | if(down_trylock(&parent->sem)) | 65 | if (device_trylock(parent)) |
66 | return -EAGAIN; | 66 | return -EAGAIN; |
67 | ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); | 67 | ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); |
68 | if (ret >= 0) | 68 | if (ret >= 0) |
69 | ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper); | 69 | ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper); |
70 | up(&parent->sem); | 70 | device_unlock(parent); |
71 | 71 | ||
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index d5bcfc1c227a..157485c862c0 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h | |||
@@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal); | |||
366 | 366 | ||
367 | static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) | 367 | static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) |
368 | { | 368 | { |
369 | down(&uwb_dev->dev.sem); | 369 | device_lock(&uwb_dev->dev); |
370 | } | 370 | } |
371 | 371 | ||
372 | static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev) | 372 | static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev) |
373 | { | 373 | { |
374 | up(&uwb_dev->dev.sem); | 374 | device_unlock(&uwb_dev->dev); |
375 | } | 375 | } |
376 | 376 | ||
377 | #endif /* #ifndef __UWB_INTERNAL_H__ */ | 377 | #endif /* #ifndef __UWB_INTERNAL_H__ */ |
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 5a777d8624da..6210fe1fd1bb 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c | |||
@@ -43,7 +43,7 @@ | |||
43 | * | 43 | * |
44 | * EVENTS | 44 | * EVENTS |
45 | * | 45 | * |
46 | * Events have a type, a subtype, a lenght, some other stuff and the | 46 | * Events have a type, a subtype, a length, some other stuff and the |
47 | * data blob, which depends on the event. The header is 'struct | 47 | * data blob, which depends on the event. The header is 'struct |
48 | * uwb_event'; for payloads, see 'struct uwbd_evt_*'. | 48 | * uwb_event'; for payloads, see 'struct uwbd_evt_*'. |
49 | * | 49 | * |
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c index 0370399ff4bb..6627c94cc854 100644 --- a/drivers/uwb/wlp/sysfs.c +++ b/drivers/uwb/wlp/sysfs.c | |||
@@ -615,8 +615,7 @@ ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr, | |||
615 | return ret; | 615 | return ret; |
616 | } | 616 | } |
617 | 617 | ||
618 | static | 618 | static const struct sysfs_ops wss_sysfs_ops = { |
619 | struct sysfs_ops wss_sysfs_ops = { | ||
620 | .show = wlp_wss_attr_show, | 619 | .show = wlp_wss_attr_show, |
621 | .store = wlp_wss_attr_store, | 620 | .store = wlp_wss_attr_store, |
622 | }; | 621 | }; |
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c index 0b17824b0eb5..2110556f76b3 100644 --- a/drivers/video/68328fb.c +++ b/drivers/video/68328fb.c | |||
@@ -308,7 +308,7 @@ static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
308 | * Pseudocolor: | 308 | * Pseudocolor: |
309 | * uses offset = 0 && length = RAMDAC register width. | 309 | * uses offset = 0 && length = RAMDAC register width. |
310 | * var->{color}.offset is 0 | 310 | * var->{color}.offset is 0 |
311 | * var->{color}.length contains widht of DAC | 311 | * var->{color}.length contains width of DAC |
312 | * cmap is not used | 312 | * cmap is not used |
313 | * RAMDAC[X] is programmed to (red, green, blue) | 313 | * RAMDAC[X] is programmed to (red, green, blue) |
314 | * Truecolor: | 314 | * Truecolor: |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5a5c303a6373..dabe804ba575 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -400,9 +400,12 @@ config FB_SA1100 | |||
400 | If you plan to use the LCD display with your SA-1100 system, say | 400 | If you plan to use the LCD display with your SA-1100 system, say |
401 | Y here. | 401 | Y here. |
402 | 402 | ||
403 | config HAVE_FB_IMX | ||
404 | bool | ||
405 | |||
403 | config FB_IMX | 406 | config FB_IMX |
404 | tristate "Motorola i.MX LCD support" | 407 | tristate "Motorola i.MX LCD support" |
405 | depends on FB && (ARCH_MX1 || ARCH_MX2) | 408 | depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2) |
406 | select FB_CFB_FILLRECT | 409 | select FB_CFB_FILLRECT |
407 | select FB_CFB_COPYAREA | 410 | select FB_CFB_COPYAREA |
408 | select FB_CFB_IMAGEBLIT | 411 | select FB_CFB_IMAGEBLIT |
@@ -909,6 +912,18 @@ config FB_XVR2500 | |||
909 | mostly initialized the card already. It is treated as a | 912 | mostly initialized the card already. It is treated as a |
910 | completely dumb framebuffer device. | 913 | completely dumb framebuffer device. |
911 | 914 | ||
915 | config FB_XVR1000 | ||
916 | bool "Sun XVR-1000 support" | ||
917 | depends on SPARC64 | ||
918 | select FB_CFB_FILLRECT | ||
919 | select FB_CFB_COPYAREA | ||
920 | select FB_CFB_IMAGEBLIT | ||
921 | help | ||
922 | This is the framebuffer device for the Sun XVR-1000 and similar | ||
923 | graphics cards. The driver only works on sparc64 systems where | ||
924 | the system firmware has mostly initialized the card already. It | ||
925 | is treated as a completely dumb framebuffer device. | ||
926 | |||
912 | config FB_PVR2 | 927 | config FB_PVR2 |
913 | tristate "NEC PowerVR 2 display support" | 928 | tristate "NEC PowerVR 2 display support" |
914 | depends on FB && SH_DREAMCAST | 929 | depends on FB && SH_DREAMCAST |
@@ -1494,7 +1509,6 @@ config FB_VIA | |||
1494 | select FB_CFB_FILLRECT | 1509 | select FB_CFB_FILLRECT |
1495 | select FB_CFB_COPYAREA | 1510 | select FB_CFB_COPYAREA |
1496 | select FB_CFB_IMAGEBLIT | 1511 | select FB_CFB_IMAGEBLIT |
1497 | select FB_SOFT_CURSOR | ||
1498 | select I2C_ALGOBIT | 1512 | select I2C_ALGOBIT |
1499 | select I2C | 1513 | select I2C |
1500 | help | 1514 | help |
@@ -1945,6 +1959,27 @@ config FB_S3C2410_DEBUG | |||
1945 | Turn on debugging messages. Note that you can set/unset at run time | 1959 | Turn on debugging messages. Note that you can set/unset at run time |
1946 | through sysfs | 1960 | through sysfs |
1947 | 1961 | ||
1962 | config FB_NUC900 | ||
1963 | bool "NUC900 LCD framebuffer support" | ||
1964 | depends on FB && ARCH_W90X900 | ||
1965 | select FB_CFB_FILLRECT | ||
1966 | select FB_CFB_COPYAREA | ||
1967 | select FB_CFB_IMAGEBLIT | ||
1968 | ---help--- | ||
1969 | Frame buffer driver for the built-in LCD controller in the Nuvoton | ||
1970 | NUC900 processor | ||
1971 | |||
1972 | config GPM1040A0_320X240 | ||
1973 | bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" | ||
1974 | depends on FB_NUC900 | ||
1975 | |||
1976 | config FB_NUC900_DEBUG | ||
1977 | bool "NUC900 lcd debug messages" | ||
1978 | depends on FB_NUC900 | ||
1979 | help | ||
1980 | Turn on debugging messages. Note that you can set/unset at run time | ||
1981 | through sysfs | ||
1982 | |||
1948 | config FB_SM501 | 1983 | config FB_SM501 |
1949 | tristate "Silicon Motion SM501 framebuffer support" | 1984 | tristate "Silicon Motion SM501 framebuffer support" |
1950 | depends on FB && MFD_SM501 | 1985 | depends on FB && MFD_SM501 |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 4ecb30c4f3f2..ddc2af2ba45b 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -79,6 +79,7 @@ obj-$(CONFIG_FB_N411) += n411.o | |||
79 | obj-$(CONFIG_FB_HGA) += hgafb.o | 79 | obj-$(CONFIG_FB_HGA) += hgafb.o |
80 | obj-$(CONFIG_FB_XVR500) += sunxvr500.o | 80 | obj-$(CONFIG_FB_XVR500) += sunxvr500.o |
81 | obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o | 81 | obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o |
82 | obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o | ||
82 | obj-$(CONFIG_FB_IGA) += igafb.o | 83 | obj-$(CONFIG_FB_IGA) += igafb.o |
83 | obj-$(CONFIG_FB_APOLLO) += dnfb.o | 84 | obj-$(CONFIG_FB_APOLLO) += dnfb.o |
84 | obj-$(CONFIG_FB_Q40) += q40fb.o | 85 | obj-$(CONFIG_FB_Q40) += q40fb.o |
@@ -129,6 +130,7 @@ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o | |||
129 | obj-$(CONFIG_FB_CARMINE) += carminefb.o | 130 | obj-$(CONFIG_FB_CARMINE) += carminefb.o |
130 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ | 131 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ |
131 | obj-$(CONFIG_FB_MSM) += msm/ | 132 | obj-$(CONFIG_FB_MSM) += msm/ |
133 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o | ||
132 | 134 | ||
133 | # Platform or fallback drivers go here | 135 | # Platform or fallback drivers go here |
134 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 136 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 0bcc59eb37fa..43d7d5067361 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c | |||
@@ -1221,7 +1221,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) | |||
1221 | printk("acornfb: freed %dK memory\n", mb_freed); | 1221 | printk("acornfb: freed %dK memory\n", mb_freed); |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static int __init acornfb_probe(struct platform_device *dev) | 1224 | static int __devinit acornfb_probe(struct platform_device *dev) |
1225 | { | 1225 | { |
1226 | unsigned long size; | 1226 | unsigned long size; |
1227 | u_int h_sync, v_sync; | 1227 | u_int h_sync, v_sync; |
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index c3431691c9f2..01554d696528 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c | |||
@@ -504,7 +504,7 @@ static struct fb_ops arcfb_ops = { | |||
504 | .fb_ioctl = arcfb_ioctl, | 504 | .fb_ioctl = arcfb_ioctl, |
505 | }; | 505 | }; |
506 | 506 | ||
507 | static int __init arcfb_probe(struct platform_device *dev) | 507 | static int __devinit arcfb_probe(struct platform_device *dev) |
508 | { | 508 | { |
509 | struct fb_info *info; | 509 | struct fb_info *info; |
510 | int retval = -ENOMEM; | 510 | int retval = -ENOMEM; |
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index 9fe90ce928fb..e70bc225fe31 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c | |||
@@ -140,7 +140,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc | |||
140 | 140 | ||
141 | /* 3 <= m <= 257 */ | 141 | /* 3 <= m <= 257 */ |
142 | if (m >= 3 && m <= 257) { | 142 | if (m >= 3 && m <= 257) { |
143 | unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ? | 143 | unsigned new_error = Ftarget * n >= Fref * m ? |
144 | ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n)); | 144 | ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n)); |
145 | if (new_error < best_error) { | 145 | if (new_error < best_error) { |
146 | best_n = n; | 146 | best_n = n; |
@@ -152,7 +152,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc | |||
152 | else if (m <= 1028) { | 152 | else if (m <= 1028) { |
153 | /* remember there are still only 8-bits of precision in m, so | 153 | /* remember there are still only 8-bits of precision in m, so |
154 | * avoid over-optimistic error calculations */ | 154 | * avoid over-optimistic error calculations */ |
155 | unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ? | 155 | unsigned new_error = Ftarget * n >= Fref * (m & ~3) ? |
156 | ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n)); | 156 | ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n)); |
157 | if (new_error < best_error) { | 157 | if (new_error < best_error) { |
158 | best_n = n; | 158 | best_n = n; |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index e49ae5edcc00..814312a7452f 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -82,7 +82,6 @@ struct bfin_bf54xfb_info { | |||
82 | unsigned char *fb_buffer; /* RGB Buffer */ | 82 | unsigned char *fb_buffer; /* RGB Buffer */ |
83 | 83 | ||
84 | dma_addr_t dma_handle; | 84 | dma_addr_t dma_handle; |
85 | int lq043_mmap; | ||
86 | int lq043_open_cnt; | 85 | int lq043_open_cnt; |
87 | int irq; | 86 | int irq; |
88 | spinlock_t lock; /* lock */ | 87 | spinlock_t lock; /* lock */ |
@@ -316,7 +315,6 @@ static int bfin_bf54x_fb_release(struct fb_info *info, int user) | |||
316 | spin_lock(&fbi->lock); | 315 | spin_lock(&fbi->lock); |
317 | 316 | ||
318 | fbi->lq043_open_cnt--; | 317 | fbi->lq043_open_cnt--; |
319 | fbi->lq043_mmap = 0; | ||
320 | 318 | ||
321 | if (fbi->lq043_open_cnt <= 0) { | 319 | if (fbi->lq043_open_cnt <= 0) { |
322 | 320 | ||
@@ -374,33 +372,6 @@ static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var, | |||
374 | return 0; | 372 | return 0; |
375 | } | 373 | } |
376 | 374 | ||
377 | static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
378 | { | ||
379 | |||
380 | struct bfin_bf54xfb_info *fbi = info->par; | ||
381 | |||
382 | if (fbi->lq043_mmap) | ||
383 | return -1; | ||
384 | |||
385 | spin_lock(&fbi->lock); | ||
386 | fbi->lq043_mmap = 1; | ||
387 | spin_unlock(&fbi->lock); | ||
388 | |||
389 | vma->vm_start = (unsigned long)(fbi->fb_buffer); | ||
390 | |||
391 | vma->vm_end = vma->vm_start + info->fix.smem_len; | ||
392 | /* For those who don't understand how mmap works, go read | ||
393 | * Documentation/nommu-mmap.txt. | ||
394 | * For those that do, you will know that the VM_MAYSHARE flag | ||
395 | * must be set in the vma->vm_flags structure on noMMU | ||
396 | * Other flags can be set, and are documented in | ||
397 | * include/linux/mm.h | ||
398 | */ | ||
399 | vma->vm_flags |= VM_MAYSHARE | VM_SHARED; | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 375 | int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
405 | { | 376 | { |
406 | if (nocursor) | 377 | if (nocursor) |
@@ -452,7 +423,6 @@ static struct fb_ops bfin_bf54x_fb_ops = { | |||
452 | .fb_fillrect = cfb_fillrect, | 423 | .fb_fillrect = cfb_fillrect, |
453 | .fb_copyarea = cfb_copyarea, | 424 | .fb_copyarea = cfb_copyarea, |
454 | .fb_imageblit = cfb_imageblit, | 425 | .fb_imageblit = cfb_imageblit, |
455 | .fb_mmap = bfin_bf54x_fb_mmap, | ||
456 | .fb_cursor = bfin_bf54x_fb_cursor, | 426 | .fb_cursor = bfin_bf54x_fb_cursor, |
457 | .fb_setcolreg = bfin_bf54x_fb_setcolreg, | 427 | .fb_setcolreg = bfin_bf54x_fb_setcolreg, |
458 | }; | 428 | }; |
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index b690c269784a..03872365a36d 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
25 | #include <linux/dma-mapping.h> | ||
26 | 25 | ||
27 | #include <asm/blackfin.h> | 26 | #include <asm/blackfin.h> |
28 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 2549c53b26a0..5653d083a983 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -87,7 +87,6 @@ struct bfin_t350mcqbfb_info { | |||
87 | struct device *dev; | 87 | struct device *dev; |
88 | unsigned char *fb_buffer; /* RGB Buffer */ | 88 | unsigned char *fb_buffer; /* RGB Buffer */ |
89 | dma_addr_t dma_handle; | 89 | dma_addr_t dma_handle; |
90 | int lq043_mmap; | ||
91 | int lq043_open_cnt; | 90 | int lq043_open_cnt; |
92 | int irq; | 91 | int irq; |
93 | spinlock_t lock; /* lock */ | 92 | spinlock_t lock; /* lock */ |
@@ -235,7 +234,6 @@ static int bfin_t350mcqb_fb_release(struct fb_info *info, int user) | |||
235 | spin_lock(&fbi->lock); | 234 | spin_lock(&fbi->lock); |
236 | 235 | ||
237 | fbi->lq043_open_cnt--; | 236 | fbi->lq043_open_cnt--; |
238 | fbi->lq043_mmap = 0; | ||
239 | 237 | ||
240 | if (fbi->lq043_open_cnt <= 0) { | 238 | if (fbi->lq043_open_cnt <= 0) { |
241 | bfin_t350mcqb_disable_ppi(); | 239 | bfin_t350mcqb_disable_ppi(); |
@@ -293,32 +291,6 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, | |||
293 | return 0; | 291 | return 0; |
294 | } | 292 | } |
295 | 293 | ||
296 | static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
297 | { | ||
298 | struct bfin_t350mcqbfb_info *fbi = info->par; | ||
299 | |||
300 | if (fbi->lq043_mmap) | ||
301 | return -1; | ||
302 | |||
303 | spin_lock(&fbi->lock); | ||
304 | fbi->lq043_mmap = 1; | ||
305 | spin_unlock(&fbi->lock); | ||
306 | |||
307 | vma->vm_start = (unsigned long)(fbi->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET); | ||
308 | |||
309 | vma->vm_end = vma->vm_start + info->fix.smem_len; | ||
310 | /* For those who don't understand how mmap works, go read | ||
311 | * Documentation/nommu-mmap.txt. | ||
312 | * For those that do, you will know that the VM_MAYSHARE flag | ||
313 | * must be set in the vma->vm_flags structure on noMMU | ||
314 | * Other flags can be set, and are documented in | ||
315 | * include/linux/mm.h | ||
316 | */ | ||
317 | vma->vm_flags |= VM_MAYSHARE | VM_SHARED; | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 294 | int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
323 | { | 295 | { |
324 | if (nocursor) | 296 | if (nocursor) |
@@ -370,7 +342,6 @@ static struct fb_ops bfin_t350mcqb_fb_ops = { | |||
370 | .fb_fillrect = cfb_fillrect, | 342 | .fb_fillrect = cfb_fillrect, |
371 | .fb_copyarea = cfb_copyarea, | 343 | .fb_copyarea = cfb_copyarea, |
372 | .fb_imageblit = cfb_imageblit, | 344 | .fb_imageblit = cfb_imageblit, |
373 | .fb_mmap = bfin_t350mcqb_fb_mmap, | ||
374 | .fb_cursor = bfin_t350mcqb_fb_cursor, | 345 | .fb_cursor = bfin_t350mcqb_fb_cursor, |
375 | .fb_setcolreg = bfin_t350mcqb_fb_setcolreg, | 346 | .fb_setcolreg = bfin_t350mcqb_fb_setcolreg, |
376 | }; | 347 | }; |
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c index df9ccb901d86..ebda6876d3a9 100644 --- a/drivers/video/broadsheetfb.c +++ b/drivers/video/broadsheetfb.c | |||
@@ -29,11 +29,65 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/list.h> | 31 | #include <linux/list.h> |
32 | #include <linux/firmware.h> | ||
32 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
33 | 34 | ||
34 | #include <video/broadsheetfb.h> | 35 | #include <video/broadsheetfb.h> |
35 | 36 | ||
36 | /* Display specific information */ | 37 | /* track panel specific parameters */ |
38 | struct panel_info { | ||
39 | int w; | ||
40 | int h; | ||
41 | u16 sdcfg; | ||
42 | u16 gdcfg; | ||
43 | u16 lutfmt; | ||
44 | u16 fsynclen; | ||
45 | u16 fendfbegin; | ||
46 | u16 lsynclen; | ||
47 | u16 lendlbegin; | ||
48 | u16 pixclk; | ||
49 | }; | ||
50 | |||
51 | /* table of panel specific parameters to be indexed into by the board drivers */ | ||
52 | static struct panel_info panel_table[] = { | ||
53 | { /* standard 6" on TFT backplane */ | ||
54 | .w = 800, | ||
55 | .h = 600, | ||
56 | .sdcfg = (100 | (1 << 8) | (1 << 9)), | ||
57 | .gdcfg = 2, | ||
58 | .lutfmt = (4 | (1 << 7)), | ||
59 | .fsynclen = 4, | ||
60 | .fendfbegin = (10 << 8) | 4, | ||
61 | .lsynclen = 10, | ||
62 | .lendlbegin = (100 << 8) | 4, | ||
63 | .pixclk = 6, | ||
64 | }, | ||
65 | { /* custom 3.7" flexible on PET or steel */ | ||
66 | .w = 320, | ||
67 | .h = 240, | ||
68 | .sdcfg = (67 | (0 << 8) | (0 << 9) | (0 << 10) | (0 << 12)), | ||
69 | .gdcfg = 3, | ||
70 | .lutfmt = (4 | (1 << 7)), | ||
71 | .fsynclen = 0, | ||
72 | .fendfbegin = (80 << 8) | 4, | ||
73 | .lsynclen = 10, | ||
74 | .lendlbegin = (80 << 8) | 20, | ||
75 | .pixclk = 14, | ||
76 | }, | ||
77 | { /* standard 9.7" on TFT backplane */ | ||
78 | .w = 1200, | ||
79 | .h = 825, | ||
80 | .sdcfg = (100 | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 12)), | ||
81 | .gdcfg = 2, | ||
82 | .lutfmt = (4 | (1 << 7)), | ||
83 | .fsynclen = 0, | ||
84 | .fendfbegin = (4 << 8) | 4, | ||
85 | .lsynclen = 4, | ||
86 | .lendlbegin = (60 << 8) | 10, | ||
87 | .pixclk = 3, | ||
88 | }, | ||
89 | }; | ||
90 | |||
37 | #define DPY_W 800 | 91 | #define DPY_W 800 |
38 | #define DPY_H 600 | 92 | #define DPY_H 600 |
39 | 93 | ||
@@ -62,30 +116,30 @@ static struct fb_var_screeninfo broadsheetfb_var __devinitdata = { | |||
62 | }; | 116 | }; |
63 | 117 | ||
64 | /* main broadsheetfb functions */ | 118 | /* main broadsheetfb functions */ |
65 | static void broadsheet_issue_data(struct broadsheetfb_par *par, u16 data) | 119 | static void broadsheet_gpio_issue_data(struct broadsheetfb_par *par, u16 data) |
66 | { | 120 | { |
67 | par->board->set_ctl(par, BS_WR, 0); | 121 | par->board->set_ctl(par, BS_WR, 0); |
68 | par->board->set_hdb(par, data); | 122 | par->board->set_hdb(par, data); |
69 | par->board->set_ctl(par, BS_WR, 1); | 123 | par->board->set_ctl(par, BS_WR, 1); |
70 | } | 124 | } |
71 | 125 | ||
72 | static void broadsheet_issue_cmd(struct broadsheetfb_par *par, u16 data) | 126 | static void broadsheet_gpio_issue_cmd(struct broadsheetfb_par *par, u16 data) |
73 | { | 127 | { |
74 | par->board->set_ctl(par, BS_DC, 0); | 128 | par->board->set_ctl(par, BS_DC, 0); |
75 | broadsheet_issue_data(par, data); | 129 | broadsheet_gpio_issue_data(par, data); |
76 | } | 130 | } |
77 | 131 | ||
78 | static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data) | 132 | static void broadsheet_gpio_send_command(struct broadsheetfb_par *par, u16 data) |
79 | { | 133 | { |
80 | par->board->wait_for_rdy(par); | 134 | par->board->wait_for_rdy(par); |
81 | 135 | ||
82 | par->board->set_ctl(par, BS_CS, 0); | 136 | par->board->set_ctl(par, BS_CS, 0); |
83 | broadsheet_issue_cmd(par, data); | 137 | broadsheet_gpio_issue_cmd(par, data); |
84 | par->board->set_ctl(par, BS_DC, 1); | 138 | par->board->set_ctl(par, BS_DC, 1); |
85 | par->board->set_ctl(par, BS_CS, 1); | 139 | par->board->set_ctl(par, BS_CS, 1); |
86 | } | 140 | } |
87 | 141 | ||
88 | static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, | 142 | static void broadsheet_gpio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, |
89 | int argc, u16 *argv) | 143 | int argc, u16 *argv) |
90 | { | 144 | { |
91 | int i; | 145 | int i; |
@@ -93,15 +147,43 @@ static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, | |||
93 | par->board->wait_for_rdy(par); | 147 | par->board->wait_for_rdy(par); |
94 | 148 | ||
95 | par->board->set_ctl(par, BS_CS, 0); | 149 | par->board->set_ctl(par, BS_CS, 0); |
96 | broadsheet_issue_cmd(par, cmd); | 150 | broadsheet_gpio_issue_cmd(par, cmd); |
97 | par->board->set_ctl(par, BS_DC, 1); | 151 | par->board->set_ctl(par, BS_DC, 1); |
98 | 152 | ||
99 | for (i = 0; i < argc; i++) | 153 | for (i = 0; i < argc; i++) |
100 | broadsheet_issue_data(par, argv[i]); | 154 | broadsheet_gpio_issue_data(par, argv[i]); |
101 | par->board->set_ctl(par, BS_CS, 1); | 155 | par->board->set_ctl(par, BS_CS, 1); |
102 | } | 156 | } |
103 | 157 | ||
104 | static void broadsheet_burst_write(struct broadsheetfb_par *par, int size, | 158 | static void broadsheet_mmio_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, |
159 | int argc, u16 *argv) | ||
160 | { | ||
161 | int i; | ||
162 | |||
163 | par->board->mmio_write(par, BS_MMIO_CMD, cmd); | ||
164 | |||
165 | for (i = 0; i < argc; i++) | ||
166 | par->board->mmio_write(par, BS_MMIO_DATA, argv[i]); | ||
167 | } | ||
168 | |||
169 | static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data) | ||
170 | { | ||
171 | if (par->board->mmio_write) | ||
172 | par->board->mmio_write(par, BS_MMIO_CMD, data); | ||
173 | else | ||
174 | broadsheet_gpio_send_command(par, data); | ||
175 | } | ||
176 | |||
177 | static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd, | ||
178 | int argc, u16 *argv) | ||
179 | { | ||
180 | if (par->board->mmio_write) | ||
181 | broadsheet_mmio_send_cmdargs(par, cmd, argc, argv); | ||
182 | else | ||
183 | broadsheet_gpio_send_cmdargs(par, cmd, argc, argv); | ||
184 | } | ||
185 | |||
186 | static void broadsheet_gpio_burst_write(struct broadsheetfb_par *par, int size, | ||
105 | u16 *data) | 187 | u16 *data) |
106 | { | 188 | { |
107 | int i; | 189 | int i; |
@@ -121,7 +203,30 @@ static void broadsheet_burst_write(struct broadsheetfb_par *par, int size, | |||
121 | par->board->set_ctl(par, BS_CS, 1); | 203 | par->board->set_ctl(par, BS_CS, 1); |
122 | } | 204 | } |
123 | 205 | ||
124 | static u16 broadsheet_get_data(struct broadsheetfb_par *par) | 206 | static void broadsheet_mmio_burst_write(struct broadsheetfb_par *par, int size, |
207 | u16 *data) | ||
208 | { | ||
209 | int i; | ||
210 | u16 tmp; | ||
211 | |||
212 | for (i = 0; i < size; i++) { | ||
213 | tmp = (data[i] & 0x0F) << 4; | ||
214 | tmp |= (data[i] & 0x0F00) << 4; | ||
215 | par->board->mmio_write(par, BS_MMIO_DATA, tmp); | ||
216 | } | ||
217 | |||
218 | } | ||
219 | |||
220 | static void broadsheet_burst_write(struct broadsheetfb_par *par, int size, | ||
221 | u16 *data) | ||
222 | { | ||
223 | if (par->board->mmio_write) | ||
224 | broadsheet_mmio_burst_write(par, size, data); | ||
225 | else | ||
226 | broadsheet_gpio_burst_write(par, size, data); | ||
227 | } | ||
228 | |||
229 | static u16 broadsheet_gpio_get_data(struct broadsheetfb_par *par) | ||
125 | { | 230 | { |
126 | u16 res; | 231 | u16 res; |
127 | /* wait for ready to go hi. (lo is busy) */ | 232 | /* wait for ready to go hi. (lo is busy) */ |
@@ -141,7 +246,16 @@ static u16 broadsheet_get_data(struct broadsheetfb_par *par) | |||
141 | return res; | 246 | return res; |
142 | } | 247 | } |
143 | 248 | ||
144 | static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg, | 249 | |
250 | static u16 broadsheet_get_data(struct broadsheetfb_par *par) | ||
251 | { | ||
252 | if (par->board->mmio_read) | ||
253 | return par->board->mmio_read(par); | ||
254 | else | ||
255 | return broadsheet_gpio_get_data(par); | ||
256 | } | ||
257 | |||
258 | static void broadsheet_gpio_write_reg(struct broadsheetfb_par *par, u16 reg, | ||
145 | u16 data) | 259 | u16 data) |
146 | { | 260 | { |
147 | /* wait for ready to go hi. (lo is busy) */ | 261 | /* wait for ready to go hi. (lo is busy) */ |
@@ -150,44 +264,541 @@ static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg, | |||
150 | /* cs lo, dc lo for cmd, we lo for each data, db as usual */ | 264 | /* cs lo, dc lo for cmd, we lo for each data, db as usual */ |
151 | par->board->set_ctl(par, BS_CS, 0); | 265 | par->board->set_ctl(par, BS_CS, 0); |
152 | 266 | ||
153 | broadsheet_issue_cmd(par, BS_CMD_WR_REG); | 267 | broadsheet_gpio_issue_cmd(par, BS_CMD_WR_REG); |
154 | 268 | ||
155 | par->board->set_ctl(par, BS_DC, 1); | 269 | par->board->set_ctl(par, BS_DC, 1); |
156 | 270 | ||
157 | broadsheet_issue_data(par, reg); | 271 | broadsheet_gpio_issue_data(par, reg); |
158 | broadsheet_issue_data(par, data); | 272 | broadsheet_gpio_issue_data(par, data); |
159 | 273 | ||
160 | par->board->set_ctl(par, BS_CS, 1); | 274 | par->board->set_ctl(par, BS_CS, 1); |
161 | } | 275 | } |
162 | 276 | ||
277 | static void broadsheet_mmio_write_reg(struct broadsheetfb_par *par, u16 reg, | ||
278 | u16 data) | ||
279 | { | ||
280 | par->board->mmio_write(par, BS_MMIO_CMD, BS_CMD_WR_REG); | ||
281 | par->board->mmio_write(par, BS_MMIO_DATA, reg); | ||
282 | par->board->mmio_write(par, BS_MMIO_DATA, data); | ||
283 | |||
284 | } | ||
285 | |||
286 | static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg, | ||
287 | u16 data) | ||
288 | { | ||
289 | if (par->board->mmio_write) | ||
290 | broadsheet_mmio_write_reg(par, reg, data); | ||
291 | else | ||
292 | broadsheet_gpio_write_reg(par, reg, data); | ||
293 | } | ||
294 | |||
295 | static void broadsheet_write_reg32(struct broadsheetfb_par *par, u16 reg, | ||
296 | u32 data) | ||
297 | { | ||
298 | broadsheet_write_reg(par, reg, cpu_to_le32(data) & 0xFFFF); | ||
299 | broadsheet_write_reg(par, reg + 2, (cpu_to_le32(data) >> 16) & 0xFFFF); | ||
300 | } | ||
301 | |||
302 | |||
163 | static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) | 303 | static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg) |
164 | { | 304 | { |
165 | broadsheet_send_command(par, reg); | 305 | broadsheet_send_cmdargs(par, BS_CMD_RD_REG, 1, ®); |
166 | msleep(100); | 306 | par->board->wait_for_rdy(par); |
167 | return broadsheet_get_data(par); | 307 | return broadsheet_get_data(par); |
168 | } | 308 | } |
169 | 309 | ||
310 | /* functions for waveform manipulation */ | ||
311 | static int is_broadsheet_pll_locked(struct broadsheetfb_par *par) | ||
312 | { | ||
313 | return broadsheet_read_reg(par, 0x000A) & 0x0001; | ||
314 | } | ||
315 | |||
316 | static int broadsheet_setup_plls(struct broadsheetfb_par *par) | ||
317 | { | ||
318 | int retry_count = 0; | ||
319 | u16 tmp; | ||
320 | |||
321 | /* disable arral saemipu mode */ | ||
322 | broadsheet_write_reg(par, 0x0006, 0x0000); | ||
323 | |||
324 | broadsheet_write_reg(par, 0x0010, 0x0004); | ||
325 | broadsheet_write_reg(par, 0x0012, 0x5949); | ||
326 | broadsheet_write_reg(par, 0x0014, 0x0040); | ||
327 | broadsheet_write_reg(par, 0x0016, 0x0000); | ||
328 | |||
329 | do { | ||
330 | if (retry_count++ > 100) | ||
331 | return -ETIMEDOUT; | ||
332 | mdelay(1); | ||
333 | } while (!is_broadsheet_pll_locked(par)); | ||
334 | |||
335 | tmp = broadsheet_read_reg(par, 0x0006); | ||
336 | tmp &= ~0x1; | ||
337 | broadsheet_write_reg(par, 0x0006, tmp); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int broadsheet_setup_spi(struct broadsheetfb_par *par) | ||
343 | { | ||
344 | |||
345 | broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1)); | ||
346 | broadsheet_write_reg(par, 0x0208, 0x0001); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int broadsheet_setup_spiflash(struct broadsheetfb_par *par, | ||
352 | u16 *orig_sfmcd) | ||
353 | { | ||
354 | |||
355 | *orig_sfmcd = broadsheet_read_reg(par, 0x0204); | ||
356 | broadsheet_write_reg(par, 0x0208, 0); | ||
357 | broadsheet_write_reg(par, 0x0204, 0); | ||
358 | broadsheet_write_reg(par, 0x0204, ((3 << 3) | 1)); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int broadsheet_spiflash_wait_for_bit(struct broadsheetfb_par *par, | ||
364 | u16 reg, int bitnum, int val, | ||
365 | int timeout) | ||
366 | { | ||
367 | u16 tmp; | ||
368 | |||
369 | do { | ||
370 | tmp = broadsheet_read_reg(par, reg); | ||
371 | if (((tmp >> bitnum) & 1) == val) | ||
372 | return 0; | ||
373 | mdelay(1); | ||
374 | } while (timeout--); | ||
375 | |||
376 | return -ETIMEDOUT; | ||
377 | } | ||
378 | |||
379 | static int broadsheet_spiflash_write_byte(struct broadsheetfb_par *par, u8 data) | ||
380 | { | ||
381 | broadsheet_write_reg(par, 0x0202, (data | 0x100)); | ||
382 | |||
383 | return broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100); | ||
384 | } | ||
385 | |||
386 | static int broadsheet_spiflash_read_byte(struct broadsheetfb_par *par, u8 *data) | ||
387 | { | ||
388 | int err; | ||
389 | u16 tmp; | ||
390 | |||
391 | broadsheet_write_reg(par, 0x0202, 0); | ||
392 | |||
393 | err = broadsheet_spiflash_wait_for_bit(par, 0x0206, 3, 0, 100); | ||
394 | if (err) | ||
395 | return err; | ||
396 | |||
397 | tmp = broadsheet_read_reg(par, 0x200); | ||
398 | |||
399 | *data = tmp & 0xFF; | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static int broadsheet_spiflash_wait_for_status(struct broadsheetfb_par *par, | ||
405 | int timeout) | ||
406 | { | ||
407 | u8 tmp; | ||
408 | int err; | ||
409 | |||
410 | do { | ||
411 | broadsheet_write_reg(par, 0x0208, 1); | ||
412 | |||
413 | err = broadsheet_spiflash_write_byte(par, 0x05); | ||
414 | if (err) | ||
415 | goto failout; | ||
416 | |||
417 | err = broadsheet_spiflash_read_byte(par, &tmp); | ||
418 | if (err) | ||
419 | goto failout; | ||
420 | |||
421 | broadsheet_write_reg(par, 0x0208, 0); | ||
422 | |||
423 | if (!(tmp & 0x1)) | ||
424 | return 0; | ||
425 | |||
426 | mdelay(5); | ||
427 | } while (timeout--); | ||
428 | |||
429 | dev_err(par->info->device, "Timed out waiting for spiflash status\n"); | ||
430 | return -ETIMEDOUT; | ||
431 | |||
432 | failout: | ||
433 | broadsheet_write_reg(par, 0x0208, 0); | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | static int broadsheet_spiflash_op_on_address(struct broadsheetfb_par *par, | ||
438 | u8 op, u32 addr) | ||
439 | { | ||
440 | int i; | ||
441 | u8 tmp; | ||
442 | int err; | ||
443 | |||
444 | broadsheet_write_reg(par, 0x0208, 1); | ||
445 | |||
446 | err = broadsheet_spiflash_write_byte(par, op); | ||
447 | if (err) | ||
448 | return err; | ||
449 | |||
450 | for (i = 2; i >= 0; i--) { | ||
451 | tmp = ((addr >> (i * 8)) & 0xFF); | ||
452 | err = broadsheet_spiflash_write_byte(par, tmp); | ||
453 | if (err) | ||
454 | return err; | ||
455 | } | ||
456 | |||
457 | return err; | ||
458 | } | ||
459 | |||
460 | static int broadsheet_verify_spiflash(struct broadsheetfb_par *par, | ||
461 | int *flash_type) | ||
462 | { | ||
463 | int err = 0; | ||
464 | u8 sig; | ||
465 | |||
466 | err = broadsheet_spiflash_op_on_address(par, 0xAB, 0x00000000); | ||
467 | if (err) | ||
468 | goto failout; | ||
469 | |||
470 | err = broadsheet_spiflash_read_byte(par, &sig); | ||
471 | if (err) | ||
472 | goto failout; | ||
473 | |||
474 | if ((sig != 0x10) && (sig != 0x11)) { | ||
475 | dev_err(par->info->device, "Unexpected flash type\n"); | ||
476 | err = -EINVAL; | ||
477 | goto failout; | ||
478 | } | ||
479 | |||
480 | *flash_type = sig; | ||
481 | |||
482 | failout: | ||
483 | broadsheet_write_reg(par, 0x0208, 0); | ||
484 | return err; | ||
485 | } | ||
486 | |||
487 | static int broadsheet_setup_for_wfm_write(struct broadsheetfb_par *par, | ||
488 | u16 *initial_sfmcd, int *flash_type) | ||
489 | |||
490 | { | ||
491 | int err; | ||
492 | |||
493 | err = broadsheet_setup_plls(par); | ||
494 | if (err) | ||
495 | return err; | ||
496 | |||
497 | broadsheet_write_reg(par, 0x0106, 0x0203); | ||
498 | |||
499 | err = broadsheet_setup_spi(par); | ||
500 | if (err) | ||
501 | return err; | ||
502 | |||
503 | err = broadsheet_setup_spiflash(par, initial_sfmcd); | ||
504 | if (err) | ||
505 | return err; | ||
506 | |||
507 | return broadsheet_verify_spiflash(par, flash_type); | ||
508 | } | ||
509 | |||
510 | static int broadsheet_spiflash_write_control(struct broadsheetfb_par *par, | ||
511 | int mode) | ||
512 | { | ||
513 | int err; | ||
514 | |||
515 | broadsheet_write_reg(par, 0x0208, 1); | ||
516 | if (mode) | ||
517 | err = broadsheet_spiflash_write_byte(par, 0x06); | ||
518 | else | ||
519 | err = broadsheet_spiflash_write_byte(par, 0x04); | ||
520 | |||
521 | broadsheet_write_reg(par, 0x0208, 0); | ||
522 | return err; | ||
523 | } | ||
524 | |||
525 | static int broadsheet_spiflash_erase_sector(struct broadsheetfb_par *par, | ||
526 | int addr) | ||
527 | { | ||
528 | int err; | ||
529 | |||
530 | broadsheet_spiflash_write_control(par, 1); | ||
531 | |||
532 | err = broadsheet_spiflash_op_on_address(par, 0xD8, addr); | ||
533 | |||
534 | broadsheet_write_reg(par, 0x0208, 0); | ||
535 | |||
536 | if (err) | ||
537 | return err; | ||
538 | |||
539 | err = broadsheet_spiflash_wait_for_status(par, 1000); | ||
540 | |||
541 | return err; | ||
542 | } | ||
543 | |||
544 | static int broadsheet_spiflash_read_range(struct broadsheetfb_par *par, | ||
545 | int addr, int size, char *data) | ||
546 | { | ||
547 | int err; | ||
548 | int i; | ||
549 | |||
550 | err = broadsheet_spiflash_op_on_address(par, 0x03, addr); | ||
551 | if (err) | ||
552 | goto failout; | ||
553 | |||
554 | for (i = 0; i < size; i++) { | ||
555 | err = broadsheet_spiflash_read_byte(par, &data[i]); | ||
556 | if (err) | ||
557 | goto failout; | ||
558 | } | ||
559 | |||
560 | failout: | ||
561 | broadsheet_write_reg(par, 0x0208, 0); | ||
562 | return err; | ||
563 | } | ||
564 | |||
565 | #define BS_SPIFLASH_PAGE_SIZE 256 | ||
566 | static int broadsheet_spiflash_write_page(struct broadsheetfb_par *par, | ||
567 | int addr, const char *data) | ||
568 | { | ||
569 | int err; | ||
570 | int i; | ||
571 | |||
572 | broadsheet_spiflash_write_control(par, 1); | ||
573 | |||
574 | err = broadsheet_spiflash_op_on_address(par, 0x02, addr); | ||
575 | if (err) | ||
576 | goto failout; | ||
577 | |||
578 | for (i = 0; i < BS_SPIFLASH_PAGE_SIZE; i++) { | ||
579 | err = broadsheet_spiflash_write_byte(par, data[i]); | ||
580 | if (err) | ||
581 | goto failout; | ||
582 | } | ||
583 | |||
584 | broadsheet_write_reg(par, 0x0208, 0); | ||
585 | |||
586 | err = broadsheet_spiflash_wait_for_status(par, 100); | ||
587 | |||
588 | failout: | ||
589 | return err; | ||
590 | } | ||
591 | |||
592 | static int broadsheet_spiflash_write_sector(struct broadsheetfb_par *par, | ||
593 | int addr, const char *data, int sector_size) | ||
594 | { | ||
595 | int i; | ||
596 | int err; | ||
597 | |||
598 | for (i = 0; i < sector_size; i += BS_SPIFLASH_PAGE_SIZE) { | ||
599 | err = broadsheet_spiflash_write_page(par, addr + i, &data[i]); | ||
600 | if (err) | ||
601 | return err; | ||
602 | } | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * The caller must guarantee that the data to be rewritten is entirely | ||
608 | * contained within this sector. That is, data_start_addr + data_len | ||
609 | * must be less than sector_start_addr + sector_size. | ||
610 | */ | ||
611 | static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, | ||
612 | int sector_size, int data_start_addr, | ||
613 | int data_len, const char *data) | ||
614 | { | ||
615 | int err; | ||
616 | char *sector_buffer; | ||
617 | int tail_start_addr; | ||
618 | int start_sector_addr; | ||
619 | |||
620 | sector_buffer = kzalloc(sizeof(char)*sector_size, GFP_KERNEL); | ||
621 | if (!sector_buffer) | ||
622 | return -ENOMEM; | ||
623 | |||
624 | /* the start address of the sector is the 0th byte of that sector */ | ||
625 | start_sector_addr = (data_start_addr / sector_size) * sector_size; | ||
626 | |||
627 | /* | ||
628 | * check if there is head data that we need to readback into our sector | ||
629 | * buffer first | ||
630 | */ | ||
631 | if (data_start_addr != start_sector_addr) { | ||
632 | /* | ||
633 | * we need to read every byte up till the start address of our | ||
634 | * data and we put it into our sector buffer. | ||
635 | */ | ||
636 | err = broadsheet_spiflash_read_range(par, start_sector_addr, | ||
637 | data_start_addr, sector_buffer); | ||
638 | if (err) | ||
639 | return err; | ||
640 | } | ||
641 | |||
642 | /* now we copy our data into the right place in the sector buffer */ | ||
643 | memcpy(sector_buffer + data_start_addr, data, data_len); | ||
644 | |||
645 | /* | ||
646 | * now we check if there is a tail section of the sector that we need to | ||
647 | * readback. | ||
648 | */ | ||
649 | tail_start_addr = (data_start_addr + data_len) % sector_size; | ||
650 | |||
651 | if (tail_start_addr) { | ||
652 | int tail_len; | ||
653 | |||
654 | tail_len = sector_size - tail_start_addr; | ||
655 | |||
656 | /* now we read this tail into our sector buffer */ | ||
657 | err = broadsheet_spiflash_read_range(par, tail_start_addr, | ||
658 | tail_len, sector_buffer + tail_start_addr); | ||
659 | if (err) | ||
660 | return err; | ||
661 | } | ||
662 | |||
663 | /* if we got here we have the full sector that we want to rewrite. */ | ||
664 | |||
665 | /* first erase the sector */ | ||
666 | err = broadsheet_spiflash_erase_sector(par, start_sector_addr); | ||
667 | if (err) | ||
668 | return err; | ||
669 | |||
670 | /* now write it */ | ||
671 | err = broadsheet_spiflash_write_sector(par, start_sector_addr, | ||
672 | sector_buffer, sector_size); | ||
673 | return err; | ||
674 | } | ||
675 | |||
676 | static int broadsheet_write_spiflash(struct broadsheetfb_par *par, u32 wfm_addr, | ||
677 | const u8 *wfm, int bytecount, int flash_type) | ||
678 | { | ||
679 | int sector_size; | ||
680 | int err; | ||
681 | int cur_addr; | ||
682 | int writecount; | ||
683 | int maxlen; | ||
684 | int offset = 0; | ||
685 | |||
686 | switch (flash_type) { | ||
687 | case 0x10: | ||
688 | sector_size = 32*1024; | ||
689 | break; | ||
690 | case 0x11: | ||
691 | default: | ||
692 | sector_size = 64*1024; | ||
693 | break; | ||
694 | } | ||
695 | |||
696 | while (bytecount) { | ||
697 | cur_addr = wfm_addr + offset; | ||
698 | maxlen = roundup(cur_addr, sector_size) - cur_addr; | ||
699 | writecount = min(bytecount, maxlen); | ||
700 | |||
701 | err = broadsheet_spiflash_rewrite_sector(par, sector_size, | ||
702 | cur_addr, writecount, wfm + offset); | ||
703 | if (err) | ||
704 | return err; | ||
705 | |||
706 | offset += writecount; | ||
707 | bytecount -= writecount; | ||
708 | } | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int broadsheet_store_waveform_to_spiflash(struct broadsheetfb_par *par, | ||
714 | const u8 *wfm, size_t wfm_size) | ||
715 | { | ||
716 | int err = 0; | ||
717 | u16 initial_sfmcd = 0; | ||
718 | int flash_type = 0; | ||
719 | |||
720 | err = broadsheet_setup_for_wfm_write(par, &initial_sfmcd, &flash_type); | ||
721 | if (err) | ||
722 | goto failout; | ||
723 | |||
724 | err = broadsheet_write_spiflash(par, 0x886, wfm, wfm_size, flash_type); | ||
725 | |||
726 | failout: | ||
727 | broadsheet_write_reg(par, 0x0204, initial_sfmcd); | ||
728 | return err; | ||
729 | } | ||
730 | |||
731 | static ssize_t broadsheet_loadstore_waveform(struct device *dev, | ||
732 | struct device_attribute *attr, | ||
733 | const char *buf, size_t len) | ||
734 | { | ||
735 | int err; | ||
736 | struct fb_info *info = dev_get_drvdata(dev); | ||
737 | struct broadsheetfb_par *par = info->par; | ||
738 | const struct firmware *fw_entry; | ||
739 | |||
740 | if (len < 1) | ||
741 | return -EINVAL; | ||
742 | |||
743 | err = request_firmware(&fw_entry, "broadsheet.wbf", dev); | ||
744 | if (err < 0) { | ||
745 | dev_err(dev, "Failed to get broadsheet waveform\n"); | ||
746 | goto err_failed; | ||
747 | } | ||
748 | |||
749 | /* try to enforce reasonable min max on waveform */ | ||
750 | if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) { | ||
751 | dev_err(dev, "Invalid waveform\n"); | ||
752 | err = -EINVAL; | ||
753 | goto err_failed; | ||
754 | } | ||
755 | |||
756 | mutex_lock(&(par->io_lock)); | ||
757 | err = broadsheet_store_waveform_to_spiflash(par, fw_entry->data, | ||
758 | fw_entry->size); | ||
759 | |||
760 | mutex_unlock(&(par->io_lock)); | ||
761 | if (err < 0) { | ||
762 | dev_err(dev, "Failed to store broadsheet waveform\n"); | ||
763 | goto err_failed; | ||
764 | } | ||
765 | |||
766 | dev_info(dev, "Stored broadsheet waveform, size %zd\n", fw_entry->size); | ||
767 | |||
768 | return len; | ||
769 | |||
770 | err_failed: | ||
771 | return err; | ||
772 | } | ||
773 | static DEVICE_ATTR(loadstore_waveform, S_IWUSR, NULL, | ||
774 | broadsheet_loadstore_waveform); | ||
775 | |||
776 | /* upper level functions that manipulate the display and other stuff */ | ||
170 | static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) | 777 | static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) |
171 | { | 778 | { |
172 | u16 args[5]; | 779 | u16 args[5]; |
173 | 780 | int xres = par->info->var.xres; | |
174 | args[0] = DPY_W; | 781 | int yres = par->info->var.yres; |
175 | args[1] = DPY_H; | 782 | |
176 | args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */ | 783 | args[0] = panel_table[par->panel_index].w; |
177 | args[3] = 2; /* gdrv cfg */ | 784 | args[1] = panel_table[par->panel_index].h; |
178 | args[4] = (4 | (1 << 7)); /* lut index format */ | 785 | args[2] = panel_table[par->panel_index].sdcfg; |
786 | args[3] = panel_table[par->panel_index].gdcfg; | ||
787 | args[4] = panel_table[par->panel_index].lutfmt; | ||
179 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); | 788 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); |
180 | 789 | ||
181 | /* did the controller really set it? */ | 790 | /* did the controller really set it? */ |
182 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); | 791 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args); |
183 | 792 | ||
184 | args[0] = 4; /* fsync len */ | 793 | args[0] = panel_table[par->panel_index].fsynclen; |
185 | args[1] = (10 << 8) | 4; /* fend/fbegin len */ | 794 | args[1] = panel_table[par->panel_index].fendfbegin; |
186 | args[2] = 10; /* line sync len */ | 795 | args[2] = panel_table[par->panel_index].lsynclen; |
187 | args[3] = (100 << 8) | 4; /* line end/begin len */ | 796 | args[3] = panel_table[par->panel_index].lendlbegin; |
188 | args[4] = 6; /* pixel clock cfg */ | 797 | args[4] = panel_table[par->panel_index].pixclk; |
189 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); | 798 | broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args); |
190 | 799 | ||
800 | broadsheet_write_reg32(par, 0x310, xres*yres*2); | ||
801 | |||
191 | /* setup waveform */ | 802 | /* setup waveform */ |
192 | args[0] = 0x886; | 803 | args[0] = 0x886; |
193 | args[1] = 0; | 804 | args[1] = 0; |
@@ -207,8 +818,9 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) | |||
207 | args[0] = 0x154; | 818 | args[0] = 0x154; |
208 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); | 819 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); |
209 | 820 | ||
210 | broadsheet_burst_write(par, DPY_W*DPY_H/2, | 821 | broadsheet_burst_write(par, (panel_table[par->panel_index].w * |
211 | (u16 *) par->info->screen_base); | 822 | panel_table[par->panel_index].h)/2, |
823 | (u16 *) par->info->screen_base); | ||
212 | 824 | ||
213 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); | 825 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); |
214 | 826 | ||
@@ -222,6 +834,21 @@ static void __devinit broadsheet_init_display(struct broadsheetfb_par *par) | |||
222 | par->board->wait_for_rdy(par); | 834 | par->board->wait_for_rdy(par); |
223 | } | 835 | } |
224 | 836 | ||
837 | static void __devinit broadsheet_identify(struct broadsheetfb_par *par) | ||
838 | { | ||
839 | u16 rev, prc; | ||
840 | struct device *dev = par->info->device; | ||
841 | |||
842 | rev = broadsheet_read_reg(par, BS_REG_REV); | ||
843 | prc = broadsheet_read_reg(par, BS_REG_PRC); | ||
844 | dev_info(dev, "Broadsheet Rev 0x%x, Product Code 0x%x\n", rev, prc); | ||
845 | |||
846 | if (prc != 0x0047) | ||
847 | dev_warn(dev, "Unrecognized Broadsheet Product Code\n"); | ||
848 | if (rev != 0x0100) | ||
849 | dev_warn(dev, "Unrecognized Broadsheet Revision\n"); | ||
850 | } | ||
851 | |||
225 | static void __devinit broadsheet_init(struct broadsheetfb_par *par) | 852 | static void __devinit broadsheet_init(struct broadsheetfb_par *par) |
226 | { | 853 | { |
227 | broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN); | 854 | broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN); |
@@ -236,6 +863,7 @@ static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par, | |||
236 | u16 args[5]; | 863 | u16 args[5]; |
237 | unsigned char *buf = (unsigned char *)par->info->screen_base; | 864 | unsigned char *buf = (unsigned char *)par->info->screen_base; |
238 | 865 | ||
866 | mutex_lock(&(par->io_lock)); | ||
239 | /* y1 must be a multiple of 4 so drop the lower bits */ | 867 | /* y1 must be a multiple of 4 so drop the lower bits */ |
240 | y1 &= 0xFFFC; | 868 | y1 &= 0xFFFC; |
241 | /* y2 must be a multiple of 4 , but - 1 so up the lower bits */ | 869 | /* y2 must be a multiple of 4 , but - 1 so up the lower bits */ |
@@ -265,6 +893,7 @@ static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par, | |||
265 | broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); | 893 | broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); |
266 | 894 | ||
267 | par->board->wait_for_rdy(par); | 895 | par->board->wait_for_rdy(par); |
896 | mutex_unlock(&(par->io_lock)); | ||
268 | 897 | ||
269 | } | 898 | } |
270 | 899 | ||
@@ -272,13 +901,15 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par) | |||
272 | { | 901 | { |
273 | u16 args[5]; | 902 | u16 args[5]; |
274 | 903 | ||
904 | mutex_lock(&(par->io_lock)); | ||
275 | args[0] = 0x3 << 4; | 905 | args[0] = 0x3 << 4; |
276 | broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args); | 906 | broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args); |
277 | 907 | ||
278 | args[0] = 0x154; | 908 | args[0] = 0x154; |
279 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); | 909 | broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args); |
280 | broadsheet_burst_write(par, DPY_W*DPY_H/2, | 910 | broadsheet_burst_write(par, (panel_table[par->panel_index].w * |
281 | (u16 *) par->info->screen_base); | 911 | panel_table[par->panel_index].h)/2, |
912 | (u16 *) par->info->screen_base); | ||
282 | 913 | ||
283 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); | 914 | broadsheet_send_command(par, BS_CMD_LD_IMG_END); |
284 | 915 | ||
@@ -290,7 +921,7 @@ static void broadsheetfb_dpy_update(struct broadsheetfb_par *par) | |||
290 | broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); | 921 | broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND); |
291 | 922 | ||
292 | par->board->wait_for_rdy(par); | 923 | par->board->wait_for_rdy(par); |
293 | 924 | mutex_unlock(&(par->io_lock)); | |
294 | } | 925 | } |
295 | 926 | ||
296 | /* this is called back from the deferred io workqueue */ | 927 | /* this is called back from the deferred io workqueue */ |
@@ -436,6 +1067,8 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
436 | unsigned char *videomemory; | 1067 | unsigned char *videomemory; |
437 | struct broadsheetfb_par *par; | 1068 | struct broadsheetfb_par *par; |
438 | int i; | 1069 | int i; |
1070 | int dpyw, dpyh; | ||
1071 | int panel_index; | ||
439 | 1072 | ||
440 | /* pick up board specific routines */ | 1073 | /* pick up board specific routines */ |
441 | board = dev->dev.platform_data; | 1074 | board = dev->dev.platform_data; |
@@ -450,7 +1083,24 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
450 | if (!info) | 1083 | if (!info) |
451 | goto err; | 1084 | goto err; |
452 | 1085 | ||
453 | videomemorysize = (DPY_W*DPY_H); | 1086 | switch (board->get_panel_type()) { |
1087 | case 37: | ||
1088 | panel_index = 1; | ||
1089 | break; | ||
1090 | case 97: | ||
1091 | panel_index = 2; | ||
1092 | break; | ||
1093 | case 6: | ||
1094 | default: | ||
1095 | panel_index = 0; | ||
1096 | break; | ||
1097 | } | ||
1098 | |||
1099 | dpyw = panel_table[panel_index].w; | ||
1100 | dpyh = panel_table[panel_index].h; | ||
1101 | |||
1102 | videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE); | ||
1103 | |||
454 | videomemory = vmalloc(videomemorysize); | 1104 | videomemory = vmalloc(videomemorysize); |
455 | if (!videomemory) | 1105 | if (!videomemory) |
456 | goto err_fb_rel; | 1106 | goto err_fb_rel; |
@@ -460,16 +1110,25 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
460 | info->screen_base = (char *)videomemory; | 1110 | info->screen_base = (char *)videomemory; |
461 | info->fbops = &broadsheetfb_ops; | 1111 | info->fbops = &broadsheetfb_ops; |
462 | 1112 | ||
1113 | broadsheetfb_var.xres = dpyw; | ||
1114 | broadsheetfb_var.yres = dpyh; | ||
1115 | broadsheetfb_var.xres_virtual = dpyw; | ||
1116 | broadsheetfb_var.yres_virtual = dpyh; | ||
463 | info->var = broadsheetfb_var; | 1117 | info->var = broadsheetfb_var; |
1118 | |||
1119 | broadsheetfb_fix.line_length = dpyw; | ||
464 | info->fix = broadsheetfb_fix; | 1120 | info->fix = broadsheetfb_fix; |
465 | info->fix.smem_len = videomemorysize; | 1121 | info->fix.smem_len = videomemorysize; |
466 | par = info->par; | 1122 | par = info->par; |
1123 | par->panel_index = panel_index; | ||
467 | par->info = info; | 1124 | par->info = info; |
468 | par->board = board; | 1125 | par->board = board; |
469 | par->write_reg = broadsheet_write_reg; | 1126 | par->write_reg = broadsheet_write_reg; |
470 | par->read_reg = broadsheet_read_reg; | 1127 | par->read_reg = broadsheet_read_reg; |
471 | init_waitqueue_head(&par->waitq); | 1128 | init_waitqueue_head(&par->waitq); |
472 | 1129 | ||
1130 | mutex_init(&par->io_lock); | ||
1131 | |||
473 | info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; | 1132 | info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; |
474 | 1133 | ||
475 | info->fbdefio = &broadsheetfb_defio; | 1134 | info->fbdefio = &broadsheetfb_defio; |
@@ -496,13 +1155,20 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
496 | if (retval < 0) | 1155 | if (retval < 0) |
497 | goto err_free_irq; | 1156 | goto err_free_irq; |
498 | 1157 | ||
1158 | broadsheet_identify(par); | ||
1159 | |||
499 | broadsheet_init(par); | 1160 | broadsheet_init(par); |
500 | 1161 | ||
501 | retval = register_framebuffer(info); | 1162 | retval = register_framebuffer(info); |
502 | if (retval < 0) | 1163 | if (retval < 0) |
503 | goto err_free_irq; | 1164 | goto err_free_irq; |
1165 | |||
504 | platform_set_drvdata(dev, info); | 1166 | platform_set_drvdata(dev, info); |
505 | 1167 | ||
1168 | retval = device_create_file(&dev->dev, &dev_attr_loadstore_waveform); | ||
1169 | if (retval < 0) | ||
1170 | goto err_unreg_fb; | ||
1171 | |||
506 | printk(KERN_INFO | 1172 | printk(KERN_INFO |
507 | "fb%d: Broadsheet frame buffer, using %dK of video memory\n", | 1173 | "fb%d: Broadsheet frame buffer, using %dK of video memory\n", |
508 | info->node, videomemorysize >> 10); | 1174 | info->node, videomemorysize >> 10); |
@@ -510,6 +1176,8 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) | |||
510 | 1176 | ||
511 | return 0; | 1177 | return 0; |
512 | 1178 | ||
1179 | err_unreg_fb: | ||
1180 | unregister_framebuffer(info); | ||
513 | err_free_irq: | 1181 | err_free_irq: |
514 | board->cleanup(par); | 1182 | board->cleanup(par); |
515 | err_cmap: | 1183 | err_cmap: |
@@ -530,6 +1198,8 @@ static int __devexit broadsheetfb_remove(struct platform_device *dev) | |||
530 | 1198 | ||
531 | if (info) { | 1199 | if (info) { |
532 | struct broadsheetfb_par *par = info->par; | 1200 | struct broadsheetfb_par *par = info->par; |
1201 | |||
1202 | device_remove_file(info->dev, &dev_attr_loadstore_waveform); | ||
533 | unregister_framebuffer(info); | 1203 | unregister_framebuffer(info); |
534 | fb_deferred_io_cleanup(info); | 1204 | fb_deferred_io_cleanup(info); |
535 | par->board->cleanup(par); | 1205 | par->board->cleanup(par); |
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c index 108b89e09a80..5eb61b5adfe8 100644 --- a/drivers/video/cobalt_lcdfb.c +++ b/drivers/video/cobalt_lcdfb.c | |||
@@ -287,7 +287,7 @@ static struct fb_ops cobalt_lcd_fbops = { | |||
287 | .fb_cursor = cobalt_lcdfb_cursor, | 287 | .fb_cursor = cobalt_lcdfb_cursor, |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static int __init cobalt_lcdfb_probe(struct platform_device *dev) | 290 | static int __devinit cobalt_lcdfb_probe(struct platform_device *dev) |
291 | { | 291 | { |
292 | struct fb_info *info; | 292 | struct fb_info *info; |
293 | struct resource *res; | 293 | struct resource *res; |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index d25df51bb0d2..581d2dbf675a 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -210,7 +210,7 @@ static int __init efifb_setup(char *options) | |||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | static int __init efifb_probe(struct platform_device *dev) | 213 | static int __devinit efifb_probe(struct platform_device *dev) |
214 | { | 214 | { |
215 | struct fb_info *info; | 215 | struct fb_info *info; |
216 | int err; | 216 | int err; |
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 2735b79e52a1..6d755bb3a2bc 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c | |||
@@ -602,7 +602,7 @@ static int epson1355fb_remove(struct platform_device *dev) | |||
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
605 | int __init epson1355fb_probe(struct platform_device *dev) | 605 | int __devinit epson1355fb_probe(struct platform_device *dev) |
606 | { | 606 | { |
607 | struct epson1355_par *default_par; | 607 | struct epson1355_par *default_par; |
608 | struct fb_info *info; | 608 | struct fb_info *info; |
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 695fa013fe7e..5643a35c1746 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c | |||
@@ -1128,7 +1128,7 @@ static int __init gbefb_setup(char *options) | |||
1128 | return 0; | 1128 | return 0; |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | static int __init gbefb_probe(struct platform_device *p_dev) | 1131 | static int __devinit gbefb_probe(struct platform_device *p_dev) |
1132 | { | 1132 | { |
1133 | int i, ret = 0; | 1133 | int i, ret = 0; |
1134 | struct fb_info *info; | 1134 | struct fb_info *info; |
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index 0129c044f6d6..db9b785b56eb 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c | |||
@@ -551,7 +551,7 @@ static struct fb_ops hgafb_ops = { | |||
551 | * Initialization | 551 | * Initialization |
552 | */ | 552 | */ |
553 | 553 | ||
554 | static int __init hgafb_probe(struct platform_device *pdev) | 554 | static int __devinit hgafb_probe(struct platform_device *pdev) |
555 | { | 555 | { |
556 | struct fb_info *info; | 556 | struct fb_info *info; |
557 | 557 | ||
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 73c83a8de2d3..bf78779199c6 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c | |||
@@ -325,7 +325,7 @@ static struct fb_ops hitfb_ops = { | |||
325 | .fb_imageblit = cfb_imageblit, | 325 | .fb_imageblit = cfb_imageblit, |
326 | }; | 326 | }; |
327 | 327 | ||
328 | static int __init hitfb_probe(struct platform_device *dev) | 328 | static int __devinit hitfb_probe(struct platform_device *dev) |
329 | { | 329 | { |
330 | unsigned short lcdclor, ldr3, ldvndr; | 330 | unsigned short lcdclor, ldr3, ldvndr; |
331 | struct fb_info *info; | 331 | struct fb_info *info; |
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index fabb0c59a211..8280a58a0e55 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
@@ -31,15 +31,6 @@ | |||
31 | #define CARMINE_MEM_SIZE 0x8000000 | 31 | #define CARMINE_MEM_SIZE 0x8000000 |
32 | #define DRV_NAME "mb862xxfb" | 32 | #define DRV_NAME "mb862xxfb" |
33 | 33 | ||
34 | #if defined(CONFIG_LWMON5) | ||
35 | static struct mb862xx_gc_mode lwmon5_gc_mode = { | ||
36 | /* Mode for Sharp LQ104V1DG61 TFT LCD Panel */ | ||
37 | { "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 }, | ||
38 | /* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */ | ||
39 | 16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2 | ||
40 | }; | ||
41 | #endif | ||
42 | |||
43 | #if defined(CONFIG_SOCRATES) | 34 | #if defined(CONFIG_SOCRATES) |
44 | static struct mb862xx_gc_mode socrates_gc_mode = { | 35 | static struct mb862xx_gc_mode socrates_gc_mode = { |
45 | /* Mode for Prime View PM070WL4 TFT LCD Panel */ | 36 | /* Mode for Prime View PM070WL4 TFT LCD Panel */ |
@@ -600,10 +591,6 @@ static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, | |||
600 | goto irqdisp; | 591 | goto irqdisp; |
601 | } | 592 | } |
602 | 593 | ||
603 | #if defined(CONFIG_LWMON5) | ||
604 | par->gc_mode = &lwmon5_gc_mode; | ||
605 | #endif | ||
606 | |||
607 | #if defined(CONFIG_SOCRATES) | 594 | #if defined(CONFIG_SOCRATES) |
608 | par->gc_mode = &socrates_gc_mode; | 595 | par->gc_mode = &socrates_gc_mode; |
609 | #endif | 596 | #endif |
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 01f77bcc68f9..afea9abbd678 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c | |||
@@ -693,7 +693,7 @@ static void __devinit setup_memc(struct fb_info *fbi) | |||
693 | unsigned long tmp; | 693 | unsigned long tmp; |
694 | int i; | 694 | int i; |
695 | 695 | ||
696 | /* FIXME: use platfrom specific parameters */ | 696 | /* FIXME: use platform specific parameters */ |
697 | /* setup SDRAM controller */ | 697 | /* setup SDRAM controller */ |
698 | write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | | 698 | write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | |
699 | LMCFG_LMA_TS), | 699 | LMCFG_LMA_TS), |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0129f1bc3522..b895aae41630 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -893,7 +893,7 @@ const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var, | |||
893 | } | 893 | } |
894 | 894 | ||
895 | /** | 895 | /** |
896 | * fb_add_videomode: adds videomode entry to modelist | 896 | * fb_add_videomode - adds videomode entry to modelist |
897 | * @mode: videomode to add | 897 | * @mode: videomode to add |
898 | * @head: struct list_head of modelist | 898 | * @head: struct list_head of modelist |
899 | * | 899 | * |
@@ -928,7 +928,7 @@ int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head) | |||
928 | } | 928 | } |
929 | 929 | ||
930 | /** | 930 | /** |
931 | * fb_delete_videomode: removed videomode entry from modelist | 931 | * fb_delete_videomode - removed videomode entry from modelist |
932 | * @mode: videomode to remove | 932 | * @mode: videomode to remove |
933 | * @head: struct list_head of modelist | 933 | * @head: struct list_head of modelist |
934 | * | 934 | * |
@@ -953,7 +953,7 @@ void fb_delete_videomode(const struct fb_videomode *mode, | |||
953 | } | 953 | } |
954 | 954 | ||
955 | /** | 955 | /** |
956 | * fb_destroy_modelist: destroy modelist | 956 | * fb_destroy_modelist - destroy modelist |
957 | * @head: struct list_head of modelist | 957 | * @head: struct list_head of modelist |
958 | */ | 958 | */ |
959 | void fb_destroy_modelist(struct list_head *head) | 959 | void fb_destroy_modelist(struct list_head *head) |
@@ -968,7 +968,7 @@ void fb_destroy_modelist(struct list_head *head) | |||
968 | EXPORT_SYMBOL_GPL(fb_destroy_modelist); | 968 | EXPORT_SYMBOL_GPL(fb_destroy_modelist); |
969 | 969 | ||
970 | /** | 970 | /** |
971 | * fb_videomode_to_modelist: convert mode array to mode list | 971 | * fb_videomode_to_modelist - convert mode array to mode list |
972 | * @modedb: array of struct fb_videomode | 972 | * @modedb: array of struct fb_videomode |
973 | * @num: number of entries in array | 973 | * @num: number of entries in array |
974 | * @head: struct list_head of modelist | 974 | * @head: struct list_head of modelist |
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c new file mode 100644 index 000000000000..6bf0d460a738 --- /dev/null +++ b/drivers/video/nuc900fb.c | |||
@@ -0,0 +1,779 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright (c) 2009 Nuvoton technology corporation | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * Description: | ||
12 | * Nuvoton LCD Controller Driver | ||
13 | * Author: | ||
14 | * Wang Qiang (rurality.linux@gmail.com) 2009/12/11 | ||
15 | */ | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <linux/tty.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/fb.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/workqueue.h> | ||
29 | #include <linux/wait.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/clk.h> | ||
32 | #include <linux/cpufreq.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <linux/pm.h> | ||
35 | #include <linux/device.h> | ||
36 | |||
37 | #include <mach/map.h> | ||
38 | #include <mach/regs-clock.h> | ||
39 | #include <mach/regs-ldm.h> | ||
40 | #include <mach/fb.h> | ||
41 | #include <mach/clkdev.h> | ||
42 | |||
43 | #include "nuc900fb.h" | ||
44 | |||
45 | |||
46 | /* | ||
47 | * Initialize the nuc900 video (dual) buffer address | ||
48 | */ | ||
49 | static void nuc900fb_set_lcdaddr(struct fb_info *info) | ||
50 | { | ||
51 | struct nuc900fb_info *fbi = info->par; | ||
52 | void __iomem *regs = fbi->io; | ||
53 | unsigned long vbaddr1, vbaddr2; | ||
54 | |||
55 | vbaddr1 = info->fix.smem_start; | ||
56 | vbaddr2 = info->fix.smem_start; | ||
57 | vbaddr2 += info->fix.line_length * info->var.yres; | ||
58 | |||
59 | /* set frambuffer start phy addr*/ | ||
60 | writel(vbaddr1, regs + REG_LCM_VA_BADDR0); | ||
61 | writel(vbaddr2, regs + REG_LCM_VA_BADDR1); | ||
62 | |||
63 | writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL); | ||
64 | writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE); | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * calculate divider for lcd div | ||
69 | */ | ||
70 | static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi, | ||
71 | unsigned long pixclk) | ||
72 | { | ||
73 | unsigned long clk = fbi->clk_rate; | ||
74 | unsigned long long div; | ||
75 | |||
76 | /* pixclk is in picseconds. our clock is in Hz*/ | ||
77 | /* div = (clk * pixclk)/10^12 */ | ||
78 | div = (unsigned long long)clk * pixclk; | ||
79 | div >>= 12; | ||
80 | do_div(div, 625 * 625UL * 625); | ||
81 | |||
82 | dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div); | ||
83 | |||
84 | return div; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Check the video params of 'var'. | ||
89 | */ | ||
90 | static int nuc900fb_check_var(struct fb_var_screeninfo *var, | ||
91 | struct fb_info *info) | ||
92 | { | ||
93 | struct nuc900fb_info *fbi = info->par; | ||
94 | struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data; | ||
95 | struct nuc900fb_display *display = NULL; | ||
96 | struct nuc900fb_display *default_display = mach_info->displays + | ||
97 | mach_info->default_display; | ||
98 | int i; | ||
99 | |||
100 | dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info); | ||
101 | |||
102 | /* validate x/y resolution */ | ||
103 | /* choose default mode if possible */ | ||
104 | if (var->xres == default_display->xres && | ||
105 | var->yres == default_display->yres && | ||
106 | var->bits_per_pixel == default_display->bpp) | ||
107 | display = default_display; | ||
108 | else | ||
109 | for (i = 0; i < mach_info->num_displays; i++) | ||
110 | if (var->xres == mach_info->displays[i].xres && | ||
111 | var->yres == mach_info->displays[i].yres && | ||
112 | var->bits_per_pixel == mach_info->displays[i].bpp) { | ||
113 | display = mach_info->displays + i; | ||
114 | break; | ||
115 | } | ||
116 | |||
117 | if (display == NULL) { | ||
118 | printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n", | ||
119 | var->xres, var->yres, var->bits_per_pixel); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* it should be the same size as the display */ | ||
124 | var->xres_virtual = display->xres; | ||
125 | var->yres_virtual = display->yres; | ||
126 | var->height = display->height; | ||
127 | var->width = display->width; | ||
128 | |||
129 | /* copy lcd settings */ | ||
130 | var->pixclock = display->pixclock; | ||
131 | var->left_margin = display->left_margin; | ||
132 | var->right_margin = display->right_margin; | ||
133 | var->upper_margin = display->upper_margin; | ||
134 | var->lower_margin = display->lower_margin; | ||
135 | var->vsync_len = display->vsync_len; | ||
136 | var->hsync_len = display->hsync_len; | ||
137 | |||
138 | var->transp.offset = 0; | ||
139 | var->transp.length = 0; | ||
140 | |||
141 | fbi->regs.lcd_dccs = display->dccs; | ||
142 | fbi->regs.lcd_device_ctrl = display->devctl; | ||
143 | fbi->regs.lcd_va_fbctrl = display->fbctrl; | ||
144 | fbi->regs.lcd_va_scale = display->scale; | ||
145 | |||
146 | /* set R/G/B possions */ | ||
147 | switch (var->bits_per_pixel) { | ||
148 | case 1: | ||
149 | case 2: | ||
150 | case 4: | ||
151 | case 8: | ||
152 | default: | ||
153 | var->red.offset = 0; | ||
154 | var->red.length = var->bits_per_pixel; | ||
155 | var->green = var->red; | ||
156 | var->blue = var->red; | ||
157 | break; | ||
158 | case 12: | ||
159 | var->red.length = 4; | ||
160 | var->green.length = 4; | ||
161 | var->blue.length = 4; | ||
162 | var->red.offset = 8; | ||
163 | var->green.offset = 4; | ||
164 | var->blue.offset = 0; | ||
165 | break; | ||
166 | case 16: | ||
167 | var->red.length = 5; | ||
168 | var->green.length = 6; | ||
169 | var->blue.length = 5; | ||
170 | var->red.offset = 11; | ||
171 | var->green.offset = 5; | ||
172 | var->blue.offset = 0; | ||
173 | break; | ||
174 | case 18: | ||
175 | var->red.length = 6; | ||
176 | var->green.length = 6; | ||
177 | var->blue.length = 6; | ||
178 | var->red.offset = 12; | ||
179 | var->green.offset = 6; | ||
180 | var->blue.offset = 0; | ||
181 | break; | ||
182 | case 32: | ||
183 | var->red.length = 8; | ||
184 | var->green.length = 8; | ||
185 | var->blue.length = 8; | ||
186 | var->red.offset = 16; | ||
187 | var->green.offset = 8; | ||
188 | var->blue.offset = 0; | ||
189 | break; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Calculate lcd register values from var setting & save into hw | ||
197 | */ | ||
198 | static void nuc900fb_calculate_lcd_regs(const struct fb_info *info, | ||
199 | struct nuc900fb_hw *regs) | ||
200 | { | ||
201 | const struct fb_var_screeninfo *var = &info->var; | ||
202 | int vtt = var->height + var->upper_margin + var->lower_margin; | ||
203 | int htt = var->width + var->left_margin + var->right_margin; | ||
204 | int hsync = var->width + var->right_margin; | ||
205 | int vsync = var->height + var->lower_margin; | ||
206 | |||
207 | regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) | | ||
208 | LCM_CRTC_SIZE_HTTVAL(htt); | ||
209 | regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) | | ||
210 | LCM_CRTC_DEND_HDENDVAL(var->width); | ||
211 | regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) | | ||
212 | LCM_CRTC_HR_SVAL(var->width + 1); | ||
213 | regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) | | ||
214 | LCM_CRTC_HSYNC_SVAL(hsync); | ||
215 | regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) | | ||
216 | LCM_CRTC_VR_SVAL(vsync); | ||
217 | |||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Activate (set) the controller from the given framebuffer | ||
222 | * information | ||
223 | */ | ||
224 | static void nuc900fb_activate_var(struct fb_info *info) | ||
225 | { | ||
226 | struct nuc900fb_info *fbi = info->par; | ||
227 | void __iomem *regs = fbi->io; | ||
228 | struct fb_var_screeninfo *var = &info->var; | ||
229 | int clkdiv; | ||
230 | |||
231 | clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1; | ||
232 | if (clkdiv < 0) | ||
233 | clkdiv = 0; | ||
234 | |||
235 | nuc900fb_calculate_lcd_regs(info, &fbi->regs); | ||
236 | |||
237 | /* set the new lcd registers*/ | ||
238 | |||
239 | dev_dbg(fbi->dev, "new lcd register set:\n"); | ||
240 | dev_dbg(fbi->dev, "dccs = 0x%08x\n", fbi->regs.lcd_dccs); | ||
241 | dev_dbg(fbi->dev, "dev_ctl = 0x%08x\n", fbi->regs.lcd_device_ctrl); | ||
242 | dev_dbg(fbi->dev, "crtc_size = 0x%08x\n", fbi->regs.lcd_crtc_size); | ||
243 | dev_dbg(fbi->dev, "crtc_dend = 0x%08x\n", fbi->regs.lcd_crtc_dend); | ||
244 | dev_dbg(fbi->dev, "crtc_hr = 0x%08x\n", fbi->regs.lcd_crtc_hr); | ||
245 | dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync); | ||
246 | dev_dbg(fbi->dev, "crtc_vr = 0x%08x\n", fbi->regs.lcd_crtc_vr); | ||
247 | |||
248 | writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL); | ||
249 | writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE); | ||
250 | writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND); | ||
251 | writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR); | ||
252 | writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC); | ||
253 | writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR); | ||
254 | |||
255 | /* set lcd address pointers */ | ||
256 | nuc900fb_set_lcdaddr(info); | ||
257 | |||
258 | writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS); | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Alters the hardware state. | ||
263 | * | ||
264 | */ | ||
265 | static int nuc900fb_set_par(struct fb_info *info) | ||
266 | { | ||
267 | struct fb_var_screeninfo *var = &info->var; | ||
268 | |||
269 | switch (var->bits_per_pixel) { | ||
270 | case 32: | ||
271 | case 24: | ||
272 | case 18: | ||
273 | case 16: | ||
274 | case 12: | ||
275 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
276 | break; | ||
277 | case 1: | ||
278 | info->fix.visual = FB_VISUAL_MONO01; | ||
279 | break; | ||
280 | default: | ||
281 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
282 | break; | ||
283 | } | ||
284 | |||
285 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; | ||
286 | |||
287 | /* activate this new configuration */ | ||
288 | nuc900fb_activate_var(info); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static inline unsigned int chan_to_field(unsigned int chan, | ||
293 | struct fb_bitfield *bf) | ||
294 | { | ||
295 | chan &= 0xffff; | ||
296 | chan >>= 16 - bf->length; | ||
297 | return chan << bf->offset; | ||
298 | } | ||
299 | |||
300 | static int nuc900fb_setcolreg(unsigned regno, | ||
301 | unsigned red, unsigned green, unsigned blue, | ||
302 | unsigned transp, struct fb_info *info) | ||
303 | { | ||
304 | unsigned int val; | ||
305 | |||
306 | switch (info->fix.visual) { | ||
307 | case FB_VISUAL_TRUECOLOR: | ||
308 | /* true-colour, use pseuo-palette */ | ||
309 | if (regno < 16) { | ||
310 | u32 *pal = info->pseudo_palette; | ||
311 | |||
312 | val = chan_to_field(red, &info->var.red); | ||
313 | val |= chan_to_field(green, &info->var.green); | ||
314 | val |= chan_to_field(blue, &info->var.blue); | ||
315 | pal[regno] = val; | ||
316 | } | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | return 1; /* unknown type */ | ||
321 | } | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | /** | ||
326 | * nuc900fb_blank | ||
327 | * | ||
328 | */ | ||
329 | static int nuc900fb_blank(int blank_mode, struct fb_info *info) | ||
330 | { | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static struct fb_ops nuc900fb_ops = { | ||
336 | .owner = THIS_MODULE, | ||
337 | .fb_check_var = nuc900fb_check_var, | ||
338 | .fb_set_par = nuc900fb_set_par, | ||
339 | .fb_blank = nuc900fb_blank, | ||
340 | .fb_setcolreg = nuc900fb_setcolreg, | ||
341 | .fb_fillrect = cfb_fillrect, | ||
342 | .fb_copyarea = cfb_copyarea, | ||
343 | .fb_imageblit = cfb_imageblit, | ||
344 | }; | ||
345 | |||
346 | |||
347 | static inline void modify_gpio(void __iomem *reg, | ||
348 | unsigned long set, unsigned long mask) | ||
349 | { | ||
350 | unsigned long tmp; | ||
351 | tmp = readl(reg) & ~mask; | ||
352 | writel(tmp | set, reg); | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * Initialise LCD-related registers | ||
357 | */ | ||
358 | static int nuc900fb_init_registers(struct fb_info *info) | ||
359 | { | ||
360 | struct nuc900fb_info *fbi = info->par; | ||
361 | struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data; | ||
362 | void __iomem *regs = fbi->io; | ||
363 | |||
364 | /*reset the display engine*/ | ||
365 | writel(0, regs + REG_LCM_DCCS); | ||
366 | writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST, | ||
367 | regs + REG_LCM_DCCS); | ||
368 | ndelay(100); | ||
369 | writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST), | ||
370 | regs + REG_LCM_DCCS); | ||
371 | ndelay(100); | ||
372 | |||
373 | writel(0, regs + REG_LCM_DEV_CTRL); | ||
374 | |||
375 | /* config gpio output */ | ||
376 | modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir, | ||
377 | mach_info->gpio_dir_mask); | ||
378 | modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data, | ||
379 | mach_info->gpio_data_mask); | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | |||
385 | /* | ||
386 | * Alloc the SDRAM region of NUC900 for the frame buffer. | ||
387 | * The buffer should be a non-cached, non-buffered, memory region | ||
388 | * to allow palette and pixel writes without flushing the cache. | ||
389 | */ | ||
390 | static int __init nuc900fb_map_video_memory(struct fb_info *info) | ||
391 | { | ||
392 | struct nuc900fb_info *fbi = info->par; | ||
393 | dma_addr_t map_dma; | ||
394 | unsigned long map_size = PAGE_ALIGN(info->fix.smem_len); | ||
395 | |||
396 | dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n", | ||
397 | fbi, map_size); | ||
398 | |||
399 | info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, | ||
400 | &map_dma, GFP_KERNEL); | ||
401 | |||
402 | if (!info->screen_base) | ||
403 | return -ENOMEM; | ||
404 | |||
405 | memset(info->screen_base, 0x00, map_size); | ||
406 | info->fix.smem_start = map_dma; | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static inline void nuc900fb_unmap_video_memory(struct fb_info *info) | ||
412 | { | ||
413 | struct nuc900fb_info *fbi = info->par; | ||
414 | dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len), | ||
415 | info->screen_base, info->fix.smem_start); | ||
416 | } | ||
417 | |||
418 | static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id) | ||
419 | { | ||
420 | struct nuc900fb_info *fbi = dev_id; | ||
421 | void __iomem *regs = fbi->io; | ||
422 | void __iomem *irq_base = fbi->irq_base; | ||
423 | unsigned long lcdirq = readl(regs + REG_LCM_INT_CS); | ||
424 | |||
425 | if (lcdirq & LCM_INT_CS_DISP_F_STATUS) { | ||
426 | writel(readl(irq_base) | 1<<30, irq_base); | ||
427 | |||
428 | /* wait VA_EN low */ | ||
429 | if ((readl(regs + REG_LCM_DCCS) & | ||
430 | LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE) | ||
431 | while ((readl(regs + REG_LCM_DCCS) & | ||
432 | LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN) | ||
433 | ; | ||
434 | /* display_out-enable */ | ||
435 | writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN, | ||
436 | regs + REG_LCM_DCCS); | ||
437 | /* va-enable*/ | ||
438 | writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN, | ||
439 | regs + REG_LCM_DCCS); | ||
440 | } else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) { | ||
441 | writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base); | ||
442 | } else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) { | ||
443 | writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base); | ||
444 | } | ||
445 | |||
446 | return IRQ_HANDLED; | ||
447 | } | ||
448 | |||
449 | #ifdef CONFIG_CPU_FREQ | ||
450 | |||
451 | static int nuc900fb_cpufreq_transition(struct notifier_block *nb, | ||
452 | unsigned long val, void *data) | ||
453 | { | ||
454 | struct nuc900fb_info *info; | ||
455 | struct fb_info *fbinfo; | ||
456 | long delta_f; | ||
457 | info = container_of(nb, struct nuc900fb_info, freq_transition); | ||
458 | fbinfo = platform_get_drvdata(to_platform_device(info->dev)); | ||
459 | |||
460 | delta_f = info->clk_rate - clk_get_rate(info->clk); | ||
461 | |||
462 | if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) || | ||
463 | (val == CPUFREQ_PRECHANGE && delta_f < 0)) { | ||
464 | info->clk_rate = clk_get_rate(info->clk); | ||
465 | nuc900fb_activate_var(fbinfo); | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi) | ||
472 | { | ||
473 | fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition; | ||
474 | return cpufreq_register_notifier(&fbi->freq_transition, | ||
475 | CPUFREQ_TRANSITION_NOTIFIER); | ||
476 | } | ||
477 | |||
478 | static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi) | ||
479 | { | ||
480 | cpufreq_unregister_notifier(&fbi->freq_transition, | ||
481 | CPUFREQ_TRANSITION_NOTIFIER); | ||
482 | } | ||
483 | #else | ||
484 | static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb, | ||
485 | unsigned long val, void *data) | ||
486 | { | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi) | ||
491 | { | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info) | ||
496 | { | ||
497 | } | ||
498 | #endif | ||
499 | |||
500 | static char driver_name[] = "nuc900fb"; | ||
501 | |||
502 | static int __devinit nuc900fb_probe(struct platform_device *pdev) | ||
503 | { | ||
504 | struct nuc900fb_info *fbi; | ||
505 | struct nuc900fb_display *display; | ||
506 | struct fb_info *fbinfo; | ||
507 | struct nuc900fb_mach_info *mach_info; | ||
508 | struct resource *res; | ||
509 | int ret; | ||
510 | int irq; | ||
511 | int i; | ||
512 | int size; | ||
513 | |||
514 | dev_dbg(&pdev->dev, "devinit\n"); | ||
515 | mach_info = pdev->dev.platform_data; | ||
516 | if (mach_info == NULL) { | ||
517 | dev_err(&pdev->dev, | ||
518 | "no platform data for lcd, cannot attach\n"); | ||
519 | return -EINVAL; | ||
520 | } | ||
521 | |||
522 | if (mach_info->default_display > mach_info->num_displays) { | ||
523 | dev_err(&pdev->dev, | ||
524 | "default display No. is %d but only %d displays \n", | ||
525 | mach_info->default_display, mach_info->num_displays); | ||
526 | return -EINVAL; | ||
527 | } | ||
528 | |||
529 | |||
530 | display = mach_info->displays + mach_info->default_display; | ||
531 | |||
532 | irq = platform_get_irq(pdev, 0); | ||
533 | if (irq < 0) { | ||
534 | dev_err(&pdev->dev, "no irq for device\n"); | ||
535 | return -ENOENT; | ||
536 | } | ||
537 | |||
538 | fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev); | ||
539 | if (!fbinfo) | ||
540 | return -ENOMEM; | ||
541 | |||
542 | platform_set_drvdata(pdev, fbinfo); | ||
543 | |||
544 | fbi = fbinfo->par; | ||
545 | fbi->dev = &pdev->dev; | ||
546 | |||
547 | #ifdef CONFIG_CPU_NUC950 | ||
548 | fbi->drv_type = LCDDRV_NUC950; | ||
549 | #endif | ||
550 | |||
551 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
552 | |||
553 | size = (res->end - res->start) + 1; | ||
554 | fbi->mem = request_mem_region(res->start, size, pdev->name); | ||
555 | if (fbi->mem == NULL) { | ||
556 | dev_err(&pdev->dev, "failed to alloc memory region\n"); | ||
557 | ret = -ENOENT; | ||
558 | goto free_fb; | ||
559 | } | ||
560 | |||
561 | fbi->io = ioremap(res->start, size); | ||
562 | if (fbi->io == NULL) { | ||
563 | dev_err(&pdev->dev, "ioremap() of lcd registers failed\n"); | ||
564 | ret = -ENXIO; | ||
565 | goto release_mem_region; | ||
566 | } | ||
567 | |||
568 | fbi->irq_base = fbi->io + REG_LCM_INT_CS; | ||
569 | |||
570 | |||
571 | /* Stop the LCD */ | ||
572 | writel(0, fbi->io + REG_LCM_DCCS); | ||
573 | |||
574 | /* fill the fbinfo*/ | ||
575 | strcpy(fbinfo->fix.id, driver_name); | ||
576 | fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; | ||
577 | fbinfo->fix.type_aux = 0; | ||
578 | fbinfo->fix.xpanstep = 0; | ||
579 | fbinfo->fix.ypanstep = 0; | ||
580 | fbinfo->fix.ywrapstep = 0; | ||
581 | fbinfo->fix.accel = FB_ACCEL_NONE; | ||
582 | fbinfo->var.nonstd = 0; | ||
583 | fbinfo->var.activate = FB_ACTIVATE_NOW; | ||
584 | fbinfo->var.accel_flags = 0; | ||
585 | fbinfo->var.vmode = FB_VMODE_NONINTERLACED; | ||
586 | fbinfo->fbops = &nuc900fb_ops; | ||
587 | fbinfo->flags = FBINFO_FLAG_DEFAULT; | ||
588 | fbinfo->pseudo_palette = &fbi->pseudo_pal; | ||
589 | |||
590 | ret = request_irq(irq, nuc900fb_irqhandler, IRQF_DISABLED, | ||
591 | pdev->name, fbinfo); | ||
592 | if (ret) { | ||
593 | dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n", | ||
594 | irq, ret); | ||
595 | ret = -EBUSY; | ||
596 | goto release_regs; | ||
597 | } | ||
598 | |||
599 | nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2); | ||
600 | |||
601 | fbi->clk = clk_get(&pdev->dev, NULL); | ||
602 | if (!fbi->clk || IS_ERR(fbi->clk)) { | ||
603 | printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n"); | ||
604 | ret = -ENOENT; | ||
605 | goto release_irq; | ||
606 | } | ||
607 | |||
608 | clk_enable(fbi->clk); | ||
609 | dev_dbg(&pdev->dev, "got and enabled clock\n"); | ||
610 | |||
611 | fbi->clk_rate = clk_get_rate(fbi->clk); | ||
612 | |||
613 | /* calutate the video buffer size */ | ||
614 | for (i = 0; i < mach_info->num_displays; i++) { | ||
615 | unsigned long smem_len = mach_info->displays[i].xres; | ||
616 | smem_len *= mach_info->displays[i].yres; | ||
617 | smem_len *= mach_info->displays[i].bpp; | ||
618 | smem_len >>= 3; | ||
619 | if (fbinfo->fix.smem_len < smem_len) | ||
620 | fbinfo->fix.smem_len = smem_len; | ||
621 | } | ||
622 | |||
623 | /* Initialize Video Memory */ | ||
624 | ret = nuc900fb_map_video_memory(fbinfo); | ||
625 | if (ret) { | ||
626 | printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret); | ||
627 | goto release_clock; | ||
628 | } | ||
629 | |||
630 | dev_dbg(&pdev->dev, "got video memory\n"); | ||
631 | |||
632 | fbinfo->var.xres = display->xres; | ||
633 | fbinfo->var.yres = display->yres; | ||
634 | fbinfo->var.bits_per_pixel = display->bpp; | ||
635 | |||
636 | nuc900fb_init_registers(fbinfo); | ||
637 | |||
638 | nuc900fb_check_var(&fbinfo->var, fbinfo); | ||
639 | |||
640 | ret = nuc900fb_cpufreq_register(fbi); | ||
641 | if (ret < 0) { | ||
642 | dev_err(&pdev->dev, "Failed to register cpufreq\n"); | ||
643 | goto free_video_memory; | ||
644 | } | ||
645 | |||
646 | ret = register_framebuffer(fbinfo); | ||
647 | if (ret) { | ||
648 | printk(KERN_ERR "failed to register framebuffer device: %d\n", | ||
649 | ret); | ||
650 | goto free_cpufreq; | ||
651 | } | ||
652 | |||
653 | printk(KERN_INFO "fb%d: %s frame buffer device\n", | ||
654 | fbinfo->node, fbinfo->fix.id); | ||
655 | |||
656 | return 0; | ||
657 | |||
658 | free_cpufreq: | ||
659 | nuc900fb_cpufreq_deregister(fbi); | ||
660 | free_video_memory: | ||
661 | nuc900fb_unmap_video_memory(fbinfo); | ||
662 | release_clock: | ||
663 | clk_disable(fbi->clk); | ||
664 | clk_put(fbi->clk); | ||
665 | release_irq: | ||
666 | free_irq(irq, fbi); | ||
667 | release_regs: | ||
668 | iounmap(fbi->io); | ||
669 | release_mem_region: | ||
670 | release_mem_region((unsigned long)fbi->mem, size); | ||
671 | free_fb: | ||
672 | framebuffer_release(fbinfo); | ||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | /* | ||
677 | * shutdown the lcd controller | ||
678 | */ | ||
679 | static void nuc900fb_stop_lcd(struct fb_info *info) | ||
680 | { | ||
681 | struct nuc900fb_info *fbi = info->par; | ||
682 | void __iomem *regs = fbi->io; | ||
683 | |||
684 | writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN), | ||
685 | regs + REG_LCM_DCCS); | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * Cleanup | ||
690 | */ | ||
691 | static int nuc900fb_remove(struct platform_device *pdev) | ||
692 | { | ||
693 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
694 | struct nuc900fb_info *fbi = fbinfo->par; | ||
695 | int irq; | ||
696 | |||
697 | nuc900fb_stop_lcd(fbinfo); | ||
698 | msleep(1); | ||
699 | |||
700 | nuc900fb_unmap_video_memory(fbinfo); | ||
701 | |||
702 | iounmap(fbi->io); | ||
703 | |||
704 | irq = platform_get_irq(pdev, 0); | ||
705 | free_irq(irq, fbi); | ||
706 | |||
707 | release_resource(fbi->mem); | ||
708 | kfree(fbi->mem); | ||
709 | |||
710 | platform_set_drvdata(pdev, NULL); | ||
711 | framebuffer_release(fbinfo); | ||
712 | |||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | #ifdef CONFIG_PM | ||
717 | |||
718 | /* | ||
719 | * suspend and resume support for the lcd controller | ||
720 | */ | ||
721 | |||
722 | static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state) | ||
723 | { | ||
724 | struct fb_info *fbinfo = platform_get_drvdata(dev); | ||
725 | struct nuc900fb_info *info = fbinfo->par; | ||
726 | |||
727 | nuc900fb_stop_lcd(); | ||
728 | msleep(1); | ||
729 | clk_disable(info->clk); | ||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | static int nuc900fb_resume(struct platform_device *dev) | ||
734 | { | ||
735 | struct fb_info *fbinfo = platform_get_drvdata(dev); | ||
736 | struct nuc900fb_info *fbi = fbinfo->par; | ||
737 | |||
738 | printk(KERN_INFO "nuc900fb resume\n"); | ||
739 | |||
740 | clk_enable(fbi->clk); | ||
741 | msleep(1); | ||
742 | |||
743 | nuc900fb_init_registers(fbinfo); | ||
744 | nuc900fb_activate_var(bfinfo); | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | #else | ||
750 | #define nuc900fb_suspend NULL | ||
751 | #define nuc900fb_resume NULL | ||
752 | #endif | ||
753 | |||
754 | static struct platform_driver nuc900fb_driver = { | ||
755 | .probe = nuc900fb_probe, | ||
756 | .remove = nuc900fb_remove, | ||
757 | .suspend = nuc900fb_suspend, | ||
758 | .resume = nuc900fb_resume, | ||
759 | .driver = { | ||
760 | .name = "nuc900-lcd", | ||
761 | .owner = THIS_MODULE, | ||
762 | }, | ||
763 | }; | ||
764 | |||
765 | int __devinit nuc900fb_init(void) | ||
766 | { | ||
767 | return platform_driver_register(&nuc900fb_driver); | ||
768 | } | ||
769 | |||
770 | static void __exit nuc900fb_cleanup(void) | ||
771 | { | ||
772 | platform_driver_unregister(&nuc900fb_driver); | ||
773 | } | ||
774 | |||
775 | module_init(nuc900fb_init); | ||
776 | module_exit(nuc900fb_cleanup); | ||
777 | |||
778 | MODULE_DESCRIPTION("Framebuffer driver for the NUC900"); | ||
779 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h new file mode 100644 index 000000000000..6c23aa3d3b89 --- /dev/null +++ b/drivers/video/nuc900fb.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright (c) 2009 Nuvoton technology corporation | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * Auther: | ||
12 | * Wang Qiang(rurality.linux@gmail.com) 2009/12/16 | ||
13 | */ | ||
14 | |||
15 | #ifndef __NUC900FB_H | ||
16 | #define __NUC900FB_H | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <mach/fb.h> | ||
20 | |||
21 | enum nuc900_lcddrv_type { | ||
22 | LCDDRV_NUC910, | ||
23 | LCDDRV_NUC930, | ||
24 | LCDDRV_NUC932, | ||
25 | LCDDRV_NUC950, | ||
26 | LCDDRV_NUC960, | ||
27 | }; | ||
28 | |||
29 | |||
30 | #define PALETTE_BUFFER_SIZE 256 | ||
31 | #define PALETTE_BUFF_CLEAR (0x80000000) /* entry is clear/invalid */ | ||
32 | |||
33 | struct nuc900fb_info { | ||
34 | struct device *dev; | ||
35 | struct clk *clk; | ||
36 | |||
37 | struct resource *mem; | ||
38 | void __iomem *io; | ||
39 | void __iomem *irq_base; | ||
40 | int drv_type; | ||
41 | struct nuc900fb_hw regs; | ||
42 | unsigned long clk_rate; | ||
43 | |||
44 | #ifdef CONFIG_CPU_FREQ | ||
45 | struct notifier_block freq_transition; | ||
46 | #endif | ||
47 | |||
48 | /* keep these registers in case we need to re-write palette */ | ||
49 | u32 palette_buffer[PALETTE_BUFFER_SIZE]; | ||
50 | u32 pseudo_pal[16]; | ||
51 | }; | ||
52 | |||
53 | int nuc900fb_init(void); | ||
54 | |||
55 | #endif /* __NUC900FB_H */ | ||
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index a33483910dc8..9557f963662e 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c | |||
@@ -389,7 +389,7 @@ static int omap_lcdc_enable_plane(int plane, int enable) | |||
389 | /* | 389 | /* |
390 | * Configure the LCD DMA for a palette load operation and do the palette | 390 | * Configure the LCD DMA for a palette load operation and do the palette |
391 | * downloading synchronously. We don't use the frame+palette load mode of | 391 | * downloading synchronously. We don't use the frame+palette load mode of |
392 | * the controller, since the palette can always be downloaded seperately. | 392 | * the controller, since the palette can always be downloaded separately. |
393 | */ | 393 | */ |
394 | static void load_palette(void) | 394 | static void load_palette(void) |
395 | { | 395 | { |
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 913142d4cab1..9acef00c47ea 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
@@ -341,7 +341,7 @@ static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, | |||
341 | return manager_attr->store(manager, buf, size); | 341 | return manager_attr->store(manager, buf, size); |
342 | } | 342 | } |
343 | 343 | ||
344 | static struct sysfs_ops manager_sysfs_ops = { | 344 | static const struct sysfs_ops manager_sysfs_ops = { |
345 | .show = manager_attr_show, | 345 | .show = manager_attr_show, |
346 | .store = manager_attr_store, | 346 | .store = manager_attr_store, |
347 | }; | 347 | }; |
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 0c5bea263ac6..aed3f3194347 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c | |||
@@ -320,7 +320,7 @@ static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, | |||
320 | return overlay_attr->store(overlay, buf, size); | 320 | return overlay_attr->store(overlay, buf, size); |
321 | } | 321 | } |
322 | 322 | ||
323 | static struct sysfs_ops overlay_sysfs_ops = { | 323 | static const struct sysfs_ops overlay_sysfs_ops = { |
324 | .show = overlay_attr_show, | 324 | .show = overlay_attr_show, |
325 | .store = overlay_attr_store, | 325 | .store = overlay_attr_store, |
326 | }; | 326 | }; |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 36436ee6c1a4..27f93aab6ddc 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -896,7 +896,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
896 | * Pseudocolor: | 896 | * Pseudocolor: |
897 | * uses offset = 0 && length = DAC register width. | 897 | * uses offset = 0 && length = DAC register width. |
898 | * var->{color}.offset is 0 | 898 | * var->{color}.offset is 0 |
899 | * var->{color}.length contains widht of DAC | 899 | * var->{color}.length contains width of DAC |
900 | * cmap is not used | 900 | * cmap is not used |
901 | * DAC[X] is programmed to (red, green, blue) | 901 | * DAC[X] is programmed to (red, green, blue) |
902 | * Truecolor: | 902 | * Truecolor: |
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index 4beac1df617b..de40a626dc76 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c | |||
@@ -85,7 +85,7 @@ static struct fb_ops q40fb_ops = { | |||
85 | .fb_imageblit = cfb_imageblit, | 85 | .fb_imageblit = cfb_imageblit, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static int __init q40fb_probe(struct platform_device *dev) | 88 | static int __devinit q40fb_probe(struct platform_device *dev) |
89 | { | 89 | { |
90 | struct fb_info *info; | 90 | struct fb_info *info; |
91 | 91 | ||
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index 0deb0a8867b7..7b63429f1a7c 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c | |||
@@ -517,12 +517,12 @@ s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) | |||
517 | src = (sy * stride) + (bpp * sx); | 517 | src = (sy * stride) + (bpp * sx); |
518 | } | 518 | } |
519 | 519 | ||
520 | /* set source adress */ | 520 | /* set source address */ |
521 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); | 521 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); |
522 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); | 522 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); |
523 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); | 523 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); |
524 | 524 | ||
525 | /* set destination adress */ | 525 | /* set destination address */ |
526 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); | 526 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); |
527 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); | 527 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); |
528 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); | 528 | s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index aac661225c78..2b094dec4a56 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -1004,12 +1004,12 @@ dealloc_fb: | |||
1004 | return ret; | 1004 | return ret; |
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | static int __init s3c2410fb_probe(struct platform_device *pdev) | 1007 | static int __devinit s3c2410fb_probe(struct platform_device *pdev) |
1008 | { | 1008 | { |
1009 | return s3c24xxfb_probe(pdev, DRV_S3C2410); | 1009 | return s3c24xxfb_probe(pdev, DRV_S3C2410); |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | static int __init s3c2412fb_probe(struct platform_device *pdev) | 1012 | static int __devinit s3c2412fb_probe(struct platform_device *pdev) |
1013 | { | 1013 | { |
1014 | return s3c24xxfb_probe(pdev, DRV_S3C2412); | 1014 | return s3c24xxfb_probe(pdev, DRV_S3C2412); |
1015 | } | 1015 | } |
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index cdaa873a6054..e8b76d65a070 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c | |||
@@ -1435,7 +1435,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) | |||
1435 | return fbi; | 1435 | return fbi; |
1436 | } | 1436 | } |
1437 | 1437 | ||
1438 | static int __init sa1100fb_probe(struct platform_device *pdev) | 1438 | static int __devinit sa1100fb_probe(struct platform_device *pdev) |
1439 | { | 1439 | { |
1440 | struct sa1100fb_info *fbi; | 1440 | struct sa1100fb_info *fbi; |
1441 | int ret, irq; | 1441 | int ret, irq; |
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index f86012239bff..7a3a5e28eca1 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c | |||
@@ -745,7 +745,7 @@ int __init sgivwfb_setup(char *options) | |||
745 | /* | 745 | /* |
746 | * Initialisation | 746 | * Initialisation |
747 | */ | 747 | */ |
748 | static int __init sgivwfb_probe(struct platform_device *dev) | 748 | static int __devinit sgivwfb_probe(struct platform_device *dev) |
749 | { | 749 | { |
750 | struct sgivw_par *par; | 750 | struct sgivw_par *par; |
751 | struct fb_info *info; | 751 | struct fb_info *info; |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 8d7653e56df5..bbd1dbf4026a 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -943,7 +943,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { | |||
943 | 943 | ||
944 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); | 944 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); |
945 | 945 | ||
946 | static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | 946 | static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) |
947 | { | 947 | { |
948 | struct fb_info *info; | 948 | struct fb_info *info; |
949 | struct sh_mobile_lcdc_priv *priv; | 949 | struct sh_mobile_lcdc_priv *priv; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 9d2b6bc49036..a531a0f7cdf2 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -1891,9 +1891,6 @@ static struct fb_ops sisfb_ops = { | |||
1891 | .fb_fillrect = fbcon_sis_fillrect, | 1891 | .fb_fillrect = fbcon_sis_fillrect, |
1892 | .fb_copyarea = fbcon_sis_copyarea, | 1892 | .fb_copyarea = fbcon_sis_copyarea, |
1893 | .fb_imageblit = cfb_imageblit, | 1893 | .fb_imageblit = cfb_imageblit, |
1894 | #ifdef CONFIG_FB_SOFT_CURSOR | ||
1895 | .fb_cursor = soft_cursor, | ||
1896 | #endif | ||
1897 | .fb_sync = fbcon_sis_sync, | 1894 | .fb_sync = fbcon_sis_sync, |
1898 | #ifdef SIS_NEW_CONFIG_COMPAT | 1895 | #ifdef SIS_NEW_CONFIG_COMPAT |
1899 | .fb_compat_ioctl= sisfb_ioctl, | 1896 | .fb_compat_ioctl= sisfb_ioctl, |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 35370d0ecf03..b7dc1800efa9 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -411,7 +411,7 @@ static int sm501fb_set_par_common(struct fb_info *info, | |||
411 | struct sm501fb_par *par = info->par; | 411 | struct sm501fb_par *par = info->par; |
412 | struct sm501fb_info *fbi = par->info; | 412 | struct sm501fb_info *fbi = par->info; |
413 | unsigned long pixclock; /* pixelclock in Hz */ | 413 | unsigned long pixclock; /* pixelclock in Hz */ |
414 | unsigned long sm501pixclock; /* pixelclock the 501 can achive in Hz */ | 414 | unsigned long sm501pixclock; /* pixelclock the 501 can achieve in Hz */ |
415 | unsigned int mem_type; | 415 | unsigned int mem_type; |
416 | unsigned int clock_type; | 416 | unsigned int clock_type; |
417 | unsigned int head_addr; | 417 | unsigned int head_addr; |
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 609d0a521ca2..79840f11fecb 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c | |||
@@ -1102,7 +1102,7 @@ static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) | |||
1102 | * detect dac type | 1102 | * detect dac type |
1103 | * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset, | 1103 | * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset, |
1104 | * dram refresh disabled, FbiInit remaped. | 1104 | * dram refresh disabled, FbiInit remaped. |
1105 | * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ... | 1105 | * TODO: mmh.. maybe i should put the "prerequisite" in the func ... |
1106 | */ | 1106 | */ |
1107 | 1107 | ||
1108 | 1108 | ||
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c new file mode 100644 index 000000000000..a8248c0b9192 --- /dev/null +++ b/drivers/video/sunxvr1000.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems | ||
2 | * | ||
3 | * Copyright (C) 2010 David S. Miller (davem@davemloft.net) | ||
4 | */ | ||
5 | |||
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <linux/fb.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/of_device.h> | ||
12 | |||
13 | struct gfb_info { | ||
14 | struct fb_info *info; | ||
15 | |||
16 | char __iomem *fb_base; | ||
17 | unsigned long fb_base_phys; | ||
18 | |||
19 | struct device_node *of_node; | ||
20 | |||
21 | unsigned int width; | ||
22 | unsigned int height; | ||
23 | unsigned int depth; | ||
24 | unsigned int fb_size; | ||
25 | |||
26 | u32 pseudo_palette[16]; | ||
27 | }; | ||
28 | |||
29 | static int __devinit gfb_get_props(struct gfb_info *gp) | ||
30 | { | ||
31 | gp->width = of_getintprop_default(gp->of_node, "width", 0); | ||
32 | gp->height = of_getintprop_default(gp->of_node, "height", 0); | ||
33 | gp->depth = of_getintprop_default(gp->of_node, "depth", 32); | ||
34 | |||
35 | if (!gp->width || !gp->height) { | ||
36 | printk(KERN_ERR "gfb: Critical properties missing for %s\n", | ||
37 | gp->of_node->full_name); | ||
38 | return -EINVAL; | ||
39 | } | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int gfb_setcolreg(unsigned regno, | ||
45 | unsigned red, unsigned green, unsigned blue, | ||
46 | unsigned transp, struct fb_info *info) | ||
47 | { | ||
48 | u32 value; | ||
49 | |||
50 | if (regno < 16) { | ||
51 | red >>= 8; | ||
52 | green >>= 8; | ||
53 | blue >>= 8; | ||
54 | |||
55 | value = (blue << 16) | (green << 8) | red; | ||
56 | ((u32 *)info->pseudo_palette)[regno] = value; | ||
57 | } | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static struct fb_ops gfb_ops = { | ||
63 | .owner = THIS_MODULE, | ||
64 | .fb_setcolreg = gfb_setcolreg, | ||
65 | .fb_fillrect = cfb_fillrect, | ||
66 | .fb_copyarea = cfb_copyarea, | ||
67 | .fb_imageblit = cfb_imageblit, | ||
68 | }; | ||
69 | |||
70 | static int __devinit gfb_set_fbinfo(struct gfb_info *gp) | ||
71 | { | ||
72 | struct fb_info *info = gp->info; | ||
73 | struct fb_var_screeninfo *var = &info->var; | ||
74 | |||
75 | info->flags = FBINFO_DEFAULT; | ||
76 | info->fbops = &gfb_ops; | ||
77 | info->screen_base = gp->fb_base; | ||
78 | info->screen_size = gp->fb_size; | ||
79 | |||
80 | info->pseudo_palette = gp->pseudo_palette; | ||
81 | |||
82 | /* Fill fix common fields */ | ||
83 | strlcpy(info->fix.id, "gfb", sizeof(info->fix.id)); | ||
84 | info->fix.smem_start = gp->fb_base_phys; | ||
85 | info->fix.smem_len = gp->fb_size; | ||
86 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
87 | if (gp->depth == 32 || gp->depth == 24) | ||
88 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
89 | else | ||
90 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
91 | |||
92 | var->xres = gp->width; | ||
93 | var->yres = gp->height; | ||
94 | var->xres_virtual = var->xres; | ||
95 | var->yres_virtual = var->yres; | ||
96 | var->bits_per_pixel = gp->depth; | ||
97 | |||
98 | var->red.offset = 0; | ||
99 | var->red.length = 8; | ||
100 | var->green.offset = 8; | ||
101 | var->green.length = 8; | ||
102 | var->blue.offset = 16; | ||
103 | var->blue.length = 8; | ||
104 | var->transp.offset = 0; | ||
105 | var->transp.length = 0; | ||
106 | |||
107 | if (fb_alloc_cmap(&info->cmap, 256, 0)) { | ||
108 | printk(KERN_ERR "gfb: Cannot allocate color map.\n"); | ||
109 | return -ENOMEM; | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int __devinit gfb_probe(struct of_device *op, | ||
116 | const struct of_device_id *match) | ||
117 | { | ||
118 | struct device_node *dp = op->node; | ||
119 | struct fb_info *info; | ||
120 | struct gfb_info *gp; | ||
121 | int err; | ||
122 | |||
123 | info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev); | ||
124 | if (!info) { | ||
125 | printk(KERN_ERR "gfb: Cannot allocate fb_info\n"); | ||
126 | err = -ENOMEM; | ||
127 | goto err_out; | ||
128 | } | ||
129 | |||
130 | gp = info->par; | ||
131 | gp->info = info; | ||
132 | gp->of_node = dp; | ||
133 | |||
134 | gp->fb_base_phys = op->resource[6].start; | ||
135 | |||
136 | err = gfb_get_props(gp); | ||
137 | if (err) | ||
138 | goto err_release_fb; | ||
139 | |||
140 | /* Framebuffer length is the same regardless of resolution. */ | ||
141 | info->fix.line_length = 16384; | ||
142 | gp->fb_size = info->fix.line_length * gp->height; | ||
143 | |||
144 | gp->fb_base = of_ioremap(&op->resource[6], 0, | ||
145 | gp->fb_size, "gfb fb"); | ||
146 | if (!gp->fb_base) | ||
147 | goto err_release_fb; | ||
148 | |||
149 | err = gfb_set_fbinfo(gp); | ||
150 | if (err) | ||
151 | goto err_unmap_fb; | ||
152 | |||
153 | printk("gfb: Found device at %s\n", dp->full_name); | ||
154 | |||
155 | err = register_framebuffer(info); | ||
156 | if (err < 0) { | ||
157 | printk(KERN_ERR "gfb: Could not register framebuffer %s\n", | ||
158 | dp->full_name); | ||
159 | goto err_unmap_fb; | ||
160 | } | ||
161 | |||
162 | dev_set_drvdata(&op->dev, info); | ||
163 | |||
164 | return 0; | ||
165 | |||
166 | err_unmap_fb: | ||
167 | of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size); | ||
168 | |||
169 | err_release_fb: | ||
170 | framebuffer_release(info); | ||
171 | |||
172 | err_out: | ||
173 | return err; | ||
174 | } | ||
175 | |||
176 | static int __devexit gfb_remove(struct of_device *op) | ||
177 | { | ||
178 | struct fb_info *info = dev_get_drvdata(&op->dev); | ||
179 | struct gfb_info *gp = info->par; | ||
180 | |||
181 | unregister_framebuffer(info); | ||
182 | |||
183 | iounmap(gp->fb_base); | ||
184 | |||
185 | of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size); | ||
186 | |||
187 | framebuffer_release(info); | ||
188 | |||
189 | dev_set_drvdata(&op->dev, NULL); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static const struct of_device_id gfb_match[] = { | ||
195 | { | ||
196 | .name = "SUNW,gfb", | ||
197 | }, | ||
198 | {}, | ||
199 | }; | ||
200 | MODULE_DEVICE_TABLE(of, ffb_match); | ||
201 | |||
202 | static struct of_platform_driver gfb_driver = { | ||
203 | .name = "gfb", | ||
204 | .match_table = gfb_match, | ||
205 | .probe = gfb_probe, | ||
206 | .remove = __devexit_p(gfb_remove), | ||
207 | }; | ||
208 | |||
209 | static int __init gfb_init(void) | ||
210 | { | ||
211 | if (fb_get_options("gfb", NULL)) | ||
212 | return -ENODEV; | ||
213 | |||
214 | return of_register_driver(&gfb_driver, &of_bus_type); | ||
215 | } | ||
216 | |||
217 | static void __exit gfb_exit(void) | ||
218 | { | ||
219 | of_unregister_driver(&gfb_driver); | ||
220 | } | ||
221 | |||
222 | module_init(gfb_init); | ||
223 | module_exit(gfb_exit); | ||
224 | |||
225 | MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics"); | ||
226 | MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); | ||
227 | MODULE_VERSION("1.0"); | ||
228 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index bd37ee1f6a25..ef4128c8e57a 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -226,7 +226,7 @@ static int __init vesafb_setup(char *options) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int __init vesafb_probe(struct platform_device *dev) | 229 | static int __devinit vesafb_probe(struct platform_device *dev) |
230 | { | 230 | { |
231 | struct fb_info *info; | 231 | struct fb_info *info; |
232 | int i, err; | 232 | int i, err; |
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 050d432c7d95..b8ab995fbda7 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c | |||
@@ -479,7 +479,7 @@ static int __init vfb_setup(char *options) | |||
479 | * Initialisation | 479 | * Initialisation |
480 | */ | 480 | */ |
481 | 481 | ||
482 | static int __init vfb_probe(struct platform_device *dev) | 482 | static int __devinit vfb_probe(struct platform_device *dev) |
483 | { | 483 | { |
484 | struct fb_info *info; | 484 | struct fb_info *info; |
485 | int retval = -ENOMEM; | 485 | int retval = -ENOMEM; |
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 5b2938903ac2..76d8dae5b1bb 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c | |||
@@ -1293,7 +1293,7 @@ static int vga16fb_setup(char *options) | |||
1293 | } | 1293 | } |
1294 | #endif | 1294 | #endif |
1295 | 1295 | ||
1296 | static int __init vga16fb_probe(struct platform_device *dev) | 1296 | static int __devinit vga16fb_probe(struct platform_device *dev) |
1297 | { | 1297 | { |
1298 | struct fb_info *info; | 1298 | struct fb_info *info; |
1299 | struct vga16fb_par *par; | 1299 | struct vga16fb_par *par; |
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index e533b4b6aba4..eeed238ad6a2 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_FB_VIA) += viafb.o | 5 | obj-$(CONFIG_FB_VIA) += viafb.o |
6 | 6 | ||
7 | viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o | 7 | viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o |
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 474f428aea92..8c06bd3c0b4d 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h | |||
@@ -107,7 +107,6 @@ | |||
107 | struct tmds_chip_information { | 107 | struct tmds_chip_information { |
108 | int tmds_chip_name; | 108 | int tmds_chip_name; |
109 | int tmds_chip_slave_addr; | 109 | int tmds_chip_slave_addr; |
110 | int dvi_panel_id; | ||
111 | int data_mode; | 110 | int data_mode; |
112 | int output_interface; | 111 | int output_interface; |
113 | int i2c_port; | 112 | int i2c_port; |
@@ -142,14 +141,9 @@ struct tmds_setting_information { | |||
142 | int iga_path; | 141 | int iga_path; |
143 | int h_active; | 142 | int h_active; |
144 | int v_active; | 143 | int v_active; |
145 | int bpp; | ||
146 | int refresh_rate; | ||
147 | int get_dvi_size_method; | ||
148 | int max_pixel_clock; | 144 | int max_pixel_clock; |
149 | int dvi_panel_size; | 145 | int max_hres; |
150 | int dvi_panel_hres; | 146 | int max_vres; |
151 | int dvi_panel_vres; | ||
152 | int native_size; | ||
153 | }; | 147 | }; |
154 | 148 | ||
155 | struct lvds_setting_information { | 149 | struct lvds_setting_information { |
@@ -160,7 +154,6 @@ struct lvds_setting_information { | |||
160 | int refresh_rate; | 154 | int refresh_rate; |
161 | int get_lcd_size_method; | 155 | int get_lcd_size_method; |
162 | int lcd_panel_id; | 156 | int lcd_panel_id; |
163 | int lcd_panel_size; | ||
164 | int lcd_panel_hres; | 157 | int lcd_panel_hres; |
165 | int lcd_panel_vres; | 158 | int lcd_panel_vres; |
166 | int display_method; | 159 | int display_method; |
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 67b36932212b..abe59b8c7a05 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -23,11 +23,10 @@ | |||
23 | static void tmds_register_write(int index, u8 data); | 23 | static void tmds_register_write(int index, u8 data); |
24 | static int tmds_register_read(int index); | 24 | static int tmds_register_read(int index); |
25 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); | 25 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); |
26 | static int check_reduce_blanking_mode(int mode_index, | 26 | static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information |
27 | int refresh_rate); | 27 | *tmds_chip, struct tmds_setting_information *tmds_setting); |
28 | static int dvi_get_panel_size_from_DDCv1(void); | 28 | static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information |
29 | static int dvi_get_panel_size_from_DDCv2(void); | 29 | *tmds_chip, struct tmds_setting_information *tmds_setting); |
30 | static unsigned char dvi_get_panel_info(void); | ||
31 | static int viafb_dvi_query_EDID(void); | 30 | static int viafb_dvi_query_EDID(void); |
32 | 31 | ||
33 | static int check_tmds_chip(int device_id_subaddr, int device_id) | 32 | static int check_tmds_chip(int device_id_subaddr, int device_id) |
@@ -38,23 +37,24 @@ static int check_tmds_chip(int device_id_subaddr, int device_id) | |||
38 | return FAIL; | 37 | return FAIL; |
39 | } | 38 | } |
40 | 39 | ||
41 | void viafb_init_dvi_size(void) | 40 | void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, |
41 | struct tmds_setting_information *tmds_setting) | ||
42 | { | 42 | { |
43 | DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); | 43 | DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); |
44 | DEBUG_MSG(KERN_INFO | ||
45 | "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n", | ||
46 | viaparinfo->tmds_setting_info->get_dvi_size_method); | ||
47 | 44 | ||
48 | switch (viaparinfo->tmds_setting_info->get_dvi_size_method) { | 45 | viafb_dvi_sense(); |
49 | case GET_DVI_SIZE_BY_SYSTEM_BIOS: | 46 | switch (viafb_dvi_query_EDID()) { |
47 | case 1: | ||
48 | dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); | ||
50 | break; | 49 | break; |
51 | case GET_DVI_SZIE_BY_HW_STRAPPING: | 50 | case 2: |
51 | dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting); | ||
52 | break; | 52 | break; |
53 | case GET_DVI_SIZE_BY_VGA_BIOS: | ||
54 | default: | 53 | default: |
55 | dvi_get_panel_info(); | 54 | printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n"); |
56 | break; | 55 | break; |
57 | } | 56 | } |
57 | |||
58 | return; | 58 | return; |
59 | } | 59 | } |
60 | 60 | ||
@@ -189,42 +189,14 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | static int check_reduce_blanking_mode(int mode_index, | ||
193 | int refresh_rate) | ||
194 | { | ||
195 | if (refresh_rate != 60) | ||
196 | return false; | ||
197 | |||
198 | switch (mode_index) { | ||
199 | /* Following modes have reduce blanking mode. */ | ||
200 | case VIA_RES_1360X768: | ||
201 | case VIA_RES_1400X1050: | ||
202 | case VIA_RES_1440X900: | ||
203 | case VIA_RES_1600X900: | ||
204 | case VIA_RES_1680X1050: | ||
205 | case VIA_RES_1920X1080: | ||
206 | case VIA_RES_1920X1200: | ||
207 | break; | ||
208 | |||
209 | default: | ||
210 | DEBUG_MSG(KERN_INFO | ||
211 | "This dvi mode %d have no reduce blanking mode!\n", | ||
212 | mode_index); | ||
213 | return false; | ||
214 | } | ||
215 | |||
216 | return true; | ||
217 | } | ||
218 | |||
219 | /* DVI Set Mode */ | 192 | /* DVI Set Mode */ |
220 | void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga) | 193 | void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, |
194 | int set_iga) | ||
221 | { | 195 | { |
222 | struct VideoModeTable *videoMode = NULL; | 196 | struct VideoModeTable *rb_mode; |
223 | struct crt_mode_table *pDviTiming; | 197 | struct crt_mode_table *pDviTiming; |
224 | unsigned long desirePixelClock, maxPixelClock; | 198 | unsigned long desirePixelClock, maxPixelClock; |
225 | int status = 0; | 199 | pDviTiming = mode->crtc; |
226 | videoMode = viafb_get_modetbl_pointer(video_index); | ||
227 | pDviTiming = videoMode->crtc; | ||
228 | desirePixelClock = pDviTiming->clk / 1000000; | 200 | desirePixelClock = pDviTiming->clk / 1000000; |
229 | maxPixelClock = (unsigned long)viaparinfo-> | 201 | maxPixelClock = (unsigned long)viaparinfo-> |
230 | tmds_setting_info->max_pixel_clock; | 202 | tmds_setting_info->max_pixel_clock; |
@@ -232,20 +204,14 @@ void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga) | |||
232 | DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n"); | 204 | DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n"); |
233 | 205 | ||
234 | if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) { | 206 | if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) { |
235 | /*Check if reduce-blanking mode is exist */ | 207 | rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr, |
236 | status = | 208 | mode->crtc[0].crtc.ver_addr); |
237 | check_reduce_blanking_mode(video_index, | 209 | if (rb_mode) { |
238 | pDviTiming->refresh_rate); | 210 | mode = rb_mode; |
239 | if (status) { | 211 | pDviTiming = rb_mode->crtc; |
240 | video_index += 100; /*Use reduce-blanking mode */ | ||
241 | videoMode = viafb_get_modetbl_pointer(video_index); | ||
242 | pDviTiming = videoMode->crtc; | ||
243 | DEBUG_MSG(KERN_INFO | ||
244 | "DVI use reduce blanking mode %d!!\n", | ||
245 | video_index); | ||
246 | } | 212 | } |
247 | } | 213 | } |
248 | viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga); | 214 | viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); |
249 | viafb_set_output_path(DEVICE_DVI, set_iga, | 215 | viafb_set_output_path(DEVICE_DVI, set_iga, |
250 | viaparinfo->chip_info->tmds_chip_info.output_interface); | 216 | viaparinfo->chip_info->tmds_chip_info.output_interface); |
251 | } | 217 | } |
@@ -350,25 +316,18 @@ static int viafb_dvi_query_EDID(void) | |||
350 | return false; | 316 | return false; |
351 | } | 317 | } |
352 | 318 | ||
353 | /* | 319 | /* Get Panel Size Using EDID1 Table */ |
354 | * | 320 | static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information |
355 | * int dvi_get_panel_size_from_DDCv1(void) | 321 | *tmds_chip, struct tmds_setting_information *tmds_setting) |
356 | * | ||
357 | * - Get Panel Size Using EDID1 Table | ||
358 | * | ||
359 | * Return Type: int | ||
360 | * | ||
361 | */ | ||
362 | static int dvi_get_panel_size_from_DDCv1(void) | ||
363 | { | 322 | { |
364 | int i, max_h = 0, max_v = 0, tmp, restore; | 323 | int i, max_h = 0, tmp, restore; |
365 | unsigned char rData; | 324 | unsigned char rData; |
366 | unsigned char EDID_DATA[18]; | 325 | unsigned char EDID_DATA[18]; |
367 | 326 | ||
368 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); | 327 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n"); |
369 | 328 | ||
370 | restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; | 329 | restore = tmds_chip->tmds_chip_slave_addr; |
371 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0; | 330 | tmds_chip->tmds_chip_slave_addr = 0xA0; |
372 | 331 | ||
373 | rData = tmds_register_read(0x23); | 332 | rData = tmds_register_read(0x23); |
374 | if (rData & 0x3C) | 333 | if (rData & 0x3C) |
@@ -414,8 +373,8 @@ static int dvi_get_panel_size_from_DDCv1(void) | |||
414 | /* The first two byte must be zero. */ | 373 | /* The first two byte must be zero. */ |
415 | if (EDID_DATA[3] == 0xFD) { | 374 | if (EDID_DATA[3] == 0xFD) { |
416 | /* To get max pixel clock. */ | 375 | /* To get max pixel clock. */ |
417 | viaparinfo->tmds_setting_info-> | 376 | tmds_setting->max_pixel_clock = |
418 | max_pixel_clock = EDID_DATA[9] * 10; | 377 | EDID_DATA[9] * 10; |
419 | } | 378 | } |
420 | } | 379 | } |
421 | break; | 380 | break; |
@@ -425,154 +384,88 @@ static int dvi_get_panel_size_from_DDCv1(void) | |||
425 | } | 384 | } |
426 | } | 385 | } |
427 | 386 | ||
387 | tmds_setting->max_hres = max_h; | ||
428 | switch (max_h) { | 388 | switch (max_h) { |
429 | case 640: | 389 | case 640: |
430 | viaparinfo->tmds_setting_info->dvi_panel_size = | 390 | tmds_setting->max_vres = 480; |
431 | VIA_RES_640X480; | ||
432 | break; | 391 | break; |
433 | case 800: | 392 | case 800: |
434 | viaparinfo->tmds_setting_info->dvi_panel_size = | 393 | tmds_setting->max_vres = 600; |
435 | VIA_RES_800X600; | ||
436 | break; | 394 | break; |
437 | case 1024: | 395 | case 1024: |
438 | viaparinfo->tmds_setting_info->dvi_panel_size = | 396 | tmds_setting->max_vres = 768; |
439 | VIA_RES_1024X768; | ||
440 | break; | 397 | break; |
441 | case 1280: | 398 | case 1280: |
442 | viaparinfo->tmds_setting_info->dvi_panel_size = | 399 | tmds_setting->max_vres = 1024; |
443 | VIA_RES_1280X1024; | ||
444 | break; | 400 | break; |
445 | case 1400: | 401 | case 1400: |
446 | viaparinfo->tmds_setting_info->dvi_panel_size = | 402 | tmds_setting->max_vres = 1050; |
447 | VIA_RES_1400X1050; | ||
448 | break; | 403 | break; |
449 | case 1440: | 404 | case 1440: |
450 | viaparinfo->tmds_setting_info->dvi_panel_size = | 405 | tmds_setting->max_vres = 1050; |
451 | VIA_RES_1440X1050; | ||
452 | break; | 406 | break; |
453 | case 1600: | 407 | case 1600: |
454 | viaparinfo->tmds_setting_info->dvi_panel_size = | 408 | tmds_setting->max_vres = 1200; |
455 | VIA_RES_1600X1200; | ||
456 | break; | 409 | break; |
457 | case 1920: | 410 | case 1920: |
458 | if (max_v == 1200) { | 411 | tmds_setting->max_vres = 1080; |
459 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
460 | VIA_RES_1920X1200; | ||
461 | } else { | ||
462 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
463 | VIA_RES_1920X1080; | ||
464 | } | ||
465 | |||
466 | break; | 412 | break; |
467 | default: | 413 | default: |
468 | viaparinfo->tmds_setting_info->dvi_panel_size = | 414 | DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! " |
469 | VIA_RES_1024X768; | 415 | "set default panel size.\n", max_h); |
470 | DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\ | ||
471 | set default panel size.\n", max_h); | ||
472 | break; | 416 | break; |
473 | } | 417 | } |
474 | 418 | ||
475 | DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", | 419 | DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n", |
476 | viaparinfo->tmds_setting_info->max_pixel_clock); | 420 | tmds_setting->max_pixel_clock); |
477 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; | 421 | tmds_chip->tmds_chip_slave_addr = restore; |
478 | return viaparinfo->tmds_setting_info->dvi_panel_size; | ||
479 | } | 422 | } |
480 | 423 | ||
481 | /* | 424 | /* Get Panel Size Using EDID2 Table */ |
482 | * | 425 | static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information |
483 | * int dvi_get_panel_size_from_DDCv2(void) | 426 | *tmds_chip, struct tmds_setting_information *tmds_setting) |
484 | * | ||
485 | * - Get Panel Size Using EDID2 Table | ||
486 | * | ||
487 | * Return Type: int | ||
488 | * | ||
489 | */ | ||
490 | static int dvi_get_panel_size_from_DDCv2(void) | ||
491 | { | 427 | { |
492 | int HSize = 0, restore; | 428 | int restore; |
493 | unsigned char R_Buffer[2]; | 429 | unsigned char R_Buffer[2]; |
494 | 430 | ||
495 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); | 431 | DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); |
496 | 432 | ||
497 | restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr; | 433 | restore = tmds_chip->tmds_chip_slave_addr; |
498 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2; | 434 | tmds_chip->tmds_chip_slave_addr = 0xA2; |
499 | 435 | ||
500 | /* Horizontal: 0x76, 0x77 */ | 436 | /* Horizontal: 0x76, 0x77 */ |
501 | tmds_register_read_bytes(0x76, R_Buffer, 2); | 437 | tmds_register_read_bytes(0x76, R_Buffer, 2); |
502 | HSize = R_Buffer[0]; | 438 | tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8); |
503 | HSize += R_Buffer[1] << 8; | ||
504 | 439 | ||
505 | switch (HSize) { | 440 | switch (tmds_setting->max_hres) { |
506 | case 640: | 441 | case 640: |
507 | viaparinfo->tmds_setting_info->dvi_panel_size = | 442 | tmds_setting->max_vres = 480; |
508 | VIA_RES_640X480; | ||
509 | break; | 443 | break; |
510 | case 800: | 444 | case 800: |
511 | viaparinfo->tmds_setting_info->dvi_panel_size = | 445 | tmds_setting->max_vres = 600; |
512 | VIA_RES_800X600; | ||
513 | break; | 446 | break; |
514 | case 1024: | 447 | case 1024: |
515 | viaparinfo->tmds_setting_info->dvi_panel_size = | 448 | tmds_setting->max_vres = 768; |
516 | VIA_RES_1024X768; | ||
517 | break; | 449 | break; |
518 | case 1280: | 450 | case 1280: |
519 | viaparinfo->tmds_setting_info->dvi_panel_size = | 451 | tmds_setting->max_vres = 1024; |
520 | VIA_RES_1280X1024; | ||
521 | break; | 452 | break; |
522 | case 1400: | 453 | case 1400: |
523 | viaparinfo->tmds_setting_info->dvi_panel_size = | 454 | tmds_setting->max_vres = 1050; |
524 | VIA_RES_1400X1050; | ||
525 | break; | 455 | break; |
526 | case 1440: | 456 | case 1440: |
527 | viaparinfo->tmds_setting_info->dvi_panel_size = | 457 | tmds_setting->max_vres = 1050; |
528 | VIA_RES_1440X1050; | ||
529 | break; | 458 | break; |
530 | case 1600: | 459 | case 1600: |
531 | viaparinfo->tmds_setting_info->dvi_panel_size = | 460 | tmds_setting->max_vres = 1200; |
532 | VIA_RES_1600X1200; | ||
533 | break; | ||
534 | default: | ||
535 | viaparinfo->tmds_setting_info->dvi_panel_size = | ||
536 | VIA_RES_1024X768; | ||
537 | DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\ | ||
538 | set default panel size.\n", HSize); | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; | ||
543 | return viaparinfo->tmds_setting_info->dvi_panel_size; | ||
544 | } | ||
545 | |||
546 | /* | ||
547 | * | ||
548 | * unsigned char dvi_get_panel_info(void) | ||
549 | * | ||
550 | * - Get Panel Size | ||
551 | * | ||
552 | * Return Type: unsigned char | ||
553 | */ | ||
554 | static unsigned char dvi_get_panel_info(void) | ||
555 | { | ||
556 | unsigned char dvipanelsize; | ||
557 | DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n"); | ||
558 | |||
559 | viafb_dvi_sense(); | ||
560 | switch (viafb_dvi_query_EDID()) { | ||
561 | case 1: | ||
562 | dvi_get_panel_size_from_DDCv1(); | ||
563 | break; | ||
564 | case 2: | ||
565 | dvi_get_panel_size_from_DDCv2(); | ||
566 | break; | 461 | break; |
567 | default: | 462 | default: |
463 | DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! " | ||
464 | "set default panel size.\n", tmds_setting->max_hres); | ||
568 | break; | 465 | break; |
569 | } | 466 | } |
570 | 467 | ||
571 | DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n", | 468 | tmds_chip->tmds_chip_slave_addr = restore; |
572 | viaparinfo->tmds_setting_info->dvi_panel_size); | ||
573 | dvipanelsize = (unsigned char)(viaparinfo-> | ||
574 | tmds_setting_info->dvi_panel_size); | ||
575 | return dvipanelsize; | ||
576 | } | 469 | } |
577 | 470 | ||
578 | /* If Disable DVI, turn off pad */ | 471 | /* If Disable DVI, turn off pad */ |
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index e1ec37fb0dc3..0dffcfd395f3 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h | |||
@@ -53,12 +53,13 @@ | |||
53 | #define DEV_CONNECT_DVI 0x01 | 53 | #define DEV_CONNECT_DVI 0x01 |
54 | #define DEV_CONNECT_HDMI 0x02 | 54 | #define DEV_CONNECT_HDMI 0x02 |
55 | 55 | ||
56 | struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index); | ||
57 | int viafb_dvi_sense(void); | 56 | int viafb_dvi_sense(void); |
58 | void viafb_dvi_disable(void); | 57 | void viafb_dvi_disable(void); |
59 | void viafb_dvi_enable(void); | 58 | void viafb_dvi_enable(void); |
60 | int viafb_tmds_trasmitter_identify(void); | 59 | int viafb_tmds_trasmitter_identify(void); |
61 | void viafb_init_dvi_size(void); | 60 | void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, |
62 | void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga); | 61 | struct tmds_setting_information *tmds_setting); |
62 | void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, | ||
63 | int set_iga); | ||
63 | 64 | ||
64 | #endif /* __DVI_H__ */ | 65 | #endif /* __DVI_H__ */ |
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c index b675cdbb03ad..1ee511b73307 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/via/global.c | |||
@@ -23,15 +23,12 @@ int viafb_platform_epia_dvi = STATE_OFF; | |||
23 | int viafb_device_lcd_dualedge = STATE_OFF; | 23 | int viafb_device_lcd_dualedge = STATE_OFF; |
24 | int viafb_bus_width = 12; | 24 | int viafb_bus_width = 12; |
25 | int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI; | 25 | int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI; |
26 | int viafb_memsize; | ||
27 | int viafb_DeviceStatus = CRT_Device; | 26 | int viafb_DeviceStatus = CRT_Device; |
28 | int viafb_hotplug; | 27 | int viafb_hotplug; |
29 | int viafb_refresh = 60; | 28 | int viafb_refresh = 60; |
30 | int viafb_refresh1 = 60; | 29 | int viafb_refresh1 = 60; |
31 | int viafb_lcd_dsp_method = LCD_EXPANDSION; | 30 | int viafb_lcd_dsp_method = LCD_EXPANDSION; |
32 | int viafb_lcd_mode = LCD_OPENLDI; | 31 | int viafb_lcd_mode = LCD_OPENLDI; |
33 | int viafb_bpp = 32; | ||
34 | int viafb_bpp1 = 32; | ||
35 | int viafb_CRT_ON = 1; | 32 | int viafb_CRT_ON = 1; |
36 | int viafb_DVI_ON; | 33 | int viafb_DVI_ON; |
37 | int viafb_LCD_ON ; | 34 | int viafb_LCD_ON ; |
@@ -42,8 +39,6 @@ int viafb_hotplug_Xres = 640; | |||
42 | int viafb_hotplug_Yres = 480; | 39 | int viafb_hotplug_Yres = 480; |
43 | int viafb_hotplug_bpp = 32; | 40 | int viafb_hotplug_bpp = 32; |
44 | int viafb_hotplug_refresh = 60; | 41 | int viafb_hotplug_refresh = 60; |
45 | unsigned int viafb_second_offset; | ||
46 | int viafb_second_size; | ||
47 | int viafb_primary_dev = None_Device; | 42 | int viafb_primary_dev = None_Device; |
48 | unsigned int viafb_second_xres = 640; | 43 | unsigned int viafb_second_xres = 640; |
49 | unsigned int viafb_second_yres = 480; | 44 | unsigned int viafb_second_yres = 480; |
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index d69d0ca99c2f..8d95d5fd1388 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | #include "debug.h" | 36 | #include "debug.h" |
37 | 37 | ||
38 | #include "iface.h" | ||
39 | #include "viafbdev.h" | 38 | #include "viafbdev.h" |
40 | #include "chip.h" | 39 | #include "chip.h" |
41 | #include "accel.h" | 40 | #include "accel.h" |
@@ -68,8 +67,6 @@ extern int viafb_refresh; | |||
68 | extern int viafb_refresh1; | 67 | extern int viafb_refresh1; |
69 | extern int viafb_lcd_dsp_method; | 68 | extern int viafb_lcd_dsp_method; |
70 | extern int viafb_lcd_mode; | 69 | extern int viafb_lcd_mode; |
71 | extern int viafb_bpp; | ||
72 | extern int viafb_bpp1; | ||
73 | 70 | ||
74 | extern int viafb_CRT_ON; | 71 | extern int viafb_CRT_ON; |
75 | extern int viafb_hotplug_Xres; | 72 | extern int viafb_hotplug_Xres; |
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 3e083ff67ae2..f2583b1b527f 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -524,7 +524,6 @@ static void dvi_patch_skew_dvp1(void); | |||
524 | static void dvi_patch_skew_dvp_low(void); | 524 | static void dvi_patch_skew_dvp_low(void); |
525 | static void set_dvi_output_path(int set_iga, int output_interface); | 525 | static void set_dvi_output_path(int set_iga, int output_interface); |
526 | static void set_lcd_output_path(int set_iga, int output_interface); | 526 | static void set_lcd_output_path(int set_iga, int output_interface); |
527 | static int search_mode_setting(int ModeInfoIndex); | ||
528 | static void load_fix_bit_crtc_reg(void); | 527 | static void load_fix_bit_crtc_reg(void); |
529 | static void init_gfx_chip_info(struct pci_dev *pdev, | 528 | static void init_gfx_chip_info(struct pci_dev *pdev, |
530 | const struct pci_device_id *pdi); | 529 | const struct pci_device_id *pdi); |
@@ -686,6 +685,84 @@ void viafb_set_secondary_pitch(u32 pitch) | |||
686 | viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80); | 685 | viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80); |
687 | } | 686 | } |
688 | 687 | ||
688 | void viafb_set_primary_color_depth(u8 depth) | ||
689 | { | ||
690 | u8 value; | ||
691 | |||
692 | DEBUG_MSG(KERN_DEBUG "viafb_set_primary_color_depth(%d)\n", depth); | ||
693 | switch (depth) { | ||
694 | case 8: | ||
695 | value = 0x00; | ||
696 | break; | ||
697 | case 15: | ||
698 | value = 0x04; | ||
699 | break; | ||
700 | case 16: | ||
701 | value = 0x14; | ||
702 | break; | ||
703 | case 24: | ||
704 | value = 0x0C; | ||
705 | break; | ||
706 | case 30: | ||
707 | value = 0x08; | ||
708 | break; | ||
709 | default: | ||
710 | printk(KERN_WARNING "viafb_set_primary_color_depth: " | ||
711 | "Unsupported depth: %d\n", depth); | ||
712 | return; | ||
713 | } | ||
714 | |||
715 | viafb_write_reg_mask(0x15, VIASR, value, 0x1C); | ||
716 | } | ||
717 | |||
718 | void viafb_set_secondary_color_depth(u8 depth) | ||
719 | { | ||
720 | u8 value; | ||
721 | |||
722 | DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_color_depth(%d)\n", depth); | ||
723 | switch (depth) { | ||
724 | case 8: | ||
725 | value = 0x00; | ||
726 | break; | ||
727 | case 16: | ||
728 | value = 0x40; | ||
729 | break; | ||
730 | case 24: | ||
731 | value = 0xC0; | ||
732 | break; | ||
733 | case 30: | ||
734 | value = 0x80; | ||
735 | break; | ||
736 | default: | ||
737 | printk(KERN_WARNING "viafb_set_secondary_color_depth: " | ||
738 | "Unsupported depth: %d\n", depth); | ||
739 | return; | ||
740 | } | ||
741 | |||
742 | viafb_write_reg_mask(0x67, VIACR, value, 0xC0); | ||
743 | } | ||
744 | |||
745 | static void set_color_register(u8 index, u8 red, u8 green, u8 blue) | ||
746 | { | ||
747 | outb(0xFF, 0x3C6); /* bit mask of palette */ | ||
748 | outb(index, 0x3C8); | ||
749 | outb(red, 0x3C9); | ||
750 | outb(green, 0x3C9); | ||
751 | outb(blue, 0x3C9); | ||
752 | } | ||
753 | |||
754 | void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue) | ||
755 | { | ||
756 | viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01); | ||
757 | set_color_register(index, red, green, blue); | ||
758 | } | ||
759 | |||
760 | void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue) | ||
761 | { | ||
762 | viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01); | ||
763 | set_color_register(index, red, green, blue); | ||
764 | } | ||
765 | |||
689 | void viafb_set_output_path(int device, int set_iga, int output_interface) | 766 | void viafb_set_output_path(int device, int set_iga, int output_interface) |
690 | { | 767 | { |
691 | switch (device) { | 768 | switch (device) { |
@@ -710,11 +787,8 @@ static void set_crt_output_path(int set_iga) | |||
710 | viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); | 787 | viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); |
711 | break; | 788 | break; |
712 | case IGA2: | 789 | case IGA2: |
713 | case IGA1_IGA2: | ||
714 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); | 790 | viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); |
715 | viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); | 791 | viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); |
716 | if (set_iga == IGA1_IGA2) | ||
717 | viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3); | ||
718 | break; | 792 | break; |
719 | } | 793 | } |
720 | } | 794 | } |
@@ -904,13 +978,6 @@ static void set_lcd_output_path(int set_iga, int output_interface) | |||
904 | 978 | ||
905 | enable_second_display_channel(); | 979 | enable_second_display_channel(); |
906 | break; | 980 | break; |
907 | |||
908 | case IGA1_IGA2: | ||
909 | viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3); | ||
910 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | ||
911 | |||
912 | disable_second_display_channel(); | ||
913 | break; | ||
914 | } | 981 | } |
915 | 982 | ||
916 | switch (output_interface) { | 983 | switch (output_interface) { |
@@ -987,49 +1054,6 @@ static void set_lcd_output_path(int set_iga, int output_interface) | |||
987 | } | 1054 | } |
988 | } | 1055 | } |
989 | 1056 | ||
990 | /* Search Mode Index */ | ||
991 | static int search_mode_setting(int ModeInfoIndex) | ||
992 | { | ||
993 | int i = 0; | ||
994 | |||
995 | while ((i < NUM_TOTAL_MODETABLE) && | ||
996 | (ModeInfoIndex != CLE266Modes[i].ModeIndex)) | ||
997 | i++; | ||
998 | if (i >= NUM_TOTAL_MODETABLE) | ||
999 | i = 0; | ||
1000 | return i; | ||
1001 | |||
1002 | } | ||
1003 | |||
1004 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index) | ||
1005 | { | ||
1006 | struct VideoModeTable *TmpTbl = NULL; | ||
1007 | TmpTbl = &CLE266Modes[search_mode_setting(Index)]; | ||
1008 | return TmpTbl; | ||
1009 | } | ||
1010 | |||
1011 | struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index) | ||
1012 | { | ||
1013 | struct VideoModeTable *TmpTbl = NULL; | ||
1014 | int i = 0; | ||
1015 | while ((i < NUM_TOTAL_CEA_MODES) && | ||
1016 | (Index != CEA_HDMI_Modes[i].ModeIndex)) | ||
1017 | i++; | ||
1018 | if ((i < NUM_TOTAL_CEA_MODES)) | ||
1019 | TmpTbl = &CEA_HDMI_Modes[i]; | ||
1020 | else { | ||
1021 | /*Still use general timing if don't find CEA timing */ | ||
1022 | i = 0; | ||
1023 | while ((i < NUM_TOTAL_MODETABLE) && | ||
1024 | (Index != CLE266Modes[i].ModeIndex)) | ||
1025 | i++; | ||
1026 | if (i >= NUM_TOTAL_MODETABLE) | ||
1027 | i = 0; | ||
1028 | TmpTbl = &CLE266Modes[i]; | ||
1029 | } | ||
1030 | return TmpTbl; | ||
1031 | } | ||
1032 | |||
1033 | static void load_fix_bit_crtc_reg(void) | 1057 | static void load_fix_bit_crtc_reg(void) |
1034 | { | 1058 | { |
1035 | /* always set to 1 */ | 1059 | /* always set to 1 */ |
@@ -1121,15 +1145,13 @@ void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) | |||
1121 | struct io_register *reg = NULL; | 1145 | struct io_register *reg = NULL; |
1122 | 1146 | ||
1123 | switch (set_iga) { | 1147 | switch (set_iga) { |
1124 | case IGA1_IGA2: | ||
1125 | case IGA1: | 1148 | case IGA1: |
1126 | reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte); | 1149 | reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte); |
1127 | viafb_load_reg_num = fetch_count_reg. | 1150 | viafb_load_reg_num = fetch_count_reg. |
1128 | iga1_fetch_count_reg.reg_num; | 1151 | iga1_fetch_count_reg.reg_num; |
1129 | reg = fetch_count_reg.iga1_fetch_count_reg.reg; | 1152 | reg = fetch_count_reg.iga1_fetch_count_reg.reg; |
1130 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); | 1153 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR); |
1131 | if (set_iga == IGA1) | 1154 | break; |
1132 | break; | ||
1133 | case IGA2: | 1155 | case IGA2: |
1134 | reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte); | 1156 | reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte); |
1135 | viafb_load_reg_num = fetch_count_reg. | 1157 | viafb_load_reg_num = fetch_count_reg. |
@@ -1499,7 +1521,7 @@ void viafb_set_vclock(u32 CLK, int set_iga) | |||
1499 | /* H.W. Reset : ON */ | 1521 | /* H.W. Reset : ON */ |
1500 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | 1522 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); |
1501 | 1523 | ||
1502 | if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) { | 1524 | if (set_iga == IGA1) { |
1503 | /* Change D,N FOR VCLK */ | 1525 | /* Change D,N FOR VCLK */ |
1504 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1526 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1505 | case UNICHROME_CLE266: | 1527 | case UNICHROME_CLE266: |
@@ -1528,7 +1550,7 @@ void viafb_set_vclock(u32 CLK, int set_iga) | |||
1528 | } | 1550 | } |
1529 | } | 1551 | } |
1530 | 1552 | ||
1531 | if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) { | 1553 | if (set_iga == IGA2) { |
1532 | /* Change D,N FOR LCK */ | 1554 | /* Change D,N FOR LCK */ |
1533 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1555 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1534 | case UNICHROME_CLE266: | 1556 | case UNICHROME_CLE266: |
@@ -1557,12 +1579,12 @@ void viafb_set_vclock(u32 CLK, int set_iga) | |||
1557 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | 1579 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); |
1558 | 1580 | ||
1559 | /* Reset PLL */ | 1581 | /* Reset PLL */ |
1560 | if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) { | 1582 | if (set_iga == IGA1) { |
1561 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | 1583 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); |
1562 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | 1584 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); |
1563 | } | 1585 | } |
1564 | 1586 | ||
1565 | if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) { | 1587 | if (set_iga == IGA2) { |
1566 | viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); | 1588 | viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); |
1567 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); | 1589 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); |
1568 | } | 1590 | } |
@@ -1805,47 +1827,15 @@ void viafb_load_crtc_timing(struct display_timing device_timing, | |||
1805 | viafb_lock_crt(); | 1827 | viafb_lock_crt(); |
1806 | } | 1828 | } |
1807 | 1829 | ||
1808 | void viafb_set_color_depth(int bpp_byte, int set_iga) | ||
1809 | { | ||
1810 | if (set_iga == IGA1) { | ||
1811 | switch (bpp_byte) { | ||
1812 | case MODE_8BPP: | ||
1813 | viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E); | ||
1814 | break; | ||
1815 | case MODE_16BPP: | ||
1816 | viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE); | ||
1817 | break; | ||
1818 | case MODE_32BPP: | ||
1819 | viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE); | ||
1820 | break; | ||
1821 | } | ||
1822 | } else { | ||
1823 | switch (bpp_byte) { | ||
1824 | case MODE_8BPP: | ||
1825 | viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7); | ||
1826 | break; | ||
1827 | case MODE_16BPP: | ||
1828 | viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7); | ||
1829 | break; | ||
1830 | case MODE_32BPP: | ||
1831 | viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7); | ||
1832 | break; | ||
1833 | } | ||
1834 | } | ||
1835 | } | ||
1836 | |||
1837 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | 1830 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, |
1838 | int mode_index, int bpp_byte, int set_iga) | 1831 | struct VideoModeTable *video_mode, int bpp_byte, int set_iga) |
1839 | { | 1832 | { |
1840 | struct VideoModeTable *video_mode; | ||
1841 | struct display_timing crt_reg; | 1833 | struct display_timing crt_reg; |
1842 | int i; | 1834 | int i; |
1843 | int index = 0; | 1835 | int index = 0; |
1844 | int h_addr, v_addr; | 1836 | int h_addr, v_addr; |
1845 | u32 pll_D_N; | 1837 | u32 pll_D_N; |
1846 | 1838 | ||
1847 | video_mode = &CLE266Modes[search_mode_setting(mode_index)]; | ||
1848 | |||
1849 | for (i = 0; i < video_mode->mode_array; i++) { | 1839 | for (i = 0; i < video_mode->mode_array; i++) { |
1850 | index = i; | 1840 | index = i; |
1851 | 1841 | ||
@@ -1858,8 +1848,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1858 | 1848 | ||
1859 | /* Mode 640x480 has border, but LCD/DFP didn't have border. */ | 1849 | /* Mode 640x480 has border, but LCD/DFP didn't have border. */ |
1860 | /* So we would delete border. */ | 1850 | /* So we would delete border. */ |
1861 | if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480) | 1851 | if ((viafb_LCD_ON | viafb_DVI_ON) |
1862 | && (viaparinfo->crt_setting_info->refresh_rate == 60)) { | 1852 | && video_mode->crtc[0].crtc.hor_addr == 640 |
1853 | && video_mode->crtc[0].crtc.ver_addr == 480 | ||
1854 | && viaparinfo->crt_setting_info->refresh_rate == 60) { | ||
1863 | /* The border is 8 pixels. */ | 1855 | /* The border is 8 pixels. */ |
1864 | crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; | 1856 | crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8; |
1865 | 1857 | ||
@@ -1912,9 +1904,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
1912 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | 1904 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) |
1913 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); | 1905 | viafb_load_FIFO_reg(set_iga, h_addr, v_addr); |
1914 | 1906 | ||
1915 | /* load SR Register About Memory and Color part */ | ||
1916 | viafb_set_color_depth(bpp_byte, set_iga); | ||
1917 | |||
1918 | pll_D_N = viafb_get_clk_value(crt_table[index].clk); | 1907 | pll_D_N = viafb_get_clk_value(crt_table[index].clk); |
1919 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); | 1908 | DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); |
1920 | viafb_set_vclock(pll_D_N, set_iga); | 1909 | viafb_set_vclock(pll_D_N, set_iga); |
@@ -1956,9 +1945,6 @@ void viafb_update_device_setting(int hres, int vres, | |||
1956 | 1945 | ||
1957 | viaparinfo->tmds_setting_info->h_active = hres; | 1946 | viaparinfo->tmds_setting_info->h_active = hres; |
1958 | viaparinfo->tmds_setting_info->v_active = vres; | 1947 | viaparinfo->tmds_setting_info->v_active = vres; |
1959 | viaparinfo->tmds_setting_info->bpp = bpp; | ||
1960 | viaparinfo->tmds_setting_info->refresh_rate = | ||
1961 | vmode_refresh; | ||
1962 | 1948 | ||
1963 | viaparinfo->lvds_setting_info->h_active = hres; | 1949 | viaparinfo->lvds_setting_info->h_active = hres; |
1964 | viaparinfo->lvds_setting_info->v_active = vres; | 1950 | viaparinfo->lvds_setting_info->v_active = vres; |
@@ -1975,9 +1961,6 @@ void viafb_update_device_setting(int hres, int vres, | |||
1975 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { | 1961 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { |
1976 | viaparinfo->tmds_setting_info->h_active = hres; | 1962 | viaparinfo->tmds_setting_info->h_active = hres; |
1977 | viaparinfo->tmds_setting_info->v_active = vres; | 1963 | viaparinfo->tmds_setting_info->v_active = vres; |
1978 | viaparinfo->tmds_setting_info->bpp = bpp; | ||
1979 | viaparinfo->tmds_setting_info->refresh_rate = | ||
1980 | vmode_refresh; | ||
1981 | } | 1964 | } |
1982 | 1965 | ||
1983 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) { | 1966 | if (viaparinfo->lvds_setting_info->iga_path == IGA2) { |
@@ -2076,9 +2059,8 @@ static void init_tmds_chip_info(void) | |||
2076 | 2059 | ||
2077 | DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n", | 2060 | DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n", |
2078 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); | 2061 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name); |
2079 | viaparinfo->tmds_setting_info->get_dvi_size_method = | 2062 | viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info, |
2080 | GET_DVI_SIZE_BY_VGA_BIOS; | 2063 | &viaparinfo->shared->tmds_setting_info); |
2081 | viafb_init_dvi_size(); | ||
2082 | } | 2064 | } |
2083 | 2065 | ||
2084 | static void init_lvds_chip_info(void) | 2066 | static void init_lvds_chip_info(void) |
@@ -2195,28 +2177,19 @@ static void set_display_channel(void) | |||
2195 | } | 2177 | } |
2196 | } | 2178 | } |
2197 | 2179 | ||
2198 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | 2180 | int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, |
2199 | int vmode_index1, int hor_res1, int ver_res1, int video_bpp1) | 2181 | struct VideoModeTable *vmode_tbl1, int video_bpp1) |
2200 | { | 2182 | { |
2201 | int i, j; | 2183 | int i, j; |
2202 | int port; | 2184 | int port; |
2203 | u8 value, index, mask; | 2185 | u8 value, index, mask; |
2204 | struct VideoModeTable *vmode_tbl; | ||
2205 | struct crt_mode_table *crt_timing; | 2186 | struct crt_mode_table *crt_timing; |
2206 | struct VideoModeTable *vmode_tbl1 = NULL; | ||
2207 | struct crt_mode_table *crt_timing1 = NULL; | 2187 | struct crt_mode_table *crt_timing1 = NULL; |
2208 | 2188 | ||
2209 | DEBUG_MSG(KERN_INFO "Set Mode!!\n"); | ||
2210 | DEBUG_MSG(KERN_INFO | ||
2211 | "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n", | ||
2212 | vmode_index, hor_res, ver_res, video_bpp); | ||
2213 | |||
2214 | device_screen_off(); | 2189 | device_screen_off(); |
2215 | vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)]; | ||
2216 | crt_timing = vmode_tbl->crtc; | 2190 | crt_timing = vmode_tbl->crtc; |
2217 | 2191 | ||
2218 | if (viafb_SAMM_ON == 1) { | 2192 | if (viafb_SAMM_ON == 1) { |
2219 | vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)]; | ||
2220 | crt_timing1 = vmode_tbl1->crtc; | 2193 | crt_timing1 = vmode_tbl1->crtc; |
2221 | } | 2194 | } |
2222 | 2195 | ||
@@ -2267,12 +2240,11 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2267 | outb(VPIT.SR[i - 1], VIASR + 1); | 2240 | outb(VPIT.SR[i - 1], VIASR + 1); |
2268 | } | 2241 | } |
2269 | 2242 | ||
2270 | viafb_set_primary_address(0); | 2243 | viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); |
2271 | viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); | ||
2272 | viafb_set_iga_path(); | 2244 | viafb_set_iga_path(); |
2273 | 2245 | ||
2274 | /* Write CRTC */ | 2246 | /* Write CRTC */ |
2275 | viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1); | 2247 | viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); |
2276 | 2248 | ||
2277 | /* Write Graphic Controller */ | 2249 | /* Write Graphic Controller */ |
2278 | for (i = 0; i < StdGR; i++) { | 2250 | for (i = 0; i < StdGR; i++) { |
@@ -2292,65 +2264,25 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2292 | 2264 | ||
2293 | /* Update Patch Register */ | 2265 | /* Update Patch Register */ |
2294 | 2266 | ||
2295 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | 2267 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266 |
2296 | || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) { | 2268 | || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400) |
2297 | for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) { | 2269 | && vmode_tbl->crtc[0].crtc.hor_addr == 1024 |
2298 | if (res_patch_table[i].mode_index == vmode_index) { | 2270 | && vmode_tbl->crtc[0].crtc.ver_addr == 768) { |
2299 | for (j = 0; | 2271 | for (j = 0; j < res_patch_table[0].table_length; j++) { |
2300 | j < res_patch_table[i].table_length; j++) { | 2272 | index = res_patch_table[0].io_reg_table[j].index; |
2301 | index = | 2273 | port = res_patch_table[0].io_reg_table[j].port; |
2302 | res_patch_table[i]. | 2274 | value = res_patch_table[0].io_reg_table[j].value; |
2303 | io_reg_table[j].index; | 2275 | mask = res_patch_table[0].io_reg_table[j].mask; |
2304 | port = | 2276 | viafb_write_reg_mask(index, port, value, mask); |
2305 | res_patch_table[i]. | ||
2306 | io_reg_table[j].port; | ||
2307 | value = | ||
2308 | res_patch_table[i]. | ||
2309 | io_reg_table[j].value; | ||
2310 | mask = | ||
2311 | res_patch_table[i]. | ||
2312 | io_reg_table[j].mask; | ||
2313 | viafb_write_reg_mask(index, port, value, | ||
2314 | mask); | ||
2315 | } | ||
2316 | } | ||
2317 | } | ||
2318 | } | ||
2319 | |||
2320 | if (viafb_SAMM_ON == 1) { | ||
2321 | if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | ||
2322 | || (viaparinfo->chip_info->gfx_chip_name == | ||
2323 | UNICHROME_K400)) { | ||
2324 | for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) { | ||
2325 | if (res_patch_table[i].mode_index == | ||
2326 | vmode_index1) { | ||
2327 | for (j = 0; | ||
2328 | j < | ||
2329 | res_patch_table[i]. | ||
2330 | table_length; j++) { | ||
2331 | index = | ||
2332 | res_patch_table[i]. | ||
2333 | io_reg_table[j].index; | ||
2334 | port = | ||
2335 | res_patch_table[i]. | ||
2336 | io_reg_table[j].port; | ||
2337 | value = | ||
2338 | res_patch_table[i]. | ||
2339 | io_reg_table[j].value; | ||
2340 | mask = | ||
2341 | res_patch_table[i]. | ||
2342 | io_reg_table[j].mask; | ||
2343 | viafb_write_reg_mask(index, | ||
2344 | port, value, mask); | ||
2345 | } | ||
2346 | } | ||
2347 | } | ||
2348 | } | 2277 | } |
2349 | } | 2278 | } |
2350 | 2279 | ||
2351 | viafb_set_primary_pitch(viafbinfo->fix.line_length); | 2280 | viafb_set_primary_pitch(viafbinfo->fix.line_length); |
2352 | viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length | 2281 | viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length |
2353 | : viafbinfo->fix.line_length); | 2282 | : viafbinfo->fix.line_length); |
2283 | viafb_set_primary_color_depth(viaparinfo->depth); | ||
2284 | viafb_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth | ||
2285 | : viaparinfo->depth); | ||
2354 | /* Update Refresh Rate Setting */ | 2286 | /* Update Refresh Rate Setting */ |
2355 | 2287 | ||
2356 | /* Clear On Screen */ | 2288 | /* Clear On Screen */ |
@@ -2359,11 +2291,11 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2359 | if (viafb_CRT_ON) { | 2291 | if (viafb_CRT_ON) { |
2360 | if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == | 2292 | if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == |
2361 | IGA2)) { | 2293 | IGA2)) { |
2362 | viafb_fill_crtc_timing(crt_timing1, vmode_index1, | 2294 | viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, |
2363 | video_bpp1 / 8, | 2295 | video_bpp1 / 8, |
2364 | viaparinfo->crt_setting_info->iga_path); | 2296 | viaparinfo->crt_setting_info->iga_path); |
2365 | } else { | 2297 | } else { |
2366 | viafb_fill_crtc_timing(crt_timing, vmode_index, | 2298 | viafb_fill_crtc_timing(crt_timing, vmode_tbl, |
2367 | video_bpp / 8, | 2299 | video_bpp / 8, |
2368 | viaparinfo->crt_setting_info->iga_path); | 2300 | viaparinfo->crt_setting_info->iga_path); |
2369 | } | 2301 | } |
@@ -2373,7 +2305,7 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2373 | /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode | 2305 | /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode |
2374 | to 8 alignment (1368),there is several pixels (2 pixels) | 2306 | to 8 alignment (1368),there is several pixels (2 pixels) |
2375 | on right side of screen. */ | 2307 | on right side of screen. */ |
2376 | if (hor_res % 8) { | 2308 | if (vmode_tbl->crtc[0].crtc.hor_addr % 8) { |
2377 | viafb_unlock_crt(); | 2309 | viafb_unlock_crt(); |
2378 | viafb_write_reg(CR02, VIACR, | 2310 | viafb_write_reg(CR02, VIACR, |
2379 | viafb_read_reg(VIACR, CR02) - 1); | 2311 | viafb_read_reg(VIACR, CR02) - 1); |
@@ -2384,14 +2316,14 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2384 | if (viafb_DVI_ON) { | 2316 | if (viafb_DVI_ON) { |
2385 | if (viafb_SAMM_ON && | 2317 | if (viafb_SAMM_ON && |
2386 | (viaparinfo->tmds_setting_info->iga_path == IGA2)) { | 2318 | (viaparinfo->tmds_setting_info->iga_path == IGA2)) { |
2387 | viafb_dvi_set_mode(viafb_get_mode_index | 2319 | viafb_dvi_set_mode(viafb_get_mode |
2388 | (viaparinfo->tmds_setting_info->h_active, | 2320 | (viaparinfo->tmds_setting_info->h_active, |
2389 | viaparinfo->tmds_setting_info-> | 2321 | viaparinfo->tmds_setting_info-> |
2390 | v_active), | 2322 | v_active), |
2391 | video_bpp1, viaparinfo-> | 2323 | video_bpp1, viaparinfo-> |
2392 | tmds_setting_info->iga_path); | 2324 | tmds_setting_info->iga_path); |
2393 | } else { | 2325 | } else { |
2394 | viafb_dvi_set_mode(viafb_get_mode_index | 2326 | viafb_dvi_set_mode(viafb_get_mode |
2395 | (viaparinfo->tmds_setting_info->h_active, | 2327 | (viaparinfo->tmds_setting_info->h_active, |
2396 | viaparinfo-> | 2328 | viaparinfo-> |
2397 | tmds_setting_info->v_active), | 2329 | tmds_setting_info->v_active), |
@@ -2445,8 +2377,8 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
2445 | 2377 | ||
2446 | /* If set mode normally, save resolution information for hot-plug . */ | 2378 | /* If set mode normally, save resolution information for hot-plug . */ |
2447 | if (!viafb_hotplug) { | 2379 | if (!viafb_hotplug) { |
2448 | viafb_hotplug_Xres = hor_res; | 2380 | viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr; |
2449 | viafb_hotplug_Yres = ver_res; | 2381 | viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr; |
2450 | viafb_hotplug_bpp = video_bpp; | 2382 | viafb_hotplug_bpp = video_bpp; |
2451 | viafb_hotplug_refresh = viafb_refresh; | 2383 | viafb_hotplug_refresh = viafb_refresh; |
2452 | 2384 | ||
@@ -2706,13 +2638,11 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | |||
2706 | 2638 | ||
2707 | /*According var's xres, yres fill var's other timing information*/ | 2639 | /*According var's xres, yres fill var's other timing information*/ |
2708 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | 2640 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
2709 | int mode_index) | 2641 | struct VideoModeTable *vmode_tbl) |
2710 | { | 2642 | { |
2711 | struct VideoModeTable *vmode_tbl = NULL; | ||
2712 | struct crt_mode_table *crt_timing = NULL; | 2643 | struct crt_mode_table *crt_timing = NULL; |
2713 | struct display_timing crt_reg; | 2644 | struct display_timing crt_reg; |
2714 | int i = 0, index = 0; | 2645 | int i = 0, index = 0; |
2715 | vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)]; | ||
2716 | crt_timing = vmode_tbl->crtc; | 2646 | crt_timing = vmode_tbl->crtc; |
2717 | for (i = 0; i < vmode_tbl->mode_array; i++) { | 2647 | for (i = 0; i < vmode_tbl->mode_array; i++) { |
2718 | index = i; | 2648 | index = i; |
@@ -2721,36 +2651,6 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | |||
2721 | } | 2651 | } |
2722 | 2652 | ||
2723 | crt_reg = crt_timing[index].crtc; | 2653 | crt_reg = crt_timing[index].crtc; |
2724 | switch (var->bits_per_pixel) { | ||
2725 | case 8: | ||
2726 | var->red.offset = 0; | ||
2727 | var->green.offset = 0; | ||
2728 | var->blue.offset = 0; | ||
2729 | var->red.length = 6; | ||
2730 | var->green.length = 6; | ||
2731 | var->blue.length = 6; | ||
2732 | break; | ||
2733 | case 16: | ||
2734 | var->red.offset = 11; | ||
2735 | var->green.offset = 5; | ||
2736 | var->blue.offset = 0; | ||
2737 | var->red.length = 5; | ||
2738 | var->green.length = 6; | ||
2739 | var->blue.length = 5; | ||
2740 | break; | ||
2741 | case 32: | ||
2742 | var->red.offset = 16; | ||
2743 | var->green.offset = 8; | ||
2744 | var->blue.offset = 0; | ||
2745 | var->red.length = 8; | ||
2746 | var->green.length = 8; | ||
2747 | var->blue.length = 8; | ||
2748 | break; | ||
2749 | default: | ||
2750 | /* never happed, put here to keep consistent */ | ||
2751 | break; | ||
2752 | } | ||
2753 | |||
2754 | var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh); | 2654 | var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh); |
2755 | var->left_margin = | 2655 | var->left_margin = |
2756 | crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); | 2656 | crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); |
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index b874d952b446..12ef32d334cb 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #ifndef __HW_H__ | 22 | #ifndef __HW_H__ |
23 | #define __HW_H__ | 23 | #define __HW_H__ |
24 | 24 | ||
25 | #include "viamode.h" | ||
25 | #include "global.h" | 26 | #include "global.h" |
26 | 27 | ||
27 | /*************************************************** | 28 | /*************************************************** |
@@ -862,8 +863,6 @@ struct pci_device_id_info { | |||
862 | }; | 863 | }; |
863 | 864 | ||
864 | extern unsigned int viafb_second_virtual_xres; | 865 | extern unsigned int viafb_second_virtual_xres; |
865 | extern unsigned int viafb_second_offset; | ||
866 | extern int viafb_second_size; | ||
867 | extern int viafb_SAMM_ON; | 866 | extern int viafb_SAMM_ON; |
868 | extern int viafb_dual_fb; | 867 | extern int viafb_dual_fb; |
869 | extern int viafb_LCD2_ON; | 868 | extern int viafb_LCD2_ON; |
@@ -874,8 +873,9 @@ extern int viafb_hotplug; | |||
874 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); | 873 | void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask); |
875 | void viafb_set_output_path(int device, int set_iga, | 874 | void viafb_set_output_path(int device, int set_iga, |
876 | int output_interface); | 875 | int output_interface); |
876 | |||
877 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | 877 | void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, |
878 | int mode_index, int bpp_byte, int set_iga); | 878 | struct VideoModeTable *video_mode, int bpp_byte, int set_iga); |
879 | 879 | ||
880 | void viafb_set_vclock(u32 CLK, int set_iga); | 880 | void viafb_set_vclock(u32 CLK, int set_iga); |
881 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, | 881 | void viafb_load_reg(int timing_value, int viafb_load_reg_num, |
@@ -891,16 +891,15 @@ void viafb_lock_crt(void); | |||
891 | void viafb_unlock_crt(void); | 891 | void viafb_unlock_crt(void); |
892 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); | 892 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); |
893 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); | 893 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); |
894 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); | ||
895 | u32 viafb_get_clk_value(int clk); | 894 | u32 viafb_get_clk_value(int clk); |
896 | void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); | 895 | void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); |
897 | void viafb_set_color_depth(int bpp_byte, int set_iga); | ||
898 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | 896 | void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ |
899 | *p_gfx_dpa_setting); | 897 | *p_gfx_dpa_setting); |
900 | 898 | ||
901 | int viafb_setmode(int vmode_index, int hor_res, int ver_res, | 899 | int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, |
902 | int video_bpp, int vmode_index1, int hor_res1, | 900 | struct VideoModeTable *vmode_tbl1, int video_bpp1); |
903 | int ver_res1, int video_bpp1); | 901 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
902 | struct VideoModeTable *vmode_tbl); | ||
904 | void viafb_init_chip_info(struct pci_dev *pdev, | 903 | void viafb_init_chip_info(struct pci_dev *pdev, |
905 | const struct pci_device_id *pdi); | 904 | const struct pci_device_id *pdi); |
906 | void viafb_init_dac(int set_iga); | 905 | void viafb_init_dac(int set_iga); |
@@ -915,6 +914,8 @@ void viafb_set_primary_address(u32 addr); | |||
915 | void viafb_set_secondary_address(u32 addr); | 914 | void viafb_set_secondary_address(u32 addr); |
916 | void viafb_set_primary_pitch(u32 pitch); | 915 | void viafb_set_primary_pitch(u32 pitch); |
917 | void viafb_set_secondary_pitch(u32 pitch); | 916 | void viafb_set_secondary_pitch(u32 pitch); |
917 | void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue); | ||
918 | void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue); | ||
918 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); | 919 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); |
919 | 920 | ||
920 | #endif /* __HW_H__ */ | 921 | #endif /* __HW_H__ */ |
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c deleted file mode 100644 index 1570636c8d51..000000000000 --- a/drivers/video/via/iface.c +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include "global.h" | ||
23 | |||
24 | /* Get frame buffer size from VGA BIOS */ | ||
25 | |||
26 | unsigned int viafb_get_memsize(void) | ||
27 | { | ||
28 | unsigned int m; | ||
29 | |||
30 | /* If memory size provided by user */ | ||
31 | if (viafb_memsize) | ||
32 | m = viafb_memsize * Mb; | ||
33 | else { | ||
34 | m = (unsigned int)viafb_read_reg(VIASR, SR39); | ||
35 | m = m * (4 * Mb); | ||
36 | |||
37 | if ((m < (16 * Mb)) || (m > (64 * Mb))) | ||
38 | m = 16 * Mb; | ||
39 | } | ||
40 | DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb); | ||
41 | return m; | ||
42 | } | ||
43 | |||
44 | /* Get Video Buffer Starting Physical Address(back door)*/ | ||
45 | |||
46 | unsigned long viafb_get_videobuf_addr(void) | ||
47 | { | ||
48 | struct pci_dev *pdev = NULL; | ||
49 | unsigned char sys_mem; | ||
50 | unsigned char video_mem; | ||
51 | unsigned long sys_mem_size; | ||
52 | unsigned long video_mem_size; | ||
53 | /*system memory = 256 MB, video memory 64 MB */ | ||
54 | unsigned long vmem_starting_adr = 0x0C000000; | ||
55 | |||
56 | pdev = | ||
57 | (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID, | ||
58 | VIA_K800_BRIDGE_DID, NULL); | ||
59 | if (pdev != NULL) { | ||
60 | pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG, | ||
61 | &sys_mem); | ||
62 | pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG, | ||
63 | &video_mem); | ||
64 | video_mem = (video_mem & 0x70) >> 4; | ||
65 | sys_mem_size = ((unsigned long)sys_mem) << 24; | ||
66 | if (video_mem != 0) | ||
67 | video_mem_size = (1 << (video_mem)) * 1024 * 1024; | ||
68 | else | ||
69 | video_mem_size = 0; | ||
70 | |||
71 | vmem_starting_adr = sys_mem_size - video_mem_size; | ||
72 | pci_dev_put(pdev); | ||
73 | } | ||
74 | |||
75 | DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n", | ||
76 | vmem_starting_adr); | ||
77 | return vmem_starting_adr; | ||
78 | } | ||
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h deleted file mode 100644 index 790ec3e3aea2..000000000000 --- a/drivers/video/via/iface.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | ||
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | ||
4 | |||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * either version 2, or (at your option) any later version. | ||
9 | |||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | ||
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | ||
14 | * for more details. | ||
15 | |||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __IFACE_H__ | ||
23 | #define __IFACE_H__ | ||
24 | |||
25 | #define Kb (1024) | ||
26 | #define Mb (Kb*Kb) | ||
27 | |||
28 | #define VIA_K800_BRIDGE_VID 0x1106 | ||
29 | #define VIA_K800_BRIDGE_DID 0x3204 | ||
30 | |||
31 | #define VIA_K800_SYSTEM_MEMORY_REG 0x47 | ||
32 | #define VIA_K800_VIDEO_MEMORY_REG 0xA1 | ||
33 | |||
34 | extern int viafb_memsize; | ||
35 | unsigned int viafb_get_memsize(void); | ||
36 | unsigned long viafb_get_videobuf_addr(void); | ||
37 | |||
38 | #endif /* __IFACE_H__ */ | ||
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 09353e2b92f6..1b1ccdc2d83d 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
@@ -22,25 +22,7 @@ | |||
22 | #include "global.h" | 22 | #include "global.h" |
23 | #include "lcdtbl.h" | 23 | #include "lcdtbl.h" |
24 | 24 | ||
25 | static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = { | 25 | #define viafb_compact_res(x, y) (((x)<<16)|(y)) |
26 | /* IGA2 Shadow Horizontal Total */ | ||
27 | {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } }, | ||
28 | /* IGA2 Shadow Horizontal Blank End */ | ||
29 | {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } }, | ||
30 | /* IGA2 Shadow Vertical Total */ | ||
31 | {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } }, | ||
32 | /* IGA2 Shadow Vertical Addressable Video */ | ||
33 | {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } }, | ||
34 | /* IGA2 Shadow Vertical Blank Start */ | ||
35 | {IGA2_SHADOW_VER_BLANK_START_REG_NUM, | ||
36 | {{CR72, 0, 7}, {CR74, 4, 6} } }, | ||
37 | /* IGA2 Shadow Vertical Blank End */ | ||
38 | {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } }, | ||
39 | /* IGA2 Shadow Vertical Sync Start */ | ||
40 | {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } }, | ||
41 | /* IGA2 Shadow Vertical Sync End */ | ||
42 | {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } } | ||
43 | }; | ||
44 | 26 | ||
45 | static struct _lcd_scaling_factor lcd_scaling_factor = { | 27 | static struct _lcd_scaling_factor lcd_scaling_factor = { |
46 | /* LCD Horizontal Scaling Factor Register */ | 28 | /* LCD Horizontal Scaling Factor Register */ |
@@ -59,16 +41,10 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { | |||
59 | 41 | ||
60 | static int check_lvds_chip(int device_id_subaddr, int device_id); | 42 | static int check_lvds_chip(int device_id_subaddr, int device_id); |
61 | static bool lvds_identify_integratedlvds(void); | 43 | static bool lvds_identify_integratedlvds(void); |
62 | static int fp_id_to_vindex(int panel_id); | 44 | static void fp_id_to_vindex(int panel_id); |
63 | static int lvds_register_read(int index); | 45 | static int lvds_register_read(int index); |
64 | static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, | 46 | static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, |
65 | int panel_vres); | 47 | int panel_vres); |
66 | static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, | ||
67 | int panel_id); | ||
68 | static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, | ||
69 | int panel_id); | ||
70 | static void load_lcd_patch_regs(int set_hres, int set_vres, | ||
71 | int panel_id, int set_iga); | ||
72 | static void via_pitch_alignment_patch_lcd( | 48 | static void via_pitch_alignment_patch_lcd( |
73 | struct lvds_setting_information *plvds_setting_info, | 49 | struct lvds_setting_information *plvds_setting_info, |
74 | struct lvds_chip_information | 50 | struct lvds_chip_information |
@@ -98,8 +74,6 @@ static void check_diport_of_integrated_lvds( | |||
98 | static struct display_timing lcd_centering_timging(struct display_timing | 74 | static struct display_timing lcd_centering_timging(struct display_timing |
99 | mode_crt_reg, | 75 | mode_crt_reg, |
100 | struct display_timing panel_crt_reg); | 76 | struct display_timing panel_crt_reg); |
101 | static void load_crtc_shadow_timing(struct display_timing mode_timing, | ||
102 | struct display_timing panel_timing); | ||
103 | static void viafb_load_scaling_factor_for_p4m900(int set_hres, | 77 | static void viafb_load_scaling_factor_for_p4m900(int set_hres, |
104 | int set_vres, int panel_hres, int panel_vres); | 78 | int set_vres, int panel_hres, int panel_vres); |
105 | 79 | ||
@@ -125,33 +99,24 @@ void viafb_init_lcd_size(void) | |||
125 | break; | 99 | break; |
126 | case GET_LCD_SIZE_BY_VGA_BIOS: | 100 | case GET_LCD_SIZE_BY_VGA_BIOS: |
127 | DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); | 101 | DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n"); |
128 | viaparinfo->lvds_setting_info->lcd_panel_size = | 102 | fp_id_to_vindex(viafb_lcd_panel_id); |
129 | fp_id_to_vindex(viafb_lcd_panel_id); | ||
130 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", | 103 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", |
131 | viaparinfo->lvds_setting_info->lcd_panel_id); | 104 | viaparinfo->lvds_setting_info->lcd_panel_id); |
132 | DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", | ||
133 | viaparinfo->lvds_setting_info->lcd_panel_size); | ||
134 | break; | 105 | break; |
135 | case GET_LCD_SIZE_BY_USER_SETTING: | 106 | case GET_LCD_SIZE_BY_USER_SETTING: |
136 | DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); | 107 | DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n"); |
137 | viaparinfo->lvds_setting_info->lcd_panel_size = | 108 | fp_id_to_vindex(viafb_lcd_panel_id); |
138 | fp_id_to_vindex(viafb_lcd_panel_id); | ||
139 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", | 109 | DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n", |
140 | viaparinfo->lvds_setting_info->lcd_panel_id); | 110 | viaparinfo->lvds_setting_info->lcd_panel_id); |
141 | DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n", | ||
142 | viaparinfo->lvds_setting_info->lcd_panel_size); | ||
143 | break; | 111 | break; |
144 | default: | 112 | default: |
145 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n"); | 113 | DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n"); |
146 | viaparinfo->lvds_setting_info->lcd_panel_id = | 114 | viaparinfo->lvds_setting_info->lcd_panel_id = |
147 | LCD_PANEL_ID1_800X600; | 115 | LCD_PANEL_ID1_800X600; |
148 | viaparinfo->lvds_setting_info->lcd_panel_size = | 116 | fp_id_to_vindex(LCD_PANEL_ID1_800X600); |
149 | fp_id_to_vindex(LCD_PANEL_ID1_800X600); | ||
150 | } | 117 | } |
151 | viaparinfo->lvds_setting_info2->lcd_panel_id = | 118 | viaparinfo->lvds_setting_info2->lcd_panel_id = |
152 | viaparinfo->lvds_setting_info->lcd_panel_id; | 119 | viaparinfo->lvds_setting_info->lcd_panel_id; |
153 | viaparinfo->lvds_setting_info2->lcd_panel_size = | ||
154 | viaparinfo->lvds_setting_info->lcd_panel_size; | ||
155 | viaparinfo->lvds_setting_info2->lcd_panel_hres = | 120 | viaparinfo->lvds_setting_info2->lcd_panel_hres = |
156 | viaparinfo->lvds_setting_info->lcd_panel_hres; | 121 | viaparinfo->lvds_setting_info->lcd_panel_hres; |
157 | viaparinfo->lvds_setting_info2->lcd_panel_vres = | 122 | viaparinfo->lvds_setting_info2->lcd_panel_vres = |
@@ -171,13 +136,13 @@ static bool lvds_identify_integratedlvds(void) | |||
171 | if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { | 136 | if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) { |
172 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = | 137 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = |
173 | INTEGRATED_LVDS; | 138 | INTEGRATED_LVDS; |
174 | DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\ | 139 | DEBUG_MSG(KERN_INFO "Support two dual channel LVDS! " |
175 | (Internal LVDS + External LVDS)\n"); | 140 | "(Internal LVDS + External LVDS)\n"); |
176 | } else { | 141 | } else { |
177 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | 142 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = |
178 | INTEGRATED_LVDS; | 143 | INTEGRATED_LVDS; |
179 | DEBUG_MSG(KERN_INFO "Not found external LVDS,\ | 144 | DEBUG_MSG(KERN_INFO "Not found external LVDS, " |
180 | so can't support two dual channel LVDS!\n"); | 145 | "so can't support two dual channel LVDS!\n"); |
181 | } | 146 | } |
182 | } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { | 147 | } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) { |
183 | /* Two single channel LCD (Internal LVDS + Internal LVDS): */ | 148 | /* Two single channel LCD (Internal LVDS + Internal LVDS): */ |
@@ -185,8 +150,8 @@ static bool lvds_identify_integratedlvds(void) | |||
185 | INTEGRATED_LVDS; | 150 | INTEGRATED_LVDS; |
186 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = | 151 | viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name = |
187 | INTEGRATED_LVDS; | 152 | INTEGRATED_LVDS; |
188 | DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\ | 153 | DEBUG_MSG(KERN_INFO "Support two single channel LVDS! " |
189 | (Internal LVDS + Internal LVDS)\n"); | 154 | "(Internal LVDS + Internal LVDS)\n"); |
190 | } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { | 155 | } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) { |
191 | /* If we have found external LVDS, just use it, | 156 | /* If we have found external LVDS, just use it, |
192 | otherwise, we will use internal LVDS as default. */ | 157 | otherwise, we will use internal LVDS as default. */ |
@@ -248,7 +213,7 @@ int viafb_lvds_trasmitter_identify(void) | |||
248 | return FAIL; | 213 | return FAIL; |
249 | } | 214 | } |
250 | 215 | ||
251 | static int fp_id_to_vindex(int panel_id) | 216 | static void fp_id_to_vindex(int panel_id) |
252 | { | 217 | { |
253 | DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); | 218 | DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); |
254 | 219 | ||
@@ -264,7 +229,6 @@ static int fp_id_to_vindex(int panel_id) | |||
264 | LCD_PANEL_ID0_640X480; | 229 | LCD_PANEL_ID0_640X480; |
265 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 230 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
266 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 231 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
267 | return VIA_RES_640X480; | ||
268 | break; | 232 | break; |
269 | case 0x1: | 233 | case 0x1: |
270 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 234 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
@@ -273,7 +237,6 @@ static int fp_id_to_vindex(int panel_id) | |||
273 | LCD_PANEL_ID1_800X600; | 237 | LCD_PANEL_ID1_800X600; |
274 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 238 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
275 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 239 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
276 | return VIA_RES_800X600; | ||
277 | break; | 240 | break; |
278 | case 0x2: | 241 | case 0x2: |
279 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 242 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
@@ -282,7 +245,6 @@ static int fp_id_to_vindex(int panel_id) | |||
282 | LCD_PANEL_ID2_1024X768; | 245 | LCD_PANEL_ID2_1024X768; |
283 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 246 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
284 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 247 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
285 | return VIA_RES_1024X768; | ||
286 | break; | 248 | break; |
287 | case 0x3: | 249 | case 0x3: |
288 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 250 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -291,7 +253,6 @@ static int fp_id_to_vindex(int panel_id) | |||
291 | LCD_PANEL_ID3_1280X768; | 253 | LCD_PANEL_ID3_1280X768; |
292 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 254 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
293 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 255 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
294 | return VIA_RES_1280X768; | ||
295 | break; | 256 | break; |
296 | case 0x4: | 257 | case 0x4: |
297 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 258 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -300,7 +261,6 @@ static int fp_id_to_vindex(int panel_id) | |||
300 | LCD_PANEL_ID4_1280X1024; | 261 | LCD_PANEL_ID4_1280X1024; |
301 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 262 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
302 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 263 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
303 | return VIA_RES_1280X1024; | ||
304 | break; | 264 | break; |
305 | case 0x5: | 265 | case 0x5: |
306 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | 266 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; |
@@ -309,7 +269,6 @@ static int fp_id_to_vindex(int panel_id) | |||
309 | LCD_PANEL_ID5_1400X1050; | 269 | LCD_PANEL_ID5_1400X1050; |
310 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 270 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
311 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 271 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
312 | return VIA_RES_1400X1050; | ||
313 | break; | 272 | break; |
314 | case 0x6: | 273 | case 0x6: |
315 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | 274 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; |
@@ -318,7 +277,6 @@ static int fp_id_to_vindex(int panel_id) | |||
318 | LCD_PANEL_ID6_1600X1200; | 277 | LCD_PANEL_ID6_1600X1200; |
319 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 278 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
320 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 279 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
321 | return VIA_RES_1600X1200; | ||
322 | break; | 280 | break; |
323 | case 0x8: | 281 | case 0x8: |
324 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 282 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
@@ -327,7 +285,6 @@ static int fp_id_to_vindex(int panel_id) | |||
327 | LCD_PANEL_IDA_800X480; | 285 | LCD_PANEL_IDA_800X480; |
328 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 286 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
329 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 287 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
330 | return VIA_RES_800X480; | ||
331 | break; | 288 | break; |
332 | case 0x9: | 289 | case 0x9: |
333 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 290 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
@@ -336,7 +293,6 @@ static int fp_id_to_vindex(int panel_id) | |||
336 | LCD_PANEL_ID2_1024X768; | 293 | LCD_PANEL_ID2_1024X768; |
337 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 294 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
338 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 295 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
339 | return VIA_RES_1024X768; | ||
340 | break; | 296 | break; |
341 | case 0xA: | 297 | case 0xA: |
342 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 298 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
@@ -345,7 +301,6 @@ static int fp_id_to_vindex(int panel_id) | |||
345 | LCD_PANEL_ID2_1024X768; | 301 | LCD_PANEL_ID2_1024X768; |
346 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 302 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
347 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 303 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
348 | return VIA_RES_1024X768; | ||
349 | break; | 304 | break; |
350 | case 0xB: | 305 | case 0xB: |
351 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 306 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
@@ -354,7 +309,6 @@ static int fp_id_to_vindex(int panel_id) | |||
354 | LCD_PANEL_ID2_1024X768; | 309 | LCD_PANEL_ID2_1024X768; |
355 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 310 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
356 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 311 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
357 | return VIA_RES_1024X768; | ||
358 | break; | 312 | break; |
359 | case 0xC: | 313 | case 0xC: |
360 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 314 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -363,7 +317,6 @@ static int fp_id_to_vindex(int panel_id) | |||
363 | LCD_PANEL_ID3_1280X768; | 317 | LCD_PANEL_ID3_1280X768; |
364 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 318 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
365 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 319 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
366 | return VIA_RES_1280X768; | ||
367 | break; | 320 | break; |
368 | case 0xD: | 321 | case 0xD: |
369 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 322 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -372,7 +325,6 @@ static int fp_id_to_vindex(int panel_id) | |||
372 | LCD_PANEL_ID4_1280X1024; | 325 | LCD_PANEL_ID4_1280X1024; |
373 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 326 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
374 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 327 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
375 | return VIA_RES_1280X1024; | ||
376 | break; | 328 | break; |
377 | case 0xE: | 329 | case 0xE: |
378 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; | 330 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1400; |
@@ -381,7 +333,6 @@ static int fp_id_to_vindex(int panel_id) | |||
381 | LCD_PANEL_ID5_1400X1050; | 333 | LCD_PANEL_ID5_1400X1050; |
382 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 334 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
383 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 335 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
384 | return VIA_RES_1400X1050; | ||
385 | break; | 336 | break; |
386 | case 0xF: | 337 | case 0xF: |
387 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; | 338 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1600; |
@@ -390,7 +341,6 @@ static int fp_id_to_vindex(int panel_id) | |||
390 | LCD_PANEL_ID6_1600X1200; | 341 | LCD_PANEL_ID6_1600X1200; |
391 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 342 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
392 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 343 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
393 | return VIA_RES_1600X1200; | ||
394 | break; | 344 | break; |
395 | case 0x10: | 345 | case 0x10: |
396 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; | 346 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1366; |
@@ -399,7 +349,6 @@ static int fp_id_to_vindex(int panel_id) | |||
399 | LCD_PANEL_ID7_1366X768; | 349 | LCD_PANEL_ID7_1366X768; |
400 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 350 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
401 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 351 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
402 | return VIA_RES_1368X768; | ||
403 | break; | 352 | break; |
404 | case 0x11: | 353 | case 0x11: |
405 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; | 354 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1024; |
@@ -408,7 +357,6 @@ static int fp_id_to_vindex(int panel_id) | |||
408 | LCD_PANEL_ID8_1024X600; | 357 | LCD_PANEL_ID8_1024X600; |
409 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 358 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
410 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 359 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
411 | return VIA_RES_1024X600; | ||
412 | break; | 360 | break; |
413 | case 0x12: | 361 | case 0x12: |
414 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 362 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -417,7 +365,6 @@ static int fp_id_to_vindex(int panel_id) | |||
417 | LCD_PANEL_ID3_1280X768; | 365 | LCD_PANEL_ID3_1280X768; |
418 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 366 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
419 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 367 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
420 | return VIA_RES_1280X768; | ||
421 | break; | 368 | break; |
422 | case 0x13: | 369 | case 0x13: |
423 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 370 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -426,7 +373,6 @@ static int fp_id_to_vindex(int panel_id) | |||
426 | LCD_PANEL_ID9_1280X800; | 373 | LCD_PANEL_ID9_1280X800; |
427 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 374 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
428 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 375 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
429 | return VIA_RES_1280X800; | ||
430 | break; | 376 | break; |
431 | case 0x14: | 377 | case 0x14: |
432 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; | 378 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1360; |
@@ -435,7 +381,6 @@ static int fp_id_to_vindex(int panel_id) | |||
435 | LCD_PANEL_IDB_1360X768; | 381 | LCD_PANEL_IDB_1360X768; |
436 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 382 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
437 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 383 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
438 | return VIA_RES_1360X768; | ||
439 | break; | 384 | break; |
440 | case 0x15: | 385 | case 0x15: |
441 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; | 386 | viaparinfo->lvds_setting_info->lcd_panel_hres = 1280; |
@@ -444,7 +389,6 @@ static int fp_id_to_vindex(int panel_id) | |||
444 | LCD_PANEL_ID3_1280X768; | 389 | LCD_PANEL_ID3_1280X768; |
445 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; | 390 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 1; |
446 | viaparinfo->lvds_setting_info->LCDDithering = 0; | 391 | viaparinfo->lvds_setting_info->LCDDithering = 0; |
447 | return VIA_RES_1280X768; | ||
448 | break; | 392 | break; |
449 | case 0x16: | 393 | case 0x16: |
450 | viaparinfo->lvds_setting_info->lcd_panel_hres = 480; | 394 | viaparinfo->lvds_setting_info->lcd_panel_hres = 480; |
@@ -453,7 +397,6 @@ static int fp_id_to_vindex(int panel_id) | |||
453 | LCD_PANEL_IDC_480X640; | 397 | LCD_PANEL_IDC_480X640; |
454 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 398 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
455 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 399 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
456 | return VIA_RES_480X640; | ||
457 | break; | 400 | break; |
458 | default: | 401 | default: |
459 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; | 402 | viaparinfo->lvds_setting_info->lcd_panel_hres = 800; |
@@ -462,7 +405,6 @@ static int fp_id_to_vindex(int panel_id) | |||
462 | LCD_PANEL_ID1_800X600; | 405 | LCD_PANEL_ID1_800X600; |
463 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; | 406 | viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; |
464 | viaparinfo->lvds_setting_info->LCDDithering = 1; | 407 | viaparinfo->lvds_setting_info->LCDDithering = 1; |
465 | return VIA_RES_800X600; | ||
466 | } | 408 | } |
467 | } | 409 | } |
468 | 410 | ||
@@ -573,284 +515,6 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, | |||
573 | } | 515 | } |
574 | } | 516 | } |
575 | 517 | ||
576 | static void load_lcd_k400_patch_tbl(int set_hres, int set_vres, | ||
577 | int panel_id) | ||
578 | { | ||
579 | int vmode_index; | ||
580 | int reg_num = 0; | ||
581 | struct io_reg *lcd_patch_reg = NULL; | ||
582 | |||
583 | vmode_index = viafb_get_mode_index(set_hres, set_vres); | ||
584 | switch (panel_id) { | ||
585 | /* LCD 800x600 */ | ||
586 | case LCD_PANEL_ID1_800X600: | ||
587 | switch (vmode_index) { | ||
588 | case VIA_RES_640X400: | ||
589 | case VIA_RES_640X480: | ||
590 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6; | ||
591 | lcd_patch_reg = K400_LCD_RES_6X4_8X6; | ||
592 | break; | ||
593 | case VIA_RES_720X480: | ||
594 | case VIA_RES_720X576: | ||
595 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6; | ||
596 | lcd_patch_reg = K400_LCD_RES_7X4_8X6; | ||
597 | break; | ||
598 | } | ||
599 | break; | ||
600 | |||
601 | /* LCD 1024x768 */ | ||
602 | case LCD_PANEL_ID2_1024X768: | ||
603 | switch (vmode_index) { | ||
604 | case VIA_RES_640X400: | ||
605 | case VIA_RES_640X480: | ||
606 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7; | ||
607 | lcd_patch_reg = K400_LCD_RES_6X4_10X7; | ||
608 | break; | ||
609 | case VIA_RES_720X480: | ||
610 | case VIA_RES_720X576: | ||
611 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7; | ||
612 | lcd_patch_reg = K400_LCD_RES_7X4_10X7; | ||
613 | break; | ||
614 | case VIA_RES_800X600: | ||
615 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7; | ||
616 | lcd_patch_reg = K400_LCD_RES_8X6_10X7; | ||
617 | break; | ||
618 | } | ||
619 | break; | ||
620 | |||
621 | /* LCD 1280x1024 */ | ||
622 | case LCD_PANEL_ID4_1280X1024: | ||
623 | switch (vmode_index) { | ||
624 | case VIA_RES_640X400: | ||
625 | case VIA_RES_640X480: | ||
626 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10; | ||
627 | lcd_patch_reg = K400_LCD_RES_6X4_12X10; | ||
628 | break; | ||
629 | case VIA_RES_720X480: | ||
630 | case VIA_RES_720X576: | ||
631 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10; | ||
632 | lcd_patch_reg = K400_LCD_RES_7X4_12X10; | ||
633 | break; | ||
634 | case VIA_RES_800X600: | ||
635 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10; | ||
636 | lcd_patch_reg = K400_LCD_RES_8X6_12X10; | ||
637 | break; | ||
638 | case VIA_RES_1024X768: | ||
639 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10; | ||
640 | lcd_patch_reg = K400_LCD_RES_10X7_12X10; | ||
641 | break; | ||
642 | |||
643 | } | ||
644 | break; | ||
645 | |||
646 | /* LCD 1400x1050 */ | ||
647 | case LCD_PANEL_ID5_1400X1050: | ||
648 | switch (vmode_index) { | ||
649 | case VIA_RES_640X480: | ||
650 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10; | ||
651 | lcd_patch_reg = K400_LCD_RES_6X4_14X10; | ||
652 | break; | ||
653 | case VIA_RES_800X600: | ||
654 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10; | ||
655 | lcd_patch_reg = K400_LCD_RES_8X6_14X10; | ||
656 | break; | ||
657 | case VIA_RES_1024X768: | ||
658 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10; | ||
659 | lcd_patch_reg = K400_LCD_RES_10X7_14X10; | ||
660 | break; | ||
661 | case VIA_RES_1280X768: | ||
662 | case VIA_RES_1280X800: | ||
663 | case VIA_RES_1280X960: | ||
664 | case VIA_RES_1280X1024: | ||
665 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10; | ||
666 | lcd_patch_reg = K400_LCD_RES_12X10_14X10; | ||
667 | break; | ||
668 | } | ||
669 | break; | ||
670 | |||
671 | /* LCD 1600x1200 */ | ||
672 | case LCD_PANEL_ID6_1600X1200: | ||
673 | switch (vmode_index) { | ||
674 | case VIA_RES_640X400: | ||
675 | case VIA_RES_640X480: | ||
676 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12; | ||
677 | lcd_patch_reg = K400_LCD_RES_6X4_16X12; | ||
678 | break; | ||
679 | case VIA_RES_720X480: | ||
680 | case VIA_RES_720X576: | ||
681 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12; | ||
682 | lcd_patch_reg = K400_LCD_RES_7X4_16X12; | ||
683 | break; | ||
684 | case VIA_RES_800X600: | ||
685 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12; | ||
686 | lcd_patch_reg = K400_LCD_RES_8X6_16X12; | ||
687 | break; | ||
688 | case VIA_RES_1024X768: | ||
689 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12; | ||
690 | lcd_patch_reg = K400_LCD_RES_10X7_16X12; | ||
691 | break; | ||
692 | case VIA_RES_1280X768: | ||
693 | case VIA_RES_1280X800: | ||
694 | case VIA_RES_1280X960: | ||
695 | case VIA_RES_1280X1024: | ||
696 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12; | ||
697 | lcd_patch_reg = K400_LCD_RES_12X10_16X12; | ||
698 | break; | ||
699 | } | ||
700 | break; | ||
701 | |||
702 | /* LCD 1366x768 */ | ||
703 | case LCD_PANEL_ID7_1366X768: | ||
704 | switch (vmode_index) { | ||
705 | case VIA_RES_640X480: | ||
706 | reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7; | ||
707 | lcd_patch_reg = K400_LCD_RES_6X4_1366X7; | ||
708 | break; | ||
709 | case VIA_RES_720X480: | ||
710 | case VIA_RES_720X576: | ||
711 | reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7; | ||
712 | lcd_patch_reg = K400_LCD_RES_7X4_1366X7; | ||
713 | break; | ||
714 | case VIA_RES_800X600: | ||
715 | reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7; | ||
716 | lcd_patch_reg = K400_LCD_RES_8X6_1366X7; | ||
717 | break; | ||
718 | case VIA_RES_1024X768: | ||
719 | reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7; | ||
720 | lcd_patch_reg = K400_LCD_RES_10X7_1366X7; | ||
721 | break; | ||
722 | case VIA_RES_1280X768: | ||
723 | case VIA_RES_1280X800: | ||
724 | case VIA_RES_1280X960: | ||
725 | case VIA_RES_1280X1024: | ||
726 | reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7; | ||
727 | lcd_patch_reg = K400_LCD_RES_12X10_1366X7; | ||
728 | break; | ||
729 | } | ||
730 | break; | ||
731 | |||
732 | /* LCD 1360x768 */ | ||
733 | case LCD_PANEL_IDB_1360X768: | ||
734 | break; | ||
735 | } | ||
736 | if (reg_num != 0) { | ||
737 | /* H.W. Reset : ON */ | ||
738 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
739 | |||
740 | viafb_write_regx(lcd_patch_reg, reg_num); | ||
741 | |||
742 | /* H.W. Reset : OFF */ | ||
743 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
744 | |||
745 | /* Reset PLL */ | ||
746 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
747 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
748 | |||
749 | /* Fire! */ | ||
750 | outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); | ||
751 | } | ||
752 | } | ||
753 | |||
754 | static void load_lcd_p880_patch_tbl(int set_hres, int set_vres, | ||
755 | int panel_id) | ||
756 | { | ||
757 | int vmode_index; | ||
758 | int reg_num = 0; | ||
759 | struct io_reg *lcd_patch_reg = NULL; | ||
760 | |||
761 | vmode_index = viafb_get_mode_index(set_hres, set_vres); | ||
762 | |||
763 | switch (panel_id) { | ||
764 | case LCD_PANEL_ID5_1400X1050: | ||
765 | switch (vmode_index) { | ||
766 | case VIA_RES_640X480: | ||
767 | reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10; | ||
768 | lcd_patch_reg = P880_LCD_RES_6X4_14X10; | ||
769 | break; | ||
770 | case VIA_RES_800X600: | ||
771 | reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10; | ||
772 | lcd_patch_reg = P880_LCD_RES_8X6_14X10; | ||
773 | break; | ||
774 | } | ||
775 | break; | ||
776 | case LCD_PANEL_ID6_1600X1200: | ||
777 | switch (vmode_index) { | ||
778 | case VIA_RES_640X400: | ||
779 | case VIA_RES_640X480: | ||
780 | reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12; | ||
781 | lcd_patch_reg = P880_LCD_RES_6X4_16X12; | ||
782 | break; | ||
783 | case VIA_RES_720X480: | ||
784 | case VIA_RES_720X576: | ||
785 | reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12; | ||
786 | lcd_patch_reg = P880_LCD_RES_7X4_16X12; | ||
787 | break; | ||
788 | case VIA_RES_800X600: | ||
789 | reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12; | ||
790 | lcd_patch_reg = P880_LCD_RES_8X6_16X12; | ||
791 | break; | ||
792 | case VIA_RES_1024X768: | ||
793 | reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12; | ||
794 | lcd_patch_reg = P880_LCD_RES_10X7_16X12; | ||
795 | break; | ||
796 | case VIA_RES_1280X768: | ||
797 | case VIA_RES_1280X960: | ||
798 | case VIA_RES_1280X1024: | ||
799 | reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12; | ||
800 | lcd_patch_reg = P880_LCD_RES_12X10_16X12; | ||
801 | break; | ||
802 | } | ||
803 | break; | ||
804 | |||
805 | } | ||
806 | if (reg_num != 0) { | ||
807 | /* H.W. Reset : ON */ | ||
808 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
809 | |||
810 | viafb_write_regx(lcd_patch_reg, reg_num); | ||
811 | |||
812 | /* H.W. Reset : OFF */ | ||
813 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
814 | |||
815 | /* Reset PLL */ | ||
816 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
817 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
818 | |||
819 | /* Fire! */ | ||
820 | outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | static void load_lcd_patch_regs(int set_hres, int set_vres, | ||
825 | int panel_id, int set_iga) | ||
826 | { | ||
827 | int vmode_index; | ||
828 | |||
829 | vmode_index = viafb_get_mode_index(set_hres, set_vres); | ||
830 | |||
831 | viafb_unlock_crt(); | ||
832 | |||
833 | /* Patch for simultaneous & Expansion */ | ||
834 | if ((set_iga == IGA1_IGA2) && | ||
835 | (viaparinfo->lvds_setting_info->display_method == | ||
836 | LCD_EXPANDSION)) { | ||
837 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
838 | case UNICHROME_CLE266: | ||
839 | case UNICHROME_K400: | ||
840 | load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id); | ||
841 | break; | ||
842 | case UNICHROME_K800: | ||
843 | break; | ||
844 | case UNICHROME_PM800: | ||
845 | case UNICHROME_CN700: | ||
846 | case UNICHROME_CX700: | ||
847 | load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id); | ||
848 | } | ||
849 | } | ||
850 | |||
851 | viafb_lock_crt(); | ||
852 | } | ||
853 | |||
854 | static void via_pitch_alignment_patch_lcd( | 518 | static void via_pitch_alignment_patch_lcd( |
855 | struct lvds_setting_information *plvds_setting_info, | 519 | struct lvds_setting_information *plvds_setting_info, |
856 | struct lvds_chip_information | 520 | struct lvds_chip_information |
@@ -949,29 +613,25 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
949 | struct lvds_setting_information *plvds_setting_info, | 613 | struct lvds_setting_information *plvds_setting_info, |
950 | struct lvds_chip_information *plvds_chip_info) | 614 | struct lvds_chip_information *plvds_chip_info) |
951 | { | 615 | { |
952 | int video_index = plvds_setting_info->lcd_panel_size; | ||
953 | int set_iga = plvds_setting_info->iga_path; | 616 | int set_iga = plvds_setting_info->iga_path; |
954 | int mode_bpp = plvds_setting_info->bpp; | 617 | int mode_bpp = plvds_setting_info->bpp; |
955 | int set_hres, set_vres; | 618 | int set_hres = plvds_setting_info->h_active; |
956 | int panel_hres, panel_vres; | 619 | int set_vres = plvds_setting_info->v_active; |
620 | int panel_hres = plvds_setting_info->lcd_panel_hres; | ||
621 | int panel_vres = plvds_setting_info->lcd_panel_vres; | ||
957 | u32 pll_D_N; | 622 | u32 pll_D_N; |
958 | int offset; | ||
959 | struct display_timing mode_crt_reg, panel_crt_reg; | 623 | struct display_timing mode_crt_reg, panel_crt_reg; |
960 | struct crt_mode_table *panel_crt_table = NULL; | 624 | struct crt_mode_table *panel_crt_table = NULL; |
961 | struct VideoModeTable *vmode_tbl = NULL; | 625 | struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, |
626 | panel_vres); | ||
962 | 627 | ||
963 | DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); | 628 | DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); |
964 | /* Get mode table */ | 629 | /* Get mode table */ |
965 | mode_crt_reg = mode_crt_table->crtc; | 630 | mode_crt_reg = mode_crt_table->crtc; |
966 | /* Get panel table Pointer */ | 631 | /* Get panel table Pointer */ |
967 | vmode_tbl = viafb_get_modetbl_pointer(video_index); | ||
968 | panel_crt_table = vmode_tbl->crtc; | 632 | panel_crt_table = vmode_tbl->crtc; |
969 | panel_crt_reg = panel_crt_table->crtc; | 633 | panel_crt_reg = panel_crt_table->crtc; |
970 | DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); | 634 | DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); |
971 | set_hres = plvds_setting_info->h_active; | ||
972 | set_vres = plvds_setting_info->v_active; | ||
973 | panel_hres = plvds_setting_info->lcd_panel_hres; | ||
974 | panel_vres = plvds_setting_info->lcd_panel_vres; | ||
975 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) | 635 | if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) |
976 | viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); | 636 | viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info); |
977 | plvds_setting_info->vclk = panel_crt_table->clk; | 637 | plvds_setting_info->vclk = panel_crt_table->clk; |
@@ -1001,54 +661,12 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
1001 | } | 661 | } |
1002 | } | 662 | } |
1003 | 663 | ||
1004 | if (set_iga == IGA1_IGA2) { | 664 | /* Fetch count for IGA2 only */ |
1005 | load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg); | 665 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); |
1006 | /* Fill shadow registers */ | ||
1007 | |||
1008 | switch (plvds_setting_info->lcd_panel_id) { | ||
1009 | case LCD_PANEL_ID0_640X480: | ||
1010 | offset = 80; | ||
1011 | break; | ||
1012 | case LCD_PANEL_ID1_800X600: | ||
1013 | case LCD_PANEL_IDA_800X480: | ||
1014 | offset = 110; | ||
1015 | break; | ||
1016 | case LCD_PANEL_ID2_1024X768: | ||
1017 | offset = 150; | ||
1018 | break; | ||
1019 | case LCD_PANEL_ID3_1280X768: | ||
1020 | case LCD_PANEL_ID4_1280X1024: | ||
1021 | case LCD_PANEL_ID5_1400X1050: | ||
1022 | case LCD_PANEL_ID9_1280X800: | ||
1023 | offset = 190; | ||
1024 | break; | ||
1025 | case LCD_PANEL_ID6_1600X1200: | ||
1026 | offset = 250; | ||
1027 | break; | ||
1028 | case LCD_PANEL_ID7_1366X768: | ||
1029 | case LCD_PANEL_IDB_1360X768: | ||
1030 | offset = 212; | ||
1031 | break; | ||
1032 | default: | ||
1033 | offset = 140; | ||
1034 | break; | ||
1035 | } | ||
1036 | |||
1037 | /* Offset for simultaneous */ | ||
1038 | viafb_set_secondary_pitch(offset << 3); | ||
1039 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); | ||
1040 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); | ||
1041 | /* Fetch count for simultaneous */ | ||
1042 | } else { /* SAMM */ | ||
1043 | /* Fetch count for IGA2 only */ | ||
1044 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); | ||
1045 | |||
1046 | if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) | ||
1047 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) | ||
1048 | viafb_load_FIFO_reg(set_iga, set_hres, set_vres); | ||
1049 | 666 | ||
1050 | viafb_set_color_depth(mode_bpp / 8, set_iga); | 667 | if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) |
1051 | } | 668 | && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)) |
669 | viafb_load_FIFO_reg(set_iga, set_hres, set_vres); | ||
1052 | 670 | ||
1053 | fill_lcd_format(); | 671 | fill_lcd_format(); |
1054 | 672 | ||
@@ -1065,11 +683,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
1065 | || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)) | 683 | || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)) |
1066 | viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); | 684 | viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); |
1067 | 685 | ||
1068 | load_lcd_patch_regs(set_hres, set_vres, | ||
1069 | plvds_setting_info->lcd_panel_id, set_iga); | ||
1070 | |||
1071 | DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n"); | ||
1072 | |||
1073 | /* Patch for non 32bit alignment mode */ | 686 | /* Patch for non 32bit alignment mode */ |
1074 | via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info); | 687 | via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info); |
1075 | } | 688 | } |
@@ -1283,8 +896,7 @@ void viafb_lcd_enable(void) | |||
1283 | viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); | 896 | viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); |
1284 | } | 897 | } |
1285 | 898 | ||
1286 | if ((viaparinfo->lvds_setting_info->iga_path == IGA1) | 899 | if (viaparinfo->lvds_setting_info->iga_path == IGA1) { |
1287 | || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) { | ||
1288 | /* CRT path set to IGA2 */ | 900 | /* CRT path set to IGA2 */ |
1289 | viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40); | 901 | viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40); |
1290 | /* IGA2 path disabled */ | 902 | /* IGA2 path disabled */ |
@@ -1476,210 +1088,6 @@ static struct display_timing lcd_centering_timging(struct display_timing | |||
1476 | return crt_reg; | 1088 | return crt_reg; |
1477 | } | 1089 | } |
1478 | 1090 | ||
1479 | static void load_crtc_shadow_timing(struct display_timing mode_timing, | ||
1480 | struct display_timing panel_timing) | ||
1481 | { | ||
1482 | struct io_register *reg = NULL; | ||
1483 | int i; | ||
1484 | int viafb_load_reg_Num = 0; | ||
1485 | int reg_value = 0; | ||
1486 | |||
1487 | if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) { | ||
1488 | /* Expansion */ | ||
1489 | for (i = 12; i < 20; i++) { | ||
1490 | switch (i) { | ||
1491 | case H_TOTAL_SHADOW_INDEX: | ||
1492 | reg_value = | ||
1493 | IGA2_HOR_TOTAL_SHADOW_FORMULA | ||
1494 | (panel_timing.hor_total); | ||
1495 | viafb_load_reg_Num = | ||
1496 | iga2_shadow_crtc_reg.hor_total_shadow. | ||
1497 | reg_num; | ||
1498 | reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; | ||
1499 | break; | ||
1500 | case H_BLANK_END_SHADOW_INDEX: | ||
1501 | reg_value = | ||
1502 | IGA2_HOR_BLANK_END_SHADOW_FORMULA | ||
1503 | (panel_timing.hor_blank_start, | ||
1504 | panel_timing.hor_blank_end); | ||
1505 | viafb_load_reg_Num = | ||
1506 | iga2_shadow_crtc_reg. | ||
1507 | hor_blank_end_shadow.reg_num; | ||
1508 | reg = | ||
1509 | iga2_shadow_crtc_reg. | ||
1510 | hor_blank_end_shadow.reg; | ||
1511 | break; | ||
1512 | case V_TOTAL_SHADOW_INDEX: | ||
1513 | reg_value = | ||
1514 | IGA2_VER_TOTAL_SHADOW_FORMULA | ||
1515 | (panel_timing.ver_total); | ||
1516 | viafb_load_reg_Num = | ||
1517 | iga2_shadow_crtc_reg.ver_total_shadow. | ||
1518 | reg_num; | ||
1519 | reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; | ||
1520 | break; | ||
1521 | case V_ADDR_SHADOW_INDEX: | ||
1522 | reg_value = | ||
1523 | IGA2_VER_ADDR_SHADOW_FORMULA | ||
1524 | (panel_timing.ver_addr); | ||
1525 | viafb_load_reg_Num = | ||
1526 | iga2_shadow_crtc_reg.ver_addr_shadow. | ||
1527 | reg_num; | ||
1528 | reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; | ||
1529 | break; | ||
1530 | case V_BLANK_SATRT_SHADOW_INDEX: | ||
1531 | reg_value = | ||
1532 | IGA2_VER_BLANK_START_SHADOW_FORMULA | ||
1533 | (panel_timing.ver_blank_start); | ||
1534 | viafb_load_reg_Num = | ||
1535 | iga2_shadow_crtc_reg. | ||
1536 | ver_blank_start_shadow.reg_num; | ||
1537 | reg = | ||
1538 | iga2_shadow_crtc_reg. | ||
1539 | ver_blank_start_shadow.reg; | ||
1540 | break; | ||
1541 | case V_BLANK_END_SHADOW_INDEX: | ||
1542 | reg_value = | ||
1543 | IGA2_VER_BLANK_END_SHADOW_FORMULA | ||
1544 | (panel_timing.ver_blank_start, | ||
1545 | panel_timing.ver_blank_end); | ||
1546 | viafb_load_reg_Num = | ||
1547 | iga2_shadow_crtc_reg. | ||
1548 | ver_blank_end_shadow.reg_num; | ||
1549 | reg = | ||
1550 | iga2_shadow_crtc_reg. | ||
1551 | ver_blank_end_shadow.reg; | ||
1552 | break; | ||
1553 | case V_SYNC_SATRT_SHADOW_INDEX: | ||
1554 | reg_value = | ||
1555 | IGA2_VER_SYNC_START_SHADOW_FORMULA | ||
1556 | (panel_timing.ver_sync_start); | ||
1557 | viafb_load_reg_Num = | ||
1558 | iga2_shadow_crtc_reg. | ||
1559 | ver_sync_start_shadow.reg_num; | ||
1560 | reg = | ||
1561 | iga2_shadow_crtc_reg. | ||
1562 | ver_sync_start_shadow.reg; | ||
1563 | break; | ||
1564 | case V_SYNC_END_SHADOW_INDEX: | ||
1565 | reg_value = | ||
1566 | IGA2_VER_SYNC_END_SHADOW_FORMULA | ||
1567 | (panel_timing.ver_sync_start, | ||
1568 | panel_timing.ver_sync_end); | ||
1569 | viafb_load_reg_Num = | ||
1570 | iga2_shadow_crtc_reg. | ||
1571 | ver_sync_end_shadow.reg_num; | ||
1572 | reg = | ||
1573 | iga2_shadow_crtc_reg. | ||
1574 | ver_sync_end_shadow.reg; | ||
1575 | break; | ||
1576 | } | ||
1577 | viafb_load_reg(reg_value, | ||
1578 | viafb_load_reg_Num, reg, VIACR); | ||
1579 | } | ||
1580 | } else { /* Centering */ | ||
1581 | for (i = 12; i < 20; i++) { | ||
1582 | switch (i) { | ||
1583 | case H_TOTAL_SHADOW_INDEX: | ||
1584 | reg_value = | ||
1585 | IGA2_HOR_TOTAL_SHADOW_FORMULA | ||
1586 | (panel_timing.hor_total); | ||
1587 | viafb_load_reg_Num = | ||
1588 | iga2_shadow_crtc_reg.hor_total_shadow. | ||
1589 | reg_num; | ||
1590 | reg = iga2_shadow_crtc_reg.hor_total_shadow.reg; | ||
1591 | break; | ||
1592 | case H_BLANK_END_SHADOW_INDEX: | ||
1593 | reg_value = | ||
1594 | IGA2_HOR_BLANK_END_SHADOW_FORMULA | ||
1595 | (panel_timing.hor_blank_start, | ||
1596 | panel_timing.hor_blank_end); | ||
1597 | viafb_load_reg_Num = | ||
1598 | iga2_shadow_crtc_reg. | ||
1599 | hor_blank_end_shadow.reg_num; | ||
1600 | reg = | ||
1601 | iga2_shadow_crtc_reg. | ||
1602 | hor_blank_end_shadow.reg; | ||
1603 | break; | ||
1604 | case V_TOTAL_SHADOW_INDEX: | ||
1605 | reg_value = | ||
1606 | IGA2_VER_TOTAL_SHADOW_FORMULA | ||
1607 | (panel_timing.ver_total); | ||
1608 | viafb_load_reg_Num = | ||
1609 | iga2_shadow_crtc_reg.ver_total_shadow. | ||
1610 | reg_num; | ||
1611 | reg = iga2_shadow_crtc_reg.ver_total_shadow.reg; | ||
1612 | break; | ||
1613 | case V_ADDR_SHADOW_INDEX: | ||
1614 | reg_value = | ||
1615 | IGA2_VER_ADDR_SHADOW_FORMULA | ||
1616 | (mode_timing.ver_addr); | ||
1617 | viafb_load_reg_Num = | ||
1618 | iga2_shadow_crtc_reg.ver_addr_shadow. | ||
1619 | reg_num; | ||
1620 | reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg; | ||
1621 | break; | ||
1622 | case V_BLANK_SATRT_SHADOW_INDEX: | ||
1623 | reg_value = | ||
1624 | IGA2_VER_BLANK_START_SHADOW_FORMULA | ||
1625 | (mode_timing.ver_blank_start); | ||
1626 | viafb_load_reg_Num = | ||
1627 | iga2_shadow_crtc_reg. | ||
1628 | ver_blank_start_shadow.reg_num; | ||
1629 | reg = | ||
1630 | iga2_shadow_crtc_reg. | ||
1631 | ver_blank_start_shadow.reg; | ||
1632 | break; | ||
1633 | case V_BLANK_END_SHADOW_INDEX: | ||
1634 | reg_value = | ||
1635 | IGA2_VER_BLANK_END_SHADOW_FORMULA | ||
1636 | (panel_timing.ver_blank_start, | ||
1637 | panel_timing.ver_blank_end); | ||
1638 | viafb_load_reg_Num = | ||
1639 | iga2_shadow_crtc_reg. | ||
1640 | ver_blank_end_shadow.reg_num; | ||
1641 | reg = | ||
1642 | iga2_shadow_crtc_reg. | ||
1643 | ver_blank_end_shadow.reg; | ||
1644 | break; | ||
1645 | case V_SYNC_SATRT_SHADOW_INDEX: | ||
1646 | reg_value = | ||
1647 | IGA2_VER_SYNC_START_SHADOW_FORMULA( | ||
1648 | (panel_timing.ver_sync_start - | ||
1649 | panel_timing.ver_blank_start) + | ||
1650 | (panel_timing.ver_addr - | ||
1651 | mode_timing.ver_addr) / 2 + | ||
1652 | mode_timing.ver_addr); | ||
1653 | viafb_load_reg_Num = | ||
1654 | iga2_shadow_crtc_reg.ver_sync_start_shadow. | ||
1655 | reg_num; | ||
1656 | reg = | ||
1657 | iga2_shadow_crtc_reg.ver_sync_start_shadow. | ||
1658 | reg; | ||
1659 | break; | ||
1660 | case V_SYNC_END_SHADOW_INDEX: | ||
1661 | reg_value = | ||
1662 | IGA2_VER_SYNC_END_SHADOW_FORMULA( | ||
1663 | (panel_timing.ver_sync_start - | ||
1664 | panel_timing.ver_blank_start) + | ||
1665 | (panel_timing.ver_addr - | ||
1666 | mode_timing.ver_addr) / 2 + | ||
1667 | mode_timing.ver_addr, | ||
1668 | panel_timing.ver_sync_end); | ||
1669 | viafb_load_reg_Num = | ||
1670 | iga2_shadow_crtc_reg.ver_sync_end_shadow. | ||
1671 | reg_num; | ||
1672 | reg = | ||
1673 | iga2_shadow_crtc_reg.ver_sync_end_shadow. | ||
1674 | reg; | ||
1675 | break; | ||
1676 | } | ||
1677 | viafb_load_reg(reg_value, | ||
1678 | viafb_load_reg_Num, reg, VIACR); | ||
1679 | } | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | bool viafb_lcd_get_mobile_state(bool *mobile) | 1091 | bool viafb_lcd_get_mobile_state(bool *mobile) |
1684 | { | 1092 | { |
1685 | unsigned char *romptr, *tableptr; | 1093 | unsigned char *romptr, *tableptr; |
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 7cd03e2a1275..d55aaa7b912c 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h | |||
@@ -43,61 +43,6 @@ | |||
43 | /* Video Memory Size */ | 43 | /* Video Memory Size */ |
44 | #define VIDEO_MEMORY_SIZE_16M 0x1000000 | 44 | #define VIDEO_MEMORY_SIZE_16M 0x1000000 |
45 | 45 | ||
46 | /* Definition Mode Index | ||
47 | */ | ||
48 | #define VIA_RES_640X480 0 | ||
49 | #define VIA_RES_800X600 1 | ||
50 | #define VIA_RES_1024X768 2 | ||
51 | #define VIA_RES_1152X864 3 | ||
52 | #define VIA_RES_1280X1024 4 | ||
53 | #define VIA_RES_1600X1200 5 | ||
54 | #define VIA_RES_1440X1050 6 | ||
55 | #define VIA_RES_1280X768 7 | ||
56 | #define VIA_RES_1280X960 8 | ||
57 | #define VIA_RES_1920X1440 9 | ||
58 | #define VIA_RES_848X480 10 | ||
59 | #define VIA_RES_1400X1050 11 | ||
60 | #define VIA_RES_720X480 12 | ||
61 | #define VIA_RES_720X576 13 | ||
62 | #define VIA_RES_1024X512 14 | ||
63 | #define VIA_RES_856X480 15 | ||
64 | #define VIA_RES_1024X576 16 | ||
65 | #define VIA_RES_640X400 17 | ||
66 | #define VIA_RES_1280X720 18 | ||
67 | #define VIA_RES_1920X1080 19 | ||
68 | #define VIA_RES_800X480 20 | ||
69 | #define VIA_RES_1368X768 21 | ||
70 | #define VIA_RES_1024X600 22 | ||
71 | #define VIA_RES_1280X800 23 | ||
72 | #define VIA_RES_1680X1050 24 | ||
73 | #define VIA_RES_960X600 25 | ||
74 | #define VIA_RES_1000X600 26 | ||
75 | #define VIA_RES_1088X612 27 | ||
76 | #define VIA_RES_1152X720 28 | ||
77 | #define VIA_RES_1200X720 29 | ||
78 | #define VIA_RES_1280X600 30 | ||
79 | #define VIA_RES_1360X768 31 | ||
80 | #define VIA_RES_1366X768 32 | ||
81 | #define VIA_RES_1440X900 33 | ||
82 | #define VIA_RES_1600X900 34 | ||
83 | #define VIA_RES_1600X1024 35 | ||
84 | #define VIA_RES_1792X1344 36 | ||
85 | #define VIA_RES_1856X1392 37 | ||
86 | #define VIA_RES_1920X1200 38 | ||
87 | #define VIA_RES_2048X1536 39 | ||
88 | #define VIA_RES_480X640 40 | ||
89 | |||
90 | /*Reduce Blanking*/ | ||
91 | #define VIA_RES_1360X768_RB 131 | ||
92 | #define VIA_RES_1440X900_RB 133 | ||
93 | #define VIA_RES_1400X1050_RB 111 | ||
94 | #define VIA_RES_1600X900_RB 134 | ||
95 | #define VIA_RES_1680X1050_RB 124 | ||
96 | #define VIA_RES_1920X1080_RB 119 | ||
97 | #define VIA_RES_1920X1200_RB 138 | ||
98 | |||
99 | #define VIA_RES_INVALID 255 | ||
100 | |||
101 | /* standard VGA IO port | 46 | /* standard VGA IO port |
102 | */ | 47 | */ |
103 | #define VIARMisc 0x3CC | 48 | #define VIARMisc 0x3CC |
@@ -118,7 +63,6 @@ | |||
118 | /* Display path */ | 63 | /* Display path */ |
119 | #define IGA1 1 | 64 | #define IGA1 1 |
120 | #define IGA2 2 | 65 | #define IGA2 2 |
121 | #define IGA1_IGA2 3 | ||
122 | 66 | ||
123 | /* Define Color Depth */ | 67 | /* Define Color Depth */ |
124 | #define MODE_8BPP 1 | 68 | #define MODE_8BPP 1 |
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c index d53c3d54ed8e..aefdeeec89b1 100644 --- a/drivers/video/via/via_utility.c +++ b/drivers/video/via/via_utility.c | |||
@@ -239,15 +239,3 @@ void viafb_get_gamma_support_state(int bpp, unsigned int *support_state) | |||
239 | else | 239 | else |
240 | *support_state = CRT_Device | DVI_Device | LCD_Device; | 240 | *support_state = CRT_Device | DVI_Device | LCD_Device; |
241 | } | 241 | } |
242 | |||
243 | int viafb_input_parameter_converter(int parameter_value) | ||
244 | { | ||
245 | int result; | ||
246 | |||
247 | if (parameter_value >= 1 && parameter_value <= 9) | ||
248 | result = 1 << (parameter_value - 1); | ||
249 | else | ||
250 | result = 1; | ||
251 | |||
252 | return result; | ||
253 | } | ||
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h index 2fd455202ebd..1670ba82143f 100644 --- a/drivers/video/via/via_utility.h +++ b/drivers/video/via/via_utility.h | |||
@@ -30,6 +30,5 @@ bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres); | |||
30 | void viafb_set_gamma_table(int bpp, unsigned int *gamma_table); | 30 | void viafb_set_gamma_table(int bpp, unsigned int *gamma_table); |
31 | void viafb_get_gamma_table(unsigned int *gamma_table); | 31 | void viafb_get_gamma_table(unsigned int *gamma_table); |
32 | void viafb_get_gamma_support_state(int bpp, unsigned int *support_state); | 32 | void viafb_get_gamma_support_state(int bpp, unsigned int *support_state); |
33 | int viafb_input_parameter_converter(int parameter_value); | ||
34 | 33 | ||
35 | #endif /* __VIAUTILITY_H__ */ | 34 | #endif /* __VIAUTILITY_H__ */ |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 3028e7ddc3b5..ce7783b63f6a 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -26,18 +26,22 @@ | |||
26 | 26 | ||
27 | #include "global.h" | 27 | #include "global.h" |
28 | 28 | ||
29 | static struct fb_var_screeninfo default_var; | ||
30 | static char *viafb_name = "Via"; | 29 | static char *viafb_name = "Via"; |
31 | static u32 pseudo_pal[17]; | 30 | static u32 pseudo_pal[17]; |
32 | 31 | ||
33 | /* video mode */ | 32 | /* video mode */ |
34 | static char *viafb_mode = "640x480"; | 33 | static char *viafb_mode; |
35 | static char *viafb_mode1 = "640x480"; | 34 | static char *viafb_mode1; |
35 | static int viafb_bpp = 32; | ||
36 | static int viafb_bpp1 = 32; | ||
37 | |||
38 | static unsigned int viafb_second_offset; | ||
39 | static int viafb_second_size; | ||
36 | 40 | ||
37 | static int viafb_accel = 1; | 41 | static int viafb_accel = 1; |
38 | 42 | ||
39 | /* Added for specifying active devices.*/ | 43 | /* Added for specifying active devices.*/ |
40 | char *viafb_active_dev = ""; | 44 | char *viafb_active_dev; |
41 | 45 | ||
42 | /*Added for specify lcd output port*/ | 46 | /*Added for specify lcd output port*/ |
43 | char *viafb_lcd_port = ""; | 47 | char *viafb_lcd_port = ""; |
@@ -50,18 +54,78 @@ static void apply_second_mode_setting(struct fb_var_screeninfo | |||
50 | *sec_var); | 54 | *sec_var); |
51 | static void retrieve_device_setting(struct viafb_ioctl_setting | 55 | static void retrieve_device_setting(struct viafb_ioctl_setting |
52 | *setting_info); | 56 | *setting_info); |
57 | static int viafb_pan_display(struct fb_var_screeninfo *var, | ||
58 | struct fb_info *info); | ||
53 | 59 | ||
54 | static struct fb_ops viafb_ops; | 60 | static struct fb_ops viafb_ops; |
55 | 61 | ||
56 | 62 | ||
63 | static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) | ||
64 | { | ||
65 | var->grayscale = 0; | ||
66 | var->red.msb_right = 0; | ||
67 | var->green.msb_right = 0; | ||
68 | var->blue.msb_right = 0; | ||
69 | var->transp.offset = 0; | ||
70 | var->transp.length = 0; | ||
71 | var->transp.msb_right = 0; | ||
72 | var->nonstd = 0; | ||
73 | switch (depth) { | ||
74 | case 8: | ||
75 | var->bits_per_pixel = 8; | ||
76 | var->red.offset = 0; | ||
77 | var->green.offset = 0; | ||
78 | var->blue.offset = 0; | ||
79 | var->red.length = 8; | ||
80 | var->green.length = 8; | ||
81 | var->blue.length = 8; | ||
82 | break; | ||
83 | case 15: | ||
84 | var->bits_per_pixel = 16; | ||
85 | var->red.offset = 10; | ||
86 | var->green.offset = 5; | ||
87 | var->blue.offset = 0; | ||
88 | var->red.length = 5; | ||
89 | var->green.length = 5; | ||
90 | var->blue.length = 5; | ||
91 | break; | ||
92 | case 16: | ||
93 | var->bits_per_pixel = 16; | ||
94 | var->red.offset = 11; | ||
95 | var->green.offset = 5; | ||
96 | var->blue.offset = 0; | ||
97 | var->red.length = 5; | ||
98 | var->green.length = 6; | ||
99 | var->blue.length = 5; | ||
100 | break; | ||
101 | case 24: | ||
102 | var->bits_per_pixel = 32; | ||
103 | var->red.offset = 16; | ||
104 | var->green.offset = 8; | ||
105 | var->blue.offset = 0; | ||
106 | var->red.length = 8; | ||
107 | var->green.length = 8; | ||
108 | var->blue.length = 8; | ||
109 | break; | ||
110 | case 30: | ||
111 | var->bits_per_pixel = 32; | ||
112 | var->red.offset = 20; | ||
113 | var->green.offset = 10; | ||
114 | var->blue.offset = 0; | ||
115 | var->red.length = 10; | ||
116 | var->green.length = 10; | ||
117 | var->blue.length = 10; | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | |||
57 | static void viafb_update_fix(struct fb_info *info) | 122 | static void viafb_update_fix(struct fb_info *info) |
58 | { | 123 | { |
59 | u32 bpp = info->var.bits_per_pixel; | 124 | u32 bpp = info->var.bits_per_pixel; |
60 | 125 | ||
61 | info->fix.visual = | 126 | info->fix.visual = |
62 | bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | 127 | bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; |
63 | info->fix.line_length = | 128 | info->fix.line_length = (info->var.xres_virtual * bpp / 8 + 7) & ~7; |
64 | ((info->var.xres_virtual + 7) & ~7) * bpp / 8; | ||
65 | } | 129 | } |
66 | 130 | ||
67 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | 131 | static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, |
@@ -75,6 +139,7 @@ static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix, | |||
75 | 139 | ||
76 | fix->type = FB_TYPE_PACKED_PIXELS; | 140 | fix->type = FB_TYPE_PACKED_PIXELS; |
77 | fix->type_aux = 0; | 141 | fix->type_aux = 0; |
142 | fix->visual = FB_VISUAL_TRUECOLOR; | ||
78 | 143 | ||
79 | fix->xpanstep = fix->ywrapstep = 0; | 144 | fix->xpanstep = fix->ywrapstep = 0; |
80 | fix->ypanstep = 1; | 145 | fix->ypanstep = 1; |
@@ -97,9 +162,10 @@ static int viafb_release(struct fb_info *info, int user) | |||
97 | static int viafb_check_var(struct fb_var_screeninfo *var, | 162 | static int viafb_check_var(struct fb_var_screeninfo *var, |
98 | struct fb_info *info) | 163 | struct fb_info *info) |
99 | { | 164 | { |
100 | int vmode_index, htotal, vtotal; | 165 | int htotal, vtotal, depth; |
166 | struct VideoModeTable *vmode_entry; | ||
101 | struct viafb_par *ppar = info->par; | 167 | struct viafb_par *ppar = info->par; |
102 | u32 long_refresh; | 168 | u32 long_refresh, line; |
103 | 169 | ||
104 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); | 170 | DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); |
105 | /* Sanity check */ | 171 | /* Sanity check */ |
@@ -107,26 +173,36 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
107 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) | 173 | if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) |
108 | return -EINVAL; | 174 | return -EINVAL; |
109 | 175 | ||
110 | vmode_index = viafb_get_mode_index(var->xres, var->yres); | 176 | vmode_entry = viafb_get_mode(var->xres, var->yres); |
111 | if (vmode_index == VIA_RES_INVALID) { | 177 | if (!vmode_entry) { |
112 | DEBUG_MSG(KERN_INFO | 178 | DEBUG_MSG(KERN_INFO |
113 | "viafb: Mode %dx%dx%d not supported!!\n", | 179 | "viafb: Mode %dx%dx%d not supported!!\n", |
114 | var->xres, var->yres, var->bits_per_pixel); | 180 | var->xres, var->yres, var->bits_per_pixel); |
115 | return -EINVAL; | 181 | return -EINVAL; |
116 | } | 182 | } |
117 | 183 | ||
118 | if (24 == var->bits_per_pixel) | 184 | depth = fb_get_color_depth(var, &info->fix); |
119 | var->bits_per_pixel = 32; | 185 | if (!depth) |
186 | depth = var->bits_per_pixel; | ||
120 | 187 | ||
121 | if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && | 188 | if (depth < 0 || depth > 32) |
122 | var->bits_per_pixel != 32) | ||
123 | return -EINVAL; | 189 | return -EINVAL; |
190 | else if (!depth) | ||
191 | depth = 24; | ||
192 | else if (depth == 15 && viafb_dual_fb && ppar->iga_path == IGA1) | ||
193 | depth = 15; | ||
194 | else if (depth == 30) | ||
195 | depth = 30; | ||
196 | else if (depth <= 8) | ||
197 | depth = 8; | ||
198 | else if (depth <= 16) | ||
199 | depth = 16; | ||
200 | else | ||
201 | depth = 24; | ||
124 | 202 | ||
125 | if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F) | 203 | viafb_fill_var_color_info(var, depth); |
126 | /*32 pixel alignment */ | 204 | line = (var->xres_virtual * var->bits_per_pixel / 8 + 7) & ~7; |
127 | var->xres_virtual = (var->xres_virtual + 31) & ~31; | 205 | if (line * var->yres_virtual > ppar->memsize) |
128 | if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > | ||
129 | ppar->memsize) | ||
130 | return -EINVAL; | 206 | return -EINVAL; |
131 | 207 | ||
132 | /* Based on var passed in to calculate the refresh, | 208 | /* Based on var passed in to calculate the refresh, |
@@ -142,7 +218,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
142 | viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh); | 218 | viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh); |
143 | 219 | ||
144 | /* Adjust var according to our driver's own table */ | 220 | /* Adjust var according to our driver's own table */ |
145 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); | 221 | viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); |
146 | if (info->var.accel_flags & FB_ACCELF_TEXT && | 222 | if (info->var.accel_flags & FB_ACCELF_TEXT && |
147 | !ppar->shared->engine_mmio) | 223 | !ppar->shared->engine_mmio) |
148 | info->var.accel_flags = 0; | 224 | info->var.accel_flags = 0; |
@@ -153,39 +229,45 @@ static int viafb_check_var(struct fb_var_screeninfo *var, | |||
153 | static int viafb_set_par(struct fb_info *info) | 229 | static int viafb_set_par(struct fb_info *info) |
154 | { | 230 | { |
155 | struct viafb_par *viapar = info->par; | 231 | struct viafb_par *viapar = info->par; |
156 | int vmode_index; | 232 | struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; |
157 | int vmode_index1 = 0; | ||
158 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); | 233 | DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); |
159 | 234 | ||
160 | viapar->depth = fb_get_color_depth(&info->var, &info->fix); | 235 | viapar->depth = fb_get_color_depth(&info->var, &info->fix); |
161 | viafb_update_device_setting(info->var.xres, info->var.yres, | 236 | viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, |
162 | info->var.bits_per_pixel, viafb_refresh, 0); | 237 | viafbinfo->var.bits_per_pixel, viafb_refresh, 0); |
163 | 238 | ||
164 | vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres); | 239 | vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres); |
165 | 240 | if (viafb_dual_fb) { | |
166 | if (viafb_SAMM_ON == 1) { | 241 | vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres, |
242 | viafbinfo1->var.yres); | ||
243 | viafb_update_device_setting(viafbinfo1->var.xres, | ||
244 | viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, | ||
245 | viafb_refresh1, 1); | ||
246 | } else if (viafb_SAMM_ON == 1) { | ||
167 | DEBUG_MSG(KERN_INFO | 247 | DEBUG_MSG(KERN_INFO |
168 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", | 248 | "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", |
169 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 249 | viafb_second_xres, viafb_second_yres, viafb_bpp1); |
170 | vmode_index1 = viafb_get_mode_index(viafb_second_xres, | 250 | vmode_entry1 = viafb_get_mode(viafb_second_xres, |
171 | viafb_second_yres); | 251 | viafb_second_yres); |
172 | DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n", | ||
173 | vmode_index1); | ||
174 | 252 | ||
175 | viafb_update_device_setting(viafb_second_xres, | 253 | viafb_update_device_setting(viafb_second_xres, |
176 | viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); | 254 | viafb_second_yres, viafb_bpp1, viafb_refresh1, 1); |
177 | } | 255 | } |
178 | 256 | ||
179 | if (vmode_index != VIA_RES_INVALID) { | 257 | if (vmode_entry) { |
180 | viafb_update_fix(info); | 258 | viafb_update_fix(info); |
181 | viafb_bpp = info->var.bits_per_pixel; | 259 | if (viafb_dual_fb && viapar->iga_path == IGA2) |
260 | viafb_bpp1 = info->var.bits_per_pixel; | ||
261 | else | ||
262 | viafb_bpp = info->var.bits_per_pixel; | ||
263 | |||
182 | if (info->var.accel_flags & FB_ACCELF_TEXT) | 264 | if (info->var.accel_flags & FB_ACCELF_TEXT) |
183 | info->flags &= ~FBINFO_HWACCEL_DISABLED; | 265 | info->flags &= ~FBINFO_HWACCEL_DISABLED; |
184 | else | 266 | else |
185 | info->flags |= FBINFO_HWACCEL_DISABLED; | 267 | info->flags |= FBINFO_HWACCEL_DISABLED; |
186 | viafb_setmode(vmode_index, info->var.xres, info->var.yres, | 268 | viafb_setmode(vmode_entry, info->var.bits_per_pixel, |
187 | info->var.bits_per_pixel, vmode_index1, | 269 | vmode_entry1, viafb_bpp1); |
188 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 270 | viafb_pan_display(&info->var, info); |
189 | } | 271 | } |
190 | 272 | ||
191 | return 0; | 273 | return 0; |
@@ -195,234 +277,52 @@ static int viafb_set_par(struct fb_info *info) | |||
195 | static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, | 277 | static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green, |
196 | unsigned blue, unsigned transp, struct fb_info *info) | 278 | unsigned blue, unsigned transp, struct fb_info *info) |
197 | { | 279 | { |
198 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | 280 | struct viafb_par *viapar = info->par; |
199 | unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16; | 281 | u32 r, g, b; |
200 | DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n"); | ||
201 | if (regno >= cmap_entries) | ||
202 | return 1; | ||
203 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
204 | /* | ||
205 | * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev. | ||
206 | */ | ||
207 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
208 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
209 | } | ||
210 | switch (info->var.bits_per_pixel) { | ||
211 | case 8: | ||
212 | outb(0x1A, 0x3C4); | ||
213 | sr1a = inb(0x3C5); | ||
214 | outb(0x1B, 0x3C4); | ||
215 | sr1b = inb(0x3C5); | ||
216 | outb(0x67, 0x3D4); | ||
217 | cr67 = inb(0x3D5); | ||
218 | outb(0x6A, 0x3D4); | ||
219 | cr6a = inb(0x3D5); | ||
220 | |||
221 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
222 | outb(0x1A, 0x3C4); | ||
223 | outb(sr1a | 0x01, 0x3C5); | ||
224 | /* Second Display Engine colck always on */ | ||
225 | outb(0x1B, 0x3C4); | ||
226 | outb(sr1b | 0x80, 0x3C5); | ||
227 | /* Second Display Color Depth 8 */ | ||
228 | outb(0x67, 0x3D4); | ||
229 | outb(cr67 & 0x3F, 0x3D5); | ||
230 | outb(0x6A, 0x3D4); | ||
231 | /* Second Display Channel Reset CR6A[6]) */ | ||
232 | outb(cr6a & 0xBF, 0x3D5); | ||
233 | /* Second Display Channel Enable CR6A[7] */ | ||
234 | outb(cr6a | 0x80, 0x3D5); | ||
235 | /* Second Display Channel stop reset) */ | ||
236 | outb(cr6a | 0x40, 0x3D5); | ||
237 | |||
238 | /* Bit mask of palette */ | ||
239 | outb(0xFF, 0x3c6); | ||
240 | /* Write one register of IGA2 */ | ||
241 | outb(regno, 0x3C8); | ||
242 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
243 | rev >= 15) { | ||
244 | shift = 8; | ||
245 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
246 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
247 | } else { | ||
248 | shift = 10; | ||
249 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
250 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
251 | } | ||
252 | outb(red >> shift, 0x3C9); | ||
253 | outb(green >> shift, 0x3C9); | ||
254 | outb(blue >> shift, 0x3C9); | ||
255 | |||
256 | /* Map the 3C6/7/8/9 to the IGA1 */ | ||
257 | outb(0x1A, 0x3C4); | ||
258 | outb(sr1a & 0xFE, 0x3C5); | ||
259 | /* Bit mask of palette */ | ||
260 | outb(0xFF, 0x3c6); | ||
261 | /* Write one register of IGA1 */ | ||
262 | outb(regno, 0x3C8); | ||
263 | outb(red >> shift, 0x3C9); | ||
264 | outb(green >> shift, 0x3C9); | ||
265 | outb(blue >> shift, 0x3C9); | ||
266 | |||
267 | outb(0x1A, 0x3C4); | ||
268 | outb(sr1a, 0x3C5); | ||
269 | outb(0x1B, 0x3C4); | ||
270 | outb(sr1b, 0x3C5); | ||
271 | outb(0x67, 0x3D4); | ||
272 | outb(cr67, 0x3D5); | ||
273 | outb(0x6A, 0x3D4); | ||
274 | outb(cr6a, 0x3D5); | ||
275 | break; | ||
276 | case 16: | ||
277 | ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) | | ||
278 | ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); | ||
279 | break; | ||
280 | case 32: | ||
281 | ((u32 *) info->pseudo_palette)[regno] = | ||
282 | ((transp & 0xFF00) << 16) | | ||
283 | ((red & 0xFF00) << 8) | | ||
284 | ((green & 0xFF00)) | ((blue & 0xFF00) >> 8); | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | 282 | ||
290 | } | 283 | if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { |
284 | if (regno > 255) | ||
285 | return -EINVAL; | ||
291 | 286 | ||
292 | /*CALLED BY: fb_set_cmap */ | 287 | if (!viafb_dual_fb || viapar->iga_path == IGA1) |
293 | /* fb_set_var, pass 256 colors */ | 288 | viafb_set_primary_color_register(regno, red >> 8, |
294 | /*CALLED BY: fb_set_cmap */ | 289 | green >> 8, blue >> 8); |
295 | /* fbcon_set_palette, pass 16 colors */ | ||
296 | static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
297 | { | ||
298 | u32 len = cmap->len; | ||
299 | u32 i; | ||
300 | u16 *pred = cmap->red; | ||
301 | u16 *pgreen = cmap->green; | ||
302 | u16 *pblue = cmap->blue; | ||
303 | u16 *ptransp = cmap->transp; | ||
304 | u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10; | ||
305 | if (len > 256) | ||
306 | return 1; | ||
307 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) { | ||
308 | /* | ||
309 | * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip | ||
310 | * rev. | ||
311 | */ | ||
312 | outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8); | ||
313 | rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff; | ||
314 | } | ||
315 | switch (info->var.bits_per_pixel) { | ||
316 | case 8: | ||
317 | outb(0x1A, 0x3C4); | ||
318 | sr1a = inb(0x3C5); | ||
319 | outb(0x1B, 0x3C4); | ||
320 | sr1b = inb(0x3C5); | ||
321 | outb(0x67, 0x3D4); | ||
322 | cr67 = inb(0x3D5); | ||
323 | outb(0x6A, 0x3D4); | ||
324 | cr6a = inb(0x3D5); | ||
325 | /* Map the 3C6/7/8/9 to the IGA2 */ | ||
326 | outb(0x1A, 0x3C4); | ||
327 | outb(sr1a | 0x01, 0x3C5); | ||
328 | outb(0x1B, 0x3C4); | ||
329 | /* Second Display Engine colck always on */ | ||
330 | outb(sr1b | 0x80, 0x3C5); | ||
331 | outb(0x67, 0x3D4); | ||
332 | /* Second Display Color Depth 8 */ | ||
333 | outb(cr67 & 0x3F, 0x3D5); | ||
334 | outb(0x6A, 0x3D4); | ||
335 | /* Second Display Channel Reset CR6A[6]) */ | ||
336 | outb(cr6a & 0xBF, 0x3D5); | ||
337 | /* Second Display Channel Enable CR6A[7] */ | ||
338 | outb(cr6a | 0x80, 0x3D5); | ||
339 | /* Second Display Channel stop reset) */ | ||
340 | outb(cr6a | 0xC0, 0x3D5); | ||
341 | |||
342 | /* Bit mask of palette */ | ||
343 | outb(0xFF, 0x3c6); | ||
344 | outb(0x00, 0x3C8); | ||
345 | if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name && | ||
346 | rev >= 15) { | ||
347 | shift = 8; | ||
348 | viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5); | ||
349 | viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7); | ||
350 | } else { | ||
351 | shift = 10; | ||
352 | viafb_write_reg_mask(CR6A, VIACR, 0, BIT5); | ||
353 | viafb_write_reg_mask(SR15, VIASR, 0, BIT7); | ||
354 | } | ||
355 | for (i = 0; i < len; i++) { | ||
356 | outb((*(pred + i)) >> shift, 0x3C9); | ||
357 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
358 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
359 | } | ||
360 | 290 | ||
361 | outb(0x1A, 0x3C4); | 291 | if (!viafb_dual_fb || viapar->iga_path == IGA2) |
362 | /* Map the 3C6/7/8/9 to the IGA1 */ | 292 | viafb_set_secondary_color_register(regno, red >> 8, |
363 | outb(sr1a & 0xFE, 0x3C5); | 293 | green >> 8, blue >> 8); |
364 | /* Bit mask of palette */ | 294 | } else { |
365 | outb(0xFF, 0x3c6); | 295 | if (regno > 15) |
366 | outb(0x00, 0x3C8); | 296 | return -EINVAL; |
367 | for (i = 0; i < len; i++) { | ||
368 | outb((*(pred + i)) >> shift, 0x3C9); | ||
369 | outb((*(pgreen + i)) >> shift, 0x3C9); | ||
370 | outb((*(pblue + i)) >> shift, 0x3C9); | ||
371 | } | ||
372 | 297 | ||
373 | outb(0x1A, 0x3C4); | 298 | r = (red >> (16 - info->var.red.length)) |
374 | outb(sr1a, 0x3C5); | 299 | << info->var.red.offset; |
375 | outb(0x1B, 0x3C4); | 300 | b = (blue >> (16 - info->var.blue.length)) |
376 | outb(sr1b, 0x3C5); | 301 | << info->var.blue.offset; |
377 | outb(0x67, 0x3D4); | 302 | g = (green >> (16 - info->var.green.length)) |
378 | outb(cr67, 0x3D5); | 303 | << info->var.green.offset; |
379 | outb(0x6A, 0x3D4); | 304 | ((u32 *) info->pseudo_palette)[regno] = r | g | b; |
380 | outb(cr6a, 0x3D5); | ||
381 | break; | ||
382 | case 16: | ||
383 | if (len > 17) | ||
384 | return 0; /* Because static u32 pseudo_pal[17]; */ | ||
385 | for (i = 0; i < len; i++) | ||
386 | ((u32 *) info->pseudo_palette)[i] = | ||
387 | (*(pred + i) & 0xF800) | | ||
388 | ((*(pgreen + i) & 0xFC00) >> 5) | | ||
389 | ((*(pblue + i) & 0xF800) >> 11); | ||
390 | break; | ||
391 | case 32: | ||
392 | if (len > 17) | ||
393 | return 0; | ||
394 | if (ptransp) { | ||
395 | for (i = 0; i < len; i++) | ||
396 | ((u32 *) info->pseudo_palette)[i] = | ||
397 | ((*(ptransp + i) & 0xFF00) << 16) | | ||
398 | ((*(pred + i) & 0xFF00) << 8) | | ||
399 | ((*(pgreen + i) & 0xFF00)) | | ||
400 | ((*(pblue + i) & 0xFF00) >> 8); | ||
401 | } else { | ||
402 | for (i = 0; i < len; i++) | ||
403 | ((u32 *) info->pseudo_palette)[i] = | ||
404 | 0x00000000 | | ||
405 | ((*(pred + i) & 0xFF00) << 8) | | ||
406 | ((*(pgreen + i) & 0xFF00)) | | ||
407 | ((*(pblue + i) & 0xFF00) >> 8); | ||
408 | } | ||
409 | break; | ||
410 | } | 305 | } |
306 | |||
411 | return 0; | 307 | return 0; |
412 | } | 308 | } |
413 | 309 | ||
414 | static int viafb_pan_display(struct fb_var_screeninfo *var, | 310 | static int viafb_pan_display(struct fb_var_screeninfo *var, |
415 | struct fb_info *info) | 311 | struct fb_info *info) |
416 | { | 312 | { |
417 | unsigned int offset; | 313 | struct viafb_par *viapar = info->par; |
418 | 314 | u32 vram_addr = (var->yoffset * var->xres_virtual + var->xoffset) | |
419 | DEBUG_MSG(KERN_INFO "viafb_pan_display!\n"); | 315 | * (var->bits_per_pixel / 8) + viapar->vram_addr; |
420 | 316 | ||
421 | offset = (var->xoffset + (var->yoffset * var->xres_virtual)) * | 317 | DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr); |
422 | var->bits_per_pixel / 16; | 318 | if (!viafb_dual_fb) { |
319 | viafb_set_primary_address(vram_addr); | ||
320 | viafb_set_secondary_address(vram_addr); | ||
321 | } else if (viapar->iga_path == IGA1) | ||
322 | viafb_set_primary_address(vram_addr); | ||
323 | else | ||
324 | viafb_set_secondary_address(vram_addr); | ||
423 | 325 | ||
424 | DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset); | ||
425 | viafb_set_primary_address(offset); | ||
426 | return 0; | 326 | return 0; |
427 | } | 327 | } |
428 | 328 | ||
@@ -476,6 +376,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) | |||
476 | u32 gpu32; | 376 | u32 gpu32; |
477 | 377 | ||
478 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); | 378 | DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd); |
379 | printk(KERN_WARNING "viafb_ioctl: Please avoid this interface as it is unstable and might change or vanish at any time!\n"); | ||
479 | memset(&u, 0, sizeof(u)); | 380 | memset(&u, 0, sizeof(u)); |
480 | 381 | ||
481 | switch (cmd) { | 382 | switch (cmd) { |
@@ -1015,23 +916,6 @@ static int viafb_sync(struct fb_info *info) | |||
1015 | return 0; | 916 | return 0; |
1016 | } | 917 | } |
1017 | 918 | ||
1018 | int viafb_get_mode_index(int hres, int vres) | ||
1019 | { | ||
1020 | u32 i; | ||
1021 | DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n"); | ||
1022 | |||
1023 | for (i = 0; i < NUM_TOTAL_MODETABLE; i++) | ||
1024 | if (CLE266Modes[i].mode_array && | ||
1025 | CLE266Modes[i].crtc[0].crtc.hor_addr == hres && | ||
1026 | CLE266Modes[i].crtc[0].crtc.ver_addr == vres) | ||
1027 | break; | ||
1028 | |||
1029 | if (i == NUM_TOTAL_MODETABLE) | ||
1030 | return VIA_RES_INVALID; | ||
1031 | |||
1032 | return CLE266Modes[i].ModeIndex; | ||
1033 | } | ||
1034 | |||
1035 | static void check_available_device_to_enable(int device_id) | 919 | static void check_available_device_to_enable(int device_id) |
1036 | { | 920 | { |
1037 | int device_num = 0; | 921 | int device_num = 0; |
@@ -1330,7 +1214,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting | |||
1330 | setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; | 1214 | setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; |
1331 | } | 1215 | } |
1332 | 1216 | ||
1333 | static void parse_active_dev(void) | 1217 | static int parse_active_dev(void) |
1334 | { | 1218 | { |
1335 | viafb_CRT_ON = STATE_OFF; | 1219 | viafb_CRT_ON = STATE_OFF; |
1336 | viafb_DVI_ON = STATE_OFF; | 1220 | viafb_DVI_ON = STATE_OFF; |
@@ -1341,60 +1225,63 @@ static void parse_active_dev(void) | |||
1341 | IGA path to devices in SAMM case. */ | 1225 | IGA path to devices in SAMM case. */ |
1342 | /* Note: The previous of active_dev is primary device, | 1226 | /* Note: The previous of active_dev is primary device, |
1343 | and the following is secondary device. */ | 1227 | and the following is secondary device. */ |
1344 | if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) { | 1228 | if (!viafb_active_dev) { |
1229 | viafb_CRT_ON = STATE_ON; | ||
1230 | viafb_SAMM_ON = STATE_OFF; | ||
1231 | } else if (!strcmp(viafb_active_dev, "CRT+DVI")) { | ||
1345 | /* CRT+DVI */ | 1232 | /* CRT+DVI */ |
1346 | viafb_CRT_ON = STATE_ON; | 1233 | viafb_CRT_ON = STATE_ON; |
1347 | viafb_DVI_ON = STATE_ON; | 1234 | viafb_DVI_ON = STATE_ON; |
1348 | viafb_primary_dev = CRT_Device; | 1235 | viafb_primary_dev = CRT_Device; |
1349 | } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) { | 1236 | } else if (!strcmp(viafb_active_dev, "DVI+CRT")) { |
1350 | /* DVI+CRT */ | 1237 | /* DVI+CRT */ |
1351 | viafb_CRT_ON = STATE_ON; | 1238 | viafb_CRT_ON = STATE_ON; |
1352 | viafb_DVI_ON = STATE_ON; | 1239 | viafb_DVI_ON = STATE_ON; |
1353 | viafb_primary_dev = DVI_Device; | 1240 | viafb_primary_dev = DVI_Device; |
1354 | } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) { | 1241 | } else if (!strcmp(viafb_active_dev, "CRT+LCD")) { |
1355 | /* CRT+LCD */ | 1242 | /* CRT+LCD */ |
1356 | viafb_CRT_ON = STATE_ON; | 1243 | viafb_CRT_ON = STATE_ON; |
1357 | viafb_LCD_ON = STATE_ON; | 1244 | viafb_LCD_ON = STATE_ON; |
1358 | viafb_primary_dev = CRT_Device; | 1245 | viafb_primary_dev = CRT_Device; |
1359 | } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) { | 1246 | } else if (!strcmp(viafb_active_dev, "LCD+CRT")) { |
1360 | /* LCD+CRT */ | 1247 | /* LCD+CRT */ |
1361 | viafb_CRT_ON = STATE_ON; | 1248 | viafb_CRT_ON = STATE_ON; |
1362 | viafb_LCD_ON = STATE_ON; | 1249 | viafb_LCD_ON = STATE_ON; |
1363 | viafb_primary_dev = LCD_Device; | 1250 | viafb_primary_dev = LCD_Device; |
1364 | } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) { | 1251 | } else if (!strcmp(viafb_active_dev, "DVI+LCD")) { |
1365 | /* DVI+LCD */ | 1252 | /* DVI+LCD */ |
1366 | viafb_DVI_ON = STATE_ON; | 1253 | viafb_DVI_ON = STATE_ON; |
1367 | viafb_LCD_ON = STATE_ON; | 1254 | viafb_LCD_ON = STATE_ON; |
1368 | viafb_primary_dev = DVI_Device; | 1255 | viafb_primary_dev = DVI_Device; |
1369 | } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) { | 1256 | } else if (!strcmp(viafb_active_dev, "LCD+DVI")) { |
1370 | /* LCD+DVI */ | 1257 | /* LCD+DVI */ |
1371 | viafb_DVI_ON = STATE_ON; | 1258 | viafb_DVI_ON = STATE_ON; |
1372 | viafb_LCD_ON = STATE_ON; | 1259 | viafb_LCD_ON = STATE_ON; |
1373 | viafb_primary_dev = LCD_Device; | 1260 | viafb_primary_dev = LCD_Device; |
1374 | } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) { | 1261 | } else if (!strcmp(viafb_active_dev, "LCD+LCD2")) { |
1375 | viafb_LCD_ON = STATE_ON; | 1262 | viafb_LCD_ON = STATE_ON; |
1376 | viafb_LCD2_ON = STATE_ON; | 1263 | viafb_LCD2_ON = STATE_ON; |
1377 | viafb_primary_dev = LCD_Device; | 1264 | viafb_primary_dev = LCD_Device; |
1378 | } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) { | 1265 | } else if (!strcmp(viafb_active_dev, "LCD2+LCD")) { |
1379 | viafb_LCD_ON = STATE_ON; | 1266 | viafb_LCD_ON = STATE_ON; |
1380 | viafb_LCD2_ON = STATE_ON; | 1267 | viafb_LCD2_ON = STATE_ON; |
1381 | viafb_primary_dev = LCD2_Device; | 1268 | viafb_primary_dev = LCD2_Device; |
1382 | } else if (!strncmp(viafb_active_dev, "CRT", 3)) { | 1269 | } else if (!strcmp(viafb_active_dev, "CRT")) { |
1383 | /* CRT only */ | 1270 | /* CRT only */ |
1384 | viafb_CRT_ON = STATE_ON; | 1271 | viafb_CRT_ON = STATE_ON; |
1385 | viafb_SAMM_ON = STATE_OFF; | 1272 | viafb_SAMM_ON = STATE_OFF; |
1386 | } else if (!strncmp(viafb_active_dev, "DVI", 3)) { | 1273 | } else if (!strcmp(viafb_active_dev, "DVI")) { |
1387 | /* DVI only */ | 1274 | /* DVI only */ |
1388 | viafb_DVI_ON = STATE_ON; | 1275 | viafb_DVI_ON = STATE_ON; |
1389 | viafb_SAMM_ON = STATE_OFF; | 1276 | viafb_SAMM_ON = STATE_OFF; |
1390 | } else if (!strncmp(viafb_active_dev, "LCD", 3)) { | 1277 | } else if (!strcmp(viafb_active_dev, "LCD")) { |
1391 | /* LCD only */ | 1278 | /* LCD only */ |
1392 | viafb_LCD_ON = STATE_ON; | 1279 | viafb_LCD_ON = STATE_ON; |
1393 | viafb_SAMM_ON = STATE_OFF; | 1280 | viafb_SAMM_ON = STATE_OFF; |
1394 | } else { | 1281 | } else |
1395 | viafb_CRT_ON = STATE_ON; | 1282 | return -EINVAL; |
1396 | viafb_SAMM_ON = STATE_OFF; | 1283 | |
1397 | } | 1284 | return 0; |
1398 | } | 1285 | } |
1399 | 1286 | ||
1400 | static int parse_port(char *opt_str, int *output_interface) | 1287 | static int parse_port(char *opt_str, int *output_interface) |
@@ -1823,35 +1710,37 @@ static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) | |||
1823 | remove_proc_entry("viafb", NULL); | 1710 | remove_proc_entry("viafb", NULL); |
1824 | } | 1711 | } |
1825 | 1712 | ||
1826 | static void parse_mode(const char *str, u32 *xres, u32 *yres) | 1713 | static int parse_mode(const char *str, u32 *xres, u32 *yres) |
1827 | { | 1714 | { |
1828 | char *ptr; | 1715 | char *ptr; |
1829 | 1716 | ||
1717 | if (!str) { | ||
1718 | *xres = 640; | ||
1719 | *yres = 480; | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1830 | *xres = simple_strtoul(str, &ptr, 10); | 1723 | *xres = simple_strtoul(str, &ptr, 10); |
1831 | if (ptr[0] != 'x') | 1724 | if (ptr[0] != 'x') |
1832 | goto out_default; | 1725 | return -EINVAL; |
1833 | 1726 | ||
1834 | *yres = simple_strtoul(&ptr[1], &ptr, 10); | 1727 | *yres = simple_strtoul(&ptr[1], &ptr, 10); |
1835 | if (ptr[0]) | 1728 | if (ptr[0]) |
1836 | goto out_default; | 1729 | return -EINVAL; |
1837 | |||
1838 | return; | ||
1839 | 1730 | ||
1840 | out_default: | 1731 | return 0; |
1841 | printk(KERN_WARNING "viafb received invalid mode string: %s\n", str); | ||
1842 | *xres = 640; | ||
1843 | *yres = 480; | ||
1844 | } | 1732 | } |
1845 | 1733 | ||
1846 | static int __devinit via_pci_probe(struct pci_dev *pdev, | 1734 | static int __devinit via_pci_probe(struct pci_dev *pdev, |
1847 | const struct pci_device_id *ent) | 1735 | const struct pci_device_id *ent) |
1848 | { | 1736 | { |
1849 | u32 default_xres, default_yres; | 1737 | u32 default_xres, default_yres; |
1850 | int vmode_index; | 1738 | struct VideoModeTable *vmode_entry; |
1739 | struct fb_var_screeninfo default_var; | ||
1851 | u32 viafb_par_length; | 1740 | u32 viafb_par_length; |
1852 | 1741 | ||
1853 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); | 1742 | DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); |
1854 | 1743 | memset(&default_var, 0, sizeof(default_var)); | |
1855 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); | 1744 | viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8); |
1856 | 1745 | ||
1857 | /* Allocate fb_info and ***_par here, also including some other needed | 1746 | /* Allocate fb_info and ***_par here, also including some other needed |
@@ -1877,7 +1766,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1877 | 1766 | ||
1878 | if (viafb_dual_fb) | 1767 | if (viafb_dual_fb) |
1879 | viafb_SAMM_ON = 1; | 1768 | viafb_SAMM_ON = 1; |
1880 | parse_active_dev(); | ||
1881 | parse_lcd_port(); | 1769 | parse_lcd_port(); |
1882 | parse_dvi_port(); | 1770 | parse_dvi_port(); |
1883 | 1771 | ||
@@ -1926,9 +1814,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1926 | } | 1814 | } |
1927 | 1815 | ||
1928 | parse_mode(viafb_mode, &default_xres, &default_yres); | 1816 | parse_mode(viafb_mode, &default_xres, &default_yres); |
1929 | vmode_index = viafb_get_mode_index(default_xres, default_yres); | 1817 | vmode_entry = viafb_get_mode(default_xres, default_yres); |
1930 | DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index); | ||
1931 | |||
1932 | if (viafb_SAMM_ON == 1) { | 1818 | if (viafb_SAMM_ON == 1) { |
1933 | parse_mode(viafb_mode1, &viafb_second_xres, | 1819 | parse_mode(viafb_mode1, &viafb_second_xres, |
1934 | &viafb_second_yres); | 1820 | &viafb_second_yres); |
@@ -1947,19 +1833,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1947 | viafb_second_virtual_yres = viafb_second_yres; | 1833 | viafb_second_virtual_yres = viafb_second_yres; |
1948 | } | 1834 | } |
1949 | 1835 | ||
1950 | switch (viafb_bpp) { | ||
1951 | case 0 ... 8: | ||
1952 | viafb_bpp = 8; | ||
1953 | break; | ||
1954 | case 9 ... 16: | ||
1955 | viafb_bpp = 16; | ||
1956 | break; | ||
1957 | case 17 ... 32: | ||
1958 | viafb_bpp = 32; | ||
1959 | break; | ||
1960 | default: | ||
1961 | viafb_bpp = 8; | ||
1962 | } | ||
1963 | default_var.xres = default_xres; | 1836 | default_var.xres = default_xres; |
1964 | default_var.yres = default_yres; | 1837 | default_var.yres = default_yres; |
1965 | switch (default_xres) { | 1838 | switch (default_xres) { |
@@ -1972,8 +1845,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1972 | } | 1845 | } |
1973 | default_var.yres_virtual = default_yres; | 1846 | default_var.yres_virtual = default_yres; |
1974 | default_var.bits_per_pixel = viafb_bpp; | 1847 | default_var.bits_per_pixel = viafb_bpp; |
1975 | if (default_var.bits_per_pixel == 15) | ||
1976 | default_var.bits_per_pixel = 16; | ||
1977 | default_var.pixclock = | 1848 | default_var.pixclock = |
1978 | viafb_get_pixclock(default_xres, default_yres, viafb_refresh); | 1849 | viafb_get_pixclock(default_xres, default_yres, viafb_refresh); |
1979 | default_var.left_margin = (default_xres >> 3) & 0xf8; | 1850 | default_var.left_margin = (default_xres >> 3) & 0xf8; |
@@ -1982,6 +1853,8 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1982 | default_var.lower_margin = 4; | 1853 | default_var.lower_margin = 4; |
1983 | default_var.hsync_len = default_var.left_margin; | 1854 | default_var.hsync_len = default_var.left_margin; |
1984 | default_var.vsync_len = 4; | 1855 | default_var.vsync_len = 4; |
1856 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | ||
1857 | viafbinfo->var = default_var; | ||
1985 | 1858 | ||
1986 | if (viafb_dual_fb) { | 1859 | if (viafb_dual_fb) { |
1987 | viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); | 1860 | viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); |
@@ -2016,8 +1889,6 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
2016 | default_var.yres = viafb_second_yres; | 1889 | default_var.yres = viafb_second_yres; |
2017 | default_var.xres_virtual = viafb_second_virtual_xres; | 1890 | default_var.xres_virtual = viafb_second_virtual_xres; |
2018 | default_var.yres_virtual = viafb_second_virtual_yres; | 1891 | default_var.yres_virtual = viafb_second_virtual_yres; |
2019 | if (viafb_bpp1 != viafb_bpp) | ||
2020 | viafb_bpp1 = viafb_bpp; | ||
2021 | default_var.bits_per_pixel = viafb_bpp1; | 1892 | default_var.bits_per_pixel = viafb_bpp1; |
2022 | default_var.pixclock = | 1893 | default_var.pixclock = |
2023 | viafb_get_pixclock(viafb_second_xres, viafb_second_yres, | 1894 | viafb_get_pixclock(viafb_second_xres, viafb_second_yres, |
@@ -2037,9 +1908,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
2037 | &viafbinfo1->fix); | 1908 | &viafbinfo1->fix); |
2038 | } | 1909 | } |
2039 | 1910 | ||
2040 | viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); | 1911 | viafb_check_var(&viafbinfo->var, viafbinfo); |
2041 | viafb_check_var(&default_var, viafbinfo); | ||
2042 | viafbinfo->var = default_var; | ||
2043 | viafb_update_fix(viafbinfo); | 1912 | viafb_update_fix(viafbinfo); |
2044 | viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, | 1913 | viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, |
2045 | &viafbinfo->fix); | 1914 | &viafbinfo->fix); |
@@ -2197,12 +2066,20 @@ static struct pci_driver viafb_driver = { | |||
2197 | 2066 | ||
2198 | static int __init viafb_init(void) | 2067 | static int __init viafb_init(void) |
2199 | { | 2068 | { |
2069 | u32 dummy; | ||
2200 | #ifndef MODULE | 2070 | #ifndef MODULE |
2201 | char *option = NULL; | 2071 | char *option = NULL; |
2202 | if (fb_get_options("viafb", &option)) | 2072 | if (fb_get_options("viafb", &option)) |
2203 | return -ENODEV; | 2073 | return -ENODEV; |
2204 | viafb_setup(option); | 2074 | viafb_setup(option); |
2205 | #endif | 2075 | #endif |
2076 | if (parse_mode(viafb_mode, &dummy, &dummy) | ||
2077 | || parse_mode(viafb_mode1, &dummy, &dummy) | ||
2078 | || viafb_bpp < 0 || viafb_bpp > 32 | ||
2079 | || viafb_bpp1 < 0 || viafb_bpp1 > 32 | ||
2080 | || parse_active_dev()) | ||
2081 | return -EINVAL; | ||
2082 | |||
2206 | printk(KERN_INFO | 2083 | printk(KERN_INFO |
2207 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", | 2084 | "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", |
2208 | VERSION_MAJOR, VERSION_MINOR); | 2085 | VERSION_MAJOR, VERSION_MINOR); |
@@ -2230,15 +2107,12 @@ static struct fb_ops viafb_ops = { | |||
2230 | .fb_cursor = viafb_cursor, | 2107 | .fb_cursor = viafb_cursor, |
2231 | .fb_ioctl = viafb_ioctl, | 2108 | .fb_ioctl = viafb_ioctl, |
2232 | .fb_sync = viafb_sync, | 2109 | .fb_sync = viafb_sync, |
2233 | .fb_setcmap = viafb_setcmap, | ||
2234 | }; | 2110 | }; |
2235 | 2111 | ||
2236 | module_init(viafb_init); | 2112 | module_init(viafb_init); |
2237 | module_exit(viafb_exit); | 2113 | module_exit(viafb_exit); |
2238 | 2114 | ||
2239 | #ifdef MODULE | 2115 | #ifdef MODULE |
2240 | module_param(viafb_memsize, int, S_IRUSR); | ||
2241 | |||
2242 | module_param(viafb_mode, charp, S_IRUSR); | 2116 | module_param(viafb_mode, charp, S_IRUSR); |
2243 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); | 2117 | MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)"); |
2244 | 2118 | ||
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 0c94d2441922..61b5953cd159 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
@@ -83,22 +83,16 @@ struct viafb_par { | |||
83 | 83 | ||
84 | extern unsigned int viafb_second_virtual_yres; | 84 | extern unsigned int viafb_second_virtual_yres; |
85 | extern unsigned int viafb_second_virtual_xres; | 85 | extern unsigned int viafb_second_virtual_xres; |
86 | extern unsigned int viafb_second_offset; | ||
87 | extern int viafb_second_size; | ||
88 | extern int viafb_SAMM_ON; | 86 | extern int viafb_SAMM_ON; |
89 | extern int viafb_dual_fb; | 87 | extern int viafb_dual_fb; |
90 | extern int viafb_LCD2_ON; | 88 | extern int viafb_LCD2_ON; |
91 | extern int viafb_LCD_ON; | 89 | extern int viafb_LCD_ON; |
92 | extern int viafb_DVI_ON; | 90 | extern int viafb_DVI_ON; |
93 | extern int viafb_hotplug; | 91 | extern int viafb_hotplug; |
94 | extern int viafb_memsize; | ||
95 | 92 | ||
96 | extern int strict_strtoul(const char *cp, unsigned int base, | 93 | extern int strict_strtoul(const char *cp, unsigned int base, |
97 | unsigned long *res); | 94 | unsigned long *res); |
98 | 95 | ||
99 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | ||
100 | int mode_index); | ||
101 | int viafb_get_mode_index(int hres, int vres); | ||
102 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | 96 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information |
103 | *plvds_setting_info, struct lvds_chip_information | 97 | *plvds_setting_info, struct lvds_chip_information |
104 | *plvds_chip_info, u8 index); | 98 | *plvds_chip_info, u8 index); |
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index b74f8a67923c..af50e244016c 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c | |||
@@ -412,7 +412,7 @@ struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C}, | |||
412 | }; | 412 | }; |
413 | 413 | ||
414 | struct patch_table res_patch_table[] = { | 414 | struct patch_table res_patch_table[] = { |
415 | {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768} | 415 | {ARRAY_SIZE(PM1024x768), PM1024x768} |
416 | }; | 416 | }; |
417 | 417 | ||
418 | /* struct VPITTable { | 418 | /* struct VPITTable { |
@@ -879,169 +879,151 @@ struct crt_mode_table CRTM2048x1536[] = { | |||
879 | {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } | 879 | {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} } |
880 | }; | 880 | }; |
881 | 881 | ||
882 | /* Video Mode Table */ | 882 | struct VideoModeTable viafb_modes[] = { |
883 | /* struct VideoModeTable {*/ | ||
884 | /* int ModeIndex;*/ | ||
885 | /* struct crt_mode_table *crtc;*/ | ||
886 | /* int mode_array;*/ | ||
887 | /* };*/ | ||
888 | struct VideoModeTable CLE266Modes[] = { | ||
889 | /* Display : 480x640 (GTF) */ | 883 | /* Display : 480x640 (GTF) */ |
890 | {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)}, | 884 | {CRTM480x640, ARRAY_SIZE(CRTM480x640)}, |
891 | 885 | ||
892 | /* Display : 640x480 */ | 886 | /* Display : 640x480 */ |
893 | {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)}, | 887 | {CRTM640x480, ARRAY_SIZE(CRTM640x480)}, |
894 | 888 | ||
895 | /* Display : 720x480 (GTF) */ | 889 | /* Display : 720x480 (GTF) */ |
896 | {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)}, | 890 | {CRTM720x480, ARRAY_SIZE(CRTM720x480)}, |
897 | 891 | ||
898 | /* Display : 720x576 (GTF) */ | 892 | /* Display : 720x576 (GTF) */ |
899 | {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)}, | 893 | {CRTM720x576, ARRAY_SIZE(CRTM720x576)}, |
900 | 894 | ||
901 | /* Display : 800x600 */ | 895 | /* Display : 800x600 */ |
902 | {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)}, | 896 | {CRTM800x600, ARRAY_SIZE(CRTM800x600)}, |
903 | 897 | ||
904 | /* Display : 800x480 (CVT) */ | 898 | /* Display : 800x480 (CVT) */ |
905 | {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)}, | 899 | {CRTM800x480, ARRAY_SIZE(CRTM800x480)}, |
906 | 900 | ||
907 | /* Display : 848x480 (CVT) */ | 901 | /* Display : 848x480 (CVT) */ |
908 | {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)}, | 902 | {CRTM848x480, ARRAY_SIZE(CRTM848x480)}, |
909 | 903 | ||
910 | /* Display : 852x480 (GTF) */ | 904 | /* Display : 852x480 (GTF) */ |
911 | {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)}, | 905 | {CRTM852x480, ARRAY_SIZE(CRTM852x480)}, |
912 | 906 | ||
913 | /* Display : 1024x512 (GTF) */ | 907 | /* Display : 1024x512 (GTF) */ |
914 | {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)}, | 908 | {CRTM1024x512, ARRAY_SIZE(CRTM1024x512)}, |
915 | 909 | ||
916 | /* Display : 1024x600 */ | 910 | /* Display : 1024x600 */ |
917 | {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)}, | 911 | {CRTM1024x600, ARRAY_SIZE(CRTM1024x600)}, |
918 | |||
919 | /* Display : 1024x576 (GTF) */ | ||
920 | /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */ | ||
921 | 912 | ||
922 | /* Display : 1024x768 */ | 913 | /* Display : 1024x768 */ |
923 | {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)}, | 914 | {CRTM1024x768, ARRAY_SIZE(CRTM1024x768)}, |
924 | 915 | ||
925 | /* Display : 1152x864 */ | 916 | /* Display : 1152x864 */ |
926 | {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)}, | 917 | {CRTM1152x864, ARRAY_SIZE(CRTM1152x864)}, |
927 | 918 | ||
928 | /* Display : 1280x768 (GTF) */ | 919 | /* Display : 1280x768 (GTF) */ |
929 | {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)}, | 920 | {CRTM1280x768, ARRAY_SIZE(CRTM1280x768)}, |
930 | 921 | ||
931 | /* Display : 960x600 (CVT) */ | 922 | /* Display : 960x600 (CVT) */ |
932 | {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)}, | 923 | {CRTM960x600, ARRAY_SIZE(CRTM960x600)}, |
933 | 924 | ||
934 | /* Display : 1000x600 (GTF) */ | 925 | /* Display : 1000x600 (GTF) */ |
935 | {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)}, | 926 | {CRTM1000x600, ARRAY_SIZE(CRTM1000x600)}, |
936 | 927 | ||
937 | /* Display : 1024x576 (GTF) */ | 928 | /* Display : 1024x576 (GTF) */ |
938 | {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, | 929 | {CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, |
939 | 930 | ||
940 | /* Display : 1088x612 (GTF) */ | 931 | /* Display : 1088x612 (GTF) */ |
941 | {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)}, | 932 | {CRTM1088x612, ARRAY_SIZE(CRTM1088x612)}, |
942 | 933 | ||
943 | /* Display : 1152x720 (CVT) */ | 934 | /* Display : 1152x720 (CVT) */ |
944 | {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)}, | 935 | {CRTM1152x720, ARRAY_SIZE(CRTM1152x720)}, |
945 | 936 | ||
946 | /* Display : 1200x720 (GTF) */ | 937 | /* Display : 1200x720 (GTF) */ |
947 | {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)}, | 938 | {CRTM1200x720, ARRAY_SIZE(CRTM1200x720)}, |
948 | 939 | ||
949 | /* Display : 1280x600 (GTF) */ | 940 | /* Display : 1280x600 (GTF) */ |
950 | {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)}, | 941 | {CRTM1280x600, ARRAY_SIZE(CRTM1280x600)}, |
951 | 942 | ||
952 | /* Display : 1280x800 (CVT) */ | 943 | /* Display : 1280x800 (CVT) */ |
953 | {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, | 944 | {CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, |
954 | |||
955 | /* Display : 1280x800 (GTF) */ | ||
956 | /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */ | ||
957 | 945 | ||
958 | /* Display : 1280x960 */ | 946 | /* Display : 1280x960 */ |
959 | {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)}, | 947 | {CRTM1280x960, ARRAY_SIZE(CRTM1280x960)}, |
960 | 948 | ||
961 | /* Display : 1280x1024 */ | 949 | /* Display : 1280x1024 */ |
962 | {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)}, | 950 | {CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)}, |
963 | 951 | ||
964 | /* Display : 1360x768 (CVT) */ | 952 | /* Display : 1360x768 (CVT) */ |
965 | {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)}, | 953 | {CRTM1360x768, ARRAY_SIZE(CRTM1360x768)}, |
966 | |||
967 | /* Display : 1360x768 (CVT Reduce Blanking) */ | ||
968 | {VIA_RES_1360X768_RB, CRTM1360x768_RB, | ||
969 | ARRAY_SIZE(CRTM1360x768_RB)}, | ||
970 | 954 | ||
971 | /* Display : 1366x768 */ | 955 | /* Display : 1366x768 */ |
972 | {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)}, | 956 | {CRTM1366x768, ARRAY_SIZE(CRTM1366x768)}, |
973 | 957 | ||
974 | /* Display : 1368x768 (GTF) */ | 958 | /* Display : 1368x768 (GTF) */ |
975 | /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */ | 959 | {CRTM1368x768, ARRAY_SIZE(CRTM1368x768)}, |
976 | /* Display : 1368x768 (GTF) */ | ||
977 | {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)}, | ||
978 | 960 | ||
979 | /* Display : 1440x900 (CVT) */ | 961 | /* Display : 1440x900 (CVT) */ |
980 | {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)}, | 962 | {CRTM1440x900, ARRAY_SIZE(CRTM1440x900)}, |
981 | |||
982 | /* Display : 1440x900 (CVT Reduce Blanking) */ | ||
983 | {VIA_RES_1440X900_RB, CRTM1440x900_RB, | ||
984 | ARRAY_SIZE(CRTM1440x900_RB)}, | ||
985 | 963 | ||
986 | /* Display : 1440x1050 (GTF) */ | 964 | /* Display : 1440x1050 (GTF) */ |
987 | {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)}, | 965 | {CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)}, |
988 | |||
989 | /* Display : 1400x1050 (CVT Reduce Blanking) */ | ||
990 | {VIA_RES_1400X1050_RB, CRTM1400x1050_RB, | ||
991 | ARRAY_SIZE(CRTM1400x1050_RB)}, | ||
992 | 966 | ||
993 | /* Display : 1600x900 (CVT) */ | 967 | /* Display : 1600x900 (CVT) */ |
994 | {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)}, | 968 | {CRTM1600x900, ARRAY_SIZE(CRTM1600x900)}, |
995 | |||
996 | /* Display : 1600x900 (CVT Reduce Blanking) */ | ||
997 | {VIA_RES_1600X900_RB, CRTM1600x900_RB, | ||
998 | ARRAY_SIZE(CRTM1600x900_RB)}, | ||
999 | 969 | ||
1000 | /* Display : 1600x1024 (GTF) */ | 970 | /* Display : 1600x1024 (GTF) */ |
1001 | {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)}, | 971 | {CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)}, |
1002 | 972 | ||
1003 | /* Display : 1600x1200 */ | 973 | /* Display : 1600x1200 */ |
1004 | {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)}, | 974 | {CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)}, |
1005 | 975 | ||
1006 | /* Display : 1680x1050 (CVT) */ | 976 | /* Display : 1680x1050 (CVT) */ |
1007 | {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)}, | 977 | {CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)}, |
1008 | |||
1009 | /* Display : 1680x1050 (CVT Reduce Blanking) */ | ||
1010 | {VIA_RES_1680X1050_RB, CRTM1680x1050_RB, | ||
1011 | ARRAY_SIZE(CRTM1680x1050_RB)}, | ||
1012 | 978 | ||
1013 | /* Display : 1792x1344 (DMT) */ | 979 | /* Display : 1792x1344 (DMT) */ |
1014 | {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)}, | 980 | {CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)}, |
1015 | 981 | ||
1016 | /* Display : 1856x1392 (DMT) */ | 982 | /* Display : 1856x1392 (DMT) */ |
1017 | {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)}, | 983 | {CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)}, |
1018 | 984 | ||
1019 | /* Display : 1920x1440 */ | 985 | /* Display : 1920x1440 */ |
1020 | {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)}, | 986 | {CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)}, |
1021 | 987 | ||
1022 | /* Display : 2048x1536 */ | 988 | /* Display : 2048x1536 */ |
1023 | {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)}, | 989 | {CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)}, |
1024 | 990 | ||
1025 | /* Display : 1280x720 */ | 991 | /* Display : 1280x720 */ |
1026 | {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)}, | 992 | {CRTM1280x720, ARRAY_SIZE(CRTM1280x720)}, |
1027 | 993 | ||
1028 | /* Display : 1920x1080 (CVT) */ | 994 | /* Display : 1920x1080 (CVT) */ |
1029 | {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)}, | 995 | {CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)}, |
1030 | |||
1031 | /* Display : 1920x1080 (CVT Reduce Blanking) */ | ||
1032 | {VIA_RES_1920X1080_RB, CRTM1920x1080_RB, | ||
1033 | ARRAY_SIZE(CRTM1920x1080_RB)}, | ||
1034 | 996 | ||
1035 | /* Display : 1920x1200 (CVT) */ | 997 | /* Display : 1920x1200 (CVT) */ |
1036 | {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)}, | 998 | {CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)}, |
1037 | |||
1038 | /* Display : 1920x1200 (CVT Reduce Blanking) */ | ||
1039 | {VIA_RES_1920X1200_RB, CRTM1920x1200_RB, | ||
1040 | ARRAY_SIZE(CRTM1920x1200_RB)}, | ||
1041 | 999 | ||
1042 | /* Display : 1400x1050 (CVT) */ | 1000 | /* Display : 1400x1050 (CVT) */ |
1043 | {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} | 1001 | {CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)} |
1044 | }; | 1002 | }; |
1003 | |||
1004 | struct VideoModeTable viafb_rb_modes[] = { | ||
1005 | /* Display : 1360x768 (CVT Reduce Blanking) */ | ||
1006 | {CRTM1360x768_RB, ARRAY_SIZE(CRTM1360x768_RB)}, | ||
1007 | |||
1008 | /* Display : 1440x900 (CVT Reduce Blanking) */ | ||
1009 | {CRTM1440x900_RB, ARRAY_SIZE(CRTM1440x900_RB)}, | ||
1010 | |||
1011 | /* Display : 1400x1050 (CVT Reduce Blanking) */ | ||
1012 | {CRTM1400x1050_RB, ARRAY_SIZE(CRTM1400x1050_RB)}, | ||
1013 | |||
1014 | /* Display : 1600x900 (CVT Reduce Blanking) */ | ||
1015 | {CRTM1600x900_RB, ARRAY_SIZE(CRTM1600x900_RB)}, | ||
1016 | |||
1017 | /* Display : 1680x1050 (CVT Reduce Blanking) */ | ||
1018 | {CRTM1680x1050_RB, ARRAY_SIZE(CRTM1680x1050_RB)}, | ||
1019 | |||
1020 | /* Display : 1920x1080 (CVT Reduce Blanking) */ | ||
1021 | {CRTM1920x1080_RB, ARRAY_SIZE(CRTM1920x1080_RB)}, | ||
1022 | |||
1023 | /* Display : 1920x1200 (CVT Reduce Blanking) */ | ||
1024 | {CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)} | ||
1025 | }; | ||
1026 | |||
1045 | struct crt_mode_table CEAM1280x720[] = { | 1027 | struct crt_mode_table CEAM1280x720[] = { |
1046 | {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP, | 1028 | {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP, |
1047 | M1280X720_CEA_R60_VSP, | 1029 | M1280X720_CEA_R60_VSP, |
@@ -1056,8 +1038,8 @@ struct crt_mode_table CEAM1920x1080[] = { | |||
1056 | }; | 1038 | }; |
1057 | struct VideoModeTable CEA_HDMI_Modes[] = { | 1039 | struct VideoModeTable CEA_HDMI_Modes[] = { |
1058 | /* Display : 1280x720 */ | 1040 | /* Display : 1280x720 */ |
1059 | {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, | 1041 | {CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, |
1060 | {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} | 1042 | {CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} |
1061 | }; | 1043 | }; |
1062 | 1044 | ||
1063 | int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl); | 1045 | int NUM_TOTAL_RES_MAP_REFRESH = ARRAY_SIZE(res_map_refresh_tbl); |
@@ -1069,4 +1051,28 @@ int NUM_TOTAL_CX700_ModeXregs = ARRAY_SIZE(CX700_ModeXregs); | |||
1069 | int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs); | 1051 | int NUM_TOTAL_VX855_ModeXregs = ARRAY_SIZE(VX855_ModeXregs); |
1070 | int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs); | 1052 | int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs); |
1071 | int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table); | 1053 | int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table); |
1072 | int NUM_TOTAL_MODETABLE = ARRAY_SIZE(CLE266Modes); | 1054 | |
1055 | |||
1056 | struct VideoModeTable *viafb_get_mode(int hres, int vres) | ||
1057 | { | ||
1058 | u32 i; | ||
1059 | for (i = 0; i < ARRAY_SIZE(viafb_modes); i++) | ||
1060 | if (viafb_modes[i].mode_array && | ||
1061 | viafb_modes[i].crtc[0].crtc.hor_addr == hres && | ||
1062 | viafb_modes[i].crtc[0].crtc.ver_addr == vres) | ||
1063 | return &viafb_modes[i]; | ||
1064 | |||
1065 | return NULL; | ||
1066 | } | ||
1067 | |||
1068 | struct VideoModeTable *viafb_get_rb_mode(int hres, int vres) | ||
1069 | { | ||
1070 | u32 i; | ||
1071 | for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++) | ||
1072 | if (viafb_rb_modes[i].mode_array && | ||
1073 | viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres && | ||
1074 | viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres) | ||
1075 | return &viafb_rb_modes[i]; | ||
1076 | |||
1077 | return NULL; | ||
1078 | } | ||
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h index a9d6554fabdf..5b1ced86514b 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/via/viamode.h | |||
@@ -32,13 +32,11 @@ struct VPITTable { | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | struct VideoModeTable { | 34 | struct VideoModeTable { |
35 | int ModeIndex; | ||
36 | struct crt_mode_table *crtc; | 35 | struct crt_mode_table *crtc; |
37 | int mode_array; | 36 | int mode_array; |
38 | }; | 37 | }; |
39 | 38 | ||
40 | struct patch_table { | 39 | struct patch_table { |
41 | int mode_index; | ||
42 | int table_length; | 40 | int table_length; |
43 | struct io_reg *io_reg_table; | 41 | struct io_reg *io_reg_table; |
44 | }; | 42 | }; |
@@ -59,13 +57,11 @@ extern int NUM_TOTAL_CX700_ModeXregs; | |||
59 | extern int NUM_TOTAL_VX855_ModeXregs; | 57 | extern int NUM_TOTAL_VX855_ModeXregs; |
60 | extern int NUM_TOTAL_CLE266_ModeXregs; | 58 | extern int NUM_TOTAL_CLE266_ModeXregs; |
61 | extern int NUM_TOTAL_PATCH_MODE; | 59 | extern int NUM_TOTAL_PATCH_MODE; |
62 | extern int NUM_TOTAL_MODETABLE; | ||
63 | 60 | ||
64 | /********************/ | 61 | /********************/ |
65 | /* Mode Table */ | 62 | /* Mode Table */ |
66 | /********************/ | 63 | /********************/ |
67 | 64 | ||
68 | extern struct VideoModeTable CLE266Modes[]; | ||
69 | extern struct crt_mode_table CEAM1280x720[]; | 65 | extern struct crt_mode_table CEAM1280x720[]; |
70 | extern struct crt_mode_table CEAM1920x1080[]; | 66 | extern struct crt_mode_table CEAM1920x1080[]; |
71 | extern struct VideoModeTable CEA_HDMI_Modes[]; | 67 | extern struct VideoModeTable CEA_HDMI_Modes[]; |
@@ -81,4 +77,8 @@ extern struct io_reg CLE266_ModeXregs[]; | |||
81 | extern struct io_reg PM1024x768[]; | 77 | extern struct io_reg PM1024x768[]; |
82 | extern struct patch_table res_patch_table[]; | 78 | extern struct patch_table res_patch_table[]; |
83 | extern struct VPITTable VPIT; | 79 | extern struct VPITTable VPIT; |
80 | |||
81 | struct VideoModeTable *viafb_get_mode(int hres, int vres); | ||
82 | struct VideoModeTable *viafb_get_rb_mode(int hres, int vres); | ||
83 | |||
84 | #endif /* __VIAMODE_H__ */ | 84 | #endif /* __VIAMODE_H__ */ |
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 2376f688ec8b..5d223959778a 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -628,7 +628,7 @@ static int w100fb_resume(struct platform_device *dev) | |||
628 | #endif | 628 | #endif |
629 | 629 | ||
630 | 630 | ||
631 | int __init w100fb_probe(struct platform_device *pdev) | 631 | int __devinit w100fb_probe(struct platform_device *pdev) |
632 | { | 632 | { |
633 | int err = -EIO; | 633 | int err = -EIO; |
634 | struct w100fb_mach_info *inf; | 634 | struct w100fb_mach_info *inf; |
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index 406caa6a71cb..e5f74416d4b7 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c | |||
@@ -214,7 +214,7 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev) | |||
214 | (++retries < DS2482_WAIT_IDLE_TIMEOUT)); | 214 | (++retries < DS2482_WAIT_IDLE_TIMEOUT)); |
215 | } | 215 | } |
216 | 216 | ||
217 | if (retries > DS2482_WAIT_IDLE_TIMEOUT) | 217 | if (retries >= DS2482_WAIT_IDLE_TIMEOUT) |
218 | printk(KERN_ERR "%s: timeout on channel %d\n", | 218 | printk(KERN_ERR "%s: timeout on channel %d\n", |
219 | __func__, pdev->channel); | 219 | __func__, pdev->channel); |
220 | 220 | ||
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 65244c02551b..492670358cbf 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c | |||
@@ -102,7 +102,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit) | |||
102 | return ((__raw_readb(ctrl_addr)) >> 3) & 0x1; | 102 | return ((__raw_readb(ctrl_addr)) >> 3) & 0x1; |
103 | } | 103 | } |
104 | 104 | ||
105 | static int __init mxc_w1_probe(struct platform_device *pdev) | 105 | static int __devinit mxc_w1_probe(struct platform_device *pdev) |
106 | { | 106 | { |
107 | struct mxc_w1_device *mdev; | 107 | struct mxc_w1_device *mdev; |
108 | struct resource *res; | 108 | struct resource *res; |
@@ -166,7 +166,7 @@ failed_clk: | |||
166 | /* | 166 | /* |
167 | * disassociate the w1 device from the driver | 167 | * disassociate the w1 device from the driver |
168 | */ | 168 | */ |
169 | static int mxc_w1_remove(struct platform_device *pdev) | 169 | static int __devexit mxc_w1_remove(struct platform_device *pdev) |
170 | { | 170 | { |
171 | struct mxc_w1_device *mdev = platform_get_drvdata(pdev); | 171 | struct mxc_w1_device *mdev = platform_get_drvdata(pdev); |
172 | struct resource *res; | 172 | struct resource *res; |
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 0d92969404c3..22977d30f89e 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c | |||
@@ -72,7 +72,7 @@ struct hdq_data { | |||
72 | int init_trans; | 72 | int init_trans; |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static int __init omap_hdq_probe(struct platform_device *pdev); | 75 | static int __devinit omap_hdq_probe(struct platform_device *pdev); |
76 | static int omap_hdq_remove(struct platform_device *pdev); | 76 | static int omap_hdq_remove(struct platform_device *pdev); |
77 | 77 | ||
78 | static struct platform_driver omap_hdq_driver = { | 78 | static struct platform_driver omap_hdq_driver = { |
@@ -558,7 +558,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) | |||
558 | return; | 558 | return; |
559 | } | 559 | } |
560 | 560 | ||
561 | static int __init omap_hdq_probe(struct platform_device *pdev) | 561 | static int __devinit omap_hdq_probe(struct platform_device *pdev) |
562 | { | 562 | { |
563 | struct hdq_data *hdq_data; | 563 | struct hdq_data *hdq_data; |
564 | struct resource *res; | 564 | struct resource *res; |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index acc7e3b7fe17..ad5897dc4495 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -986,7 +986,7 @@ int w1_process(void *data) | |||
986 | return 0; | 986 | return 0; |
987 | } | 987 | } |
988 | 988 | ||
989 | static int w1_init(void) | 989 | static int __init w1_init(void) |
990 | { | 990 | { |
991 | int retval; | 991 | int retval; |
992 | 992 | ||
@@ -1034,7 +1034,7 @@ err_out_exit_init: | |||
1034 | return retval; | 1034 | return retval; |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | static void w1_fini(void) | 1037 | static void __exit w1_fini(void) |
1038 | { | 1038 | { |
1039 | struct w1_master *dev; | 1039 | struct w1_master *dev; |
1040 | 1040 | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3da3f48720a7..bdcdbd53da89 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -55,6 +55,11 @@ config SOFT_WATCHDOG | |||
55 | To compile this driver as a module, choose M here: the | 55 | To compile this driver as a module, choose M here: the |
56 | module will be called softdog. | 56 | module will be called softdog. |
57 | 57 | ||
58 | config MAX63XX_WATCHDOG | ||
59 | tristate "Max63xx watchdog" | ||
60 | help | ||
61 | Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. | ||
62 | |||
58 | config WM831X_WATCHDOG | 63 | config WM831X_WATCHDOG |
59 | tristate "WM831x watchdog" | 64 | tristate "WM831x watchdog" |
60 | depends on MFD_WM831X | 65 | depends on MFD_WM831X |
@@ -289,6 +294,17 @@ config ADX_WATCHDOG | |||
289 | Say Y here if you want support for the watchdog timer on Avionic | 294 | Say Y here if you want support for the watchdog timer on Avionic |
290 | Design Xanthos boards. | 295 | Design Xanthos boards. |
291 | 296 | ||
297 | config TS72XX_WATCHDOG | ||
298 | tristate "TS-72XX SBC Watchdog" | ||
299 | depends on MACH_TS72XX | ||
300 | help | ||
301 | Technologic Systems TS-7200, TS-7250 and TS-7260 boards have | ||
302 | watchdog timer implemented in a external CPLD chip. Say Y here | ||
303 | if you want to support for the watchdog timer on TS-72XX boards. | ||
304 | |||
305 | To compile this driver as a module, choose M here: the | ||
306 | module will be called ts72xx_wdt. | ||
307 | |||
292 | # AVR32 Architecture | 308 | # AVR32 Architecture |
293 | 309 | ||
294 | config AT32AP700X_WDT | 310 | config AT32AP700X_WDT |
@@ -845,10 +861,10 @@ config TXX9_WDT | |||
845 | # POWERPC Architecture | 861 | # POWERPC Architecture |
846 | 862 | ||
847 | config GEF_WDT | 863 | config GEF_WDT |
848 | tristate "GE Fanuc Watchdog Timer" | 864 | tristate "GE Watchdog Timer" |
849 | depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A | 865 | depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A |
850 | ---help--- | 866 | ---help--- |
851 | Watchdog timer found in a number of GE Fanuc single board computers. | 867 | Watchdog timer found in a number of GE single board computers. |
852 | 868 | ||
853 | config MPC5200_WDT | 869 | config MPC5200_WDT |
854 | bool "MPC52xx Watchdog Timer" | 870 | bool "MPC52xx Watchdog Timer" |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 475c61100069..5e3cb95bb0e9 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o | |||
46 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o | 46 | obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o |
47 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o | 47 | obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o |
48 | obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o | 48 | obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o |
49 | obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o | ||
49 | 50 | ||
50 | # AVR32 Architecture | 51 | # AVR32 Architecture |
51 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 52 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
@@ -142,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o | |||
142 | # Architecture Independant | 143 | # Architecture Independant |
143 | obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o | 144 | obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o |
144 | obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o | 145 | obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o |
146 | obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o | ||
145 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o | 147 | obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o |
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 4d18c874d963..2ffce4d75443 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c | |||
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
150 | int options, retval = -EINVAL; | 150 | int options, retval = -EINVAL; |
151 | void __user *argp = (void __user *)arg; | 151 | void __user *argp = (void __user *)arg; |
152 | int __user *p = argp; | 152 | int __user *p = argp; |
153 | static struct watchdog_info ident = { | 153 | static const struct watchdog_info ident = { |
154 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 154 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
155 | .firmware_version = 1, | 155 | .firmware_version = 1, |
156 | .identity = WATCHDOG_NAME, | 156 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 824d076a5cd6..4d40965d2c9f 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c | |||
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
137 | int new_timeout; | 137 | int new_timeout; |
138 | void __user *argp = (void __user *)arg; | 138 | void __user *argp = (void __user *)arg; |
139 | int __user *p = argp; | 139 | int __user *p = argp; |
140 | static struct watchdog_info ident = { | 140 | static const struct watchdog_info ident = { |
141 | .options = WDIOF_KEEPALIVEPING | | 141 | .options = WDIOF_KEEPALIVEPING | |
142 | WDIOF_SETTIMEOUT | | 142 | WDIOF_SETTIMEOUT | |
143 | WDIOF_MAGICCLOSE, | 143 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c index 9d7d155364f8..a5ca7a6ee133 100644 --- a/drivers/watchdog/adx_wdt.c +++ b/drivers/watchdog/adx_wdt.c | |||
@@ -37,7 +37,7 @@ struct adx_wdt { | |||
37 | spinlock_t lock; | 37 | spinlock_t lock; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct watchdog_info adx_wdt_info = { | 40 | static const struct watchdog_info adx_wdt_info = { |
41 | .identity = "Avionic Design Xanthos Watchdog", | 41 | .identity = "Avionic Design Xanthos Watchdog", |
42 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 42 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
43 | }; | 43 | }; |
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index 937a80fb61e1..1e9caea8ff8a 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c | |||
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
180 | { | 180 | { |
181 | void __user *argp = (void __user *)arg; | 181 | void __user *argp = (void __user *)arg; |
182 | int __user *p = argp; | 182 | int __user *p = argp; |
183 | static struct watchdog_info ident = { | 183 | static const struct watchdog_info ident = { |
184 | .options = WDIOF_KEEPALIVEPING | | 184 | .options = WDIOF_KEEPALIVEPING | |
185 | WDIOF_SETTIMEOUT | | 185 | WDIOF_SETTIMEOUT | |
186 | WDIOF_MAGICCLOSE, | 186 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index f90afdb1b255..d8d4da9a483d 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c | |||
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
238 | { | 238 | { |
239 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
240 | int __user *p = argp; | 240 | int __user *p = argp; |
241 | static struct watchdog_info ident = { | 241 | static const struct watchdog_info ident = { |
242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
243 | | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
244 | .firmware_version = 1, | 244 | .firmware_version = 1, |
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 2bb95cd308c1..c764c52412e4 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -219,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, | |||
219 | static long ar7_wdt_ioctl(struct file *file, | 219 | static long ar7_wdt_ioctl(struct file *file, |
220 | unsigned int cmd, unsigned long arg) | 220 | unsigned int cmd, unsigned long arg) |
221 | { | 221 | { |
222 | static struct watchdog_info ident = { | 222 | static const struct watchdog_info ident = { |
223 | .identity = LONGNAME, | 223 | .identity = LONGNAME, |
224 | .firmware_version = 1, | 224 | .firmware_version = 1, |
225 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | 225 | .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index 037847923dcb..6873376f986c 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c | |||
@@ -202,7 +202,7 @@ static int at32_wdt_get_status(void) | |||
202 | return status; | 202 | return status; |
203 | } | 203 | } |
204 | 204 | ||
205 | static struct watchdog_info at32_wdt_info = { | 205 | static const struct watchdog_info at32_wdt_info = { |
206 | .identity = "at32ap700x watchdog", | 206 | .identity = "at32ap700x watchdog", |
207 | .options = WDIOF_SETTIMEOUT | | 207 | .options = WDIOF_SETTIMEOUT | |
208 | WDIOF_KEEPALIVEPING | | 208 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index b185dafe1494..b3046dc4b56c 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_time) | |||
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | static struct watchdog_info at91_wdt_info = { | 124 | static const struct watchdog_info at91_wdt_info = { |
125 | .identity = "at91 watchdog", | 125 | .identity = "at91 watchdog", |
126 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 126 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
127 | }; | 127 | }; |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index 751c003864ad..5f245522397b 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data, | |||
149 | return len; | 149 | return len; |
150 | } | 150 | } |
151 | 151 | ||
152 | static struct watchdog_info bcm47xx_wdt_info = { | 152 | static const struct watchdog_info bcm47xx_wdt_info = { |
153 | .identity = DRV_NAME, | 153 | .identity = DRV_NAME, |
154 | .options = WDIOF_SETTIMEOUT | | 154 | .options = WDIOF_SETTIMEOUT | |
155 | WDIOF_KEEPALIVEPING | | 155 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 2159e668751c..9c7ccd1e9088 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
20 | #include <linux/watchdog.h> | 20 | #include <linux/watchdog.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/notifier.h> | ||
23 | #include <linux/reboot.h> | ||
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
26 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
@@ -74,7 +72,7 @@ | |||
74 | 72 | ||
75 | static unsigned int timeout = WATCHDOG_TIMEOUT; | 73 | static unsigned int timeout = WATCHDOG_TIMEOUT; |
76 | static int nowayout = WATCHDOG_NOWAYOUT; | 74 | static int nowayout = WATCHDOG_NOWAYOUT; |
77 | static struct watchdog_info bfin_wdt_info; | 75 | static const struct watchdog_info bfin_wdt_info; |
78 | static unsigned long open_check; | 76 | static unsigned long open_check; |
79 | static char expect_close; | 77 | static char expect_close; |
80 | static DEFINE_SPINLOCK(bfin_wdt_spinlock); | 78 | static DEFINE_SPINLOCK(bfin_wdt_spinlock); |
@@ -309,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file, | |||
309 | } | 307 | } |
310 | } | 308 | } |
311 | 309 | ||
312 | /** | ||
313 | * bfin_wdt_notify_sys - Notifier Handler | ||
314 | * @this: notifier block | ||
315 | * @code: notifier event | ||
316 | * @unused: unused | ||
317 | * | ||
318 | * Handles specific events, such as turning off the watchdog during a | ||
319 | * shutdown event. | ||
320 | */ | ||
321 | static int bfin_wdt_notify_sys(struct notifier_block *this, | ||
322 | unsigned long code, void *unused) | ||
323 | { | ||
324 | stampit(); | ||
325 | |||
326 | if (code == SYS_DOWN || code == SYS_HALT) | ||
327 | bfin_wdt_stop(); | ||
328 | |||
329 | return NOTIFY_DONE; | ||
330 | } | ||
331 | |||
332 | #ifdef CONFIG_PM | 310 | #ifdef CONFIG_PM |
333 | static int state_before_suspend; | 311 | static int state_before_suspend; |
334 | 312 | ||
@@ -388,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = { | |||
388 | .fops = &bfin_wdt_fops, | 366 | .fops = &bfin_wdt_fops, |
389 | }; | 367 | }; |
390 | 368 | ||
391 | static struct watchdog_info bfin_wdt_info = { | 369 | static const struct watchdog_info bfin_wdt_info = { |
392 | .identity = "Blackfin Watchdog", | 370 | .identity = "Blackfin Watchdog", |
393 | .options = WDIOF_SETTIMEOUT | | 371 | .options = WDIOF_SETTIMEOUT | |
394 | WDIOF_KEEPALIVEPING | | 372 | WDIOF_KEEPALIVEPING | |
395 | WDIOF_MAGICCLOSE, | 373 | WDIOF_MAGICCLOSE, |
396 | }; | 374 | }; |
397 | 375 | ||
398 | static struct notifier_block bfin_wdt_notifier = { | ||
399 | .notifier_call = bfin_wdt_notify_sys, | ||
400 | }; | ||
401 | |||
402 | /** | 376 | /** |
403 | * bfin_wdt_probe - Initialize module | 377 | * bfin_wdt_probe - Initialize module |
404 | * | 378 | * |
405 | * Registers the misc device and notifier handler. Actual device | 379 | * Registers the misc device. Actual device |
406 | * initialization is handled by bfin_wdt_open(). | 380 | * initialization is handled by bfin_wdt_open(). |
407 | */ | 381 | */ |
408 | static int __devinit bfin_wdt_probe(struct platform_device *pdev) | 382 | static int __devinit bfin_wdt_probe(struct platform_device *pdev) |
409 | { | 383 | { |
410 | int ret; | 384 | int ret; |
411 | 385 | ||
412 | ret = register_reboot_notifier(&bfin_wdt_notifier); | ||
413 | if (ret) { | ||
414 | pr_devinit(KERN_ERR PFX | ||
415 | "cannot register reboot notifier (err=%d)\n", ret); | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | ret = misc_register(&bfin_wdt_miscdev); | 386 | ret = misc_register(&bfin_wdt_miscdev); |
420 | if (ret) { | 387 | if (ret) { |
421 | pr_devinit(KERN_ERR PFX | 388 | pr_devinit(KERN_ERR PFX |
422 | "cannot register miscdev on minor=%d (err=%d)\n", | 389 | "cannot register miscdev on minor=%d (err=%d)\n", |
423 | WATCHDOG_MINOR, ret); | 390 | WATCHDOG_MINOR, ret); |
424 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
425 | return ret; | 391 | return ret; |
426 | } | 392 | } |
427 | 393 | ||
@@ -434,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev) | |||
434 | /** | 400 | /** |
435 | * bfin_wdt_remove - Initialize module | 401 | * bfin_wdt_remove - Initialize module |
436 | * | 402 | * |
437 | * Unregisters the misc device and notifier handler. Actual device | 403 | * Unregisters the misc device. Actual device |
438 | * deinitialization is handled by bfin_wdt_close(). | 404 | * deinitialization is handled by bfin_wdt_close(). |
439 | */ | 405 | */ |
440 | static int __devexit bfin_wdt_remove(struct platform_device *pdev) | 406 | static int __devexit bfin_wdt_remove(struct platform_device *pdev) |
441 | { | 407 | { |
442 | misc_deregister(&bfin_wdt_miscdev); | 408 | misc_deregister(&bfin_wdt_miscdev); |
443 | unregister_reboot_notifier(&bfin_wdt_notifier); | ||
444 | return 0; | 409 | return 0; |
445 | } | 410 | } |
446 | 411 | ||
412 | /** | ||
413 | * bfin_wdt_shutdown - Soft Shutdown Handler | ||
414 | * | ||
415 | * Handles the soft shutdown event. | ||
416 | */ | ||
417 | static void bfin_wdt_shutdown(struct platform_device *pdev) | ||
418 | { | ||
419 | stampit(); | ||
420 | |||
421 | bfin_wdt_stop(); | ||
422 | } | ||
423 | |||
447 | static struct platform_device *bfin_wdt_device; | 424 | static struct platform_device *bfin_wdt_device; |
448 | 425 | ||
449 | static struct platform_driver bfin_wdt_driver = { | 426 | static struct platform_driver bfin_wdt_driver = { |
450 | .probe = bfin_wdt_probe, | 427 | .probe = bfin_wdt_probe, |
451 | .remove = __devexit_p(bfin_wdt_remove), | 428 | .remove = __devexit_p(bfin_wdt_remove), |
429 | .shutdown = bfin_wdt_shutdown, | ||
452 | .suspend = bfin_wdt_suspend, | 430 | .suspend = bfin_wdt_suspend, |
453 | .resume = bfin_wdt_resume, | 431 | .resume = bfin_wdt_resume, |
454 | .driver = { | 432 | .driver = { |
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index e8380ef65c1c..8b724aad6825 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -121,7 +121,7 @@ static ssize_t booke_wdt_write(struct file *file, const char __user *buf, | |||
121 | return count; | 121 | return count; |
122 | } | 122 | } |
123 | 123 | ||
124 | static struct watchdog_info ident = { | 124 | static const struct watchdog_info ident = { |
125 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 125 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
126 | .identity = "PowerPC Book-E Watchdog", | 126 | .identity = "PowerPC Book-E Watchdog", |
127 | }; | 127 | }; |
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c index 923cc68dba26..9291506b8b23 100644 --- a/drivers/watchdog/coh901327_wdt.c +++ b/drivers/watchdog/coh901327_wdt.c | |||
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file *file, unsigned int cmd, | |||
257 | struct watchdog_info __user *ident; | 257 | struct watchdog_info __user *ident; |
258 | int __user *i; | 258 | int __user *i; |
259 | } uarg; | 259 | } uarg; |
260 | static struct watchdog_info ident = { | 260 | static const struct watchdog_info ident = { |
261 | .options = WDIOF_CARDRESET | | 261 | .options = WDIOF_CARDRESET | |
262 | WDIOF_SETTIMEOUT | | 262 | WDIOF_SETTIMEOUT | |
263 | WDIOF_KEEPALIVEPING, | 263 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 71f6d7eec9a8..edd3475f41db 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c | |||
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *file, unsigned int cmd, | |||
154 | void __user *argp = (void __user *)arg; | 154 | void __user *argp = (void __user *)arg; |
155 | int __user *p = argp; | 155 | int __user *p = argp; |
156 | unsigned int value; | 156 | unsigned int value; |
157 | static struct watchdog_info ident = { | 157 | static const struct watchdog_info ident = { |
158 | .options = WDIOF_CARDRESET, | 158 | .options = WDIOF_CARDRESET, |
159 | .identity = "CPU5 WDT", | 159 | .identity = "CPU5 WDT", |
160 | }; | 160 | }; |
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 081f2955419e..37ea052d4dee 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c | |||
@@ -403,7 +403,7 @@ static int cpwd_release(struct inode *inode, struct file *file) | |||
403 | 403 | ||
404 | static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 404 | static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
405 | { | 405 | { |
406 | static struct watchdog_info info = { | 406 | static const struct watchdog_info info = { |
407 | .options = WDIOF_SETTIMEOUT, | 407 | .options = WDIOF_SETTIMEOUT, |
408 | .firmware_version = 1, | 408 | .firmware_version = 1, |
409 | .identity = DRIVER_NAME, | 409 | .identity = DRIVER_NAME, |
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 887136de1857..56162c87f5d8 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c | |||
@@ -142,7 +142,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len, | |||
142 | return len; | 142 | return len; |
143 | } | 143 | } |
144 | 144 | ||
145 | static struct watchdog_info ident = { | 145 | static const struct watchdog_info ident = { |
146 | .options = WDIOF_KEEPALIVEPING, | 146 | .options = WDIOF_KEEPALIVEPING, |
147 | .identity = "DaVinci Watchdog", | 147 | .identity = "DaVinci Watchdog", |
148 | }; | 148 | }; |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index cdd55e0d09f8..88ed54e50f74 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, const char __user *data, size_t len, | |||
131 | return len; | 131 | return len; |
132 | } | 132 | } |
133 | 133 | ||
134 | static struct watchdog_info ident = { | 134 | static const struct watchdog_info ident = { |
135 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, | 135 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, |
136 | .identity = "EP93xx Watchdog", | 136 | .identity = "EP93xx Watchdog", |
137 | }; | 137 | }; |
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index 9add3541fb42..d1c4e55b1db0 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c | |||
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *file, | |||
238 | { | 238 | { |
239 | void __user *argp = (void __user *)arg; | 239 | void __user *argp = (void __user *)arg; |
240 | int __user *p = argp; | 240 | int __user *p = argp; |
241 | static struct watchdog_info ident = { | 241 | static const struct watchdog_info ident = { |
242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 242 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
243 | | WDIOF_MAGICCLOSE, | 243 | | WDIOF_MAGICCLOSE, |
244 | .firmware_version = 1, | 244 | .firmware_version = 1, |
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 734d9806a872..abdbad034a6c 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * GE Fanuc watchdog userspace interface | 2 | * GE watchdog userspace interface |
3 | * | 3 | * |
4 | * Author: Martyn Welch <martyn.welch@gefanuc.com> | 4 | * Author: Martyn Welch <martyn.welch@ge.com> |
5 | * | 5 | * |
6 | * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. | 6 | * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *file, unsigned int cmd, | |||
161 | int timeout; | 161 | int timeout; |
162 | int options; | 162 | int options; |
163 | void __user *argp = (void __user *)arg; | 163 | void __user *argp = (void __user *)arg; |
164 | static struct watchdog_info info = { | 164 | static const struct watchdog_info info = { |
165 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | | 165 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | |
166 | WDIOF_KEEPALIVEPING, | 166 | WDIOF_KEEPALIVEPING, |
167 | .firmware_version = 0, | 167 | .firmware_version = 0, |
168 | .identity = "GE Fanuc watchdog", | 168 | .identity = "GE watchdog", |
169 | }; | 169 | }; |
170 | 170 | ||
171 | switch (cmd) { | 171 | switch (cmd) { |
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt_driver = { | |||
311 | 311 | ||
312 | static int __init gef_wdt_init(void) | 312 | static int __init gef_wdt_init(void) |
313 | { | 313 | { |
314 | printk(KERN_INFO "GE Fanuc watchdog driver\n"); | 314 | printk(KERN_INFO "GE watchdog driver\n"); |
315 | return of_register_platform_driver(&gef_wdt_driver); | 315 | return of_register_platform_driver(&gef_wdt_driver); |
316 | } | 316 | } |
317 | 317 | ||
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void) | |||
323 | module_init(gef_wdt_init); | 323 | module_init(gef_wdt_init); |
324 | module_exit(gef_wdt_exit); | 324 | module_exit(gef_wdt_exit); |
325 | 325 | ||
326 | MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); | 326 | MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>"); |
327 | MODULE_DESCRIPTION("GE Fanuc watchdog driver"); | 327 | MODULE_DESCRIPTION("GE watchdog driver"); |
328 | MODULE_LICENSE("GPL"); | 328 | MODULE_LICENSE("GPL"); |
329 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 329 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
330 | MODULE_ALIAS("platform: gef_wdt"); | 330 | MODULE_ALIAS("platform: gef_wdt"); |
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 38252ff828ca..9b49b125ad5a 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c | |||
@@ -142,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd, | |||
142 | int __user *p = argp; | 142 | int __user *p = argp; |
143 | int interval; | 143 | int interval; |
144 | 144 | ||
145 | static struct watchdog_info ident = { | 145 | static const struct watchdog_info ident = { |
146 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 146 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
147 | | WDIOF_MAGICCLOSE, | 147 | | WDIOF_MAGICCLOSE, |
148 | .firmware_version = 1, | 148 | .firmware_version = 1, |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index a6c5674c78e6..70c2c24660d0 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -554,7 +554,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data, | |||
554 | return len; | 554 | return len; |
555 | } | 555 | } |
556 | 556 | ||
557 | static struct watchdog_info ident = { | 557 | static const struct watchdog_info ident = { |
558 | .options = WDIOF_SETTIMEOUT | | 558 | .options = WDIOF_SETTIMEOUT | |
559 | WDIOF_KEEPALIVEPING | | 559 | WDIOF_KEEPALIVEPING | |
560 | WDIOF_MAGICCLOSE, | 560 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 7ba0b11ec525..bb9750a03942 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/miscdevice.h> | 35 | #include <linux/miscdevice.h> |
36 | #include <linux/watchdog.h> | 36 | #include <linux/watchdog.h> |
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
40 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
@@ -42,7 +41,7 @@ | |||
42 | #include <linux/io.h> | 41 | #include <linux/io.h> |
43 | 42 | ||
44 | /* Module and version information */ | 43 | /* Module and version information */ |
45 | #define ESB_VERSION "0.04" | 44 | #define ESB_VERSION "0.05" |
46 | #define ESB_MODULE_NAME "i6300ESB timer" | 45 | #define ESB_MODULE_NAME "i6300ESB timer" |
47 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION | 46 | #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION |
48 | #define PFX ESB_MODULE_NAME ": " | 47 | #define PFX ESB_MODULE_NAME ": " |
@@ -65,7 +64,7 @@ | |||
65 | /* Config register bits */ | 64 | /* Config register bits */ |
66 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ | 65 | #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ |
67 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ | 66 | #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ |
68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ | 67 | #define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */ |
69 | 68 | ||
70 | /* Reload register bits */ | 69 | /* Reload register bits */ |
71 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ | 70 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ |
@@ -82,7 +81,9 @@ static unsigned long timer_alive; | |||
82 | static struct pci_dev *esb_pci; | 81 | static struct pci_dev *esb_pci; |
83 | static unsigned short triggered; /* The status of the watchdog upon boot */ | 82 | static unsigned short triggered; /* The status of the watchdog upon boot */ |
84 | static char esb_expect_close; | 83 | static char esb_expect_close; |
85 | static struct platform_device *esb_platform_device; | 84 | |
85 | /* We can only use 1 card due to the /dev/watchdog restriction */ | ||
86 | static int cards_found; | ||
86 | 87 | ||
87 | /* module parameters */ | 88 | /* module parameters */ |
88 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ | 89 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout, | |||
111 | */ | 112 | */ |
112 | static inline void esb_unlock_registers(void) | 113 | static inline void esb_unlock_registers(void) |
113 | { | 114 | { |
114 | writeb(ESB_UNLOCK1, ESB_RELOAD_REG); | 115 | writew(ESB_UNLOCK1, ESB_RELOAD_REG); |
115 | writeb(ESB_UNLOCK2, ESB_RELOAD_REG); | 116 | writew(ESB_UNLOCK2, ESB_RELOAD_REG); |
116 | } | 117 | } |
117 | 118 | ||
118 | static int esb_timer_start(void) | 119 | static int esb_timer_start(void) |
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
256 | int new_heartbeat; | 257 | int new_heartbeat; |
257 | void __user *argp = (void __user *)arg; | 258 | void __user *argp = (void __user *)arg; |
258 | int __user *p = argp; | 259 | int __user *p = argp; |
259 | static struct watchdog_info ident = { | 260 | static const struct watchdog_info ident = { |
260 | .options = WDIOF_SETTIMEOUT | | 261 | .options = WDIOF_SETTIMEOUT | |
261 | WDIOF_KEEPALIVEPING | | 262 | WDIOF_KEEPALIVEPING | |
262 | WDIOF_MAGICCLOSE, | 263 | WDIOF_MAGICCLOSE, |
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = { | |||
332 | 333 | ||
333 | /* | 334 | /* |
334 | * Data for PCI driver interface | 335 | * Data for PCI driver interface |
335 | * | ||
336 | * This data only exists for exporting the supported | ||
337 | * PCI ids via MODULE_DEVICE_TABLE. We do not actually | ||
338 | * register a pci_driver, because someone else might one day | ||
339 | * want to register another driver on the same PCI id. | ||
340 | */ | 336 | */ |
341 | static struct pci_device_id esb_pci_tbl[] = { | 337 | static struct pci_device_id esb_pci_tbl[] = { |
342 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, | 338 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, |
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); | |||
348 | * Init & exit routines | 344 | * Init & exit routines |
349 | */ | 345 | */ |
350 | 346 | ||
351 | static unsigned char __devinit esb_getdevice(void) | 347 | static unsigned char __devinit esb_getdevice(struct pci_dev *pdev) |
352 | { | 348 | { |
353 | /* | 349 | if (pci_enable_device(pdev)) { |
354 | * Find the PCI device | ||
355 | */ | ||
356 | |||
357 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
358 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); | ||
359 | |||
360 | if (!esb_pci) | ||
361 | return 0; | ||
362 | |||
363 | if (pci_enable_device(esb_pci)) { | ||
364 | printk(KERN_ERR PFX "failed to enable device\n"); | 350 | printk(KERN_ERR PFX "failed to enable device\n"); |
365 | goto err_devput; | 351 | goto err_devput; |
366 | } | 352 | } |
367 | 353 | ||
368 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 354 | if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) { |
369 | printk(KERN_ERR PFX "failed to request region\n"); | 355 | printk(KERN_ERR PFX "failed to request region\n"); |
370 | goto err_disable; | 356 | goto err_disable; |
371 | } | 357 | } |
372 | 358 | ||
373 | BASEADDR = pci_ioremap_bar(esb_pci, 0); | 359 | BASEADDR = pci_ioremap_bar(pdev, 0); |
374 | if (BASEADDR == NULL) { | 360 | if (BASEADDR == NULL) { |
375 | /* Something's wrong here, BASEADDR has to be set */ | 361 | /* Something's wrong here, BASEADDR has to be set */ |
376 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); | 362 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void) | |||
378 | } | 364 | } |
379 | 365 | ||
380 | /* Done */ | 366 | /* Done */ |
367 | esb_pci = pdev; | ||
381 | return 1; | 368 | return 1; |
382 | 369 | ||
383 | err_release: | 370 | err_release: |
384 | pci_release_region(esb_pci, 0); | 371 | pci_release_region(pdev, 0); |
385 | err_disable: | 372 | err_disable: |
386 | pci_disable_device(esb_pci); | 373 | pci_disable_device(pdev); |
387 | err_devput: | 374 | err_devput: |
388 | pci_dev_put(esb_pci); | ||
389 | return 0; | 375 | return 0; |
390 | } | 376 | } |
391 | 377 | ||
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void) | |||
430 | esb_timer_set_heartbeat(heartbeat); | 416 | esb_timer_set_heartbeat(heartbeat); |
431 | } | 417 | } |
432 | 418 | ||
433 | static int __devinit esb_probe(struct platform_device *dev) | 419 | static int __devinit esb_probe(struct pci_dev *pdev, |
420 | const struct pci_device_id *ent) | ||
434 | { | 421 | { |
435 | int ret; | 422 | int ret; |
436 | 423 | ||
424 | cards_found++; | ||
425 | if (cards_found == 1) | ||
426 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
427 | ESB_VERSION); | ||
428 | |||
429 | if (cards_found > 1) { | ||
430 | printk(KERN_ERR PFX "This driver only supports 1 device\n"); | ||
431 | return -ENODEV; | ||
432 | } | ||
433 | |||
437 | /* Check whether or not the hardware watchdog is there */ | 434 | /* Check whether or not the hardware watchdog is there */ |
438 | if (!esb_getdevice() || esb_pci == NULL) | 435 | if (!esb_getdevice(pdev) || esb_pci == NULL) |
439 | return -ENODEV; | 436 | return -ENODEV; |
440 | 437 | ||
441 | /* Check that the heartbeat value is within it's range; | 438 | /* Check that the heartbeat value is within it's range; |
@@ -467,11 +464,11 @@ err_unmap: | |||
467 | iounmap(BASEADDR); | 464 | iounmap(BASEADDR); |
468 | pci_release_region(esb_pci, 0); | 465 | pci_release_region(esb_pci, 0); |
469 | pci_disable_device(esb_pci); | 466 | pci_disable_device(esb_pci); |
470 | pci_dev_put(esb_pci); | 467 | esb_pci = NULL; |
471 | return ret; | 468 | return ret; |
472 | } | 469 | } |
473 | 470 | ||
474 | static int __devexit esb_remove(struct platform_device *dev) | 471 | static void __devexit esb_remove(struct pci_dev *pdev) |
475 | { | 472 | { |
476 | /* Stop the timer before we leave */ | 473 | /* Stop the timer before we leave */ |
477 | if (!nowayout) | 474 | if (!nowayout) |
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev) | |||
482 | iounmap(BASEADDR); | 479 | iounmap(BASEADDR); |
483 | pci_release_region(esb_pci, 0); | 480 | pci_release_region(esb_pci, 0); |
484 | pci_disable_device(esb_pci); | 481 | pci_disable_device(esb_pci); |
485 | pci_dev_put(esb_pci); | 482 | esb_pci = NULL; |
486 | return 0; | ||
487 | } | 483 | } |
488 | 484 | ||
489 | static void esb_shutdown(struct platform_device *dev) | 485 | static void esb_shutdown(struct pci_dev *pdev) |
490 | { | 486 | { |
491 | esb_timer_stop(); | 487 | esb_timer_stop(); |
492 | } | 488 | } |
493 | 489 | ||
494 | static struct platform_driver esb_platform_driver = { | 490 | static struct pci_driver esb_driver = { |
491 | .name = ESB_MODULE_NAME, | ||
492 | .id_table = esb_pci_tbl, | ||
495 | .probe = esb_probe, | 493 | .probe = esb_probe, |
496 | .remove = __devexit_p(esb_remove), | 494 | .remove = __devexit_p(esb_remove), |
497 | .shutdown = esb_shutdown, | 495 | .shutdown = esb_shutdown, |
498 | .driver = { | ||
499 | .owner = THIS_MODULE, | ||
500 | .name = ESB_MODULE_NAME, | ||
501 | }, | ||
502 | }; | 496 | }; |
503 | 497 | ||
504 | static int __init watchdog_init(void) | 498 | static int __init watchdog_init(void) |
505 | { | 499 | { |
506 | int err; | 500 | return pci_register_driver(&esb_driver); |
507 | |||
508 | printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", | ||
509 | ESB_VERSION); | ||
510 | |||
511 | err = platform_driver_register(&esb_platform_driver); | ||
512 | if (err) | ||
513 | return err; | ||
514 | |||
515 | esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME, | ||
516 | -1, NULL, 0); | ||
517 | if (IS_ERR(esb_platform_device)) { | ||
518 | err = PTR_ERR(esb_platform_device); | ||
519 | goto unreg_platform_driver; | ||
520 | } | ||
521 | |||
522 | return 0; | ||
523 | |||
524 | unreg_platform_driver: | ||
525 | platform_driver_unregister(&esb_platform_driver); | ||
526 | return err; | ||
527 | } | 501 | } |
528 | 502 | ||
529 | static void __exit watchdog_cleanup(void) | 503 | static void __exit watchdog_cleanup(void) |
530 | { | 504 | { |
531 | platform_device_unregister(esb_platform_device); | 505 | pci_unregister_driver(&esb_driver); |
532 | platform_driver_unregister(&esb_platform_driver); | ||
533 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); | 506 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); |
534 | } | 507 | } |
535 | 508 | ||
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 4bdb7f1a9077..44bc6aa46edf 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -584,7 +584,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd, | |||
584 | int new_heartbeat; | 584 | int new_heartbeat; |
585 | void __user *argp = (void __user *)arg; | 585 | void __user *argp = (void __user *)arg; |
586 | int __user *p = argp; | 586 | int __user *p = argp; |
587 | static struct watchdog_info ident = { | 587 | static const struct watchdog_info ident = { |
588 | .options = WDIOF_SETTIMEOUT | | 588 | .options = WDIOF_SETTIMEOUT | |
589 | WDIOF_KEEPALIVEPING | | 589 | WDIOF_KEEPALIVEPING | |
590 | WDIOF_MAGICCLOSE, | 590 | WDIOF_MAGICCLOSE, |
@@ -698,7 +698,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
698 | if (iTCO_wdt_private.iTCO_version == 2) { | 698 | if (iTCO_wdt_private.iTCO_version == 2) { |
699 | pci_read_config_dword(pdev, 0xf0, &base_address); | 699 | pci_read_config_dword(pdev, 0xf0, &base_address); |
700 | if ((base_address & 1) == 0) { | 700 | if ((base_address & 1) == 0) { |
701 | printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); | 701 | printk(KERN_ERR PFX "RCBA is disabled by hardware\n"); |
702 | ret = -ENODEV; | 702 | ret = -ENODEV; |
703 | goto out; | 703 | goto out; |
704 | } | 704 | } |
@@ -708,8 +708,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
708 | 708 | ||
709 | /* Check chipset's NO_REBOOT bit */ | 709 | /* Check chipset's NO_REBOOT bit */ |
710 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { | 710 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { |
711 | printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " | 711 | printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, " |
712 | "reboot disabled by hardware\n"); | 712 | "platform may have disabled it\n"); |
713 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 713 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
714 | goto out_unmap; | 714 | goto out_unmap; |
715 | } | 715 | } |
@@ -805,6 +805,7 @@ static void __devexit iTCO_wdt_cleanup(void) | |||
805 | 805 | ||
806 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) | 806 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) |
807 | { | 807 | { |
808 | int ret = -ENODEV; | ||
808 | int found = 0; | 809 | int found = 0; |
809 | struct pci_dev *pdev = NULL; | 810 | struct pci_dev *pdev = NULL; |
810 | const struct pci_device_id *ent; | 811 | const struct pci_device_id *ent; |
@@ -814,19 +815,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev) | |||
814 | for_each_pci_dev(pdev) { | 815 | for_each_pci_dev(pdev) { |
815 | ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); | 816 | ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); |
816 | if (ent) { | 817 | if (ent) { |
817 | if (!(iTCO_wdt_init(pdev, ent, dev))) { | 818 | found++; |
818 | found++; | 819 | ret = iTCO_wdt_init(pdev, ent, dev); |
820 | if (!ret) | ||
819 | break; | 821 | break; |
820 | } | ||
821 | } | 822 | } |
822 | } | 823 | } |
823 | 824 | ||
824 | if (!found) { | 825 | if (!found) |
825 | printk(KERN_INFO PFX "No card detected\n"); | 826 | printk(KERN_INFO PFX "No card detected\n"); |
826 | return -ENODEV; | ||
827 | } | ||
828 | 827 | ||
829 | return 0; | 828 | return ret; |
830 | } | 829 | } |
831 | 830 | ||
832 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) | 831 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 4bef3ddff4a5..0149d8dfc81d 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
174 | void __user *argp = (void __user *)arg; | 174 | void __user *argp = (void __user *)arg; |
175 | int __user *p = argp; | 175 | int __user *p = argp; |
176 | 176 | ||
177 | static struct watchdog_info ident = { | 177 | static const struct watchdog_info ident = { |
178 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 178 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
179 | | WDIOF_MAGICCLOSE, | 179 | | WDIOF_MAGICCLOSE, |
180 | .firmware_version = 1, | 180 | .firmware_version = 1, |
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index bea8a124a559..1cc5609666d1 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c | |||
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd, | |||
111 | unsigned long arg) | 111 | unsigned long arg) |
112 | { | 112 | { |
113 | int options, retval = -EINVAL; | 113 | int options, retval = -EINVAL; |
114 | static struct watchdog_info ident = { | 114 | static const struct watchdog_info ident = { |
115 | .options = WDIOF_KEEPALIVEPING, | 115 | .options = WDIOF_KEEPALIVEPING, |
116 | .firmware_version = 0, | 116 | .firmware_version = 0, |
117 | .identity = "Hardware Watchdog for SGI IP22", | 117 | .identity = "Hardware Watchdog for SGI IP22", |
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index daed48ded7fe..f52c162b1bea 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c | |||
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, | |||
236 | { | 236 | { |
237 | void __user *argp = (void __user *)arg; | 237 | void __user *argp = (void __user *)arg; |
238 | int __user *p = argp; | 238 | int __user *p = argp; |
239 | static struct watchdog_info ident = { | 239 | static const struct watchdog_info ident = { |
240 | .identity = "IT8712F Watchdog", | 240 | .identity = "IT8712F Watchdog", |
241 | .firmware_version = 1, | 241 | .firmware_version = 1, |
242 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | | 242 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index cc133c531d08..b709b3b2d1ef 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c | |||
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
421 | return count; | 421 | return count; |
422 | } | 422 | } |
423 | 423 | ||
424 | static struct watchdog_info ident = { | 424 | static const struct watchdog_info ident = { |
425 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 425 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
426 | .firmware_version = 1, | 426 | .firmware_version = 1, |
427 | .identity = WATCHDOG_NAME, | 427 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c index 3c79dc587958..e86952a7168c 100644 --- a/drivers/watchdog/ixp2000_wdt.c +++ b/drivers/watchdog/ixp2000_wdt.c | |||
@@ -100,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data, | |||
100 | } | 100 | } |
101 | 101 | ||
102 | 102 | ||
103 | static struct watchdog_info ident = { | 103 | static const struct watchdog_info ident = { |
104 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 104 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
105 | WDIOF_KEEPALIVEPING, | 105 | WDIOF_KEEPALIVEPING, |
106 | .identity = "IXP2000 Watchdog", | 106 | .identity = "IXP2000 Watchdog", |
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c index 147b4d5c63b3..e02c0ecda26b 100644 --- a/drivers/watchdog/ixp4xx_wdt.c +++ b/drivers/watchdog/ixp4xx_wdt.c | |||
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | |||
89 | return len; | 89 | return len; |
90 | } | 90 | } |
91 | 91 | ||
92 | static struct watchdog_info ident = { | 92 | static const struct watchdog_info ident = { |
93 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | 93 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | |
94 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 94 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
95 | .identity = "IXP4xx Watchdog", | 95 | .identity = "IXP4xx Watchdog", |
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index e1c82769b08e..2852bb2e3fd9 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode *inode, struct file *file) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static struct watchdog_info ks8695_wdt_info = { | 148 | static const struct watchdog_info ks8695_wdt_info = { |
149 | .identity = "ks8695 watchdog", | 149 | .identity = "ks8695 watchdog", |
150 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 150 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
151 | }; | 151 | }; |
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index 47d719717a3b..2d118cf022fc 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c | |||
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout, | |||
101 | 101 | ||
102 | #define PFX "machzwd" | 102 | #define PFX "machzwd" |
103 | 103 | ||
104 | static struct watchdog_info zf_info = { | 104 | static const struct watchdog_info zf_info = { |
105 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 105 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
106 | .firmware_version = 1, | 106 | .firmware_version = 1, |
107 | .identity = "ZF-Logic watchdog", | 107 | .identity = "ZF-Logic watchdog", |
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c new file mode 100644 index 000000000000..6eb91d757604 --- /dev/null +++ b/drivers/watchdog/max63xx_wdt.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * drivers/char/watchdog/max63xx_wdt.c | ||
3 | * | ||
4 | * Driver for max63{69,70,71,72,73,74} watchdog timers | ||
5 | * | ||
6 | * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | * | ||
12 | * This driver assumes the watchdog pins are memory mapped (as it is | ||
13 | * the case for the Arcom Zeus). Should it be connected over GPIOs or | ||
14 | * another interface, some abstraction will have to be introduced. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/moduleparam.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/fs.h> | ||
22 | #include <linux/miscdevice.h> | ||
23 | #include <linux/watchdog.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/bitops.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/spinlock.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/device.h> | ||
31 | |||
32 | #define DEFAULT_HEARTBEAT 60 | ||
33 | #define MAX_HEARTBEAT 60 | ||
34 | |||
35 | static int heartbeat = DEFAULT_HEARTBEAT; | ||
36 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
37 | |||
38 | /* | ||
39 | * Memory mapping: a single byte, 3 first lower bits to select bit 3 | ||
40 | * to ping the watchdog. | ||
41 | */ | ||
42 | #define MAX6369_WDSET (7 << 0) | ||
43 | #define MAX6369_WDI (1 << 3) | ||
44 | |||
45 | static DEFINE_SPINLOCK(io_lock); | ||
46 | |||
47 | static unsigned long wdt_status; | ||
48 | #define WDT_IN_USE 0 | ||
49 | #define WDT_RUNNING 1 | ||
50 | #define WDT_OK_TO_CLOSE 2 | ||
51 | |||
52 | static int nodelay; | ||
53 | static struct resource *wdt_mem; | ||
54 | static void __iomem *wdt_base; | ||
55 | static struct platform_device *max63xx_pdev; | ||
56 | |||
57 | /* | ||
58 | * The timeout values used are actually the absolute minimum the chip | ||
59 | * offers. Typical values on my board are slightly over twice as long | ||
60 | * (10s setting ends up with a 25s timeout), and can be up to 3 times | ||
61 | * the nominal setting (according to the datasheet). So please take | ||
62 | * these values with a grain of salt. Same goes for the initial delay | ||
63 | * "feature". Only max6373/74 have a few settings without this initial | ||
64 | * delay (selected with the "nodelay" parameter). | ||
65 | * | ||
66 | * I also decided to remove from the tables any timeout smaller than a | ||
67 | * second, as it looked completly overkill... | ||
68 | */ | ||
69 | |||
70 | /* Timeouts in second */ | ||
71 | struct max63xx_timeout { | ||
72 | u8 wdset; | ||
73 | u8 tdelay; | ||
74 | u8 twd; | ||
75 | }; | ||
76 | |||
77 | static struct max63xx_timeout max6369_table[] = { | ||
78 | { 5, 1, 1 }, | ||
79 | { 6, 10, 10 }, | ||
80 | { 7, 60, 60 }, | ||
81 | { }, | ||
82 | }; | ||
83 | |||
84 | static struct max63xx_timeout max6371_table[] = { | ||
85 | { 6, 60, 3 }, | ||
86 | { 7, 60, 60 }, | ||
87 | { }, | ||
88 | }; | ||
89 | |||
90 | static struct max63xx_timeout max6373_table[] = { | ||
91 | { 2, 60, 1 }, | ||
92 | { 5, 0, 1 }, | ||
93 | { 1, 3, 3 }, | ||
94 | { 7, 60, 10 }, | ||
95 | { 6, 0, 10 }, | ||
96 | { }, | ||
97 | }; | ||
98 | |||
99 | static struct max63xx_timeout *current_timeout; | ||
100 | |||
101 | static struct max63xx_timeout * | ||
102 | max63xx_select_timeout(struct max63xx_timeout *table, int value) | ||
103 | { | ||
104 | while (table->twd) { | ||
105 | if (value <= table->twd) { | ||
106 | if (nodelay && table->tdelay == 0) | ||
107 | return table; | ||
108 | |||
109 | if (!nodelay) | ||
110 | return table; | ||
111 | } | ||
112 | |||
113 | table++; | ||
114 | } | ||
115 | |||
116 | return NULL; | ||
117 | } | ||
118 | |||
119 | static void max63xx_wdt_ping(void) | ||
120 | { | ||
121 | u8 val; | ||
122 | |||
123 | spin_lock(&io_lock); | ||
124 | |||
125 | val = __raw_readb(wdt_base); | ||
126 | |||
127 | __raw_writeb(val | MAX6369_WDI, wdt_base); | ||
128 | __raw_writeb(val & ~MAX6369_WDI, wdt_base); | ||
129 | |||
130 | spin_unlock(&io_lock); | ||
131 | } | ||
132 | |||
133 | static void max63xx_wdt_enable(struct max63xx_timeout *entry) | ||
134 | { | ||
135 | u8 val; | ||
136 | |||
137 | if (test_and_set_bit(WDT_RUNNING, &wdt_status)) | ||
138 | return; | ||
139 | |||
140 | spin_lock(&io_lock); | ||
141 | |||
142 | val = __raw_readb(wdt_base); | ||
143 | val &= ~MAX6369_WDSET; | ||
144 | val |= entry->wdset; | ||
145 | __raw_writeb(val, wdt_base); | ||
146 | |||
147 | spin_unlock(&io_lock); | ||
148 | |||
149 | /* check for a edge triggered startup */ | ||
150 | if (entry->tdelay == 0) | ||
151 | max63xx_wdt_ping(); | ||
152 | } | ||
153 | |||
154 | static void max63xx_wdt_disable(void) | ||
155 | { | ||
156 | spin_lock(&io_lock); | ||
157 | |||
158 | __raw_writeb(3, wdt_base); | ||
159 | |||
160 | spin_unlock(&io_lock); | ||
161 | |||
162 | clear_bit(WDT_RUNNING, &wdt_status); | ||
163 | } | ||
164 | |||
165 | static int max63xx_wdt_open(struct inode *inode, struct file *file) | ||
166 | { | ||
167 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | ||
168 | return -EBUSY; | ||
169 | |||
170 | max63xx_wdt_enable(current_timeout); | ||
171 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
172 | |||
173 | return nonseekable_open(inode, file); | ||
174 | } | ||
175 | |||
176 | static ssize_t max63xx_wdt_write(struct file *file, const char *data, | ||
177 | size_t len, loff_t *ppos) | ||
178 | { | ||
179 | if (len) { | ||
180 | if (!nowayout) { | ||
181 | size_t i; | ||
182 | |||
183 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
184 | for (i = 0; i != len; i++) { | ||
185 | char c; | ||
186 | |||
187 | if (get_user(c, data + i)) | ||
188 | return -EFAULT; | ||
189 | |||
190 | if (c == 'V') | ||
191 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | max63xx_wdt_ping(); | ||
196 | } | ||
197 | |||
198 | return len; | ||
199 | } | ||
200 | |||
201 | static const struct watchdog_info ident = { | ||
202 | .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | ||
203 | .identity = "max63xx Watchdog", | ||
204 | }; | ||
205 | |||
206 | static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd, | ||
207 | unsigned long arg) | ||
208 | { | ||
209 | int ret = -ENOTTY; | ||
210 | |||
211 | switch (cmd) { | ||
212 | case WDIOC_GETSUPPORT: | ||
213 | ret = copy_to_user((struct watchdog_info *)arg, &ident, | ||
214 | sizeof(ident)) ? -EFAULT : 0; | ||
215 | break; | ||
216 | |||
217 | case WDIOC_GETSTATUS: | ||
218 | case WDIOC_GETBOOTSTATUS: | ||
219 | ret = put_user(0, (int *)arg); | ||
220 | break; | ||
221 | |||
222 | case WDIOC_KEEPALIVE: | ||
223 | max63xx_wdt_ping(); | ||
224 | ret = 0; | ||
225 | break; | ||
226 | |||
227 | case WDIOC_GETTIMEOUT: | ||
228 | ret = put_user(heartbeat, (int *)arg); | ||
229 | break; | ||
230 | } | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | static int max63xx_wdt_release(struct inode *inode, struct file *file) | ||
235 | { | ||
236 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | ||
237 | max63xx_wdt_disable(); | ||
238 | else | ||
239 | dev_crit(&max63xx_pdev->dev, | ||
240 | "device closed unexpectedly - timer will not stop\n"); | ||
241 | |||
242 | clear_bit(WDT_IN_USE, &wdt_status); | ||
243 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static const struct file_operations max63xx_wdt_fops = { | ||
249 | .owner = THIS_MODULE, | ||
250 | .llseek = no_llseek, | ||
251 | .write = max63xx_wdt_write, | ||
252 | .unlocked_ioctl = max63xx_wdt_ioctl, | ||
253 | .open = max63xx_wdt_open, | ||
254 | .release = max63xx_wdt_release, | ||
255 | }; | ||
256 | |||
257 | static struct miscdevice max63xx_wdt_miscdev = { | ||
258 | .minor = WATCHDOG_MINOR, | ||
259 | .name = "watchdog", | ||
260 | .fops = &max63xx_wdt_fops, | ||
261 | }; | ||
262 | |||
263 | static int __devinit max63xx_wdt_probe(struct platform_device *pdev) | ||
264 | { | ||
265 | int ret = 0; | ||
266 | int size; | ||
267 | struct resource *res; | ||
268 | struct device *dev = &pdev->dev; | ||
269 | struct max63xx_timeout *table; | ||
270 | |||
271 | table = (struct max63xx_timeout *)pdev->id_entry->driver_data; | ||
272 | |||
273 | if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) | ||
274 | heartbeat = DEFAULT_HEARTBEAT; | ||
275 | |||
276 | dev_info(dev, "requesting %ds heartbeat\n", heartbeat); | ||
277 | current_timeout = max63xx_select_timeout(table, heartbeat); | ||
278 | |||
279 | if (!current_timeout) { | ||
280 | dev_err(dev, "unable to satisfy heartbeat request\n"); | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | |||
284 | dev_info(dev, "using %ds heartbeat with %ds initial delay\n", | ||
285 | current_timeout->twd, current_timeout->tdelay); | ||
286 | |||
287 | heartbeat = current_timeout->twd; | ||
288 | |||
289 | max63xx_pdev = pdev; | ||
290 | |||
291 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
292 | if (res == NULL) { | ||
293 | dev_err(dev, "failed to get memory region resource\n"); | ||
294 | return -ENOENT; | ||
295 | } | ||
296 | |||
297 | size = resource_size(res); | ||
298 | wdt_mem = request_mem_region(res->start, size, pdev->name); | ||
299 | |||
300 | if (wdt_mem == NULL) { | ||
301 | dev_err(dev, "failed to get memory region\n"); | ||
302 | return -ENOENT; | ||
303 | } | ||
304 | |||
305 | wdt_base = ioremap(res->start, size); | ||
306 | if (!wdt_base) { | ||
307 | dev_err(dev, "failed to map memory region\n"); | ||
308 | ret = -ENOMEM; | ||
309 | goto out_request; | ||
310 | } | ||
311 | |||
312 | ret = misc_register(&max63xx_wdt_miscdev); | ||
313 | if (ret < 0) { | ||
314 | dev_err(dev, "cannot register misc device\n"); | ||
315 | goto out_unmap; | ||
316 | } | ||
317 | |||
318 | return 0; | ||
319 | |||
320 | out_unmap: | ||
321 | iounmap(wdt_base); | ||
322 | out_request: | ||
323 | release_resource(wdt_mem); | ||
324 | kfree(wdt_mem); | ||
325 | |||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static int __devexit max63xx_wdt_remove(struct platform_device *pdev) | ||
330 | { | ||
331 | misc_deregister(&max63xx_wdt_miscdev); | ||
332 | if (wdt_mem) { | ||
333 | release_resource(wdt_mem); | ||
334 | kfree(wdt_mem); | ||
335 | wdt_mem = NULL; | ||
336 | } | ||
337 | |||
338 | if (wdt_base) | ||
339 | iounmap(wdt_base); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static struct platform_device_id max63xx_id_table[] = { | ||
345 | { "max6369_wdt", (kernel_ulong_t)max6369_table, }, | ||
346 | { "max6370_wdt", (kernel_ulong_t)max6369_table, }, | ||
347 | { "max6371_wdt", (kernel_ulong_t)max6371_table, }, | ||
348 | { "max6372_wdt", (kernel_ulong_t)max6371_table, }, | ||
349 | { "max6373_wdt", (kernel_ulong_t)max6373_table, }, | ||
350 | { "max6374_wdt", (kernel_ulong_t)max6373_table, }, | ||
351 | { }, | ||
352 | }; | ||
353 | MODULE_DEVICE_TABLE(platform, max63xx_id_table); | ||
354 | |||
355 | static struct platform_driver max63xx_wdt_driver = { | ||
356 | .probe = max63xx_wdt_probe, | ||
357 | .remove = __devexit_p(max63xx_wdt_remove), | ||
358 | .id_table = max63xx_id_table, | ||
359 | .driver = { | ||
360 | .name = "max63xx_wdt", | ||
361 | .owner = THIS_MODULE, | ||
362 | }, | ||
363 | }; | ||
364 | |||
365 | static int __init max63xx_wdt_init(void) | ||
366 | { | ||
367 | return platform_driver_register(&max63xx_wdt_driver); | ||
368 | } | ||
369 | |||
370 | static void __exit max63xx_wdt_exit(void) | ||
371 | { | ||
372 | platform_driver_unregister(&max63xx_wdt_driver); | ||
373 | } | ||
374 | |||
375 | module_init(max63xx_wdt_init); | ||
376 | module_exit(max63xx_wdt_exit); | ||
377 | |||
378 | MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>"); | ||
379 | MODULE_DESCRIPTION("max63xx Watchdog Driver"); | ||
380 | |||
381 | module_param(heartbeat, int, 0); | ||
382 | MODULE_PARM_DESC(heartbeat, | ||
383 | "Watchdog heartbeat period in seconds from 1 to " | ||
384 | __MODULE_STRING(MAX_HEARTBEAT) ", default " | ||
385 | __MODULE_STRING(DEFAULT_HEARTBEAT)); | ||
386 | |||
387 | module_param(nowayout, int, 0); | ||
388 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
389 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
390 | |||
391 | module_param(nodelay, int, 0); | ||
392 | MODULE_PARM_DESC(nodelay, | ||
393 | "Force selection of a timeout setting without initial delay " | ||
394 | "(max6373/74 only, default=0)"); | ||
395 | |||
396 | MODULE_LICENSE("GPL"); | ||
397 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 407b025cb104..bc820d16699a 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c | |||
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *file, | |||
201 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
202 | int __user *p = argp; | 202 | int __user *p = argp; |
203 | int status; | 203 | int status; |
204 | static struct watchdog_info ident = { | 204 | static const struct watchdog_info ident = { |
205 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 205 | .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
206 | .firmware_version = 1, | 206 | .firmware_version = 1, |
207 | .identity = "MixCOM watchdog", | 207 | .identity = "MixCOM watchdog", |
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 38c588ee694f..4e3941c5e293 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c | |||
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd, | |||
148 | { | 148 | { |
149 | void __user *argp = (void __user *)arg; | 149 | void __user *argp = (void __user *)arg; |
150 | int __user *p = argp; | 150 | int __user *p = argp; |
151 | static struct watchdog_info ident = { | 151 | static const struct watchdog_info ident = { |
152 | .options = WDIOF_KEEPALIVEPING, | 152 | .options = WDIOF_KEEPALIVEPING, |
153 | .firmware_version = 1, | 153 | .firmware_version = 1, |
154 | .identity = "MPC8xxx", | 154 | .identity = "MPC8xxx", |
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c index a2dc07c2ed49..b0646dac924e 100644 --- a/drivers/watchdog/mpcore_wdt.c +++ b/drivers/watchdog/mpcore_wdt.c | |||
@@ -213,7 +213,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data, | |||
213 | return len; | 213 | return len; |
214 | } | 214 | } |
215 | 215 | ||
216 | static struct watchdog_info ident = { | 216 | static const struct watchdog_info ident = { |
217 | .options = WDIOF_SETTIMEOUT | | 217 | .options = WDIOF_SETTIMEOUT | |
218 | WDIOF_KEEPALIVEPING | | 218 | WDIOF_KEEPALIVEPING | |
219 | WDIOF_MAGICCLOSE, | 219 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c index a51dbe4c43da..97f8a48d8b78 100644 --- a/drivers/watchdog/mv64x60_wdt.c +++ b/drivers/watchdog/mv64x60_wdt.c | |||
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct file *file, | |||
179 | int timeout; | 179 | int timeout; |
180 | int options; | 180 | int options; |
181 | void __user *argp = (void __user *)arg; | 181 | void __user *argp = (void __user *)arg; |
182 | static struct watchdog_info info = { | 182 | static const struct watchdog_info info = { |
183 | .options = WDIOF_SETTIMEOUT | | 183 | .options = WDIOF_SETTIMEOUT | |
184 | WDIOF_MAGICCLOSE | | 184 | WDIOF_MAGICCLOSE | |
185 | WDIOF_KEEPALIVEPING, | 185 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index 1a2b916e3f8d..d3aa2f1fe61d 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c | |||
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd, | |||
407 | int __user *i; | 407 | int __user *i; |
408 | } uarg; | 408 | } uarg; |
409 | 409 | ||
410 | static struct watchdog_info ident = { | 410 | static const struct watchdog_info ident = { |
411 | .options = WDIOF_KEEPALIVEPING | | 411 | .options = WDIOF_KEEPALIVEPING | |
412 | WDIOF_SETTIMEOUT | | 412 | WDIOF_SETTIMEOUT | |
413 | WDIOF_MAGICCLOSE, | 413 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index aa9512321f3a..06f7922606c0 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c | |||
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
606 | int temperature; | 606 | int temperature; |
607 | int new_heartbeat; | 607 | int new_heartbeat; |
608 | int __user *argp = (int __user *)arg; | 608 | int __user *argp = (int __user *)arg; |
609 | static struct watchdog_info ident = { | 609 | static const struct watchdog_info ident = { |
610 | .options = WDIOF_OVERHEAT | | 610 | .options = WDIOF_OVERHEAT | |
611 | WDIOF_CARDRESET | | 611 | WDIOF_CARDRESET | |
612 | WDIOF_KEEPALIVEPING | | 612 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index 698f51bff1bc..64374d636f09 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c | |||
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd, | |||
481 | { | 481 | { |
482 | void __user *argp = (void __user *)arg; | 482 | void __user *argp = (void __user *)arg; |
483 | int __user *p = argp; | 483 | int __user *p = argp; |
484 | static struct watchdog_info ident = { | 484 | static const struct watchdog_info ident = { |
485 | .options = WDIOF_OVERHEAT | | 485 | .options = WDIOF_OVERHEAT | |
486 | WDIOF_CARDRESET | | 486 | WDIOF_CARDRESET | |
487 | WDIOF_KEEPALIVEPING | | 487 | WDIOF_KEEPALIVEPING | |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 052fe451851f..8e4eacc5bb52 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c | |||
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd, | |||
404 | { | 404 | { |
405 | void __user *argp = (void __user *)arg; | 405 | void __user *argp = (void __user *)arg; |
406 | int __user *p = argp; | 406 | int __user *p = argp; |
407 | static struct watchdog_info ident = { | 407 | static const struct watchdog_info ident = { |
408 | .options = WDIOF_KEEPALIVEPING | | 408 | .options = WDIOF_KEEPALIVEPING | |
409 | WDIOF_SETTIMEOUT | | 409 | WDIOF_SETTIMEOUT | |
410 | WDIOF_MAGICCLOSE, | 410 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c index 2d22e996e996..435ec2aed4fe 100644 --- a/drivers/watchdog/pika_wdt.c +++ b/drivers/watchdog/pika_wdt.c | |||
@@ -52,7 +52,7 @@ static struct { | |||
52 | struct timer_list timer; /* The timer that pings the watchdog */ | 52 | struct timer_list timer; /* The timer that pings the watchdog */ |
53 | } pikawdt_private; | 53 | } pikawdt_private; |
54 | 54 | ||
55 | static struct watchdog_info ident = { | 55 | static const struct watchdog_info ident = { |
56 | .identity = DRV_NAME, | 56 | .identity = DRV_NAME, |
57 | .options = WDIOF_CARDRESET | | 57 | .options = WDIOF_CARDRESET | |
58 | WDIOF_SETTIMEOUT | | 58 | WDIOF_SETTIMEOUT | |
diff --git a/drivers/watchdog/pnx833x_wdt.c b/drivers/watchdog/pnx833x_wdt.c index 538ec2c05197..09102f09e681 100644 --- a/drivers/watchdog/pnx833x_wdt.c +++ b/drivers/watchdog/pnx833x_wdt.c | |||
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
141 | int options, new_timeout = 0; | 141 | int options, new_timeout = 0; |
142 | uint32_t timeout, timeout_left = 0; | 142 | uint32_t timeout, timeout_left = 0; |
143 | 143 | ||
144 | static struct watchdog_info ident = { | 144 | static const struct watchdog_info ident = { |
145 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, | 145 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, |
146 | .firmware_version = 0, | 146 | .firmware_version = 0, |
147 | .identity = "Hardware Watchdog for PNX833x", | 147 | .identity = "Hardware Watchdog for PNX833x", |
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index bf12d06b5877..d4c29b5311a4 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c | |||
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, | |||
198 | void __user *argp = (void __user *)arg; | 198 | void __user *argp = (void __user *)arg; |
199 | int new_timeout; | 199 | int new_timeout; |
200 | unsigned int value; | 200 | unsigned int value; |
201 | static struct watchdog_info ident = { | 201 | static const struct watchdog_info ident = { |
202 | .options = WDIOF_SETTIMEOUT | | 202 | .options = WDIOF_SETTIMEOUT | |
203 | WDIOF_KEEPALIVEPING | | 203 | WDIOF_KEEPALIVEPING | |
204 | WDIOF_MAGICCLOSE, | 204 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 4976bfd1fce6..69c6adbd8205 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c | |||
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
149 | { | 149 | { |
150 | void __user *argp = (void __user *)arg; | 150 | void __user *argp = (void __user *)arg; |
151 | unsigned int value; | 151 | unsigned int value; |
152 | static struct watchdog_info ident = { | 152 | static const struct watchdog_info ident = { |
153 | .options = WDIOF_CARDRESET, | 153 | .options = WDIOF_CARDRESET, |
154 | .identity = "RDC321x WDT", | 154 | .identity = "RDC321x WDT", |
155 | }; | 155 | }; |
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index c14ae8676903..ae57bf9e1b03 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c | |||
@@ -85,7 +85,7 @@ static int riowd_release(struct inode *inode, struct file *filp) | |||
85 | 85 | ||
86 | static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 86 | static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
87 | { | 87 | { |
88 | static struct watchdog_info info = { | 88 | static const struct watchdog_info info = { |
89 | .options = WDIOF_SETTIMEOUT, | 89 | .options = WDIOF_SETTIMEOUT, |
90 | .firmware_version = 1, | 90 | .firmware_version = 1, |
91 | .identity = DRIVER_NAME, | 91 | .identity = DRIVER_NAME, |
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c index e6763d2a567b..8d44c9b6fb5b 100644 --- a/drivers/watchdog/sbc_fitpc2_wdt.c +++ b/drivers/watchdog/sbc_fitpc2_wdt.c | |||
@@ -111,7 +111,7 @@ out: | |||
111 | } | 111 | } |
112 | 112 | ||
113 | 113 | ||
114 | static struct watchdog_info ident = { | 114 | static const struct watchdog_info ident = { |
115 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 115 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
116 | WDIOF_KEEPALIVEPING, | 116 | WDIOF_KEEPALIVEPING, |
117 | .identity = WATCHDOG_NAME, | 117 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 569eb295a7a8..9c40f48804f5 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c | |||
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
250 | int new_timeout; | 250 | int new_timeout; |
251 | void __user *argp = (void __user *)arg; | 251 | void __user *argp = (void __user *)arg; |
252 | int __user *p = argp; | 252 | int __user *p = argp; |
253 | static struct watchdog_info ident = { | 253 | static const struct watchdog_info ident = { |
254 | .options = WDIOF_KEEPALIVEPING | | 254 | .options = WDIOF_KEEPALIVEPING | |
255 | WDIOF_SETTIMEOUT | | 255 | WDIOF_SETTIMEOUT | |
256 | WDIOF_MAGICCLOSE, | 256 | WDIOF_MAGICCLOSE, |
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c index 5dd952681f32..b3421fd2cda8 100644 --- a/drivers/watchdog/stmp3xxx_wdt.c +++ b/drivers/watchdog/stmp3xxx_wdt.c | |||
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct file *file, const char __user *data, | |||
94 | return len; | 94 | return len; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct watchdog_info ident = { | 97 | static const struct watchdog_info ident = { |
98 | .options = WDIOF_CARDRESET | | 98 | .options = WDIOF_CARDRESET | |
99 | WDIOF_MAGICCLOSE | | 99 | WDIOF_MAGICCLOSE | |
100 | WDIOF_SETTIMEOUT | | 100 | WDIOF_SETTIMEOUT | |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c new file mode 100644 index 000000000000..565a2c3321e5 --- /dev/null +++ b/drivers/watchdog/ts72xx_wdt.c | |||
@@ -0,0 +1,520 @@ | |||
1 | /* | ||
2 | * Watchdog driver for Technologic Systems TS-72xx based SBCs | ||
3 | * (TS-7200, TS-7250 and TS-7260). These boards have external | ||
4 | * glue logic CPLD chip, which includes programmable watchdog | ||
5 | * timer. | ||
6 | * | ||
7 | * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi> | ||
8 | * | ||
9 | * This driver is based on ep93xx_wdt and wm831x_wdt drivers. | ||
10 | * | ||
11 | * This file is licensed under the terms of the GNU General Public | ||
12 | * License version 2. This program is licensed "as is" without any | ||
13 | * warranty of any kind, whether express or implied. | ||
14 | */ | ||
15 | |||
16 | #include <linux/fs.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/miscdevice.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/watchdog.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | |||
26 | #define TS72XX_WDT_FEED_VAL 0x05 | ||
27 | #define TS72XX_WDT_DEFAULT_TIMEOUT 8 | ||
28 | |||
29 | static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT; | ||
30 | module_param(timeout, int, 0); | ||
31 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. " | ||
32 | "(1 <= timeout <= 8, default=" | ||
33 | __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT) | ||
34 | ")"); | ||
35 | |||
36 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
37 | module_param(nowayout, int, 0); | ||
38 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | ||
39 | |||
40 | /** | ||
41 | * struct ts72xx_wdt - watchdog control structure | ||
42 | * @lock: lock that protects this structure | ||
43 | * @regval: watchdog timeout value suitable for control register | ||
44 | * @flags: flags controlling watchdog device state | ||
45 | * @control_reg: watchdog control register | ||
46 | * @feed_reg: watchdog feed register | ||
47 | * @pdev: back pointer to platform dev | ||
48 | */ | ||
49 | struct ts72xx_wdt { | ||
50 | struct mutex lock; | ||
51 | int regval; | ||
52 | |||
53 | #define TS72XX_WDT_BUSY_FLAG 1 | ||
54 | #define TS72XX_WDT_EXPECT_CLOSE_FLAG 2 | ||
55 | int flags; | ||
56 | |||
57 | void __iomem *control_reg; | ||
58 | void __iomem *feed_reg; | ||
59 | |||
60 | struct platform_device *pdev; | ||
61 | }; | ||
62 | |||
63 | struct platform_device *ts72xx_wdt_pdev; | ||
64 | |||
65 | /* | ||
66 | * TS-72xx Watchdog supports following timeouts (value written | ||
67 | * to control register): | ||
68 | * value description | ||
69 | * ------------------------- | ||
70 | * 0x00 watchdog disabled | ||
71 | * 0x01 250ms | ||
72 | * 0x02 500ms | ||
73 | * 0x03 1s | ||
74 | * 0x04 reserved | ||
75 | * 0x05 2s | ||
76 | * 0x06 4s | ||
77 | * 0x07 8s | ||
78 | * | ||
79 | * Timeouts below 1s are not very usable so we don't | ||
80 | * allow them at all. | ||
81 | * | ||
82 | * We provide two functions that convert between these: | ||
83 | * timeout_to_regval() and regval_to_timeout(). | ||
84 | */ | ||
85 | static const struct { | ||
86 | int timeout; | ||
87 | int regval; | ||
88 | } ts72xx_wdt_map[] = { | ||
89 | { 1, 3 }, | ||
90 | { 2, 5 }, | ||
91 | { 4, 6 }, | ||
92 | { 8, 7 }, | ||
93 | }; | ||
94 | |||
95 | /** | ||
96 | * timeout_to_regval() - converts given timeout to control register value | ||
97 | * @new_timeout: timeout in seconds to be converted | ||
98 | * | ||
99 | * Function converts given @new_timeout into valid value that can | ||
100 | * be programmed into watchdog control register. When conversion is | ||
101 | * not possible, function returns %-EINVAL. | ||
102 | */ | ||
103 | static int timeout_to_regval(int new_timeout) | ||
104 | { | ||
105 | int i; | ||
106 | |||
107 | /* first limit it to 1 - 8 seconds */ | ||
108 | new_timeout = clamp_val(new_timeout, 1, 8); | ||
109 | |||
110 | for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) { | ||
111 | if (ts72xx_wdt_map[i].timeout >= new_timeout) | ||
112 | return ts72xx_wdt_map[i].regval; | ||
113 | } | ||
114 | |||
115 | return -EINVAL; | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * regval_to_timeout() - converts control register value to timeout | ||
120 | * @regval: control register value to be converted | ||
121 | * | ||
122 | * Function converts given @regval to timeout in seconds (1, 2, 4 or 8). | ||
123 | * If @regval cannot be converted, function returns %-EINVAL. | ||
124 | */ | ||
125 | static int regval_to_timeout(int regval) | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) { | ||
130 | if (ts72xx_wdt_map[i].regval == regval) | ||
131 | return ts72xx_wdt_map[i].timeout; | ||
132 | } | ||
133 | |||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * ts72xx_wdt_kick() - kick the watchdog | ||
139 | * @wdt: watchdog to be kicked | ||
140 | * | ||
141 | * Called with @wdt->lock held. | ||
142 | */ | ||
143 | static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt) | ||
144 | { | ||
145 | __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg); | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * ts72xx_wdt_start() - starts the watchdog timer | ||
150 | * @wdt: watchdog to be started | ||
151 | * | ||
152 | * This function programs timeout to watchdog timer | ||
153 | * and starts it. | ||
154 | * | ||
155 | * Called with @wdt->lock held. | ||
156 | */ | ||
157 | static void ts72xx_wdt_start(struct ts72xx_wdt *wdt) | ||
158 | { | ||
159 | /* | ||
160 | * To program the wdt, it first must be "fed" and | ||
161 | * only after that (within 30 usecs) the configuration | ||
162 | * can be changed. | ||
163 | */ | ||
164 | ts72xx_wdt_kick(wdt); | ||
165 | __raw_writeb((u8)wdt->regval, wdt->control_reg); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * ts72xx_wdt_stop() - stops the watchdog timer | ||
170 | * @wdt: watchdog to be stopped | ||
171 | * | ||
172 | * Called with @wdt->lock held. | ||
173 | */ | ||
174 | static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt) | ||
175 | { | ||
176 | ts72xx_wdt_kick(wdt); | ||
177 | __raw_writeb(0, wdt->control_reg); | ||
178 | } | ||
179 | |||
180 | static int ts72xx_wdt_open(struct inode *inode, struct file *file) | ||
181 | { | ||
182 | struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev); | ||
183 | int regval; | ||
184 | |||
185 | /* | ||
186 | * Try to convert default timeout to valid register | ||
187 | * value first. | ||
188 | */ | ||
189 | regval = timeout_to_regval(timeout); | ||
190 | if (regval < 0) { | ||
191 | dev_err(&wdt->pdev->dev, | ||
192 | "failed to convert timeout (%d) to register value\n", | ||
193 | timeout); | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | |||
197 | if (mutex_lock_interruptible(&wdt->lock)) | ||
198 | return -ERESTARTSYS; | ||
199 | |||
200 | if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) { | ||
201 | mutex_unlock(&wdt->lock); | ||
202 | return -EBUSY; | ||
203 | } | ||
204 | |||
205 | wdt->flags = TS72XX_WDT_BUSY_FLAG; | ||
206 | wdt->regval = regval; | ||
207 | file->private_data = wdt; | ||
208 | |||
209 | ts72xx_wdt_start(wdt); | ||
210 | |||
211 | mutex_unlock(&wdt->lock); | ||
212 | return nonseekable_open(inode, file); | ||
213 | } | ||
214 | |||
215 | static int ts72xx_wdt_release(struct inode *inode, struct file *file) | ||
216 | { | ||
217 | struct ts72xx_wdt *wdt = file->private_data; | ||
218 | |||
219 | if (mutex_lock_interruptible(&wdt->lock)) | ||
220 | return -ERESTARTSYS; | ||
221 | |||
222 | if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) { | ||
223 | ts72xx_wdt_stop(wdt); | ||
224 | } else { | ||
225 | dev_warn(&wdt->pdev->dev, | ||
226 | "TS-72XX WDT device closed unexpectly. " | ||
227 | "Watchdog timer will not stop!\n"); | ||
228 | /* | ||
229 | * Kick it one more time, to give userland some time | ||
230 | * to recover (for example, respawning the kicker | ||
231 | * daemon). | ||
232 | */ | ||
233 | ts72xx_wdt_kick(wdt); | ||
234 | } | ||
235 | |||
236 | wdt->flags = 0; | ||
237 | |||
238 | mutex_unlock(&wdt->lock); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static ssize_t ts72xx_wdt_write(struct file *file, | ||
243 | const char __user *data, | ||
244 | size_t len, | ||
245 | loff_t *ppos) | ||
246 | { | ||
247 | struct ts72xx_wdt *wdt = file->private_data; | ||
248 | |||
249 | if (!len) | ||
250 | return 0; | ||
251 | |||
252 | if (mutex_lock_interruptible(&wdt->lock)) | ||
253 | return -ERESTARTSYS; | ||
254 | |||
255 | ts72xx_wdt_kick(wdt); | ||
256 | |||
257 | /* | ||
258 | * Support for magic character closing. User process | ||
259 | * writes 'V' into the device, just before it is closed. | ||
260 | * This means that we know that the wdt timer can be | ||
261 | * stopped after user closes the device. | ||
262 | */ | ||
263 | if (!nowayout) { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < len; i++) { | ||
267 | char c; | ||
268 | |||
269 | /* In case it was set long ago */ | ||
270 | wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG; | ||
271 | |||
272 | if (get_user(c, data + i)) { | ||
273 | mutex_unlock(&wdt->lock); | ||
274 | return -EFAULT; | ||
275 | } | ||
276 | if (c == 'V') { | ||
277 | wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG; | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | mutex_unlock(&wdt->lock); | ||
284 | return len; | ||
285 | } | ||
286 | |||
287 | static const struct watchdog_info winfo = { | ||
288 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | ||
289 | WDIOF_MAGICCLOSE, | ||
290 | .firmware_version = 1, | ||
291 | .identity = "TS-72XX WDT", | ||
292 | }; | ||
293 | |||
294 | static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, | ||
295 | unsigned long arg) | ||
296 | { | ||
297 | struct ts72xx_wdt *wdt = file->private_data; | ||
298 | void __user *argp = (void __user *)arg; | ||
299 | int __user *p = (int __user *)argp; | ||
300 | int error = 0; | ||
301 | |||
302 | if (mutex_lock_interruptible(&wdt->lock)) | ||
303 | return -ERESTARTSYS; | ||
304 | |||
305 | switch (cmd) { | ||
306 | case WDIOC_GETSUPPORT: | ||
307 | error = copy_to_user(argp, &winfo, sizeof(winfo)); | ||
308 | break; | ||
309 | |||
310 | case WDIOC_GETSTATUS: | ||
311 | case WDIOC_GETBOOTSTATUS: | ||
312 | return put_user(0, p); | ||
313 | |||
314 | case WDIOC_KEEPALIVE: | ||
315 | ts72xx_wdt_kick(wdt); | ||
316 | break; | ||
317 | |||
318 | case WDIOC_SETOPTIONS: { | ||
319 | int options; | ||
320 | |||
321 | if (get_user(options, p)) { | ||
322 | error = -EFAULT; | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | error = -EINVAL; | ||
327 | |||
328 | if ((options & WDIOS_DISABLECARD) != 0) { | ||
329 | ts72xx_wdt_stop(wdt); | ||
330 | error = 0; | ||
331 | } | ||
332 | if ((options & WDIOS_ENABLECARD) != 0) { | ||
333 | ts72xx_wdt_start(wdt); | ||
334 | error = 0; | ||
335 | } | ||
336 | |||
337 | break; | ||
338 | } | ||
339 | |||
340 | case WDIOC_SETTIMEOUT: { | ||
341 | int new_timeout; | ||
342 | |||
343 | if (get_user(new_timeout, p)) { | ||
344 | error = -EFAULT; | ||
345 | } else { | ||
346 | int regval; | ||
347 | |||
348 | regval = timeout_to_regval(new_timeout); | ||
349 | if (regval < 0) { | ||
350 | error = -EINVAL; | ||
351 | } else { | ||
352 | ts72xx_wdt_stop(wdt); | ||
353 | wdt->regval = regval; | ||
354 | ts72xx_wdt_start(wdt); | ||
355 | } | ||
356 | } | ||
357 | if (error) | ||
358 | break; | ||
359 | |||
360 | /*FALLTHROUGH*/ | ||
361 | } | ||
362 | |||
363 | case WDIOC_GETTIMEOUT: | ||
364 | if (put_user(regval_to_timeout(wdt->regval), p)) | ||
365 | error = -EFAULT; | ||
366 | break; | ||
367 | |||
368 | default: | ||
369 | error = -ENOTTY; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | mutex_unlock(&wdt->lock); | ||
374 | return error; | ||
375 | } | ||
376 | |||
377 | static const struct file_operations ts72xx_wdt_fops = { | ||
378 | .owner = THIS_MODULE, | ||
379 | .llseek = no_llseek, | ||
380 | .open = ts72xx_wdt_open, | ||
381 | .release = ts72xx_wdt_release, | ||
382 | .write = ts72xx_wdt_write, | ||
383 | .unlocked_ioctl = ts72xx_wdt_ioctl, | ||
384 | }; | ||
385 | |||
386 | static struct miscdevice ts72xx_wdt_miscdev = { | ||
387 | .minor = WATCHDOG_MINOR, | ||
388 | .name = "watchdog", | ||
389 | .fops = &ts72xx_wdt_fops, | ||
390 | }; | ||
391 | |||
392 | static __devinit int ts72xx_wdt_probe(struct platform_device *pdev) | ||
393 | { | ||
394 | struct ts72xx_wdt *wdt; | ||
395 | struct resource *r1, *r2; | ||
396 | int error = 0; | ||
397 | |||
398 | wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL); | ||
399 | if (!wdt) { | ||
400 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
401 | return -ENOMEM; | ||
402 | } | ||
403 | |||
404 | r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
405 | if (!r1) { | ||
406 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
407 | error = -ENODEV; | ||
408 | goto fail; | ||
409 | } | ||
410 | |||
411 | r1 = request_mem_region(r1->start, resource_size(r1), pdev->name); | ||
412 | if (!r1) { | ||
413 | dev_err(&pdev->dev, "cannot request memory region\n"); | ||
414 | error = -EBUSY; | ||
415 | goto fail; | ||
416 | } | ||
417 | |||
418 | wdt->control_reg = ioremap(r1->start, resource_size(r1)); | ||
419 | if (!wdt->control_reg) { | ||
420 | dev_err(&pdev->dev, "failed to map memory\n"); | ||
421 | error = -ENODEV; | ||
422 | goto fail_free_control; | ||
423 | } | ||
424 | |||
425 | r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
426 | if (!r2) { | ||
427 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
428 | error = -ENODEV; | ||
429 | goto fail_unmap_control; | ||
430 | } | ||
431 | |||
432 | r2 = request_mem_region(r2->start, resource_size(r2), pdev->name); | ||
433 | if (!r2) { | ||
434 | dev_err(&pdev->dev, "cannot request memory region\n"); | ||
435 | error = -EBUSY; | ||
436 | goto fail_unmap_control; | ||
437 | } | ||
438 | |||
439 | wdt->feed_reg = ioremap(r2->start, resource_size(r2)); | ||
440 | if (!wdt->feed_reg) { | ||
441 | dev_err(&pdev->dev, "failed to map memory\n"); | ||
442 | error = -ENODEV; | ||
443 | goto fail_free_feed; | ||
444 | } | ||
445 | |||
446 | platform_set_drvdata(pdev, wdt); | ||
447 | ts72xx_wdt_pdev = pdev; | ||
448 | wdt->pdev = pdev; | ||
449 | mutex_init(&wdt->lock); | ||
450 | |||
451 | error = misc_register(&ts72xx_wdt_miscdev); | ||
452 | if (error) { | ||
453 | dev_err(&pdev->dev, "failed to register miscdev\n"); | ||
454 | goto fail_unmap_feed; | ||
455 | } | ||
456 | |||
457 | dev_info(&pdev->dev, "TS-72xx Watchdog driver\n"); | ||
458 | |||
459 | return 0; | ||
460 | |||
461 | fail_unmap_feed: | ||
462 | platform_set_drvdata(pdev, NULL); | ||
463 | iounmap(wdt->feed_reg); | ||
464 | fail_free_feed: | ||
465 | release_mem_region(r2->start, resource_size(r2)); | ||
466 | fail_unmap_control: | ||
467 | iounmap(wdt->control_reg); | ||
468 | fail_free_control: | ||
469 | release_mem_region(r1->start, resource_size(r1)); | ||
470 | fail: | ||
471 | kfree(wdt); | ||
472 | return error; | ||
473 | } | ||
474 | |||
475 | static __devexit int ts72xx_wdt_remove(struct platform_device *pdev) | ||
476 | { | ||
477 | struct ts72xx_wdt *wdt = platform_get_drvdata(pdev); | ||
478 | struct resource *res; | ||
479 | int error; | ||
480 | |||
481 | error = misc_deregister(&ts72xx_wdt_miscdev); | ||
482 | platform_set_drvdata(pdev, NULL); | ||
483 | |||
484 | iounmap(wdt->feed_reg); | ||
485 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
486 | release_mem_region(res->start, resource_size(res)); | ||
487 | |||
488 | iounmap(wdt->control_reg); | ||
489 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
490 | release_mem_region(res->start, resource_size(res)); | ||
491 | |||
492 | kfree(wdt); | ||
493 | return error; | ||
494 | } | ||
495 | |||
496 | static struct platform_driver ts72xx_wdt_driver = { | ||
497 | .probe = ts72xx_wdt_probe, | ||
498 | .remove = __devexit_p(ts72xx_wdt_remove), | ||
499 | .driver = { | ||
500 | .name = "ts72xx-wdt", | ||
501 | .owner = THIS_MODULE, | ||
502 | }, | ||
503 | }; | ||
504 | |||
505 | static __init int ts72xx_wdt_init(void) | ||
506 | { | ||
507 | return platform_driver_register(&ts72xx_wdt_driver); | ||
508 | } | ||
509 | module_init(ts72xx_wdt_init); | ||
510 | |||
511 | static __exit void ts72xx_wdt_exit(void) | ||
512 | { | ||
513 | platform_driver_unregister(&ts72xx_wdt_driver); | ||
514 | } | ||
515 | module_exit(ts72xx_wdt_exit); | ||
516 | |||
517 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); | ||
518 | MODULE_DESCRIPTION("TS-72xx SBC Watchdog"); | ||
519 | MODULE_LICENSE("GPL"); | ||
520 | MODULE_ALIAS("platform:ts72xx-wdt"); | ||
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index d635566e9307..9e9ed7bfabcb 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/miscdevice.h> | 13 | #include <linux/miscdevice.h> |
14 | #include <linux/watchdog.h> | 14 | #include <linux/watchdog.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/reboot.h> | ||
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
19 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *file, unsigned int cmd, | |||
166 | } | 165 | } |
167 | } | 166 | } |
168 | 167 | ||
169 | static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code, | ||
170 | void *unused) | ||
171 | { | ||
172 | if (code == SYS_DOWN || code == SYS_HALT) | ||
173 | txx9wdt_stop(); | ||
174 | return NOTIFY_DONE; | ||
175 | } | ||
176 | |||
177 | static const struct file_operations txx9wdt_fops = { | 168 | static const struct file_operations txx9wdt_fops = { |
178 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
179 | .llseek = no_llseek, | 170 | .llseek = no_llseek, |
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev = { | |||
189 | .fops = &txx9wdt_fops, | 180 | .fops = &txx9wdt_fops, |
190 | }; | 181 | }; |
191 | 182 | ||
192 | static struct notifier_block txx9wdt_notifier = { | ||
193 | .notifier_call = txx9wdt_notify_sys, | ||
194 | }; | ||
195 | |||
196 | static int __init txx9wdt_probe(struct platform_device *dev) | 183 | static int __init txx9wdt_probe(struct platform_device *dev) |
197 | { | 184 | { |
198 | struct resource *res; | 185 | struct resource *res; |
@@ -221,13 +208,8 @@ static int __init txx9wdt_probe(struct platform_device *dev) | |||
221 | if (!txx9wdt_reg) | 208 | if (!txx9wdt_reg) |
222 | goto exit_busy; | 209 | goto exit_busy; |
223 | 210 | ||
224 | ret = register_reboot_notifier(&txx9wdt_notifier); | ||
225 | if (ret) | ||
226 | goto exit; | ||
227 | |||
228 | ret = misc_register(&txx9wdt_miscdev); | 211 | ret = misc_register(&txx9wdt_miscdev); |
229 | if (ret) { | 212 | if (ret) { |
230 | unregister_reboot_notifier(&txx9wdt_notifier); | ||
231 | goto exit; | 213 | goto exit; |
232 | } | 214 | } |
233 | 215 | ||
@@ -249,14 +231,19 @@ exit: | |||
249 | static int __exit txx9wdt_remove(struct platform_device *dev) | 231 | static int __exit txx9wdt_remove(struct platform_device *dev) |
250 | { | 232 | { |
251 | misc_deregister(&txx9wdt_miscdev); | 233 | misc_deregister(&txx9wdt_miscdev); |
252 | unregister_reboot_notifier(&txx9wdt_notifier); | ||
253 | clk_disable(txx9_imclk); | 234 | clk_disable(txx9_imclk); |
254 | clk_put(txx9_imclk); | 235 | clk_put(txx9_imclk); |
255 | return 0; | 236 | return 0; |
256 | } | 237 | } |
257 | 238 | ||
239 | static void txx9wdt_shutdown(struct platform_device *dev) | ||
240 | { | ||
241 | txx9wdt_stop(); | ||
242 | } | ||
243 | |||
258 | static struct platform_driver txx9wdt_driver = { | 244 | static struct platform_driver txx9wdt_driver = { |
259 | .remove = __exit_p(txx9wdt_remove), | 245 | .remove = __exit_p(txx9wdt_remove), |
246 | .shutdown = txx9wdt_shutdown, | ||
260 | .driver = { | 247 | .driver = { |
261 | .name = "txx9wdt", | 248 | .name = "txx9wdt", |
262 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE, |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index f201accc4e3d..0f5288df0091 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
201 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
202 | int __user *p = argp; | 202 | int __user *p = argp; |
203 | int new_timeout; | 203 | int new_timeout; |
204 | static struct watchdog_info ident = { | 204 | static const struct watchdog_info ident = { |
205 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 205 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
206 | WDIOF_MAGICCLOSE, | 206 | WDIOF_MAGICCLOSE, |
207 | .firmware_version = 1, | 207 | .firmware_version = 1, |
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index 0560182a1d09..6e6743d1066f 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c | |||
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, | |||
371 | * according to their available features. | 371 | * according to their available features. |
372 | */ | 372 | */ |
373 | 373 | ||
374 | static struct watchdog_info ident = { | 374 | static const struct watchdog_info ident = { |
375 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, | 375 | .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, |
376 | .firmware_version = 1, | 376 | .firmware_version = 1, |
377 | .identity = WATCHDOG_NAME, | 377 | .identity = WATCHDOG_NAME, |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 5bfb1f2c5319..94ec22b9e66b 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *file, unsigned int cmd, | |||
312 | { | 312 | { |
313 | int __user *argp = (void __user *)arg; | 313 | int __user *argp = (void __user *)arg; |
314 | int i; | 314 | int i; |
315 | static struct watchdog_info wdinfo = { | 315 | static const struct watchdog_info wdinfo = { |
316 | .options = WDRTAS_SUPPORTED_MASK, | 316 | .options = WDRTAS_SUPPORTED_MASK, |
317 | .firmware_version = 0, | 317 | .firmware_version = 0, |
318 | .identity = "wdrtas", | 318 | .identity = "wdrtas", |
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 3bbefe9a2634..bfda2e99dd89 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c | |||
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
358 | int new_heartbeat; | 358 | int new_heartbeat; |
359 | int status; | 359 | int status; |
360 | 360 | ||
361 | static struct watchdog_info ident = { | 361 | struct watchdog_info ident = { |
362 | .options = WDIOF_SETTIMEOUT| | 362 | .options = WDIOF_SETTIMEOUT| |
363 | WDIOF_MAGICCLOSE| | 363 | WDIOF_MAGICCLOSE| |
364 | WDIOF_KEEPALIVEPING, | 364 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index f368dd87083a..7b22e3cdbc81 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, | |||
412 | int new_heartbeat; | 412 | int new_heartbeat; |
413 | int status; | 413 | int status; |
414 | 414 | ||
415 | static struct watchdog_info ident = { | 415 | struct watchdog_info ident = { |
416 | .options = WDIOF_SETTIMEOUT| | 416 | .options = WDIOF_SETTIMEOUT| |
417 | WDIOF_MAGICCLOSE| | 417 | WDIOF_MAGICCLOSE| |
418 | WDIOF_KEEPALIVEPING, | 418 | WDIOF_KEEPALIVEPING, |
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 775bcd807f31..8c4b2d5bb7da 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c | |||
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct file *file, | |||
213 | return count; | 213 | return count; |
214 | } | 214 | } |
215 | 215 | ||
216 | static struct watchdog_info ident = { | 216 | static const struct watchdog_info ident = { |
217 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 217 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
218 | .identity = "WM831x Watchdog", | 218 | .identity = "WM831x Watchdog", |
219 | }; | 219 | }; |
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index a2d2e8eb2282..89dd7b035295 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c | |||
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct file *file, | |||
177 | return count; | 177 | return count; |
178 | } | 178 | } |
179 | 179 | ||
180 | static struct watchdog_info ident = { | 180 | static const struct watchdog_info ident = { |
181 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | 181 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, |
182 | .identity = "WM8350 Watchdog", | 182 | .identity = "WM8350 Watchdog", |
183 | }; | 183 | }; |
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index ae5cb05a1a1c..bb71ab2336c8 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c | |||
@@ -426,7 +426,7 @@ static ssize_t hyp_sysfs_store(struct kobject *kobj, | |||
426 | return 0; | 426 | return 0; |
427 | } | 427 | } |
428 | 428 | ||
429 | static struct sysfs_ops hyp_sysfs_ops = { | 429 | static const struct sysfs_ops hyp_sysfs_ops = { |
430 | .show = hyp_sysfs_show, | 430 | .show = hyp_sysfs_show, |
431 | .store = hyp_sysfs_store, | 431 | .store = hyp_sysfs_store, |
432 | }; | 432 | }; |
diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids index 0c0f99e2dd62..de24e3decedd 100644 --- a/drivers/zorro/zorro.ids +++ b/drivers/zorro/zorro.ids | |||
@@ -108,7 +108,7 @@ | |||
108 | 0c00 500XP/SupraDrive WordSync [SCSI Host Adapter] | 108 | 0c00 500XP/SupraDrive WordSync [SCSI Host Adapter] |
109 | 0d00 SupraDrive WordSync II [SCSI Host Adapter] | 109 | 0d00 SupraDrive WordSync II [SCSI Host Adapter] |
110 | 1000 2400zi+ [Modem] | 110 | 1000 2400zi+ [Modem] |
111 | 0422 Computer Systems Assosiates | 111 | 0422 Computer Systems Associates |
112 | 1100 Magnum 40 [Accelerator and SCSI Host Adapter] | 112 | 1100 Magnum 40 [Accelerator and SCSI Host Adapter] |
113 | 1500 12 Gauge [SCSI Host Adapter] | 113 | 1500 12 Gauge [SCSI Host Adapter] |
114 | 0439 Marc Michael Groth | 114 | 0439 Marc Michael Groth |