diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-03 03:14:09 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-03 03:14:09 -0400 |
commit | 27b030d58c8e72fc7a95187a791bd9406e350f02 (patch) | |
tree | ab3bab7f39a5ce5bab65578a7e08fa4dfdeb198c /drivers | |
parent | 79d20b14a0d651f15b0ef9a22b6cf12d284a6d38 (diff) | |
parent | 6628465e33ca694bd8fd5c3cf4eb7ff9177bc694 (diff) |
Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers')
112 files changed, 1919 insertions, 648 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 05a17812d521..ff64d333e95f 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -838,7 +838,7 @@ int acpi_processor_cst_has_changed (struct acpi_processor *pr) | |||
838 | 838 | ||
839 | /* Fall back to the default idle loop */ | 839 | /* Fall back to the default idle loop */ |
840 | pm_idle = pm_idle_save; | 840 | pm_idle = pm_idle_save; |
841 | synchronize_kernel(); | 841 | synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ |
842 | 842 | ||
843 | pr->flags.power = 0; | 843 | pr->flags.power = 0; |
844 | result = acpi_processor_get_power_info(pr); | 844 | result = acpi_processor_get_power_info(pr); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e7ca06626566..119c94093a13 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -379,8 +379,8 @@ ACPI_DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | |||
379 | 379 | ||
380 | /** | 380 | /** |
381 | * setup_sys_fs_device_files - sets up the device files under device namespace | 381 | * setup_sys_fs_device_files - sets up the device files under device namespace |
382 | * @@dev: acpi_device object | 382 | * @dev: acpi_device object |
383 | * @@func: function pointer to create or destroy the device file | 383 | * @func: function pointer to create or destroy the device file |
384 | */ | 384 | */ |
385 | static void | 385 | static void |
386 | setup_sys_fs_device_files ( | 386 | setup_sys_fs_device_files ( |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cd6453905a9b..3a5f4c991797 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -115,7 +115,7 @@ int platform_add_devices(struct platform_device **devs, int num) | |||
115 | 115 | ||
116 | /** | 116 | /** |
117 | * platform_device_register - add a platform-level device | 117 | * platform_device_register - add a platform-level device |
118 | * @dev: platform device we're adding | 118 | * @pdev: platform device we're adding |
119 | * | 119 | * |
120 | */ | 120 | */ |
121 | int platform_device_register(struct platform_device * pdev) | 121 | int platform_device_register(struct platform_device * pdev) |
@@ -174,7 +174,7 @@ int platform_device_register(struct platform_device * pdev) | |||
174 | 174 | ||
175 | /** | 175 | /** |
176 | * platform_device_unregister - remove a platform-level device | 176 | * platform_device_unregister - remove a platform-level device |
177 | * @dev: platform device we're removing | 177 | * @pdev: platform device we're removing |
178 | * | 178 | * |
179 | * Note that this function will also release all memory- and port-based | 179 | * Note that this function will also release all memory- and port-based |
180 | * resources owned by the device (@dev->resource). | 180 | * resources owned by the device (@dev->resource). |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index efdf04450bf7..9e268ddedfbd 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #define DBG_RX 0x0200 | 78 | #define DBG_RX 0x0200 |
79 | #define DBG_TX 0x0400 | 79 | #define DBG_TX 0x0400 |
80 | static unsigned int debugflags; | 80 | static unsigned int debugflags; |
81 | static unsigned int nbds_max = 16; | ||
81 | #endif /* NDEBUG */ | 82 | #endif /* NDEBUG */ |
82 | 83 | ||
83 | static struct nbd_device nbd_dev[MAX_NBD]; | 84 | static struct nbd_device nbd_dev[MAX_NBD]; |
@@ -647,7 +648,13 @@ static int __init nbd_init(void) | |||
647 | return -EIO; | 648 | return -EIO; |
648 | } | 649 | } |
649 | 650 | ||
650 | for (i = 0; i < MAX_NBD; i++) { | 651 | if (nbds_max > MAX_NBD) { |
652 | printk(KERN_CRIT "nbd: cannot allocate more than %u nbds; %u requested.\n", MAX_NBD, | ||
653 | nbds_max); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | for (i = 0; i < nbds_max; i++) { | ||
651 | struct gendisk *disk = alloc_disk(1); | 658 | struct gendisk *disk = alloc_disk(1); |
652 | if (!disk) | 659 | if (!disk) |
653 | goto out; | 660 | goto out; |
@@ -673,7 +680,7 @@ static int __init nbd_init(void) | |||
673 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); | 680 | dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags); |
674 | 681 | ||
675 | devfs_mk_dir("nbd"); | 682 | devfs_mk_dir("nbd"); |
676 | for (i = 0; i < MAX_NBD; i++) { | 683 | for (i = 0; i < nbds_max; i++) { |
677 | struct gendisk *disk = nbd_dev[i].disk; | 684 | struct gendisk *disk = nbd_dev[i].disk; |
678 | nbd_dev[i].file = NULL; | 685 | nbd_dev[i].file = NULL; |
679 | nbd_dev[i].magic = LO_MAGIC; | 686 | nbd_dev[i].magic = LO_MAGIC; |
@@ -706,8 +713,9 @@ out: | |||
706 | static void __exit nbd_cleanup(void) | 713 | static void __exit nbd_cleanup(void) |
707 | { | 714 | { |
708 | int i; | 715 | int i; |
709 | for (i = 0; i < MAX_NBD; i++) { | 716 | for (i = 0; i < nbds_max; i++) { |
710 | struct gendisk *disk = nbd_dev[i].disk; | 717 | struct gendisk *disk = nbd_dev[i].disk; |
718 | nbd_dev[i].magic = 0; | ||
711 | if (disk) { | 719 | if (disk) { |
712 | del_gendisk(disk); | 720 | del_gendisk(disk); |
713 | blk_cleanup_queue(disk->queue); | 721 | blk_cleanup_queue(disk->queue); |
@@ -725,6 +733,8 @@ module_exit(nbd_cleanup); | |||
725 | MODULE_DESCRIPTION("Network Block Device"); | 733 | MODULE_DESCRIPTION("Network Block Device"); |
726 | MODULE_LICENSE("GPL"); | 734 | MODULE_LICENSE("GPL"); |
727 | 735 | ||
736 | module_param(nbds_max, int, 0444); | ||
737 | MODULE_PARM_DESC(nbds_max, "How many network block devices to initialize."); | ||
728 | #ifndef NDEBUG | 738 | #ifndef NDEBUG |
729 | module_param(debugflags, int, 0644); | 739 | module_param(debugflags, int, 0644); |
730 | MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); | 740 | MODULE_PARM_DESC(debugflags, "flags for controlling debug output"); |
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c index 888c477e02b3..b1730b62c37e 100644 --- a/drivers/block/noop-iosched.c +++ b/drivers/block/noop-iosched.c | |||
@@ -13,34 +13,13 @@ | |||
13 | static int elevator_noop_merge(request_queue_t *q, struct request **req, | 13 | static int elevator_noop_merge(request_queue_t *q, struct request **req, |
14 | struct bio *bio) | 14 | struct bio *bio) |
15 | { | 15 | { |
16 | struct list_head *entry = &q->queue_head; | ||
17 | struct request *__rq; | ||
18 | int ret; | 16 | int ret; |
19 | 17 | ||
20 | if ((ret = elv_try_last_merge(q, bio))) { | 18 | ret = elv_try_last_merge(q, bio); |
19 | if (ret != ELEVATOR_NO_MERGE) | ||
21 | *req = q->last_merge; | 20 | *req = q->last_merge; |
22 | return ret; | ||
23 | } | ||
24 | 21 | ||
25 | while ((entry = entry->prev) != &q->queue_head) { | 22 | return ret; |
26 | __rq = list_entry_rq(entry); | ||
27 | |||
28 | if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) | ||
29 | break; | ||
30 | else if (__rq->flags & REQ_STARTED) | ||
31 | break; | ||
32 | |||
33 | if (!blk_fs_request(__rq)) | ||
34 | continue; | ||
35 | |||
36 | if ((ret = elv_try_merge(__rq, bio))) { | ||
37 | *req = __rq; | ||
38 | q->last_merge = __rq; | ||
39 | return ret; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | return ELEVATOR_NO_MERGE; | ||
44 | } | 23 | } |
45 | 24 | ||
46 | static void elevator_noop_merge_requests(request_queue_t *q, struct request *req, | 25 | static void elevator_noop_merge_requests(request_queue_t *q, struct request *req, |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 9deca49c71f0..beaa561f2ed8 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -645,7 +645,7 @@ static int cdrom_mrw_exit(struct cdrom_device_info *cdi) | |||
645 | ret = cdrom_mrw_bgformat_susp(cdi, 0); | 645 | ret = cdrom_mrw_bgformat_susp(cdi, 0); |
646 | } | 646 | } |
647 | 647 | ||
648 | if (!ret) | 648 | if (!ret && cdi->media_written) |
649 | ret = cdrom_flush_cache(cdi); | 649 | ret = cdrom_flush_cache(cdi); |
650 | 650 | ||
651 | return ret; | 651 | return ret; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 97ac4edf4655..e162dab64ffd 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -982,7 +982,7 @@ config MAX_RAW_DEVS | |||
982 | 982 | ||
983 | config HANGCHECK_TIMER | 983 | config HANGCHECK_TIMER |
984 | tristate "Hangcheck timer" | 984 | tristate "Hangcheck timer" |
985 | depends on X86_64 || X86 | 985 | depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390 |
986 | help | 986 | help |
987 | The hangcheck-timer module detects when the system has gone | 987 | The hangcheck-timer module detects when the system has gone |
988 | out to lunch past a certain margin. It can reboot the system | 988 | out to lunch past a certain margin. It can reboot the system |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index c86a22c5499b..0212febda654 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -192,7 +192,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] = | |||
192 | {4, 1024, 0, 3} | 192 | {4, 1024, 0, 3} |
193 | }; | 193 | }; |
194 | 194 | ||
195 | struct agp_bridge_driver ali_generic_bridge = { | 195 | static struct agp_bridge_driver ali_generic_bridge = { |
196 | .owner = THIS_MODULE, | 196 | .owner = THIS_MODULE, |
197 | .aperture_sizes = ali_generic_sizes, | 197 | .aperture_sizes = ali_generic_sizes, |
198 | .size_type = U32_APER_SIZE, | 198 | .size_type = U32_APER_SIZE, |
@@ -215,7 +215,7 @@ struct agp_bridge_driver ali_generic_bridge = { | |||
215 | .agp_destroy_page = ali_destroy_page, | 215 | .agp_destroy_page = ali_destroy_page, |
216 | }; | 216 | }; |
217 | 217 | ||
218 | struct agp_bridge_driver ali_m1541_bridge = { | 218 | static struct agp_bridge_driver ali_m1541_bridge = { |
219 | .owner = THIS_MODULE, | 219 | .owner = THIS_MODULE, |
220 | .aperture_sizes = ali_generic_sizes, | 220 | .aperture_sizes = ali_generic_sizes, |
221 | .size_type = U32_APER_SIZE, | 221 | .size_type = U32_APER_SIZE, |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index f1ea87ea6b65..e62a3c2c44a9 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -358,7 +358,7 @@ static struct gatt_mask amd_irongate_masks[] = | |||
358 | {.mask = 1, .type = 0} | 358 | {.mask = 1, .type = 0} |
359 | }; | 359 | }; |
360 | 360 | ||
361 | struct agp_bridge_driver amd_irongate_driver = { | 361 | static struct agp_bridge_driver amd_irongate_driver = { |
362 | .owner = THIS_MODULE, | 362 | .owner = THIS_MODULE, |
363 | .aperture_sizes = amd_irongate_sizes, | 363 | .aperture_sizes = amd_irongate_sizes, |
364 | .size_type = LVL2_APER_SIZE, | 364 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 905f0629c44f..399c042f68f0 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -243,7 +243,7 @@ static void amd64_cleanup(void) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | 245 | ||
246 | struct agp_bridge_driver amd_8151_driver = { | 246 | static struct agp_bridge_driver amd_8151_driver = { |
247 | .owner = THIS_MODULE, | 247 | .owner = THIS_MODULE, |
248 | .aperture_sizes = amd_8151_sizes, | 248 | .aperture_sizes = amd_8151_sizes, |
249 | .size_type = U32_APER_SIZE, | 249 | .size_type = U32_APER_SIZE, |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 757dde006fc9..a65f8827c283 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -393,7 +393,7 @@ static int ati_free_gatt_table(struct agp_bridge_data *bridge) | |||
393 | return 0; | 393 | return 0; |
394 | } | 394 | } |
395 | 395 | ||
396 | struct agp_bridge_driver ati_generic_bridge = { | 396 | static struct agp_bridge_driver ati_generic_bridge = { |
397 | .owner = THIS_MODULE, | 397 | .owner = THIS_MODULE, |
398 | .aperture_sizes = ati_generic_sizes, | 398 | .aperture_sizes = ati_generic_sizes, |
399 | .size_type = LVL2_APER_SIZE, | 399 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index c3442f3c6480..2f3dfb63bdc6 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge) | |||
97 | EXPORT_SYMBOL(agp_backend_release); | 97 | EXPORT_SYMBOL(agp_backend_release); |
98 | 98 | ||
99 | 99 | ||
100 | struct { int mem, agp; } maxes_table[] = { | 100 | static struct { int mem, agp; } maxes_table[] = { |
101 | {0, 0}, | 101 | {0, 0}, |
102 | {32, 4}, | 102 | {32, 4}, |
103 | {64, 28}, | 103 | {64, 28}, |
@@ -322,7 +322,7 @@ static int __init agp_init(void) | |||
322 | return 0; | 322 | return 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | void __exit agp_exit(void) | 325 | static void __exit agp_exit(void) |
326 | { | 326 | { |
327 | } | 327 | } |
328 | 328 | ||
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 2a87cecdc912..1383c3165ea1 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
@@ -303,7 +303,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t | |||
303 | } | 303 | } |
304 | 304 | ||
305 | 305 | ||
306 | struct agp_bridge_driver efficeon_driver = { | 306 | static struct agp_bridge_driver efficeon_driver = { |
307 | .owner = THIS_MODULE, | 307 | .owner = THIS_MODULE, |
308 | .aperture_sizes = efficeon_generic_sizes, | 308 | .aperture_sizes = efficeon_generic_sizes, |
309 | .size_type = LVL2_APER_SIZE, | 309 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index f633623ac802..3dfb6648547b 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -235,7 +235,7 @@ static void agp_insert_into_pool(struct agp_memory * temp) | |||
235 | 235 | ||
236 | /* File private list routines */ | 236 | /* File private list routines */ |
237 | 237 | ||
238 | struct agp_file_private *agp_find_private(pid_t pid) | 238 | static struct agp_file_private *agp_find_private(pid_t pid) |
239 | { | 239 | { |
240 | struct agp_file_private *curr; | 240 | struct agp_file_private *curr; |
241 | 241 | ||
@@ -250,7 +250,7 @@ struct agp_file_private *agp_find_private(pid_t pid) | |||
250 | return NULL; | 250 | return NULL; |
251 | } | 251 | } |
252 | 252 | ||
253 | void agp_insert_file_private(struct agp_file_private * priv) | 253 | static void agp_insert_file_private(struct agp_file_private * priv) |
254 | { | 254 | { |
255 | struct agp_file_private *prev; | 255 | struct agp_file_private *prev; |
256 | 256 | ||
@@ -262,7 +262,7 @@ void agp_insert_file_private(struct agp_file_private * priv) | |||
262 | agp_fe.file_priv_list = priv; | 262 | agp_fe.file_priv_list = priv; |
263 | } | 263 | } |
264 | 264 | ||
265 | void agp_remove_file_private(struct agp_file_private * priv) | 265 | static void agp_remove_file_private(struct agp_file_private * priv) |
266 | { | 266 | { |
267 | struct agp_file_private *next; | 267 | struct agp_file_private *next; |
268 | struct agp_file_private *prev; | 268 | struct agp_file_private *prev; |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 4f7a3e8bc919..80dafa3030bd 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -288,7 +288,7 @@ static struct gatt_mask nvidia_generic_masks[] = | |||
288 | }; | 288 | }; |
289 | 289 | ||
290 | 290 | ||
291 | struct agp_bridge_driver nvidia_driver = { | 291 | static struct agp_bridge_driver nvidia_driver = { |
292 | .owner = THIS_MODULE, | 292 | .owner = THIS_MODULE, |
293 | .aperture_sizes = nvidia_generic_sizes, | 293 | .aperture_sizes = nvidia_generic_sizes, |
294 | .size_type = U8_APER_SIZE, | 294 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index cfccacb2a647..ebc05554045c 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c | |||
@@ -119,7 +119,7 @@ static struct aper_size_info_8 sis_generic_sizes[7] = | |||
119 | {4, 1024, 0, 3} | 119 | {4, 1024, 0, 3} |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct agp_bridge_driver sis_driver = { | 122 | static struct agp_bridge_driver sis_driver = { |
123 | .owner = THIS_MODULE, | 123 | .owner = THIS_MODULE, |
124 | .aperture_sizes = sis_generic_sizes, | 124 | .aperture_sizes = sis_generic_sizes, |
125 | .size_type = U8_APER_SIZE, | 125 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index bb338d9134e0..10c23302dd84 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -409,7 +409,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
409 | agp_device_command(command, 0); | 409 | agp_device_command(command, 0); |
410 | } | 410 | } |
411 | 411 | ||
412 | struct agp_bridge_driver sworks_driver = { | 412 | static struct agp_bridge_driver sworks_driver = { |
413 | .owner = THIS_MODULE, | 413 | .owner = THIS_MODULE, |
414 | .aperture_sizes = serverworks_sizes, | 414 | .aperture_sizes = serverworks_sizes, |
415 | .size_type = LVL2_APER_SIZE, | 415 | .size_type = LVL2_APER_SIZE, |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index e1451dd9b6a7..c847df575cf5 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -170,7 +170,7 @@ static void via_tlbflush_agp3(struct agp_memory *mem) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | 172 | ||
173 | struct agp_bridge_driver via_agp3_driver = { | 173 | static struct agp_bridge_driver via_agp3_driver = { |
174 | .owner = THIS_MODULE, | 174 | .owner = THIS_MODULE, |
175 | .aperture_sizes = agp3_generic_sizes, | 175 | .aperture_sizes = agp3_generic_sizes, |
176 | .size_type = U8_APER_SIZE, | 176 | .size_type = U8_APER_SIZE, |
@@ -193,7 +193,7 @@ struct agp_bridge_driver via_agp3_driver = { | |||
193 | .agp_destroy_page = agp_generic_destroy_page, | 193 | .agp_destroy_page = agp_generic_destroy_page, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | struct agp_bridge_driver via_driver = { | 196 | static struct agp_bridge_driver via_driver = { |
197 | .owner = THIS_MODULE, | 197 | .owner = THIS_MODULE, |
198 | .aperture_sizes = via_generic_sizes, | 198 | .aperture_sizes = via_generic_sizes, |
199 | .size_type = U8_APER_SIZE, | 199 | .size_type = U8_APER_SIZE, |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 903e4c3cc209..a229915ce1b2 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #define KERNEL | 52 | #define KERNEL |
53 | #include <linux/types.h> | 53 | #include <linux/types.h> |
54 | #include <linux/fs.h> | 54 | #include <linux/fs.h> |
55 | #include <linux/mm.h> /* for verify_area */ | 55 | #include <linux/mm.h> |
56 | #include <linux/errno.h> /* for -EBUSY */ | 56 | #include <linux/errno.h> /* for -EBUSY */ |
57 | #include <linux/ioport.h> /* for request_region */ | 57 | #include <linux/ioport.h> /* for request_region */ |
58 | #include <linux/delay.h> /* for loops_per_jiffy */ | 58 | #include <linux/delay.h> /* for loops_per_jiffy */ |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 83d6b37b36cd..78e650fc5b41 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Driver for a little io fencing timer. | 4 | * Driver for a little io fencing timer. |
5 | * | 5 | * |
6 | * Copyright (C) 2002 Oracle Corporation. All rights reserved. | 6 | * Copyright (C) 2002, 2003 Oracle. All rights reserved. |
7 | * | 7 | * |
8 | * Author: Joel Becker <joel.becker@oracle.com> | 8 | * Author: Joel Becker <joel.becker@oracle.com> |
9 | * | 9 | * |
@@ -44,11 +44,14 @@ | |||
44 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
45 | #include <linux/mm.h> | 45 | #include <linux/mm.h> |
46 | #include <linux/reboot.h> | 46 | #include <linux/reboot.h> |
47 | #include <linux/smp_lock.h> | ||
47 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/delay.h> | ||
48 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
51 | #include <linux/sysrq.h> | ||
49 | 52 | ||
50 | 53 | ||
51 | #define VERSION_STR "0.5.0" | 54 | #define VERSION_STR "0.9.0" |
52 | 55 | ||
53 | #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ | 56 | #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ |
54 | #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ | 57 | #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ |
@@ -56,18 +59,89 @@ | |||
56 | static int hangcheck_tick = DEFAULT_IOFENCE_TICK; | 59 | static int hangcheck_tick = DEFAULT_IOFENCE_TICK; |
57 | static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; | 60 | static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; |
58 | static int hangcheck_reboot; /* Defaults to not reboot */ | 61 | static int hangcheck_reboot; /* Defaults to not reboot */ |
62 | static int hangcheck_dump_tasks; /* Defaults to not dumping SysRQ T */ | ||
59 | 63 | ||
60 | /* Driver options */ | 64 | /* options - modular */ |
61 | module_param(hangcheck_tick, int, 0); | 65 | module_param(hangcheck_tick, int, 0); |
62 | MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); | 66 | MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); |
63 | module_param(hangcheck_margin, int, 0); | 67 | module_param(hangcheck_margin, int, 0); |
64 | MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); | 68 | MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); |
65 | module_param(hangcheck_reboot, int, 0); | 69 | module_param(hangcheck_reboot, int, 0); |
66 | MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); | 70 | MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); |
71 | module_param(hangcheck_dump_tasks, int, 0); | ||
72 | MODULE_PARM_DESC(hangcheck_dump_tasks, "If nonzero, the machine will dump the system task state when the timer margin is exceeded."); | ||
67 | 73 | ||
68 | MODULE_AUTHOR("Joel Becker"); | 74 | MODULE_AUTHOR("Oracle"); |
69 | MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); | 75 | MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); |
70 | MODULE_LICENSE("GPL"); | 76 | MODULE_LICENSE("GPL"); |
77 | MODULE_VERSION(VERSION_STR); | ||
78 | |||
79 | /* options - nonmodular */ | ||
80 | #ifndef MODULE | ||
81 | |||
82 | static int __init hangcheck_parse_tick(char *str) | ||
83 | { | ||
84 | int par; | ||
85 | if (get_option(&str,&par)) | ||
86 | hangcheck_tick = par; | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | static int __init hangcheck_parse_margin(char *str) | ||
91 | { | ||
92 | int par; | ||
93 | if (get_option(&str,&par)) | ||
94 | hangcheck_margin = par; | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | static int __init hangcheck_parse_reboot(char *str) | ||
99 | { | ||
100 | int par; | ||
101 | if (get_option(&str,&par)) | ||
102 | hangcheck_reboot = par; | ||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | static int __init hangcheck_parse_dump_tasks(char *str) | ||
107 | { | ||
108 | int par; | ||
109 | if (get_option(&str,&par)) | ||
110 | hangcheck_dump_tasks = par; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | __setup("hcheck_tick", hangcheck_parse_tick); | ||
115 | __setup("hcheck_margin", hangcheck_parse_margin); | ||
116 | __setup("hcheck_reboot", hangcheck_parse_reboot); | ||
117 | __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); | ||
118 | #endif /* not MODULE */ | ||
119 | |||
120 | #if defined(CONFIG_X86) || defined(CONFIG_X86_64) | ||
121 | # define HAVE_MONOTONIC | ||
122 | # define TIMER_FREQ 1000000000ULL | ||
123 | #elif defined(CONFIG_ARCH_S390) | ||
124 | /* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */ | ||
125 | # define TIMER_FREQ 0xFA240000ULL | ||
126 | #elif defined(CONFIG_IA64) | ||
127 | # define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq) | ||
128 | #elif defined(CONFIG_PPC64) | ||
129 | # define TIMER_FREQ (HZ*loops_per_jiffy) | ||
130 | #endif | ||
131 | |||
132 | #ifdef HAVE_MONOTONIC | ||
133 | extern unsigned long long monotonic_clock(void); | ||
134 | #else | ||
135 | static inline unsigned long long monotonic_clock(void) | ||
136 | { | ||
137 | # ifdef __s390__ | ||
138 | /* returns the TOD. see 4-38 Principles of Op of zSeries */ | ||
139 | return get_clock(); | ||
140 | # else | ||
141 | return get_cycles(); | ||
142 | # endif /* __s390__ */ | ||
143 | } | ||
144 | #endif /* HAVE_MONOTONIC */ | ||
71 | 145 | ||
72 | 146 | ||
73 | /* Last time scheduled */ | 147 | /* Last time scheduled */ |
@@ -78,7 +152,6 @@ static void hangcheck_fire(unsigned long); | |||
78 | static struct timer_list hangcheck_ticktock = | 152 | static struct timer_list hangcheck_ticktock = |
79 | TIMER_INITIALIZER(hangcheck_fire, 0, 0); | 153 | TIMER_INITIALIZER(hangcheck_fire, 0, 0); |
80 | 154 | ||
81 | extern unsigned long long monotonic_clock(void); | ||
82 | 155 | ||
83 | static void hangcheck_fire(unsigned long data) | 156 | static void hangcheck_fire(unsigned long data) |
84 | { | 157 | { |
@@ -92,6 +165,12 @@ static void hangcheck_fire(unsigned long data) | |||
92 | tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ | 165 | tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ |
93 | 166 | ||
94 | if (tsc_diff > hangcheck_tsc_margin) { | 167 | if (tsc_diff > hangcheck_tsc_margin) { |
168 | if (hangcheck_dump_tasks) { | ||
169 | printk(KERN_CRIT "Hangcheck: Task state:\n"); | ||
170 | #ifdef CONFIG_MAGIC_SYSRQ | ||
171 | handle_sysrq('t', NULL, NULL); | ||
172 | #endif /* CONFIG_MAGIC_SYSRQ */ | ||
173 | } | ||
95 | if (hangcheck_reboot) { | 174 | if (hangcheck_reboot) { |
96 | printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); | 175 | printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); |
97 | machine_restart(NULL); | 176 | machine_restart(NULL); |
@@ -108,10 +187,16 @@ static int __init hangcheck_init(void) | |||
108 | { | 187 | { |
109 | printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", | 188 | printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", |
110 | VERSION_STR, hangcheck_tick, hangcheck_margin); | 189 | VERSION_STR, hangcheck_tick, hangcheck_margin); |
111 | 190 | #if defined (HAVE_MONOTONIC) | |
112 | hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick; | 191 | printk("Hangcheck: Using monotonic_clock().\n"); |
113 | hangcheck_tsc_margin *= 1000000000; | 192 | #elif defined(__s390__) |
114 | 193 | printk("Hangcheck: Using TOD.\n"); | |
194 | #else | ||
195 | printk("Hangcheck: Using get_cycles().\n"); | ||
196 | #endif /* HAVE_MONOTONIC */ | ||
197 | hangcheck_tsc_margin = | ||
198 | (unsigned long long)(hangcheck_margin + hangcheck_tick); | ||
199 | hangcheck_tsc_margin *= (unsigned long long)TIMER_FREQ; | ||
115 | 200 | ||
116 | hangcheck_tsc = monotonic_clock(); | 201 | hangcheck_tsc = monotonic_clock(); |
117 | mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); | 202 | mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); |
@@ -123,6 +208,7 @@ static int __init hangcheck_init(void) | |||
123 | static void __exit hangcheck_exit(void) | 208 | static void __exit hangcheck_exit(void) |
124 | { | 209 | { |
125 | del_timer_sync(&hangcheck_ticktock); | 210 | del_timer_sync(&hangcheck_ticktock); |
211 | printk("Hangcheck: Stopped hangcheck timer.\n"); | ||
126 | } | 212 | } |
127 | 213 | ||
128 | module_init(hangcheck_init); | 214 | module_init(hangcheck_init); |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 225b330115bb..5ce9c6269033 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt) | |||
235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); | 235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); |
236 | BT_CONTROL(BT_CLR_WR_PTR); | 236 | BT_CONTROL(BT_CLR_WR_PTR); |
237 | BT_CONTROL(BT_SMS_ATN); | 237 | BT_CONTROL(BT_SMS_ATN); |
238 | BT_INTMASK_W(BT_BMC_HWRST); | ||
239 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION | 238 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION |
240 | if (BT_STATUS & BT_B2H_ATN) { | 239 | if (BT_STATUS & BT_B2H_ATN) { |
241 | int i; | 240 | int i; |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index a6606a1aced7..d7fb452af7f9 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -2588,28 +2588,20 @@ handle_msg_timeout(struct ipmi_recv_msg *msg) | |||
2588 | deliver_response(msg); | 2588 | deliver_response(msg); |
2589 | } | 2589 | } |
2590 | 2590 | ||
2591 | static void | 2591 | static struct ipmi_smi_msg * |
2592 | send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | 2592 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, |
2593 | struct ipmi_smi_msg *smi_msg, | 2593 | unsigned char seq, long seqid) |
2594 | unsigned char seq, long seqid) | ||
2595 | { | 2594 | { |
2596 | if (!smi_msg) | 2595 | struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg(); |
2597 | smi_msg = ipmi_alloc_smi_msg(); | ||
2598 | if (!smi_msg) | 2596 | if (!smi_msg) |
2599 | /* If we can't allocate the message, then just return, we | 2597 | /* If we can't allocate the message, then just return, we |
2600 | get 4 retries, so this should be ok. */ | 2598 | get 4 retries, so this should be ok. */ |
2601 | return; | 2599 | return NULL; |
2602 | 2600 | ||
2603 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); | 2601 | memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len); |
2604 | smi_msg->data_size = recv_msg->msg.data_len; | 2602 | smi_msg->data_size = recv_msg->msg.data_len; |
2605 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); | 2603 | smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid); |
2606 | 2604 | ||
2607 | /* Send the new message. We send with a zero priority. It | ||
2608 | timed out, I doubt time is that critical now, and high | ||
2609 | priority messages are really only for messages to the local | ||
2610 | MC, which don't get resent. */ | ||
2611 | intf->handlers->sender(intf->send_info, smi_msg, 0); | ||
2612 | |||
2613 | #ifdef DEBUG_MSGING | 2605 | #ifdef DEBUG_MSGING |
2614 | { | 2606 | { |
2615 | int m; | 2607 | int m; |
@@ -2619,6 +2611,7 @@ send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | |||
2619 | printk("\n"); | 2611 | printk("\n"); |
2620 | } | 2612 | } |
2621 | #endif | 2613 | #endif |
2614 | return smi_msg; | ||
2622 | } | 2615 | } |
2623 | 2616 | ||
2624 | static void | 2617 | static void |
@@ -2683,14 +2676,13 @@ ipmi_timeout_handler(long timeout_period) | |||
2683 | intf->timed_out_ipmb_commands++; | 2676 | intf->timed_out_ipmb_commands++; |
2684 | spin_unlock(&intf->counter_lock); | 2677 | spin_unlock(&intf->counter_lock); |
2685 | } else { | 2678 | } else { |
2679 | struct ipmi_smi_msg *smi_msg; | ||
2686 | /* More retries, send again. */ | 2680 | /* More retries, send again. */ |
2687 | 2681 | ||
2688 | /* Start with the max timer, set to normal | 2682 | /* Start with the max timer, set to normal |
2689 | timer after the message is sent. */ | 2683 | timer after the message is sent. */ |
2690 | ent->timeout = MAX_MSG_TIMEOUT; | 2684 | ent->timeout = MAX_MSG_TIMEOUT; |
2691 | ent->retries_left--; | 2685 | ent->retries_left--; |
2692 | send_from_recv_msg(intf, ent->recv_msg, NULL, | ||
2693 | j, ent->seqid); | ||
2694 | spin_lock(&intf->counter_lock); | 2686 | spin_lock(&intf->counter_lock); |
2695 | if (ent->recv_msg->addr.addr_type | 2687 | if (ent->recv_msg->addr.addr_type |
2696 | == IPMI_LAN_ADDR_TYPE) | 2688 | == IPMI_LAN_ADDR_TYPE) |
@@ -2698,6 +2690,20 @@ ipmi_timeout_handler(long timeout_period) | |||
2698 | else | 2690 | else |
2699 | intf->retransmitted_ipmb_commands++; | 2691 | intf->retransmitted_ipmb_commands++; |
2700 | spin_unlock(&intf->counter_lock); | 2692 | spin_unlock(&intf->counter_lock); |
2693 | smi_msg = smi_from_recv_msg(intf, | ||
2694 | ent->recv_msg, j, ent->seqid); | ||
2695 | if(!smi_msg) | ||
2696 | continue; | ||
2697 | |||
2698 | spin_unlock_irqrestore(&(intf->seq_lock),flags); | ||
2699 | /* Send the new message. We send with a zero | ||
2700 | * priority. It timed out, I doubt time is | ||
2701 | * that critical now, and high priority | ||
2702 | * messages are really only for messages to the | ||
2703 | * local MC, which don't get resent. */ | ||
2704 | intf->handlers->sender(intf->send_info, | ||
2705 | smi_msg, 0); | ||
2706 | spin_lock_irqsave(&(intf->seq_lock), flags); | ||
2701 | } | 2707 | } |
2702 | } | 2708 | } |
2703 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 2709 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 29de259a981e..5419440087fd 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -100,6 +100,11 @@ enum si_intf_state { | |||
100 | /* FIXME - add watchdog stuff. */ | 100 | /* FIXME - add watchdog stuff. */ |
101 | }; | 101 | }; |
102 | 102 | ||
103 | /* Some BT-specific defines we need here. */ | ||
104 | #define IPMI_BT_INTMASK_REG 2 | ||
105 | #define IPMI_BT_INTMASK_CLEAR_IRQ_BIT 2 | ||
106 | #define IPMI_BT_INTMASK_ENABLE_IRQ_BIT 1 | ||
107 | |||
103 | enum si_type { | 108 | enum si_type { |
104 | SI_KCS, SI_SMIC, SI_BT | 109 | SI_KCS, SI_SMIC, SI_BT |
105 | }; | 110 | }; |
@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs) | |||
875 | return IRQ_HANDLED; | 880 | return IRQ_HANDLED; |
876 | } | 881 | } |
877 | 882 | ||
883 | static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) | ||
884 | { | ||
885 | struct smi_info *smi_info = data; | ||
886 | /* We need to clear the IRQ flag for the BT interface. */ | ||
887 | smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG, | ||
888 | IPMI_BT_INTMASK_CLEAR_IRQ_BIT | ||
889 | | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | ||
890 | return si_irq_handler(irq, data, regs); | ||
891 | } | ||
892 | |||
893 | |||
878 | static struct ipmi_smi_handlers handlers = | 894 | static struct ipmi_smi_handlers handlers = |
879 | { | 895 | { |
880 | .owner = THIS_MODULE, | 896 | .owner = THIS_MODULE, |
@@ -1001,11 +1017,22 @@ static int std_irq_setup(struct smi_info *info) | |||
1001 | if (!info->irq) | 1017 | if (!info->irq) |
1002 | return 0; | 1018 | return 0; |
1003 | 1019 | ||
1004 | rv = request_irq(info->irq, | 1020 | if (info->si_type == SI_BT) { |
1005 | si_irq_handler, | 1021 | rv = request_irq(info->irq, |
1006 | SA_INTERRUPT, | 1022 | si_bt_irq_handler, |
1007 | DEVICE_NAME, | 1023 | SA_INTERRUPT, |
1008 | info); | 1024 | DEVICE_NAME, |
1025 | info); | ||
1026 | if (!rv) | ||
1027 | /* Enable the interrupt in the BT interface. */ | ||
1028 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, | ||
1029 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT); | ||
1030 | } else | ||
1031 | rv = request_irq(info->irq, | ||
1032 | si_irq_handler, | ||
1033 | SA_INTERRUPT, | ||
1034 | DEVICE_NAME, | ||
1035 | info); | ||
1009 | if (rv) { | 1036 | if (rv) { |
1010 | printk(KERN_WARNING | 1037 | printk(KERN_WARNING |
1011 | "ipmi_si: %s unable to claim interrupt %d," | 1038 | "ipmi_si: %s unable to claim interrupt %d," |
@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info) | |||
1024 | if (!info->irq) | 1051 | if (!info->irq) |
1025 | return; | 1052 | return; |
1026 | 1053 | ||
1054 | if (info->si_type == SI_BT) | ||
1055 | /* Disable the interrupt in the BT interface. */ | ||
1056 | info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0); | ||
1027 | free_irq(info->irq, info); | 1057 | free_irq(info->irq, info); |
1028 | } | 1058 | } |
1029 | 1059 | ||
@@ -1526,8 +1556,17 @@ static int try_init_acpi(int intf_num, struct smi_info **new_info) | |||
1526 | info->irq_setup = NULL; | 1556 | info->irq_setup = NULL; |
1527 | } | 1557 | } |
1528 | 1558 | ||
1529 | regspacings[intf_num] = spmi->addr.register_bit_width / 8; | 1559 | if (spmi->addr.register_bit_width) { |
1530 | info->io.regspacing = spmi->addr.register_bit_width / 8; | 1560 | /* A (hopefully) properly formed register bit width. */ |
1561 | regspacings[intf_num] = spmi->addr.register_bit_width / 8; | ||
1562 | info->io.regspacing = spmi->addr.register_bit_width / 8; | ||
1563 | } else { | ||
1564 | /* Some broken systems get this wrong and set the value | ||
1565 | * to zero. Assume it is the default spacing. If that | ||
1566 | * is wrong, too bad, the vendor should fix the tables. */ | ||
1567 | regspacings[intf_num] = DEFAULT_REGSPACING; | ||
1568 | info->io.regspacing = DEFAULT_REGSPACING; | ||
1569 | } | ||
1531 | regsizes[intf_num] = regspacings[intf_num]; | 1570 | regsizes[intf_num] = regspacings[intf_num]; |
1532 | info->io.regsize = regsizes[intf_num]; | 1571 | info->io.regsize = regsizes[intf_num]; |
1533 | regshifts[intf_num] = spmi->addr.register_bit_offset; | 1572 | regshifts[intf_num] = spmi->addr.register_bit_offset; |
@@ -1623,7 +1662,13 @@ static int decode_dmi(dmi_header_t *dm, int intf_num) | |||
1623 | } | 1662 | } |
1624 | } else { | 1663 | } else { |
1625 | /* Old DMI spec. */ | 1664 | /* Old DMI spec. */ |
1626 | ipmi_data->base_addr = base_addr; | 1665 | /* Note that technically, the lower bit of the base |
1666 | * address should be 1 if the address is I/O and 0 if | ||
1667 | * the address is in memory. So many systems get that | ||
1668 | * wrong (and all that I have seen are I/O) so we just | ||
1669 | * ignore that bit and assume I/O. Systems that use | ||
1670 | * memory should use the newer spec, anyway. */ | ||
1671 | ipmi_data->base_addr = base_addr & 0xfffe; | ||
1627 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; | 1672 | ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; |
1628 | ipmi_data->offset = 1; | 1673 | ipmi_data->offset = 1; |
1629 | } | 1674 | } |
@@ -2199,7 +2244,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi) | |||
2199 | /* Wait until we know that we are out of any interrupt | 2244 | /* Wait until we know that we are out of any interrupt |
2200 | handlers might have been running before we freed the | 2245 | handlers might have been running before we freed the |
2201 | interrupt. */ | 2246 | interrupt. */ |
2202 | synchronize_kernel(); | 2247 | synchronize_sched(); |
2203 | 2248 | ||
2204 | if (new_smi->si_sm) { | 2249 | if (new_smi->si_sm) { |
2205 | if (new_smi->handlers) | 2250 | if (new_smi->handlers) |
@@ -2312,7 +2357,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) | |||
2312 | /* Wait until we know that we are out of any interrupt | 2357 | /* Wait until we know that we are out of any interrupt |
2313 | handlers might have been running before we freed the | 2358 | handlers might have been running before we freed the |
2314 | interrupt. */ | 2359 | interrupt. */ |
2315 | synchronize_kernel(); | 2360 | synchronize_sched(); |
2316 | 2361 | ||
2317 | /* Wait for the timer to stop. This avoids problems with race | 2362 | /* Wait for the timer to stop. This avoids problems with race |
2318 | conditions removing the timer here. */ | 2363 | conditions removing the timer here. */ |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index fd7093879c66..fcd1c02a32cb 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -709,11 +709,11 @@ static int ipmi_close(struct inode *ino, struct file *filep) | |||
709 | if (expect_close == 42) { | 709 | if (expect_close == 42) { |
710 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 710 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
711 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | 711 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); |
712 | clear_bit(0, &ipmi_wdog_open); | ||
713 | } else { | 712 | } else { |
714 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 713 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); |
715 | ipmi_heartbeat(); | 714 | ipmi_heartbeat(); |
716 | } | 715 | } |
716 | clear_bit(0, &ipmi_wdog_open); | ||
717 | } | 717 | } |
718 | 718 | ||
719 | ipmi_fasync (-1, filep, 0); | 719 | ipmi_fasync (-1, filep, 0); |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index a91ae271cf0a..763893e289b3 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -221,7 +221,7 @@ static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000}; | |||
221 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | 221 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. |
222 | Some architectures may need more. -- Changed to LONG to | 222 | Some architectures may need more. -- Changed to LONG to |
223 | support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ | 223 | support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ |
224 | long rio_irqmask = -1; | 224 | static long rio_irqmask = -1; |
225 | 225 | ||
226 | MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>"); | 226 | MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>"); |
227 | MODULE_DESCRIPTION("RIO driver"); | 227 | MODULE_DESCRIPTION("RIO driver"); |
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c index 8e61be34a1d3..ed867db550a9 100644 --- a/drivers/char/s3c2410-rtc.c +++ b/drivers/char/s3c2410-rtc.c | |||
@@ -116,7 +116,7 @@ static void s3c2410_rtc_setfreq(int freq) | |||
116 | 116 | ||
117 | /* Time read/write */ | 117 | /* Time read/write */ |
118 | 118 | ||
119 | static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm) | 119 | static int s3c2410_rtc_gettime(struct rtc_time *rtc_tm) |
120 | { | 120 | { |
121 | unsigned int have_retried = 0; | 121 | unsigned int have_retried = 0; |
122 | 122 | ||
@@ -151,6 +151,8 @@ static void s3c2410_rtc_gettime(struct rtc_time *rtc_tm) | |||
151 | 151 | ||
152 | rtc_tm->tm_year += 100; | 152 | rtc_tm->tm_year += 100; |
153 | rtc_tm->tm_mon -= 1; | 153 | rtc_tm->tm_mon -= 1; |
154 | |||
155 | return 0; | ||
154 | } | 156 | } |
155 | 157 | ||
156 | 158 | ||
@@ -171,7 +173,7 @@ static int s3c2410_rtc_settime(struct rtc_time *tm) | |||
171 | return 0; | 173 | return 0; |
172 | } | 174 | } |
173 | 175 | ||
174 | static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) | 176 | static int s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) |
175 | { | 177 | { |
176 | struct rtc_time *alm_tm = &alrm->time; | 178 | struct rtc_time *alm_tm = &alrm->time; |
177 | unsigned int alm_en; | 179 | unsigned int alm_en; |
@@ -231,6 +233,8 @@ static void s3c2410_rtc_getalarm(struct rtc_wkalrm *alrm) | |||
231 | } | 233 | } |
232 | 234 | ||
233 | /* todo - set alrm->enabled ? */ | 235 | /* todo - set alrm->enabled ? */ |
236 | |||
237 | return 0; | ||
234 | } | 238 | } |
235 | 239 | ||
236 | static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm) | 240 | static int s3c2410_rtc_setalarm(struct rtc_wkalrm *alrm) |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c789d5ceac76..50e0b612a8a2 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -1987,10 +1987,9 @@ static inline int sx_set_serial_info(struct specialix_port * port, | |||
1987 | 1987 | ||
1988 | func_enter(); | 1988 | func_enter(); |
1989 | /* | 1989 | /* |
1990 | error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp)); | 1990 | if (!access_ok(VERIFY_READ, (void *) newinfo, sizeof(tmp))) { |
1991 | if (error) { | ||
1992 | func_exit(); | 1991 | func_exit(); |
1993 | return error; | 1992 | return -EFAULT; |
1994 | } | 1993 | } |
1995 | */ | 1994 | */ |
1996 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { | 1995 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { |
@@ -2046,14 +2045,12 @@ static inline int sx_get_serial_info(struct specialix_port * port, | |||
2046 | { | 2045 | { |
2047 | struct serial_struct tmp; | 2046 | struct serial_struct tmp; |
2048 | struct specialix_board *bp = port_Board(port); | 2047 | struct specialix_board *bp = port_Board(port); |
2049 | // int error; | ||
2050 | 2048 | ||
2051 | func_enter(); | 2049 | func_enter(); |
2052 | 2050 | ||
2053 | /* | 2051 | /* |
2054 | error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)); | 2052 | if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp))) |
2055 | if (error) | 2053 | return -EFAULT; |
2056 | return error; | ||
2057 | */ | 2054 | */ |
2058 | 2055 | ||
2059 | memset(&tmp, 0, sizeof(tmp)); | 2056 | memset(&tmp, 0, sizeof(tmp)); |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index de166608c59e..b8899f560b5e 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -466,7 +466,7 @@ static int stl_parsebrd(stlconf_t *confp, char **argp); | |||
466 | 466 | ||
467 | static unsigned long stl_atol(char *str); | 467 | static unsigned long stl_atol(char *str); |
468 | 468 | ||
469 | int stl_init(void); | 469 | static int stl_init(void); |
470 | static int stl_open(struct tty_struct *tty, struct file *filp); | 470 | static int stl_open(struct tty_struct *tty, struct file *filp); |
471 | static void stl_close(struct tty_struct *tty, struct file *filp); | 471 | static void stl_close(struct tty_struct *tty, struct file *filp); |
472 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count); | 472 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count); |
@@ -3063,7 +3063,7 @@ static struct tty_operations stl_ops = { | |||
3063 | 3063 | ||
3064 | /*****************************************************************************/ | 3064 | /*****************************************************************************/ |
3065 | 3065 | ||
3066 | int __init stl_init(void) | 3066 | static int __init stl_init(void) |
3067 | { | 3067 | { |
3068 | int i; | 3068 | int i; |
3069 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | 3069 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 5d386f4bea49..8971484b956b 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/major.h> | 24 | #include <linux/major.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/signal.h> | ||
27 | 28 | ||
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
@@ -641,7 +642,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
641 | extern int spawnpid, spawnsig; | 642 | extern int spawnpid, spawnsig; |
642 | if (!perm || !capable(CAP_KILL)) | 643 | if (!perm || !capable(CAP_KILL)) |
643 | return -EPERM; | 644 | return -EPERM; |
644 | if (arg < 1 || arg > _NSIG || arg == SIGKILL) | 645 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) |
645 | return -EINVAL; | 646 | return -EINVAL; |
646 | spawnpid = current->pid; | 647 | spawnpid = current->pid; |
647 | spawnsig = arg; | 648 | spawnsig = arg; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b30001f31610..8e561313d094 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -223,7 +223,7 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | |||
223 | } | 223 | } |
224 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || | 224 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || |
225 | (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) || | 225 | (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) || |
226 | (val == CPUFREQ_RESUMECHANGE)) { | 226 | (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { |
227 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); | 227 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); |
228 | dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new); | 228 | dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new); |
229 | } | 229 | } |
@@ -866,11 +866,90 @@ EXPORT_SYMBOL(cpufreq_get); | |||
866 | 866 | ||
867 | 867 | ||
868 | /** | 868 | /** |
869 | * cpufreq_suspend - let the low level driver prepare for suspend | ||
870 | */ | ||
871 | |||
872 | static int cpufreq_suspend(struct sys_device * sysdev, u32 state) | ||
873 | { | ||
874 | int cpu = sysdev->id; | ||
875 | unsigned int ret = 0; | ||
876 | unsigned int cur_freq = 0; | ||
877 | struct cpufreq_policy *cpu_policy; | ||
878 | |||
879 | dprintk("resuming cpu %u\n", cpu); | ||
880 | |||
881 | if (!cpu_online(cpu)) | ||
882 | return 0; | ||
883 | |||
884 | /* we may be lax here as interrupts are off. Nonetheless | ||
885 | * we need to grab the correct cpu policy, as to check | ||
886 | * whether we really run on this CPU. | ||
887 | */ | ||
888 | |||
889 | cpu_policy = cpufreq_cpu_get(cpu); | ||
890 | if (!cpu_policy) | ||
891 | return -EINVAL; | ||
892 | |||
893 | /* only handle each CPU group once */ | ||
894 | if (unlikely(cpu_policy->cpu != cpu)) { | ||
895 | cpufreq_cpu_put(cpu_policy); | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | if (cpufreq_driver->suspend) { | ||
900 | ret = cpufreq_driver->suspend(cpu_policy, state); | ||
901 | if (ret) { | ||
902 | printk(KERN_ERR "cpufreq: suspend failed in ->suspend " | ||
903 | "step on CPU %u\n", cpu_policy->cpu); | ||
904 | cpufreq_cpu_put(cpu_policy); | ||
905 | return ret; | ||
906 | } | ||
907 | } | ||
908 | |||
909 | |||
910 | if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS) | ||
911 | goto out; | ||
912 | |||
913 | if (cpufreq_driver->get) | ||
914 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); | ||
915 | |||
916 | if (!cur_freq || !cpu_policy->cur) { | ||
917 | printk(KERN_ERR "cpufreq: suspend failed to assert current " | ||
918 | "frequency is what timing core thinks it is.\n"); | ||
919 | goto out; | ||
920 | } | ||
921 | |||
922 | if (unlikely(cur_freq != cpu_policy->cur)) { | ||
923 | struct cpufreq_freqs freqs; | ||
924 | |||
925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | ||
926 | printk(KERN_DEBUG "Warning: CPU frequency is %u, " | ||
927 | "cpufreq assumed %u kHz.\n", | ||
928 | cur_freq, cpu_policy->cur); | ||
929 | |||
930 | freqs.cpu = cpu; | ||
931 | freqs.old = cpu_policy->cur; | ||
932 | freqs.new = cur_freq; | ||
933 | |||
934 | notifier_call_chain(&cpufreq_transition_notifier_list, | ||
935 | CPUFREQ_SUSPENDCHANGE, &freqs); | ||
936 | adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs); | ||
937 | |||
938 | cpu_policy->cur = cur_freq; | ||
939 | } | ||
940 | |||
941 | out: | ||
942 | cpufreq_cpu_put(cpu_policy); | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | /** | ||
869 | * cpufreq_resume - restore proper CPU frequency handling after resume | 947 | * cpufreq_resume - restore proper CPU frequency handling after resume |
870 | * | 948 | * |
871 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) | 949 | * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) |
872 | * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync | 950 | * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync |
873 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored. | 951 | * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are |
952 | * restored. | ||
874 | */ | 953 | */ |
875 | static int cpufreq_resume(struct sys_device * sysdev) | 954 | static int cpufreq_resume(struct sys_device * sysdev) |
876 | { | 955 | { |
@@ -915,21 +994,26 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
915 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); | 994 | cur_freq = cpufreq_driver->get(cpu_policy->cpu); |
916 | 995 | ||
917 | if (!cur_freq || !cpu_policy->cur) { | 996 | if (!cur_freq || !cpu_policy->cur) { |
918 | printk(KERN_ERR "cpufreq: resume failed to assert current frequency is what timing core thinks it is.\n"); | 997 | printk(KERN_ERR "cpufreq: resume failed to assert " |
998 | "current frequency is what timing core " | ||
999 | "thinks it is.\n"); | ||
919 | goto out; | 1000 | goto out; |
920 | } | 1001 | } |
921 | 1002 | ||
922 | if (unlikely(cur_freq != cpu_policy->cur)) { | 1003 | if (unlikely(cur_freq != cpu_policy->cur)) { |
923 | struct cpufreq_freqs freqs; | 1004 | struct cpufreq_freqs freqs; |
924 | 1005 | ||
925 | printk(KERN_WARNING "Warning: CPU frequency is %u, " | 1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
926 | "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); | 1007 | printk(KERN_WARNING "Warning: CPU frequency" |
1008 | "is %u, cpufreq assumed %u kHz.\n", | ||
1009 | cur_freq, cpu_policy->cur); | ||
927 | 1010 | ||
928 | freqs.cpu = cpu; | 1011 | freqs.cpu = cpu; |
929 | freqs.old = cpu_policy->cur; | 1012 | freqs.old = cpu_policy->cur; |
930 | freqs.new = cur_freq; | 1013 | freqs.new = cur_freq; |
931 | 1014 | ||
932 | notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs); | 1015 | notifier_call_chain(&cpufreq_transition_notifier_list, |
1016 | CPUFREQ_RESUMECHANGE, &freqs); | ||
933 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); | 1017 | adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); |
934 | 1018 | ||
935 | cpu_policy->cur = cur_freq; | 1019 | cpu_policy->cur = cur_freq; |
@@ -945,6 +1029,7 @@ out: | |||
945 | static struct sysdev_driver cpufreq_sysdev_driver = { | 1029 | static struct sysdev_driver cpufreq_sysdev_driver = { |
946 | .add = cpufreq_add_dev, | 1030 | .add = cpufreq_add_dev, |
947 | .remove = cpufreq_remove_dev, | 1031 | .remove = cpufreq_remove_dev, |
1032 | .suspend = cpufreq_suspend, | ||
948 | .resume = cpufreq_resume, | 1033 | .resume = cpufreq_resume, |
949 | }; | 1034 | }; |
950 | 1035 | ||
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 6dc273a81327..569f16767442 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1204,6 +1204,8 @@ pmac_ide_do_suspend(ide_hwif_t *hwif) | |||
1204 | } | 1204 | } |
1205 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ | 1205 | #endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ |
1206 | 1206 | ||
1207 | disable_irq(pmif->irq); | ||
1208 | |||
1207 | /* The media bay will handle itself just fine */ | 1209 | /* The media bay will handle itself just fine */ |
1208 | if (pmif->mediabay) | 1210 | if (pmif->mediabay) |
1209 | return 0; | 1211 | return 0; |
@@ -1236,7 +1238,6 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
1236 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); | 1238 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); |
1237 | msleep(10); | 1239 | msleep(10); |
1238 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0); | 1240 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0); |
1239 | msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY)); | ||
1240 | 1241 | ||
1241 | /* Kauai has it different */ | 1242 | /* Kauai has it different */ |
1242 | if (pmif->kauai_fcr) { | 1243 | if (pmif->kauai_fcr) { |
@@ -1244,11 +1245,15 @@ pmac_ide_do_resume(ide_hwif_t *hwif) | |||
1244 | fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE; | 1245 | fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE; |
1245 | writel(fcr, pmif->kauai_fcr); | 1246 | writel(fcr, pmif->kauai_fcr); |
1246 | } | 1247 | } |
1248 | |||
1249 | msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY)); | ||
1247 | } | 1250 | } |
1248 | 1251 | ||
1249 | /* Sanitize drive timings */ | 1252 | /* Sanitize drive timings */ |
1250 | sanitize_timings(pmif); | 1253 | sanitize_timings(pmif); |
1251 | 1254 | ||
1255 | enable_irq(pmif->irq); | ||
1256 | |||
1252 | return 0; | 1257 | return 0; |
1253 | } | 1258 | } |
1254 | 1259 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 986f2180404b..637b30e35592 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -32,10 +32,11 @@ | |||
32 | * $Id$ | 32 | * $Id$ |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/mm.h> | ||
36 | |||
35 | #include "mthca_memfree.h" | 37 | #include "mthca_memfree.h" |
36 | #include "mthca_dev.h" | 38 | #include "mthca_dev.h" |
37 | #include "mthca_cmd.h" | 39 | #include "mthca_cmd.h" |
38 | #include <linux/mm.h> | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * We allocate in as big chunks as we can, up to a maximum of 256 KB | 42 | * We allocate in as big chunks as we can, up to a maximum of 256 KB |
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c76cf8ff29c0..874367bfab08 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c | |||
@@ -116,7 +116,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r | |||
116 | 116 | ||
117 | case 'K': /* Button data */ | 117 | case 'K': /* Button data */ |
118 | if (spaceorb->idx != 5) return; | 118 | if (spaceorb->idx != 5) return; |
119 | for (i = 0; i < 7; i++) | 119 | for (i = 0; i < 6; i++) |
120 | input_report_key(dev, spaceorb_buttons[i], (data[2] >> i) & 1); | 120 | input_report_key(dev, spaceorb_buttons[i], (data[2] >> i) & 1); |
121 | 121 | ||
122 | break; | 122 | break; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index f7304f0ce542..ff66ed4ee2cd 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -678,7 +678,7 @@ static void atkbd_disconnect(struct serio *serio) | |||
678 | atkbd_disable(atkbd); | 678 | atkbd_disable(atkbd); |
679 | 679 | ||
680 | /* make sure we don't have a command in flight */ | 680 | /* make sure we don't have a command in flight */ |
681 | synchronize_kernel(); | 681 | synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ |
682 | flush_scheduled_work(); | 682 | flush_scheduled_work(); |
683 | 683 | ||
684 | device_remove_file(&serio->dev, &atkbd_attr_extra); | 684 | device_remove_file(&serio->dev, &atkbd_attr_extra); |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 06163538bb20..12dee8e9fbbe 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -60,12 +60,12 @@ MODULE_LICENSE("GPL"); | |||
60 | 60 | ||
61 | static struct class_simple *capi_class; | 61 | static struct class_simple *capi_class; |
62 | 62 | ||
63 | int capi_major = 68; /* allocated */ | 63 | static int capi_major = 68; /* allocated */ |
64 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 64 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
65 | #define CAPINC_NR_PORTS 32 | 65 | #define CAPINC_NR_PORTS 32 |
66 | #define CAPINC_MAX_PORTS 256 | 66 | #define CAPINC_MAX_PORTS 256 |
67 | int capi_ttymajor = 191; | 67 | static int capi_ttymajor = 191; |
68 | int capi_ttyminors = CAPINC_NR_PORTS; | 68 | static int capi_ttyminors = CAPINC_NR_PORTS; |
69 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | 69 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ |
70 | 70 | ||
71 | module_param_named(major, capi_major, uint, 0); | 71 | module_param_named(major, capi_major, uint, 0); |
@@ -268,7 +268,7 @@ static void capiminor_free(struct capiminor *mp) | |||
268 | kfree(mp); | 268 | kfree(mp); |
269 | } | 269 | } |
270 | 270 | ||
271 | struct capiminor *capiminor_find(unsigned int minor) | 271 | static struct capiminor *capiminor_find(unsigned int minor) |
272 | { | 272 | { |
273 | struct list_head *l; | 273 | struct list_head *l; |
274 | struct capiminor *p = NULL; | 274 | struct capiminor *p = NULL; |
@@ -1166,7 +1166,7 @@ static int capinc_tty_write_room(struct tty_struct *tty) | |||
1166 | return room; | 1166 | return room; |
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | int capinc_tty_chars_in_buffer(struct tty_struct *tty) | 1169 | static int capinc_tty_chars_in_buffer(struct tty_struct *tty) |
1170 | { | 1170 | { |
1171 | struct capiminor *mp = (struct capiminor *)tty->driver_data; | 1171 | struct capiminor *mp = (struct capiminor *)tty->driver_data; |
1172 | if (!mp || !mp->nccip) { | 1172 | if (!mp || !mp->nccip) { |
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c index 16dc5418ff41..2cc8b27e4c3b 100644 --- a/drivers/isdn/capi/kcapi_proc.c +++ b/drivers/isdn/capi/kcapi_proc.c | |||
@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_file *seq, void *v) | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | struct seq_operations seq_controller_ops = { | 92 | static struct seq_operations seq_controller_ops = { |
93 | .start = controller_start, | 93 | .start = controller_start, |
94 | .next = controller_next, | 94 | .next = controller_next, |
95 | .stop = controller_stop, | 95 | .stop = controller_stop, |
96 | .show = controller_show, | 96 | .show = controller_show, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | struct seq_operations seq_contrstats_ops = { | 99 | static struct seq_operations seq_contrstats_ops = { |
100 | .start = controller_start, | 100 | .start = controller_start, |
101 | .next = controller_next, | 101 | .next = controller_next, |
102 | .stop = controller_stop, | 102 | .stop = controller_stop, |
@@ -192,14 +192,14 @@ applstats_show(struct seq_file *seq, void *v) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | struct seq_operations seq_applications_ops = { | 195 | static struct seq_operations seq_applications_ops = { |
196 | .start = applications_start, | 196 | .start = applications_start, |
197 | .next = applications_next, | 197 | .next = applications_next, |
198 | .stop = applications_stop, | 198 | .stop = applications_stop, |
199 | .show = applications_show, | 199 | .show = applications_show, |
200 | }; | 200 | }; |
201 | 201 | ||
202 | struct seq_operations seq_applstats_ops = { | 202 | static struct seq_operations seq_applstats_ops = { |
203 | .start = applications_start, | 203 | .start = applications_start, |
204 | .next = applications_next, | 204 | .next = applications_next, |
205 | .stop = applications_stop, | 205 | .stop = applications_stop, |
@@ -287,7 +287,7 @@ static int capi_driver_show(struct seq_file *seq, void *v) | |||
287 | return 0; | 287 | return 0; |
288 | } | 288 | } |
289 | 289 | ||
290 | struct seq_operations seq_capi_driver_ops = { | 290 | static struct seq_operations seq_capi_driver_ops = { |
291 | .start = capi_driver_start, | 291 | .start = capi_driver_start, |
292 | .next = capi_driver_next, | 292 | .next = capi_driver_next, |
293 | .stop = capi_driver_stop, | 293 | .stop = capi_driver_stop, |
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 1eb112213f0c..0bfd698726a6 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c | |||
@@ -383,7 +383,7 @@ divert_rule *getruleptr(int idx) | |||
383 | /*************************************************/ | 383 | /*************************************************/ |
384 | /* called from common module on an incoming call */ | 384 | /* called from common module on an incoming call */ |
385 | /*************************************************/ | 385 | /*************************************************/ |
386 | int isdn_divert_icall(isdn_ctrl *ic) | 386 | static int isdn_divert_icall(isdn_ctrl *ic) |
387 | { int retval = 0; | 387 | { int retval = 0; |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | struct call_struc *cs = NULL; | 389 | struct call_struc *cs = NULL; |
@@ -552,7 +552,7 @@ void deleteprocs(void) | |||
552 | /****************************************************/ | 552 | /****************************************************/ |
553 | /* put a address including address type into buffer */ | 553 | /* put a address including address type into buffer */ |
554 | /****************************************************/ | 554 | /****************************************************/ |
555 | int put_address(char *st, u_char *p, int len) | 555 | static int put_address(char *st, u_char *p, int len) |
556 | { u_char retval = 0; | 556 | { u_char retval = 0; |
557 | u_char adr_typ = 0; /* network standard */ | 557 | u_char adr_typ = 0; /* network standard */ |
558 | 558 | ||
@@ -595,7 +595,7 @@ int put_address(char *st, u_char *p, int len) | |||
595 | /*************************************/ | 595 | /*************************************/ |
596 | /* report a succesfull interrogation */ | 596 | /* report a succesfull interrogation */ |
597 | /*************************************/ | 597 | /*************************************/ |
598 | int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) | 598 | static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) |
599 | { char *src = ic->parm.dss1_io.data; | 599 | { char *src = ic->parm.dss1_io.data; |
600 | int restlen = ic->parm.dss1_io.datalen; | 600 | int restlen = ic->parm.dss1_io.datalen; |
601 | int cnt = 1; | 601 | int cnt = 1; |
@@ -689,7 +689,7 @@ int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) | |||
689 | /*********************************************/ | 689 | /*********************************************/ |
690 | /* callback for protocol specific extensions */ | 690 | /* callback for protocol specific extensions */ |
691 | /*********************************************/ | 691 | /*********************************************/ |
692 | int prot_stat_callback(isdn_ctrl *ic) | 692 | static int prot_stat_callback(isdn_ctrl *ic) |
693 | { struct call_struc *cs, *cs1; | 693 | { struct call_struc *cs, *cs1; |
694 | int i; | 694 | int i; |
695 | unsigned long flags; | 695 | unsigned long flags; |
@@ -781,7 +781,7 @@ int prot_stat_callback(isdn_ctrl *ic) | |||
781 | /***************************/ | 781 | /***************************/ |
782 | /* status callback from HL */ | 782 | /* status callback from HL */ |
783 | /***************************/ | 783 | /***************************/ |
784 | int isdn_divert_stat_callback(isdn_ctrl *ic) | 784 | static int isdn_divert_stat_callback(isdn_ctrl *ic) |
785 | { struct call_struc *cs, *cs1; | 785 | { struct call_struc *cs, *cs1; |
786 | unsigned long flags; | 786 | unsigned long flags; |
787 | int retval; | 787 | int retval; |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 8f93d01d8928..db654e8bd67e 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -555,6 +555,42 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto | |||
555 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 555 | #endif /* CONFIG_PMAC_BACKLIGHT */ |
556 | input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); | 556 | input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down); |
557 | break; | 557 | break; |
558 | |||
559 | case 0xc: /* videomode switch */ | ||
560 | input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down); | ||
561 | break; | ||
562 | |||
563 | case 0xd: /* keyboard illumination toggle */ | ||
564 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down); | ||
565 | break; | ||
566 | |||
567 | case 0xe: /* keyboard illumination decrease */ | ||
568 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down); | ||
569 | break; | ||
570 | |||
571 | case 0xf: | ||
572 | switch (data[1]) { | ||
573 | case 0x8f: | ||
574 | case 0x0f: | ||
575 | /* keyboard illumination increase */ | ||
576 | input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down); | ||
577 | break; | ||
578 | |||
579 | case 0x7f: | ||
580 | case 0xff: | ||
581 | /* keypad overlay toogle */ | ||
582 | break; | ||
583 | |||
584 | default: | ||
585 | printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", | ||
586 | data[0], data[1], data[2], data[3]); | ||
587 | break; | ||
588 | } | ||
589 | break; | ||
590 | default: | ||
591 | printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n", | ||
592 | data[0], data[1], data[2], data[3]); | ||
593 | break; | ||
558 | } | 594 | } |
559 | } | 595 | } |
560 | break; | 596 | break; |
@@ -775,6 +811,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id, | |||
775 | set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit); | 811 | set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit); |
776 | set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit); | 812 | set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit); |
777 | set_bit(KEY_EJECTCD, adbhid[id]->input.keybit); | 813 | set_bit(KEY_EJECTCD, adbhid[id]->input.keybit); |
814 | set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit); | ||
815 | set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit); | ||
816 | set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit); | ||
817 | set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit); | ||
778 | break; | 818 | break; |
779 | } | 819 | } |
780 | if (adbhid[id]->name[0]) | 820 | if (adbhid[id]->name[0]) |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index fdea1a3a631d..e654aa5eecd4 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -2351,6 +2351,10 @@ pmac_suspend_devices(void) | |||
2351 | return -EBUSY; | 2351 | return -EBUSY; |
2352 | } | 2352 | } |
2353 | 2353 | ||
2354 | /* Disable clock spreading on some machines */ | ||
2355 | pmac_tweak_clock_spreading(0); | ||
2356 | |||
2357 | /* Stop preemption */ | ||
2354 | preempt_disable(); | 2358 | preempt_disable(); |
2355 | 2359 | ||
2356 | /* Make sure the decrementer won't interrupt us */ | 2360 | /* Make sure the decrementer won't interrupt us */ |
@@ -2417,11 +2421,12 @@ pmac_wakeup_devices(void) | |||
2417 | 2421 | ||
2418 | /* Re-enable local CPU interrupts */ | 2422 | /* Re-enable local CPU interrupts */ |
2419 | local_irq_enable(); | 2423 | local_irq_enable(); |
2420 | |||
2421 | mdelay(100); | 2424 | mdelay(100); |
2422 | |||
2423 | preempt_enable(); | 2425 | preempt_enable(); |
2424 | 2426 | ||
2427 | /* Re-enable clock spreading on some machines */ | ||
2428 | pmac_tweak_clock_spreading(1); | ||
2429 | |||
2425 | /* Resume devices */ | 2430 | /* Resume devices */ |
2426 | device_resume(); | 2431 | device_resume(); |
2427 | 2432 | ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 77619a56e2bf..0dd6c2b5391b 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -331,25 +331,19 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
331 | struct bio *bio; | 331 | struct bio *bio; |
332 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 332 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
333 | int gfp_mask = GFP_NOIO | __GFP_HIGHMEM; | 333 | int gfp_mask = GFP_NOIO | __GFP_HIGHMEM; |
334 | unsigned long flags = current->flags; | ||
335 | unsigned int i; | 334 | unsigned int i; |
336 | 335 | ||
337 | /* | 336 | /* |
338 | * Tell VM to act less aggressively and fail earlier. | 337 | * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and |
339 | * This is not necessary but increases throughput. | 338 | * to fail earlier. This is not necessary but increases throughput. |
340 | * FIXME: Is this really intelligent? | 339 | * FIXME: Is this really intelligent? |
341 | */ | 340 | */ |
342 | current->flags &= ~PF_MEMALLOC; | ||
343 | |||
344 | if (base_bio) | 341 | if (base_bio) |
345 | bio = bio_clone(base_bio, GFP_NOIO); | 342 | bio = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC); |
346 | else | 343 | else |
347 | bio = bio_alloc(GFP_NOIO, nr_iovecs); | 344 | bio = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs); |
348 | if (!bio) { | 345 | if (!bio) |
349 | if (flags & PF_MEMALLOC) | ||
350 | current->flags |= PF_MEMALLOC; | ||
351 | return NULL; | 346 | return NULL; |
352 | } | ||
353 | 347 | ||
354 | /* if the last bio was not complete, continue where that one ended */ | 348 | /* if the last bio was not complete, continue where that one ended */ |
355 | bio->bi_idx = *bio_vec_idx; | 349 | bio->bi_idx = *bio_vec_idx; |
@@ -386,9 +380,6 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size, | |||
386 | size -= bv->bv_len; | 380 | size -= bv->bv_len; |
387 | } | 381 | } |
388 | 382 | ||
389 | if (flags & PF_MEMALLOC) | ||
390 | current->flags |= PF_MEMALLOC; | ||
391 | |||
392 | if (!bio->bi_size) { | 383 | if (!bio->bi_size) { |
393 | bio_put(bio); | 384 | bio_put(bio); |
394 | return NULL; | 385 | return NULL; |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index c9b134cd1532..1891e4930dcc 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -355,7 +355,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number) | |||
355 | goto abort; | 355 | goto abort; |
356 | } | 356 | } |
357 | p->rdev = NULL; | 357 | p->rdev = NULL; |
358 | synchronize_kernel(); | 358 | synchronize_rcu(); |
359 | if (atomic_read(&rdev->nr_pending)) { | 359 | if (atomic_read(&rdev->nr_pending)) { |
360 | /* lost the race, try later */ | 360 | /* lost the race, try later */ |
361 | err = -EBUSY; | 361 | err = -EBUSY; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a389394b52f6..83380b5d6593 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -797,7 +797,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
797 | goto abort; | 797 | goto abort; |
798 | } | 798 | } |
799 | p->rdev = NULL; | 799 | p->rdev = NULL; |
800 | synchronize_kernel(); | 800 | synchronize_rcu(); |
801 | if (atomic_read(&rdev->nr_pending)) { | 801 | if (atomic_read(&rdev->nr_pending)) { |
802 | /* lost the race, try later */ | 802 | /* lost the race, try later */ |
803 | err = -EBUSY; | 803 | err = -EBUSY; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b100bfe4fdca..e9dc2876a626 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -977,7 +977,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
977 | goto abort; | 977 | goto abort; |
978 | } | 978 | } |
979 | p->rdev = NULL; | 979 | p->rdev = NULL; |
980 | synchronize_kernel(); | 980 | synchronize_rcu(); |
981 | if (atomic_read(&rdev->nr_pending)) { | 981 | if (atomic_read(&rdev->nr_pending)) { |
982 | /* lost the race, try later */ | 982 | /* lost the race, try later */ |
983 | err = -EBUSY; | 983 | err = -EBUSY; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 52c3a81c4aa7..e96e2a10a9c9 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1873,7 +1873,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number) | |||
1873 | goto abort; | 1873 | goto abort; |
1874 | } | 1874 | } |
1875 | p->rdev = NULL; | 1875 | p->rdev = NULL; |
1876 | synchronize_kernel(); | 1876 | synchronize_rcu(); |
1877 | if (atomic_read(&rdev->nr_pending)) { | 1877 | if (atomic_read(&rdev->nr_pending)) { |
1878 | /* lost the race, try later */ | 1878 | /* lost the race, try later */ |
1879 | err = -EBUSY; | 1879 | err = -EBUSY; |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 7e30ab29691a..8a33f351e092 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -2038,7 +2038,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number) | |||
2038 | goto abort; | 2038 | goto abort; |
2039 | } | 2039 | } |
2040 | p->rdev = NULL; | 2040 | p->rdev = NULL; |
2041 | synchronize_kernel(); | 2041 | synchronize_rcu(); |
2042 | if (atomic_read(&rdev->nr_pending)) { | 2042 | if (atomic_read(&rdev->nr_pending)) { |
2043 | /* lost the race, try later */ | 2043 | /* lost the race, try later */ |
2044 | err = -EBUSY; | 2044 | err = -EBUSY; |
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index 8c842e2f59a2..84a49d2ec919 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c | |||
@@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
131 | [ 18 ] = KEY_KP0, | 131 | [ 18 ] = KEY_KP0, |
132 | 132 | ||
133 | [ 0 ] = KEY_POWER, | 133 | [ 0 ] = KEY_POWER, |
134 | // [ 27 ] = MTS button | 134 | [ 27 ] = KEY_LANGUAGE, //MTS button |
135 | [ 2 ] = KEY_TUNER, // TV/FM | 135 | [ 2 ] = KEY_TUNER, // TV/FM |
136 | [ 30 ] = KEY_VIDEO, | 136 | [ 30 ] = KEY_VIDEO, |
137 | // [ 22 ] = display button | 137 | [ 22 ] = KEY_INFO, //display button |
138 | [ 4 ] = KEY_VOLUMEUP, | 138 | [ 4 ] = KEY_VOLUMEUP, |
139 | [ 8 ] = KEY_VOLUMEDOWN, | 139 | [ 8 ] = KEY_VOLUMEDOWN, |
140 | [ 12 ] = KEY_CHANNELUP, | 140 | [ 12 ] = KEY_CHANNELUP, |
@@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
142 | [ 3 ] = KEY_ZOOM, // fullscreen | 142 | [ 3 ] = KEY_ZOOM, // fullscreen |
143 | [ 31 ] = KEY_SUBTITLE, // closed caption/teletext | 143 | [ 31 ] = KEY_SUBTITLE, // closed caption/teletext |
144 | [ 32 ] = KEY_SLEEP, | 144 | [ 32 ] = KEY_SLEEP, |
145 | // [ 41 ] = boss key | 145 | [ 41 ] = KEY_SEARCH, //boss key |
146 | [ 20 ] = KEY_MUTE, | 146 | [ 20 ] = KEY_MUTE, |
147 | [ 43 ] = KEY_RED, | 147 | [ 43 ] = KEY_RED, |
148 | [ 44 ] = KEY_GREEN, | 148 | [ 44 ] = KEY_GREEN, |
@@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
150 | [ 46 ] = KEY_BLUE, | 150 | [ 46 ] = KEY_BLUE, |
151 | [ 24 ] = KEY_KPPLUS, //fine tune + | 151 | [ 24 ] = KEY_KPPLUS, //fine tune + |
152 | [ 25 ] = KEY_KPMINUS, //fine tune - | 152 | [ 25 ] = KEY_KPMINUS, //fine tune - |
153 | // [ 42 ] = picture in picture | 153 | [ 42 ] = KEY_ANGLE, //picture in picture |
154 | [ 33 ] = KEY_KPDOT, | 154 | [ 33 ] = KEY_KPDOT, |
155 | [ 19 ] = KEY_KPENTER, | 155 | [ 19 ] = KEY_KPENTER, |
156 | // [ 17 ] = recall | 156 | [ 17 ] = KEY_AGAIN, //recall |
157 | [ 34 ] = KEY_BACK, | 157 | [ 34 ] = KEY_BACK, |
158 | [ 35 ] = KEY_PLAYPAUSE, | 158 | [ 35 ] = KEY_PLAYPAUSE, |
159 | [ 36 ] = KEY_NEXT, | 159 | [ 36 ] = KEY_NEXT, |
160 | // [ 37 ] = time shifting | 160 | [ 37 ] = KEY_T, //time shifting |
161 | [ 38 ] = KEY_STOP, | 161 | [ 38 ] = KEY_STOP, |
162 | [ 39 ] = KEY_RECORD | 162 | [ 39 ] = KEY_RECORD, |
163 | // [ 40 ] = snapshot | 163 | [ 40 ] = KEY_SHUFFLE //snapshot |
164 | }; | 164 | }; |
165 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 165 | EXPORT_SYMBOL_GPL(ir_codes_winfast); |
166 | 166 | ||
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 1930b513eefa..011860ce36cc 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "dvb-pll.h" | ||
35 | #include "cx22702.h" | 36 | #include "cx22702.h" |
36 | 37 | ||
37 | 38 | ||
@@ -203,7 +204,19 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
203 | 204 | ||
204 | /* set PLL */ | 205 | /* set PLL */ |
205 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 206 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); |
206 | state->config->pll_set(fe, p); | 207 | if (state->config->pll_set) { |
208 | state->config->pll_set(fe, p); | ||
209 | } else if (state->config->pll_desc) { | ||
210 | u8 pllbuf[4]; | ||
211 | struct i2c_msg msg = { .addr = state->config->pll_address, | ||
212 | .buf = pllbuf, .len = 4 }; | ||
213 | dvb_pll_configure(state->config->pll_desc, pllbuf, | ||
214 | p->frequency, | ||
215 | p->u.ofdm.bandwidth); | ||
216 | i2c_transfer(state->i2c, &msg, 1); | ||
217 | } else { | ||
218 | BUG(); | ||
219 | } | ||
207 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 220 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); |
208 | 221 | ||
209 | /* set inversion */ | 222 | /* set inversion */ |
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index 6e34f997aba2..559fdb906669 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -36,6 +36,9 @@ struct cx22702_config | |||
36 | u8 demod_address; | 36 | u8 demod_address; |
37 | 37 | ||
38 | /* PLL maintenance */ | 38 | /* PLL maintenance */ |
39 | u8 pll_address; | ||
40 | struct dvb_pll_desc *pll_desc; | ||
41 | |||
39 | int (*pll_init)(struct dvb_frontend* fe); | 42 | int (*pll_init)(struct dvb_frontend* fe); |
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 43 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
41 | }; | 44 | }; |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index c1b3542dad88..d3dd4228b72d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -252,6 +252,7 @@ config VIDEO_SAA7134_DVB | |||
252 | depends on VIDEO_SAA7134 && DVB_CORE | 252 | depends on VIDEO_SAA7134 && DVB_CORE |
253 | select VIDEO_BUF_DVB | 253 | select VIDEO_BUF_DVB |
254 | select DVB_MT352 | 254 | select DVB_MT352 |
255 | select DVB_CX22702 | ||
255 | ---help--- | 256 | ---help--- |
256 | This adds support for DVB cards based on the | 257 | This adds support for DVB cards based on the |
257 | Philips saa7134 chip. | 258 | Philips saa7134 chip. |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index c13f222fe6bd..033cc5498f23 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -3169,7 +3169,7 @@ static struct video_device radio_template = | |||
3169 | /* ----------------------------------------------------------------------- */ | 3169 | /* ----------------------------------------------------------------------- */ |
3170 | /* some debug code */ | 3170 | /* some debug code */ |
3171 | 3171 | ||
3172 | int bttv_risc_decode(u32 risc) | 3172 | static int bttv_risc_decode(u32 risc) |
3173 | { | 3173 | { |
3174 | static char *instr[16] = { | 3174 | static char *instr[16] = { |
3175 | [ BT848_RISC_WRITE >> 28 ] = "write", | 3175 | [ BT848_RISC_WRITE >> 28 ] = "write", |
@@ -3206,8 +3206,8 @@ int bttv_risc_decode(u32 risc) | |||
3206 | return incr[risc >> 28] ? incr[risc >> 28] : 1; | 3206 | return incr[risc >> 28] ? incr[risc >> 28] : 1; |
3207 | } | 3207 | } |
3208 | 3208 | ||
3209 | void bttv_risc_disasm(struct bttv *btv, | 3209 | static void bttv_risc_disasm(struct bttv *btv, |
3210 | struct btcx_riscmem *risc) | 3210 | struct btcx_riscmem *risc) |
3211 | { | 3211 | { |
3212 | unsigned int i,j,n; | 3212 | unsigned int i,j,n; |
3213 | 3213 | ||
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 26a6138015cb..1ff79b5a8835 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -429,7 +429,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, | |||
429 | /* ------------------------------------------------------------------ */ | 429 | /* ------------------------------------------------------------------ */ |
430 | /* debug helper code */ | 430 | /* debug helper code */ |
431 | 431 | ||
432 | int cx88_risc_decode(u32 risc) | 432 | static int cx88_risc_decode(u32 risc) |
433 | { | 433 | { |
434 | static char *instr[16] = { | 434 | static char *instr[16] = { |
435 | [ RISC_SYNC >> 28 ] = "sync", | 435 | [ RISC_SYNC >> 28 ] = "sync", |
@@ -542,7 +542,7 @@ void cx88_sram_channel_dump(struct cx88_core *core, | |||
542 | core->name,cx_read(ch->cnt2_reg)); | 542 | core->name,cx_read(ch->cnt2_reg)); |
543 | } | 543 | } |
544 | 544 | ||
545 | char *cx88_pci_irqs[32] = { | 545 | static char *cx88_pci_irqs[32] = { |
546 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", | 546 | "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", |
547 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", | 547 | "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", |
548 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", | 548 | "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", |
@@ -1206,7 +1206,6 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) | |||
1206 | /* ------------------------------------------------------------------ */ | 1206 | /* ------------------------------------------------------------------ */ |
1207 | 1207 | ||
1208 | EXPORT_SYMBOL(cx88_print_ioctl); | 1208 | EXPORT_SYMBOL(cx88_print_ioctl); |
1209 | EXPORT_SYMBOL(cx88_pci_irqs); | ||
1210 | EXPORT_SYMBOL(cx88_vid_irqs); | 1209 | EXPORT_SYMBOL(cx88_vid_irqs); |
1211 | EXPORT_SYMBOL(cx88_mpeg_irqs); | 1210 | EXPORT_SYMBOL(cx88_mpeg_irqs); |
1212 | EXPORT_SYMBOL(cx88_print_irqbits); | 1211 | EXPORT_SYMBOL(cx88_print_irqbits); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index bc6f18c45357..9d15d3d5a2b7 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/suspend.h> | 31 | #include <linux/suspend.h> |
32 | 32 | ||
33 | /* those two frontends need merging via linuxtv cvs ... */ | 33 | /* those two frontends need merging via linuxtv cvs ... */ |
34 | #define HAVE_CX22702 0 | 34 | #define HAVE_CX22702 1 |
35 | #define HAVE_OR51132 1 | 35 | #define HAVE_OR51132 1 |
36 | 36 | ||
37 | #include "cx88.h" | 37 | #include "cx88.h" |
@@ -91,7 +91,7 @@ static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb | |||
91 | cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb); | 91 | cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb); |
92 | } | 92 | } |
93 | 93 | ||
94 | struct videobuf_queue_ops dvb_qops = { | 94 | static struct videobuf_queue_ops dvb_qops = { |
95 | .buf_setup = dvb_buf_setup, | 95 | .buf_setup = dvb_buf_setup, |
96 | .buf_prepare = dvb_buf_prepare, | 96 | .buf_prepare = dvb_buf_prepare, |
97 | .buf_queue = dvb_buf_queue, | 97 | .buf_queue = dvb_buf_queue, |
@@ -191,7 +191,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe, | |||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | struct or51132_config pchdtv_hd3000 = { | 194 | static struct or51132_config pchdtv_hd3000 = { |
195 | .demod_address = 0x15, | 195 | .demod_address = 0x15, |
196 | .pll_address = 0x61, | 196 | .pll_address = 0x61, |
197 | .pll_desc = &dvb_pll_thomson_dtt7610, | 197 | .pll_desc = &dvb_pll_thomson_dtt7610, |
@@ -243,10 +243,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
243 | break; | 243 | break; |
244 | #endif | 244 | #endif |
245 | default: | 245 | default: |
246 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n" | 246 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
247 | "%s: you might want to look out for patches here:\n" | 247 | dev->core->name); |
248 | "%s: http://dl.bytesex.org/patches/\n", | ||
249 | dev->core->name, dev->core->name, dev->core->name); | ||
250 | break; | 248 | break; |
251 | } | 249 | } |
252 | if (NULL == dev->dvb.frontend) { | 250 | if (NULL == dev->dvb.frontend) { |
@@ -308,9 +306,11 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
308 | dev); | 306 | dev); |
309 | err = dvb_register(dev); | 307 | err = dvb_register(dev); |
310 | if (0 != err) | 308 | if (0 != err) |
311 | goto fail_free; | 309 | goto fail_fini; |
312 | return 0; | 310 | return 0; |
313 | 311 | ||
312 | fail_fini: | ||
313 | cx8802_fini_common(dev); | ||
314 | fail_free: | 314 | fail_free: |
315 | kfree(dev); | 315 | kfree(dev); |
316 | fail_core: | 316 | fail_core: |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 60800172c026..0725b1288f4f 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); | |||
45 | 45 | ||
46 | /* ----------------------------------------------------------------------- */ | 46 | /* ----------------------------------------------------------------------- */ |
47 | 47 | ||
48 | void cx8800_bit_setscl(void *data, int state) | 48 | static void cx8800_bit_setscl(void *data, int state) |
49 | { | 49 | { |
50 | struct cx88_core *core = data; | 50 | struct cx88_core *core = data; |
51 | 51 | ||
@@ -57,7 +57,7 @@ void cx8800_bit_setscl(void *data, int state) | |||
57 | cx_read(MO_I2C); | 57 | cx_read(MO_I2C); |
58 | } | 58 | } |
59 | 59 | ||
60 | void cx8800_bit_setsda(void *data, int state) | 60 | static void cx8800_bit_setsda(void *data, int state) |
61 | { | 61 | { |
62 | struct cx88_core *core = data; | 62 | struct cx88_core *core = data; |
63 | 63 | ||
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 471e508b0746..0584ff476387 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c | |||
@@ -46,9 +46,9 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f) | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | int cx8800_start_vbi_dma(struct cx8800_dev *dev, | 49 | static int cx8800_start_vbi_dma(struct cx8800_dev *dev, |
50 | struct cx88_dmaqueue *q, | 50 | struct cx88_dmaqueue *q, |
51 | struct cx88_buffer *buf) | 51 | struct cx88_buffer *buf) |
52 | { | 52 | { |
53 | struct cx88_core *core = dev->core; | 53 | struct cx88_core *core = dev->core; |
54 | 54 | ||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 701f594e1816..d1f5c92f0ce5 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -325,7 +325,7 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
325 | .shift = 0, | 325 | .shift = 0, |
326 | } | 326 | } |
327 | }; | 327 | }; |
328 | const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); | 328 | static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); |
329 | 329 | ||
330 | /* ------------------------------------------------------------------- */ | 330 | /* ------------------------------------------------------------------- */ |
331 | /* resource management */ | 331 | /* resource management */ |
@@ -665,7 +665,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
665 | cx88_free_buffer(fh->dev->pci,buf); | 665 | cx88_free_buffer(fh->dev->pci,buf); |
666 | } | 666 | } |
667 | 667 | ||
668 | struct videobuf_queue_ops cx8800_video_qops = { | 668 | static struct videobuf_queue_ops cx8800_video_qops = { |
669 | .buf_setup = buffer_setup, | 669 | .buf_setup = buffer_setup, |
670 | .buf_prepare = buffer_prepare, | 670 | .buf_prepare = buffer_prepare, |
671 | .buf_queue = buffer_queue, | 671 | .buf_queue = buffer_queue, |
@@ -1924,7 +1924,7 @@ static struct file_operations video_fops = | |||
1924 | .llseek = no_llseek, | 1924 | .llseek = no_llseek, |
1925 | }; | 1925 | }; |
1926 | 1926 | ||
1927 | struct video_device cx8800_video_template = | 1927 | static struct video_device cx8800_video_template = |
1928 | { | 1928 | { |
1929 | .name = "cx8800-video", | 1929 | .name = "cx8800-video", |
1930 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, | 1930 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, |
@@ -1933,7 +1933,7 @@ struct video_device cx8800_video_template = | |||
1933 | .minor = -1, | 1933 | .minor = -1, |
1934 | }; | 1934 | }; |
1935 | 1935 | ||
1936 | struct video_device cx8800_vbi_template = | 1936 | static struct video_device cx8800_vbi_template = |
1937 | { | 1937 | { |
1938 | .name = "cx8800-vbi", | 1938 | .name = "cx8800-vbi", |
1939 | .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER, | 1939 | .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER, |
@@ -1951,7 +1951,7 @@ static struct file_operations radio_fops = | |||
1951 | .llseek = no_llseek, | 1951 | .llseek = no_llseek, |
1952 | }; | 1952 | }; |
1953 | 1953 | ||
1954 | struct video_device cx8800_radio_template = | 1954 | static struct video_device cx8800_radio_template = |
1955 | { | 1955 | { |
1956 | .name = "cx8800-radio", | 1956 | .name = "cx8800-radio", |
1957 | .type = VID_TYPE_TUNER, | 1957 | .type = VID_TYPE_TUNER, |
@@ -2226,7 +2226,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) | |||
2226 | 2226 | ||
2227 | /* ----------------------------------------------------------- */ | 2227 | /* ----------------------------------------------------------- */ |
2228 | 2228 | ||
2229 | struct pci_device_id cx8800_pci_tbl[] = { | 2229 | static struct pci_device_id cx8800_pci_tbl[] = { |
2230 | { | 2230 | { |
2231 | .vendor = 0x14f1, | 2231 | .vendor = 0x14f1, |
2232 | .device = 0x8800, | 2232 | .device = 0x8800, |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index b351d9eae615..88eaaaba5ad8 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -420,7 +420,6 @@ struct cx8802_dev { | |||
420 | /* ----------------------------------------------------------- */ | 420 | /* ----------------------------------------------------------- */ |
421 | /* cx88-core.c */ | 421 | /* cx88-core.c */ |
422 | 422 | ||
423 | extern char *cx88_pci_irqs[32]; | ||
424 | extern char *cx88_vid_irqs[32]; | 423 | extern char *cx88_vid_irqs[32]; |
425 | extern char *cx88_mpeg_irqs[32]; | 424 | extern char *cx88_mpeg_irqs[32]; |
426 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, | 425 | extern void cx88_print_irqbits(char *name, char *tag, char **strings, |
@@ -472,9 +471,6 @@ extern void cx88_core_put(struct cx88_core *core, | |||
472 | /* cx88-vbi.c */ | 471 | /* cx88-vbi.c */ |
473 | 472 | ||
474 | void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); | 473 | void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); |
475 | int cx8800_start_vbi_dma(struct cx8800_dev *dev, | ||
476 | struct cx88_dmaqueue *q, | ||
477 | struct cx88_buffer *buf); | ||
478 | int cx8800_stop_vbi_dma(struct cx8800_dev *dev); | 474 | int cx8800_stop_vbi_dma(struct cx8800_dev *dev); |
479 | int cx8800_restart_vbi_queue(struct cx8800_dev *dev, | 475 | int cx8800_restart_vbi_queue(struct cx8800_dev *dev, |
480 | struct cx88_dmaqueue *q); | 476 | struct cx88_dmaqueue *q); |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index c97df705df5e..7fbb8581a87d 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -380,7 +380,9 @@ static void msp3400c_setvolume(struct i2c_client *client, | |||
380 | int val = 0, bal = 0; | 380 | int val = 0, bal = 0; |
381 | 381 | ||
382 | if (!muted) { | 382 | if (!muted) { |
383 | val = (volume * 0x7F / 65535) << 8; | 383 | /* 0x7f instead if 0x73 here has sound quality issues, |
384 | * probably due to overmodulation + clipping ... */ | ||
385 | val = (volume * 0x73 / 65535) << 8; | ||
384 | } | 386 | } |
385 | if (val) { | 387 | if (val) { |
386 | bal = (balance / 256) - 128; | 388 | bal = (balance / 256) - 128; |
@@ -997,7 +999,13 @@ static int msp34xx_modus(int norm) | |||
997 | { | 999 | { |
998 | switch (norm) { | 1000 | switch (norm) { |
999 | case VIDEO_MODE_PAL: | 1001 | case VIDEO_MODE_PAL: |
1002 | #if 1 | ||
1003 | /* experimental: not sure this works with all chip versions */ | ||
1004 | return 0x7003; | ||
1005 | #else | ||
1006 | /* previous value, try this if it breaks ... */ | ||
1000 | return 0x1003; | 1007 | return 0x1003; |
1008 | #endif | ||
1001 | case VIDEO_MODE_NTSC: /* BTSC */ | 1009 | case VIDEO_MODE_NTSC: /* BTSC */ |
1002 | return 0x2003; | 1010 | return 0x2003; |
1003 | case VIDEO_MODE_SECAM: | 1011 | case VIDEO_MODE_SECAM: |
@@ -1264,6 +1272,7 @@ static int msp34xxg_thread(void *data) | |||
1264 | int val, std, i; | 1272 | int val, std, i; |
1265 | 1273 | ||
1266 | printk("msp34xxg: daemon started\n"); | 1274 | printk("msp34xxg: daemon started\n"); |
1275 | msp->source = 1; /* default */ | ||
1267 | for (;;) { | 1276 | for (;;) { |
1268 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); | 1277 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); |
1269 | msp34xx_sleep(msp,-1); | 1278 | msp34xx_sleep(msp,-1); |
@@ -1334,8 +1343,9 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1334 | 1343 | ||
1335 | /* fix matrix mode to stereo and let the msp choose what | 1344 | /* fix matrix mode to stereo and let the msp choose what |
1336 | * to output according to 'source', as recommended | 1345 | * to output according to 'source', as recommended |
1346 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
1337 | */ | 1347 | */ |
1338 | int value = (source&0x07)<<8|(source==0 ? 0x00:0x20); | 1348 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); |
1339 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); | 1349 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); |
1340 | msp3400c_write(client, | 1350 | msp3400c_write(client, |
1341 | I2C_MSP3400C_DFP, | 1351 | I2C_MSP3400C_DFP, |
@@ -1359,7 +1369,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1359 | msp3400c_write(client, | 1369 | msp3400c_write(client, |
1360 | I2C_MSP3400C_DEM, | 1370 | I2C_MSP3400C_DEM, |
1361 | 0x22, /* a2 threshold for stereo/bilingual */ | 1371 | 0x22, /* a2 threshold for stereo/bilingual */ |
1362 | source==0 ? 0x7f0:stereo_threshold); | 1372 | stereo_threshold); |
1363 | msp->source=source; | 1373 | msp->source=source; |
1364 | } | 1374 | } |
1365 | 1375 | ||
@@ -1394,7 +1404,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) | |||
1394 | static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | 1404 | static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) |
1395 | { | 1405 | { |
1396 | struct msp3400c *msp = i2c_get_clientdata(client); | 1406 | struct msp3400c *msp = i2c_get_clientdata(client); |
1397 | int source = 0; | 1407 | int source; |
1398 | 1408 | ||
1399 | switch (audmode) { | 1409 | switch (audmode) { |
1400 | case V4L2_TUNER_MODE_MONO: | 1410 | case V4L2_TUNER_MODE_MONO: |
@@ -1410,9 +1420,10 @@ static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) | |||
1410 | case V4L2_TUNER_MODE_LANG2: | 1420 | case V4L2_TUNER_MODE_LANG2: |
1411 | source=4; /* stereo or B */ | 1421 | source=4; /* stereo or B */ |
1412 | break; | 1422 | break; |
1413 | default: /* doing nothing: a safe, sane default */ | 1423 | default: |
1414 | audmode = 0; | 1424 | audmode = 0; |
1415 | return; | 1425 | source = 1; |
1426 | break; | ||
1416 | } | 1427 | } |
1417 | msp->audmode = audmode; | 1428 | msp->audmode = audmode; |
1418 | msp34xxg_set_source(client, source); | 1429 | msp34xxg_set_source(client, source); |
@@ -1514,12 +1525,9 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1514 | 1525 | ||
1515 | msp->opmode = opmode; | 1526 | msp->opmode = opmode; |
1516 | if (OPMODE_AUTO == msp->opmode) { | 1527 | if (OPMODE_AUTO == msp->opmode) { |
1517 | #if 0 /* seems to work for ivtv only, disable by default for now ... */ | ||
1518 | if (HAVE_SIMPLER(msp)) | 1528 | if (HAVE_SIMPLER(msp)) |
1519 | msp->opmode = OPMODE_SIMPLER; | 1529 | msp->opmode = OPMODE_SIMPLER; |
1520 | else | 1530 | else if (HAVE_SIMPLE(msp)) |
1521 | #endif | ||
1522 | if (HAVE_SIMPLE(msp)) | ||
1523 | msp->opmode = OPMODE_SIMPLE; | 1531 | msp->opmode = OPMODE_SIMPLE; |
1524 | else | 1532 | else |
1525 | msp->opmode = OPMODE_MANUAL; | 1533 | msp->opmode = OPMODE_MANUAL; |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 180d3175ea5b..c51eb7f078d3 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -183,12 +183,12 @@ struct saa7134_board saa7134_boards[] = { | |||
183 | .name = "LifeView FlyTV Platinum FM", | 183 | .name = "LifeView FlyTV Platinum FM", |
184 | .audio_clock = 0x00200000, | 184 | .audio_clock = 0x00200000, |
185 | .tuner_type = TUNER_PHILIPS_TDA8290, | 185 | .tuner_type = TUNER_PHILIPS_TDA8290, |
186 | // .gpiomask = 0xe000, | 186 | .gpiomask = 0x1E000, /* Set GP16 and unused 15,14,13 to Output */ |
187 | .inputs = {{ | 187 | .inputs = {{ |
188 | .name = name_tv, | 188 | .name = name_tv, |
189 | .vmux = 1, | 189 | .vmux = 1, |
190 | .amux = TV, | 190 | .amux = TV, |
191 | // .gpio = 0x0000, | 191 | .gpio = 0x10000, /* GP16=1 selects TV input */ |
192 | .tv = 1, | 192 | .tv = 1, |
193 | },{ | 193 | },{ |
194 | /* .name = name_tv_mono, | 194 | /* .name = name_tv_mono, |
@@ -212,12 +212,12 @@ struct saa7134_board saa7134_boards[] = { | |||
212 | .amux = LINE2, | 212 | .amux = LINE2, |
213 | // .gpio = 0x4000, | 213 | // .gpio = 0x4000, |
214 | }}, | 214 | }}, |
215 | /* .radio = { | 215 | .radio = { |
216 | .name = name_radio, | 216 | .name = name_radio, |
217 | .amux = LINE2, | 217 | .amux = TV, |
218 | .gpio = 0x2000, | 218 | .gpio = 0x00000, /* GP16=0 selects FM radio antenna */ |
219 | }, | 219 | }, |
220 | */ }, | 220 | }, |
221 | [SAA7134_BOARD_EMPRESS] = { | 221 | [SAA7134_BOARD_EMPRESS] = { |
222 | /* "Gert Vervoort" <gert.vervoort@philips.com> */ | 222 | /* "Gert Vervoort" <gert.vervoort@philips.com> */ |
223 | .name = "EMPRESS", | 223 | .name = "EMPRESS", |
@@ -1628,11 +1628,17 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
1628 | },{ | 1628 | },{ |
1629 | .vendor = PCI_VENDOR_ID_PHILIPS, | 1629 | .vendor = PCI_VENDOR_ID_PHILIPS, |
1630 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 1630 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
1631 | .subvendor = 0x5168, | 1631 | .subvendor = 0x5168, /* Animation Technologies (LifeView) */ |
1632 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ | 1632 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ |
1633 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, | 1633 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, |
1634 | },{ | 1634 | },{ |
1635 | .vendor = PCI_VENDOR_ID_PHILIPS, | 1635 | .vendor = PCI_VENDOR_ID_PHILIPS, |
1636 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
1637 | .subvendor = 0x1489, /* KYE */ | ||
1638 | .subdevice = 0x0214, /* Genius VideoWonder ProTV */ | ||
1639 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */ | ||
1640 | },{ | ||
1641 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
1636 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 1642 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
1637 | .subvendor = 0x16be, | 1643 | .subvendor = 0x16be, |
1638 | .subdevice = 0x0003, | 1644 | .subdevice = 0x0003, |
@@ -1948,6 +1954,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
1948 | dev->has_remote = 1; | 1954 | dev->has_remote = 1; |
1949 | board_flyvideo(dev); | 1955 | board_flyvideo(dev); |
1950 | break; | 1956 | break; |
1957 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | ||
1951 | case SAA7134_BOARD_CINERGY400: | 1958 | case SAA7134_BOARD_CINERGY400: |
1952 | case SAA7134_BOARD_CINERGY600: | 1959 | case SAA7134_BOARD_CINERGY600: |
1953 | case SAA7134_BOARD_CINERGY600_MK3: | 1960 | case SAA7134_BOARD_CINERGY600_MK3: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index dd4a6c8ee65f..c2873ae029f9 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -172,7 +172,7 @@ static int fe_request_firmware(struct dvb_frontend* fe, | |||
172 | return request_firmware(fw, name, &dev->pci->dev); | 172 | return request_firmware(fw, name, &dev->pci->dev); |
173 | } | 173 | } |
174 | 174 | ||
175 | struct tda1004x_config medion_cardbus = { | 175 | static struct tda1004x_config medion_cardbus = { |
176 | .demod_address = 0x08, /* not sure this is correct */ | 176 | .demod_address = 0x08, /* not sure this is correct */ |
177 | .invert = 0, | 177 | .invert = 0, |
178 | .invert_oclk = 0, | 178 | .invert_oclk = 0, |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 727d437e07df..ca50cf531f20 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -379,6 +379,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
379 | switch (dev->board) { | 379 | switch (dev->board) { |
380 | case SAA7134_BOARD_FLYVIDEO2000: | 380 | case SAA7134_BOARD_FLYVIDEO2000: |
381 | case SAA7134_BOARD_FLYVIDEO3000: | 381 | case SAA7134_BOARD_FLYVIDEO3000: |
382 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | ||
382 | ir_codes = flyvideo_codes; | 383 | ir_codes = flyvideo_codes; |
383 | mask_keycode = 0xEC00000; | 384 | mask_keycode = 0xEC00000; |
384 | mask_keydown = 0x0040000; | 385 | mask_keydown = 0x0040000; |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 065eb4007b1d..80dc34f18c2c 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -991,7 +991,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) | |||
991 | { | 991 | { |
992 | if (tda9874a_SIF > 2) | 992 | if (tda9874a_SIF > 2) |
993 | tda9874a_SIF = 1; | 993 | tda9874a_SIF = 1; |
994 | if (tda9874a_STD >= 8) | 994 | if (tda9874a_STD > 8) |
995 | tda9874a_STD = 0; | 995 | tda9874a_STD = 0; |
996 | if(tda9874a_AMSEL > 1) | 996 | if(tda9874a_AMSEL > 1) |
997 | tda9874a_AMSEL = 0; | 997 | tda9874a_AMSEL = 0; |
diff --git a/drivers/net/gt96100eth.h b/drivers/net/gt96100eth.h index 2f4bfd4dacbe..395869c5ed3e 100644 --- a/drivers/net/gt96100eth.h +++ b/drivers/net/gt96100eth.h | |||
@@ -214,7 +214,7 @@ typedef struct { | |||
214 | u32 cmdstat; | 214 | u32 cmdstat; |
215 | u32 next; | 215 | u32 next; |
216 | u32 buff_ptr; | 216 | u32 buff_ptr; |
217 | } gt96100_td_t __attribute__ ((packed)); | 217 | } __attribute__ ((packed)) gt96100_td_t; |
218 | 218 | ||
219 | typedef struct { | 219 | typedef struct { |
220 | #ifdef DESC_BE | 220 | #ifdef DESC_BE |
@@ -227,7 +227,7 @@ typedef struct { | |||
227 | u32 cmdstat; | 227 | u32 cmdstat; |
228 | u32 next; | 228 | u32 next; |
229 | u32 buff_ptr; | 229 | u32 buff_ptr; |
230 | } gt96100_rd_t __attribute__ ((packed)); | 230 | } __attribute__ ((packed)) gt96100_rd_t; |
231 | 231 | ||
232 | 232 | ||
233 | /* Values for the Tx command-status descriptor entry. */ | 233 | /* Values for the Tx command-status descriptor entry. */ |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index acb170152bbd..b3a898c5a585 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -13,8 +13,8 @@ | |||
13 | ** This driver has only been tested with | 13 | ** This driver has only been tested with |
14 | ** -- HP J2585B 10/100 Mbit/s PCI Busmaster | 14 | ** -- HP J2585B 10/100 Mbit/s PCI Busmaster |
15 | ** -- HP J2585A 10/100 Mbit/s PCI | 15 | ** -- HP J2585A 10/100 Mbit/s PCI |
16 | ** -- HP J2970 10 Mbit/s PCI Combo 10base-T/BNC | 16 | ** -- HP J2970A 10 Mbit/s PCI Combo 10base-T/BNC |
17 | ** -- HP J2973 10 Mbit/s PCI 10base-T | 17 | ** -- HP J2973A 10 Mbit/s PCI 10base-T |
18 | ** -- HP J2573 10/100 ISA | 18 | ** -- HP J2573 10/100 ISA |
19 | ** -- Compex ReadyLink ENET100-VG4 10/100 Mbit/s PCI / EISA | 19 | ** -- Compex ReadyLink ENET100-VG4 10/100 Mbit/s PCI / EISA |
20 | ** -- Compex FreedomLine 100/VG 10/100 Mbit/s ISA / EISA / PCI | 20 | ** -- Compex FreedomLine 100/VG 10/100 Mbit/s ISA / EISA / PCI |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 07e2df09491f..c59507f8a76b 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -2385,7 +2385,7 @@ core_down: | |||
2385 | } | 2385 | } |
2386 | 2386 | ||
2387 | /* Give a racing hard_start_xmit a few cycles to complete. */ | 2387 | /* Give a racing hard_start_xmit a few cycles to complete. */ |
2388 | synchronize_kernel(); | 2388 | synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ |
2389 | 2389 | ||
2390 | /* | 2390 | /* |
2391 | * And now for the 50k$ question: are IRQ disabled or not ? | 2391 | * And now for the 50k$ question: are IRQ disabled or not ? |
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index d471b3ea5d12..021d0f76bc4c 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c | |||
@@ -120,6 +120,10 @@ static int pci_visit_bridge (struct pci_visit * fn, | |||
120 | 120 | ||
121 | /** | 121 | /** |
122 | * pci_visit_dev - scans the pci buses. | 122 | * pci_visit_dev - scans the pci buses. |
123 | * @fn: callback functions that are called while visiting | ||
124 | * @wrapped_dev: the device to scan | ||
125 | * @wrapped_parent: the bus where @wrapped_dev is connected to | ||
126 | * | ||
123 | * Every bus and every function is presented to a custom | 127 | * Every bus and every function is presented to a custom |
124 | * function that can act upon it. | 128 | * function that can act upon it. |
125 | */ | 129 | */ |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 3e64ff64b38c..838575e3fac6 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | /** | 15 | /** |
16 | * pci_enable_rom - enable ROM decoding for a PCI device | 16 | * pci_enable_rom - enable ROM decoding for a PCI device |
17 | * @dev: PCI device to enable | 17 | * @pdev: PCI device to enable |
18 | * | 18 | * |
19 | * Enable ROM decoding on @dev. This involves simply turning on the last | 19 | * Enable ROM decoding on @dev. This involves simply turning on the last |
20 | * bit of the PCI ROM BAR. Note that some cards may share address decoders | 20 | * bit of the PCI ROM BAR. Note that some cards may share address decoders |
@@ -32,7 +32,7 @@ static void pci_enable_rom(struct pci_dev *pdev) | |||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * pci_disable_rom - disable ROM decoding for a PCI device | 34 | * pci_disable_rom - disable ROM decoding for a PCI device |
35 | * @dev: PCI device to disable | 35 | * @pdev: PCI device to disable |
36 | * | 36 | * |
37 | * Disable ROM decoding on a PCI device by turning off the last bit in the | 37 | * Disable ROM decoding on a PCI device by turning off the last bit in the |
38 | * ROM BAR. | 38 | * ROM BAR. |
@@ -47,7 +47,7 @@ static void pci_disable_rom(struct pci_dev *pdev) | |||
47 | 47 | ||
48 | /** | 48 | /** |
49 | * pci_map_rom - map a PCI ROM to kernel space | 49 | * pci_map_rom - map a PCI ROM to kernel space |
50 | * @dev: pointer to pci device struct | 50 | * @pdev: pointer to pci device struct |
51 | * @size: pointer to receive size of pci window over ROM | 51 | * @size: pointer to receive size of pci window over ROM |
52 | * @return: kernel virtual pointer to image of ROM | 52 | * @return: kernel virtual pointer to image of ROM |
53 | * | 53 | * |
@@ -132,7 +132,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
132 | 132 | ||
133 | /** | 133 | /** |
134 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy | 134 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy |
135 | * @dev: pointer to pci device struct | 135 | * @pdev: pointer to pci device struct |
136 | * @size: pointer to receive size of pci window over ROM | 136 | * @size: pointer to receive size of pci window over ROM |
137 | * @return: kernel virtual pointer to image of ROM | 137 | * @return: kernel virtual pointer to image of ROM |
138 | * | 138 | * |
@@ -166,7 +166,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) | |||
166 | 166 | ||
167 | /** | 167 | /** |
168 | * pci_unmap_rom - unmap the ROM from kernel space | 168 | * pci_unmap_rom - unmap the ROM from kernel space |
169 | * @dev: pointer to pci device struct | 169 | * @pdev: pointer to pci device struct |
170 | * @rom: virtual address of the previous mapping | 170 | * @rom: virtual address of the previous mapping |
171 | * | 171 | * |
172 | * Remove a mapping of a previously mapped ROM | 172 | * Remove a mapping of a previously mapped ROM |
@@ -187,7 +187,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
187 | 187 | ||
188 | /** | 188 | /** |
189 | * pci_remove_rom - disable the ROM and remove its sysfs attribute | 189 | * pci_remove_rom - disable the ROM and remove its sysfs attribute |
190 | * @dev: pointer to pci device struct | 190 | * @pdev: pointer to pci device struct |
191 | * | 191 | * |
192 | * Remove the rom file in sysfs and disable ROM decoding. | 192 | * Remove the rom file in sysfs and disable ROM decoding. |
193 | */ | 193 | */ |
@@ -206,7 +206,7 @@ void pci_remove_rom(struct pci_dev *pdev) | |||
206 | /** | 206 | /** |
207 | * pci_cleanup_rom - internal routine for freeing the ROM copy created | 207 | * pci_cleanup_rom - internal routine for freeing the ROM copy created |
208 | * by pci_map_rom_copy called from remove.c | 208 | * by pci_map_rom_copy called from remove.c |
209 | * @dev: pointer to pci device struct | 209 | * @pdev: pointer to pci device struct |
210 | * | 210 | * |
211 | * Free the copied ROM if we allocated one. | 211 | * Free the copied ROM if we allocated one. |
212 | */ | 212 | */ |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 639e04253482..65ecef738537 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -253,7 +253,7 @@ void pnp_init_resource_table(struct pnp_resource_table *table) | |||
253 | 253 | ||
254 | /** | 254 | /** |
255 | * pnp_clean_resources - clears resources that were not manually set | 255 | * pnp_clean_resources - clears resources that were not manually set |
256 | * @res - the resources to clean | 256 | * @res: the resources to clean |
257 | * | 257 | * |
258 | */ | 258 | */ |
259 | static void pnp_clean_resource_table(struct pnp_resource_table * res) | 259 | static void pnp_clean_resource_table(struct pnp_resource_table * res) |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c0ddb1eb8c4d..dd61e09029b1 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -94,8 +94,8 @@ static void | |||
94 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | 94 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) |
95 | { | 95 | { |
96 | int i = 0; | 96 | int i = 0; |
97 | while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && | 97 | while (i < PNP_MAX_DMA && |
98 | i < PNP_MAX_DMA) | 98 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) |
99 | i++; | 99 | i++; |
100 | if (i < PNP_MAX_DMA) { | 100 | if (i < PNP_MAX_DMA) { |
101 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | 101 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 618ac15a9e90..79bce7b75740 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -72,7 +72,9 @@ static void | |||
72 | pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | 72 | pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) |
73 | { | 73 | { |
74 | int i = 0; | 74 | int i = 0; |
75 | while (!(res->dma_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_DMA) i++; | 75 | while (i < PNP_MAX_DMA && |
76 | !(res->dma_resource[i].flags & IORESOURCE_UNSET)) | ||
77 | i++; | ||
76 | if (i < PNP_MAX_DMA) { | 78 | if (i < PNP_MAX_DMA) { |
77 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | 79 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag |
78 | if (dma == -1) { | 80 | if (dma == -1) { |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index b755bac6ccbc..02cfe244e069 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.158 $ | 10 | * $Revision: 1.161 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1131,13 +1131,17 @@ __dasd_process_blk_queue(struct dasd_device * device) | |||
1131 | request_queue_t *queue; | 1131 | request_queue_t *queue; |
1132 | struct request *req; | 1132 | struct request *req; |
1133 | struct dasd_ccw_req *cqr; | 1133 | struct dasd_ccw_req *cqr; |
1134 | int nr_queued; | 1134 | int nr_queued, feature_ro; |
1135 | 1135 | ||
1136 | queue = device->request_queue; | 1136 | queue = device->request_queue; |
1137 | /* No queue ? Then there is nothing to do. */ | 1137 | /* No queue ? Then there is nothing to do. */ |
1138 | if (queue == NULL) | 1138 | if (queue == NULL) |
1139 | return; | 1139 | return; |
1140 | 1140 | ||
1141 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
1142 | if (feature_ro < 0) /* no devmap */ | ||
1143 | return; | ||
1144 | |||
1141 | /* | 1145 | /* |
1142 | * We requeue request from the block device queue to the ccw | 1146 | * We requeue request from the block device queue to the ccw |
1143 | * queue only in two states. In state DASD_STATE_READY the | 1147 | * queue only in two states. In state DASD_STATE_READY the |
@@ -1157,8 +1161,8 @@ __dasd_process_blk_queue(struct dasd_device * device) | |||
1157 | elv_next_request(queue) && | 1161 | elv_next_request(queue) && |
1158 | nr_queued < DASD_CHANQ_MAX_SIZE) { | 1162 | nr_queued < DASD_CHANQ_MAX_SIZE) { |
1159 | req = elv_next_request(queue); | 1163 | req = elv_next_request(queue); |
1160 | if (test_bit(DASD_FLAG_RO, &device->flags) && | 1164 | |
1161 | rq_data_dir(req) == WRITE) { | 1165 | if (feature_ro && rq_data_dir(req) == WRITE) { |
1162 | DBF_DEV_EVENT(DBF_ERR, device, | 1166 | DBF_DEV_EVENT(DBF_ERR, device, |
1163 | "Rejecting write request %p", | 1167 | "Rejecting write request %p", |
1164 | req); | 1168 | req); |
@@ -1631,6 +1635,7 @@ dasd_setup_queue(struct dasd_device * device) | |||
1631 | blk_queue_max_hw_segments(device->request_queue, -1L); | 1635 | blk_queue_max_hw_segments(device->request_queue, -1L); |
1632 | blk_queue_max_segment_size(device->request_queue, -1L); | 1636 | blk_queue_max_segment_size(device->request_queue, -1L); |
1633 | blk_queue_segment_boundary(device->request_queue, -1L); | 1637 | blk_queue_segment_boundary(device->request_queue, -1L); |
1638 | blk_queue_ordered(device->request_queue, 1); | ||
1634 | } | 1639 | } |
1635 | 1640 | ||
1636 | /* | 1641 | /* |
@@ -1803,13 +1808,17 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1803 | 1808 | ||
1804 | { | 1809 | { |
1805 | struct dasd_device *device; | 1810 | struct dasd_device *device; |
1806 | int rc; | 1811 | int feature_diag, rc; |
1812 | |||
1813 | feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG); | ||
1814 | if (feature_diag < 0) | ||
1815 | return feature_diag; | ||
1807 | 1816 | ||
1808 | device = dasd_create_device(cdev); | 1817 | device = dasd_create_device(cdev); |
1809 | if (IS_ERR(device)) | 1818 | if (IS_ERR(device)) |
1810 | return PTR_ERR(device); | 1819 | return PTR_ERR(device); |
1811 | 1820 | ||
1812 | if (test_bit(DASD_FLAG_USE_DIAG, &device->flags)) { | 1821 | if (feature_diag) { |
1813 | if (!dasd_diag_discipline_pointer) { | 1822 | if (!dasd_diag_discipline_pointer) { |
1814 | printk (KERN_WARNING | 1823 | printk (KERN_WARNING |
1815 | "dasd_generic couldn't online device %s " | 1824 | "dasd_generic couldn't online device %s " |
diff --git a/drivers/s390/block/dasd_cmb.c b/drivers/s390/block/dasd_cmb.c index ed1ab474c0c6..4f365bff275c 100644 --- a/drivers/s390/block/dasd_cmb.c +++ b/drivers/s390/block/dasd_cmb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.6 $) | 2 | * linux/drivers/s390/block/dasd_cmb.c ($Revision: 1.9 $) |
3 | * | 3 | * |
4 | * Linux on zSeries Channel Measurement Facility support | 4 | * Linux on zSeries Channel Measurement Facility support |
5 | * (dasd device driver interface) | 5 | * (dasd device driver interface) |
@@ -23,7 +23,6 @@ | |||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/ioctl32.h> | ||
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | #include <asm/ccwdev.h> | 27 | #include <asm/ccwdev.h> |
29 | #include <asm/cmb.h> | 28 | #include <asm/cmb.h> |
@@ -84,27 +83,13 @@ dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args) | |||
84 | static inline int | 83 | static inline int |
85 | ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler) | 84 | ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler) |
86 | { | 85 | { |
87 | int ret; | 86 | return dasd_ioctl_no_register(THIS_MODULE, no, handler); |
88 | ret = dasd_ioctl_no_register(THIS_MODULE, no, handler); | ||
89 | #ifdef CONFIG_COMPAT | ||
90 | if (ret) | ||
91 | return ret; | ||
92 | |||
93 | ret = register_ioctl32_conversion(no, NULL); | ||
94 | if (ret) | ||
95 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); | ||
96 | #endif | ||
97 | return ret; | ||
98 | } | 87 | } |
99 | 88 | ||
100 | static inline void | 89 | static inline void |
101 | ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler) | 90 | ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler) |
102 | { | 91 | { |
103 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); | 92 | dasd_ioctl_no_unregister(THIS_MODULE, no, handler); |
104 | #ifdef CONFIG_COMPAT | ||
105 | unregister_ioctl32_conversion(no); | ||
106 | #endif | ||
107 | |||
108 | } | 93 | } |
109 | 94 | ||
110 | static void | 95 | static void |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index ad1841a96c87..1aedc48e5f85 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * functions may not be called from interrupt context. In particular | 11 | * functions may not be called from interrupt context. In particular |
12 | * dasd_get_device is a no-no from interrupt context. | 12 | * dasd_get_device is a no-no from interrupt context. |
13 | * | 13 | * |
14 | * $Revision: 1.37 $ | 14 | * $Revision: 1.40 $ |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
@@ -513,14 +513,6 @@ dasd_create_device(struct ccw_device *cdev) | |||
513 | if (!devmap->device) { | 513 | if (!devmap->device) { |
514 | devmap->device = device; | 514 | devmap->device = device; |
515 | device->devindex = devmap->devindex; | 515 | device->devindex = devmap->devindex; |
516 | if (devmap->features & DASD_FEATURE_READONLY) | ||
517 | set_bit(DASD_FLAG_RO, &device->flags); | ||
518 | else | ||
519 | clear_bit(DASD_FLAG_RO, &device->flags); | ||
520 | if (devmap->features & DASD_FEATURE_USEDIAG) | ||
521 | set_bit(DASD_FLAG_USE_DIAG, &device->flags); | ||
522 | else | ||
523 | clear_bit(DASD_FLAG_USE_DIAG, &device->flags); | ||
524 | get_device(&cdev->dev); | 516 | get_device(&cdev->dev); |
525 | device->cdev = cdev; | 517 | device->cdev = cdev; |
526 | rc = 0; | 518 | rc = 0; |
@@ -651,14 +643,8 @@ dasd_ro_store(struct device *dev, const char *buf, size_t count) | |||
651 | devmap->features |= DASD_FEATURE_READONLY; | 643 | devmap->features |= DASD_FEATURE_READONLY; |
652 | else | 644 | else |
653 | devmap->features &= ~DASD_FEATURE_READONLY; | 645 | devmap->features &= ~DASD_FEATURE_READONLY; |
654 | if (devmap->device) { | 646 | if (devmap->device && devmap->device->gdp) |
655 | if (devmap->device->gdp) | 647 | set_disk_ro(devmap->device->gdp, ro_flag); |
656 | set_disk_ro(devmap->device->gdp, ro_flag); | ||
657 | if (ro_flag) | ||
658 | set_bit(DASD_FLAG_RO, &devmap->device->flags); | ||
659 | else | ||
660 | clear_bit(DASD_FLAG_RO, &devmap->device->flags); | ||
661 | } | ||
662 | spin_unlock(&dasd_devmap_lock); | 648 | spin_unlock(&dasd_devmap_lock); |
663 | return count; | 649 | return count; |
664 | } | 650 | } |
@@ -739,6 +725,45 @@ static struct attribute_group dasd_attr_group = { | |||
739 | .attrs = dasd_attrs, | 725 | .attrs = dasd_attrs, |
740 | }; | 726 | }; |
741 | 727 | ||
728 | /* | ||
729 | * Return value of the specified feature. | ||
730 | */ | ||
731 | int | ||
732 | dasd_get_feature(struct ccw_device *cdev, int feature) | ||
733 | { | ||
734 | struct dasd_devmap *devmap; | ||
735 | |||
736 | devmap = dasd_find_busid(cdev->dev.bus_id); | ||
737 | if (IS_ERR(devmap)) | ||
738 | return (int) PTR_ERR(devmap); | ||
739 | |||
740 | return ((devmap->features & feature) != 0); | ||
741 | } | ||
742 | |||
743 | /* | ||
744 | * Set / reset given feature. | ||
745 | * Flag indicates wether to set (!=0) or the reset (=0) the feature. | ||
746 | */ | ||
747 | int | ||
748 | dasd_set_feature(struct ccw_device *cdev, int feature, int flag) | ||
749 | { | ||
750 | struct dasd_devmap *devmap; | ||
751 | |||
752 | devmap = dasd_find_busid(cdev->dev.bus_id); | ||
753 | if (IS_ERR(devmap)) | ||
754 | return (int) PTR_ERR(devmap); | ||
755 | |||
756 | spin_lock(&dasd_devmap_lock); | ||
757 | if (flag) | ||
758 | devmap->features |= feature; | ||
759 | else | ||
760 | devmap->features &= ~feature; | ||
761 | |||
762 | spin_unlock(&dasd_devmap_lock); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | |||
742 | int | 767 | int |
743 | dasd_add_sysfs_files(struct ccw_device *cdev) | 768 | dasd_add_sysfs_files(struct ccw_device *cdev) |
744 | { | 769 | { |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 838aedf78a56..811060e10c00 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
9 | * | 9 | * |
10 | * $Revision: 1.69 $ | 10 | * $Revision: 1.71 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1101,7 +1101,8 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1101 | if (dasd_eckd_cdl_special(blk_per_trk, recid)){ | 1101 | if (dasd_eckd_cdl_special(blk_per_trk, recid)){ |
1102 | rcmd |= 0x8; | 1102 | rcmd |= 0x8; |
1103 | count = dasd_eckd_cdl_reclen(recid); | 1103 | count = dasd_eckd_cdl_reclen(recid); |
1104 | if (count < blksize) | 1104 | if (count < blksize && |
1105 | rq_data_dir(req) == READ) | ||
1105 | memset(dst + count, 0xe5, | 1106 | memset(dst + count, 0xe5, |
1106 | blksize - count); | 1107 | blksize - count); |
1107 | } | 1108 | } |
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 1d52db406b2e..96c49349701f 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * gendisk related functions for the dasd driver. | 10 | * gendisk related functions for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.48 $ | 12 | * $Revision: 1.50 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
@@ -31,12 +31,16 @@ int | |||
31 | dasd_gendisk_alloc(struct dasd_device *device) | 31 | dasd_gendisk_alloc(struct dasd_device *device) |
32 | { | 32 | { |
33 | struct gendisk *gdp; | 33 | struct gendisk *gdp; |
34 | int len; | 34 | int len, feature_ro; |
35 | 35 | ||
36 | /* Make sure the minor for this device exists. */ | 36 | /* Make sure the minor for this device exists. */ |
37 | if (device->devindex >= DASD_PER_MAJOR) | 37 | if (device->devindex >= DASD_PER_MAJOR) |
38 | return -EBUSY; | 38 | return -EBUSY; |
39 | 39 | ||
40 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
41 | if (feature_ro < 0) | ||
42 | return feature_ro; | ||
43 | |||
40 | gdp = alloc_disk(1 << DASD_PARTN_BITS); | 44 | gdp = alloc_disk(1 << DASD_PARTN_BITS); |
41 | if (!gdp) | 45 | if (!gdp) |
42 | return -ENOMEM; | 46 | return -ENOMEM; |
@@ -71,7 +75,7 @@ dasd_gendisk_alloc(struct dasd_device *device) | |||
71 | 75 | ||
72 | sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); | 76 | sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id); |
73 | 77 | ||
74 | if (test_bit(DASD_FLAG_RO, &device->flags)) | 78 | if (feature_ro) |
75 | set_disk_ro(gdp, 1); | 79 | set_disk_ro(gdp, 1); |
76 | gdp->private_data = device; | 80 | gdp->private_data = device; |
77 | gdp->queue = device->request_queue; | 81 | gdp->queue = device->request_queue; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 4586e0ecc526..a9f38b235981 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
8 | * | 8 | * |
9 | * $Revision: 1.63 $ | 9 | * $Revision: 1.64 $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef DASD_INT_H | 12 | #ifndef DASD_INT_H |
@@ -329,8 +329,6 @@ struct dasd_device { | |||
329 | #define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ | 329 | #define DASD_STOPPED_DC_EIO 16 /* disconnected, return -EIO */ |
330 | 330 | ||
331 | /* per device flags */ | 331 | /* per device flags */ |
332 | #define DASD_FLAG_RO 0 /* device is read-only */ | ||
333 | #define DASD_FLAG_USE_DIAG 1 /* use diag disciplnie */ | ||
334 | #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ | 332 | #define DASD_FLAG_DSC_ERROR 2 /* return -EIO when disconnected */ |
335 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ | 333 | #define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ |
336 | 334 | ||
@@ -501,6 +499,9 @@ void dasd_devmap_exit(void); | |||
501 | struct dasd_device *dasd_create_device(struct ccw_device *); | 499 | struct dasd_device *dasd_create_device(struct ccw_device *); |
502 | void dasd_delete_device(struct dasd_device *); | 500 | void dasd_delete_device(struct dasd_device *); |
503 | 501 | ||
502 | int dasd_get_feature(struct ccw_device *, int); | ||
503 | int dasd_set_feature(struct ccw_device *, int, int); | ||
504 | |||
504 | int dasd_add_sysfs_files(struct ccw_device *); | 505 | int dasd_add_sysfs_files(struct ccw_device *); |
505 | void dasd_remove_sysfs_files(struct ccw_device *); | 506 | void dasd_remove_sysfs_files(struct ccw_device *); |
506 | 507 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index f1892baa3b18..980c555aa538 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.45 $ | ||
11 | * | ||
10 | * i/o controls for the dasd driver. | 12 | * i/o controls for the dasd driver. |
11 | */ | 13 | */ |
12 | #include <linux/config.h> | 14 | #include <linux/config.h> |
@@ -294,6 +296,7 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
294 | { | 296 | { |
295 | struct dasd_device *device; | 297 | struct dasd_device *device; |
296 | struct format_data_t fdata; | 298 | struct format_data_t fdata; |
299 | int feature_ro; | ||
297 | 300 | ||
298 | if (!capable(CAP_SYS_ADMIN)) | 301 | if (!capable(CAP_SYS_ADMIN)) |
299 | return -EACCES; | 302 | return -EACCES; |
@@ -304,7 +307,11 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args) | |||
304 | 307 | ||
305 | if (device == NULL) | 308 | if (device == NULL) |
306 | return -ENODEV; | 309 | return -ENODEV; |
307 | if (test_bit(DASD_FLAG_RO, &device->flags)) | 310 | |
311 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
312 | if (feature_ro < 0) | ||
313 | return feature_ro; | ||
314 | if (feature_ro) | ||
308 | return -EROFS; | 315 | return -EROFS; |
309 | if (copy_from_user(&fdata, (void __user *) args, | 316 | if (copy_from_user(&fdata, (void __user *) args, |
310 | sizeof (struct format_data_t))) | 317 | sizeof (struct format_data_t))) |
@@ -377,7 +384,7 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
377 | struct dasd_device *device; | 384 | struct dasd_device *device; |
378 | struct dasd_information2_t *dasd_info; | 385 | struct dasd_information2_t *dasd_info; |
379 | unsigned long flags; | 386 | unsigned long flags; |
380 | int rc; | 387 | int rc, feature_ro; |
381 | struct ccw_device *cdev; | 388 | struct ccw_device *cdev; |
382 | 389 | ||
383 | device = bdev->bd_disk->private_data; | 390 | device = bdev->bd_disk->private_data; |
@@ -387,6 +394,10 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
387 | if (!device->discipline->fill_info) | 394 | if (!device->discipline->fill_info) |
388 | return -EINVAL; | 395 | return -EINVAL; |
389 | 396 | ||
397 | feature_ro = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); | ||
398 | if (feature_ro < 0) | ||
399 | return feature_ro; | ||
400 | |||
390 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); | 401 | dasd_info = kmalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); |
391 | if (dasd_info == NULL) | 402 | if (dasd_info == NULL) |
392 | return -ENOMEM; | 403 | return -ENOMEM; |
@@ -415,9 +426,8 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args) | |||
415 | if ((device->state < DASD_STATE_READY) || | 426 | if ((device->state < DASD_STATE_READY) || |
416 | (dasd_check_blocksize(device->bp_block))) | 427 | (dasd_check_blocksize(device->bp_block))) |
417 | dasd_info->format = DASD_FORMAT_NONE; | 428 | dasd_info->format = DASD_FORMAT_NONE; |
418 | 429 | ||
419 | dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ? | 430 | dasd_info->features |= feature_ro; |
420 | DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT; | ||
421 | 431 | ||
422 | if (device->discipline) | 432 | if (device->discipline) |
423 | memcpy(dasd_info->type, device->discipline->name, 4); | 433 | memcpy(dasd_info->type, device->discipline->name, 4); |
@@ -460,7 +470,7 @@ static int | |||
460 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | 470 | dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) |
461 | { | 471 | { |
462 | struct dasd_device *device; | 472 | struct dasd_device *device; |
463 | int intval; | 473 | int intval, rc; |
464 | 474 | ||
465 | if (!capable(CAP_SYS_ADMIN)) | 475 | if (!capable(CAP_SYS_ADMIN)) |
466 | return -EACCES; | 476 | return -EACCES; |
@@ -472,12 +482,11 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) | |||
472 | device = bdev->bd_disk->private_data; | 482 | device = bdev->bd_disk->private_data; |
473 | if (device == NULL) | 483 | if (device == NULL) |
474 | return -ENODEV; | 484 | return -ENODEV; |
485 | |||
475 | set_disk_ro(bdev->bd_disk, intval); | 486 | set_disk_ro(bdev->bd_disk, intval); |
476 | if (intval) | 487 | rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval); |
477 | set_bit(DASD_FLAG_RO, &device->flags); | 488 | |
478 | else | 489 | return rc; |
479 | clear_bit(DASD_FLAG_RO, &device->flags); | ||
480 | return 0; | ||
481 | } | 490 | } |
482 | 491 | ||
483 | /* | 492 | /* |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 353d41118c62..d7f19745911f 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * /proc interface for the dasd driver. | 10 | * /proc interface for the dasd driver. |
11 | * | 11 | * |
12 | * $Revision: 1.30 $ | 12 | * $Revision: 1.31 $ |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
@@ -54,6 +54,7 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
54 | { | 54 | { |
55 | struct dasd_device *device; | 55 | struct dasd_device *device; |
56 | char *substr; | 56 | char *substr; |
57 | int feature; | ||
57 | 58 | ||
58 | device = dasd_device_from_devindex((unsigned long) v - 1); | 59 | device = dasd_device_from_devindex((unsigned long) v - 1); |
59 | if (IS_ERR(device)) | 60 | if (IS_ERR(device)) |
@@ -77,7 +78,10 @@ dasd_devices_show(struct seq_file *m, void *v) | |||
77 | else | 78 | else |
78 | seq_printf(m, " is ????????"); | 79 | seq_printf(m, " is ????????"); |
79 | /* Print devices features. */ | 80 | /* Print devices features. */ |
80 | substr = test_bit(DASD_FLAG_RO, &device->flags) ? "(ro)" : " "; | 81 | feature = dasd_get_feature(device->cdev, DASD_FEATURE_READONLY); |
82 | if (feature < 0) | ||
83 | return 0; | ||
84 | substr = feature ? "(ro)" : " "; | ||
81 | seq_printf(m, "%4s: ", substr); | 85 | seq_printf(m, "%4s: ", substr); |
82 | /* Print device status information. */ | 86 | /* Print device status information. */ |
83 | switch ((device != NULL) ? device->state : -1) { | 87 | switch ((device != NULL) ? device->state : -1) { |
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 3720e77b465f..83e6a060668e 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c | |||
@@ -45,7 +45,7 @@ s390_register_adapter_interrupt (adapter_int_handler_t handler) | |||
45 | else | 45 | else |
46 | ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); | 46 | ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0); |
47 | if (!ret) | 47 | if (!ret) |
48 | synchronize_kernel(); | 48 | synchronize_sched(); /* Allow interrupts to complete. */ |
49 | 49 | ||
50 | sprintf (dbf_txt, "ret:%d", ret); | 50 | sprintf (dbf_txt, "ret:%d", ret); |
51 | CIO_TRACE_EVENT (4, dbf_txt); | 51 | CIO_TRACE_EVENT (4, dbf_txt); |
@@ -65,7 +65,7 @@ s390_unregister_adapter_interrupt (adapter_int_handler_t handler) | |||
65 | ret = -EINVAL; | 65 | ret = -EINVAL; |
66 | else { | 66 | else { |
67 | adapter_handler = NULL; | 67 | adapter_handler = NULL; |
68 | synchronize_kernel(); | 68 | synchronize_sched(); /* Allow interrupts to complete. */ |
69 | ret = 0; | 69 | ret = 0; |
70 | } | 70 | } |
71 | sprintf (dbf_txt, "ret:%d", ret); | 71 | sprintf (dbf_txt, "ret:%d", ret); |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 99ce5a567982..1d9b3f18d8de 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/cio.c | 2 | * drivers/s390/cio/cio.c |
3 | * S/390 common I/O routines -- low level i/o calls | 3 | * S/390 common I/O routines -- low level i/o calls |
4 | * $Revision: 1.131 $ | 4 | * $Revision: 1.133 $ |
5 | * | 5 | * |
6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -228,7 +228,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ | |||
228 | int | 228 | int |
229 | cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm) | 229 | cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm) |
230 | { | 230 | { |
231 | return cio_start_key(sch, cpa, lpm, default_storage_key); | 231 | return cio_start_key(sch, cpa, lpm, PAGE_DEFAULT_KEY); |
232 | } | 232 | } |
233 | 233 | ||
234 | /* | 234 | /* |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index 11e260e0b9c9..02d01a0de16c 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/device_ops.c | 2 | * drivers/s390/cio/device_ops.c |
3 | * | 3 | * |
4 | * $Revision: 1.55 $ | 4 | * $Revision: 1.56 $ |
5 | * | 5 | * |
6 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, | 6 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, |
7 | * IBM Corporation | 7 | * IBM Corporation |
@@ -128,7 +128,7 @@ ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa, | |||
128 | unsigned long intparm, __u8 lpm, unsigned long flags) | 128 | unsigned long intparm, __u8 lpm, unsigned long flags) |
129 | { | 129 | { |
130 | return ccw_device_start_key(cdev, cpa, intparm, lpm, | 130 | return ccw_device_start_key(cdev, cpa, intparm, lpm, |
131 | default_storage_key, flags); | 131 | PAGE_DEFAULT_KEY, flags); |
132 | } | 132 | } |
133 | 133 | ||
134 | int | 134 | int |
@@ -137,7 +137,7 @@ ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, | |||
137 | int expires) | 137 | int expires) |
138 | { | 138 | { |
139 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, | 139 | return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm, |
140 | default_storage_key, flags, | 140 | PAGE_DEFAULT_KEY, flags, |
141 | expires); | 141 | expires); |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 9ad14db24143..b6daadac4e8b 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -1,7 +1,9 @@ | |||
1 | #ifndef _CIO_QDIO_H | 1 | #ifndef _CIO_QDIO_H |
2 | #define _CIO_QDIO_H | 2 | #define _CIO_QDIO_H |
3 | 3 | ||
4 | #define VERSION_CIO_QDIO_H "$Revision: 1.26 $" | 4 | #include <asm/page.h> |
5 | |||
6 | #define VERSION_CIO_QDIO_H "$Revision: 1.32 $" | ||
5 | 7 | ||
6 | #ifdef CONFIG_QDIO_DEBUG | 8 | #ifdef CONFIG_QDIO_DEBUG |
7 | #define QDIO_VERBOSE_LEVEL 9 | 9 | #define QDIO_VERBOSE_LEVEL 9 |
@@ -42,7 +44,7 @@ | |||
42 | 44 | ||
43 | #define QDIO_Q_LAPS 5 | 45 | #define QDIO_Q_LAPS 5 |
44 | 46 | ||
45 | #define QDIO_STORAGE_KEY 0 | 47 | #define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY |
46 | 48 | ||
47 | #define L2_CACHELINE_SIZE 256 | 49 | #define L2_CACHELINE_SIZE 256 |
48 | #define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) | 50 | #define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) |
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index a98c00c02559..9ec29bb41b28 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -385,8 +385,8 @@ static int z90crypt_release(struct inode *, struct file *); | |||
385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); | 385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); |
386 | static ssize_t z90crypt_write(struct file *, const char __user *, | 386 | static ssize_t z90crypt_write(struct file *, const char __user *, |
387 | size_t, loff_t *); | 387 | size_t, loff_t *); |
388 | static int z90crypt_ioctl(struct inode *, struct file *, | 388 | static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long); |
389 | unsigned int, unsigned long); | 389 | static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long); |
390 | 390 | ||
391 | static void z90crypt_reader_task(unsigned long); | 391 | static void z90crypt_reader_task(unsigned long); |
392 | static void z90crypt_schedule_reader_task(unsigned long); | 392 | static void z90crypt_schedule_reader_task(unsigned long); |
@@ -433,12 +433,15 @@ static atomic_t total_open; | |||
433 | static atomic_t z90crypt_step; | 433 | static atomic_t z90crypt_step; |
434 | 434 | ||
435 | static struct file_operations z90crypt_fops = { | 435 | static struct file_operations z90crypt_fops = { |
436 | .owner = THIS_MODULE, | 436 | .owner = THIS_MODULE, |
437 | .read = z90crypt_read, | 437 | .read = z90crypt_read, |
438 | .write = z90crypt_write, | 438 | .write = z90crypt_write, |
439 | .ioctl = z90crypt_ioctl, | 439 | .unlocked_ioctl = z90crypt_unlocked_ioctl, |
440 | .open = z90crypt_open, | 440 | #ifdef CONFIG_COMPAT |
441 | .release = z90crypt_release | 441 | .compat_ioctl = z90crypt_compat_ioctl, |
442 | #endif | ||
443 | .open = z90crypt_open, | ||
444 | .release = z90crypt_release | ||
442 | }; | 445 | }; |
443 | 446 | ||
444 | #ifndef Z90CRYPT_USE_HOTPLUG | 447 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -474,14 +477,13 @@ struct ica_rsa_modexpo_32 { // For 32-bit callers | |||
474 | compat_uptr_t n_modulus; | 477 | compat_uptr_t n_modulus; |
475 | }; | 478 | }; |
476 | 479 | ||
477 | static int | 480 | static long |
478 | trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | 481 | trans_modexpo32(struct file *filp, unsigned int cmd, unsigned long arg) |
479 | struct file *file) | ||
480 | { | 482 | { |
481 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); | 483 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); |
482 | struct ica_rsa_modexpo_32 mex32k; | 484 | struct ica_rsa_modexpo_32 mex32k; |
483 | struct ica_rsa_modexpo __user *mex64; | 485 | struct ica_rsa_modexpo __user *mex64; |
484 | int ret = 0; | 486 | long ret = 0; |
485 | unsigned int i; | 487 | unsigned int i; |
486 | 488 | ||
487 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) | 489 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) |
@@ -498,7 +500,7 @@ trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
498 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || | 500 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || |
499 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) | 501 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) |
500 | return -EFAULT; | 502 | return -EFAULT; |
501 | ret = sys_ioctl(fd, cmd, (unsigned long)mex64); | 503 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)mex64); |
502 | if (!ret) | 504 | if (!ret) |
503 | if (__get_user(i, &mex64->outputdatalength) || | 505 | if (__get_user(i, &mex64->outputdatalength) || |
504 | __put_user(i, &mex32u->outputdatalength)) | 506 | __put_user(i, &mex32u->outputdatalength)) |
@@ -518,14 +520,13 @@ struct ica_rsa_modexpo_crt_32 { // For 32-bit callers | |||
518 | compat_uptr_t u_mult_inv; | 520 | compat_uptr_t u_mult_inv; |
519 | }; | 521 | }; |
520 | 522 | ||
521 | static int | 523 | static long |
522 | trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | 524 | trans_modexpo_crt32(struct file *filp, unsigned int cmd, unsigned long arg) |
523 | struct file *file) | ||
524 | { | 525 | { |
525 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); | 526 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); |
526 | struct ica_rsa_modexpo_crt_32 crt32k; | 527 | struct ica_rsa_modexpo_crt_32 crt32k; |
527 | struct ica_rsa_modexpo_crt __user *crt64; | 528 | struct ica_rsa_modexpo_crt __user *crt64; |
528 | int ret = 0; | 529 | long ret = 0; |
529 | unsigned int i; | 530 | unsigned int i; |
530 | 531 | ||
531 | if (!access_ok(VERIFY_WRITE, crt32u, | 532 | if (!access_ok(VERIFY_WRITE, crt32u, |
@@ -546,9 +547,8 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
546 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || | 547 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || |
547 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || | 548 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || |
548 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) | 549 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) |
549 | ret = -EFAULT; | 550 | return -EFAULT; |
550 | if (!ret) | 551 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64); |
551 | ret = sys_ioctl(fd, cmd, (unsigned long)crt64); | ||
552 | if (!ret) | 552 | if (!ret) |
553 | if (__get_user(i, &crt64->outputdatalength) || | 553 | if (__get_user(i, &crt64->outputdatalength) || |
554 | __put_user(i, &crt32u->outputdatalength)) | 554 | __put_user(i, &crt32u->outputdatalength)) |
@@ -556,66 +556,34 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
556 | return ret; | 556 | return ret; |
557 | } | 557 | } |
558 | 558 | ||
559 | static int compatible_ioctls[] = { | 559 | static long |
560 | ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT, | 560 | z90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
561 | Z90STAT_PCICCCOUNT, Z90STAT_PCIXCCCOUNT, Z90STAT_PCIXCCMCL2COUNT, | ||
562 | Z90STAT_PCIXCCMCL3COUNT, Z90STAT_CEX2CCOUNT, Z90STAT_REQUESTQ_COUNT, | ||
563 | Z90STAT_PENDINGQ_COUNT, Z90STAT_TOTALOPEN_COUNT, Z90STAT_DOMAIN_INDEX, | ||
564 | Z90STAT_STATUS_MASK, Z90STAT_QDEPTH_MASK, Z90STAT_PERDEV_REQCNT, | ||
565 | }; | ||
566 | |||
567 | static void z90_unregister_ioctl32s(void) | ||
568 | { | ||
569 | int i; | ||
570 | |||
571 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
572 | unregister_ioctl32_conversion(ICARSACRT); | ||
573 | |||
574 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) | ||
575 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
576 | } | ||
577 | |||
578 | static int z90_register_ioctl32s(void) | ||
579 | { | ||
580 | int result, i; | ||
581 | |||
582 | result = register_ioctl32_conversion(ICARSAMODEXPO, trans_modexpo32); | ||
583 | if (result == -EBUSY) { | ||
584 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
585 | result = register_ioctl32_conversion(ICARSAMODEXPO, | ||
586 | trans_modexpo32); | ||
587 | } | ||
588 | if (result) | ||
589 | return result; | ||
590 | result = register_ioctl32_conversion(ICARSACRT, trans_modexpo_crt32); | ||
591 | if (result == -EBUSY) { | ||
592 | unregister_ioctl32_conversion(ICARSACRT); | ||
593 | result = register_ioctl32_conversion(ICARSACRT, | ||
594 | trans_modexpo_crt32); | ||
595 | } | ||
596 | if (result) | ||
597 | return result; | ||
598 | |||
599 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) { | ||
600 | result = register_ioctl32_conversion(compatible_ioctls[i], 0); | ||
601 | if (result == -EBUSY) { | ||
602 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
603 | result = register_ioctl32_conversion( | ||
604 | compatible_ioctls[i], 0); | ||
605 | } | ||
606 | if (result) | ||
607 | return result; | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | #else // !CONFIG_COMPAT | ||
612 | static inline void z90_unregister_ioctl32s(void) | ||
613 | { | ||
614 | } | ||
615 | |||
616 | static inline int z90_register_ioctl32s(void) | ||
617 | { | 561 | { |
618 | return 0; | 562 | switch (cmd) { |
563 | case ICAZ90STATUS: | ||
564 | case Z90QUIESCE: | ||
565 | case Z90STAT_TOTALCOUNT: | ||
566 | case Z90STAT_PCICACOUNT: | ||
567 | case Z90STAT_PCICCCOUNT: | ||
568 | case Z90STAT_PCIXCCCOUNT: | ||
569 | case Z90STAT_PCIXCCMCL2COUNT: | ||
570 | case Z90STAT_PCIXCCMCL3COUNT: | ||
571 | case Z90STAT_CEX2CCOUNT: | ||
572 | case Z90STAT_REQUESTQ_COUNT: | ||
573 | case Z90STAT_PENDINGQ_COUNT: | ||
574 | case Z90STAT_TOTALOPEN_COUNT: | ||
575 | case Z90STAT_DOMAIN_INDEX: | ||
576 | case Z90STAT_STATUS_MASK: | ||
577 | case Z90STAT_QDEPTH_MASK: | ||
578 | case Z90STAT_PERDEV_REQCNT: | ||
579 | return z90crypt_unlocked_ioctl(filp, cmd, arg); | ||
580 | case ICARSAMODEXPO: | ||
581 | return trans_modexpo32(filp, cmd, arg); | ||
582 | case ICARSACRT: | ||
583 | return trans_modexpo_crt32(filp, cmd, arg); | ||
584 | default: | ||
585 | return -ENOIOCTLCMD; | ||
586 | } | ||
619 | } | 587 | } |
620 | #endif | 588 | #endif |
621 | 589 | ||
@@ -730,14 +698,9 @@ z90crypt_init_module(void) | |||
730 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); | 698 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); |
731 | add_timer(&reader_timer); | 699 | add_timer(&reader_timer); |
732 | 700 | ||
733 | if ((result = z90_register_ioctl32s())) | ||
734 | goto init_module_cleanup; | ||
735 | |||
736 | return 0; // success | 701 | return 0; // success |
737 | 702 | ||
738 | init_module_cleanup: | 703 | init_module_cleanup: |
739 | z90_unregister_ioctl32s(); | ||
740 | |||
741 | #ifndef Z90CRYPT_USE_HOTPLUG | 704 | #ifndef Z90CRYPT_USE_HOTPLUG |
742 | if ((nresult = misc_deregister(&z90crypt_misc_device))) | 705 | if ((nresult = misc_deregister(&z90crypt_misc_device))) |
743 | PRINTK("misc_deregister failed with %d.\n", nresult); | 706 | PRINTK("misc_deregister failed with %d.\n", nresult); |
@@ -763,8 +726,6 @@ z90crypt_cleanup_module(void) | |||
763 | 726 | ||
764 | PDEBUG("PID %d\n", PID()); | 727 | PDEBUG("PID %d\n", PID()); |
765 | 728 | ||
766 | z90_unregister_ioctl32s(); | ||
767 | |||
768 | remove_proc_entry("driver/z90crypt", 0); | 729 | remove_proc_entry("driver/z90crypt", 0); |
769 | 730 | ||
770 | #ifndef Z90CRYPT_USE_HOTPLUG | 731 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -800,7 +761,7 @@ z90crypt_cleanup_module(void) | |||
800 | * z90crypt_release | 761 | * z90crypt_release |
801 | * z90crypt_read | 762 | * z90crypt_read |
802 | * z90crypt_write | 763 | * z90crypt_write |
803 | * z90crypt_ioctl | 764 | * z90crypt_unlocked_ioctl |
804 | * z90crypt_status | 765 | * z90crypt_status |
805 | * z90crypt_status_write | 766 | * z90crypt_status_write |
806 | * disable_card | 767 | * disable_card |
@@ -1804,9 +1765,8 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid, | |||
1804 | * This function is a little long, but it's really just one large switch | 1765 | * This function is a little long, but it's really just one large switch |
1805 | * statement. | 1766 | * statement. |
1806 | */ | 1767 | */ |
1807 | static int | 1768 | static long |
1808 | z90crypt_ioctl(struct inode *inode, struct file *filp, | 1769 | z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1809 | unsigned int cmd, unsigned long arg) | ||
1810 | { | 1770 | { |
1811 | struct priv_data *private_data_p = filp->private_data; | 1771 | struct priv_data *private_data_p = filp->private_data; |
1812 | unsigned char *status; | 1772 | unsigned char *status; |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index a3d285859564..1e3f7f3c662f 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -32,7 +32,7 @@ struct smsg_callback { | |||
32 | struct list_head list; | 32 | struct list_head list; |
33 | char *prefix; | 33 | char *prefix; |
34 | int len; | 34 | int len; |
35 | void (*callback)(char *str); | 35 | void (*callback)(char *from, char *str); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | MODULE_AUTHOR | 38 | MODULE_AUTHOR |
@@ -55,8 +55,9 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
55 | { | 55 | { |
56 | struct smsg_callback *cb; | 56 | struct smsg_callback *cb; |
57 | unsigned char *msg; | 57 | unsigned char *msg; |
58 | unsigned char sender[9]; | ||
58 | unsigned short len; | 59 | unsigned short len; |
59 | int rc; | 60 | int rc, i; |
60 | 61 | ||
61 | len = eib->ln1msg2.ipbfln1f; | 62 | len = eib->ln1msg2.ipbfln1f; |
62 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); | 63 | msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); |
@@ -69,10 +70,18 @@ smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) | |||
69 | if (rc == 0) { | 70 | if (rc == 0) { |
70 | msg[len] = 0; | 71 | msg[len] = 0; |
71 | EBCASC(msg, len); | 72 | EBCASC(msg, len); |
73 | memcpy(sender, msg, 8); | ||
74 | sender[8] = 0; | ||
75 | /* Remove trailing whitespace from the sender name. */ | ||
76 | for (i = 7; i >= 0; i--) { | ||
77 | if (sender[i] != ' ' && sender[i] != '\t') | ||
78 | break; | ||
79 | sender[i] = 0; | ||
80 | } | ||
72 | spin_lock(&smsg_list_lock); | 81 | spin_lock(&smsg_list_lock); |
73 | list_for_each_entry(cb, &smsg_list, list) | 82 | list_for_each_entry(cb, &smsg_list, list) |
74 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { | 83 | if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { |
75 | cb->callback(msg + 8); | 84 | cb->callback(sender, msg + 8); |
76 | break; | 85 | break; |
77 | } | 86 | } |
78 | spin_unlock(&smsg_list_lock); | 87 | spin_unlock(&smsg_list_lock); |
@@ -91,7 +100,7 @@ static struct device_driver smsg_driver = { | |||
91 | }; | 100 | }; |
92 | 101 | ||
93 | int | 102 | int |
94 | smsg_register_callback(char *prefix, void (*callback)(char *str)) | 103 | smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) |
95 | { | 104 | { |
96 | struct smsg_callback *cb; | 105 | struct smsg_callback *cb; |
97 | 106 | ||
@@ -108,7 +117,7 @@ smsg_register_callback(char *prefix, void (*callback)(char *str)) | |||
108 | } | 117 | } |
109 | 118 | ||
110 | void | 119 | void |
111 | smsg_unregister_callback(char *prefix, void (*callback)(char *str)) | 120 | smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) |
112 | { | 121 | { |
113 | struct smsg_callback *cb, *tmp; | 122 | struct smsg_callback *cb, *tmp; |
114 | 123 | ||
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h index 04cd87152964..67f5d4f8378d 100644 --- a/drivers/s390/net/smsgiucv.h +++ b/drivers/s390/net/smsgiucv.h | |||
@@ -5,6 +5,6 @@ | |||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | int smsg_register_callback(char *, void (*)(char *)); | 8 | int smsg_register_callback(char *, void (*)(char *, char *)); |
9 | void smsg_unregister_callback(char *, void (*)(char *)); | 9 | void smsg_unregister_callback(char *, void (*)(char *, char *)); |
10 | 10 | ||
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index e70dedb0d0a5..7976947c0322 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c | |||
@@ -137,7 +137,7 @@ static unsigned short pas16_addr = 0; | |||
137 | static int pas16_irq = 0; | 137 | static int pas16_irq = 0; |
138 | 138 | ||
139 | 139 | ||
140 | int scsi_irq_translate[] = | 140 | static const int scsi_irq_translate[] = |
141 | { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; | 141 | { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; |
142 | 142 | ||
143 | /* The default_irqs array contains values used to set the irq into the | 143 | /* The default_irqs array contains values used to set the irq into the |
@@ -145,7 +145,7 @@ int scsi_irq_translate[] = | |||
145 | * irq jumpers on the board). The first value in the array will be | 145 | * irq jumpers on the board). The first value in the array will be |
146 | * assigned to logical board 0, the next to board 1, etc. | 146 | * assigned to logical board 0, the next to board 1, etc. |
147 | */ | 147 | */ |
148 | int default_irqs[] __initdata = | 148 | static int default_irqs[] __initdata = |
149 | { PAS16_DEFAULT_BOARD_1_IRQ, | 149 | { PAS16_DEFAULT_BOARD_1_IRQ, |
150 | PAS16_DEFAULT_BOARD_2_IRQ, | 150 | PAS16_DEFAULT_BOARD_2_IRQ, |
151 | PAS16_DEFAULT_BOARD_3_IRQ, | 151 | PAS16_DEFAULT_BOARD_3_IRQ, |
@@ -177,7 +177,7 @@ static struct base { | |||
177 | 177 | ||
178 | #define NO_BASES (sizeof (bases) / sizeof (struct base)) | 178 | #define NO_BASES (sizeof (bases) / sizeof (struct base)) |
179 | 179 | ||
180 | unsigned short pas16_offset[ 8 ] = | 180 | static const unsigned short pas16_offset[ 8 ] = |
181 | { | 181 | { |
182 | 0x1c00, /* OUTPUT_DATA_REG */ | 182 | 0x1c00, /* OUTPUT_DATA_REG */ |
183 | 0x1c01, /* INITIATOR_COMMAND_REG */ | 183 | 0x1c01, /* INITIATOR_COMMAND_REG */ |
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index a00095cc74c6..97f4d9112b48 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c | |||
@@ -945,7 +945,7 @@ static int ultrastor_abort(Scsi_Cmnd *SCpnt) | |||
945 | config.mscp[mscp_index].SCint, SCpnt); | 945 | config.mscp[mscp_index].SCint, SCpnt); |
946 | #endif | 946 | #endif |
947 | if (config.mscp[mscp_index].SCint == 0) | 947 | if (config.mscp[mscp_index].SCint == 0) |
948 | return FAILURE; | 948 | return FAILED; |
949 | 949 | ||
950 | if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort"); | 950 | if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort"); |
951 | config.mscp[mscp_index].SCint = NULL; | 951 | config.mscp[mscp_index].SCint = NULL; |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 218b69372c0b..0d9358608fdf 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option | 51 | * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option |
52 | * is unsafe when used on edge-triggered interrupts. | 52 | * is unsafe when used on edge-triggered interrupts. |
53 | */ | 53 | */ |
54 | unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 54 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Debugging. | 57 | * Debugging. |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index c682c6308cde..01a8726a3f97 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -321,18 +321,39 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
321 | #define TXTL 2 /* reset default */ | 321 | #define TXTL 2 /* reset default */ |
322 | #define RXTL 1 /* reset default */ | 322 | #define RXTL 1 /* reset default */ |
323 | 323 | ||
324 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | ||
325 | { | ||
326 | unsigned int val; | ||
327 | unsigned int ufcr_rfdiv; | ||
328 | |||
329 | /* set receiver / transmitter trigger level. | ||
330 | * RFDIV is set such way to satisfy requested uartclk value | ||
331 | */ | ||
332 | val = TXTL<<10 | RXTL; | ||
333 | ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; | ||
334 | |||
335 | if(!ufcr_rfdiv) | ||
336 | ufcr_rfdiv = 1; | ||
337 | |||
338 | if(ufcr_rfdiv >= 7) | ||
339 | ufcr_rfdiv = 6; | ||
340 | else | ||
341 | ufcr_rfdiv = 6 - ufcr_rfdiv; | ||
342 | |||
343 | val |= UFCR_RFDIV & (ufcr_rfdiv << 7); | ||
344 | |||
345 | UFCR((u32)sport->port.membase) = val; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
324 | static int imx_startup(struct uart_port *port) | 350 | static int imx_startup(struct uart_port *port) |
325 | { | 351 | { |
326 | struct imx_port *sport = (struct imx_port *)port; | 352 | struct imx_port *sport = (struct imx_port *)port; |
327 | int retval; | 353 | int retval; |
328 | unsigned int val; | ||
329 | unsigned long flags; | 354 | unsigned long flags; |
330 | 355 | ||
331 | /* set receiver / transmitter trigger level. We assume | 356 | imx_setup_ufcr(sport, 0); |
332 | * that RFDIV has been set by the arch setup or by the bootloader. | ||
333 | */ | ||
334 | val = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) | TXTL<<10 | RXTL; | ||
335 | UFCR((u32)sport->port.membase) = val; | ||
336 | 357 | ||
337 | /* disable the DREN bit (Data Ready interrupt enable) before | 358 | /* disable the DREN bit (Data Ready interrupt enable) before |
338 | * requesting IRQs | 359 | * requesting IRQs |
@@ -737,9 +758,12 @@ static void __init | |||
737 | imx_console_get_options(struct imx_port *sport, int *baud, | 758 | imx_console_get_options(struct imx_port *sport, int *baud, |
738 | int *parity, int *bits) | 759 | int *parity, int *bits) |
739 | { | 760 | { |
761 | |||
740 | if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { | 762 | if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { |
741 | /* ok, the port was enabled */ | 763 | /* ok, the port was enabled */ |
742 | unsigned int ucr2, ubir,ubmr, uartclk; | 764 | unsigned int ucr2, ubir,ubmr, uartclk; |
765 | unsigned int baud_raw; | ||
766 | unsigned int ucfr_rfdiv; | ||
743 | 767 | ||
744 | ucr2 = UCR2((u32)sport->port.membase); | 768 | ucr2 = UCR2((u32)sport->port.membase); |
745 | 769 | ||
@@ -758,9 +782,35 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
758 | 782 | ||
759 | ubir = UBIR((u32)sport->port.membase) & 0xffff; | 783 | ubir = UBIR((u32)sport->port.membase) & 0xffff; |
760 | ubmr = UBMR((u32)sport->port.membase) & 0xffff; | 784 | ubmr = UBMR((u32)sport->port.membase) & 0xffff; |
761 | uartclk = sport->port.uartclk; | ||
762 | 785 | ||
763 | *baud = ((uartclk/16) * (ubir + 1)) / (ubmr + 1); | 786 | |
787 | ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7; | ||
788 | if (ucfr_rfdiv == 6) | ||
789 | ucfr_rfdiv = 7; | ||
790 | else | ||
791 | ucfr_rfdiv = 6 - ucfr_rfdiv; | ||
792 | |||
793 | uartclk = imx_get_perclk1(); | ||
794 | uartclk /= ucfr_rfdiv; | ||
795 | |||
796 | { /* | ||
797 | * The next code provides exact computation of | ||
798 | * baud_raw = round(((uartclk/16) * (ubir + 1)) / (ubmr + 1)) | ||
799 | * without need of float support or long long division, | ||
800 | * which would be required to prevent 32bit arithmetic overflow | ||
801 | */ | ||
802 | unsigned int mul = ubir + 1; | ||
803 | unsigned int div = 16 * (ubmr + 1); | ||
804 | unsigned int rem = uartclk % div; | ||
805 | |||
806 | baud_raw = (uartclk / div) * mul; | ||
807 | baud_raw += (rem * mul + div / 2) / div; | ||
808 | *baud = (baud_raw + 50) / 100 * 100; | ||
809 | } | ||
810 | |||
811 | if(*baud != baud_raw) | ||
812 | printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", | ||
813 | baud_raw, *baud); | ||
764 | } | 814 | } |
765 | } | 815 | } |
766 | 816 | ||
@@ -787,6 +837,8 @@ imx_console_setup(struct console *co, char *options) | |||
787 | else | 837 | else |
788 | imx_console_get_options(sport, &baud, &parity, &bits); | 838 | imx_console_get_options(sport, &baud, &parity, &bits); |
789 | 839 | ||
840 | imx_setup_ufcr(sport, 0); | ||
841 | |||
790 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); | 842 | return uart_set_options(&sport->port, co, baud, parity, bits, flow); |
791 | } | 843 | } |
792 | 844 | ||
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index d054f1265701..ba4e13a22a50 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -838,7 +838,7 @@ static int inline port_init(struct ioc4_port *port) | |||
838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; | 838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; |
839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); | 839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); |
840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; | 840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; |
841 | writel(port->ip_rx_cons, &port->ip_serial_regs->srcir); | 841 | writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir); |
842 | 842 | ||
843 | /* Disable interrupts for this 16550 */ | 843 | /* Disable interrupts for this 16550 */ |
844 | uart = port->ip_uart_regs; | 844 | uart = port->ip_uart_regs; |
@@ -1272,8 +1272,9 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1272 | * and set the rx threshold to that amount. There are 4 chars | 1272 | * and set the rx threshold to that amount. There are 4 chars |
1273 | * per ring entry, so we'll divide the number of chars that will | 1273 | * per ring entry, so we'll divide the number of chars that will |
1274 | * arrive in timeout by 4. | 1274 | * arrive in timeout by 4. |
1275 | * So .... timeout * baud / 10 / HZ / 4, with HZ = 100. | ||
1275 | */ | 1276 | */ |
1276 | threshold = timeout * port->ip_baud / 10 / HZ / 4; | 1277 | threshold = timeout * port->ip_baud / 4000; |
1277 | if (threshold == 0) | 1278 | if (threshold == 0) |
1278 | threshold = 1; /* otherwise we'll intr all the time! */ | 1279 | threshold = 1; /* otherwise we'll intr all the time! */ |
1279 | 1280 | ||
@@ -1285,8 +1286,10 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1285 | 1286 | ||
1286 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | 1287 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); |
1287 | 1288 | ||
1288 | /* Now set the rx timeout to the given value */ | 1289 | /* Now set the rx timeout to the given value |
1289 | timeout = timeout * IOC4_SRTR_HZ / HZ; | 1290 | * again timeout * IOC4_SRTR_HZ / HZ |
1291 | */ | ||
1292 | timeout = timeout * IOC4_SRTR_HZ / 100; | ||
1290 | if (timeout > IOC4_SRTR_CNT) | 1293 | if (timeout > IOC4_SRTR_CNT) |
1291 | timeout = IOC4_SRTR_CNT; | 1294 | timeout = IOC4_SRTR_CNT; |
1292 | 1295 | ||
@@ -1380,7 +1383,7 @@ config_port(struct ioc4_port *port, | |||
1380 | if (port->ip_tx_lowat == 0) | 1383 | if (port->ip_tx_lowat == 0) |
1381 | port->ip_tx_lowat = 1; | 1384 | port->ip_tx_lowat = 1; |
1382 | 1385 | ||
1383 | set_rx_timeout(port, port->ip_rx_timeout); | 1386 | set_rx_timeout(port, 2); |
1384 | 1387 | ||
1385 | return 0; | 1388 | return 0; |
1386 | } | 1389 | } |
@@ -1685,8 +1688,8 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1685 | { | 1688 | { |
1686 | struct ioc4_port *port = get_ioc4_port(the_port); | 1689 | struct ioc4_port *port = get_ioc4_port(the_port); |
1687 | int baud, bits; | 1690 | int baud, bits; |
1688 | unsigned cflag, cval; | 1691 | unsigned cflag; |
1689 | int new_parity = 0, new_parity_enable = 0, new_stop = 1, new_data = 8; | 1692 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; |
1690 | struct uart_info *info = the_port->info; | 1693 | struct uart_info *info = the_port->info; |
1691 | 1694 | ||
1692 | cflag = new_termios->c_cflag; | 1695 | cflag = new_termios->c_cflag; |
@@ -1694,48 +1697,35 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1694 | switch (cflag & CSIZE) { | 1697 | switch (cflag & CSIZE) { |
1695 | case CS5: | 1698 | case CS5: |
1696 | new_data = 5; | 1699 | new_data = 5; |
1697 | cval = 0x00; | ||
1698 | bits = 7; | 1700 | bits = 7; |
1699 | break; | 1701 | break; |
1700 | case CS6: | 1702 | case CS6: |
1701 | new_data = 6; | 1703 | new_data = 6; |
1702 | cval = 0x01; | ||
1703 | bits = 8; | 1704 | bits = 8; |
1704 | break; | 1705 | break; |
1705 | case CS7: | 1706 | case CS7: |
1706 | new_data = 7; | 1707 | new_data = 7; |
1707 | cval = 0x02; | ||
1708 | bits = 9; | 1708 | bits = 9; |
1709 | break; | 1709 | break; |
1710 | case CS8: | 1710 | case CS8: |
1711 | new_data = 8; | 1711 | new_data = 8; |
1712 | cval = 0x03; | ||
1713 | bits = 10; | 1712 | bits = 10; |
1714 | break; | 1713 | break; |
1715 | default: | 1714 | default: |
1716 | /* cuz we always need a default ... */ | 1715 | /* cuz we always need a default ... */ |
1717 | new_data = 5; | 1716 | new_data = 5; |
1718 | cval = 0x00; | ||
1719 | bits = 7; | 1717 | bits = 7; |
1720 | break; | 1718 | break; |
1721 | } | 1719 | } |
1722 | if (cflag & CSTOPB) { | 1720 | if (cflag & CSTOPB) { |
1723 | cval |= 0x04; | ||
1724 | bits++; | 1721 | bits++; |
1725 | new_stop = 1; | 1722 | new_stop = 1; |
1726 | } | 1723 | } |
1727 | if (cflag & PARENB) { | 1724 | if (cflag & PARENB) { |
1728 | cval |= UART_LCR_PARITY; | ||
1729 | bits++; | 1725 | bits++; |
1730 | new_parity_enable = 1; | 1726 | new_parity_enable = 1; |
1731 | } | 1727 | if (cflag & PARODD) |
1732 | if (cflag & PARODD) { | 1728 | new_parity = 1; |
1733 | cval |= UART_LCR_EPAR; | ||
1734 | new_parity = 1; | ||
1735 | } | ||
1736 | if (cflag & IGNPAR) { | ||
1737 | cval &= ~UART_LCR_PARITY; | ||
1738 | new_parity_enable = 0; | ||
1739 | } | 1729 | } |
1740 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, | 1730 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, |
1741 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); | 1731 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); |
@@ -1765,10 +1755,15 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1765 | the_port->ignore_status_mask &= ~N_DATA_READY; | 1755 | the_port->ignore_status_mask &= ~N_DATA_READY; |
1766 | } | 1756 | } |
1767 | 1757 | ||
1768 | if (cflag & CRTSCTS) | 1758 | if (cflag & CRTSCTS) { |
1769 | info->flags |= ASYNC_CTS_FLOW; | 1759 | info->flags |= ASYNC_CTS_FLOW; |
1770 | else | 1760 | port->ip_sscr |= IOC4_SSCR_HFC_EN; |
1761 | } | ||
1762 | else { | ||
1771 | info->flags &= ~ASYNC_CTS_FLOW; | 1763 | info->flags &= ~ASYNC_CTS_FLOW; |
1764 | port->ip_sscr &= ~IOC4_SSCR_HFC_EN; | ||
1765 | } | ||
1766 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1772 | 1767 | ||
1773 | /* Set the configuration and proper notification call */ | 1768 | /* Set the configuration and proper notification call */ |
1774 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " | 1769 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " |
@@ -1825,12 +1820,6 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1825 | /* set the speed of the serial port */ | 1820 | /* set the speed of the serial port */ |
1826 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); | 1821 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); |
1827 | 1822 | ||
1828 | /* enable hardware flow control - after ioc4_change_speed because | ||
1829 | * ASYNC_CTS_FLOW is set there */ | ||
1830 | if (info->flags & ASYNC_CTS_FLOW) { | ||
1831 | port->ip_sscr |= IOC4_SSCR_HFC_EN; | ||
1832 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1833 | } | ||
1834 | info->flags |= UIF_INITIALIZED; | 1823 | info->flags |= UIF_INITIALIZED; |
1835 | return 0; | 1824 | return 0; |
1836 | } | 1825 | } |
@@ -1847,7 +1836,6 @@ static void ioc4_cb_output_lowat(struct ioc4_port *port) | |||
1847 | } | 1836 | } |
1848 | } | 1837 | } |
1849 | 1838 | ||
1850 | |||
1851 | /** | 1839 | /** |
1852 | * handle_intr - service any interrupts for the given port - 2nd level | 1840 | * handle_intr - service any interrupts for the given port - 2nd level |
1853 | * called via sd_intr | 1841 | * called via sd_intr |
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index e0717611c940..777829fa3300 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h | |||
@@ -393,7 +393,6 @@ int jsm_tty_init(struct jsm_board *); | |||
393 | int jsm_uart_port_init(struct jsm_board *); | 393 | int jsm_uart_port_init(struct jsm_board *); |
394 | int jsm_remove_uart_port(struct jsm_board *); | 394 | int jsm_remove_uart_port(struct jsm_board *); |
395 | void jsm_input(struct jsm_channel *ch); | 395 | void jsm_input(struct jsm_channel *ch); |
396 | void jsm_carrier(struct jsm_channel *ch); | ||
397 | void jsm_check_queue_flow_control(struct jsm_channel *ch); | 396 | void jsm_check_queue_flow_control(struct jsm_channel *ch); |
398 | 397 | ||
399 | #endif | 398 | #endif |
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 9b79c1ff6c72..3a11a69feb44 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c | |||
@@ -688,7 +688,7 @@ static void neo_flush_uart_read(struct jsm_channel *ch) | |||
688 | /* | 688 | /* |
689 | * No locks are assumed to be held when calling this function. | 689 | * No locks are assumed to be held when calling this function. |
690 | */ | 690 | */ |
691 | void neo_clear_break(struct jsm_channel *ch, int force) | 691 | static void neo_clear_break(struct jsm_channel *ch, int force) |
692 | { | 692 | { |
693 | unsigned long lock_flags; | 693 | unsigned long lock_flags; |
694 | 694 | ||
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 24fe76c28833..98de2258fd06 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -31,6 +31,8 @@ | |||
31 | 31 | ||
32 | #include "jsm.h" | 32 | #include "jsm.h" |
33 | 33 | ||
34 | static void jsm_carrier(struct jsm_channel *ch); | ||
35 | |||
34 | static inline int jsm_get_mstat(struct jsm_channel *ch) | 36 | static inline int jsm_get_mstat(struct jsm_channel *ch) |
35 | { | 37 | { |
36 | unsigned char mstat; | 38 | unsigned char mstat; |
@@ -755,7 +757,7 @@ void jsm_input(struct jsm_channel *ch) | |||
755 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 757 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); |
756 | } | 758 | } |
757 | 759 | ||
758 | void jsm_carrier(struct jsm_channel *ch) | 760 | static void jsm_carrier(struct jsm_channel *ch) |
759 | { | 761 | { |
760 | struct jsm_board *bd; | 762 | struct jsm_board *bd; |
761 | 763 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 9034f9ad37c7..6eeb48f6a482 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -107,6 +107,13 @@ struct serial_info { | |||
107 | int line[4]; | 107 | int line[4]; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | struct serial_cfg_mem { | ||
111 | tuple_t tuple; | ||
112 | cisparse_t parse; | ||
113 | u_char buf[256]; | ||
114 | }; | ||
115 | |||
116 | |||
110 | static void serial_config(dev_link_t * link); | 117 | static void serial_config(dev_link_t * link); |
111 | static int serial_event(event_t event, int priority, | 118 | static int serial_event(event_t event, int priority, |
112 | event_callback_args_t * args); | 119 | event_callback_args_t * args); |
@@ -357,14 +364,24 @@ static int simple_config(dev_link_t *link) | |||
357 | static int size_table[2] = { 8, 16 }; | 364 | static int size_table[2] = { 8, 16 }; |
358 | client_handle_t handle = link->handle; | 365 | client_handle_t handle = link->handle; |
359 | struct serial_info *info = link->priv; | 366 | struct serial_info *info = link->priv; |
360 | tuple_t tuple; | 367 | struct serial_cfg_mem *cfg_mem; |
361 | u_char buf[256]; | 368 | tuple_t *tuple; |
362 | cisparse_t parse; | 369 | u_char *buf; |
363 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 370 | cisparse_t *parse; |
371 | cistpl_cftable_entry_t *cf; | ||
364 | config_info_t config; | 372 | config_info_t config; |
365 | int i, j, try; | 373 | int i, j, try; |
366 | int s; | 374 | int s; |
367 | 375 | ||
376 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); | ||
377 | if (!cfg_mem) | ||
378 | return -1; | ||
379 | |||
380 | tuple = &cfg_mem->tuple; | ||
381 | parse = &cfg_mem->parse; | ||
382 | cf = &parse->cftable_entry; | ||
383 | buf = cfg_mem->buf; | ||
384 | |||
368 | /* If the card is already configured, look up the port and irq */ | 385 | /* If the card is already configured, look up the port and irq */ |
369 | i = pcmcia_get_configuration_info(handle, &config); | 386 | i = pcmcia_get_configuration_info(handle, &config); |
370 | if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { | 387 | if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { |
@@ -377,21 +394,23 @@ static int simple_config(dev_link_t *link) | |||
377 | port = config.BasePort1 + 0x28; | 394 | port = config.BasePort1 + 0x28; |
378 | info->slave = 1; | 395 | info->slave = 1; |
379 | } | 396 | } |
380 | if (info->slave) | 397 | if (info->slave) { |
398 | kfree(cfg_mem); | ||
381 | return setup_serial(handle, info, port, config.AssignedIRQ); | 399 | return setup_serial(handle, info, port, config.AssignedIRQ); |
400 | } | ||
382 | } | 401 | } |
383 | link->conf.Vcc = config.Vcc; | 402 | link->conf.Vcc = config.Vcc; |
384 | 403 | ||
385 | /* First pass: look for a config entry that looks normal. */ | 404 | /* First pass: look for a config entry that looks normal. */ |
386 | tuple.TupleData = (cisdata_t *) buf; | 405 | tuple->TupleData = (cisdata_t *) buf; |
387 | tuple.TupleOffset = 0; | 406 | tuple->TupleOffset = 0; |
388 | tuple.TupleDataMax = 255; | 407 | tuple->TupleDataMax = 255; |
389 | tuple.Attributes = 0; | 408 | tuple->Attributes = 0; |
390 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 409 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
391 | /* Two tries: without IO aliases, then with aliases */ | 410 | /* Two tries: without IO aliases, then with aliases */ |
392 | for (s = 0; s < 2; s++) { | 411 | for (s = 0; s < 2; s++) { |
393 | for (try = 0; try < 2; try++) { | 412 | for (try = 0; try < 2; try++) { |
394 | i = first_tuple(handle, &tuple, &parse); | 413 | i = first_tuple(handle, tuple, parse); |
395 | while (i != CS_NO_MORE_ITEMS) { | 414 | while (i != CS_NO_MORE_ITEMS) { |
396 | if (i != CS_SUCCESS) | 415 | if (i != CS_SUCCESS) |
397 | goto next_entry; | 416 | goto next_entry; |
@@ -409,14 +428,14 @@ static int simple_config(dev_link_t *link) | |||
409 | goto found_port; | 428 | goto found_port; |
410 | } | 429 | } |
411 | next_entry: | 430 | next_entry: |
412 | i = next_tuple(handle, &tuple, &parse); | 431 | i = next_tuple(handle, tuple, parse); |
413 | } | 432 | } |
414 | } | 433 | } |
415 | } | 434 | } |
416 | /* Second pass: try to find an entry that isn't picky about | 435 | /* Second pass: try to find an entry that isn't picky about |
417 | its base address, then try to grab any standard serial port | 436 | its base address, then try to grab any standard serial port |
418 | address, and finally try to get any free port. */ | 437 | address, and finally try to get any free port. */ |
419 | i = first_tuple(handle, &tuple, &parse); | 438 | i = first_tuple(handle, tuple, parse); |
420 | while (i != CS_NO_MORE_ITEMS) { | 439 | while (i != CS_NO_MORE_ITEMS) { |
421 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && | 440 | if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && |
422 | ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 441 | ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { |
@@ -429,7 +448,7 @@ next_entry: | |||
429 | goto found_port; | 448 | goto found_port; |
430 | } | 449 | } |
431 | } | 450 | } |
432 | i = next_tuple(handle, &tuple, &parse); | 451 | i = next_tuple(handle, tuple, parse); |
433 | } | 452 | } |
434 | 453 | ||
435 | found_port: | 454 | found_port: |
@@ -437,6 +456,7 @@ next_entry: | |||
437 | printk(KERN_NOTICE | 456 | printk(KERN_NOTICE |
438 | "serial_cs: no usable port range found, giving up\n"); | 457 | "serial_cs: no usable port range found, giving up\n"); |
439 | cs_error(link->handle, RequestIO, i); | 458 | cs_error(link->handle, RequestIO, i); |
459 | kfree(cfg_mem); | ||
440 | return -1; | 460 | return -1; |
441 | } | 461 | } |
442 | 462 | ||
@@ -450,9 +470,10 @@ next_entry: | |||
450 | i = pcmcia_request_configuration(link->handle, &link->conf); | 470 | i = pcmcia_request_configuration(link->handle, &link->conf); |
451 | if (i != CS_SUCCESS) { | 471 | if (i != CS_SUCCESS) { |
452 | cs_error(link->handle, RequestConfiguration, i); | 472 | cs_error(link->handle, RequestConfiguration, i); |
473 | kfree(cfg_mem); | ||
453 | return -1; | 474 | return -1; |
454 | } | 475 | } |
455 | 476 | kfree(cfg_mem); | |
456 | return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 477 | return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
457 | } | 478 | } |
458 | 479 | ||
@@ -460,29 +481,39 @@ static int multi_config(dev_link_t * link) | |||
460 | { | 481 | { |
461 | client_handle_t handle = link->handle; | 482 | client_handle_t handle = link->handle; |
462 | struct serial_info *info = link->priv; | 483 | struct serial_info *info = link->priv; |
463 | tuple_t tuple; | 484 | struct serial_cfg_mem *cfg_mem; |
464 | u_char buf[256]; | 485 | tuple_t *tuple; |
465 | cisparse_t parse; | 486 | u_char *buf; |
466 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 487 | cisparse_t *parse; |
488 | cistpl_cftable_entry_t *cf; | ||
467 | config_info_t config; | 489 | config_info_t config; |
468 | int i, base2 = 0; | 490 | int i, rc, base2 = 0; |
491 | |||
492 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); | ||
493 | if (!cfg_mem) | ||
494 | return -1; | ||
495 | tuple = &cfg_mem->tuple; | ||
496 | parse = &cfg_mem->parse; | ||
497 | cf = &parse->cftable_entry; | ||
498 | buf = cfg_mem->buf; | ||
469 | 499 | ||
470 | i = pcmcia_get_configuration_info(handle, &config); | 500 | i = pcmcia_get_configuration_info(handle, &config); |
471 | if (i != CS_SUCCESS) { | 501 | if (i != CS_SUCCESS) { |
472 | cs_error(handle, GetConfigurationInfo, i); | 502 | cs_error(handle, GetConfigurationInfo, i); |
473 | return -1; | 503 | rc = -1; |
504 | goto free_cfg_mem; | ||
474 | } | 505 | } |
475 | link->conf.Vcc = config.Vcc; | 506 | link->conf.Vcc = config.Vcc; |
476 | 507 | ||
477 | tuple.TupleData = (cisdata_t *) buf; | 508 | tuple->TupleData = (cisdata_t *) buf; |
478 | tuple.TupleOffset = 0; | 509 | tuple->TupleOffset = 0; |
479 | tuple.TupleDataMax = 255; | 510 | tuple->TupleDataMax = 255; |
480 | tuple.Attributes = 0; | 511 | tuple->Attributes = 0; |
481 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 512 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
482 | 513 | ||
483 | /* First, look for a generic full-sized window */ | 514 | /* First, look for a generic full-sized window */ |
484 | link->io.NumPorts1 = info->multi * 8; | 515 | link->io.NumPorts1 = info->multi * 8; |
485 | i = first_tuple(handle, &tuple, &parse); | 516 | i = first_tuple(handle, tuple, parse); |
486 | while (i != CS_NO_MORE_ITEMS) { | 517 | while (i != CS_NO_MORE_ITEMS) { |
487 | /* The quad port cards have bad CIS's, so just look for a | 518 | /* The quad port cards have bad CIS's, so just look for a |
488 | window larger than 8 ports and assume it will be right */ | 519 | window larger than 8 ports and assume it will be right */ |
@@ -497,14 +528,14 @@ static int multi_config(dev_link_t * link) | |||
497 | if (i == CS_SUCCESS) | 528 | if (i == CS_SUCCESS) |
498 | break; | 529 | break; |
499 | } | 530 | } |
500 | i = next_tuple(handle, &tuple, &parse); | 531 | i = next_tuple(handle, tuple, parse); |
501 | } | 532 | } |
502 | 533 | ||
503 | /* If that didn't work, look for two windows */ | 534 | /* If that didn't work, look for two windows */ |
504 | if (i != CS_SUCCESS) { | 535 | if (i != CS_SUCCESS) { |
505 | link->io.NumPorts1 = link->io.NumPorts2 = 8; | 536 | link->io.NumPorts1 = link->io.NumPorts2 = 8; |
506 | info->multi = 2; | 537 | info->multi = 2; |
507 | i = first_tuple(handle, &tuple, &parse); | 538 | i = first_tuple(handle, tuple, parse); |
508 | while (i != CS_NO_MORE_ITEMS) { | 539 | while (i != CS_NO_MORE_ITEMS) { |
509 | if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { | 540 | if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { |
510 | link->conf.ConfigIndex = cf->index; | 541 | link->conf.ConfigIndex = cf->index; |
@@ -517,13 +548,14 @@ static int multi_config(dev_link_t * link) | |||
517 | if (i == CS_SUCCESS) | 548 | if (i == CS_SUCCESS) |
518 | break; | 549 | break; |
519 | } | 550 | } |
520 | i = next_tuple(handle, &tuple, &parse); | 551 | i = next_tuple(handle, tuple, parse); |
521 | } | 552 | } |
522 | } | 553 | } |
523 | 554 | ||
524 | if (i != CS_SUCCESS) { | 555 | if (i != CS_SUCCESS) { |
525 | cs_error(link->handle, RequestIO, i); | 556 | cs_error(link->handle, RequestIO, i); |
526 | return -1; | 557 | rc = -1; |
558 | goto free_cfg_mem; | ||
527 | } | 559 | } |
528 | 560 | ||
529 | i = pcmcia_request_irq(link->handle, &link->irq); | 561 | i = pcmcia_request_irq(link->handle, &link->irq); |
@@ -541,7 +573,8 @@ static int multi_config(dev_link_t * link) | |||
541 | i = pcmcia_request_configuration(link->handle, &link->conf); | 573 | i = pcmcia_request_configuration(link->handle, &link->conf); |
542 | if (i != CS_SUCCESS) { | 574 | if (i != CS_SUCCESS) { |
543 | cs_error(link->handle, RequestConfiguration, i); | 575 | cs_error(link->handle, RequestConfiguration, i); |
544 | return -1; | 576 | rc = -1; |
577 | goto free_cfg_mem; | ||
545 | } | 578 | } |
546 | 579 | ||
547 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: | 580 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: |
@@ -554,17 +587,23 @@ static int multi_config(dev_link_t * link) | |||
554 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 587 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
555 | outb(12, base2 + 1); | 588 | outb(12, base2 + 1); |
556 | } | 589 | } |
557 | return 0; | 590 | rc = 0; |
591 | goto free_cfg_mem; | ||
558 | } | 592 | } |
559 | 593 | ||
560 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); | 594 | setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); |
561 | /* The Nokia cards are not really multiport cards */ | 595 | /* The Nokia cards are not really multiport cards */ |
562 | if (info->manfid == MANFID_NOKIA) | 596 | if (info->manfid == MANFID_NOKIA) { |
563 | return 0; | 597 | rc = 0; |
598 | goto free_cfg_mem; | ||
599 | } | ||
564 | for (i = 0; i < info->multi - 1; i++) | 600 | for (i = 0; i < info->multi - 1; i++) |
565 | setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ); | 601 | setup_serial(handle, info, base2 + (8 * i), |
566 | 602 | link->irq.AssignedIRQ); | |
567 | return 0; | 603 | rc = 0; |
604 | free_cfg_mem: | ||
605 | kfree(cfg_mem); | ||
606 | return rc; | ||
568 | } | 607 | } |
569 | 608 | ||
570 | /*====================================================================== | 609 | /*====================================================================== |
@@ -579,39 +618,49 @@ void serial_config(dev_link_t * link) | |||
579 | { | 618 | { |
580 | client_handle_t handle = link->handle; | 619 | client_handle_t handle = link->handle; |
581 | struct serial_info *info = link->priv; | 620 | struct serial_info *info = link->priv; |
582 | tuple_t tuple; | 621 | struct serial_cfg_mem *cfg_mem; |
583 | u_short buf[128]; | 622 | tuple_t *tuple; |
584 | cisparse_t parse; | 623 | u_char *buf; |
585 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 624 | cisparse_t *parse; |
625 | cistpl_cftable_entry_t *cf; | ||
586 | int i, last_ret, last_fn; | 626 | int i, last_ret, last_fn; |
587 | 627 | ||
588 | DEBUG(0, "serial_config(0x%p)\n", link); | 628 | DEBUG(0, "serial_config(0x%p)\n", link); |
589 | 629 | ||
590 | tuple.TupleData = (cisdata_t *) buf; | 630 | cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); |
591 | tuple.TupleOffset = 0; | 631 | if (!cfg_mem) |
592 | tuple.TupleDataMax = 255; | 632 | goto failed; |
593 | tuple.Attributes = 0; | 633 | |
634 | tuple = &cfg_mem->tuple; | ||
635 | parse = &cfg_mem->parse; | ||
636 | cf = &parse->cftable_entry; | ||
637 | buf = cfg_mem->buf; | ||
638 | |||
639 | tuple->TupleData = (cisdata_t *) buf; | ||
640 | tuple->TupleOffset = 0; | ||
641 | tuple->TupleDataMax = 255; | ||
642 | tuple->Attributes = 0; | ||
594 | /* Get configuration register information */ | 643 | /* Get configuration register information */ |
595 | tuple.DesiredTuple = CISTPL_CONFIG; | 644 | tuple->DesiredTuple = CISTPL_CONFIG; |
596 | last_ret = first_tuple(handle, &tuple, &parse); | 645 | last_ret = first_tuple(handle, tuple, parse); |
597 | if (last_ret != CS_SUCCESS) { | 646 | if (last_ret != CS_SUCCESS) { |
598 | last_fn = ParseTuple; | 647 | last_fn = ParseTuple; |
599 | goto cs_failed; | 648 | goto cs_failed; |
600 | } | 649 | } |
601 | link->conf.ConfigBase = parse.config.base; | 650 | link->conf.ConfigBase = parse->config.base; |
602 | link->conf.Present = parse.config.rmask[0]; | 651 | link->conf.Present = parse->config.rmask[0]; |
603 | 652 | ||
604 | /* Configure card */ | 653 | /* Configure card */ |
605 | link->state |= DEV_CONFIG; | 654 | link->state |= DEV_CONFIG; |
606 | 655 | ||
607 | /* Is this a compliant multifunction card? */ | 656 | /* Is this a compliant multifunction card? */ |
608 | tuple.DesiredTuple = CISTPL_LONGLINK_MFC; | 657 | tuple->DesiredTuple = CISTPL_LONGLINK_MFC; |
609 | tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; | 658 | tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; |
610 | info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS); | 659 | info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); |
611 | 660 | ||
612 | /* Is this a multiport card? */ | 661 | /* Is this a multiport card? */ |
613 | tuple.DesiredTuple = CISTPL_MANFID; | 662 | tuple->DesiredTuple = CISTPL_MANFID; |
614 | if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { | 663 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { |
615 | info->manfid = le16_to_cpu(buf[0]); | 664 | info->manfid = le16_to_cpu(buf[0]); |
616 | for (i = 0; i < MULTI_COUNT; i++) | 665 | for (i = 0; i < MULTI_COUNT; i++) |
617 | if ((info->manfid == multi_id[i].manfid) && | 666 | if ((info->manfid == multi_id[i].manfid) && |
@@ -623,13 +672,13 @@ void serial_config(dev_link_t * link) | |||
623 | 672 | ||
624 | /* Another check for dual-serial cards: look for either serial or | 673 | /* Another check for dual-serial cards: look for either serial or |
625 | multifunction cards that ask for appropriate IO port ranges */ | 674 | multifunction cards that ask for appropriate IO port ranges */ |
626 | tuple.DesiredTuple = CISTPL_FUNCID; | 675 | tuple->DesiredTuple = CISTPL_FUNCID; |
627 | if ((info->multi == 0) && | 676 | if ((info->multi == 0) && |
628 | ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) || | 677 | ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || |
629 | (parse.funcid.func == CISTPL_FUNCID_MULTI) || | 678 | (parse->funcid.func == CISTPL_FUNCID_MULTI) || |
630 | (parse.funcid.func == CISTPL_FUNCID_SERIAL))) { | 679 | (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { |
631 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 680 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
632 | if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { | 681 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { |
633 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) | 682 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) |
634 | info->multi = cf->io.win[0].len >> 3; | 683 | info->multi = cf->io.win[0].len >> 3; |
635 | if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && | 684 | if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && |
@@ -664,6 +713,7 @@ void serial_config(dev_link_t * link) | |||
664 | 713 | ||
665 | link->dev = &info->node[0]; | 714 | link->dev = &info->node[0]; |
666 | link->state &= ~DEV_CONFIG_PENDING; | 715 | link->state &= ~DEV_CONFIG_PENDING; |
716 | kfree(cfg_mem); | ||
667 | return; | 717 | return; |
668 | 718 | ||
669 | cs_failed: | 719 | cs_failed: |
@@ -671,6 +721,7 @@ void serial_config(dev_link_t * link) | |||
671 | failed: | 721 | failed: |
672 | serial_remove(link); | 722 | serial_remove(link); |
673 | link->state &= ~DEV_CONFIG_PENDING; | 723 | link->state &= ~DEV_CONFIG_PENDING; |
724 | kfree(cfg_mem); | ||
674 | } | 725 | } |
675 | 726 | ||
676 | /*====================================================================== | 727 | /*====================================================================== |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index ffaab9b90fd8..fee6418e84c4 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -787,7 +787,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port) | |||
787 | 787 | ||
788 | static void sn_sal_console_write(struct console *, const char *, unsigned); | 788 | static void sn_sal_console_write(struct console *, const char *, unsigned); |
789 | static int __init sn_sal_console_setup(struct console *, char *); | 789 | static int __init sn_sal_console_setup(struct console *, char *); |
790 | extern struct uart_driver sal_console_uart; | 790 | static struct uart_driver sal_console_uart; |
791 | extern struct tty_driver *uart_console_device(struct console *, int *); | 791 | extern struct tty_driver *uart_console_device(struct console *, int *); |
792 | 792 | ||
793 | static struct console sal_console = { | 793 | static struct console sal_console = { |
@@ -801,7 +801,7 @@ static struct console sal_console = { | |||
801 | 801 | ||
802 | #define SAL_CONSOLE &sal_console | 802 | #define SAL_CONSOLE &sal_console |
803 | 803 | ||
804 | struct uart_driver sal_console_uart = { | 804 | static struct uart_driver sal_console_uart = { |
805 | .owner = THIS_MODULE, | 805 | .owner = THIS_MODULE, |
806 | .driver_name = "sn_console", | 806 | .driver_name = "sn_console", |
807 | .dev_name = DEVICE_NAME, | 807 | .dev_name = DEVICE_NAME, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2a1c5965de22..6be8fbec0a0e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -198,6 +198,14 @@ config FB_SA1100 | |||
198 | If you plan to use the LCD display with your SA-1100 system, say | 198 | If you plan to use the LCD display with your SA-1100 system, say |
199 | Y here. | 199 | Y here. |
200 | 200 | ||
201 | config FB_IMX | ||
202 | tristate "Motorola i.MX LCD support" | ||
203 | depends on FB && ARM && ARCH_IMX | ||
204 | select FB_CFB_FILLRECT | ||
205 | select FB_CFB_COPYAREA | ||
206 | select FB_CFB_IMAGEBLIT | ||
207 | select FB_SOFT_CURSOR | ||
208 | |||
201 | config FB_CYBER2000 | 209 | config FB_CYBER2000 |
202 | tristate "CyberPro 2000/2010/5000 support" | 210 | tristate "CyberPro 2000/2010/5000 support" |
203 | depends on FB && PCI && (BROKEN || !SPARC64) | 211 | depends on FB && PCI && (BROKEN || !SPARC64) |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 92265b741dc3..bd8dc0ffe723 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -90,6 +90,7 @@ obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o | |||
90 | obj-$(CONFIG_FB_MAXINE) += maxinefb.o | 90 | obj-$(CONFIG_FB_MAXINE) += maxinefb.o |
91 | obj-$(CONFIG_FB_TX3912) += tx3912fb.o | 91 | obj-$(CONFIG_FB_TX3912) += tx3912fb.o |
92 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o | 92 | obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o |
93 | obj-$(CONFIG_FB_IMX) += imxfb.o | ||
93 | 94 | ||
94 | # Platform or fallback drivers go here | 95 | # Platform or fallback drivers go here |
95 | obj-$(CONFIG_FB_VESA) += vesafb.o | 96 | obj-$(CONFIG_FB_VESA) += vesafb.o |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index 3e386fd4c5c6..321dbe91dc14 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -134,16 +134,16 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) | |||
134 | break; | 134 | break; |
135 | case 16: | 135 | case 16: |
136 | var->red.length = 5; | 136 | var->red.length = 5; |
137 | var->green.length = 5; | 137 | var->green.length = 6; |
138 | var->blue.length = 5; | 138 | var->blue.length = 5; |
139 | if (fb->panel->cntl & CNTL_BGR) { | 139 | if (fb->panel->cntl & CNTL_BGR) { |
140 | var->red.offset = 10; | 140 | var->red.offset = 11; |
141 | var->green.offset = 5; | 141 | var->green.offset = 5; |
142 | var->blue.offset = 0; | 142 | var->blue.offset = 0; |
143 | } else { | 143 | } else { |
144 | var->red.offset = 0; | 144 | var->red.offset = 0; |
145 | var->green.offset = 5; | 145 | var->green.offset = 5; |
146 | var->blue.offset = 10; | 146 | var->blue.offset = 11; |
147 | } | 147 | } |
148 | break; | 148 | break; |
149 | case 32: | 149 | case 32: |
@@ -256,7 +256,7 @@ clcdfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, | |||
256 | convert_bitfield(green, &fb->fb.var.green) | | 256 | convert_bitfield(green, &fb->fb.var.green) | |
257 | convert_bitfield(red, &fb->fb.var.red); | 257 | convert_bitfield(red, &fb->fb.var.red); |
258 | 258 | ||
259 | if (fb->fb.var.bits_per_pixel == 8 && regno < 256) { | 259 | if (fb->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR && regno < 256) { |
260 | int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); | 260 | int hw_reg = CLCD_PALETTE + ((regno * 2) & ~3); |
261 | u32 val, mask, newval; | 261 | u32 val, mask, newval; |
262 | 262 | ||
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index e8eb124754b1..ee25b9e8db60 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -1057,13 +1057,14 @@ static int radeonfb_blank (int blank, struct fb_info *info) | |||
1057 | return radeon_screen_blank(rinfo, blank, 0); | 1057 | return radeon_screen_blank(rinfo, blank, 0); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | 1060 | static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, |
1061 | unsigned blue, unsigned transp, struct fb_info *info) | 1061 | unsigned blue, unsigned transp, |
1062 | struct radeonfb_info *rinfo) | ||
1062 | { | 1063 | { |
1063 | struct radeonfb_info *rinfo = info->par; | ||
1064 | u32 pindex; | 1064 | u32 pindex; |
1065 | unsigned int i; | 1065 | unsigned int i; |
1066 | 1066 | ||
1067 | |||
1067 | if (regno > 255) | 1068 | if (regno > 255) |
1068 | return 1; | 1069 | return 1; |
1069 | 1070 | ||
@@ -1078,20 +1079,7 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1078 | pindex = regno; | 1079 | pindex = regno; |
1079 | 1080 | ||
1080 | if (!rinfo->asleep) { | 1081 | if (!rinfo->asleep) { |
1081 | u32 dac_cntl2, vclk_cntl = 0; | ||
1082 | |||
1083 | radeon_fifo_wait(9); | 1082 | radeon_fifo_wait(9); |
1084 | if (rinfo->is_mobility) { | ||
1085 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1086 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1087 | } | ||
1088 | |||
1089 | /* Make sure we are on first palette */ | ||
1090 | if (rinfo->has_CRTC2) { | ||
1091 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1092 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1093 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1094 | } | ||
1095 | 1083 | ||
1096 | if (rinfo->bpp == 16) { | 1084 | if (rinfo->bpp == 16) { |
1097 | pindex = regno * 8; | 1085 | pindex = regno * 8; |
@@ -1101,24 +1089,27 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1101 | if (rinfo->depth == 15 && regno > 31) | 1089 | if (rinfo->depth == 15 && regno > 31) |
1102 | return 1; | 1090 | return 1; |
1103 | 1091 | ||
1104 | /* For 565, the green component is mixed one order below */ | 1092 | /* For 565, the green component is mixed one order |
1093 | * below | ||
1094 | */ | ||
1105 | if (rinfo->depth == 16) { | 1095 | if (rinfo->depth == 16) { |
1106 | OUTREG(PALETTE_INDEX, pindex>>1); | 1096 | OUTREG(PALETTE_INDEX, pindex>>1); |
1107 | OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) | | 1097 | OUTREG(PALETTE_DATA, |
1108 | (green << 8) | (rinfo->palette[regno>>1].blue)); | 1098 | (rinfo->palette[regno>>1].red << 16) | |
1099 | (green << 8) | | ||
1100 | (rinfo->palette[regno>>1].blue)); | ||
1109 | green = rinfo->palette[regno<<1].green; | 1101 | green = rinfo->palette[regno<<1].green; |
1110 | } | 1102 | } |
1111 | } | 1103 | } |
1112 | 1104 | ||
1113 | if (rinfo->depth != 16 || regno < 32) { | 1105 | if (rinfo->depth != 16 || regno < 32) { |
1114 | OUTREG(PALETTE_INDEX, pindex); | 1106 | OUTREG(PALETTE_INDEX, pindex); |
1115 | OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue); | 1107 | OUTREG(PALETTE_DATA, (red << 16) | |
1108 | (green << 8) | blue); | ||
1116 | } | 1109 | } |
1117 | if (rinfo->is_mobility) | ||
1118 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1119 | } | 1110 | } |
1120 | if (regno < 16) { | 1111 | if (regno < 16) { |
1121 | u32 *pal = info->pseudo_palette; | 1112 | u32 *pal = rinfo->info->pseudo_palette; |
1122 | switch (rinfo->depth) { | 1113 | switch (rinfo->depth) { |
1123 | case 15: | 1114 | case 15: |
1124 | pal[regno] = (regno << 10) | (regno << 5) | regno; | 1115 | pal[regno] = (regno << 10) | (regno << 5) | regno; |
@@ -1138,6 +1129,84 @@ static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | |||
1138 | return 0; | 1129 | return 0; |
1139 | } | 1130 | } |
1140 | 1131 | ||
1132 | static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green, | ||
1133 | unsigned blue, unsigned transp, | ||
1134 | struct fb_info *info) | ||
1135 | { | ||
1136 | struct radeonfb_info *rinfo = info->par; | ||
1137 | u32 dac_cntl2, vclk_cntl = 0; | ||
1138 | int rc; | ||
1139 | |||
1140 | if (!rinfo->asleep) { | ||
1141 | if (rinfo->is_mobility) { | ||
1142 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1143 | OUTPLL(VCLK_ECP_CNTL, | ||
1144 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1145 | } | ||
1146 | |||
1147 | /* Make sure we are on first palette */ | ||
1148 | if (rinfo->has_CRTC2) { | ||
1149 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1150 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1151 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | rc = radeon_setcolreg (regno, red, green, blue, transp, rinfo); | ||
1156 | |||
1157 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1158 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1159 | |||
1160 | return rc; | ||
1161 | } | ||
1162 | |||
1163 | static int radeonfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
1164 | { | ||
1165 | struct radeonfb_info *rinfo = info->par; | ||
1166 | u16 *red, *green, *blue, *transp; | ||
1167 | u32 dac_cntl2, vclk_cntl = 0; | ||
1168 | int i, start, rc = 0; | ||
1169 | |||
1170 | if (!rinfo->asleep) { | ||
1171 | if (rinfo->is_mobility) { | ||
1172 | vclk_cntl = INPLL(VCLK_ECP_CNTL); | ||
1173 | OUTPLL(VCLK_ECP_CNTL, | ||
1174 | vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); | ||
1175 | } | ||
1176 | |||
1177 | /* Make sure we are on first palette */ | ||
1178 | if (rinfo->has_CRTC2) { | ||
1179 | dac_cntl2 = INREG(DAC_CNTL2); | ||
1180 | dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL; | ||
1181 | OUTREG(DAC_CNTL2, dac_cntl2); | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | red = cmap->red; | ||
1186 | green = cmap->green; | ||
1187 | blue = cmap->blue; | ||
1188 | transp = cmap->transp; | ||
1189 | start = cmap->start; | ||
1190 | |||
1191 | for (i = 0; i < cmap->len; i++) { | ||
1192 | u_int hred, hgreen, hblue, htransp = 0xffff; | ||
1193 | |||
1194 | hred = *red++; | ||
1195 | hgreen = *green++; | ||
1196 | hblue = *blue++; | ||
1197 | if (transp) | ||
1198 | htransp = *transp++; | ||
1199 | rc = radeon_setcolreg (start++, hred, hgreen, hblue, htransp, | ||
1200 | rinfo); | ||
1201 | if (rc) | ||
1202 | break; | ||
1203 | } | ||
1204 | |||
1205 | if (!rinfo->asleep && rinfo->is_mobility) | ||
1206 | OUTPLL(VCLK_ECP_CNTL, vclk_cntl); | ||
1207 | |||
1208 | return rc; | ||
1209 | } | ||
1141 | 1210 | ||
1142 | static void radeon_save_state (struct radeonfb_info *rinfo, | 1211 | static void radeon_save_state (struct radeonfb_info *rinfo, |
1143 | struct radeon_regs *save) | 1212 | struct radeon_regs *save) |
@@ -1796,6 +1865,7 @@ static struct fb_ops radeonfb_ops = { | |||
1796 | .fb_check_var = radeonfb_check_var, | 1865 | .fb_check_var = radeonfb_check_var, |
1797 | .fb_set_par = radeonfb_set_par, | 1866 | .fb_set_par = radeonfb_set_par, |
1798 | .fb_setcolreg = radeonfb_setcolreg, | 1867 | .fb_setcolreg = radeonfb_setcolreg, |
1868 | .fb_setcmap = radeonfb_setcmap, | ||
1799 | .fb_pan_display = radeonfb_pan_display, | 1869 | .fb_pan_display = radeonfb_pan_display, |
1800 | .fb_blank = radeonfb_blank, | 1870 | .fb_blank = radeonfb_blank, |
1801 | .fb_ioctl = radeonfb_ioctl, | 1871 | .fb_ioctl = radeonfb_ioctl, |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 59e3b4b4e7e3..b209adbd508a 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -906,10 +906,13 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
906 | struct vc_data *svc = *default_mode; | 906 | struct vc_data *svc = *default_mode; |
907 | struct display *t, *p = &fb_display[vc->vc_num]; | 907 | struct display *t, *p = &fb_display[vc->vc_num]; |
908 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; | 908 | int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; |
909 | int cap = info->flags; | 909 | int cap; |
910 | 910 | ||
911 | if (info_idx == -1 || info == NULL) | 911 | if (info_idx == -1 || info == NULL) |
912 | return; | 912 | return; |
913 | |||
914 | cap = info->flags; | ||
915 | |||
913 | if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || | 916 | if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || |
914 | (info->fix.type == FB_TYPE_TEXT)) | 917 | (info->fix.type == FB_TYPE_TEXT)) |
915 | logo = 0; | 918 | logo = 0; |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 7d1ae06667c6..bcf59b28a14f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -337,6 +337,8 @@ static void vgacon_init(struct vc_data *c, int init) | |||
337 | c->vc_scan_lines = vga_scan_lines; | 337 | c->vc_scan_lines = vga_scan_lines; |
338 | c->vc_font.height = vga_video_font_height; | 338 | c->vc_font.height = vga_video_font_height; |
339 | c->vc_complement_mask = 0x7700; | 339 | c->vc_complement_mask = 0x7700; |
340 | if (vga_512_chars) | ||
341 | c->vc_hi_font_mask = 0x0800; | ||
340 | p = *c->vc_uni_pagedir_loc; | 342 | p = *c->vc_uni_pagedir_loc; |
341 | if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || | 343 | if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || |
342 | !--c->vc_uni_pagedir_loc[1]) | 344 | !--c->vc_uni_pagedir_loc[1]) |
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index c51f8fb5c1de..4e5ce8f7d65e 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c | |||
@@ -222,8 +222,11 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) | |||
222 | transp = cmap->transp; | 222 | transp = cmap->transp; |
223 | start = cmap->start; | 223 | start = cmap->start; |
224 | 224 | ||
225 | if (start < 0 || !info->fbops->fb_setcolreg) | 225 | if (start < 0 || (!info->fbops->fb_setcolreg && |
226 | !info->fbops->fb_setcmap)) | ||
226 | return -EINVAL; | 227 | return -EINVAL; |
228 | if (info->fbops->fb_setcmap) | ||
229 | return info->fbops->fb_setcmap(cmap, info); | ||
227 | for (i = 0; i < cmap->len; i++) { | 230 | for (i = 0; i < cmap->len; i++) { |
228 | hred = *red++; | 231 | hred = *red++; |
229 | hgreen = *green++; | 232 | hgreen = *green++; |
@@ -250,8 +253,33 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
250 | transp = cmap->transp; | 253 | transp = cmap->transp; |
251 | start = cmap->start; | 254 | start = cmap->start; |
252 | 255 | ||
253 | if (start < 0 || !info->fbops->fb_setcolreg) | 256 | if (start < 0 || (!info->fbops->fb_setcolreg && |
257 | !info->fbops->fb_setcmap)) | ||
254 | return -EINVAL; | 258 | return -EINVAL; |
259 | |||
260 | /* If we can batch, do it */ | ||
261 | if (info->fbops->fb_setcmap && cmap->len > 1) { | ||
262 | struct fb_cmap umap; | ||
263 | int size = cmap->len * sizeof(u16); | ||
264 | int rc; | ||
265 | |||
266 | memset(&umap, 0, sizeof(struct fb_cmap)); | ||
267 | rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL); | ||
268 | if (rc) | ||
269 | return rc; | ||
270 | if (copy_from_user(umap.red, red, size) || | ||
271 | copy_from_user(umap.green, green, size) || | ||
272 | copy_from_user(umap.blue, blue, size) || | ||
273 | (transp && copy_from_user(umap.transp, transp, size))) { | ||
274 | rc = -EFAULT; | ||
275 | } | ||
276 | umap.start = start; | ||
277 | if (rc == 0) | ||
278 | rc = info->fbops->fb_setcmap(&umap, info); | ||
279 | fb_dealloc_cmap(&umap); | ||
280 | return rc; | ||
281 | } | ||
282 | |||
255 | for (i = 0; i < cmap->len; i++, red++, blue++, green++) { | 283 | for (i = 0; i < cmap->len; i++, red++, blue++, green++) { |
256 | if (get_user(hred, red) || | 284 | if (get_user(hred, red) || |
257 | get_user(hgreen, green) || | 285 | get_user(hgreen, green) || |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 25f460ca0daf..208a68ceb63b 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1257,6 +1257,8 @@ int fb_new_modelist(struct fb_info *info) | |||
1257 | static char *video_options[FB_MAX]; | 1257 | static char *video_options[FB_MAX]; |
1258 | static int ofonly; | 1258 | static int ofonly; |
1259 | 1259 | ||
1260 | extern const char *global_mode_option; | ||
1261 | |||
1260 | /** | 1262 | /** |
1261 | * fb_get_options - get kernel boot parameters | 1263 | * fb_get_options - get kernel boot parameters |
1262 | * @name: framebuffer name as it would appear in | 1264 | * @name: framebuffer name as it would appear in |
@@ -1297,9 +1299,6 @@ int fb_get_options(char *name, char **option) | |||
1297 | return retval; | 1299 | return retval; |
1298 | } | 1300 | } |
1299 | 1301 | ||
1300 | |||
1301 | extern const char *global_mode_option; | ||
1302 | |||
1303 | /** | 1302 | /** |
1304 | * video_setup - process command line options | 1303 | * video_setup - process command line options |
1305 | * @options: string of options | 1304 | * @options: string of options |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 978def013587..6cd1976548d4 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/pci-bridge.h> | 35 | #include <asm/pci-bridge.h> |
36 | #endif | 36 | #endif |
37 | #include <video/edid.h> | ||
38 | #include "edid.h" | 37 | #include "edid.h" |
39 | 38 | ||
40 | /* | 39 | /* |
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 9ec8781794c0..e04d3e8b2549 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -999,8 +999,14 @@ static int i810_check_params(struct fb_var_screeninfo *var, | |||
999 | info->monspecs.dclkmin = 15000000; | 999 | info->monspecs.dclkmin = 15000000; |
1000 | 1000 | ||
1001 | if (fb_validate_mode(var, info)) { | 1001 | if (fb_validate_mode(var, info)) { |
1002 | if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) | 1002 | if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) { |
1003 | int default_sync = (hsync1-HFMIN)|(hsync2-HFMAX) | ||
1004 | |(vsync1-VFMIN)|(vsync2-VFMAX); | ||
1005 | printk("i810fb: invalid video mode%s\n", | ||
1006 | default_sync ? "" : | ||
1007 | ". Specifying vsyncN/hsyncN parameters may help"); | ||
1003 | return -EINVAL; | 1008 | return -EINVAL; |
1009 | } | ||
1004 | } | 1010 | } |
1005 | 1011 | ||
1006 | var->xres = xres; | 1012 | var->xres = xres; |
@@ -2023,10 +2029,10 @@ MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines" | |||
2023 | " (default = 480)"); | 2029 | " (default = 480)"); |
2024 | module_param(hsync1, int, 0); | 2030 | module_param(hsync1, int, 0); |
2025 | MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz" | 2031 | MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz" |
2026 | " (default = 31)"); | 2032 | " (default = 29)"); |
2027 | module_param(hsync2, int, 0); | 2033 | module_param(hsync2, int, 0); |
2028 | MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz" | 2034 | MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz" |
2029 | " (default = 31)"); | 2035 | " (default = 30)"); |
2030 | module_param(vsync1, int, 0); | 2036 | module_param(vsync1, int, 0); |
2031 | MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz" | 2037 | MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz" |
2032 | " (default = 50)"); | 2038 | " (default = 50)"); |
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c new file mode 100644 index 000000000000..8fe1c12a17bd --- /dev/null +++ b/drivers/video/imxfb.c | |||
@@ -0,0 +1,695 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/imxfb.c | ||
3 | * | ||
4 | * Freescale i.MX Frame Buffer device driver | ||
5 | * | ||
6 | * Copyright (C) 2004 Sascha Hauer, Pengutronix | ||
7 | * Based on acornfb.c Copyright (C) Russell King. | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | * | ||
13 | * Please direct your questions and comments on this driver to the following | ||
14 | * email address: | ||
15 | * | ||
16 | * linux-arm-kernel@lists.arm.linux.org.uk | ||
17 | */ | ||
18 | |||
19 | //#define DEBUG 1 | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/string.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/fb.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/ioport.h> | ||
33 | #include <linux/cpufreq.h> | ||
34 | #include <linux/device.h> | ||
35 | #include <linux/dma-mapping.h> | ||
36 | |||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/mach-types.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | #include <asm/arch/imxfb.h> | ||
42 | |||
43 | /* | ||
44 | * Complain if VAR is out of range. | ||
45 | */ | ||
46 | #define DEBUG_VAR 1 | ||
47 | |||
48 | #include "imxfb.h" | ||
49 | |||
50 | static struct imxfb_rgb def_rgb_16 = { | ||
51 | .red = { .offset = 8, .length = 4, }, | ||
52 | .green = { .offset = 4, .length = 4, }, | ||
53 | .blue = { .offset = 0, .length = 4, }, | ||
54 | .transp = { .offset = 0, .length = 0, }, | ||
55 | }; | ||
56 | |||
57 | static struct imxfb_rgb def_rgb_8 = { | ||
58 | .red = { .offset = 0, .length = 8, }, | ||
59 | .green = { .offset = 0, .length = 8, }, | ||
60 | .blue = { .offset = 0, .length = 8, }, | ||
61 | .transp = { .offset = 0, .length = 0, }, | ||
62 | }; | ||
63 | |||
64 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info); | ||
65 | |||
66 | static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) | ||
67 | { | ||
68 | chan &= 0xffff; | ||
69 | chan >>= 16 - bf->length; | ||
70 | return chan << bf->offset; | ||
71 | } | ||
72 | |||
73 | #define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2) | ||
74 | static int | ||
75 | imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, | ||
76 | u_int trans, struct fb_info *info) | ||
77 | { | ||
78 | struct imxfb_info *fbi = info->par; | ||
79 | u_int val, ret = 1; | ||
80 | |||
81 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) | ||
82 | if (regno < fbi->palette_size) { | ||
83 | val = (CNVT_TOHW(red, 4) << 8) | | ||
84 | (CNVT_TOHW(green,4) << 4) | | ||
85 | CNVT_TOHW(blue, 4); | ||
86 | |||
87 | LCDC_PALETTE(regno) = val; | ||
88 | ret = 0; | ||
89 | } | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
95 | u_int trans, struct fb_info *info) | ||
96 | { | ||
97 | struct imxfb_info *fbi = info->par; | ||
98 | unsigned int val; | ||
99 | int ret = 1; | ||
100 | |||
101 | /* | ||
102 | * If inverse mode was selected, invert all the colours | ||
103 | * rather than the register number. The register number | ||
104 | * is what you poke into the framebuffer to produce the | ||
105 | * colour you requested. | ||
106 | */ | ||
107 | if (fbi->cmap_inverse) { | ||
108 | red = 0xffff - red; | ||
109 | green = 0xffff - green; | ||
110 | blue = 0xffff - blue; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * If greyscale is true, then we convert the RGB value | ||
115 | * to greyscale no mater what visual we are using. | ||
116 | */ | ||
117 | if (info->var.grayscale) | ||
118 | red = green = blue = (19595 * red + 38470 * green + | ||
119 | 7471 * blue) >> 16; | ||
120 | |||
121 | switch (info->fix.visual) { | ||
122 | case FB_VISUAL_TRUECOLOR: | ||
123 | /* | ||
124 | * 12 or 16-bit True Colour. We encode the RGB value | ||
125 | * according to the RGB bitfield information. | ||
126 | */ | ||
127 | if (regno < 16) { | ||
128 | u32 *pal = info->pseudo_palette; | ||
129 | |||
130 | val = chan_to_field(red, &info->var.red); | ||
131 | val |= chan_to_field(green, &info->var.green); | ||
132 | val |= chan_to_field(blue, &info->var.blue); | ||
133 | |||
134 | pal[regno] = val; | ||
135 | ret = 0; | ||
136 | } | ||
137 | break; | ||
138 | |||
139 | case FB_VISUAL_STATIC_PSEUDOCOLOR: | ||
140 | case FB_VISUAL_PSEUDOCOLOR: | ||
141 | ret = imxfb_setpalettereg(regno, red, green, blue, trans, info); | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * imxfb_check_var(): | ||
150 | * Round up in the following order: bits_per_pixel, xres, | ||
151 | * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, | ||
152 | * bitfields, horizontal timing, vertical timing. | ||
153 | */ | ||
154 | static int | ||
155 | imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
156 | { | ||
157 | struct imxfb_info *fbi = info->par; | ||
158 | int rgbidx; | ||
159 | |||
160 | if (var->xres < MIN_XRES) | ||
161 | var->xres = MIN_XRES; | ||
162 | if (var->yres < MIN_YRES) | ||
163 | var->yres = MIN_YRES; | ||
164 | if (var->xres > fbi->max_xres) | ||
165 | var->xres = fbi->max_xres; | ||
166 | if (var->yres > fbi->max_yres) | ||
167 | var->yres = fbi->max_yres; | ||
168 | var->xres_virtual = max(var->xres_virtual, var->xres); | ||
169 | var->yres_virtual = max(var->yres_virtual, var->yres); | ||
170 | |||
171 | pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); | ||
172 | switch (var->bits_per_pixel) { | ||
173 | case 16: | ||
174 | rgbidx = RGB_16; | ||
175 | break; | ||
176 | case 8: | ||
177 | rgbidx = RGB_8; | ||
178 | break; | ||
179 | default: | ||
180 | rgbidx = RGB_16; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Copy the RGB parameters for this display | ||
185 | * from the machine specific parameters. | ||
186 | */ | ||
187 | var->red = fbi->rgb[rgbidx]->red; | ||
188 | var->green = fbi->rgb[rgbidx]->green; | ||
189 | var->blue = fbi->rgb[rgbidx]->blue; | ||
190 | var->transp = fbi->rgb[rgbidx]->transp; | ||
191 | |||
192 | pr_debug("RGBT length = %d:%d:%d:%d\n", | ||
193 | var->red.length, var->green.length, var->blue.length, | ||
194 | var->transp.length); | ||
195 | |||
196 | pr_debug("RGBT offset = %d:%d:%d:%d\n", | ||
197 | var->red.offset, var->green.offset, var->blue.offset, | ||
198 | var->transp.offset); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * imxfb_set_par(): | ||
205 | * Set the user defined part of the display for the specified console | ||
206 | */ | ||
207 | static int imxfb_set_par(struct fb_info *info) | ||
208 | { | ||
209 | struct imxfb_info *fbi = info->par; | ||
210 | struct fb_var_screeninfo *var = &info->var; | ||
211 | |||
212 | pr_debug("set_par\n"); | ||
213 | |||
214 | if (var->bits_per_pixel == 16) | ||
215 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
216 | else if (!fbi->cmap_static) | ||
217 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
218 | else { | ||
219 | /* | ||
220 | * Some people have weird ideas about wanting static | ||
221 | * pseudocolor maps. I suspect their user space | ||
222 | * applications are broken. | ||
223 | */ | ||
224 | info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
225 | } | ||
226 | |||
227 | info->fix.line_length = var->xres_virtual * | ||
228 | var->bits_per_pixel / 8; | ||
229 | fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; | ||
230 | |||
231 | imxfb_activate_var(var, info); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static void imxfb_enable_controller(struct imxfb_info *fbi) | ||
237 | { | ||
238 | pr_debug("Enabling LCD controller\n"); | ||
239 | |||
240 | /* initialize LCDC */ | ||
241 | LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */ | ||
242 | |||
243 | LCDC_SSA = fbi->screen_dma; | ||
244 | /* physical screen start address */ | ||
245 | LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4); | ||
246 | |||
247 | LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */ | ||
248 | |||
249 | /* disable hardware cursor */ | ||
250 | LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1); | ||
251 | |||
252 | /* fixed burst length (see erratum 11) */ | ||
253 | LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2); | ||
254 | |||
255 | LCDC_RMCR = RMCR_LCDC_EN; | ||
256 | |||
257 | if(fbi->backlight_power) | ||
258 | fbi->backlight_power(1); | ||
259 | if(fbi->lcd_power) | ||
260 | fbi->lcd_power(1); | ||
261 | } | ||
262 | |||
263 | static void imxfb_disable_controller(struct imxfb_info *fbi) | ||
264 | { | ||
265 | pr_debug("Disabling LCD controller\n"); | ||
266 | |||
267 | if(fbi->backlight_power) | ||
268 | fbi->backlight_power(0); | ||
269 | if(fbi->lcd_power) | ||
270 | fbi->lcd_power(0); | ||
271 | |||
272 | LCDC_RMCR = 0; | ||
273 | } | ||
274 | |||
275 | static int imxfb_blank(int blank, struct fb_info *info) | ||
276 | { | ||
277 | struct imxfb_info *fbi = info->par; | ||
278 | |||
279 | pr_debug("imxfb_blank: blank=%d\n", blank); | ||
280 | |||
281 | switch (blank) { | ||
282 | case FB_BLANK_POWERDOWN: | ||
283 | case FB_BLANK_VSYNC_SUSPEND: | ||
284 | case FB_BLANK_HSYNC_SUSPEND: | ||
285 | case FB_BLANK_NORMAL: | ||
286 | imxfb_disable_controller(fbi); | ||
287 | break; | ||
288 | |||
289 | case FB_BLANK_UNBLANK: | ||
290 | imxfb_enable_controller(fbi); | ||
291 | break; | ||
292 | } | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static struct fb_ops imxfb_ops = { | ||
297 | .owner = THIS_MODULE, | ||
298 | .fb_check_var = imxfb_check_var, | ||
299 | .fb_set_par = imxfb_set_par, | ||
300 | .fb_setcolreg = imxfb_setcolreg, | ||
301 | .fb_fillrect = cfb_fillrect, | ||
302 | .fb_copyarea = cfb_copyarea, | ||
303 | .fb_imageblit = cfb_imageblit, | ||
304 | .fb_blank = imxfb_blank, | ||
305 | .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */ | ||
306 | }; | ||
307 | |||
308 | /* | ||
309 | * imxfb_activate_var(): | ||
310 | * Configures LCD Controller based on entries in var parameter. Settings are | ||
311 | * only written to the controller if changes were made. | ||
312 | */ | ||
313 | static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
314 | { | ||
315 | struct imxfb_info *fbi = info->par; | ||
316 | pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", | ||
317 | var->xres, var->hsync_len, | ||
318 | var->left_margin, var->right_margin); | ||
319 | pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n", | ||
320 | var->yres, var->vsync_len, | ||
321 | var->upper_margin, var->lower_margin); | ||
322 | |||
323 | #if DEBUG_VAR | ||
324 | if (var->xres < 16 || var->xres > 1024) | ||
325 | printk(KERN_ERR "%s: invalid xres %d\n", | ||
326 | info->fix.id, var->xres); | ||
327 | if (var->hsync_len < 1 || var->hsync_len > 64) | ||
328 | printk(KERN_ERR "%s: invalid hsync_len %d\n", | ||
329 | info->fix.id, var->hsync_len); | ||
330 | if (var->left_margin > 255) | ||
331 | printk(KERN_ERR "%s: invalid left_margin %d\n", | ||
332 | info->fix.id, var->left_margin); | ||
333 | if (var->right_margin > 255) | ||
334 | printk(KERN_ERR "%s: invalid right_margin %d\n", | ||
335 | info->fix.id, var->right_margin); | ||
336 | if (var->yres < 1 || var->yres > 511) | ||
337 | printk(KERN_ERR "%s: invalid yres %d\n", | ||
338 | info->fix.id, var->yres); | ||
339 | if (var->vsync_len > 100) | ||
340 | printk(KERN_ERR "%s: invalid vsync_len %d\n", | ||
341 | info->fix.id, var->vsync_len); | ||
342 | if (var->upper_margin > 63) | ||
343 | printk(KERN_ERR "%s: invalid upper_margin %d\n", | ||
344 | info->fix.id, var->upper_margin); | ||
345 | if (var->lower_margin > 255) | ||
346 | printk(KERN_ERR "%s: invalid lower_margin %d\n", | ||
347 | info->fix.id, var->lower_margin); | ||
348 | #endif | ||
349 | |||
350 | LCDC_HCR = HCR_H_WIDTH(var->hsync_len) | | ||
351 | HCR_H_WAIT_1(var->left_margin) | | ||
352 | HCR_H_WAIT_2(var->right_margin); | ||
353 | |||
354 | LCDC_VCR = VCR_V_WIDTH(var->vsync_len) | | ||
355 | VCR_V_WAIT_1(var->upper_margin) | | ||
356 | VCR_V_WAIT_2(var->lower_margin); | ||
357 | |||
358 | LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres); | ||
359 | LCDC_PCR = fbi->pcr; | ||
360 | LCDC_PWMR = fbi->pwmr; | ||
361 | LCDC_LSCR1 = fbi->lscr1; | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static void imxfb_setup_gpio(struct imxfb_info *fbi) | ||
367 | { | ||
368 | int width; | ||
369 | |||
370 | LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF); | ||
371 | |||
372 | if( fbi->pcr & PCR_TFT ) | ||
373 | width = 16; | ||
374 | else | ||
375 | width = 1 << ((fbi->pcr >> 28) & 0x3); | ||
376 | |||
377 | switch(width) { | ||
378 | case 16: | ||
379 | imx_gpio_mode(PD30_PF_LD15); | ||
380 | imx_gpio_mode(PD29_PF_LD14); | ||
381 | imx_gpio_mode(PD28_PF_LD13); | ||
382 | imx_gpio_mode(PD27_PF_LD12); | ||
383 | imx_gpio_mode(PD26_PF_LD11); | ||
384 | imx_gpio_mode(PD25_PF_LD10); | ||
385 | imx_gpio_mode(PD24_PF_LD9); | ||
386 | imx_gpio_mode(PD23_PF_LD8); | ||
387 | case 8: | ||
388 | imx_gpio_mode(PD22_PF_LD7); | ||
389 | imx_gpio_mode(PD21_PF_LD6); | ||
390 | imx_gpio_mode(PD20_PF_LD5); | ||
391 | imx_gpio_mode(PD19_PF_LD4); | ||
392 | case 4: | ||
393 | imx_gpio_mode(PD18_PF_LD3); | ||
394 | imx_gpio_mode(PD17_PF_LD2); | ||
395 | case 2: | ||
396 | imx_gpio_mode(PD16_PF_LD1); | ||
397 | case 1: | ||
398 | imx_gpio_mode(PD15_PF_LD0); | ||
399 | } | ||
400 | |||
401 | /* initialize GPIOs */ | ||
402 | imx_gpio_mode(PD6_PF_LSCLK); | ||
403 | imx_gpio_mode(PD10_PF_SPL_SPR); | ||
404 | imx_gpio_mode(PD11_PF_CONTRAST); | ||
405 | imx_gpio_mode(PD14_PF_FLM_VSYNC); | ||
406 | imx_gpio_mode(PD13_PF_LP_HSYNC); | ||
407 | imx_gpio_mode(PD7_PF_REV); | ||
408 | imx_gpio_mode(PD8_PF_CLS); | ||
409 | |||
410 | #ifndef CONFIG_MACH_PIMX1 | ||
411 | /* on PiMX1 used as buffers enable signal | ||
412 | */ | ||
413 | imx_gpio_mode(PD9_PF_PS); | ||
414 | #endif | ||
415 | |||
416 | #ifndef CONFIG_MACH_MX1FS2 | ||
417 | /* on mx1fs2 this pin is used to (de)activate the display, so we need | ||
418 | * it as a normal gpio | ||
419 | */ | ||
420 | imx_gpio_mode(PD12_PF_ACD_OE); | ||
421 | #endif | ||
422 | |||
423 | } | ||
424 | |||
425 | #ifdef CONFIG_PM | ||
426 | /* | ||
427 | * Power management hooks. Note that we won't be called from IRQ context, | ||
428 | * unlike the blank functions above, so we may sleep. | ||
429 | */ | ||
430 | static int imxfb_suspend(struct device *dev, u32 state, u32 level) | ||
431 | { | ||
432 | struct imxfb_info *fbi = dev_get_drvdata(dev); | ||
433 | pr_debug("%s\n",__FUNCTION__); | ||
434 | |||
435 | if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) | ||
436 | imxfb_disable_controller(fbi); | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int imxfb_resume(struct device *dev, u32 level) | ||
441 | { | ||
442 | struct imxfb_info *fbi = dev_get_drvdata(dev); | ||
443 | pr_debug("%s\n",__FUNCTION__); | ||
444 | |||
445 | if (level == RESUME_ENABLE) | ||
446 | imxfb_enable_controller(fbi); | ||
447 | return 0; | ||
448 | } | ||
449 | #else | ||
450 | #define imxfb_suspend NULL | ||
451 | #define imxfb_resume NULL | ||
452 | #endif | ||
453 | |||
454 | static int __init imxfb_init_fbinfo(struct device *dev) | ||
455 | { | ||
456 | struct imxfb_mach_info *inf = dev->platform_data; | ||
457 | struct fb_info *info = dev_get_drvdata(dev); | ||
458 | struct imxfb_info *fbi = info->par; | ||
459 | |||
460 | pr_debug("%s\n",__FUNCTION__); | ||
461 | |||
462 | info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL); | ||
463 | if (!info->pseudo_palette) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | memset(fbi, 0, sizeof(struct imxfb_info)); | ||
467 | fbi->dev = dev; | ||
468 | |||
469 | strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); | ||
470 | |||
471 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
472 | info->fix.type_aux = 0; | ||
473 | info->fix.xpanstep = 0; | ||
474 | info->fix.ypanstep = 0; | ||
475 | info->fix.ywrapstep = 0; | ||
476 | info->fix.accel = FB_ACCEL_NONE; | ||
477 | |||
478 | info->var.nonstd = 0; | ||
479 | info->var.activate = FB_ACTIVATE_NOW; | ||
480 | info->var.height = -1; | ||
481 | info->var.width = -1; | ||
482 | info->var.accel_flags = 0; | ||
483 | info->var.vmode = FB_VMODE_NONINTERLACED; | ||
484 | |||
485 | info->fbops = &imxfb_ops; | ||
486 | info->flags = FBINFO_FLAG_DEFAULT; | ||
487 | info->pseudo_palette = (fbi + 1); | ||
488 | |||
489 | fbi->rgb[RGB_16] = &def_rgb_16; | ||
490 | fbi->rgb[RGB_8] = &def_rgb_8; | ||
491 | |||
492 | fbi->max_xres = inf->xres; | ||
493 | info->var.xres = inf->xres; | ||
494 | info->var.xres_virtual = inf->xres; | ||
495 | fbi->max_yres = inf->yres; | ||
496 | info->var.yres = inf->yres; | ||
497 | info->var.yres_virtual = inf->yres; | ||
498 | fbi->max_bpp = inf->bpp; | ||
499 | info->var.bits_per_pixel = inf->bpp; | ||
500 | info->var.pixclock = inf->pixclock; | ||
501 | info->var.hsync_len = inf->hsync_len; | ||
502 | info->var.left_margin = inf->left_margin; | ||
503 | info->var.right_margin = inf->right_margin; | ||
504 | info->var.vsync_len = inf->vsync_len; | ||
505 | info->var.upper_margin = inf->upper_margin; | ||
506 | info->var.lower_margin = inf->lower_margin; | ||
507 | info->var.sync = inf->sync; | ||
508 | info->var.grayscale = inf->cmap_greyscale; | ||
509 | fbi->cmap_inverse = inf->cmap_inverse; | ||
510 | fbi->pcr = inf->pcr; | ||
511 | fbi->lscr1 = inf->lscr1; | ||
512 | fbi->pwmr = inf->pwmr; | ||
513 | fbi->lcd_power = inf->lcd_power; | ||
514 | fbi->backlight_power = inf->backlight_power; | ||
515 | info->fix.smem_len = fbi->max_xres * fbi->max_yres * | ||
516 | fbi->max_bpp / 8; | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Allocates the DRAM memory for the frame buffer. This buffer is | ||
523 | * remapped into a non-cached, non-buffered, memory region to | ||
524 | * allow pixel writes to occur without flushing the cache. | ||
525 | * Once this area is remapped, all virtual memory access to the | ||
526 | * video memory should occur at the new region. | ||
527 | */ | ||
528 | static int __init imxfb_map_video_memory(struct fb_info *info) | ||
529 | { | ||
530 | struct imxfb_info *fbi = info->par; | ||
531 | |||
532 | fbi->map_size = PAGE_ALIGN(info->fix.smem_len); | ||
533 | fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, | ||
534 | &fbi->map_dma,GFP_KERNEL); | ||
535 | |||
536 | if (fbi->map_cpu) { | ||
537 | info->screen_base = fbi->map_cpu; | ||
538 | fbi->screen_cpu = fbi->map_cpu; | ||
539 | fbi->screen_dma = fbi->map_dma; | ||
540 | info->fix.smem_start = fbi->screen_dma; | ||
541 | } | ||
542 | |||
543 | return fbi->map_cpu ? 0 : -ENOMEM; | ||
544 | } | ||
545 | |||
546 | static int __init imxfb_probe(struct device *dev) | ||
547 | { | ||
548 | struct platform_device *pdev = to_platform_device(dev); | ||
549 | struct imxfb_info *fbi; | ||
550 | struct fb_info *info; | ||
551 | struct imxfb_mach_info *inf; | ||
552 | struct resource *res; | ||
553 | int ret; | ||
554 | |||
555 | printk("i.MX Framebuffer driver\n"); | ||
556 | |||
557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
558 | if(!res) | ||
559 | return -ENODEV; | ||
560 | |||
561 | inf = dev->platform_data; | ||
562 | if(!inf) { | ||
563 | dev_err(dev,"No platform_data available\n"); | ||
564 | return -ENOMEM; | ||
565 | } | ||
566 | |||
567 | info = framebuffer_alloc(sizeof(struct imxfb_info), dev); | ||
568 | if(!info) | ||
569 | return -ENOMEM; | ||
570 | |||
571 | fbi = info->par; | ||
572 | |||
573 | dev_set_drvdata(dev, info); | ||
574 | |||
575 | ret = imxfb_init_fbinfo(dev); | ||
576 | if( ret < 0 ) | ||
577 | goto failed_init; | ||
578 | |||
579 | res = request_mem_region(res->start, res->end - res->start + 1, "IMXFB"); | ||
580 | if (!res) { | ||
581 | ret = -EBUSY; | ||
582 | goto failed_regs; | ||
583 | } | ||
584 | |||
585 | if (!inf->fixed_screen_cpu) { | ||
586 | ret = imxfb_map_video_memory(info); | ||
587 | if (ret) { | ||
588 | dev_err(dev, "Failed to allocate video RAM: %d\n", ret); | ||
589 | ret = -ENOMEM; | ||
590 | goto failed_map; | ||
591 | } | ||
592 | } else { | ||
593 | /* Fixed framebuffer mapping enables location of the screen in eSRAM */ | ||
594 | fbi->map_cpu = inf->fixed_screen_cpu; | ||
595 | fbi->map_dma = inf->fixed_screen_dma; | ||
596 | info->screen_base = fbi->map_cpu; | ||
597 | fbi->screen_cpu = fbi->map_cpu; | ||
598 | fbi->screen_dma = fbi->map_dma; | ||
599 | info->fix.smem_start = fbi->screen_dma; | ||
600 | } | ||
601 | |||
602 | /* | ||
603 | * This makes sure that our colour bitfield | ||
604 | * descriptors are correctly initialised. | ||
605 | */ | ||
606 | imxfb_check_var(&info->var, info); | ||
607 | |||
608 | ret = fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); | ||
609 | if (ret < 0) | ||
610 | goto failed_cmap; | ||
611 | |||
612 | imxfb_setup_gpio(fbi); | ||
613 | |||
614 | imxfb_set_par(info); | ||
615 | ret = register_framebuffer(info); | ||
616 | if (ret < 0) { | ||
617 | dev_err(dev, "failed to register framebuffer\n"); | ||
618 | goto failed_register; | ||
619 | } | ||
620 | |||
621 | imxfb_enable_controller(fbi); | ||
622 | |||
623 | return 0; | ||
624 | |||
625 | failed_register: | ||
626 | fb_dealloc_cmap(&info->cmap); | ||
627 | failed_cmap: | ||
628 | if (!inf->fixed_screen_cpu) | ||
629 | dma_free_writecombine(dev,fbi->map_size,fbi->map_cpu, | ||
630 | fbi->map_dma); | ||
631 | failed_map: | ||
632 | kfree(info->pseudo_palette); | ||
633 | failed_regs: | ||
634 | release_mem_region(res->start, res->end - res->start); | ||
635 | failed_init: | ||
636 | dev_set_drvdata(dev, NULL); | ||
637 | framebuffer_release(info); | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | static int imxfb_remove(struct device *dev) | ||
642 | { | ||
643 | struct platform_device *pdev = to_platform_device(dev); | ||
644 | struct fb_info *info = dev_get_drvdata(dev); | ||
645 | struct resource *res; | ||
646 | |||
647 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
648 | |||
649 | /* disable LCD controller */ | ||
650 | LCDC_RMCR &= ~RMCR_LCDC_EN; | ||
651 | |||
652 | unregister_framebuffer(info); | ||
653 | |||
654 | fb_dealloc_cmap(&info->cmap); | ||
655 | kfree(info->pseudo_palette); | ||
656 | framebuffer_release(info); | ||
657 | |||
658 | release_mem_region(res->start, res->end - res->start + 1); | ||
659 | dev_set_drvdata(dev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | void imxfb_shutdown(struct device * dev) | ||
665 | { | ||
666 | /* disable LCD Controller */ | ||
667 | LCDC_RMCR &= ~RMCR_LCDC_EN; | ||
668 | } | ||
669 | |||
670 | static struct device_driver imxfb_driver = { | ||
671 | .name = "imx-fb", | ||
672 | .bus = &platform_bus_type, | ||
673 | .probe = imxfb_probe, | ||
674 | .suspend = imxfb_suspend, | ||
675 | .resume = imxfb_resume, | ||
676 | .remove = imxfb_remove, | ||
677 | .shutdown = imxfb_shutdown, | ||
678 | }; | ||
679 | |||
680 | int __init imxfb_init(void) | ||
681 | { | ||
682 | return driver_register(&imxfb_driver); | ||
683 | } | ||
684 | |||
685 | static void __exit imxfb_cleanup(void) | ||
686 | { | ||
687 | driver_unregister(&imxfb_driver); | ||
688 | } | ||
689 | |||
690 | module_init(imxfb_init); | ||
691 | module_exit(imxfb_cleanup); | ||
692 | |||
693 | MODULE_DESCRIPTION("Motorola i.MX framebuffer driver"); | ||
694 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | ||
695 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h new file mode 100644 index 000000000000..128c3ee515c7 --- /dev/null +++ b/drivers/video/imxfb.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/imxfb.h | ||
3 | * | ||
4 | * Freescale i.MX Frame Buffer device driver | ||
5 | * | ||
6 | * Copyright (C) 2004 S.Hauer, Pengutronix | ||
7 | * | ||
8 | * Copyright (C) 1999 Eric A. Thomas | ||
9 | * Based on acornfb.c Copyright (C) Russell King. | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file COPYING in the main directory of this archive | ||
13 | * for more details. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * These are the bitfields for each | ||
18 | * display depth that we support. | ||
19 | */ | ||
20 | struct imxfb_rgb { | ||
21 | struct fb_bitfield red; | ||
22 | struct fb_bitfield green; | ||
23 | struct fb_bitfield blue; | ||
24 | struct fb_bitfield transp; | ||
25 | }; | ||
26 | |||
27 | #define RGB_16 (0) | ||
28 | #define RGB_8 (1) | ||
29 | #define NR_RGB 2 | ||
30 | |||
31 | struct imxfb_info { | ||
32 | struct device *dev; | ||
33 | struct imxfb_rgb *rgb[NR_RGB]; | ||
34 | |||
35 | u_int max_bpp; | ||
36 | u_int max_xres; | ||
37 | u_int max_yres; | ||
38 | |||
39 | /* | ||
40 | * These are the addresses we mapped | ||
41 | * the framebuffer memory region to. | ||
42 | */ | ||
43 | dma_addr_t map_dma; | ||
44 | u_char * map_cpu; | ||
45 | u_int map_size; | ||
46 | |||
47 | u_char * screen_cpu; | ||
48 | dma_addr_t screen_dma; | ||
49 | u_int palette_size; | ||
50 | |||
51 | dma_addr_t dbar1; | ||
52 | dma_addr_t dbar2; | ||
53 | |||
54 | u_int pcr; | ||
55 | u_int pwmr; | ||
56 | u_int lscr1; | ||
57 | u_int cmap_inverse:1, | ||
58 | cmap_static:1, | ||
59 | unused:30; | ||
60 | |||
61 | void (*lcd_power)(int); | ||
62 | void (*backlight_power)(int); | ||
63 | }; | ||
64 | |||
65 | #define IMX_NAME "IMX" | ||
66 | |||
67 | /* | ||
68 | * Minimum X and Y resolutions | ||
69 | */ | ||
70 | #define MIN_XRES 64 | ||
71 | #define MIN_YRES 64 | ||
72 | |||
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 6a05b7000830..549e22939260 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -135,9 +135,45 @@ | |||
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | #include "intelfb.h" | 137 | #include "intelfb.h" |
138 | #include "intelfbdrv.h" | ||
139 | #include "intelfbhw.h" | 138 | #include "intelfbhw.h" |
140 | 139 | ||
140 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | ||
141 | static void update_dinfo(struct intelfb_info *dinfo, | ||
142 | struct fb_var_screeninfo *var); | ||
143 | static int intelfb_get_fix(struct fb_fix_screeninfo *fix, | ||
144 | struct fb_info *info); | ||
145 | |||
146 | static int intelfb_check_var(struct fb_var_screeninfo *var, | ||
147 | struct fb_info *info); | ||
148 | static int intelfb_set_par(struct fb_info *info); | ||
149 | static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
150 | unsigned blue, unsigned transp, | ||
151 | struct fb_info *info); | ||
152 | |||
153 | static int intelfb_blank(int blank, struct fb_info *info); | ||
154 | static int intelfb_pan_display(struct fb_var_screeninfo *var, | ||
155 | struct fb_info *info); | ||
156 | |||
157 | static void intelfb_fillrect(struct fb_info *info, | ||
158 | const struct fb_fillrect *rect); | ||
159 | static void intelfb_copyarea(struct fb_info *info, | ||
160 | const struct fb_copyarea *region); | ||
161 | static void intelfb_imageblit(struct fb_info *info, | ||
162 | const struct fb_image *image); | ||
163 | static int intelfb_cursor(struct fb_info *info, | ||
164 | struct fb_cursor *cursor); | ||
165 | |||
166 | static int intelfb_sync(struct fb_info *info); | ||
167 | |||
168 | static int intelfb_ioctl(struct inode *inode, struct file *file, | ||
169 | unsigned int cmd, unsigned long arg, | ||
170 | struct fb_info *info); | ||
171 | |||
172 | static int __devinit intelfb_pci_register(struct pci_dev *pdev, | ||
173 | const struct pci_device_id *ent); | ||
174 | static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); | ||
175 | static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); | ||
176 | |||
141 | /* | 177 | /* |
142 | * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the | 178 | * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the |
143 | * mobile chipsets from being registered. | 179 | * mobile chipsets from being registered. |
diff --git a/drivers/video/intelfb/intelfbdrv.h b/drivers/video/intelfb/intelfbdrv.h deleted file mode 100644 index cc3058128884..000000000000 --- a/drivers/video/intelfb/intelfbdrv.h +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | #ifndef _INTELFBDRV_H | ||
2 | #define _INTELFBDRV_H | ||
3 | |||
4 | /* | ||
5 | ****************************************************************************** | ||
6 | * intelfb | ||
7 | * | ||
8 | * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G | ||
9 | * integrated graphics chips. | ||
10 | * | ||
11 | * Copyright © 2004 Sylvain Meyer | ||
12 | * | ||
13 | * Author: Sylvain Meyer | ||
14 | * | ||
15 | ****************************************************************************** | ||
16 | * This program is free software; you can redistribute it and/or modify | ||
17 | * it under the terms of the GNU General Public License as published by | ||
18 | * the Free Software Foundation; either version 2 of the License, or | ||
19 | * (at your option) any later version. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | ||
32 | static void update_dinfo(struct intelfb_info *dinfo, | ||
33 | struct fb_var_screeninfo *var); | ||
34 | static int intelfb_get_fix(struct fb_fix_screeninfo *fix, | ||
35 | struct fb_info *info); | ||
36 | |||
37 | static int intelfb_check_var(struct fb_var_screeninfo *var, | ||
38 | struct fb_info *info); | ||
39 | static int intelfb_set_par(struct fb_info *info); | ||
40 | static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
41 | unsigned blue, unsigned transp, | ||
42 | struct fb_info *info); | ||
43 | |||
44 | static int intelfb_blank(int blank, struct fb_info *info); | ||
45 | static int intelfb_pan_display(struct fb_var_screeninfo *var, | ||
46 | struct fb_info *info); | ||
47 | |||
48 | static void intelfb_fillrect(struct fb_info *info, | ||
49 | const struct fb_fillrect *rect); | ||
50 | static void intelfb_copyarea(struct fb_info *info, | ||
51 | const struct fb_copyarea *region); | ||
52 | static void intelfb_imageblit(struct fb_info *info, | ||
53 | const struct fb_image *image); | ||
54 | static int intelfb_cursor(struct fb_info *info, | ||
55 | struct fb_cursor *cursor); | ||
56 | |||
57 | static int intelfb_sync(struct fb_info *info); | ||
58 | |||
59 | static int intelfb_ioctl(struct inode *inode, struct file *file, | ||
60 | unsigned int cmd, unsigned long arg, | ||
61 | struct fb_info *info); | ||
62 | |||
63 | static int __devinit intelfb_pci_register(struct pci_dev *pdev, | ||
64 | const struct pci_device_id *ent); | ||
65 | static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); | ||
66 | static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); | ||
67 | |||
68 | #endif | ||
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 3a6555a8aaa2..47733f58153b 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -408,6 +408,7 @@ static int hwcur __devinitdata = 0; | |||
408 | static int noaccel __devinitdata = 0; | 408 | static int noaccel __devinitdata = 0; |
409 | static int noscale __devinitdata = 0; | 409 | static int noscale __devinitdata = 0; |
410 | static int paneltweak __devinitdata = 0; | 410 | static int paneltweak __devinitdata = 0; |
411 | static int vram __devinitdata = 0; | ||
411 | #ifdef CONFIG_MTRR | 412 | #ifdef CONFIG_MTRR |
412 | static int nomtrr __devinitdata = 0; | 413 | static int nomtrr __devinitdata = 0; |
413 | #endif | 414 | #endif |
@@ -1180,7 +1181,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var, | |||
1180 | 1181 | ||
1181 | var->xres_virtual = (var->xres_virtual + 63) & ~63; | 1182 | var->xres_virtual = (var->xres_virtual + 63) & ~63; |
1182 | 1183 | ||
1183 | vramlen = info->fix.smem_len; | 1184 | vramlen = info->screen_size; |
1184 | pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8; | 1185 | pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8; |
1185 | memlen = pitch * var->yres_virtual; | 1186 | memlen = pitch * var->yres_virtual; |
1186 | 1187 | ||
@@ -1343,7 +1344,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
1343 | /* maximize virtual vertical length */ | 1344 | /* maximize virtual vertical length */ |
1344 | lpitch = info->var.xres_virtual * | 1345 | lpitch = info->var.xres_virtual * |
1345 | ((info->var.bits_per_pixel + 7) >> 3); | 1346 | ((info->var.bits_per_pixel + 7) >> 3); |
1346 | info->var.yres_virtual = info->fix.smem_len / lpitch; | 1347 | info->var.yres_virtual = info->screen_size / lpitch; |
1347 | 1348 | ||
1348 | info->pixmap.scan_align = 4; | 1349 | info->pixmap.scan_align = 4; |
1349 | info->pixmap.buf_align = 4; | 1350 | info->pixmap.buf_align = 4; |
@@ -1507,12 +1508,20 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1507 | 1508 | ||
1508 | par->FbAddress = nvidiafb_fix.smem_start; | 1509 | par->FbAddress = nvidiafb_fix.smem_start; |
1509 | par->FbMapSize = par->RamAmountKBytes * 1024; | 1510 | par->FbMapSize = par->RamAmountKBytes * 1024; |
1511 | if (vram && vram * 1024 * 1024 < par->FbMapSize) | ||
1512 | par->FbMapSize = vram * 1024 * 1024; | ||
1513 | |||
1514 | /* Limit amount of vram to 64 MB */ | ||
1515 | if (par->FbMapSize > 64 * 1024 * 1024) | ||
1516 | par->FbMapSize = 64 * 1024 * 1024; | ||
1517 | |||
1510 | par->FbUsableSize = par->FbMapSize - (128 * 1024); | 1518 | par->FbUsableSize = par->FbMapSize - (128 * 1024); |
1511 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : | 1519 | par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : |
1512 | 16 * 1024; | 1520 | 16 * 1024; |
1513 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; | 1521 | par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; |
1514 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); | 1522 | info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); |
1515 | nvidiafb_fix.smem_len = par->FbUsableSize; | 1523 | info->screen_size = par->FbUsableSize; |
1524 | nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; | ||
1516 | 1525 | ||
1517 | if (!info->screen_base) { | 1526 | if (!info->screen_base) { |
1518 | printk(KERN_ERR PFX "cannot ioremap FB base\n"); | 1527 | printk(KERN_ERR PFX "cannot ioremap FB base\n"); |
@@ -1524,7 +1533,8 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1524 | #ifdef CONFIG_MTRR | 1533 | #ifdef CONFIG_MTRR |
1525 | if (!nomtrr) { | 1534 | if (!nomtrr) { |
1526 | par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start, | 1535 | par->mtrr.vram = mtrr_add(nvidiafb_fix.smem_start, |
1527 | par->FbMapSize, MTRR_TYPE_WRCOMB, 1); | 1536 | par->RamAmountKBytes * 1024, |
1537 | MTRR_TYPE_WRCOMB, 1); | ||
1528 | if (par->mtrr.vram < 0) { | 1538 | if (par->mtrr.vram < 0) { |
1529 | printk(KERN_ERR PFX "unable to setup MTRR\n"); | 1539 | printk(KERN_ERR PFX "unable to setup MTRR\n"); |
1530 | } else { | 1540 | } else { |
@@ -1566,9 +1576,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1566 | 1576 | ||
1567 | err_out_iounmap_fb: | 1577 | err_out_iounmap_fb: |
1568 | iounmap(info->screen_base); | 1578 | iounmap(info->screen_base); |
1579 | err_out_free_base1: | ||
1569 | fb_destroy_modedb(info->monspecs.modedb); | 1580 | fb_destroy_modedb(info->monspecs.modedb); |
1570 | nvidia_delete_i2c_busses(par); | 1581 | nvidia_delete_i2c_busses(par); |
1571 | err_out_free_base1: | ||
1572 | iounmap(par->REGS); | 1582 | iounmap(par->REGS); |
1573 | err_out_free_base0: | 1583 | err_out_free_base0: |
1574 | pci_release_regions(pd); | 1584 | pci_release_regions(pd); |
@@ -1645,6 +1655,8 @@ static int __devinit nvidiafb_setup(char *options) | |||
1645 | noscale = 1; | 1655 | noscale = 1; |
1646 | } else if (!strncmp(this_opt, "paneltweak:", 11)) { | 1656 | } else if (!strncmp(this_opt, "paneltweak:", 11)) { |
1647 | paneltweak = simple_strtoul(this_opt+11, NULL, 0); | 1657 | paneltweak = simple_strtoul(this_opt+11, NULL, 0); |
1658 | } else if (!strncmp(this_opt, "vram:", 5)) { | ||
1659 | vram = simple_strtoul(this_opt+5, NULL, 0); | ||
1648 | #ifdef CONFIG_MTRR | 1660 | #ifdef CONFIG_MTRR |
1649 | } else if (!strncmp(this_opt, "nomtrr", 6)) { | 1661 | } else if (!strncmp(this_opt, "nomtrr", 6)) { |
1650 | nomtrr = 1; | 1662 | nomtrr = 1; |
@@ -1716,6 +1728,10 @@ module_param(forceCRTC, int, 0); | |||
1716 | MODULE_PARM_DESC(forceCRTC, | 1728 | MODULE_PARM_DESC(forceCRTC, |
1717 | "Forces usage of a particular CRTC in case autodetection " | 1729 | "Forces usage of a particular CRTC in case autodetection " |
1718 | "fails. (0 or 1) (default=autodetect)"); | 1730 | "fails. (0 or 1) (default=autodetect)"); |
1731 | module_param(vram, int, 0); | ||
1732 | MODULE_PARM_DESC(vram, | ||
1733 | "amount of framebuffer memory to remap in MiB" | ||
1734 | "(default=0 - remap entire memory)"); | ||
1719 | #ifdef CONFIG_MTRR | 1735 | #ifdef CONFIG_MTRR |
1720 | module_param(nomtrr, bool, 0); | 1736 | module_param(nomtrr, bool, 0); |
1721 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " | 1737 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " |
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index d9a084e77a63..c46387024b1d 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c | |||
@@ -2107,7 +2107,7 @@ static void radeon_write_mode (struct radeonfb_info *rinfo, | |||
2107 | 2107 | ||
2108 | 2108 | ||
2109 | if (rinfo->arch == RADEON_M6) { | 2109 | if (rinfo->arch == RADEON_M6) { |
2110 | for (i=0; i<8; i++) | 2110 | for (i=0; i<7; i++) |
2111 | OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val); | 2111 | OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val); |
2112 | } else { | 2112 | } else { |
2113 | for (i=0; i<9; i++) | 2113 | for (i=0; i<9; i++) |
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index c34ba39b6f7e..7044226c5d4c 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -317,30 +317,49 @@ static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c) | |||
317 | 317 | ||
318 | static u32 do_calc_pll(int freq, int* freq_out) | 318 | static u32 do_calc_pll(int freq, int* freq_out) |
319 | { | 319 | { |
320 | int m, n, k, best_m, best_n, best_k, f_cur, best_error; | 320 | int m, n, k, best_m, best_n, best_k, best_error; |
321 | int fref = 14318; | 321 | int fref = 14318; |
322 | 322 | ||
323 | /* this really could be done with more intelligence -- | ||
324 | 255*63*4 = 64260 iterations is silly */ | ||
325 | best_error = freq; | 323 | best_error = freq; |
326 | best_n = best_m = best_k = 0; | 324 | best_n = best_m = best_k = 0; |
327 | for (n = 1; n < 256; n++) { | 325 | |
328 | for (m = 1; m < 64; m++) { | 326 | for (k = 3; k >= 0; k--) { |
329 | for (k = 0; k < 4; k++) { | 327 | for (m = 63; m >= 0; m--) { |
330 | f_cur = fref*(n + 2)/(m + 2)/(1 << k); | 328 | /* |
331 | if (abs(f_cur - freq) < best_error) { | 329 | * Estimate value of n that produces target frequency |
332 | best_error = abs(f_cur-freq); | 330 | * with current m and k |
333 | best_n = n; | 331 | */ |
334 | best_m = m; | 332 | int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2; |
335 | best_k = k; | 333 | |
334 | /* Search neighborhood of estimated n */ | ||
335 | for (n = max(0, n_estimated - 1); | ||
336 | n <= min(255, n_estimated + 1); n++) { | ||
337 | /* | ||
338 | * Calculate PLL freqency with current m, k and | ||
339 | * estimated n | ||
340 | */ | ||
341 | int f = fref * (n + 2) / (m + 2) / (1 << k); | ||
342 | int error = abs (f - freq); | ||
343 | |||
344 | /* | ||
345 | * If this is the closest we've come to the | ||
346 | * target frequency then remember n, m and k | ||
347 | */ | ||
348 | if (error < best_error) { | ||
349 | best_error = error; | ||
350 | best_n = n; | ||
351 | best_m = m; | ||
352 | best_k = k; | ||
336 | } | 353 | } |
337 | } | 354 | } |
338 | } | 355 | } |
339 | } | 356 | } |
357 | |||
340 | n = best_n; | 358 | n = best_n; |
341 | m = best_m; | 359 | m = best_m; |
342 | k = best_k; | 360 | k = best_k; |
343 | *freq_out = fref*(n + 2)/(m + 2)/(1 << k); | 361 | *freq_out = fref*(n + 2)/(m + 2)/(1 << k); |
362 | |||
344 | return (n << 8) | (m << 2) | k; | 363 | return (n << 8) | (m << 2) | k; |
345 | } | 364 | } |
346 | 365 | ||
@@ -411,36 +430,35 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) | |||
411 | 430 | ||
412 | static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) | 431 | static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) |
413 | { | 432 | { |
414 | u32 draminit0 = 0; | 433 | u32 draminit0; |
415 | u32 draminit1 = 0; | 434 | u32 draminit1; |
416 | u32 miscinit1 = 0; | 435 | u32 miscinit1; |
417 | u32 lfbsize = 0; | 436 | |
418 | int sgram_p = 0; | 437 | int num_chips; |
438 | int chip_size; /* in MB */ | ||
439 | u32 lfbsize; | ||
440 | int has_sgram; | ||
419 | 441 | ||
420 | draminit0 = tdfx_inl(par, DRAMINIT0); | 442 | draminit0 = tdfx_inl(par, DRAMINIT0); |
421 | draminit1 = tdfx_inl(par, DRAMINIT1); | 443 | draminit1 = tdfx_inl(par, DRAMINIT1); |
444 | |||
445 | num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4; | ||
422 | 446 | ||
423 | if ((dev_id == PCI_DEVICE_ID_3DFX_BANSHEE) || | 447 | if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { |
424 | (dev_id == PCI_DEVICE_ID_3DFX_VOODOO3)) { | 448 | /* Banshee/Voodoo3 */ |
425 | sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1; | 449 | has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM; |
426 | 450 | chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1) | |
427 | lfbsize = sgram_p ? | 451 | : 2; |
428 | (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) * | ||
429 | ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) : | ||
430 | 16 * 1024 * 1024; | ||
431 | } else { | 452 | } else { |
432 | /* Voodoo4/5 */ | 453 | /* Voodoo4/5 */ |
433 | u32 chips, psize, banks; | 454 | has_sgram = 0; |
434 | 455 | chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT); | |
435 | chips = ((draminit0 & (1 << 26)) == 0) ? 4 : 8; | 456 | } |
436 | psize = 1 << ((draminit0 & 0x38000000) >> 28); | 457 | lfbsize = num_chips * chip_size * 1024 * 1024; |
437 | banks = ((draminit0 & (1 << 30)) == 0) ? 2 : 4; | 458 | |
438 | lfbsize = chips * psize * banks; | 459 | /* disable block writes for SDRAM */ |
439 | lfbsize <<= 20; | ||
440 | } | ||
441 | /* disable block writes for SDRAM (why?) */ | ||
442 | miscinit1 = tdfx_inl(par, MISCINIT1); | 460 | miscinit1 = tdfx_inl(par, MISCINIT1); |
443 | miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS; | 461 | miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS; |
444 | miscinit1 |= MISCINIT1_CLUT_INV; | 462 | miscinit1 |= MISCINIT1_CLUT_INV; |
445 | 463 | ||
446 | banshee_make_room(par, 1); | 464 | banshee_make_room(par, 1); |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 8fc1278d7fbd..3027841f9c24 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -19,9 +19,6 @@ | |||
19 | #include <linux/fb.h> | 19 | #include <linux/fb.h> |
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #ifdef __i386__ | ||
23 | #include <video/edid.h> | ||
24 | #endif | ||
25 | #include <asm/io.h> | 22 | #include <asm/io.h> |
26 | #include <asm/mtrr.h> | 23 | #include <asm/mtrr.h> |
27 | 24 | ||