diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-03-15 03:17:33 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-03-15 03:17:33 -0400 |
| commit | 12b8aeee3e51654fb95a3baff2e093f2513bb87d (patch) | |
| tree | 73f78d62591b197cd53747e36a2f3d707b79a50b /drivers | |
| parent | 25268498c9e07870323aead10751b7c6e99a3a78 (diff) | |
| parent | a3d3203e4bb40f253b1541e310dc0f9305be7c84 (diff) | |
Merge branch 'linus' into timers/core
Conflicts:
Documentation/feature-removal-schedule.txt
Merge reason: Resolve the conflict, update to upstream.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
336 files changed, 7267 insertions, 6423 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/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/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2bf3a6ef3684..d9301e861d9f 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) |
| @@ -1171,7 +1171,7 @@ extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf | |||
| 1171 | /* Meta data layout | 1171 | /* Meta data layout |
| 1172 | We reserve a 128MB Block (4k aligned) | 1172 | We reserve a 128MB Block (4k aligned) |
| 1173 | * either at the end of the backing device | 1173 | * either at the end of the backing device |
| 1174 | * or on a seperate meta data device. */ | 1174 | * or on a separate meta data device. */ |
| 1175 | 1175 | ||
| 1176 | #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ | 1176 | #define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ |
| 1177 | /* The following numbers are sectors */ | 1177 | /* 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/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/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/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/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/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/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/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-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/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/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/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/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/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/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/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/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/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/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/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/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/pci.c b/drivers/pci/pci.c index fdcf01af6762..cb1dd5f4988c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -2298,35 +2298,6 @@ void pci_msi_off(struct pci_dev *dev) | |||
| 2298 | } | 2298 | } |
| 2299 | } | 2299 | } |
| 2300 | 2300 | ||
| 2301 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | ||
| 2302 | /* | ||
| 2303 | * These can be overridden by arch-specific implementations | ||
| 2304 | */ | ||
| 2305 | int | ||
| 2306 | pci_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
| 2307 | { | ||
| 2308 | if (!pci_dma_supported(dev, mask)) | ||
| 2309 | return -EIO; | ||
| 2310 | |||
| 2311 | dev->dma_mask = mask; | ||
| 2312 | dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask)); | ||
| 2313 | |||
| 2314 | return 0; | ||
| 2315 | } | ||
| 2316 | |||
| 2317 | int | ||
| 2318 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | ||
| 2319 | { | ||
| 2320 | if (!pci_dma_supported(dev, mask)) | ||
| 2321 | return -EIO; | ||
| 2322 | |||
| 2323 | dev->dev.coherent_dma_mask = mask; | ||
| 2324 | dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask)); | ||
| 2325 | |||
| 2326 | return 0; | ||
| 2327 | } | ||
| 2328 | #endif | ||
| 2329 | |||
| 2330 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE | 2301 | #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE |
| 2331 | 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) |
| 2332 | { | 2303 | { |
| @@ -3068,8 +3039,6 @@ EXPORT_SYMBOL(pci_set_mwi); | |||
| 3068 | EXPORT_SYMBOL(pci_try_set_mwi); | 3039 | EXPORT_SYMBOL(pci_try_set_mwi); |
| 3069 | EXPORT_SYMBOL(pci_clear_mwi); | 3040 | EXPORT_SYMBOL(pci_clear_mwi); |
| 3070 | EXPORT_SYMBOL_GPL(pci_intx); | 3041 | EXPORT_SYMBOL_GPL(pci_intx); |
| 3071 | EXPORT_SYMBOL(pci_set_dma_mask); | ||
| 3072 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | ||
| 3073 | EXPORT_SYMBOL(pci_assign_resource); | 3042 | EXPORT_SYMBOL(pci_assign_resource); |
| 3074 | EXPORT_SYMBOL(pci_find_parent_resource); | 3043 | EXPORT_SYMBOL(pci_find_parent_resource); |
| 3075 | EXPORT_SYMBOL(pci_select_bars); | 3044 | EXPORT_SYMBOL(pci_select_bars); |
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/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 7ccf33c08967..56086363becc 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
| @@ -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) { |
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/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/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 7d25bdd443cd..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; |
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/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 1dd4d8407694..83881dfb33c0 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 |
