diff options
Diffstat (limited to 'drivers')
313 files changed, 14177 insertions, 7025 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4334c208841a..41427a41f620 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify); | |||
245 | 245 | ||
246 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | 246 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) |
247 | 247 | ||
248 | #ifdef CONFIG_PM | ||
249 | static u32 rtc_handler(void *context) | ||
250 | { | ||
251 | acpi_clear_event(ACPI_EVENT_RTC); | ||
252 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
253 | return ACPI_INTERRUPT_HANDLED; | ||
254 | } | ||
255 | |||
256 | static inline void rtc_wake_setup(void) | ||
257 | { | ||
258 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
259 | } | ||
260 | |||
261 | static void rtc_wake_on(struct device *dev) | ||
262 | { | ||
263 | acpi_clear_event(ACPI_EVENT_RTC); | ||
264 | acpi_enable_event(ACPI_EVENT_RTC, 0); | ||
265 | } | ||
266 | |||
267 | static void rtc_wake_off(struct device *dev) | ||
268 | { | ||
269 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
270 | } | ||
271 | #else | ||
272 | #define rtc_wake_setup() do{}while(0) | ||
273 | #define rtc_wake_on NULL | ||
274 | #define rtc_wake_off NULL | ||
275 | #endif | ||
276 | |||
248 | /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find | 277 | /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find |
249 | * its device node and pass extra config data. This helps its driver use | 278 | * its device node and pass extra config data. This helps its driver use |
250 | * capabilities that the now-obsolete mc146818 didn't have, and informs it | 279 | * capabilities that the now-obsolete mc146818 didn't have, and informs it |
@@ -283,11 +312,24 @@ static int __init acpi_rtc_init(void) | |||
283 | struct device *dev = get_rtc_dev(); | 312 | struct device *dev = get_rtc_dev(); |
284 | 313 | ||
285 | if (dev) { | 314 | if (dev) { |
315 | rtc_wake_setup(); | ||
316 | rtc_info.wake_on = rtc_wake_on; | ||
317 | rtc_info.wake_off = rtc_wake_off; | ||
318 | |||
319 | /* workaround bug in some ACPI tables */ | ||
320 | if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { | ||
321 | DBG("bogus FADT month_alarm\n"); | ||
322 | acpi_gbl_FADT.month_alarm = 0; | ||
323 | } | ||
324 | |||
286 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; | 325 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; |
287 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; | 326 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; |
288 | rtc_info.rtc_century = acpi_gbl_FADT.century; | 327 | rtc_info.rtc_century = acpi_gbl_FADT.century; |
289 | 328 | ||
290 | /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ | 329 | /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ |
330 | if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) | ||
331 | printk(PREFIX "RTC can wake from S4\n"); | ||
332 | |||
291 | 333 | ||
292 | dev->platform_data = &rtc_info; | 334 | dev->platform_data = &rtc_info; |
293 | 335 | ||
@@ -296,7 +338,7 @@ static int __init acpi_rtc_init(void) | |||
296 | 338 | ||
297 | put_device(dev); | 339 | put_device(dev); |
298 | } else | 340 | } else |
299 | pr_debug("ACPI: RTC unavailable?\n"); | 341 | DBG("RTC unavailable?\n"); |
300 | return 0; | 342 | return 0; |
301 | } | 343 | } |
302 | /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ | 344 | /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 8fcd6a15517f..4dd0dabe81cb 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -228,7 +228,7 @@ int __init acpi_numa_init(void) | |||
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
230 | 230 | ||
231 | int acpi_get_pxm(acpi_handle h) | 231 | int __meminit acpi_get_pxm(acpi_handle h) |
232 | { | 232 | { |
233 | unsigned long pxm; | 233 | unsigned long pxm; |
234 | acpi_status status; | 234 | acpi_status status; |
@@ -246,7 +246,7 @@ int acpi_get_pxm(acpi_handle h) | |||
246 | } | 246 | } |
247 | EXPORT_SYMBOL(acpi_get_pxm); | 247 | EXPORT_SYMBOL(acpi_get_pxm); |
248 | 248 | ||
249 | int acpi_get_node(acpi_handle *handle) | 249 | int __meminit acpi_get_node(acpi_handle *handle) |
250 | { | 250 | { |
251 | int pxm, node = -1; | 251 | int pxm, node = -1; |
252 | 252 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 971eca4864fa..c2bed56915e1 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
35 | #include <linux/kmod.h> | 34 | #include <linux/kmod.h> |
36 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d80dd84e5bfd..6b3b8a522476 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -302,7 +302,7 @@ static void acpi_device_shutdown(struct device *dev) | |||
302 | return ; | 302 | return ; |
303 | } | 303 | } |
304 | 304 | ||
305 | static struct bus_type acpi_bus_type = { | 305 | struct bus_type acpi_bus_type = { |
306 | .name = "acpi", | 306 | .name = "acpi", |
307 | .suspend = acpi_device_suspend, | 307 | .suspend = acpi_device_suspend, |
308 | .resume = acpi_device_resume, | 308 | .resume = acpi_device_resume, |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index dcde9ddd105a..5a76e5be61d5 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -70,6 +70,14 @@ acpi_system_write_sleep(struct file *file, | |||
70 | } | 70 | } |
71 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 71 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ |
72 | 72 | ||
73 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | ||
74 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | ||
75 | #else | ||
76 | #define HAVE_ACPI_LEGACY_ALARM | ||
77 | #endif | ||
78 | |||
79 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
80 | |||
73 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | 81 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) |
74 | { | 82 | { |
75 | u32 sec, min, hr; | 83 | u32 sec, min, hr; |
@@ -341,6 +349,8 @@ acpi_system_write_alarm(struct file *file, | |||
341 | end: | 349 | end: |
342 | return_VALUE(result ? result : count); | 350 | return_VALUE(result ? result : count); |
343 | } | 351 | } |
352 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
353 | |||
344 | 354 | ||
345 | extern struct list_head acpi_wakeup_device_list; | 355 | extern struct list_head acpi_wakeup_device_list; |
346 | extern spinlock_t acpi_device_lock; | 356 | extern spinlock_t acpi_device_lock; |
@@ -464,6 +474,7 @@ static const struct file_operations acpi_system_sleep_fops = { | |||
464 | }; | 474 | }; |
465 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ | 475 | #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ |
466 | 476 | ||
477 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
467 | static const struct file_operations acpi_system_alarm_fops = { | 478 | static const struct file_operations acpi_system_alarm_fops = { |
468 | .open = acpi_system_alarm_open_fs, | 479 | .open = acpi_system_alarm_open_fs, |
469 | .read = seq_read, | 480 | .read = seq_read, |
@@ -479,8 +490,9 @@ static u32 rtc_handler(void *context) | |||
479 | 490 | ||
480 | return ACPI_INTERRUPT_HANDLED; | 491 | return ACPI_INTERRUPT_HANDLED; |
481 | } | 492 | } |
493 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
482 | 494 | ||
483 | static int acpi_sleep_proc_init(void) | 495 | static int __init acpi_sleep_proc_init(void) |
484 | { | 496 | { |
485 | struct proc_dir_entry *entry = NULL; | 497 | struct proc_dir_entry *entry = NULL; |
486 | 498 | ||
@@ -496,6 +508,7 @@ static int acpi_sleep_proc_init(void) | |||
496 | entry->proc_fops = &acpi_system_sleep_fops; | 508 | entry->proc_fops = &acpi_system_sleep_fops; |
497 | #endif | 509 | #endif |
498 | 510 | ||
511 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
499 | /* 'alarm' [R/W] */ | 512 | /* 'alarm' [R/W] */ |
500 | entry = | 513 | entry = |
501 | create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, | 514 | create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, |
@@ -503,6 +516,9 @@ static int acpi_sleep_proc_init(void) | |||
503 | if (entry) | 516 | if (entry) |
504 | entry->proc_fops = &acpi_system_alarm_fops; | 517 | entry->proc_fops = &acpi_system_alarm_fops; |
505 | 518 | ||
519 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
520 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
521 | |||
506 | /* 'wakeup device' [R/W] */ | 522 | /* 'wakeup device' [R/W] */ |
507 | entry = | 523 | entry = |
508 | create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, | 524 | create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, |
@@ -510,7 +526,6 @@ static int acpi_sleep_proc_init(void) | |||
510 | if (entry) | 526 | if (entry) |
511 | entry->proc_fops = &acpi_system_wakeup_device_fops; | 527 | entry->proc_fops = &acpi_system_wakeup_device_fops; |
512 | 528 | ||
513 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
514 | return 0; | 529 | return 0; |
515 | } | 530 | } |
516 | 531 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 17b5ece8f82c..eb84d9d44645 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -160,6 +160,11 @@ static void platform_device_release(struct device *dev) | |||
160 | * | 160 | * |
161 | * Create a platform device object which can have other objects attached | 161 | * Create a platform device object which can have other objects attached |
162 | * to it, and which will have attached objects freed when it is released. | 162 | * to it, and which will have attached objects freed when it is released. |
163 | * | ||
164 | * This device will be marked as not supporting hotpluggable drivers; no | ||
165 | * device add/remove uevents will be generated. In the unusual case that | ||
166 | * the device isn't being dynamically allocated as a legacy "probe the | ||
167 | * hardware" driver, infrastructure code should reverse this marking. | ||
163 | */ | 168 | */ |
164 | struct platform_device *platform_device_alloc(const char *name, unsigned int id) | 169 | struct platform_device *platform_device_alloc(const char *name, unsigned int id) |
165 | { | 170 | { |
@@ -172,6 +177,12 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id) | |||
172 | pa->pdev.id = id; | 177 | pa->pdev.id = id; |
173 | device_initialize(&pa->pdev.dev); | 178 | device_initialize(&pa->pdev.dev); |
174 | pa->pdev.dev.release = platform_device_release; | 179 | pa->pdev.dev.release = platform_device_release; |
180 | |||
181 | /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in | ||
182 | * legacy probe-the-hardware drivers, which don't properly split | ||
183 | * out device enumeration logic from drivers. | ||
184 | */ | ||
185 | pa->pdev.dev.uevent_suppress = 1; | ||
175 | } | 186 | } |
176 | 187 | ||
177 | return pa ? &pa->pdev : NULL; | 188 | return pa ? &pa->pdev : NULL; |
@@ -351,6 +362,13 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); | |||
351 | * memory allocated for the device allows drivers using such devices | 362 | * memory allocated for the device allows drivers using such devices |
352 | * to be unloaded iwithout waiting for the last reference to the device | 363 | * to be unloaded iwithout waiting for the last reference to the device |
353 | * to be dropped. | 364 | * to be dropped. |
365 | * | ||
366 | * This interface is primarily intended for use with legacy drivers | ||
367 | * which probe hardware directly. Because such drivers create sysfs | ||
368 | * device nodes themselves, rather than letting system infrastructure | ||
369 | * handle such device enumeration tasks, they don't fully conform to | ||
370 | * the Linux driver model. In particular, when such drivers are built | ||
371 | * as modules, they can't be "hotplugged". | ||
354 | */ | 372 | */ |
355 | struct platform_device *platform_device_register_simple(char *name, unsigned int id, | 373 | struct platform_device *platform_device_register_simple(char *name, unsigned int id, |
356 | struct resource *res, unsigned int num) | 374 | struct resource *res, unsigned int num) |
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c index e2e043290963..1d9d9b4f48cc 100644 --- a/drivers/block/acsi_slm.c +++ b/drivers/block/acsi_slm.c | |||
@@ -65,7 +65,6 @@ not be guaranteed. There are several ways to assure this: | |||
65 | #include <linux/time.h> | 65 | #include <linux/time.h> |
66 | #include <linux/mm.h> | 66 | #include <linux/mm.h> |
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <linux/smp_lock.h> | ||
69 | 68 | ||
70 | #include <asm/pgtable.h> | 69 | #include <asm/pgtable.h> |
71 | #include <asm/system.h> | 70 | #include <asm/system.h> |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 65a725cd3422..370dfe1c422e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -45,6 +45,10 @@ | |||
45 | #include <linux/blkdev.h> | 45 | #include <linux/blkdev.h> |
46 | #include <linux/genhd.h> | 46 | #include <linux/genhd.h> |
47 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
48 | #include <scsi/scsi.h> | ||
49 | #include <scsi/sg.h> | ||
50 | #include <scsi/scsi_ioctl.h> | ||
51 | #include <linux/cdrom.h> | ||
48 | 52 | ||
49 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 53 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
50 | #define DRIVER_NAME "HP CISS Driver (v 3.6.14)" | 54 | #define DRIVER_NAME "HP CISS Driver (v 3.6.14)" |
@@ -1152,6 +1156,30 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
1152 | kfree(ioc); | 1156 | kfree(ioc); |
1153 | return status; | 1157 | return status; |
1154 | } | 1158 | } |
1159 | |||
1160 | /* scsi_cmd_ioctl handles these, below, though some are not */ | ||
1161 | /* very meaningful for cciss. SG_IO is the main one people want. */ | ||
1162 | |||
1163 | case SG_GET_VERSION_NUM: | ||
1164 | case SG_SET_TIMEOUT: | ||
1165 | case SG_GET_TIMEOUT: | ||
1166 | case SG_GET_RESERVED_SIZE: | ||
1167 | case SG_SET_RESERVED_SIZE: | ||
1168 | case SG_EMULATED_HOST: | ||
1169 | case SG_IO: | ||
1170 | case SCSI_IOCTL_SEND_COMMAND: | ||
1171 | return scsi_cmd_ioctl(filep, disk, cmd, argp); | ||
1172 | |||
1173 | /* scsi_cmd_ioctl would normally handle these, below, but */ | ||
1174 | /* they aren't a good fit for cciss, as CD-ROMs are */ | ||
1175 | /* not supported, and we don't have any bus/target/lun */ | ||
1176 | /* which we present to the kernel. */ | ||
1177 | |||
1178 | case CDROM_SEND_PACKET: | ||
1179 | case CDROMCLOSETRAY: | ||
1180 | case CDROMEJECT: | ||
1181 | case SCSI_IOCTL_GET_IDLUN: | ||
1182 | case SCSI_IOCTL_GET_BUS_NUMBER: | ||
1155 | default: | 1183 | default: |
1156 | return -ENOTTY; | 1184 | return -ENOTTY; |
1157 | } | 1185 | } |
@@ -1234,7 +1262,7 @@ static void cciss_softirq_done(struct request *rq) | |||
1234 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); | 1262 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); |
1235 | } | 1263 | } |
1236 | 1264 | ||
1237 | complete_buffers(rq->bio, rq->errors); | 1265 | complete_buffers(rq->bio, (rq->errors == 0)); |
1238 | 1266 | ||
1239 | if (blk_fs_request(rq)) { | 1267 | if (blk_fs_request(rq)) { |
1240 | const int rw = rq_data_dir(rq); | 1268 | const int rw = rq_data_dir(rq); |
@@ -1248,7 +1276,7 @@ static void cciss_softirq_done(struct request *rq) | |||
1248 | 1276 | ||
1249 | add_disk_randomness(rq->rq_disk); | 1277 | add_disk_randomness(rq->rq_disk); |
1250 | spin_lock_irqsave(&h->lock, flags); | 1278 | spin_lock_irqsave(&h->lock, flags); |
1251 | end_that_request_last(rq, rq->errors); | 1279 | end_that_request_last(rq, (rq->errors == 0)); |
1252 | cmd_free(h, cmd, 1); | 1280 | cmd_free(h, cmd, 1); |
1253 | cciss_check_queues(h); | 1281 | cciss_check_queues(h); |
1254 | spin_unlock_irqrestore(&h->lock, flags); | 1282 | spin_unlock_irqrestore(&h->lock, flags); |
@@ -2336,6 +2364,44 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) | |||
2336 | start_io(h); | 2364 | start_io(h); |
2337 | } | 2365 | } |
2338 | 2366 | ||
2367 | static inline int evaluate_target_status(CommandList_struct *cmd) | ||
2368 | { | ||
2369 | unsigned char sense_key; | ||
2370 | int error_count = 1; | ||
2371 | |||
2372 | if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */ | ||
2373 | if (!blk_pc_request(cmd->rq)) | ||
2374 | printk(KERN_WARNING "cciss: cmd %p " | ||
2375 | "has SCSI Status 0x%x\n", | ||
2376 | cmd, cmd->err_info->ScsiStatus); | ||
2377 | return error_count; | ||
2378 | } | ||
2379 | |||
2380 | /* check the sense key */ | ||
2381 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; | ||
2382 | /* no status or recovered error */ | ||
2383 | if ((sense_key == 0x0) || (sense_key == 0x1)) | ||
2384 | error_count = 0; | ||
2385 | |||
2386 | if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ | ||
2387 | if (error_count != 0) | ||
2388 | printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" | ||
2389 | " sense key = 0x%x\n", cmd, sense_key); | ||
2390 | return error_count; | ||
2391 | } | ||
2392 | |||
2393 | /* SG_IO or similar, copy sense data back */ | ||
2394 | if (cmd->rq->sense) { | ||
2395 | if (cmd->rq->sense_len > cmd->err_info->SenseLen) | ||
2396 | cmd->rq->sense_len = cmd->err_info->SenseLen; | ||
2397 | memcpy(cmd->rq->sense, cmd->err_info->SenseInfo, | ||
2398 | cmd->rq->sense_len); | ||
2399 | } else | ||
2400 | cmd->rq->sense_len = 0; | ||
2401 | |||
2402 | return error_count; | ||
2403 | } | ||
2404 | |||
2339 | /* checks the status of the job and calls complete buffers to mark all | 2405 | /* checks the status of the job and calls complete buffers to mark all |
2340 | * buffers for the completed job. Note that this function does not need | 2406 | * buffers for the completed job. Note that this function does not need |
2341 | * to hold the hba/queue lock. | 2407 | * to hold the hba/queue lock. |
@@ -2343,109 +2409,99 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) | |||
2343 | static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, | 2409 | static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, |
2344 | int timeout) | 2410 | int timeout) |
2345 | { | 2411 | { |
2346 | int status = 1; | ||
2347 | int retry_cmd = 0; | 2412 | int retry_cmd = 0; |
2413 | struct request *rq = cmd->rq; | ||
2414 | |||
2415 | rq->errors = 0; | ||
2348 | 2416 | ||
2349 | if (timeout) | 2417 | if (timeout) |
2350 | status = 0; | 2418 | rq->errors = 1; |
2351 | 2419 | ||
2352 | if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */ | 2420 | if (cmd->err_info->CommandStatus == 0) /* no error has occurred */ |
2353 | switch (cmd->err_info->CommandStatus) { | 2421 | goto after_error_processing; |
2354 | unsigned char sense_key; | ||
2355 | case CMD_TARGET_STATUS: | ||
2356 | status = 0; | ||
2357 | 2422 | ||
2358 | if (cmd->err_info->ScsiStatus == 0x02) { | 2423 | switch (cmd->err_info->CommandStatus) { |
2359 | printk(KERN_WARNING "cciss: cmd %p " | 2424 | case CMD_TARGET_STATUS: |
2360 | "has CHECK CONDITION " | 2425 | rq->errors = evaluate_target_status(cmd); |
2361 | " byte 2 = 0x%x\n", cmd, | 2426 | break; |
2362 | cmd->err_info->SenseInfo[2] | 2427 | case CMD_DATA_UNDERRUN: |
2363 | ); | 2428 | if (blk_fs_request(cmd->rq)) { |
2364 | /* check the sense key */ | ||
2365 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; | ||
2366 | /* no status or recovered error */ | ||
2367 | if ((sense_key == 0x0) || (sense_key == 0x1)) { | ||
2368 | status = 1; | ||
2369 | } | ||
2370 | } else { | ||
2371 | printk(KERN_WARNING "cciss: cmd %p " | ||
2372 | "has SCSI Status 0x%x\n", | ||
2373 | cmd, cmd->err_info->ScsiStatus); | ||
2374 | } | ||
2375 | break; | ||
2376 | case CMD_DATA_UNDERRUN: | ||
2377 | printk(KERN_WARNING "cciss: cmd %p has" | 2429 | printk(KERN_WARNING "cciss: cmd %p has" |
2378 | " completed with data underrun " | 2430 | " completed with data underrun " |
2379 | "reported\n", cmd); | 2431 | "reported\n", cmd); |
2380 | break; | 2432 | cmd->rq->data_len = cmd->err_info->ResidualCnt; |
2381 | case CMD_DATA_OVERRUN: | 2433 | } |
2434 | break; | ||
2435 | case CMD_DATA_OVERRUN: | ||
2436 | if (blk_fs_request(cmd->rq)) | ||
2382 | printk(KERN_WARNING "cciss: cmd %p has" | 2437 | printk(KERN_WARNING "cciss: cmd %p has" |
2383 | " completed with data overrun " | 2438 | " completed with data overrun " |
2384 | "reported\n", cmd); | 2439 | "reported\n", cmd); |
2385 | break; | 2440 | break; |
2386 | case CMD_INVALID: | 2441 | case CMD_INVALID: |
2387 | printk(KERN_WARNING "cciss: cmd %p is " | 2442 | printk(KERN_WARNING "cciss: cmd %p is " |
2388 | "reported invalid\n", cmd); | 2443 | "reported invalid\n", cmd); |
2389 | status = 0; | 2444 | rq->errors = 1; |
2390 | break; | 2445 | break; |
2391 | case CMD_PROTOCOL_ERR: | 2446 | case CMD_PROTOCOL_ERR: |
2392 | printk(KERN_WARNING "cciss: cmd %p has " | 2447 | printk(KERN_WARNING "cciss: cmd %p has " |
2393 | "protocol error \n", cmd); | 2448 | "protocol error \n", cmd); |
2394 | status = 0; | 2449 | rq->errors = 1; |
2395 | break; | 2450 | break; |
2396 | case CMD_HARDWARE_ERR: | 2451 | case CMD_HARDWARE_ERR: |
2397 | printk(KERN_WARNING "cciss: cmd %p had " | 2452 | printk(KERN_WARNING "cciss: cmd %p had " |
2398 | " hardware error\n", cmd); | 2453 | " hardware error\n", cmd); |
2399 | status = 0; | 2454 | rq->errors = 1; |
2400 | break; | 2455 | break; |
2401 | case CMD_CONNECTION_LOST: | 2456 | case CMD_CONNECTION_LOST: |
2402 | printk(KERN_WARNING "cciss: cmd %p had " | 2457 | printk(KERN_WARNING "cciss: cmd %p had " |
2403 | "connection lost\n", cmd); | 2458 | "connection lost\n", cmd); |
2404 | status = 0; | 2459 | rq->errors = 1; |
2405 | break; | 2460 | break; |
2406 | case CMD_ABORTED: | 2461 | case CMD_ABORTED: |
2407 | printk(KERN_WARNING "cciss: cmd %p was " | 2462 | printk(KERN_WARNING "cciss: cmd %p was " |
2408 | "aborted\n", cmd); | 2463 | "aborted\n", cmd); |
2409 | status = 0; | 2464 | rq->errors = 1; |
2410 | break; | 2465 | break; |
2411 | case CMD_ABORT_FAILED: | 2466 | case CMD_ABORT_FAILED: |
2412 | printk(KERN_WARNING "cciss: cmd %p reports " | 2467 | printk(KERN_WARNING "cciss: cmd %p reports " |
2413 | "abort failed\n", cmd); | 2468 | "abort failed\n", cmd); |
2414 | status = 0; | 2469 | rq->errors = 1; |
2415 | break; | 2470 | break; |
2416 | case CMD_UNSOLICITED_ABORT: | 2471 | case CMD_UNSOLICITED_ABORT: |
2417 | printk(KERN_WARNING "cciss%d: unsolicited " | 2472 | printk(KERN_WARNING "cciss%d: unsolicited " |
2418 | "abort %p\n", h->ctlr, cmd); | 2473 | "abort %p\n", h->ctlr, cmd); |
2419 | if (cmd->retry_count < MAX_CMD_RETRIES) { | 2474 | if (cmd->retry_count < MAX_CMD_RETRIES) { |
2420 | retry_cmd = 1; | 2475 | retry_cmd = 1; |
2421 | printk(KERN_WARNING | 2476 | printk(KERN_WARNING |
2422 | "cciss%d: retrying %p\n", h->ctlr, cmd); | 2477 | "cciss%d: retrying %p\n", h->ctlr, cmd); |
2423 | cmd->retry_count++; | 2478 | cmd->retry_count++; |
2424 | } else | 2479 | } else |
2425 | printk(KERN_WARNING | 2480 | printk(KERN_WARNING |
2426 | "cciss%d: %p retried too " | 2481 | "cciss%d: %p retried too " |
2427 | "many times\n", h->ctlr, cmd); | 2482 | "many times\n", h->ctlr, cmd); |
2428 | status = 0; | 2483 | rq->errors = 1; |
2429 | break; | 2484 | break; |
2430 | case CMD_TIMEOUT: | 2485 | case CMD_TIMEOUT: |
2431 | printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); | 2486 | printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); |
2432 | status = 0; | 2487 | rq->errors = 1; |
2433 | break; | 2488 | break; |
2434 | default: | 2489 | default: |
2435 | printk(KERN_WARNING "cciss: cmd %p returned " | 2490 | printk(KERN_WARNING "cciss: cmd %p returned " |
2436 | "unknown status %x\n", cmd, | 2491 | "unknown status %x\n", cmd, |
2437 | cmd->err_info->CommandStatus); | 2492 | cmd->err_info->CommandStatus); |
2438 | status = 0; | 2493 | rq->errors = 1; |
2439 | } | ||
2440 | } | 2494 | } |
2495 | |||
2496 | after_error_processing: | ||
2497 | |||
2441 | /* We need to return this command */ | 2498 | /* We need to return this command */ |
2442 | if (retry_cmd) { | 2499 | if (retry_cmd) { |
2443 | resend_cciss_cmd(h, cmd); | 2500 | resend_cciss_cmd(h, cmd); |
2444 | return; | 2501 | return; |
2445 | } | 2502 | } |
2446 | 2503 | cmd->rq->data_len = 0; | |
2447 | cmd->rq->completion_data = cmd; | 2504 | cmd->rq->completion_data = cmd; |
2448 | cmd->rq->errors = status; | ||
2449 | blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); | 2505 | blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); |
2450 | blk_complete_request(cmd->rq); | 2506 | blk_complete_request(cmd->rq); |
2451 | } | 2507 | } |
@@ -2539,32 +2595,40 @@ static void do_cciss_request(request_queue_t *q) | |||
2539 | #endif /* CCISS_DEBUG */ | 2595 | #endif /* CCISS_DEBUG */ |
2540 | 2596 | ||
2541 | c->Header.SGList = c->Header.SGTotal = seg; | 2597 | c->Header.SGList = c->Header.SGTotal = seg; |
2542 | if(h->cciss_read == CCISS_READ_10) { | 2598 | if (likely(blk_fs_request(creq))) { |
2543 | c->Request.CDB[1] = 0; | 2599 | if(h->cciss_read == CCISS_READ_10) { |
2544 | c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB | 2600 | c->Request.CDB[1] = 0; |
2545 | c->Request.CDB[3] = (start_blk >> 16) & 0xff; | 2601 | c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB |
2546 | c->Request.CDB[4] = (start_blk >> 8) & 0xff; | 2602 | c->Request.CDB[3] = (start_blk >> 16) & 0xff; |
2547 | c->Request.CDB[5] = start_blk & 0xff; | 2603 | c->Request.CDB[4] = (start_blk >> 8) & 0xff; |
2548 | c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB | 2604 | c->Request.CDB[5] = start_blk & 0xff; |
2549 | c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; | 2605 | c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB |
2550 | c->Request.CDB[8] = creq->nr_sectors & 0xff; | 2606 | c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; |
2551 | c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; | 2607 | c->Request.CDB[8] = creq->nr_sectors & 0xff; |
2608 | c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; | ||
2609 | } else { | ||
2610 | c->Request.CDBLen = 16; | ||
2611 | c->Request.CDB[1]= 0; | ||
2612 | c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB | ||
2613 | c->Request.CDB[3]= (start_blk >> 48) & 0xff; | ||
2614 | c->Request.CDB[4]= (start_blk >> 40) & 0xff; | ||
2615 | c->Request.CDB[5]= (start_blk >> 32) & 0xff; | ||
2616 | c->Request.CDB[6]= (start_blk >> 24) & 0xff; | ||
2617 | c->Request.CDB[7]= (start_blk >> 16) & 0xff; | ||
2618 | c->Request.CDB[8]= (start_blk >> 8) & 0xff; | ||
2619 | c->Request.CDB[9]= start_blk & 0xff; | ||
2620 | c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; | ||
2621 | c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; | ||
2622 | c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; | ||
2623 | c->Request.CDB[13]= creq->nr_sectors & 0xff; | ||
2624 | c->Request.CDB[14] = c->Request.CDB[15] = 0; | ||
2625 | } | ||
2626 | } else if (blk_pc_request(creq)) { | ||
2627 | c->Request.CDBLen = creq->cmd_len; | ||
2628 | memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); | ||
2552 | } else { | 2629 | } else { |
2553 | c->Request.CDBLen = 16; | 2630 | printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type); |
2554 | c->Request.CDB[1]= 0; | 2631 | BUG(); |
2555 | c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB | ||
2556 | c->Request.CDB[3]= (start_blk >> 48) & 0xff; | ||
2557 | c->Request.CDB[4]= (start_blk >> 40) & 0xff; | ||
2558 | c->Request.CDB[5]= (start_blk >> 32) & 0xff; | ||
2559 | c->Request.CDB[6]= (start_blk >> 24) & 0xff; | ||
2560 | c->Request.CDB[7]= (start_blk >> 16) & 0xff; | ||
2561 | c->Request.CDB[8]= (start_blk >> 8) & 0xff; | ||
2562 | c->Request.CDB[9]= start_blk & 0xff; | ||
2563 | c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; | ||
2564 | c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; | ||
2565 | c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; | ||
2566 | c->Request.CDB[13]= creq->nr_sectors & 0xff; | ||
2567 | c->Request.CDB[14] = c->Request.CDB[15] = 0; | ||
2568 | } | 2632 | } |
2569 | 2633 | ||
2570 | spin_lock_irq(q->queue_lock); | 2634 | spin_lock_irq(q->queue_lock); |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index bb15051ffbe0..90961a8ea895 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
37 | 37 | ||
38 | #include <scsi/scsi.h> | ||
39 | #include <scsi/scsi_cmnd.h> | 38 | #include <scsi/scsi_cmnd.h> |
40 | #include <scsi/scsi_device.h> | 39 | #include <scsi/scsi_device.h> |
41 | #include <scsi/scsi_host.h> | 40 | #include <scsi/scsi_host.h> |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 5231ed7e723f..3587cb434371 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -4334,7 +4334,10 @@ static int __init floppy_init(void) | |||
4334 | if (err) | 4334 | if (err) |
4335 | goto out_flush_work; | 4335 | goto out_flush_work; |
4336 | 4336 | ||
4337 | device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); | 4337 | err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); |
4338 | if (err) | ||
4339 | goto out_unreg_platform_dev; | ||
4340 | |||
4338 | /* to be cleaned up... */ | 4341 | /* to be cleaned up... */ |
4339 | disks[drive]->private_data = (void *)(long)drive; | 4342 | disks[drive]->private_data = (void *)(long)drive; |
4340 | disks[drive]->queue = floppy_queue; | 4343 | disks[drive]->queue = floppy_queue; |
@@ -4345,6 +4348,8 @@ static int __init floppy_init(void) | |||
4345 | 4348 | ||
4346 | return 0; | 4349 | return 0; |
4347 | 4350 | ||
4351 | out_unreg_platform_dev: | ||
4352 | platform_device_unregister(&floppy_device[drive]); | ||
4348 | out_flush_work: | 4353 | out_flush_work: |
4349 | flush_scheduled_work(); | 4354 | flush_scheduled_work(); |
4350 | if (usage_count) | 4355 | if (usage_count) |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0d4ccd4a0957..af6d7274a7cc 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -77,9 +77,8 @@ | |||
77 | 77 | ||
78 | #include <asm/uaccess.h> | 78 | #include <asm/uaccess.h> |
79 | 79 | ||
80 | static int max_loop = 8; | 80 | static LIST_HEAD(loop_devices); |
81 | static struct loop_device *loop_dev; | 81 | static DEFINE_MUTEX(loop_devices_mutex); |
82 | static struct gendisk **disks; | ||
83 | 82 | ||
84 | /* | 83 | /* |
85 | * Transfer functions | 84 | * Transfer functions |
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo) | |||
183 | if (unlikely((loff_t)x != size)) | 182 | if (unlikely((loff_t)x != size)) |
184 | return -EFBIG; | 183 | return -EFBIG; |
185 | 184 | ||
186 | set_capacity(disks[lo->lo_number], x); | 185 | set_capacity(lo->lo_disk, x); |
187 | return 0; | 186 | return 0; |
188 | } | 187 | } |
189 | 188 | ||
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
812 | lo->lo_queue->queuedata = lo; | 811 | lo->lo_queue->queuedata = lo; |
813 | lo->lo_queue->unplug_fn = loop_unplug; | 812 | lo->lo_queue->unplug_fn = loop_unplug; |
814 | 813 | ||
815 | set_capacity(disks[lo->lo_number], size); | 814 | set_capacity(lo->lo_disk, size); |
816 | bd_set_size(bdev, size << 9); | 815 | bd_set_size(bdev, size << 9); |
817 | 816 | ||
818 | set_blocksize(bdev, lo_blocksize); | 817 | set_blocksize(bdev, lo_blocksize); |
@@ -832,7 +831,7 @@ out_clr: | |||
832 | lo->lo_device = NULL; | 831 | lo->lo_device = NULL; |
833 | lo->lo_backing_file = NULL; | 832 | lo->lo_backing_file = NULL; |
834 | lo->lo_flags = 0; | 833 | lo->lo_flags = 0; |
835 | set_capacity(disks[lo->lo_number], 0); | 834 | set_capacity(lo->lo_disk, 0); |
836 | invalidate_bdev(bdev); | 835 | invalidate_bdev(bdev); |
837 | bd_set_size(bdev, 0); | 836 | bd_set_size(bdev, 0); |
838 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask); | 837 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask); |
@@ -918,7 +917,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
918 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 917 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
919 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); | 918 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
920 | invalidate_bdev(bdev); | 919 | invalidate_bdev(bdev); |
921 | set_capacity(disks[lo->lo_number], 0); | 920 | set_capacity(lo->lo_disk, 0); |
922 | bd_set_size(bdev, 0); | 921 | bd_set_size(bdev, 0); |
923 | mapping_set_gfp_mask(filp->f_mapping, gfp); | 922 | mapping_set_gfp_mask(filp->f_mapping, gfp); |
924 | lo->lo_state = Lo_unbound; | 923 | lo->lo_state = Lo_unbound; |
@@ -1322,6 +1321,18 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a | |||
1322 | } | 1321 | } |
1323 | #endif | 1322 | #endif |
1324 | 1323 | ||
1324 | static struct loop_device *loop_find_dev(int number) | ||
1325 | { | ||
1326 | struct loop_device *lo; | ||
1327 | |||
1328 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1329 | if (lo->lo_number == number) | ||
1330 | return lo; | ||
1331 | } | ||
1332 | return NULL; | ||
1333 | } | ||
1334 | |||
1335 | static struct loop_device *loop_init_one(int i); | ||
1325 | static int lo_open(struct inode *inode, struct file *file) | 1336 | static int lo_open(struct inode *inode, struct file *file) |
1326 | { | 1337 | { |
1327 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1338 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; |
@@ -1330,6 +1341,11 @@ static int lo_open(struct inode *inode, struct file *file) | |||
1330 | lo->lo_refcnt++; | 1341 | lo->lo_refcnt++; |
1331 | mutex_unlock(&lo->lo_ctl_mutex); | 1342 | mutex_unlock(&lo->lo_ctl_mutex); |
1332 | 1343 | ||
1344 | mutex_lock(&loop_devices_mutex); | ||
1345 | if (!loop_find_dev(lo->lo_number + 1)) | ||
1346 | loop_init_one(lo->lo_number + 1); | ||
1347 | mutex_unlock(&loop_devices_mutex); | ||
1348 | |||
1333 | return 0; | 1349 | return 0; |
1334 | } | 1350 | } |
1335 | 1351 | ||
@@ -1357,8 +1373,9 @@ static struct block_device_operations lo_fops = { | |||
1357 | /* | 1373 | /* |
1358 | * And now the modules code and kernel interface. | 1374 | * And now the modules code and kernel interface. |
1359 | */ | 1375 | */ |
1376 | static int max_loop; | ||
1360 | module_param(max_loop, int, 0); | 1377 | module_param(max_loop, int, 0); |
1361 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)"); | 1378 | MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand"); |
1362 | MODULE_LICENSE("GPL"); | 1379 | MODULE_LICENSE("GPL"); |
1363 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); | 1380 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); |
1364 | 1381 | ||
@@ -1383,7 +1400,7 @@ int loop_unregister_transfer(int number) | |||
1383 | 1400 | ||
1384 | xfer_funcs[n] = NULL; | 1401 | xfer_funcs[n] = NULL; |
1385 | 1402 | ||
1386 | for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { | 1403 | list_for_each_entry(lo, &loop_devices, lo_list) { |
1387 | mutex_lock(&lo->lo_ctl_mutex); | 1404 | mutex_lock(&lo->lo_ctl_mutex); |
1388 | 1405 | ||
1389 | if (lo->lo_encryption == xfer) | 1406 | if (lo->lo_encryption == xfer) |
@@ -1398,91 +1415,110 @@ int loop_unregister_transfer(int number) | |||
1398 | EXPORT_SYMBOL(loop_register_transfer); | 1415 | EXPORT_SYMBOL(loop_register_transfer); |
1399 | EXPORT_SYMBOL(loop_unregister_transfer); | 1416 | EXPORT_SYMBOL(loop_unregister_transfer); |
1400 | 1417 | ||
1401 | static int __init loop_init(void) | 1418 | static struct loop_device *loop_init_one(int i) |
1419 | { | ||
1420 | struct loop_device *lo; | ||
1421 | struct gendisk *disk; | ||
1422 | |||
1423 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); | ||
1424 | if (!lo) | ||
1425 | goto out; | ||
1426 | |||
1427 | lo->lo_queue = blk_alloc_queue(GFP_KERNEL); | ||
1428 | if (!lo->lo_queue) | ||
1429 | goto out_free_dev; | ||
1430 | |||
1431 | disk = lo->lo_disk = alloc_disk(1); | ||
1432 | if (!disk) | ||
1433 | goto out_free_queue; | ||
1434 | |||
1435 | mutex_init(&lo->lo_ctl_mutex); | ||
1436 | lo->lo_number = i; | ||
1437 | lo->lo_thread = NULL; | ||
1438 | init_waitqueue_head(&lo->lo_event); | ||
1439 | spin_lock_init(&lo->lo_lock); | ||
1440 | disk->major = LOOP_MAJOR; | ||
1441 | disk->first_minor = i; | ||
1442 | disk->fops = &lo_fops; | ||
1443 | disk->private_data = lo; | ||
1444 | disk->queue = lo->lo_queue; | ||
1445 | sprintf(disk->disk_name, "loop%d", i); | ||
1446 | add_disk(disk); | ||
1447 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1448 | return lo; | ||
1449 | |||
1450 | out_free_queue: | ||
1451 | blk_cleanup_queue(lo->lo_queue); | ||
1452 | out_free_dev: | ||
1453 | kfree(lo); | ||
1454 | out: | ||
1455 | return ERR_PTR(-ENOMEM); | ||
1456 | } | ||
1457 | |||
1458 | static void loop_del_one(struct loop_device *lo) | ||
1402 | { | 1459 | { |
1403 | int i; | 1460 | del_gendisk(lo->lo_disk); |
1461 | blk_cleanup_queue(lo->lo_queue); | ||
1462 | put_disk(lo->lo_disk); | ||
1463 | list_del(&lo->lo_list); | ||
1464 | kfree(lo); | ||
1465 | } | ||
1404 | 1466 | ||
1405 | if (max_loop < 1 || max_loop > 256) { | 1467 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) |
1406 | printk(KERN_WARNING "loop: invalid max_loop (must be between" | 1468 | { |
1407 | " 1 and 256), using default (8)\n"); | 1469 | unsigned int number = dev & MINORMASK; |
1408 | max_loop = 8; | 1470 | struct loop_device *lo; |
1409 | } | 1471 | |
1472 | mutex_lock(&loop_devices_mutex); | ||
1473 | lo = loop_find_dev(number); | ||
1474 | if (lo == NULL) | ||
1475 | lo = loop_init_one(number); | ||
1476 | mutex_unlock(&loop_devices_mutex); | ||
1477 | |||
1478 | *part = 0; | ||
1479 | if (IS_ERR(lo)) | ||
1480 | return (void *)lo; | ||
1481 | else | ||
1482 | return &lo->lo_disk->kobj; | ||
1483 | } | ||
1484 | |||
1485 | static int __init loop_init(void) | ||
1486 | { | ||
1487 | struct loop_device *lo; | ||
1410 | 1488 | ||
1411 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1489 | if (register_blkdev(LOOP_MAJOR, "loop")) |
1412 | return -EIO; | 1490 | return -EIO; |
1491 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, | ||
1492 | THIS_MODULE, loop_probe, NULL, NULL); | ||
1413 | 1493 | ||
1414 | loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); | 1494 | lo = loop_init_one(0); |
1415 | if (!loop_dev) | 1495 | if (IS_ERR(lo)) |
1416 | goto out_mem1; | 1496 | goto out; |
1417 | memset(loop_dev, 0, max_loop * sizeof(struct loop_device)); | ||
1418 | 1497 | ||
1419 | disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); | 1498 | if (max_loop) { |
1420 | if (!disks) | 1499 | printk(KERN_INFO "loop: the max_loop option is obsolete " |
1421 | goto out_mem2; | 1500 | "and will be removed in March 2008\n"); |
1422 | 1501 | ||
1423 | for (i = 0; i < max_loop; i++) { | ||
1424 | disks[i] = alloc_disk(1); | ||
1425 | if (!disks[i]) | ||
1426 | goto out_mem3; | ||
1427 | } | 1502 | } |
1428 | 1503 | printk(KERN_INFO "loop: module loaded\n"); | |
1429 | for (i = 0; i < max_loop; i++) { | ||
1430 | struct loop_device *lo = &loop_dev[i]; | ||
1431 | struct gendisk *disk = disks[i]; | ||
1432 | |||
1433 | memset(lo, 0, sizeof(*lo)); | ||
1434 | lo->lo_queue = blk_alloc_queue(GFP_KERNEL); | ||
1435 | if (!lo->lo_queue) | ||
1436 | goto out_mem4; | ||
1437 | mutex_init(&lo->lo_ctl_mutex); | ||
1438 | lo->lo_number = i; | ||
1439 | lo->lo_thread = NULL; | ||
1440 | init_waitqueue_head(&lo->lo_event); | ||
1441 | spin_lock_init(&lo->lo_lock); | ||
1442 | disk->major = LOOP_MAJOR; | ||
1443 | disk->first_minor = i; | ||
1444 | disk->fops = &lo_fops; | ||
1445 | sprintf(disk->disk_name, "loop%d", i); | ||
1446 | disk->private_data = lo; | ||
1447 | disk->queue = lo->lo_queue; | ||
1448 | } | ||
1449 | |||
1450 | /* We cannot fail after we call this, so another loop!*/ | ||
1451 | for (i = 0; i < max_loop; i++) | ||
1452 | add_disk(disks[i]); | ||
1453 | printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); | ||
1454 | return 0; | 1504 | return 0; |
1455 | 1505 | ||
1456 | out_mem4: | 1506 | out: |
1457 | while (i--) | ||
1458 | blk_cleanup_queue(loop_dev[i].lo_queue); | ||
1459 | i = max_loop; | ||
1460 | out_mem3: | ||
1461 | while (i--) | ||
1462 | put_disk(disks[i]); | ||
1463 | kfree(disks); | ||
1464 | out_mem2: | ||
1465 | kfree(loop_dev); | ||
1466 | out_mem1: | ||
1467 | unregister_blkdev(LOOP_MAJOR, "loop"); | 1507 | unregister_blkdev(LOOP_MAJOR, "loop"); |
1468 | printk(KERN_ERR "loop: ran out of memory\n"); | 1508 | printk(KERN_ERR "loop: ran out of memory\n"); |
1469 | return -ENOMEM; | 1509 | return -ENOMEM; |
1470 | } | 1510 | } |
1471 | 1511 | ||
1472 | static void loop_exit(void) | 1512 | static void __exit loop_exit(void) |
1473 | { | 1513 | { |
1474 | int i; | 1514 | struct loop_device *lo, *next; |
1475 | 1515 | ||
1476 | for (i = 0; i < max_loop; i++) { | 1516 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) |
1477 | del_gendisk(disks[i]); | 1517 | loop_del_one(lo); |
1478 | blk_cleanup_queue(loop_dev[i].lo_queue); | 1518 | |
1479 | put_disk(disks[i]); | 1519 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS); |
1480 | } | ||
1481 | if (unregister_blkdev(LOOP_MAJOR, "loop")) | 1520 | if (unregister_blkdev(LOOP_MAJOR, "loop")) |
1482 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); | 1521 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1483 | |||
1484 | kfree(disks); | ||
1485 | kfree(loop_dev); | ||
1486 | } | 1522 | } |
1487 | 1523 | ||
1488 | module_init(loop_init); | 1524 | module_init(loop_init); |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 5872036e8ae6..6f5d6203d725 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
47 | #include <linux/smp_lock.h> | ||
48 | #include <linux/timer.h> | 47 | #include <linux/timer.h> |
49 | #include <linux/pci.h> | 48 | #include <linux/pci.h> |
50 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index a26d91743b24..1e32fb834eb8 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -127,7 +127,7 @@ config ROCKETPORT | |||
127 | 127 | ||
128 | config CYCLADES | 128 | config CYCLADES |
129 | tristate "Cyclades async mux support" | 129 | tristate "Cyclades async mux support" |
130 | depends on SERIAL_NONSTANDARD | 130 | depends on SERIAL_NONSTANDARD && (PCI || ISA) |
131 | ---help--- | 131 | ---help--- |
132 | This driver supports Cyclades Z and Y multiserial boards. | 132 | This driver supports Cyclades Z and Y multiserial boards. |
133 | You would need something like this to connect more than two modems to | 133 | You would need something like this to connect more than two modems to |
@@ -1071,5 +1071,11 @@ config TELCLOCK | |||
1071 | /sys/devices/platform/telco_clock, with a number of files for | 1071 | /sys/devices/platform/telco_clock, with a number of files for |
1072 | controlling the behavior of this hardware. | 1072 | controlling the behavior of this hardware. |
1073 | 1073 | ||
1074 | config DEVPORT | ||
1075 | bool | ||
1076 | depends on !M68K | ||
1077 | depends on ISA || PCI | ||
1078 | default y | ||
1079 | |||
1074 | endmenu | 1080 | endmenu |
1075 | 1081 | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 0e2b72f2b887..4eaceabd8cea 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1574,7 +1574,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1574 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 1574 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
1575 | break; | 1575 | break; |
1576 | } | 1576 | } |
1577 | current->state = TASK_RUNNING; | 1577 | __set_current_state(TASK_RUNNING); |
1578 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1578 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1579 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1579 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1580 | #endif | 1580 | #endif |
@@ -1700,7 +1700,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1700 | #endif | 1700 | #endif |
1701 | schedule(); | 1701 | schedule(); |
1702 | } | 1702 | } |
1703 | current->state = TASK_RUNNING; | 1703 | __set_current_state(TASK_RUNNING); |
1704 | remove_wait_queue(&info->open_wait, &wait); | 1704 | remove_wait_queue(&info->open_wait, &wait); |
1705 | if (extra_count) | 1705 | if (extra_count) |
1706 | state->count++; | 1706 | state->count++; |
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index b99b7561260d..fd40b959afdd 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
@@ -626,10 +626,10 @@ conv_uni_to_pc(struct vc_data *conp, long ucs) | |||
626 | 626 | ||
627 | /* Only 16-bit codes supported at this time */ | 627 | /* Only 16-bit codes supported at this time */ |
628 | if (ucs > 0xffff) | 628 | if (ucs > 0xffff) |
629 | ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ | 629 | return -4; /* Not found */ |
630 | else if (ucs < 0x20 || ucs >= 0xfffe) | 630 | else if (ucs < 0x20) |
631 | return -1; /* Not a printable character */ | 631 | return -1; /* Not a printable character */ |
632 | else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) | 632 | else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f)) |
633 | return -2; /* Zero-width space */ | 633 | return -2; /* Zero-width space */ |
634 | /* | 634 | /* |
635 | * UNI_DIRECT_BASE indicates the start of the region in the User Zone | 635 | * UNI_DIRECT_BASE indicates the start of the region in the User Zone |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index c02d9e99e050..fe6d2407baed 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -44,6 +44,7 @@ static struct pci_device_id divil_pci[] = { | |||
44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, |
45 | { } /* NULL entry */ | 45 | { } /* NULL entry */ |
46 | }; | 46 | }; |
47 | MODULE_DEVICE_TABLE(pci, divil_pci); | ||
47 | 48 | ||
48 | static struct cdev cs5535_gpio_cdev; | 49 | static struct cdev cs5535_gpio_cdev; |
49 | 50 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 16dc5d1d3cb4..c72ee97d3892 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -10,15 +10,14 @@ | |||
10 | * | 10 | * |
11 | * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. | 11 | * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. |
12 | * Modified and maintained by Marcio Saito <marcio@cyclades.com>. | 12 | * Modified and maintained by Marcio Saito <marcio@cyclades.com>. |
13 | * Currently maintained by Cyclades team <async@cyclades.com>. | ||
14 | * | 13 | * |
15 | * For Technical support and installation problems, please send e-mail | 14 | * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com> |
16 | * to support@cyclades.com. | ||
17 | * | 15 | * |
18 | * Much of the design and some of the code came from serial.c | 16 | * Much of the design and some of the code came from serial.c |
19 | * which was copyright (C) 1991, 1992 Linus Torvalds. It was | 17 | * which was copyright (C) 1991, 1992 Linus Torvalds. It was |
20 | * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, | 18 | * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, |
21 | * and then fixed as suggested by Michael K. Johnson 12/12/92. | 19 | * and then fixed as suggested by Michael K. Johnson 12/12/92. |
20 | * Converted to pci probing and cleaned up by Jiri Slaby. | ||
22 | * | 21 | * |
23 | * This version supports shared IRQ's (only for PCI boards). | 22 | * This version supports shared IRQ's (only for PCI boards). |
24 | * | 23 | * |
@@ -591,7 +590,7 @@ | |||
591 | * | 590 | * |
592 | */ | 591 | */ |
593 | 592 | ||
594 | #define CY_VERSION "2.4" | 593 | #define CY_VERSION "2.5" |
595 | 594 | ||
596 | /* If you need to install more boards than NR_CARDS, change the constant | 595 | /* If you need to install more boards than NR_CARDS, change the constant |
597 | in the definition below. No other change is necessary to support up to | 596 | in the definition below. No other change is necessary to support up to |
@@ -624,12 +623,6 @@ | |||
624 | #undef CY_ENABLE_MONITORING | 623 | #undef CY_ENABLE_MONITORING |
625 | #undef CY_PCI_DEBUG | 624 | #undef CY_PCI_DEBUG |
626 | 625 | ||
627 | #if 0 | ||
628 | #define PAUSE __asm__("nop") | ||
629 | #else | ||
630 | #define PAUSE do {} while (0) | ||
631 | #endif | ||
632 | |||
633 | /* | 626 | /* |
634 | * Include section | 627 | * Include section |
635 | */ | 628 | */ |
@@ -659,17 +652,6 @@ | |||
659 | #include <asm/irq.h> | 652 | #include <asm/irq.h> |
660 | #include <asm/uaccess.h> | 653 | #include <asm/uaccess.h> |
661 | 654 | ||
662 | #define CY_LOCK(info,flags) \ | ||
663 | do { \ | ||
664 | spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \ | ||
665 | } while (0) | ||
666 | |||
667 | #define CY_UNLOCK(info,flags) \ | ||
668 | do { \ | ||
669 | spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \ | ||
670 | } while (0) | ||
671 | |||
672 | #include <linux/types.h> | ||
673 | #include <linux/kernel.h> | 655 | #include <linux/kernel.h> |
674 | #include <linux/pci.h> | 656 | #include <linux/pci.h> |
675 | 657 | ||
@@ -682,13 +664,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch); | |||
682 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 664 | #define IS_CYC_Z(card) ((card).num_chips == -1) |
683 | 665 | ||
684 | #define Z_FPGA_CHECK(card) \ | 666 | #define Z_FPGA_CHECK(card) \ |
685 | ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 667 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
686 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) | 668 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) |
687 | 669 | ||
688 | #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 670 | #define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \ |
689 | ((card).ctl_addr))->mail_box_0)) || \ | 671 | ((card).ctl_addr))->mail_box_0)) || \ |
690 | Z_FPGA_CHECK(card)) && \ | 672 | Z_FPGA_CHECK(card)) && \ |
691 | (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \ | 673 | (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \ |
692 | ((card).base_addr+ID_ADDRESS))->signature))) | 674 | ((card).base_addr+ID_ADDRESS))->signature))) |
693 | 675 | ||
694 | #ifndef SERIAL_XMIT_SIZE | 676 | #ifndef SERIAL_XMIT_SIZE |
@@ -725,8 +707,8 @@ static unsigned int cy_isa_addresses[] = { | |||
725 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) | 707 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) |
726 | 708 | ||
727 | #ifdef MODULE | 709 | #ifdef MODULE |
728 | static long maddr[NR_CARDS] = { 0, }; | 710 | static long maddr[NR_CARDS]; |
729 | static int irq[NR_CARDS] = { 0, }; | 711 | static int irq[NR_CARDS]; |
730 | 712 | ||
731 | module_param_array(maddr, long, NULL, 0); | 713 | module_param_array(maddr, long, NULL, 0); |
732 | module_param_array(irq, int, NULL, 0); | 714 | module_param_array(irq, int, NULL, 0); |
@@ -739,11 +721,6 @@ module_param_array(irq, int, NULL, 0); | |||
739 | */ | 721 | */ |
740 | static struct cyclades_card cy_card[NR_CARDS]; | 722 | static struct cyclades_card cy_card[NR_CARDS]; |
741 | 723 | ||
742 | /* This is the per-channel data structure containing pointers, flags | ||
743 | and variables for the port. This driver supports a maximum of NR_PORTS. | ||
744 | */ | ||
745 | static struct cyclades_port cy_port[NR_PORTS]; | ||
746 | |||
747 | static int cy_next_channel; /* next minor available */ | 724 | static int cy_next_channel; /* next minor available */ |
748 | 725 | ||
749 | /* | 726 | /* |
@@ -825,9 +802,6 @@ static int cy_chip_offset[] = { 0x0000, | |||
825 | 802 | ||
826 | /* PCI related definitions */ | 803 | /* PCI related definitions */ |
827 | 804 | ||
828 | static unsigned short cy_pci_nboard; | ||
829 | static unsigned short cy_isa_nboard; | ||
830 | static unsigned short cy_nboard; | ||
831 | #ifdef CONFIG_PCI | 805 | #ifdef CONFIG_PCI |
832 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { | 806 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { |
833 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ | 807 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ |
@@ -845,7 +819,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); | |||
845 | 819 | ||
846 | static void cy_start(struct tty_struct *); | 820 | static void cy_start(struct tty_struct *); |
847 | static void set_line_char(struct cyclades_port *); | 821 | static void set_line_char(struct cyclades_port *); |
848 | static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); | 822 | static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); |
849 | #ifdef CONFIG_ISA | 823 | #ifdef CONFIG_ISA |
850 | static unsigned detect_isa_irq(void __iomem *); | 824 | static unsigned detect_isa_irq(void __iomem *); |
851 | #endif /* CONFIG_ISA */ | 825 | #endif /* CONFIG_ISA */ |
@@ -858,7 +832,6 @@ static void cyz_poll(unsigned long); | |||
858 | /* The Cyclades-Z polling cycle is defined by this variable */ | 832 | /* The Cyclades-Z polling cycle is defined by this variable */ |
859 | static long cyz_polling_cycle = CZ_DEF_POLL; | 833 | static long cyz_polling_cycle = CZ_DEF_POLL; |
860 | 834 | ||
861 | static int cyz_timeron = 0; | ||
862 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); | 835 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); |
863 | 836 | ||
864 | #else /* CONFIG_CYZ_INTR */ | 837 | #else /* CONFIG_CYZ_INTR */ |
@@ -871,21 +844,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
871 | { | 844 | { |
872 | #ifdef SERIAL_PARANOIA_CHECK | 845 | #ifdef SERIAL_PARANOIA_CHECK |
873 | if (!info) { | 846 | if (!info) { |
874 | printk("cyc Warning: null cyclades_port for (%s) in %s\n", | 847 | printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) " |
875 | name, routine); | 848 | "in %s\n", name, routine); |
876 | return 1; | ||
877 | } | ||
878 | |||
879 | if ((long)info < (long)(&cy_port[0]) || | ||
880 | (long)(&cy_port[NR_PORTS]) < (long)info) { | ||
881 | printk("cyc Warning: cyclades_port out of range for (%s) in " | ||
882 | "%s\n", name, routine); | ||
883 | return 1; | 849 | return 1; |
884 | } | 850 | } |
885 | 851 | ||
886 | if (info->magic != CYCLADES_MAGIC) { | 852 | if (info->magic != CYCLADES_MAGIC) { |
887 | printk("cyc Warning: bad magic number for serial struct (%s) " | 853 | printk(KERN_WARNING "cyc Warning: bad magic number for serial " |
888 | "in %s\n", name, routine); | 854 | "struct (%s) in %s\n", name, routine); |
889 | return 1; | 855 | return 1; |
890 | } | 856 | } |
891 | #endif | 857 | #endif |
@@ -943,22 +909,16 @@ do_softint(struct work_struct *work) | |||
943 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) | 909 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) |
944 | wake_up_interruptible(&info->open_wait); | 910 | wake_up_interruptible(&info->open_wait); |
945 | #ifdef CONFIG_CYZ_INTR | 911 | #ifdef CONFIG_CYZ_INTR |
946 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { | 912 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && |
947 | if (cyz_rx_full_timer[info->line].function == NULL) { | 913 | !timer_pending(&cyz_rx_full_timer[info->line])) |
948 | cyz_rx_full_timer[info->line].expires = jiffies + 1; | 914 | mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); |
949 | cyz_rx_full_timer[info->line].function = cyz_rx_restart; | ||
950 | cyz_rx_full_timer[info->line].data = | ||
951 | (unsigned long)info; | ||
952 | add_timer(&cyz_rx_full_timer[info->line]); | ||
953 | } | ||
954 | } | ||
955 | #endif | 915 | #endif |
956 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) | 916 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) |
957 | wake_up_interruptible(&info->delta_msr_wait); | 917 | wake_up_interruptible(&info->delta_msr_wait); |
958 | tty_wakeup(tty); | 918 | tty_wakeup(tty); |
959 | #ifdef Z_WAKE | 919 | #ifdef Z_WAKE |
960 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) | 920 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) |
961 | wake_up_interruptible(&info->shutdown_wait); | 921 | complete(&info->shutdown_wait); |
962 | #endif | 922 | #endif |
963 | } /* do_softint */ | 923 | } /* do_softint */ |
964 | 924 | ||
@@ -975,11 +935,11 @@ do_softint(struct work_struct *work) | |||
975 | */ | 935 | */ |
976 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) | 936 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) |
977 | { | 937 | { |
978 | volatile int i; | 938 | unsigned int i; |
979 | 939 | ||
980 | /* Check to see that the previous command has completed */ | 940 | /* Check to see that the previous command has completed */ |
981 | for (i = 0; i < 100; i++) { | 941 | for (i = 0; i < 100; i++) { |
982 | if (cy_readb(base_addr + (CyCCR << index)) == 0) { | 942 | if (readb(base_addr + (CyCCR << index)) == 0) { |
983 | break; | 943 | break; |
984 | } | 944 | } |
985 | udelay(10L); | 945 | udelay(10L); |
@@ -1022,7 +982,7 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1022 | 982 | ||
1023 | cy_writeb(address + (CyCAR << index), 0); | 983 | cy_writeb(address + (CyCAR << index), 0); |
1024 | cy_writeb(address + (CySRER << index), | 984 | cy_writeb(address + (CySRER << index), |
1025 | cy_readb(address + (CySRER << index)) | CyTxRdy); | 985 | readb(address + (CySRER << index)) | CyTxRdy); |
1026 | local_irq_restore(flags); | 986 | local_irq_restore(flags); |
1027 | 987 | ||
1028 | /* Wait ... */ | 988 | /* Wait ... */ |
@@ -1032,11 +992,11 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1032 | irq = probe_irq_off(irqs); | 992 | irq = probe_irq_off(irqs); |
1033 | 993 | ||
1034 | /* Clean up */ | 994 | /* Clean up */ |
1035 | save_xir = (u_char) cy_readb(address + (CyTIR << index)); | 995 | save_xir = (u_char) readb(address + (CyTIR << index)); |
1036 | save_car = cy_readb(address + (CyCAR << index)); | 996 | save_car = readb(address + (CyCAR << index)); |
1037 | cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); | 997 | cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); |
1038 | cy_writeb(address + (CySRER << index), | 998 | cy_writeb(address + (CySRER << index), |
1039 | cy_readb(address + (CySRER << index)) & ~CyTxRdy); | 999 | readb(address + (CySRER << index)) & ~CyTxRdy); |
1040 | cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); | 1000 | cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); |
1041 | cy_writeb(address + (CyCAR << index), (save_car)); | 1001 | cy_writeb(address + (CyCAR << index), (save_car)); |
1042 | cy_writeb(address + (Cy_ClrIntr << index), 0); | 1002 | cy_writeb(address + (Cy_ClrIntr << index), 0); |
@@ -1051,45 +1011,43 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1051 | { | 1011 | { |
1052 | struct cyclades_port *info; | 1012 | struct cyclades_port *info; |
1053 | struct tty_struct *tty; | 1013 | struct tty_struct *tty; |
1054 | volatile int char_count; | 1014 | int char_count; |
1055 | int i, j, len, mdm_change, mdm_status, outch; | 1015 | int j, len, mdm_change, mdm_status, outch; |
1056 | int save_xir, channel, save_car; | 1016 | int save_xir, channel, save_car; |
1057 | char data; | 1017 | char data; |
1058 | 1018 | ||
1059 | if (status & CySRReceive) { /* reception interrupt */ | 1019 | if (status & CySRReceive) { /* reception interrupt */ |
1060 | #ifdef CY_DEBUG_INTERRUPTS | 1020 | #ifdef CY_DEBUG_INTERRUPTS |
1061 | printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); | 1021 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
1062 | #endif | 1022 | #endif |
1063 | /* determine the channel & change to that context */ | 1023 | /* determine the channel & change to that context */ |
1064 | spin_lock(&cinfo->card_lock); | 1024 | spin_lock(&cinfo->card_lock); |
1065 | save_xir = (u_char) cy_readb(base_addr + (CyRIR << index)); | 1025 | save_xir = (u_char) readb(base_addr + (CyRIR << index)); |
1066 | channel = (u_short) (save_xir & CyIRChannel); | 1026 | channel = (u_short) (save_xir & CyIRChannel); |
1067 | i = channel + chip * 4 + cinfo->first_line; | 1027 | info = &cinfo->ports[channel + chip * 4]; |
1068 | info = &cy_port[i]; | 1028 | save_car = readb(base_addr + (CyCAR << index)); |
1069 | info->last_active = jiffies; | ||
1070 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1071 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1029 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1072 | 1030 | ||
1073 | /* if there is nowhere to put the data, discard it */ | 1031 | /* if there is nowhere to put the data, discard it */ |
1074 | if (info->tty == 0) { | 1032 | if (info->tty == NULL) { |
1075 | j = (cy_readb(base_addr + (CyRIVR << index)) & | 1033 | j = (readb(base_addr + (CyRIVR << index)) & |
1076 | CyIVRMask); | 1034 | CyIVRMask); |
1077 | if (j == CyIVRRxEx) { /* exception */ | 1035 | if (j == CyIVRRxEx) { /* exception */ |
1078 | data = cy_readb(base_addr + (CyRDSR << index)); | 1036 | data = readb(base_addr + (CyRDSR << index)); |
1079 | } else { /* normal character reception */ | 1037 | } else { /* normal character reception */ |
1080 | char_count = cy_readb(base_addr + | 1038 | char_count = readb(base_addr + |
1081 | (CyRDCR << index)); | 1039 | (CyRDCR << index)); |
1082 | while (char_count--) { | 1040 | while (char_count--) { |
1083 | data = cy_readb(base_addr + | 1041 | data = readb(base_addr + |
1084 | (CyRDSR << index)); | 1042 | (CyRDSR << index)); |
1085 | } | 1043 | } |
1086 | } | 1044 | } |
1087 | } else { /* there is an open port for this data */ | 1045 | } else { /* there is an open port for this data */ |
1088 | tty = info->tty; | 1046 | tty = info->tty; |
1089 | j = (cy_readb(base_addr + (CyRIVR << index)) & | 1047 | j = (readb(base_addr + (CyRIVR << index)) & |
1090 | CyIVRMask); | 1048 | CyIVRMask); |
1091 | if (j == CyIVRRxEx) { /* exception */ | 1049 | if (j == CyIVRRxEx) { /* exception */ |
1092 | data = cy_readb(base_addr + (CyRDSR << index)); | 1050 | data = readb(base_addr + (CyRDSR << index)); |
1093 | 1051 | ||
1094 | /* For statistics only */ | 1052 | /* For statistics only */ |
1095 | if (data & CyBREAK) | 1053 | if (data & CyBREAK) |
@@ -1110,7 +1068,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1110 | if (data & CyBREAK) { | 1068 | if (data & CyBREAK) { |
1111 | tty_insert_flip_char( | 1069 | tty_insert_flip_char( |
1112 | tty, | 1070 | tty, |
1113 | cy_readb( | 1071 | readb( |
1114 | base_addr + | 1072 | base_addr + |
1115 | (CyRDSR << | 1073 | (CyRDSR << |
1116 | index)), | 1074 | index)), |
@@ -1123,7 +1081,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1123 | } else if (data & CyFRAME) { | 1081 | } else if (data & CyFRAME) { |
1124 | tty_insert_flip_char( | 1082 | tty_insert_flip_char( |
1125 | tty, | 1083 | tty, |
1126 | cy_readb( | 1084 | readb( |
1127 | base_addr + | 1085 | base_addr + |
1128 | (CyRDSR << | 1086 | (CyRDSR << |
1129 | index)), | 1087 | index)), |
@@ -1135,7 +1093,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1135 | /* Pieces of seven... */ | 1093 | /* Pieces of seven... */ |
1136 | tty_insert_flip_char( | 1094 | tty_insert_flip_char( |
1137 | tty, | 1095 | tty, |
1138 | cy_readb( | 1096 | readb( |
1139 | base_addr + | 1097 | base_addr + |
1140 | (CyRDSR << | 1098 | (CyRDSR << |
1141 | index)), | 1099 | index)), |
@@ -1154,7 +1112,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1154 | */ | 1112 | */ |
1155 | tty_insert_flip_char( | 1113 | tty_insert_flip_char( |
1156 | tty, | 1114 | tty, |
1157 | cy_readb( | 1115 | readb( |
1158 | base_addr + | 1116 | base_addr + |
1159 | (CyRDSR << | 1117 | (CyRDSR << |
1160 | index)), | 1118 | index)), |
@@ -1186,7 +1144,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1186 | } | 1144 | } |
1187 | } else { /* normal character reception */ | 1145 | } else { /* normal character reception */ |
1188 | /* load # chars available from the chip */ | 1146 | /* load # chars available from the chip */ |
1189 | char_count = cy_readb(base_addr + | 1147 | char_count = readb(base_addr + |
1190 | (CyRDCR << index)); | 1148 | (CyRDCR << index)); |
1191 | 1149 | ||
1192 | #ifdef CY_ENABLE_MONITORING | 1150 | #ifdef CY_ENABLE_MONITORING |
@@ -1198,7 +1156,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1198 | #endif | 1156 | #endif |
1199 | len = tty_buffer_request_room(tty, char_count); | 1157 | len = tty_buffer_request_room(tty, char_count); |
1200 | while (len--) { | 1158 | while (len--) { |
1201 | data = cy_readb(base_addr + | 1159 | data = readb(base_addr + |
1202 | (CyRDSR << index)); | 1160 | (CyRDSR << index)); |
1203 | tty_insert_flip_char(tty, data, | 1161 | tty_insert_flip_char(tty, data, |
1204 | TTY_NORMAL); | 1162 | TTY_NORMAL); |
@@ -1223,29 +1181,27 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1223 | is empty, we know we can always stuff a dozen | 1181 | is empty, we know we can always stuff a dozen |
1224 | characters. */ | 1182 | characters. */ |
1225 | #ifdef CY_DEBUG_INTERRUPTS | 1183 | #ifdef CY_DEBUG_INTERRUPTS |
1226 | printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); | 1184 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); |
1227 | #endif | 1185 | #endif |
1228 | 1186 | ||
1229 | /* determine the channel & change to that context */ | 1187 | /* determine the channel & change to that context */ |
1230 | spin_lock(&cinfo->card_lock); | 1188 | spin_lock(&cinfo->card_lock); |
1231 | save_xir = (u_char) cy_readb(base_addr + (CyTIR << index)); | 1189 | save_xir = (u_char) readb(base_addr + (CyTIR << index)); |
1232 | channel = (u_short) (save_xir & CyIRChannel); | 1190 | channel = (u_short) (save_xir & CyIRChannel); |
1233 | i = channel + chip * 4 + cinfo->first_line; | 1191 | save_car = readb(base_addr + (CyCAR << index)); |
1234 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1235 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1192 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1236 | 1193 | ||
1237 | /* validate the port# (as configured and open) */ | 1194 | /* validate the port# (as configured and open) */ |
1238 | if ((i < 0) || (NR_PORTS <= i)) { | 1195 | if (channel + chip * 4 >= cinfo->nports) { |
1239 | cy_writeb(base_addr + (CySRER << index), | 1196 | cy_writeb(base_addr + (CySRER << index), |
1240 | cy_readb(base_addr + (CySRER << index)) & | 1197 | readb(base_addr + (CySRER << index)) & |
1241 | ~CyTxRdy); | 1198 | ~CyTxRdy); |
1242 | goto txend; | 1199 | goto txend; |
1243 | } | 1200 | } |
1244 | info = &cy_port[i]; | 1201 | info = &cinfo->ports[channel + chip * 4]; |
1245 | info->last_active = jiffies; | 1202 | if (info->tty == NULL) { |
1246 | if (info->tty == 0) { | ||
1247 | cy_writeb(base_addr + (CySRER << index), | 1203 | cy_writeb(base_addr + (CySRER << index), |
1248 | cy_readb(base_addr + (CySRER << index)) & | 1204 | readb(base_addr + (CySRER << index)) & |
1249 | ~CyTxRdy); | 1205 | ~CyTxRdy); |
1250 | goto txdone; | 1206 | goto txdone; |
1251 | } | 1207 | } |
@@ -1278,29 +1234,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1278 | 1234 | ||
1279 | while (char_count-- > 0) { | 1235 | while (char_count-- > 0) { |
1280 | if (!info->xmit_cnt) { | 1236 | if (!info->xmit_cnt) { |
1281 | if (cy_readb(base_addr + (CySRER << index)) & | 1237 | if (readb(base_addr + (CySRER << index)) & |
1282 | CyTxMpty) { | 1238 | CyTxMpty) { |
1283 | cy_writeb(base_addr + (CySRER << index), | 1239 | cy_writeb(base_addr + (CySRER << index), |
1284 | cy_readb(base_addr + | 1240 | readb(base_addr + |
1285 | (CySRER << index)) & | 1241 | (CySRER << index)) & |
1286 | ~CyTxMpty); | 1242 | ~CyTxMpty); |
1287 | } else { | 1243 | } else { |
1288 | cy_writeb(base_addr + (CySRER << index), | 1244 | cy_writeb(base_addr + (CySRER << index), |
1289 | (cy_readb(base_addr + | 1245 | (readb(base_addr + |
1290 | (CySRER << index)) & | 1246 | (CySRER << index)) & |
1291 | ~CyTxRdy) | CyTxMpty); | 1247 | ~CyTxRdy) | CyTxMpty); |
1292 | } | 1248 | } |
1293 | goto txdone; | 1249 | goto txdone; |
1294 | } | 1250 | } |
1295 | if (info->xmit_buf == 0) { | 1251 | if (info->xmit_buf == NULL) { |
1296 | cy_writeb(base_addr + (CySRER << index), | 1252 | cy_writeb(base_addr + (CySRER << index), |
1297 | cy_readb(base_addr + (CySRER << index))& | 1253 | readb(base_addr + (CySRER << index)) & |
1298 | ~CyTxRdy); | 1254 | ~CyTxRdy); |
1299 | goto txdone; | 1255 | goto txdone; |
1300 | } | 1256 | } |
1301 | if (info->tty->stopped || info->tty->hw_stopped) { | 1257 | if (info->tty->stopped || info->tty->hw_stopped) { |
1302 | cy_writeb(base_addr + (CySRER << index), | 1258 | cy_writeb(base_addr + (CySRER << index), |
1303 | cy_readb(base_addr + (CySRER << index))& | 1259 | readb(base_addr + (CySRER << index)) & |
1304 | ~CyTxRdy); | 1260 | ~CyTxRdy); |
1305 | goto txdone; | 1261 | goto txdone; |
1306 | } | 1262 | } |
@@ -1333,7 +1289,6 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1333 | 0); | 1289 | 0); |
1334 | info->icount.tx++; | 1290 | info->icount.tx++; |
1335 | char_count--; | 1291 | char_count--; |
1336 | } else { | ||
1337 | } | 1292 | } |
1338 | } | 1293 | } |
1339 | } | 1294 | } |
@@ -1353,19 +1308,16 @@ txend: | |||
1353 | 1308 | ||
1354 | /* determine the channel & change to that context */ | 1309 | /* determine the channel & change to that context */ |
1355 | spin_lock(&cinfo->card_lock); | 1310 | spin_lock(&cinfo->card_lock); |
1356 | save_xir = (u_char) cy_readb(base_addr + (CyMIR << index)); | 1311 | save_xir = (u_char) readb(base_addr + (CyMIR << index)); |
1357 | channel = (u_short) (save_xir & CyIRChannel); | 1312 | channel = (u_short) (save_xir & CyIRChannel); |
1358 | info = &cy_port[channel + chip * 4 + cinfo->first_line]; | 1313 | info = &cinfo->ports[channel + chip * 4]; |
1359 | info->last_active = jiffies; | 1314 | save_car = readb(base_addr + (CyCAR << index)); |
1360 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1361 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1315 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1362 | 1316 | ||
1363 | mdm_change = cy_readb(base_addr + (CyMISR << index)); | 1317 | mdm_change = readb(base_addr + (CyMISR << index)); |
1364 | mdm_status = cy_readb(base_addr + (CyMSVR1 << index)); | 1318 | mdm_status = readb(base_addr + (CyMSVR1 << index)); |
1365 | 1319 | ||
1366 | if (info->tty == 0) { /* no place for data, ignore it */ | 1320 | if (info->tty) { |
1367 | ; | ||
1368 | } else { | ||
1369 | if (mdm_change & CyANY_DELTA) { | 1321 | if (mdm_change & CyANY_DELTA) { |
1370 | /* For statistics only */ | 1322 | /* For statistics only */ |
1371 | if (mdm_change & CyDCD) | 1323 | if (mdm_change & CyDCD) |
@@ -1398,7 +1350,7 @@ txend: | |||
1398 | info->tty->hw_stopped = 0; | 1350 | info->tty->hw_stopped = 0; |
1399 | cy_writeb(base_addr + | 1351 | cy_writeb(base_addr + |
1400 | (CySRER << index), | 1352 | (CySRER << index), |
1401 | cy_readb(base_addr + | 1353 | readb(base_addr + |
1402 | (CySRER << | 1354 | (CySRER << |
1403 | index))| | 1355 | index))| |
1404 | CyTxRdy); | 1356 | CyTxRdy); |
@@ -1412,17 +1364,17 @@ txend: | |||
1412 | info->tty->hw_stopped = 1; | 1364 | info->tty->hw_stopped = 1; |
1413 | cy_writeb(base_addr + | 1365 | cy_writeb(base_addr + |
1414 | (CySRER << index), | 1366 | (CySRER << index), |
1415 | cy_readb(base_addr + | 1367 | readb(base_addr + |
1416 | (CySRER << | 1368 | (CySRER << |
1417 | index)) & | 1369 | index)) & |
1418 | ~CyTxRdy); | 1370 | ~CyTxRdy); |
1419 | } | 1371 | } |
1420 | } | 1372 | } |
1421 | } | 1373 | } |
1422 | if (mdm_change & CyDSR) { | 1374 | /* if (mdm_change & CyDSR) { |
1423 | } | 1375 | } |
1424 | if (mdm_change & CyRI) { | 1376 | if (mdm_change & CyRI) { |
1425 | } | 1377 | }*/ |
1426 | } | 1378 | } |
1427 | /* end of service */ | 1379 | /* end of service */ |
1428 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | 1380 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); |
@@ -1438,16 +1390,16 @@ txend: | |||
1438 | static irqreturn_t cyy_interrupt(int irq, void *dev_id) | 1390 | static irqreturn_t cyy_interrupt(int irq, void *dev_id) |
1439 | { | 1391 | { |
1440 | int status; | 1392 | int status; |
1441 | struct cyclades_card *cinfo; | 1393 | struct cyclades_card *cinfo = dev_id; |
1442 | void __iomem *base_addr, *card_base_addr; | 1394 | void __iomem *base_addr, *card_base_addr; |
1443 | int chip; | 1395 | int chip; |
1444 | int index; | 1396 | int index; |
1445 | int too_many; | 1397 | int too_many; |
1446 | int had_work; | 1398 | int had_work; |
1447 | 1399 | ||
1448 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { | 1400 | if (unlikely(cinfo == NULL)) { |
1449 | #ifdef CY_DEBUG_INTERRUPTS | 1401 | #ifdef CY_DEBUG_INTERRUPTS |
1450 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | 1402 | printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq); |
1451 | #endif | 1403 | #endif |
1452 | return IRQ_NONE; /* spurious interrupt */ | 1404 | return IRQ_NONE; /* spurious interrupt */ |
1453 | } | 1405 | } |
@@ -1455,6 +1407,10 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1455 | card_base_addr = cinfo->base_addr; | 1407 | card_base_addr = cinfo->base_addr; |
1456 | index = cinfo->bus_index; | 1408 | index = cinfo->bus_index; |
1457 | 1409 | ||
1410 | /* card was not initialized yet (e.g. DEBUG_SHIRQ) */ | ||
1411 | if (unlikely(card_base_addr == NULL)) | ||
1412 | return IRQ_HANDLED; | ||
1413 | |||
1458 | /* This loop checks all chips in the card. Make a note whenever | 1414 | /* This loop checks all chips in the card. Make a note whenever |
1459 | _any_ chip had some work to do, as this is considered an | 1415 | _any_ chip had some work to do, as this is considered an |
1460 | indication that there will be more to do. Only when no chip | 1416 | indication that there will be more to do. Only when no chip |
@@ -1466,7 +1422,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1466 | base_addr = cinfo->base_addr + | 1422 | base_addr = cinfo->base_addr + |
1467 | (cy_chip_offset[chip] << index); | 1423 | (cy_chip_offset[chip] << index); |
1468 | too_many = 0; | 1424 | too_many = 0; |
1469 | while ((status = cy_readb(base_addr + | 1425 | while ((status = readb(base_addr + |
1470 | (CySVRR << index))) != 0x00) { | 1426 | (CySVRR << index))) != 0x00) { |
1471 | had_work++; | 1427 | had_work++; |
1472 | /* The purpose of the following test is to ensure that | 1428 | /* The purpose of the following test is to ensure that |
@@ -1498,7 +1454,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1498 | 1454 | ||
1499 | static int | 1455 | static int |
1500 | cyz_fetch_msg(struct cyclades_card *cinfo, | 1456 | cyz_fetch_msg(struct cyclades_card *cinfo, |
1501 | uclong * channel, ucchar * cmd, uclong * param) | 1457 | __u32 * channel, __u8 * cmd, __u32 * param) |
1502 | { | 1458 | { |
1503 | struct FIRM_ID __iomem *firm_id; | 1459 | struct FIRM_ID __iomem *firm_id; |
1504 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1460 | struct ZFW_CTRL __iomem *zfw_ctrl; |
@@ -1509,16 +1465,15 @@ cyz_fetch_msg(struct cyclades_card *cinfo, | |||
1509 | if (!ISZLOADED(*cinfo)) { | 1465 | if (!ISZLOADED(*cinfo)) { |
1510 | return -1; | 1466 | return -1; |
1511 | } | 1467 | } |
1512 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1468 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1513 | 0xfffff); | ||
1514 | board_ctrl = &zfw_ctrl->board_ctrl; | 1469 | board_ctrl = &zfw_ctrl->board_ctrl; |
1515 | 1470 | ||
1516 | loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) | 1471 | loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *) |
1517 | (cinfo->ctl_addr))->loc_doorbell); | 1472 | (cinfo->ctl_addr))->loc_doorbell); |
1518 | if (loc_doorbell) { | 1473 | if (loc_doorbell) { |
1519 | *cmd = (char)(0xff & loc_doorbell); | 1474 | *cmd = (char)(0xff & loc_doorbell); |
1520 | *channel = cy_readl(&board_ctrl->fwcmd_channel); | 1475 | *channel = readl(&board_ctrl->fwcmd_channel); |
1521 | *param = (uclong) cy_readl(&board_ctrl->fwcmd_param); | 1476 | *param = (__u32) readl(&board_ctrl->fwcmd_param); |
1522 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> | 1477 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> |
1523 | loc_doorbell, 0xffffffff); | 1478 | loc_doorbell, 0xffffffff); |
1524 | return 1; | 1479 | return 1; |
@@ -1528,28 +1483,27 @@ cyz_fetch_msg(struct cyclades_card *cinfo, | |||
1528 | 1483 | ||
1529 | static int | 1484 | static int |
1530 | cyz_issue_cmd(struct cyclades_card *cinfo, | 1485 | cyz_issue_cmd(struct cyclades_card *cinfo, |
1531 | uclong channel, ucchar cmd, uclong param) | 1486 | __u32 channel, __u8 cmd, __u32 param) |
1532 | { | 1487 | { |
1533 | struct FIRM_ID __iomem *firm_id; | 1488 | struct FIRM_ID __iomem *firm_id; |
1534 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1489 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1535 | struct BOARD_CTRL __iomem *board_ctrl; | 1490 | struct BOARD_CTRL __iomem *board_ctrl; |
1536 | unsigned long __iomem *pci_doorbell; | 1491 | __u32 __iomem *pci_doorbell; |
1537 | int index; | 1492 | int index; |
1538 | 1493 | ||
1539 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1494 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1540 | if (!ISZLOADED(*cinfo)) { | 1495 | if (!ISZLOADED(*cinfo)) { |
1541 | return -1; | 1496 | return -1; |
1542 | } | 1497 | } |
1543 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1498 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1544 | 0xfffff); | ||
1545 | board_ctrl = &zfw_ctrl->board_ctrl; | 1499 | board_ctrl = &zfw_ctrl->board_ctrl; |
1546 | 1500 | ||
1547 | index = 0; | 1501 | index = 0; |
1548 | pci_doorbell = | 1502 | pci_doorbell = |
1549 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; | 1503 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; |
1550 | while ((cy_readl(pci_doorbell) & 0xff) != 0) { | 1504 | while ((readl(pci_doorbell) & 0xff) != 0) { |
1551 | if (index++ == 1000) { | 1505 | if (index++ == 1000) { |
1552 | return (int)(cy_readl(pci_doorbell) & 0xff); | 1506 | return (int)(readl(pci_doorbell) & 0xff); |
1553 | } | 1507 | } |
1554 | udelay(50L); | 1508 | udelay(50L); |
1555 | } | 1509 | } |
@@ -1561,34 +1515,30 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1561 | } /* cyz_issue_cmd */ | 1515 | } /* cyz_issue_cmd */ |
1562 | 1516 | ||
1563 | static void | 1517 | static void |
1564 | cyz_handle_rx(struct cyclades_port *info, | 1518 | cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, |
1565 | volatile struct CH_CTRL __iomem * ch_ctrl, | 1519 | struct BUF_CTRL __iomem *buf_ctrl) |
1566 | volatile struct BUF_CTRL __iomem * buf_ctrl) | ||
1567 | { | 1520 | { |
1568 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1521 | struct cyclades_card *cinfo = info->card; |
1569 | struct tty_struct *tty = info->tty; | 1522 | struct tty_struct *tty = info->tty; |
1570 | volatile int char_count; | 1523 | int char_count; |
1571 | int len; | 1524 | int len; |
1572 | #ifdef BLOCKMOVE | 1525 | #ifdef BLOCKMOVE |
1573 | int small_count; | 1526 | unsigned char *buf; |
1574 | #else | 1527 | #else |
1575 | char data; | 1528 | char data; |
1576 | #endif | 1529 | #endif |
1577 | volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; | 1530 | __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; |
1578 | 1531 | ||
1579 | rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); | 1532 | rx_get = new_rx_get = readl(&buf_ctrl->rx_get); |
1580 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1533 | rx_put = readl(&buf_ctrl->rx_put); |
1581 | rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); | 1534 | rx_bufsize = readl(&buf_ctrl->rx_bufsize); |
1582 | rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); | 1535 | rx_bufaddr = readl(&buf_ctrl->rx_bufaddr); |
1583 | if (rx_put >= rx_get) | 1536 | if (rx_put >= rx_get) |
1584 | char_count = rx_put - rx_get; | 1537 | char_count = rx_put - rx_get; |
1585 | else | 1538 | else |
1586 | char_count = rx_put - rx_get + rx_bufsize; | 1539 | char_count = rx_put - rx_get + rx_bufsize; |
1587 | 1540 | ||
1588 | if (char_count) { | 1541 | if (char_count) { |
1589 | info->last_active = jiffies; | ||
1590 | info->jiffies[1] = jiffies; | ||
1591 | |||
1592 | #ifdef CY_ENABLE_MONITORING | 1542 | #ifdef CY_ENABLE_MONITORING |
1593 | info->mon.int_count++; | 1543 | info->mon.int_count++; |
1594 | info->mon.char_count += char_count; | 1544 | info->mon.char_count += char_count; |
@@ -1596,7 +1546,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1596 | info->mon.char_max = char_count; | 1546 | info->mon.char_max = char_count; |
1597 | info->mon.char_last = char_count; | 1547 | info->mon.char_last = char_count; |
1598 | #endif | 1548 | #endif |
1599 | if (tty == 0) { | 1549 | if (tty == NULL) { |
1600 | /* flush received characters */ | 1550 | /* flush received characters */ |
1601 | new_rx_get = (new_rx_get + char_count) & | 1551 | new_rx_get = (new_rx_get + char_count) & |
1602 | (rx_bufsize - 1); | 1552 | (rx_bufsize - 1); |
@@ -1606,30 +1556,28 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1606 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) | 1556 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) |
1607 | for performance, but because of buffer boundaries, there | 1557 | for performance, but because of buffer boundaries, there |
1608 | may be several steps to the operation */ | 1558 | may be several steps to the operation */ |
1609 | while (0 < (small_count = min_t(unsigned int, | 1559 | while (1) { |
1610 | rx_bufsize - new_rx_get, | 1560 | len = tty_prepare_flip_string(tty, &buf, |
1611 | min_t(unsigned int, TTY_FLIPBUF_SIZE - | 1561 | char_count); |
1612 | tty->flip.count, char_count)))){ | 1562 | if (!len) |
1613 | memcpy_fromio(tty->flip.char_buf_ptr, | 1563 | break; |
1614 | (char *)(cinfo->base_addr + rx_bufaddr + | ||
1615 | new_rx_get), | ||
1616 | small_count); | ||
1617 | 1564 | ||
1618 | tty->flip.char_buf_ptr += small_count; | 1565 | len = min_t(unsigned int, min(len, char_count), |
1619 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, | 1566 | rx_bufsize - new_rx_get); |
1620 | small_count); | 1567 | |
1621 | tty->flip.flag_buf_ptr += small_count; | 1568 | memcpy_fromio(buf, cinfo->base_addr + |
1622 | new_rx_get = (new_rx_get + small_count) & | 1569 | rx_bufaddr + new_rx_get, len); |
1570 | |||
1571 | new_rx_get = (new_rx_get + len) & | ||
1623 | (rx_bufsize - 1); | 1572 | (rx_bufsize - 1); |
1624 | char_count -= small_count; | 1573 | char_count -= len; |
1625 | info->icount.rx += small_count; | 1574 | info->icount.rx += len; |
1626 | info->idle_stats.recv_bytes += small_count; | 1575 | info->idle_stats.recv_bytes += len; |
1627 | tty->flip.count += small_count; | ||
1628 | } | 1576 | } |
1629 | #else | 1577 | #else |
1630 | len = tty_buffer_request_room(tty, char_count); | 1578 | len = tty_buffer_request_room(tty, char_count); |
1631 | while (len--) { | 1579 | while (len--) { |
1632 | data = cy_readb(cinfo->base_addr + rx_bufaddr + | 1580 | data = readb(cinfo->base_addr + rx_bufaddr + |
1633 | new_rx_get); | 1581 | new_rx_get); |
1634 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); | 1582 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); |
1635 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 1583 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
@@ -1640,13 +1588,12 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1640 | #ifdef CONFIG_CYZ_INTR | 1588 | #ifdef CONFIG_CYZ_INTR |
1641 | /* Recalculate the number of chars in the RX buffer and issue | 1589 | /* Recalculate the number of chars in the RX buffer and issue |
1642 | a cmd in case it's higher than the RX high water mark */ | 1590 | a cmd in case it's higher than the RX high water mark */ |
1643 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1591 | rx_put = readl(&buf_ctrl->rx_put); |
1644 | if (rx_put >= rx_get) | 1592 | if (rx_put >= rx_get) |
1645 | char_count = rx_put - rx_get; | 1593 | char_count = rx_put - rx_get; |
1646 | else | 1594 | else |
1647 | char_count = rx_put - rx_get + rx_bufsize; | 1595 | char_count = rx_put - rx_get + rx_bufsize; |
1648 | if (char_count >= (int)cy_readl(&buf_ctrl-> | 1596 | if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { |
1649 | rx_threshold)) { | ||
1650 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1597 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); |
1651 | } | 1598 | } |
1652 | #endif | 1599 | #endif |
@@ -1659,26 +1606,25 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1659 | } | 1606 | } |
1660 | 1607 | ||
1661 | static void | 1608 | static void |
1662 | cyz_handle_tx(struct cyclades_port *info, | 1609 | cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, |
1663 | volatile struct CH_CTRL __iomem * ch_ctrl, | 1610 | struct BUF_CTRL __iomem *buf_ctrl) |
1664 | volatile struct BUF_CTRL __iomem * buf_ctrl) | ||
1665 | { | 1611 | { |
1666 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1612 | struct cyclades_card *cinfo = info->card; |
1667 | struct tty_struct *tty = info->tty; | 1613 | struct tty_struct *tty = info->tty; |
1668 | char data; | 1614 | char data; |
1669 | volatile int char_count; | 1615 | int char_count; |
1670 | #ifdef BLOCKMOVE | 1616 | #ifdef BLOCKMOVE |
1671 | int small_count; | 1617 | int small_count; |
1672 | #endif | 1618 | #endif |
1673 | volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; | 1619 | __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr; |
1674 | 1620 | ||
1675 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ | 1621 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ |
1676 | return; | 1622 | return; |
1677 | 1623 | ||
1678 | tx_get = cy_readl(&buf_ctrl->tx_get); | 1624 | tx_get = readl(&buf_ctrl->tx_get); |
1679 | tx_put = cy_readl(&buf_ctrl->tx_put); | 1625 | tx_put = readl(&buf_ctrl->tx_put); |
1680 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 1626 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); |
1681 | tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); | 1627 | tx_bufaddr = readl(&buf_ctrl->tx_bufaddr); |
1682 | if (tx_put >= tx_get) | 1628 | if (tx_put >= tx_get) |
1683 | char_count = tx_get - tx_put - 1 + tx_bufsize; | 1629 | char_count = tx_get - tx_put - 1 + tx_bufsize; |
1684 | else | 1630 | else |
@@ -1686,9 +1632,8 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1686 | 1632 | ||
1687 | if (char_count) { | 1633 | if (char_count) { |
1688 | 1634 | ||
1689 | if (tty == 0) { | 1635 | if (tty == NULL) |
1690 | goto ztxdone; | 1636 | goto ztxdone; |
1691 | } | ||
1692 | 1637 | ||
1693 | if (info->x_char) { /* send special char */ | 1638 | if (info->x_char) { /* send special char */ |
1694 | data = info->x_char; | 1639 | data = info->x_char; |
@@ -1698,8 +1643,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1698 | info->x_char = 0; | 1643 | info->x_char = 0; |
1699 | char_count--; | 1644 | char_count--; |
1700 | info->icount.tx++; | 1645 | info->icount.tx++; |
1701 | info->last_active = jiffies; | ||
1702 | info->jiffies[2] = jiffies; | ||
1703 | } | 1646 | } |
1704 | #ifdef BLOCKMOVE | 1647 | #ifdef BLOCKMOVE |
1705 | while (0 < (small_count = min_t(unsigned int, | 1648 | while (0 < (small_count = min_t(unsigned int, |
@@ -1719,8 +1662,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1719 | info->xmit_cnt -= small_count; | 1662 | info->xmit_cnt -= small_count; |
1720 | info->xmit_tail = (info->xmit_tail + small_count) & | 1663 | info->xmit_tail = (info->xmit_tail + small_count) & |
1721 | (SERIAL_XMIT_SIZE - 1); | 1664 | (SERIAL_XMIT_SIZE - 1); |
1722 | info->last_active = jiffies; | ||
1723 | info->jiffies[2] = jiffies; | ||
1724 | } | 1665 | } |
1725 | #else | 1666 | #else |
1726 | while (info->xmit_cnt && char_count) { | 1667 | while (info->xmit_cnt && char_count) { |
@@ -1733,8 +1674,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1733 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1674 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1734 | char_count--; | 1675 | char_count--; |
1735 | info->icount.tx++; | 1676 | info->icount.tx++; |
1736 | info->last_active = jiffies; | ||
1737 | info->jiffies[2] = jiffies; | ||
1738 | } | 1677 | } |
1739 | #endif | 1678 | #endif |
1740 | ztxdone: | 1679 | ztxdone: |
@@ -1750,33 +1689,32 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1750 | { | 1689 | { |
1751 | struct tty_struct *tty; | 1690 | struct tty_struct *tty; |
1752 | struct cyclades_port *info; | 1691 | struct cyclades_port *info; |
1753 | static volatile struct FIRM_ID __iomem *firm_id; | 1692 | static struct FIRM_ID __iomem *firm_id; |
1754 | static volatile struct ZFW_CTRL __iomem *zfw_ctrl; | 1693 | static struct ZFW_CTRL __iomem *zfw_ctrl; |
1755 | static volatile struct BOARD_CTRL __iomem *board_ctrl; | 1694 | static struct BOARD_CTRL __iomem *board_ctrl; |
1756 | static volatile struct CH_CTRL __iomem *ch_ctrl; | 1695 | static struct CH_CTRL __iomem *ch_ctrl; |
1757 | static volatile struct BUF_CTRL __iomem *buf_ctrl; | 1696 | static struct BUF_CTRL __iomem *buf_ctrl; |
1758 | uclong channel; | 1697 | __u32 channel; |
1759 | ucchar cmd; | 1698 | __u8 cmd; |
1760 | uclong param; | 1699 | __u32 param; |
1761 | uclong hw_ver, fw_ver; | 1700 | __u32 hw_ver, fw_ver; |
1762 | int special_count; | 1701 | int special_count; |
1763 | int delta_count; | 1702 | int delta_count; |
1764 | 1703 | ||
1765 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1704 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1766 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1705 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1767 | 0xfffff); | ||
1768 | board_ctrl = &zfw_ctrl->board_ctrl; | 1706 | board_ctrl = &zfw_ctrl->board_ctrl; |
1769 | fw_ver = cy_readl(&board_ctrl->fw_version); | 1707 | fw_ver = readl(&board_ctrl->fw_version); |
1770 | hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> | 1708 | hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> |
1771 | mail_box_0); | 1709 | mail_box_0); |
1772 | 1710 | ||
1773 | while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { | 1711 | while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { |
1774 | special_count = 0; | 1712 | special_count = 0; |
1775 | delta_count = 0; | 1713 | delta_count = 0; |
1776 | info = &cy_port[channel + cinfo->first_line]; | 1714 | info = &cinfo->ports[channel]; |
1777 | if ((tty = info->tty) == 0) { | 1715 | if ((tty = info->tty) == NULL) |
1778 | continue; | 1716 | continue; |
1779 | } | 1717 | |
1780 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 1718 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
1781 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | 1719 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); |
1782 | 1720 | ||
@@ -1801,7 +1739,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1801 | delta_count++; | 1739 | delta_count++; |
1802 | if (info->flags & ASYNC_CHECK_CD) { | 1740 | if (info->flags & ASYNC_CHECK_CD) { |
1803 | if ((fw_ver > 241 ? ((u_long) param) : | 1741 | if ((fw_ver > 241 ? ((u_long) param) : |
1804 | cy_readl(&ch_ctrl->rs_status)) & | 1742 | readl(&ch_ctrl->rs_status)) & |
1805 | C_RS_DCD) { | 1743 | C_RS_DCD) { |
1806 | cy_sched_event(info, | 1744 | cy_sched_event(info, |
1807 | Cy_EVENT_OPEN_WAKEUP); | 1745 | Cy_EVENT_OPEN_WAKEUP); |
@@ -1833,8 +1771,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1833 | case C_CM_INTBACK2: | 1771 | case C_CM_INTBACK2: |
1834 | /* Reception Interrupt */ | 1772 | /* Reception Interrupt */ |
1835 | #ifdef CY_DEBUG_INTERRUPTS | 1773 | #ifdef CY_DEBUG_INTERRUPTS |
1836 | printk("cyz_interrupt: rcvd intr, card %d, " | 1774 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1837 | "port %ld\n\r", info->card, channel); | 1775 | "port %ld\n", info->card, channel); |
1838 | #endif | 1776 | #endif |
1839 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1777 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); |
1840 | break; | 1778 | break; |
@@ -1843,8 +1781,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1843 | case C_CM_INTBACK: | 1781 | case C_CM_INTBACK: |
1844 | /* Transmission Interrupt */ | 1782 | /* Transmission Interrupt */ |
1845 | #ifdef CY_DEBUG_INTERRUPTS | 1783 | #ifdef CY_DEBUG_INTERRUPTS |
1846 | printk("cyz_interrupt: xmit intr, card %d, " | 1784 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1847 | "port %ld\n\r", info->card, channel); | 1785 | "port %ld\n", info->card, channel); |
1848 | #endif | 1786 | #endif |
1849 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1787 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1850 | break; | 1788 | break; |
@@ -1865,18 +1803,19 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1865 | #ifdef CONFIG_CYZ_INTR | 1803 | #ifdef CONFIG_CYZ_INTR |
1866 | static irqreturn_t cyz_interrupt(int irq, void *dev_id) | 1804 | static irqreturn_t cyz_interrupt(int irq, void *dev_id) |
1867 | { | 1805 | { |
1868 | struct cyclades_card *cinfo; | 1806 | struct cyclades_card *cinfo = dev_id; |
1869 | 1807 | ||
1870 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { | 1808 | if (unlikely(cinfo == NULL)) { |
1871 | #ifdef CY_DEBUG_INTERRUPTS | 1809 | #ifdef CY_DEBUG_INTERRUPTS |
1872 | printk("cyz_interrupt: spurious interrupt %d\n\r", irq); | 1810 | printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq); |
1873 | #endif | 1811 | #endif |
1874 | return IRQ_NONE; /* spurious interrupt */ | 1812 | return IRQ_NONE; /* spurious interrupt */ |
1875 | } | 1813 | } |
1876 | 1814 | ||
1877 | if (!ISZLOADED(*cinfo)) { | 1815 | if (unlikely(!ISZLOADED(*cinfo))) { |
1878 | #ifdef CY_DEBUG_INTERRUPTS | 1816 | #ifdef CY_DEBUG_INTERRUPTS |
1879 | printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); | 1817 | printk(KERN_DEBUG "cyz_interrupt: board not yet loaded " |
1818 | "(IRQ%d).\n", irq); | ||
1880 | #endif | 1819 | #endif |
1881 | return IRQ_NONE; | 1820 | return IRQ_NONE; |
1882 | } | 1821 | } |
@@ -1890,19 +1829,18 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id) | |||
1890 | static void cyz_rx_restart(unsigned long arg) | 1829 | static void cyz_rx_restart(unsigned long arg) |
1891 | { | 1830 | { |
1892 | struct cyclades_port *info = (struct cyclades_port *)arg; | 1831 | struct cyclades_port *info = (struct cyclades_port *)arg; |
1832 | struct cyclades_card *card = info->card; | ||
1893 | int retval; | 1833 | int retval; |
1894 | int card = info->card; | 1834 | __u32 channel = info->line - card->first_line; |
1895 | uclong channel = (info->line) - (cy_card[card].first_line); | ||
1896 | unsigned long flags; | 1835 | unsigned long flags; |
1897 | 1836 | ||
1898 | CY_LOCK(info, flags); | 1837 | spin_lock_irqsave(&card->card_lock, flags); |
1899 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); | 1838 | retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L); |
1900 | if (retval != 0) { | 1839 | if (retval != 0) { |
1901 | printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", | 1840 | printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n", |
1902 | info->line, retval); | 1841 | info->line, retval); |
1903 | } | 1842 | } |
1904 | cyz_rx_full_timer[info->line].function = NULL; | 1843 | spin_unlock_irqrestore(&card->card_lock, flags); |
1905 | CY_UNLOCK(info, flags); | ||
1906 | } | 1844 | } |
1907 | 1845 | ||
1908 | #else /* CONFIG_CYZ_INTR */ | 1846 | #else /* CONFIG_CYZ_INTR */ |
@@ -1912,14 +1850,14 @@ static void cyz_poll(unsigned long arg) | |||
1912 | struct cyclades_card *cinfo; | 1850 | struct cyclades_card *cinfo; |
1913 | struct cyclades_port *info; | 1851 | struct cyclades_port *info; |
1914 | struct tty_struct *tty; | 1852 | struct tty_struct *tty; |
1915 | static volatile struct FIRM_ID *firm_id; | 1853 | static struct FIRM_ID *firm_id; |
1916 | static volatile struct ZFW_CTRL *zfw_ctrl; | 1854 | static struct ZFW_CTRL *zfw_ctrl; |
1917 | static volatile struct BOARD_CTRL *board_ctrl; | 1855 | static struct BOARD_CTRL *board_ctrl; |
1918 | static volatile struct CH_CTRL *ch_ctrl; | 1856 | static struct CH_CTRL *ch_ctrl; |
1919 | static volatile struct BUF_CTRL *buf_ctrl; | 1857 | static struct BUF_CTRL *buf_ctrl; |
1858 | unsigned long expires = jiffies + HZ; | ||
1920 | int card, port; | 1859 | int card, port; |
1921 | 1860 | ||
1922 | cyz_timerlist.expires = jiffies + (HZ); | ||
1923 | for (card = 0; card < NR_CARDS; card++) { | 1861 | for (card = 0; card < NR_CARDS; card++) { |
1924 | cinfo = &cy_card[card]; | 1862 | cinfo = &cy_card[card]; |
1925 | 1863 | ||
@@ -1930,12 +1868,12 @@ static void cyz_poll(unsigned long arg) | |||
1930 | 1868 | ||
1931 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1869 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1932 | zfw_ctrl = cinfo->base_addr + | 1870 | zfw_ctrl = cinfo->base_addr + |
1933 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1871 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1934 | board_ctrl = &(zfw_ctrl->board_ctrl); | 1872 | board_ctrl = &(zfw_ctrl->board_ctrl); |
1935 | 1873 | ||
1936 | /* Skip first polling cycle to avoid racing conditions with the FW */ | 1874 | /* Skip first polling cycle to avoid racing conditions with the FW */ |
1937 | if (!cinfo->intr_enabled) { | 1875 | if (!cinfo->intr_enabled) { |
1938 | cinfo->nports = (int)cy_readl(&board_ctrl->n_channel); | 1876 | cinfo->nports = (int)readl(&board_ctrl->n_channel); |
1939 | cinfo->intr_enabled = 1; | 1877 | cinfo->intr_enabled = 1; |
1940 | continue; | 1878 | continue; |
1941 | } | 1879 | } |
@@ -1943,7 +1881,7 @@ static void cyz_poll(unsigned long arg) | |||
1943 | cyz_handle_cmd(cinfo); | 1881 | cyz_handle_cmd(cinfo); |
1944 | 1882 | ||
1945 | for (port = 0; port < cinfo->nports; port++) { | 1883 | for (port = 0; port < cinfo->nports; port++) { |
1946 | info = &cy_port[port + cinfo->first_line]; | 1884 | info = &cinfo->ports[port]; |
1947 | tty = info->tty; | 1885 | tty = info->tty; |
1948 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | 1886 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); |
1949 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1887 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
@@ -1953,9 +1891,9 @@ static void cyz_poll(unsigned long arg) | |||
1953 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1891 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1954 | } | 1892 | } |
1955 | /* poll every 'cyz_polling_cycle' period */ | 1893 | /* poll every 'cyz_polling_cycle' period */ |
1956 | cyz_timerlist.expires = jiffies + cyz_polling_cycle; | 1894 | expires = jiffies + cyz_polling_cycle; |
1957 | } | 1895 | } |
1958 | add_timer(&cyz_timerlist); | 1896 | mod_timer(&cyz_timerlist, expires); |
1959 | } /* cyz_poll */ | 1897 | } /* cyz_poll */ |
1960 | 1898 | ||
1961 | #endif /* CONFIG_CYZ_INTR */ | 1899 | #endif /* CONFIG_CYZ_INTR */ |
@@ -1968,20 +1906,21 @@ static void cyz_poll(unsigned long arg) | |||
1968 | */ | 1906 | */ |
1969 | static int startup(struct cyclades_port *info) | 1907 | static int startup(struct cyclades_port *info) |
1970 | { | 1908 | { |
1909 | struct cyclades_card *card; | ||
1971 | unsigned long flags; | 1910 | unsigned long flags; |
1972 | int retval = 0; | 1911 | int retval = 0; |
1973 | void __iomem *base_addr; | 1912 | void __iomem *base_addr; |
1974 | int card, chip, channel, index; | 1913 | int chip, channel, index; |
1975 | unsigned long page; | 1914 | unsigned long page; |
1976 | 1915 | ||
1977 | card = info->card; | 1916 | card = info->card; |
1978 | channel = (info->line) - (cy_card[card].first_line); | 1917 | channel = info->line - card->first_line; |
1979 | 1918 | ||
1980 | page = get_zeroed_page(GFP_KERNEL); | 1919 | page = get_zeroed_page(GFP_KERNEL); |
1981 | if (!page) | 1920 | if (!page) |
1982 | return -ENOMEM; | 1921 | return -ENOMEM; |
1983 | 1922 | ||
1984 | CY_LOCK(info, flags); | 1923 | spin_lock_irqsave(&card->card_lock, flags); |
1985 | 1924 | ||
1986 | if (info->flags & ASYNC_INITIALIZED) { | 1925 | if (info->flags & ASYNC_INITIALIZED) { |
1987 | free_page(page); | 1926 | free_page(page); |
@@ -2001,24 +1940,22 @@ static int startup(struct cyclades_port *info) | |||
2001 | else | 1940 | else |
2002 | info->xmit_buf = (unsigned char *)page; | 1941 | info->xmit_buf = (unsigned char *)page; |
2003 | 1942 | ||
2004 | CY_UNLOCK(info, flags); | 1943 | spin_unlock_irqrestore(&card->card_lock, flags); |
2005 | 1944 | ||
2006 | set_line_char(info); | 1945 | set_line_char(info); |
2007 | 1946 | ||
2008 | if (!IS_CYC_Z(cy_card[card])) { | 1947 | if (!IS_CYC_Z(*card)) { |
2009 | chip = channel >> 2; | 1948 | chip = channel >> 2; |
2010 | channel &= 0x03; | 1949 | channel &= 0x03; |
2011 | index = cy_card[card].bus_index; | 1950 | index = card->bus_index; |
2012 | base_addr = cy_card[card].base_addr + | 1951 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2013 | (cy_chip_offset[chip] << index); | ||
2014 | 1952 | ||
2015 | #ifdef CY_DEBUG_OPEN | 1953 | #ifdef CY_DEBUG_OPEN |
2016 | printk("cyc startup card %d, chip %d, channel %d, " | 1954 | printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, " |
2017 | "base_addr %lx\n", | 1955 | "base_addr %p\n", |
2018 | card, chip, channel, (long)base_addr); | 1956 | card, chip, channel, base_addr); |
2019 | /**/ | ||
2020 | #endif | 1957 | #endif |
2021 | CY_LOCK(info, flags); | 1958 | spin_lock_irqsave(&card->card_lock, flags); |
2022 | 1959 | ||
2023 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 1960 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
2024 | 1961 | ||
@@ -2034,14 +1971,14 @@ static int startup(struct cyclades_port *info) | |||
2034 | cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); | 1971 | cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); |
2035 | 1972 | ||
2036 | #ifdef CY_DEBUG_DTR | 1973 | #ifdef CY_DEBUG_DTR |
2037 | printk("cyc:startup raising DTR\n"); | 1974 | printk(KERN_DEBUG "cyc:startup raising DTR\n"); |
2038 | printk(" status: 0x%x, 0x%x\n", | 1975 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2039 | cy_readb(base_addr + (CyMSVR1 << index)), | 1976 | readb(base_addr + (CyMSVR1 << index)), |
2040 | cy_readb(base_addr + (CyMSVR2 << index))); | 1977 | readb(base_addr + (CyMSVR2 << index))); |
2041 | #endif | 1978 | #endif |
2042 | 1979 | ||
2043 | cy_writeb(base_addr + (CySRER << index), | 1980 | cy_writeb(base_addr + (CySRER << index), |
2044 | cy_readb(base_addr + (CySRER << index)) | CyRxData); | 1981 | readb(base_addr + (CySRER << index)) | CyRxData); |
2045 | info->flags |= ASYNC_INITIALIZED; | 1982 | info->flags |= ASYNC_INITIALIZED; |
2046 | 1983 | ||
2047 | if (info->tty) { | 1984 | if (info->tty) { |
@@ -2054,7 +1991,7 @@ static int startup(struct cyclades_port *info) | |||
2054 | info->idle_stats.recv_idle = | 1991 | info->idle_stats.recv_idle = |
2055 | info->idle_stats.xmit_idle = jiffies; | 1992 | info->idle_stats.xmit_idle = jiffies; |
2056 | 1993 | ||
2057 | CY_UNLOCK(info, flags); | 1994 | spin_unlock_irqrestore(&card->card_lock, flags); |
2058 | 1995 | ||
2059 | } else { | 1996 | } else { |
2060 | struct FIRM_ID __iomem *firm_id; | 1997 | struct FIRM_ID __iomem *firm_id; |
@@ -2063,24 +2000,23 @@ static int startup(struct cyclades_port *info) | |||
2063 | struct CH_CTRL __iomem *ch_ctrl; | 2000 | struct CH_CTRL __iomem *ch_ctrl; |
2064 | int retval; | 2001 | int retval; |
2065 | 2002 | ||
2066 | base_addr = cy_card[card].base_addr; | 2003 | base_addr = card->base_addr; |
2067 | 2004 | ||
2068 | firm_id = base_addr + ID_ADDRESS; | 2005 | firm_id = base_addr + ID_ADDRESS; |
2069 | if (!ISZLOADED(cy_card[card])) { | 2006 | if (!ISZLOADED(*card)) { |
2070 | return -ENODEV; | 2007 | return -ENODEV; |
2071 | } | 2008 | } |
2072 | 2009 | ||
2073 | zfw_ctrl = cy_card[card].base_addr + | 2010 | zfw_ctrl = card->base_addr + |
2074 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2011 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2075 | board_ctrl = &zfw_ctrl->board_ctrl; | 2012 | board_ctrl = &zfw_ctrl->board_ctrl; |
2076 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2013 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2077 | 2014 | ||
2078 | #ifdef CY_DEBUG_OPEN | 2015 | #ifdef CY_DEBUG_OPEN |
2079 | printk("cyc startup Z card %d, channel %d, base_addr %lx\n", | 2016 | printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " |
2080 | card, channel, (long)base_addr); | 2017 | "base_addr %p\n", card, channel, base_addr); |
2081 | /**/ | ||
2082 | #endif | 2018 | #endif |
2083 | CY_LOCK(info, flags); | 2019 | spin_lock_irqsave(&card->card_lock, flags); |
2084 | 2020 | ||
2085 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); | 2021 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); |
2086 | #ifdef Z_WAKE | 2022 | #ifdef Z_WAKE |
@@ -2102,33 +2038,31 @@ static int startup(struct cyclades_port *info) | |||
2102 | #endif /* CONFIG_CYZ_INTR */ | 2038 | #endif /* CONFIG_CYZ_INTR */ |
2103 | #endif /* Z_WAKE */ | 2039 | #endif /* Z_WAKE */ |
2104 | 2040 | ||
2105 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 2041 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); |
2106 | if (retval != 0) { | 2042 | if (retval != 0) { |
2107 | printk("cyc:startup(1) retval on ttyC%d was %x\n", | 2043 | printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was " |
2108 | info->line, retval); | 2044 | "%x\n", info->line, retval); |
2109 | } | 2045 | } |
2110 | 2046 | ||
2111 | /* Flush RX buffers before raising DTR and RTS */ | 2047 | /* Flush RX buffers before raising DTR and RTS */ |
2112 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, | 2048 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L); |
2113 | 0L); | ||
2114 | if (retval != 0) { | 2049 | if (retval != 0) { |
2115 | printk("cyc:startup(2) retval on ttyC%d was %x\n", | 2050 | printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was " |
2116 | info->line, retval); | 2051 | "%x\n", info->line, retval); |
2117 | } | 2052 | } |
2118 | 2053 | ||
2119 | /* set timeout !!! */ | 2054 | /* set timeout !!! */ |
2120 | /* set RTS and DTR !!! */ | 2055 | /* set RTS and DTR !!! */ |
2121 | cy_writel(&ch_ctrl[channel].rs_control, | 2056 | cy_writel(&ch_ctrl[channel].rs_control, |
2122 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | | 2057 | readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | |
2123 | C_RS_DTR); | 2058 | C_RS_DTR); |
2124 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2059 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); |
2125 | C_CM_IOCTLM, 0L); | ||
2126 | if (retval != 0) { | 2060 | if (retval != 0) { |
2127 | printk("cyc:startup(3) retval on ttyC%d was %x\n", | 2061 | printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was " |
2128 | info->line, retval); | 2062 | "%x\n", info->line, retval); |
2129 | } | 2063 | } |
2130 | #ifdef CY_DEBUG_DTR | 2064 | #ifdef CY_DEBUG_DTR |
2131 | printk("cyc:startup raising Z DTR\n"); | 2065 | printk(KERN_DEBUG "cyc:startup raising Z DTR\n"); |
2132 | #endif | 2066 | #endif |
2133 | 2067 | ||
2134 | /* enable send, recv, modem !!! */ | 2068 | /* enable send, recv, modem !!! */ |
@@ -2144,51 +2078,50 @@ static int startup(struct cyclades_port *info) | |||
2144 | info->idle_stats.recv_idle = | 2078 | info->idle_stats.recv_idle = |
2145 | info->idle_stats.xmit_idle = jiffies; | 2079 | info->idle_stats.xmit_idle = jiffies; |
2146 | 2080 | ||
2147 | CY_UNLOCK(info, flags); | 2081 | spin_unlock_irqrestore(&card->card_lock, flags); |
2148 | } | 2082 | } |
2149 | 2083 | ||
2150 | #ifdef CY_DEBUG_OPEN | 2084 | #ifdef CY_DEBUG_OPEN |
2151 | printk(" cyc startup done\n"); | 2085 | printk(KERN_DEBUG "cyc startup done\n"); |
2152 | #endif | 2086 | #endif |
2153 | return 0; | 2087 | return 0; |
2154 | 2088 | ||
2155 | errout: | 2089 | errout: |
2156 | CY_UNLOCK(info, flags); | 2090 | spin_unlock_irqrestore(&card->card_lock, flags); |
2157 | return retval; | 2091 | return retval; |
2158 | } /* startup */ | 2092 | } /* startup */ |
2159 | 2093 | ||
2160 | static void start_xmit(struct cyclades_port *info) | 2094 | static void start_xmit(struct cyclades_port *info) |
2161 | { | 2095 | { |
2096 | struct cyclades_card *card; | ||
2162 | unsigned long flags; | 2097 | unsigned long flags; |
2163 | void __iomem *base_addr; | 2098 | void __iomem *base_addr; |
2164 | int card, chip, channel, index; | 2099 | int chip, channel, index; |
2165 | 2100 | ||
2166 | card = info->card; | 2101 | card = info->card; |
2167 | channel = (info->line) - (cy_card[card].first_line); | 2102 | channel = info->line - card->first_line; |
2168 | if (!IS_CYC_Z(cy_card[card])) { | 2103 | if (!IS_CYC_Z(*card)) { |
2169 | chip = channel >> 2; | 2104 | chip = channel >> 2; |
2170 | channel &= 0x03; | 2105 | channel &= 0x03; |
2171 | index = cy_card[card].bus_index; | 2106 | index = card->bus_index; |
2172 | base_addr = cy_card[card].base_addr + | 2107 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2173 | (cy_chip_offset[chip] << index); | ||
2174 | 2108 | ||
2175 | CY_LOCK(info, flags); | 2109 | spin_lock_irqsave(&card->card_lock, flags); |
2176 | cy_writeb(base_addr + (CyCAR << index), channel); | 2110 | cy_writeb(base_addr + (CyCAR << index), channel); |
2177 | cy_writeb(base_addr + (CySRER << index), | 2111 | cy_writeb(base_addr + (CySRER << index), |
2178 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | 2112 | readb(base_addr + (CySRER << index)) | CyTxRdy); |
2179 | CY_UNLOCK(info, flags); | 2113 | spin_unlock_irqrestore(&card->card_lock, flags); |
2180 | } else { | 2114 | } else { |
2181 | #ifdef CONFIG_CYZ_INTR | 2115 | #ifdef CONFIG_CYZ_INTR |
2182 | int retval; | 2116 | int retval; |
2183 | 2117 | ||
2184 | CY_LOCK(info, flags); | 2118 | spin_lock_irqsave(&card->card_lock, flags); |
2185 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, | 2119 | retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L); |
2186 | 0L); | ||
2187 | if (retval != 0) { | 2120 | if (retval != 0) { |
2188 | printk("cyc:start_xmit retval on ttyC%d was %x\n", | 2121 | printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was " |
2189 | info->line, retval); | 2122 | "%x\n", info->line, retval); |
2190 | } | 2123 | } |
2191 | CY_UNLOCK(info, flags); | 2124 | spin_unlock_irqrestore(&card->card_lock, flags); |
2192 | #else /* CONFIG_CYZ_INTR */ | 2125 | #else /* CONFIG_CYZ_INTR */ |
2193 | /* Don't have to do anything at this time */ | 2126 | /* Don't have to do anything at this time */ |
2194 | #endif /* CONFIG_CYZ_INTR */ | 2127 | #endif /* CONFIG_CYZ_INTR */ |
@@ -2201,30 +2134,30 @@ static void start_xmit(struct cyclades_port *info) | |||
2201 | */ | 2134 | */ |
2202 | static void shutdown(struct cyclades_port *info) | 2135 | static void shutdown(struct cyclades_port *info) |
2203 | { | 2136 | { |
2137 | struct cyclades_card *card; | ||
2204 | unsigned long flags; | 2138 | unsigned long flags; |
2205 | void __iomem *base_addr; | 2139 | void __iomem *base_addr; |
2206 | int card, chip, channel, index; | 2140 | int chip, channel, index; |
2207 | 2141 | ||
2208 | if (!(info->flags & ASYNC_INITIALIZED)) { | 2142 | if (!(info->flags & ASYNC_INITIALIZED)) { |
2209 | return; | 2143 | return; |
2210 | } | 2144 | } |
2211 | 2145 | ||
2212 | card = info->card; | 2146 | card = info->card; |
2213 | channel = info->line - cy_card[card].first_line; | 2147 | channel = info->line - card->first_line; |
2214 | if (!IS_CYC_Z(cy_card[card])) { | 2148 | if (!IS_CYC_Z(*card)) { |
2215 | chip = channel >> 2; | 2149 | chip = channel >> 2; |
2216 | channel &= 0x03; | 2150 | channel &= 0x03; |
2217 | index = cy_card[card].bus_index; | 2151 | index = card->bus_index; |
2218 | base_addr = cy_card[card].base_addr + | 2152 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2219 | (cy_chip_offset[chip] << index); | ||
2220 | 2153 | ||
2221 | #ifdef CY_DEBUG_OPEN | 2154 | #ifdef CY_DEBUG_OPEN |
2222 | printk("cyc shutdown Y card %d, chip %d, channel %d, " | 2155 | printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, " |
2223 | "base_addr %lx\n", | 2156 | "channel %d, base_addr %p\n", |
2224 | card, chip, channel, (long)base_addr); | 2157 | card, chip, channel, base_addr); |
2225 | #endif | 2158 | #endif |
2226 | 2159 | ||
2227 | CY_LOCK(info, flags); | 2160 | spin_lock_irqsave(&card->card_lock, flags); |
2228 | 2161 | ||
2229 | /* Clear delta_msr_wait queue to avoid mem leaks. */ | 2162 | /* Clear delta_msr_wait queue to avoid mem leaks. */ |
2230 | wake_up_interruptible(&info->delta_msr_wait); | 2163 | wake_up_interruptible(&info->delta_msr_wait); |
@@ -2240,10 +2173,10 @@ static void shutdown(struct cyclades_port *info) | |||
2240 | cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); | 2173 | cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); |
2241 | cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); | 2174 | cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); |
2242 | #ifdef CY_DEBUG_DTR | 2175 | #ifdef CY_DEBUG_DTR |
2243 | printk("cyc shutdown dropping DTR\n"); | 2176 | printk(KERN_DEBUG "cyc shutdown dropping DTR\n"); |
2244 | printk(" status: 0x%x, 0x%x\n", | 2177 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2245 | cy_readb(base_addr + (CyMSVR1 << index)), | 2178 | readb(base_addr + (CyMSVR1 << index)), |
2246 | cy_readb(base_addr + (CyMSVR2 << index))); | 2179 | readb(base_addr + (CyMSVR2 << index))); |
2247 | #endif | 2180 | #endif |
2248 | } | 2181 | } |
2249 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); | 2182 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); |
@@ -2254,7 +2187,7 @@ static void shutdown(struct cyclades_port *info) | |||
2254 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 2187 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2255 | } | 2188 | } |
2256 | info->flags &= ~ASYNC_INITIALIZED; | 2189 | info->flags &= ~ASYNC_INITIALIZED; |
2257 | CY_UNLOCK(info, flags); | 2190 | spin_unlock_irqrestore(&card->card_lock, flags); |
2258 | } else { | 2191 | } else { |
2259 | struct FIRM_ID __iomem *firm_id; | 2192 | struct FIRM_ID __iomem *firm_id; |
2260 | struct ZFW_CTRL __iomem *zfw_ctrl; | 2193 | struct ZFW_CTRL __iomem *zfw_ctrl; |
@@ -2262,23 +2195,23 @@ static void shutdown(struct cyclades_port *info) | |||
2262 | struct CH_CTRL __iomem *ch_ctrl; | 2195 | struct CH_CTRL __iomem *ch_ctrl; |
2263 | int retval; | 2196 | int retval; |
2264 | 2197 | ||
2265 | base_addr = cy_card[card].base_addr; | 2198 | base_addr = card->base_addr; |
2266 | #ifdef CY_DEBUG_OPEN | 2199 | #ifdef CY_DEBUG_OPEN |
2267 | printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", | 2200 | printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " |
2268 | card, channel, (long)base_addr); | 2201 | "base_addr %p\n", card, channel, base_addr); |
2269 | #endif | 2202 | #endif |
2270 | 2203 | ||
2271 | firm_id = base_addr + ID_ADDRESS; | 2204 | firm_id = base_addr + ID_ADDRESS; |
2272 | if (!ISZLOADED(cy_card[card])) { | 2205 | if (!ISZLOADED(*card)) { |
2273 | return; | 2206 | return; |
2274 | } | 2207 | } |
2275 | 2208 | ||
2276 | zfw_ctrl = cy_card[card].base_addr + | 2209 | zfw_ctrl = card->base_addr + |
2277 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2210 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2278 | board_ctrl = &zfw_ctrl->board_ctrl; | 2211 | board_ctrl = &zfw_ctrl->board_ctrl; |
2279 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2212 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2280 | 2213 | ||
2281 | CY_LOCK(info, flags); | 2214 | spin_lock_irqsave(&card->card_lock, flags); |
2282 | 2215 | ||
2283 | if (info->xmit_buf) { | 2216 | if (info->xmit_buf) { |
2284 | unsigned char *temp; | 2217 | unsigned char *temp; |
@@ -2289,16 +2222,16 @@ static void shutdown(struct cyclades_port *info) | |||
2289 | 2222 | ||
2290 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { | 2223 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { |
2291 | cy_writel(&ch_ctrl[channel].rs_control, | 2224 | cy_writel(&ch_ctrl[channel].rs_control, |
2292 | (uclong)(cy_readl(&ch_ctrl[channel].rs_control)& | 2225 | (__u32)(readl(&ch_ctrl[channel].rs_control) & |
2293 | ~(C_RS_RTS | C_RS_DTR))); | 2226 | ~(C_RS_RTS | C_RS_DTR))); |
2294 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2227 | retval = cyz_issue_cmd(info->card, channel, |
2295 | C_CM_IOCTLM, 0L); | 2228 | C_CM_IOCTLM, 0L); |
2296 | if (retval != 0) { | 2229 | if (retval != 0) { |
2297 | printk("cyc:shutdown retval on ttyC%d was %x\n", | 2230 | printk(KERN_ERR"cyc:shutdown retval on ttyC%d " |
2298 | info->line, retval); | 2231 | "was %x\n", info->line, retval); |
2299 | } | 2232 | } |
2300 | #ifdef CY_DEBUG_DTR | 2233 | #ifdef CY_DEBUG_DTR |
2301 | printk("cyc:shutdown dropping Z DTR\n"); | 2234 | printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n"); |
2302 | #endif | 2235 | #endif |
2303 | } | 2236 | } |
2304 | 2237 | ||
@@ -2307,11 +2240,11 @@ static void shutdown(struct cyclades_port *info) | |||
2307 | } | 2240 | } |
2308 | info->flags &= ~ASYNC_INITIALIZED; | 2241 | info->flags &= ~ASYNC_INITIALIZED; |
2309 | 2242 | ||
2310 | CY_UNLOCK(info, flags); | 2243 | spin_unlock_irqrestore(&card->card_lock, flags); |
2311 | } | 2244 | } |
2312 | 2245 | ||
2313 | #ifdef CY_DEBUG_OPEN | 2246 | #ifdef CY_DEBUG_OPEN |
2314 | printk(" cyc shutdown done\n"); | 2247 | printk(KERN_DEBUG "cyc shutdown done\n"); |
2315 | #endif | 2248 | #endif |
2316 | } /* shutdown */ | 2249 | } /* shutdown */ |
2317 | 2250 | ||
@@ -2332,7 +2265,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2332 | int retval; | 2265 | int retval; |
2333 | void __iomem *base_addr; | 2266 | void __iomem *base_addr; |
2334 | 2267 | ||
2335 | cinfo = &cy_card[info->card]; | 2268 | cinfo = info->card; |
2336 | channel = info->line - cinfo->first_line; | 2269 | channel = info->line - cinfo->first_line; |
2337 | 2270 | ||
2338 | /* | 2271 | /* |
@@ -2340,9 +2273,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2340 | * until it's done, and then try again. | 2273 | * until it's done, and then try again. |
2341 | */ | 2274 | */ |
2342 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2275 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2343 | if (info->flags & ASYNC_CLOSING) { | 2276 | wait_event_interruptible(info->close_wait, |
2344 | interruptible_sleep_on(&info->close_wait); | 2277 | !(info->flags & ASYNC_CLOSING)); |
2345 | } | ||
2346 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 2278 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
2347 | } | 2279 | } |
2348 | 2280 | ||
@@ -2365,17 +2297,16 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2365 | retval = 0; | 2297 | retval = 0; |
2366 | add_wait_queue(&info->open_wait, &wait); | 2298 | add_wait_queue(&info->open_wait, &wait); |
2367 | #ifdef CY_DEBUG_OPEN | 2299 | #ifdef CY_DEBUG_OPEN |
2368 | printk("cyc block_til_ready before block: ttyC%d, count = %d\n", | 2300 | printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, " |
2369 | info->line, info->count); | 2301 | "count = %d\n", info->line, info->count); |
2370 | /**/ | ||
2371 | #endif | 2302 | #endif |
2372 | CY_LOCK(info, flags); | 2303 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2373 | if (!tty_hung_up_p(filp)) | 2304 | if (!tty_hung_up_p(filp)) |
2374 | info->count--; | 2305 | info->count--; |
2375 | CY_UNLOCK(info, flags); | 2306 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2376 | #ifdef CY_DEBUG_COUNT | 2307 | #ifdef CY_DEBUG_COUNT |
2377 | printk("cyc block_til_ready: (%d): decrementing count to %d\n", | 2308 | printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to " |
2378 | current->pid, info->count); | 2309 | "%d\n", current->pid, info->count); |
2379 | #endif | 2310 | #endif |
2380 | info->blocked_open++; | 2311 | info->blocked_open++; |
2381 | 2312 | ||
@@ -2386,7 +2317,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2386 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); | 2317 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
2387 | 2318 | ||
2388 | while (1) { | 2319 | while (1) { |
2389 | CY_LOCK(info, flags); | 2320 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2390 | if ((tty->termios->c_cflag & CBAUD)) { | 2321 | if ((tty->termios->c_cflag & CBAUD)) { |
2391 | cy_writeb(base_addr + (CyCAR << index), | 2322 | cy_writeb(base_addr + (CyCAR << index), |
2392 | (u_char) channel); | 2323 | (u_char) channel); |
@@ -2395,15 +2326,14 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2395 | cy_writeb(base_addr + (CyMSVR2 << index), | 2326 | cy_writeb(base_addr + (CyMSVR2 << index), |
2396 | CyDTR); | 2327 | CyDTR); |
2397 | #ifdef CY_DEBUG_DTR | 2328 | #ifdef CY_DEBUG_DTR |
2398 | printk("cyc:block_til_ready raising DTR\n"); | 2329 | printk(KERN_DEBUG "cyc:block_til_ready raising " |
2399 | printk(" status: 0x%x, 0x%x\n", | 2330 | "DTR\n"); |
2400 | cy_readb(base_addr + | 2331 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2401 | (CyMSVR1 << index)), | 2332 | readb(base_addr + (CyMSVR1 << index)), |
2402 | cy_readb(base_addr + | 2333 | readb(base_addr + (CyMSVR2 << index))); |
2403 | (CyMSVR2 << index))); | ||
2404 | #endif | 2334 | #endif |
2405 | } | 2335 | } |
2406 | CY_UNLOCK(info, flags); | 2336 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2407 | 2337 | ||
2408 | set_current_state(TASK_INTERRUPTIBLE); | 2338 | set_current_state(TASK_INTERRUPTIBLE); |
2409 | if (tty_hung_up_p(filp) || | 2339 | if (tty_hung_up_p(filp) || |
@@ -2413,26 +2343,25 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2413 | break; | 2343 | break; |
2414 | } | 2344 | } |
2415 | 2345 | ||
2416 | CY_LOCK(info, flags); | 2346 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2417 | cy_writeb(base_addr + (CyCAR << index), | 2347 | cy_writeb(base_addr + (CyCAR << index), |
2418 | (u_char) channel); | 2348 | (u_char) channel); |
2419 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || | 2349 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2420 | (cy_readb(base_addr + | 2350 | (readb(base_addr + |
2421 | (CyMSVR1 << index)) & CyDCD))) { | 2351 | (CyMSVR1 << index)) & CyDCD))) { |
2422 | CY_UNLOCK(info, flags); | 2352 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2423 | break; | 2353 | break; |
2424 | } | 2354 | } |
2425 | CY_UNLOCK(info, flags); | 2355 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2426 | 2356 | ||
2427 | if (signal_pending(current)) { | 2357 | if (signal_pending(current)) { |
2428 | retval = -ERESTARTSYS; | 2358 | retval = -ERESTARTSYS; |
2429 | break; | 2359 | break; |
2430 | } | 2360 | } |
2431 | #ifdef CY_DEBUG_OPEN | 2361 | #ifdef CY_DEBUG_OPEN |
2432 | printk("cyc block_til_ready blocking: ttyC%d, " | 2362 | printk(KERN_DEBUG "cyc block_til_ready blocking: " |
2433 | "count = %d\n", | 2363 | "ttyC%d, count = %d\n", |
2434 | info->line, info->count); | 2364 | info->line, info->count); |
2435 | /**/ | ||
2436 | #endif | 2365 | #endif |
2437 | schedule(); | 2366 | schedule(); |
2438 | } | 2367 | } |
@@ -2446,31 +2375,30 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2446 | base_addr = cinfo->base_addr; | 2375 | base_addr = cinfo->base_addr; |
2447 | firm_id = base_addr + ID_ADDRESS; | 2376 | firm_id = base_addr + ID_ADDRESS; |
2448 | if (!ISZLOADED(*cinfo)) { | 2377 | if (!ISZLOADED(*cinfo)) { |
2449 | current->state = TASK_RUNNING; | 2378 | __set_current_state(TASK_RUNNING); |
2450 | remove_wait_queue(&info->open_wait, &wait); | 2379 | remove_wait_queue(&info->open_wait, &wait); |
2451 | return -EINVAL; | 2380 | return -EINVAL; |
2452 | } | 2381 | } |
2453 | 2382 | ||
2454 | zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 2383 | zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff); |
2455 | 0xfffff); | ||
2456 | board_ctrl = &zfw_ctrl->board_ctrl; | 2384 | board_ctrl = &zfw_ctrl->board_ctrl; |
2457 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2385 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2458 | 2386 | ||
2459 | while (1) { | 2387 | while (1) { |
2460 | if ((tty->termios->c_cflag & CBAUD)) { | 2388 | if ((tty->termios->c_cflag & CBAUD)) { |
2461 | cy_writel(&ch_ctrl[channel].rs_control, | 2389 | cy_writel(&ch_ctrl[channel].rs_control, |
2462 | cy_readl(&ch_ctrl[channel]. | 2390 | readl(&ch_ctrl[channel].rs_control) | |
2463 | rs_control) | (C_RS_RTS | | 2391 | C_RS_RTS | C_RS_DTR); |
2464 | C_RS_DTR)); | 2392 | retval = cyz_issue_cmd(cinfo, |
2465 | retval = cyz_issue_cmd(&cy_card[info->card], | 2393 | channel, C_CM_IOCTLM, 0L); |
2466 | channel, C_CM_IOCTLM, 0L); | ||
2467 | if (retval != 0) { | 2394 | if (retval != 0) { |
2468 | printk("cyc:block_til_ready retval on " | 2395 | printk(KERN_ERR "cyc:block_til_ready " |
2469 | "ttyC%d was %x\n", | 2396 | "retval on ttyC%d was %x\n", |
2470 | info->line, retval); | 2397 | info->line, retval); |
2471 | } | 2398 | } |
2472 | #ifdef CY_DEBUG_DTR | 2399 | #ifdef CY_DEBUG_DTR |
2473 | printk("cyc:block_til_ready raising Z DTR\n"); | 2400 | printk(KERN_DEBUG "cyc:block_til_ready raising " |
2401 | "Z DTR\n"); | ||
2474 | #endif | 2402 | #endif |
2475 | } | 2403 | } |
2476 | 2404 | ||
@@ -2482,7 +2410,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2482 | break; | 2410 | break; |
2483 | } | 2411 | } |
2484 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || | 2412 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2485 | (cy_readl(&ch_ctrl[channel].rs_status) & | 2413 | (readl(&ch_ctrl[channel].rs_status) & |
2486 | C_RS_DCD))) { | 2414 | C_RS_DCD))) { |
2487 | break; | 2415 | break; |
2488 | } | 2416 | } |
@@ -2491,28 +2419,26 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2491 | break; | 2419 | break; |
2492 | } | 2420 | } |
2493 | #ifdef CY_DEBUG_OPEN | 2421 | #ifdef CY_DEBUG_OPEN |
2494 | printk("cyc block_til_ready blocking: ttyC%d, " | 2422 | printk(KERN_DEBUG "cyc block_til_ready blocking: " |
2495 | "count = %d\n", | 2423 | "ttyC%d, count = %d\n", |
2496 | info->line, info->count); | 2424 | info->line, info->count); |
2497 | /**/ | ||
2498 | #endif | 2425 | #endif |
2499 | schedule(); | 2426 | schedule(); |
2500 | } | 2427 | } |
2501 | } | 2428 | } |
2502 | current->state = TASK_RUNNING; | 2429 | __set_current_state(TASK_RUNNING); |
2503 | remove_wait_queue(&info->open_wait, &wait); | 2430 | remove_wait_queue(&info->open_wait, &wait); |
2504 | if (!tty_hung_up_p(filp)) { | 2431 | if (!tty_hung_up_p(filp)) { |
2505 | info->count++; | 2432 | info->count++; |
2506 | #ifdef CY_DEBUG_COUNT | 2433 | #ifdef CY_DEBUG_COUNT |
2507 | printk("cyc:block_til_ready (%d): incrementing count to %d\n", | 2434 | printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing " |
2508 | current->pid, info->count); | 2435 | "count to %d\n", current->pid, info->count); |
2509 | #endif | 2436 | #endif |
2510 | } | 2437 | } |
2511 | info->blocked_open--; | 2438 | info->blocked_open--; |
2512 | #ifdef CY_DEBUG_OPEN | 2439 | #ifdef CY_DEBUG_OPEN |
2513 | printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", | 2440 | printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, " |
2514 | info->line, info->count); | 2441 | "count = %d\n", info->line, info->count); |
2515 | /**/ | ||
2516 | #endif | 2442 | #endif |
2517 | if (retval) | 2443 | if (retval) |
2518 | return retval; | 2444 | return retval; |
@@ -2527,13 +2453,20 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2527 | static int cy_open(struct tty_struct *tty, struct file *filp) | 2453 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2528 | { | 2454 | { |
2529 | struct cyclades_port *info; | 2455 | struct cyclades_port *info; |
2456 | unsigned int i; | ||
2530 | int retval, line; | 2457 | int retval, line; |
2531 | 2458 | ||
2532 | line = tty->index; | 2459 | line = tty->index; |
2533 | if ((line < 0) || (NR_PORTS <= line)) { | 2460 | if ((line < 0) || (NR_PORTS <= line)) { |
2534 | return -ENODEV; | 2461 | return -ENODEV; |
2535 | } | 2462 | } |
2536 | info = &cy_port[line]; | 2463 | for (i = 0; i < NR_CARDS; i++) |
2464 | if (line < cy_card[i].first_line + cy_card[i].nports && | ||
2465 | line >= cy_card[i].first_line) | ||
2466 | break; | ||
2467 | if (i >= NR_CARDS) | ||
2468 | return -ENODEV; | ||
2469 | info = &cy_card[i].ports[line - cy_card[i].first_line]; | ||
2537 | if (info->line < 0) { | 2470 | if (info->line < 0) { |
2538 | return -ENODEV; | 2471 | return -ENODEV; |
2539 | } | 2472 | } |
@@ -2542,23 +2475,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2542 | treat it as absent from the system. This | 2475 | treat it as absent from the system. This |
2543 | will make the user pay attention. | 2476 | will make the user pay attention. |
2544 | */ | 2477 | */ |
2545 | if (IS_CYC_Z(cy_card[info->card])) { | 2478 | if (IS_CYC_Z(*info->card)) { |
2546 | struct cyclades_card *cinfo = &cy_card[info->card]; | 2479 | struct cyclades_card *cinfo = info->card; |
2547 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; | 2480 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; |
2548 | 2481 | ||
2549 | if (!ISZLOADED(*cinfo)) { | 2482 | if (!ISZLOADED(*cinfo)) { |
2550 | if (((ZE_V1 == cy_readl( | 2483 | if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *) |
2551 | &((struct RUNTIME_9060 __iomem *) | ||
2552 | (cinfo->ctl_addr))->mail_box_0)) && | 2484 | (cinfo->ctl_addr))->mail_box_0)) && |
2553 | Z_FPGA_CHECK(*cinfo)) && | 2485 | Z_FPGA_CHECK(*cinfo)) && |
2554 | (ZFIRM_HLT == cy_readl( | 2486 | (ZFIRM_HLT == readl( |
2555 | &firm_id->signature))) { | 2487 | &firm_id->signature))) { |
2556 | printk("cyc:Cyclades-Z Error: you need an " | 2488 | printk(KERN_ERR "cyc:Cyclades-Z Error: you " |
2557 | "external power supply for this number " | 2489 | "need an external power supply for " |
2558 | "of ports.\n\rFirmware halted.\r\n"); | 2490 | "this number of ports.\nFirmware " |
2491 | "halted.\n"); | ||
2559 | } else { | 2492 | } else { |
2560 | printk("cyc:Cyclades-Z firmware not yet " | 2493 | printk(KERN_ERR "cyc:Cyclades-Z firmware not " |
2561 | "loaded\n"); | 2494 | "yet loaded\n"); |
2562 | } | 2495 | } |
2563 | return -ENODEV; | 2496 | return -ENODEV; |
2564 | } | 2497 | } |
@@ -2572,24 +2505,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2572 | struct BOARD_CTRL __iomem *board_ctrl; | 2505 | struct BOARD_CTRL __iomem *board_ctrl; |
2573 | 2506 | ||
2574 | zfw_ctrl = cinfo->base_addr + | 2507 | zfw_ctrl = cinfo->base_addr + |
2575 | (cy_readl(&firm_id->zfwctrl_addr) & | 2508 | (readl(&firm_id->zfwctrl_addr) & |
2576 | 0xfffff); | 2509 | 0xfffff); |
2577 | 2510 | ||
2578 | board_ctrl = &zfw_ctrl->board_ctrl; | 2511 | board_ctrl = &zfw_ctrl->board_ctrl; |
2579 | 2512 | ||
2580 | /* Enable interrupts on the PLX chip */ | 2513 | /* Enable interrupts on the PLX chip */ |
2581 | cy_writew(cinfo->ctl_addr + 0x68, | 2514 | cy_writew(cinfo->ctl_addr + 0x68, |
2582 | cy_readw(cinfo->ctl_addr + | 2515 | readw(cinfo->ctl_addr + 0x68) | 0x0900); |
2583 | 0x68) | 0x0900); | ||
2584 | /* Enable interrupts on the FW */ | 2516 | /* Enable interrupts on the FW */ |
2585 | retval = cyz_issue_cmd(cinfo, 0, | 2517 | retval = cyz_issue_cmd(cinfo, 0, |
2586 | C_CM_IRQ_ENBL, 0L); | 2518 | C_CM_IRQ_ENBL, 0L); |
2587 | if (retval != 0) { | 2519 | if (retval != 0) { |
2588 | printk("cyc:IRQ enable retval was %x\n", | 2520 | printk(KERN_ERR "cyc:IRQ enable retval " |
2589 | retval); | 2521 | "was %x\n", retval); |
2590 | } | 2522 | } |
2591 | cinfo->nports = | 2523 | cinfo->nports = |
2592 | (int)cy_readl(&board_ctrl->n_channel); | 2524 | (int)readl(&board_ctrl->n_channel); |
2593 | cinfo->intr_enabled = 1; | 2525 | cinfo->intr_enabled = 1; |
2594 | } | 2526 | } |
2595 | } | 2527 | } |
@@ -2599,7 +2531,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2599 | return -ENODEV; | 2531 | return -ENODEV; |
2600 | } | 2532 | } |
2601 | #ifdef CY_DEBUG_OTHER | 2533 | #ifdef CY_DEBUG_OTHER |
2602 | printk("cyc:cy_open ttyC%d\n", info->line); /* */ | 2534 | printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); |
2603 | #endif | 2535 | #endif |
2604 | tty->driver_data = info; | 2536 | tty->driver_data = info; |
2605 | info->tty = tty; | 2537 | info->tty = tty; |
@@ -2607,12 +2539,12 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2607 | return -ENODEV; | 2539 | return -ENODEV; |
2608 | } | 2540 | } |
2609 | #ifdef CY_DEBUG_OPEN | 2541 | #ifdef CY_DEBUG_OPEN |
2610 | printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count); | 2542 | printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, |
2611 | /**/ | 2543 | info->count); |
2612 | #endif | 2544 | #endif |
2613 | info->count++; | 2545 | info->count++; |
2614 | #ifdef CY_DEBUG_COUNT | 2546 | #ifdef CY_DEBUG_COUNT |
2615 | printk("cyc:cy_open (%d): incrementing count to %d\n", | 2547 | printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", |
2616 | current->pid, info->count); | 2548 | current->pid, info->count); |
2617 | #endif | 2549 | #endif |
2618 | 2550 | ||
@@ -2620,8 +2552,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2620 | * If the port is the middle of closing, bail out now | 2552 | * If the port is the middle of closing, bail out now |
2621 | */ | 2553 | */ |
2622 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2554 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2623 | if (info->flags & ASYNC_CLOSING) | 2555 | wait_event_interruptible(info->close_wait, |
2624 | interruptible_sleep_on(&info->close_wait); | 2556 | !(info->flags & ASYNC_CLOSING)); |
2625 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 2557 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
2626 | } | 2558 | } |
2627 | 2559 | ||
@@ -2636,8 +2568,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2636 | retval = block_til_ready(tty, filp, info); | 2568 | retval = block_til_ready(tty, filp, info); |
2637 | if (retval) { | 2569 | if (retval) { |
2638 | #ifdef CY_DEBUG_OPEN | 2570 | #ifdef CY_DEBUG_OPEN |
2639 | printk("cyc:cy_open returning after block_til_ready with %d\n", | 2571 | printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " |
2640 | retval); | 2572 | "with %d\n", retval); |
2641 | #endif | 2573 | #endif |
2642 | return retval; | 2574 | return retval; |
2643 | } | 2575 | } |
@@ -2645,8 +2577,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2645 | info->throttle = 0; | 2577 | info->throttle = 0; |
2646 | 2578 | ||
2647 | #ifdef CY_DEBUG_OPEN | 2579 | #ifdef CY_DEBUG_OPEN |
2648 | printk(" cyc:cy_open done\n"); | 2580 | printk(KERN_DEBUG "cyc:cy_open done\n"); |
2649 | /**/ | ||
2650 | #endif | 2581 | #endif |
2651 | return 0; | 2582 | return 0; |
2652 | } /* cy_open */ | 2583 | } /* cy_open */ |
@@ -2656,9 +2587,10 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2656 | */ | 2587 | */ |
2657 | static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | 2588 | static void cy_wait_until_sent(struct tty_struct *tty, int timeout) |
2658 | { | 2589 | { |
2659 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2590 | struct cyclades_card *card; |
2591 | struct cyclades_port *info = tty->driver_data; | ||
2660 | void __iomem *base_addr; | 2592 | void __iomem *base_addr; |
2661 | int card, chip, channel, index; | 2593 | int chip, channel, index; |
2662 | unsigned long orig_jiffies; | 2594 | unsigned long orig_jiffies; |
2663 | int char_time; | 2595 | int char_time; |
2664 | 2596 | ||
@@ -2697,20 +2629,19 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2697 | if (!timeout || timeout > 2 * info->timeout) | 2629 | if (!timeout || timeout > 2 * info->timeout) |
2698 | timeout = 2 * info->timeout; | 2630 | timeout = 2 * info->timeout; |
2699 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2631 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2700 | printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); | 2632 | printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", |
2701 | printk("jiff=%lu...", jiffies); | 2633 | timeout, char_time, jiffies); |
2702 | #endif | 2634 | #endif |
2703 | card = info->card; | 2635 | card = info->card; |
2704 | channel = (info->line) - (cy_card[card].first_line); | 2636 | channel = (info->line) - (card->first_line); |
2705 | if (!IS_CYC_Z(cy_card[card])) { | 2637 | if (!IS_CYC_Z(*card)) { |
2706 | chip = channel >> 2; | 2638 | chip = channel >> 2; |
2707 | channel &= 0x03; | 2639 | channel &= 0x03; |
2708 | index = cy_card[card].bus_index; | 2640 | index = card->bus_index; |
2709 | base_addr = | 2641 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2710 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | 2642 | while (readb(base_addr + (CySRER << index)) & CyTxRdy) { |
2711 | while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) { | ||
2712 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2643 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2713 | printk("Not clean (jiff=%lu)...", jiffies); | 2644 | printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); |
2714 | #endif | 2645 | #endif |
2715 | if (msleep_interruptible(jiffies_to_msecs(char_time))) | 2646 | if (msleep_interruptible(jiffies_to_msecs(char_time))) |
2716 | break; | 2647 | break; |
@@ -2718,13 +2649,11 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2718 | timeout)) | 2649 | timeout)) |
2719 | break; | 2650 | break; |
2720 | } | 2651 | } |
2721 | } else { | ||
2722 | /* Nothing to do! */ | ||
2723 | } | 2652 | } |
2724 | /* Run one more char cycle */ | 2653 | /* Run one more char cycle */ |
2725 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 2654 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
2726 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2655 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2727 | printk("Clean (jiff=%lu)...done\n", jiffies); | 2656 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); |
2728 | #endif | 2657 | #endif |
2729 | } | 2658 | } |
2730 | 2659 | ||
@@ -2733,25 +2662,29 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2733 | */ | 2662 | */ |
2734 | static void cy_close(struct tty_struct *tty, struct file *filp) | 2663 | static void cy_close(struct tty_struct *tty, struct file *filp) |
2735 | { | 2664 | { |
2736 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2665 | struct cyclades_port *info = tty->driver_data; |
2666 | struct cyclades_card *card; | ||
2737 | unsigned long flags; | 2667 | unsigned long flags; |
2738 | 2668 | ||
2739 | #ifdef CY_DEBUG_OTHER | 2669 | #ifdef CY_DEBUG_OTHER |
2740 | printk("cyc:cy_close ttyC%d\n", info->line); | 2670 | printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line); |
2741 | #endif | 2671 | #endif |
2742 | 2672 | ||
2743 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { | 2673 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { |
2744 | return; | 2674 | return; |
2745 | } | 2675 | } |
2746 | 2676 | ||
2747 | CY_LOCK(info, flags); | 2677 | card = info->card; |
2678 | |||
2679 | spin_lock_irqsave(&card->card_lock, flags); | ||
2748 | /* If the TTY is being hung up, nothing to do */ | 2680 | /* If the TTY is being hung up, nothing to do */ |
2749 | if (tty_hung_up_p(filp)) { | 2681 | if (tty_hung_up_p(filp)) { |
2750 | CY_UNLOCK(info, flags); | 2682 | spin_unlock_irqrestore(&card->card_lock, flags); |
2751 | return; | 2683 | return; |
2752 | } | 2684 | } |
2753 | #ifdef CY_DEBUG_OPEN | 2685 | #ifdef CY_DEBUG_OPEN |
2754 | printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); | 2686 | printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line, |
2687 | info->count); | ||
2755 | #endif | 2688 | #endif |
2756 | if ((tty->count == 1) && (info->count != 1)) { | 2689 | if ((tty->count == 1) && (info->count != 1)) { |
2757 | /* | 2690 | /* |
@@ -2761,22 +2694,22 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2761 | * one, we've got real problems, since it means the | 2694 | * one, we've got real problems, since it means the |
2762 | * serial port won't be shutdown. | 2695 | * serial port won't be shutdown. |
2763 | */ | 2696 | */ |
2764 | printk("cyc:cy_close: bad serial port count; tty->count is 1, " | 2697 | printk(KERN_ERR "cyc:cy_close: bad serial port count; " |
2765 | "info->count is %d\n", info->count); | 2698 | "tty->count is 1, info->count is %d\n", info->count); |
2766 | info->count = 1; | 2699 | info->count = 1; |
2767 | } | 2700 | } |
2768 | #ifdef CY_DEBUG_COUNT | 2701 | #ifdef CY_DEBUG_COUNT |
2769 | printk("cyc:cy_close at (%d): decrementing count to %d\n", | 2702 | printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n", |
2770 | current->pid, info->count - 1); | 2703 | current->pid, info->count - 1); |
2771 | #endif | 2704 | #endif |
2772 | if (--info->count < 0) { | 2705 | if (--info->count < 0) { |
2773 | #ifdef CY_DEBUG_COUNT | 2706 | #ifdef CY_DEBUG_COUNT |
2774 | printk("cyc:cyc_close setting count to 0\n"); | 2707 | printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n"); |
2775 | #endif | 2708 | #endif |
2776 | info->count = 0; | 2709 | info->count = 0; |
2777 | } | 2710 | } |
2778 | if (info->count) { | 2711 | if (info->count) { |
2779 | CY_UNLOCK(info, flags); | 2712 | spin_unlock_irqrestore(&card->card_lock, flags); |
2780 | return; | 2713 | return; |
2781 | } | 2714 | } |
2782 | info->flags |= ASYNC_CLOSING; | 2715 | info->flags |= ASYNC_CLOSING; |
@@ -2786,81 +2719,80 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2786 | * the line discipline to only process XON/XOFF characters. | 2719 | * the line discipline to only process XON/XOFF characters. |
2787 | */ | 2720 | */ |
2788 | tty->closing = 1; | 2721 | tty->closing = 1; |
2789 | CY_UNLOCK(info, flags); | 2722 | spin_unlock_irqrestore(&card->card_lock, flags); |
2790 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { | 2723 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { |
2791 | tty_wait_until_sent(tty, info->closing_wait); | 2724 | tty_wait_until_sent(tty, info->closing_wait); |
2792 | } | 2725 | } |
2793 | CY_LOCK(info, flags); | 2726 | spin_lock_irqsave(&card->card_lock, flags); |
2794 | 2727 | ||
2795 | if (!IS_CYC_Z(cy_card[info->card])) { | 2728 | if (!IS_CYC_Z(*card)) { |
2796 | int channel = info->line - cy_card[info->card].first_line; | 2729 | int channel = info->line - card->first_line; |
2797 | int index = cy_card[info->card].bus_index; | 2730 | int index = card->bus_index; |
2798 | void __iomem *base_addr = cy_card[info->card].base_addr + | 2731 | void __iomem *base_addr = card->base_addr + |
2799 | (cy_chip_offset[channel >> 2] << index); | 2732 | (cy_chip_offset[channel >> 2] << index); |
2800 | /* Stop accepting input */ | 2733 | /* Stop accepting input */ |
2801 | channel &= 0x03; | 2734 | channel &= 0x03; |
2802 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 2735 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
2803 | cy_writeb(base_addr + (CySRER << index), | 2736 | cy_writeb(base_addr + (CySRER << index), |
2804 | cy_readb(base_addr + (CySRER << index)) & ~CyRxData); | 2737 | readb(base_addr + (CySRER << index)) & ~CyRxData); |
2805 | if (info->flags & ASYNC_INITIALIZED) { | 2738 | if (info->flags & ASYNC_INITIALIZED) { |
2806 | /* Waiting for on-board buffers to be empty before closing | 2739 | /* Waiting for on-board buffers to be empty before closing |
2807 | the port */ | 2740 | the port */ |
2808 | CY_UNLOCK(info, flags); | 2741 | spin_unlock_irqrestore(&card->card_lock, flags); |
2809 | cy_wait_until_sent(tty, info->timeout); | 2742 | cy_wait_until_sent(tty, info->timeout); |
2810 | CY_LOCK(info, flags); | 2743 | spin_lock_irqsave(&card->card_lock, flags); |
2811 | } | 2744 | } |
2812 | } else { | 2745 | } else { |
2813 | #ifdef Z_WAKE | 2746 | #ifdef Z_WAKE |
2814 | /* Waiting for on-board buffers to be empty before closing the port */ | 2747 | /* Waiting for on-board buffers to be empty before closing the port */ |
2815 | void __iomem *base_addr = cy_card[info->card].base_addr; | 2748 | void __iomem *base_addr = card->base_addr; |
2816 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; | 2749 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; |
2817 | struct ZFW_CTRL __iomem *zfw_ctrl = | 2750 | struct ZFW_CTRL __iomem *zfw_ctrl = |
2818 | base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2751 | base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2819 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; | 2752 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; |
2820 | int channel = info->line - cy_card[info->card].first_line; | 2753 | int channel = info->line - card->first_line; |
2821 | int retval; | 2754 | int retval; |
2822 | 2755 | ||
2823 | if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { | 2756 | if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { |
2824 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2757 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); |
2825 | C_CM_IOCTLW, 0L); | ||
2826 | if (retval != 0) { | 2758 | if (retval != 0) { |
2827 | printk("cyc:cy_close retval on ttyC%d was %x\n", | 2759 | printk(KERN_DEBUG "cyc:cy_close retval on " |
2828 | info->line, retval); | 2760 | "ttyC%d was %x\n", info->line, retval); |
2829 | } | 2761 | } |
2830 | CY_UNLOCK(info, flags); | 2762 | spin_unlock_irqrestore(&card->card_lock, flags); |
2831 | interruptible_sleep_on(&info->shutdown_wait); | 2763 | wait_for_completion_interruptible(&info->shutdown_wait); |
2832 | CY_LOCK(info, flags); | 2764 | spin_lock_irqsave(&card->card_lock, flags); |
2833 | } | 2765 | } |
2834 | #endif | 2766 | #endif |
2835 | } | 2767 | } |
2836 | 2768 | ||
2837 | CY_UNLOCK(info, flags); | 2769 | spin_unlock_irqrestore(&card->card_lock, flags); |
2838 | shutdown(info); | 2770 | shutdown(info); |
2839 | if (tty->driver->flush_buffer) | 2771 | if (tty->driver->flush_buffer) |
2840 | tty->driver->flush_buffer(tty); | 2772 | tty->driver->flush_buffer(tty); |
2841 | tty_ldisc_flush(tty); | 2773 | tty_ldisc_flush(tty); |
2842 | CY_LOCK(info, flags); | 2774 | spin_lock_irqsave(&card->card_lock, flags); |
2843 | 2775 | ||
2844 | tty->closing = 0; | 2776 | tty->closing = 0; |
2845 | info->event = 0; | 2777 | info->event = 0; |
2846 | info->tty = NULL; | 2778 | info->tty = NULL; |
2847 | if (info->blocked_open) { | 2779 | if (info->blocked_open) { |
2848 | CY_UNLOCK(info, flags); | 2780 | spin_unlock_irqrestore(&card->card_lock, flags); |
2849 | if (info->close_delay) { | 2781 | if (info->close_delay) { |
2850 | msleep_interruptible(jiffies_to_msecs | 2782 | msleep_interruptible(jiffies_to_msecs |
2851 | (info->close_delay)); | 2783 | (info->close_delay)); |
2852 | } | 2784 | } |
2853 | wake_up_interruptible(&info->open_wait); | 2785 | wake_up_interruptible(&info->open_wait); |
2854 | CY_LOCK(info, flags); | 2786 | spin_lock_irqsave(&card->card_lock, flags); |
2855 | } | 2787 | } |
2856 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 2788 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
2857 | wake_up_interruptible(&info->close_wait); | 2789 | wake_up_interruptible(&info->close_wait); |
2858 | 2790 | ||
2859 | #ifdef CY_DEBUG_OTHER | 2791 | #ifdef CY_DEBUG_OTHER |
2860 | printk(" cyc:cy_close done\n"); | 2792 | printk(KERN_DEBUG "cyc:cy_close done\n"); |
2861 | #endif | 2793 | #endif |
2862 | 2794 | ||
2863 | CY_UNLOCK(info, flags); | 2795 | spin_unlock_irqrestore(&card->card_lock, flags); |
2864 | } /* cy_close */ | 2796 | } /* cy_close */ |
2865 | 2797 | ||
2866 | /* This routine gets called when tty_write has put something into | 2798 | /* This routine gets called when tty_write has put something into |
@@ -2878,12 +2810,12 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2878 | */ | 2810 | */ |
2879 | static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | 2811 | static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) |
2880 | { | 2812 | { |
2881 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2813 | struct cyclades_port *info = tty->driver_data; |
2882 | unsigned long flags; | 2814 | unsigned long flags; |
2883 | int c, ret = 0; | 2815 | int c, ret = 0; |
2884 | 2816 | ||
2885 | #ifdef CY_DEBUG_IO | 2817 | #ifdef CY_DEBUG_IO |
2886 | printk("cyc:cy_write ttyC%d\n", info->line); /* */ | 2818 | printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); |
2887 | #endif | 2819 | #endif |
2888 | 2820 | ||
2889 | if (serial_paranoia_check(info, tty->name, "cy_write")) { | 2821 | if (serial_paranoia_check(info, tty->name, "cy_write")) { |
@@ -2893,7 +2825,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2893 | if (!info->xmit_buf) | 2825 | if (!info->xmit_buf) |
2894 | return 0; | 2826 | return 0; |
2895 | 2827 | ||
2896 | CY_LOCK(info, flags); | 2828 | spin_lock_irqsave(&info->card->card_lock, flags); |
2897 | while (1) { | 2829 | while (1) { |
2898 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), | 2830 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), |
2899 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); | 2831 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); |
@@ -2909,7 +2841,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2909 | count -= c; | 2841 | count -= c; |
2910 | ret += c; | 2842 | ret += c; |
2911 | } | 2843 | } |
2912 | CY_UNLOCK(info, flags); | 2844 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2913 | 2845 | ||
2914 | info->idle_stats.xmit_bytes += ret; | 2846 | info->idle_stats.xmit_bytes += ret; |
2915 | info->idle_stats.xmit_idle = jiffies; | 2847 | info->idle_stats.xmit_idle = jiffies; |
@@ -2929,11 +2861,11 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2929 | */ | 2861 | */ |
2930 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) | 2862 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) |
2931 | { | 2863 | { |
2932 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2864 | struct cyclades_port *info = tty->driver_data; |
2933 | unsigned long flags; | 2865 | unsigned long flags; |
2934 | 2866 | ||
2935 | #ifdef CY_DEBUG_IO | 2867 | #ifdef CY_DEBUG_IO |
2936 | printk("cyc:cy_put_char ttyC%d\n", info->line); | 2868 | printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line); |
2937 | #endif | 2869 | #endif |
2938 | 2870 | ||
2939 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 2871 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
@@ -2942,9 +2874,9 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2942 | if (!info->xmit_buf) | 2874 | if (!info->xmit_buf) |
2943 | return; | 2875 | return; |
2944 | 2876 | ||
2945 | CY_LOCK(info, flags); | 2877 | spin_lock_irqsave(&info->card->card_lock, flags); |
2946 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { | 2878 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { |
2947 | CY_UNLOCK(info, flags); | 2879 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2948 | return; | 2880 | return; |
2949 | } | 2881 | } |
2950 | 2882 | ||
@@ -2953,7 +2885,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2953 | info->xmit_cnt++; | 2885 | info->xmit_cnt++; |
2954 | info->idle_stats.xmit_bytes++; | 2886 | info->idle_stats.xmit_bytes++; |
2955 | info->idle_stats.xmit_idle = jiffies; | 2887 | info->idle_stats.xmit_idle = jiffies; |
2956 | CY_UNLOCK(info, flags); | 2888 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2957 | } /* cy_put_char */ | 2889 | } /* cy_put_char */ |
2958 | 2890 | ||
2959 | /* | 2891 | /* |
@@ -2962,10 +2894,10 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2962 | */ | 2894 | */ |
2963 | static void cy_flush_chars(struct tty_struct *tty) | 2895 | static void cy_flush_chars(struct tty_struct *tty) |
2964 | { | 2896 | { |
2965 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2897 | struct cyclades_port *info = tty->driver_data; |
2966 | 2898 | ||
2967 | #ifdef CY_DEBUG_IO | 2899 | #ifdef CY_DEBUG_IO |
2968 | printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ | 2900 | printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line); |
2969 | #endif | 2901 | #endif |
2970 | 2902 | ||
2971 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) | 2903 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) |
@@ -2986,11 +2918,11 @@ static void cy_flush_chars(struct tty_struct *tty) | |||
2986 | */ | 2918 | */ |
2987 | static int cy_write_room(struct tty_struct *tty) | 2919 | static int cy_write_room(struct tty_struct *tty) |
2988 | { | 2920 | { |
2989 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2921 | struct cyclades_port *info = tty->driver_data; |
2990 | int ret; | 2922 | int ret; |
2991 | 2923 | ||
2992 | #ifdef CY_DEBUG_IO | 2924 | #ifdef CY_DEBUG_IO |
2993 | printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ | 2925 | printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line); |
2994 | #endif | 2926 | #endif |
2995 | 2927 | ||
2996 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) | 2928 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) |
@@ -3003,46 +2935,49 @@ static int cy_write_room(struct tty_struct *tty) | |||
3003 | 2935 | ||
3004 | static int cy_chars_in_buffer(struct tty_struct *tty) | 2936 | static int cy_chars_in_buffer(struct tty_struct *tty) |
3005 | { | 2937 | { |
3006 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2938 | struct cyclades_card *card; |
3007 | int card, channel; | 2939 | struct cyclades_port *info = tty->driver_data; |
2940 | int channel; | ||
3008 | 2941 | ||
3009 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) | 2942 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) |
3010 | return 0; | 2943 | return 0; |
3011 | 2944 | ||
3012 | card = info->card; | 2945 | card = info->card; |
3013 | channel = (info->line) - (cy_card[card].first_line); | 2946 | channel = (info->line) - (card->first_line); |
3014 | 2947 | ||
3015 | #ifdef Z_EXT_CHARS_IN_BUFFER | 2948 | #ifdef Z_EXT_CHARS_IN_BUFFER |
3016 | if (!IS_CYC_Z(cy_card[card])) { | 2949 | if (!IS_CYC_Z(cy_card[card])) { |
3017 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 2950 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
3018 | #ifdef CY_DEBUG_IO | 2951 | #ifdef CY_DEBUG_IO |
3019 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ | 2952 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2953 | info->line, info->xmit_cnt); | ||
3020 | #endif | 2954 | #endif |
3021 | return info->xmit_cnt; | 2955 | return info->xmit_cnt; |
3022 | #ifdef Z_EXT_CHARS_IN_BUFFER | 2956 | #ifdef Z_EXT_CHARS_IN_BUFFER |
3023 | } else { | 2957 | } else { |
3024 | static volatile struct FIRM_ID *firm_id; | 2958 | static struct FIRM_ID *firm_id; |
3025 | static volatile struct ZFW_CTRL *zfw_ctrl; | 2959 | static struct ZFW_CTRL *zfw_ctrl; |
3026 | static volatile struct CH_CTRL *ch_ctrl; | 2960 | static struct CH_CTRL *ch_ctrl; |
3027 | static volatile struct BUF_CTRL *buf_ctrl; | 2961 | static struct BUF_CTRL *buf_ctrl; |
3028 | int char_count; | 2962 | int char_count; |
3029 | volatile uclong tx_put, tx_get, tx_bufsize; | 2963 | __u32 tx_put, tx_get, tx_bufsize; |
3030 | 2964 | ||
3031 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 2965 | firm_id = card->base_addr + ID_ADDRESS; |
3032 | zfw_ctrl = cy_card[card].base_addr + | 2966 | zfw_ctrl = card->base_addr + |
3033 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2967 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3034 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 2968 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
3035 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | 2969 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); |
3036 | 2970 | ||
3037 | tx_get = cy_readl(&buf_ctrl->tx_get); | 2971 | tx_get = readl(&buf_ctrl->tx_get); |
3038 | tx_put = cy_readl(&buf_ctrl->tx_put); | 2972 | tx_put = readl(&buf_ctrl->tx_put); |
3039 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 2973 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); |
3040 | if (tx_put >= tx_get) | 2974 | if (tx_put >= tx_get) |
3041 | char_count = tx_put - tx_get; | 2975 | char_count = tx_put - tx_get; |
3042 | else | 2976 | else |
3043 | char_count = tx_put - tx_get + tx_bufsize; | 2977 | char_count = tx_put - tx_get + tx_bufsize; |
3044 | #ifdef CY_DEBUG_IO | 2978 | #ifdef CY_DEBUG_IO |
3045 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */ | 2979 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2980 | info->line, info->xmit_cnt + char_count); | ||
3046 | #endif | 2981 | #endif |
3047 | return info->xmit_cnt + char_count; | 2982 | return info->xmit_cnt + char_count; |
3048 | } | 2983 | } |
@@ -3055,10 +2990,10 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
3055 | * ------------------------------------------------------------ | 2990 | * ------------------------------------------------------------ |
3056 | */ | 2991 | */ |
3057 | 2992 | ||
3058 | static void cyy_baud_calc(struct cyclades_port *info, uclong baud) | 2993 | static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) |
3059 | { | 2994 | { |
3060 | int co, co_val, bpr; | 2995 | int co, co_val, bpr; |
3061 | uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : | 2996 | __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : |
3062 | 25000000); | 2997 | 25000000); |
3063 | 2998 | ||
3064 | if (baud == 0) { | 2999 | if (baud == 0) { |
@@ -3086,9 +3021,10 @@ static void cyy_baud_calc(struct cyclades_port *info, uclong baud) | |||
3086 | */ | 3021 | */ |
3087 | static void set_line_char(struct cyclades_port *info) | 3022 | static void set_line_char(struct cyclades_port *info) |
3088 | { | 3023 | { |
3024 | struct cyclades_card *card; | ||
3089 | unsigned long flags; | 3025 | unsigned long flags; |
3090 | void __iomem *base_addr; | 3026 | void __iomem *base_addr; |
3091 | int card, chip, channel, index; | 3027 | int chip, channel, index; |
3092 | unsigned cflag, iflag; | 3028 | unsigned cflag, iflag; |
3093 | unsigned short chip_number; | 3029 | unsigned short chip_number; |
3094 | int baud, baud_rate = 0; | 3030 | int baud, baud_rate = 0; |
@@ -3118,12 +3054,12 @@ static void set_line_char(struct cyclades_port *info) | |||
3118 | } | 3054 | } |
3119 | 3055 | ||
3120 | card = info->card; | 3056 | card = info->card; |
3121 | channel = (info->line) - (cy_card[card].first_line); | 3057 | channel = info->line - card->first_line; |
3122 | chip_number = channel / 4; | 3058 | chip_number = channel / 4; |
3123 | 3059 | ||
3124 | if (!IS_CYC_Z(cy_card[card])) { | 3060 | if (!IS_CYC_Z(*card)) { |
3125 | 3061 | ||
3126 | index = cy_card[card].bus_index; | 3062 | index = card->bus_index; |
3127 | 3063 | ||
3128 | /* baud rate */ | 3064 | /* baud rate */ |
3129 | baud = tty_get_baud_rate(info->tty); | 3065 | baud = tty_get_baud_rate(info->tty); |
@@ -3241,10 +3177,9 @@ static void set_line_char(struct cyclades_port *info) | |||
3241 | 3177 | ||
3242 | chip = channel >> 2; | 3178 | chip = channel >> 2; |
3243 | channel &= 0x03; | 3179 | channel &= 0x03; |
3244 | base_addr = cy_card[card].base_addr + | 3180 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3245 | (cy_chip_offset[chip] << index); | ||
3246 | 3181 | ||
3247 | CY_LOCK(info, flags); | 3182 | spin_lock_irqsave(&card->card_lock, flags); |
3248 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 3183 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3249 | 3184 | ||
3250 | /* tx and rx baud rate */ | 3185 | /* tx and rx baud rate */ |
@@ -3276,8 +3211,7 @@ static void set_line_char(struct cyclades_port *info) | |||
3276 | if (C_CLOCAL(info->tty)) { | 3211 | if (C_CLOCAL(info->tty)) { |
3277 | /* without modem intr */ | 3212 | /* without modem intr */ |
3278 | cy_writeb(base_addr + (CySRER << index), | 3213 | cy_writeb(base_addr + (CySRER << index), |
3279 | cy_readb(base_addr + | 3214 | readb(base_addr + (CySRER << index)) | CyMdmCh); |
3280 | (CySRER << index)) | CyMdmCh); | ||
3281 | /* act on 1->0 modem transitions */ | 3215 | /* act on 1->0 modem transitions */ |
3282 | if ((cflag & CRTSCTS) && info->rflow) { | 3216 | if ((cflag & CRTSCTS) && info->rflow) { |
3283 | cy_writeb(base_addr + (CyMCOR1 << index), | 3217 | cy_writeb(base_addr + (CyMCOR1 << index), |
@@ -3291,7 +3225,7 @@ static void set_line_char(struct cyclades_port *info) | |||
3291 | } else { | 3225 | } else { |
3292 | /* without modem intr */ | 3226 | /* without modem intr */ |
3293 | cy_writeb(base_addr + (CySRER << index), | 3227 | cy_writeb(base_addr + (CySRER << index), |
3294 | cy_readb(base_addr + | 3228 | readb(base_addr + |
3295 | (CySRER << index)) | CyMdmCh); | 3229 | (CySRER << index)) | CyMdmCh); |
3296 | /* act on 1->0 modem transitions */ | 3230 | /* act on 1->0 modem transitions */ |
3297 | if ((cflag & CRTSCTS) && info->rflow) { | 3231 | if ((cflag & CRTSCTS) && info->rflow) { |
@@ -3316,10 +3250,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3316 | ~CyDTR); | 3250 | ~CyDTR); |
3317 | } | 3251 | } |
3318 | #ifdef CY_DEBUG_DTR | 3252 | #ifdef CY_DEBUG_DTR |
3319 | printk("cyc:set_line_char dropping DTR\n"); | 3253 | printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n"); |
3320 | printk(" status: 0x%x, 0x%x\n", | 3254 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3321 | cy_readb(base_addr + (CyMSVR1 << index)), | 3255 | readb(base_addr + (CyMSVR1 << index)), |
3322 | cy_readb(base_addr + (CyMSVR2 << index))); | 3256 | readb(base_addr + (CyMSVR2 << index))); |
3323 | #endif | 3257 | #endif |
3324 | } else { | 3258 | } else { |
3325 | if (info->rtsdtr_inv) { | 3259 | if (info->rtsdtr_inv) { |
@@ -3330,17 +3264,17 @@ static void set_line_char(struct cyclades_port *info) | |||
3330 | CyDTR); | 3264 | CyDTR); |
3331 | } | 3265 | } |
3332 | #ifdef CY_DEBUG_DTR | 3266 | #ifdef CY_DEBUG_DTR |
3333 | printk("cyc:set_line_char raising DTR\n"); | 3267 | printk(KERN_DEBUG "cyc:set_line_char raising DTR\n"); |
3334 | printk(" status: 0x%x, 0x%x\n", | 3268 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3335 | cy_readb(base_addr + (CyMSVR1 << index)), | 3269 | readb(base_addr + (CyMSVR1 << index)), |
3336 | cy_readb(base_addr + (CyMSVR2 << index))); | 3270 | readb(base_addr + (CyMSVR2 << index))); |
3337 | #endif | 3271 | #endif |
3338 | } | 3272 | } |
3339 | 3273 | ||
3340 | if (info->tty) { | 3274 | if (info->tty) { |
3341 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 3275 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3342 | } | 3276 | } |
3343 | CY_UNLOCK(info, flags); | 3277 | spin_unlock_irqrestore(&card->card_lock, flags); |
3344 | 3278 | ||
3345 | } else { | 3279 | } else { |
3346 | struct FIRM_ID __iomem *firm_id; | 3280 | struct FIRM_ID __iomem *firm_id; |
@@ -3348,16 +3282,16 @@ static void set_line_char(struct cyclades_port *info) | |||
3348 | struct BOARD_CTRL __iomem *board_ctrl; | 3282 | struct BOARD_CTRL __iomem *board_ctrl; |
3349 | struct CH_CTRL __iomem *ch_ctrl; | 3283 | struct CH_CTRL __iomem *ch_ctrl; |
3350 | struct BUF_CTRL __iomem *buf_ctrl; | 3284 | struct BUF_CTRL __iomem *buf_ctrl; |
3351 | uclong sw_flow; | 3285 | __u32 sw_flow; |
3352 | int retval; | 3286 | int retval; |
3353 | 3287 | ||
3354 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3288 | firm_id = card->base_addr + ID_ADDRESS; |
3355 | if (!ISZLOADED(cy_card[card])) { | 3289 | if (!ISZLOADED(*card)) { |
3356 | return; | 3290 | return; |
3357 | } | 3291 | } |
3358 | 3292 | ||
3359 | zfw_ctrl = cy_card[card].base_addr + | 3293 | zfw_ctrl = card->base_addr + |
3360 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3294 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3361 | board_ctrl = &zfw_ctrl->board_ctrl; | 3295 | board_ctrl = &zfw_ctrl->board_ctrl; |
3362 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 3296 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
3363 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; | 3297 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; |
@@ -3408,10 +3342,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3408 | } | 3342 | } |
3409 | if (cflag & CSTOPB) { | 3343 | if (cflag & CSTOPB) { |
3410 | cy_writel(&ch_ctrl->comm_data_l, | 3344 | cy_writel(&ch_ctrl->comm_data_l, |
3411 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); | 3345 | readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); |
3412 | } else { | 3346 | } else { |
3413 | cy_writel(&ch_ctrl->comm_data_l, | 3347 | cy_writel(&ch_ctrl->comm_data_l, |
3414 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); | 3348 | readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); |
3415 | } | 3349 | } |
3416 | if (cflag & PARENB) { | 3350 | if (cflag & PARENB) { |
3417 | if (cflag & PARODD) { | 3351 | if (cflag & PARODD) { |
@@ -3426,12 +3360,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3426 | /* CTS flow control flag */ | 3360 | /* CTS flow control flag */ |
3427 | if (cflag & CRTSCTS) { | 3361 | if (cflag & CRTSCTS) { |
3428 | cy_writel(&ch_ctrl->hw_flow, | 3362 | cy_writel(&ch_ctrl->hw_flow, |
3429 | cy_readl(&ch_ctrl-> | 3363 | readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); |
3430 | hw_flow) | C_RS_CTS | C_RS_RTS); | ||
3431 | } else { | 3364 | } else { |
3432 | cy_writel(&ch_ctrl->hw_flow, | 3365 | cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) & |
3433 | cy_readl(&ch_ctrl-> | 3366 | ~(C_RS_CTS | C_RS_RTS)); |
3434 | hw_flow) & ~(C_RS_CTS | C_RS_RTS)); | ||
3435 | } | 3367 | } |
3436 | /* As the HW flow control is done in firmware, the driver | 3368 | /* As the HW flow control is done in firmware, the driver |
3437 | doesn't need to care about it */ | 3369 | doesn't need to care about it */ |
@@ -3446,10 +3378,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3446 | } | 3378 | } |
3447 | cy_writel(&ch_ctrl->sw_flow, sw_flow); | 3379 | cy_writel(&ch_ctrl->sw_flow, sw_flow); |
3448 | 3380 | ||
3449 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 3381 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); |
3450 | if (retval != 0) { | 3382 | if (retval != 0) { |
3451 | printk("cyc:set_line_char retval on ttyC%d was %x\n", | 3383 | printk(KERN_ERR "cyc:set_line_char retval on ttyC%d " |
3452 | info->line, retval); | 3384 | "was %x\n", info->line, retval); |
3453 | } | 3385 | } |
3454 | 3386 | ||
3455 | /* CD sensitivity */ | 3387 | /* CD sensitivity */ |
@@ -3461,22 +3393,22 @@ static void set_line_char(struct cyclades_port *info) | |||
3461 | 3393 | ||
3462 | if (baud == 0) { /* baud rate is zero, turn off line */ | 3394 | if (baud == 0) { /* baud rate is zero, turn off line */ |
3463 | cy_writel(&ch_ctrl->rs_control, | 3395 | cy_writel(&ch_ctrl->rs_control, |
3464 | cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); | 3396 | readl(&ch_ctrl->rs_control) & ~C_RS_DTR); |
3465 | #ifdef CY_DEBUG_DTR | 3397 | #ifdef CY_DEBUG_DTR |
3466 | printk("cyc:set_line_char dropping Z DTR\n"); | 3398 | printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n"); |
3467 | #endif | 3399 | #endif |
3468 | } else { | 3400 | } else { |
3469 | cy_writel(&ch_ctrl->rs_control, | 3401 | cy_writel(&ch_ctrl->rs_control, |
3470 | cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); | 3402 | readl(&ch_ctrl->rs_control) | C_RS_DTR); |
3471 | #ifdef CY_DEBUG_DTR | 3403 | #ifdef CY_DEBUG_DTR |
3472 | printk("cyc:set_line_char raising Z DTR\n"); | 3404 | printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n"); |
3473 | #endif | 3405 | #endif |
3474 | } | 3406 | } |
3475 | 3407 | ||
3476 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L); | 3408 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L); |
3477 | if (retval != 0) { | 3409 | if (retval != 0) { |
3478 | printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", | 3410 | printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " |
3479 | info->line, retval); | 3411 | "was %x\n", info->line, retval); |
3480 | } | 3412 | } |
3481 | 3413 | ||
3482 | if (info->tty) { | 3414 | if (info->tty) { |
@@ -3490,14 +3422,15 @@ get_serial_info(struct cyclades_port *info, | |||
3490 | struct serial_struct __user * retinfo) | 3422 | struct serial_struct __user * retinfo) |
3491 | { | 3423 | { |
3492 | struct serial_struct tmp; | 3424 | struct serial_struct tmp; |
3493 | struct cyclades_card *cinfo = &cy_card[info->card]; | 3425 | struct cyclades_card *cinfo = info->card; |
3494 | 3426 | ||
3495 | if (!retinfo) | 3427 | if (!retinfo) |
3496 | return -EFAULT; | 3428 | return -EFAULT; |
3497 | memset(&tmp, 0, sizeof(tmp)); | 3429 | memset(&tmp, 0, sizeof(tmp)); |
3498 | tmp.type = info->type; | 3430 | tmp.type = info->type; |
3499 | tmp.line = info->line; | 3431 | tmp.line = info->line; |
3500 | tmp.port = info->card * 0x100 + info->line - cinfo->first_line; | 3432 | tmp.port = (info->card - cy_card) * 0x100 + info->line - |
3433 | cinfo->first_line; | ||
3501 | tmp.irq = cinfo->irq; | 3434 | tmp.irq = cinfo->irq; |
3502 | tmp.flags = info->flags; | 3435 | tmp.flags = info->flags; |
3503 | tmp.close_delay = info->close_delay; | 3436 | tmp.close_delay = info->close_delay; |
@@ -3566,25 +3499,25 @@ check_and_exit: | |||
3566 | */ | 3499 | */ |
3567 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) | 3500 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) |
3568 | { | 3501 | { |
3569 | int card, chip, channel, index; | 3502 | struct cyclades_card *card; |
3503 | int chip, channel, index; | ||
3570 | unsigned char status; | 3504 | unsigned char status; |
3571 | unsigned int result; | 3505 | unsigned int result; |
3572 | unsigned long flags; | 3506 | unsigned long flags; |
3573 | void __iomem *base_addr; | 3507 | void __iomem *base_addr; |
3574 | 3508 | ||
3575 | card = info->card; | 3509 | card = info->card; |
3576 | channel = (info->line) - (cy_card[card].first_line); | 3510 | channel = (info->line) - (card->first_line); |
3577 | if (!IS_CYC_Z(cy_card[card])) { | 3511 | if (!IS_CYC_Z(*card)) { |
3578 | chip = channel >> 2; | 3512 | chip = channel >> 2; |
3579 | channel &= 0x03; | 3513 | channel &= 0x03; |
3580 | index = cy_card[card].bus_index; | 3514 | index = card->bus_index; |
3581 | base_addr = | 3515 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3582 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3583 | 3516 | ||
3584 | CY_LOCK(info, flags); | 3517 | spin_lock_irqsave(&card->card_lock, flags); |
3585 | status = cy_readb(base_addr + (CySRER << index)) & | 3518 | status = readb(base_addr + (CySRER << index)) & |
3586 | (CyTxRdy | CyTxMpty); | 3519 | (CyTxRdy | CyTxMpty); |
3587 | CY_UNLOCK(info, flags); | 3520 | spin_unlock_irqrestore(&card->card_lock, flags); |
3588 | result = (status ? 0 : TIOCSER_TEMT); | 3521 | result = (status ? 0 : TIOCSER_TEMT); |
3589 | } else { | 3522 | } else { |
3590 | /* Not supported yet */ | 3523 | /* Not supported yet */ |
@@ -3595,8 +3528,9 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) | |||
3595 | 3528 | ||
3596 | static int cy_tiocmget(struct tty_struct *tty, struct file *file) | 3529 | static int cy_tiocmget(struct tty_struct *tty, struct file *file) |
3597 | { | 3530 | { |
3598 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3531 | struct cyclades_port *info = tty->driver_data; |
3599 | int card, chip, channel, index; | 3532 | struct cyclades_card *card; |
3533 | int chip, channel, index; | ||
3600 | void __iomem *base_addr; | 3534 | void __iomem *base_addr; |
3601 | unsigned long flags; | 3535 | unsigned long flags; |
3602 | unsigned char status; | 3536 | unsigned char status; |
@@ -3611,19 +3545,18 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3611 | return -ENODEV; | 3545 | return -ENODEV; |
3612 | 3546 | ||
3613 | card = info->card; | 3547 | card = info->card; |
3614 | channel = (info->line) - (cy_card[card].first_line); | 3548 | channel = info->line - card->first_line; |
3615 | if (!IS_CYC_Z(cy_card[card])) { | 3549 | if (!IS_CYC_Z(*card)) { |
3616 | chip = channel >> 2; | 3550 | chip = channel >> 2; |
3617 | channel &= 0x03; | 3551 | channel &= 0x03; |
3618 | index = cy_card[card].bus_index; | 3552 | index = card->bus_index; |
3619 | base_addr = | 3553 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3620 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3621 | 3554 | ||
3622 | CY_LOCK(info, flags); | 3555 | spin_lock_irqsave(&card->card_lock, flags); |
3623 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 3556 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3624 | status = cy_readb(base_addr + (CyMSVR1 << index)); | 3557 | status = readb(base_addr + (CyMSVR1 << index)); |
3625 | status |= cy_readb(base_addr + (CyMSVR2 << index)); | 3558 | status |= readb(base_addr + (CyMSVR2 << index)); |
3626 | CY_UNLOCK(info, flags); | 3559 | spin_unlock_irqrestore(&card->card_lock, flags); |
3627 | 3560 | ||
3628 | if (info->rtsdtr_inv) { | 3561 | if (info->rtsdtr_inv) { |
3629 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | | 3562 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | |
@@ -3637,19 +3570,14 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3637 | ((status & CyDSR) ? TIOCM_DSR : 0) | | 3570 | ((status & CyDSR) ? TIOCM_DSR : 0) | |
3638 | ((status & CyCTS) ? TIOCM_CTS : 0); | 3571 | ((status & CyCTS) ? TIOCM_CTS : 0); |
3639 | } else { | 3572 | } else { |
3640 | base_addr = cy_card[card].base_addr; | 3573 | base_addr = card->base_addr; |
3641 | 3574 | firm_id = card->base_addr + ID_ADDRESS; | |
3642 | if (cy_card[card].num_chips != -1) { | 3575 | if (ISZLOADED(*card)) { |
3643 | return -EINVAL; | 3576 | zfw_ctrl = card->base_addr + |
3644 | } | 3577 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3645 | |||
3646 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | ||
3647 | if (ISZLOADED(cy_card[card])) { | ||
3648 | zfw_ctrl = cy_card[card].base_addr + | ||
3649 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
3650 | board_ctrl = &zfw_ctrl->board_ctrl; | 3578 | board_ctrl = &zfw_ctrl->board_ctrl; |
3651 | ch_ctrl = zfw_ctrl->ch_ctrl; | 3579 | ch_ctrl = zfw_ctrl->ch_ctrl; |
3652 | lstatus = cy_readl(&ch_ctrl[channel].rs_status); | 3580 | lstatus = readl(&ch_ctrl[channel].rs_status); |
3653 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | | 3581 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | |
3654 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | | 3582 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | |
3655 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | | 3583 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | |
@@ -3669,8 +3597,9 @@ static int | |||
3669 | cy_tiocmset(struct tty_struct *tty, struct file *file, | 3597 | cy_tiocmset(struct tty_struct *tty, struct file *file, |
3670 | unsigned int set, unsigned int clear) | 3598 | unsigned int set, unsigned int clear) |
3671 | { | 3599 | { |
3672 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3600 | struct cyclades_port *info = tty->driver_data; |
3673 | int card, chip, channel, index; | 3601 | struct cyclades_card *card; |
3602 | int chip, channel, index; | ||
3674 | void __iomem *base_addr; | 3603 | void __iomem *base_addr; |
3675 | unsigned long flags; | 3604 | unsigned long flags; |
3676 | struct FIRM_ID __iomem *firm_id; | 3605 | struct FIRM_ID __iomem *firm_id; |
@@ -3683,16 +3612,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3683 | return -ENODEV; | 3612 | return -ENODEV; |
3684 | 3613 | ||
3685 | card = info->card; | 3614 | card = info->card; |
3686 | channel = (info->line) - (cy_card[card].first_line); | 3615 | channel = (info->line) - (card->first_line); |
3687 | if (!IS_CYC_Z(cy_card[card])) { | 3616 | if (!IS_CYC_Z(*card)) { |
3688 | chip = channel >> 2; | 3617 | chip = channel >> 2; |
3689 | channel &= 0x03; | 3618 | channel &= 0x03; |
3690 | index = cy_card[card].bus_index; | 3619 | index = card->bus_index; |
3691 | base_addr = | 3620 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3692 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3693 | 3621 | ||
3694 | if (set & TIOCM_RTS) { | 3622 | if (set & TIOCM_RTS) { |
3695 | CY_LOCK(info, flags); | 3623 | spin_lock_irqsave(&card->card_lock, flags); |
3696 | cy_writeb(base_addr + (CyCAR << index), | 3624 | cy_writeb(base_addr + (CyCAR << index), |
3697 | (u_char) channel); | 3625 | (u_char) channel); |
3698 | if (info->rtsdtr_inv) { | 3626 | if (info->rtsdtr_inv) { |
@@ -3702,10 +3630,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3702 | cy_writeb(base_addr + (CyMSVR1 << index), | 3630 | cy_writeb(base_addr + (CyMSVR1 << index), |
3703 | CyRTS); | 3631 | CyRTS); |
3704 | } | 3632 | } |
3705 | CY_UNLOCK(info, flags); | 3633 | spin_unlock_irqrestore(&card->card_lock, flags); |
3706 | } | 3634 | } |
3707 | if (clear & TIOCM_RTS) { | 3635 | if (clear & TIOCM_RTS) { |
3708 | CY_LOCK(info, flags); | 3636 | spin_lock_irqsave(&card->card_lock, flags); |
3709 | cy_writeb(base_addr + (CyCAR << index), | 3637 | cy_writeb(base_addr + (CyCAR << index), |
3710 | (u_char) channel); | 3638 | (u_char) channel); |
3711 | if (info->rtsdtr_inv) { | 3639 | if (info->rtsdtr_inv) { |
@@ -3715,10 +3643,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3715 | cy_writeb(base_addr + (CyMSVR1 << index), | 3643 | cy_writeb(base_addr + (CyMSVR1 << index), |
3716 | ~CyRTS); | 3644 | ~CyRTS); |
3717 | } | 3645 | } |
3718 | CY_UNLOCK(info, flags); | 3646 | spin_unlock_irqrestore(&card->card_lock, flags); |
3719 | } | 3647 | } |
3720 | if (set & TIOCM_DTR) { | 3648 | if (set & TIOCM_DTR) { |
3721 | CY_LOCK(info, flags); | 3649 | spin_lock_irqsave(&card->card_lock, flags); |
3722 | cy_writeb(base_addr + (CyCAR << index), | 3650 | cy_writeb(base_addr + (CyCAR << index), |
3723 | (u_char) channel); | 3651 | (u_char) channel); |
3724 | if (info->rtsdtr_inv) { | 3652 | if (info->rtsdtr_inv) { |
@@ -3729,15 +3657,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3729 | CyDTR); | 3657 | CyDTR); |
3730 | } | 3658 | } |
3731 | #ifdef CY_DEBUG_DTR | 3659 | #ifdef CY_DEBUG_DTR |
3732 | printk("cyc:set_modem_info raising DTR\n"); | 3660 | printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); |
3733 | printk(" status: 0x%x, 0x%x\n", | 3661 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3734 | cy_readb(base_addr + (CyMSVR1 << index)), | 3662 | readb(base_addr + (CyMSVR1 << index)), |
3735 | cy_readb(base_addr + (CyMSVR2 << index))); | 3663 | readb(base_addr + (CyMSVR2 << index))); |
3736 | #endif | 3664 | #endif |
3737 | CY_UNLOCK(info, flags); | 3665 | spin_unlock_irqrestore(&card->card_lock, flags); |
3738 | } | 3666 | } |
3739 | if (clear & TIOCM_DTR) { | 3667 | if (clear & TIOCM_DTR) { |
3740 | CY_LOCK(info, flags); | 3668 | spin_lock_irqsave(&card->card_lock, flags); |
3741 | cy_writeb(base_addr + (CyCAR << index), | 3669 | cy_writeb(base_addr + (CyCAR << index), |
3742 | (u_char) channel); | 3670 | (u_char) channel); |
3743 | if (info->rtsdtr_inv) { | 3671 | if (info->rtsdtr_inv) { |
@@ -3749,68 +3677,69 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3749 | } | 3677 | } |
3750 | 3678 | ||
3751 | #ifdef CY_DEBUG_DTR | 3679 | #ifdef CY_DEBUG_DTR |
3752 | printk("cyc:set_modem_info dropping DTR\n"); | 3680 | printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); |
3753 | printk(" status: 0x%x, 0x%x\n", | 3681 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3754 | cy_readb(base_addr + (CyMSVR1 << index)), | 3682 | readb(base_addr + (CyMSVR1 << index)), |
3755 | cy_readb(base_addr + (CyMSVR2 << index))); | 3683 | readb(base_addr + (CyMSVR2 << index))); |
3756 | #endif | 3684 | #endif |
3757 | CY_UNLOCK(info, flags); | 3685 | spin_unlock_irqrestore(&card->card_lock, flags); |
3758 | } | 3686 | } |
3759 | } else { | 3687 | } else { |
3760 | base_addr = cy_card[card].base_addr; | 3688 | base_addr = card->base_addr; |
3761 | 3689 | ||
3762 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3690 | firm_id = card->base_addr + ID_ADDRESS; |
3763 | if (ISZLOADED(cy_card[card])) { | 3691 | if (ISZLOADED(*card)) { |
3764 | zfw_ctrl = cy_card[card].base_addr + | 3692 | zfw_ctrl = card->base_addr + |
3765 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3693 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3766 | board_ctrl = &zfw_ctrl->board_ctrl; | 3694 | board_ctrl = &zfw_ctrl->board_ctrl; |
3767 | ch_ctrl = zfw_ctrl->ch_ctrl; | 3695 | ch_ctrl = zfw_ctrl->ch_ctrl; |
3768 | 3696 | ||
3769 | if (set & TIOCM_RTS) { | 3697 | if (set & TIOCM_RTS) { |
3770 | CY_LOCK(info, flags); | 3698 | spin_lock_irqsave(&card->card_lock, flags); |
3771 | cy_writel(&ch_ctrl[channel].rs_control, | 3699 | cy_writel(&ch_ctrl[channel].rs_control, |
3772 | cy_readl(&ch_ctrl[channel]. | 3700 | readl(&ch_ctrl[channel].rs_control) | |
3773 | rs_control) | C_RS_RTS); | 3701 | C_RS_RTS); |
3774 | CY_UNLOCK(info, flags); | 3702 | spin_unlock_irqrestore(&card->card_lock, flags); |
3775 | } | 3703 | } |
3776 | if (clear & TIOCM_RTS) { | 3704 | if (clear & TIOCM_RTS) { |
3777 | CY_LOCK(info, flags); | 3705 | spin_lock_irqsave(&card->card_lock, flags); |
3778 | cy_writel(&ch_ctrl[channel].rs_control, | 3706 | cy_writel(&ch_ctrl[channel].rs_control, |
3779 | cy_readl(&ch_ctrl[channel]. | 3707 | readl(&ch_ctrl[channel].rs_control) & |
3780 | rs_control) & ~C_RS_RTS); | 3708 | ~C_RS_RTS); |
3781 | CY_UNLOCK(info, flags); | 3709 | spin_unlock_irqrestore(&card->card_lock, flags); |
3782 | } | 3710 | } |
3783 | if (set & TIOCM_DTR) { | 3711 | if (set & TIOCM_DTR) { |
3784 | CY_LOCK(info, flags); | 3712 | spin_lock_irqsave(&card->card_lock, flags); |
3785 | cy_writel(&ch_ctrl[channel].rs_control, | 3713 | cy_writel(&ch_ctrl[channel].rs_control, |
3786 | cy_readl(&ch_ctrl[channel]. | 3714 | readl(&ch_ctrl[channel].rs_control) | |
3787 | rs_control) | C_RS_DTR); | 3715 | C_RS_DTR); |
3788 | #ifdef CY_DEBUG_DTR | 3716 | #ifdef CY_DEBUG_DTR |
3789 | printk("cyc:set_modem_info raising Z DTR\n"); | 3717 | printk(KERN_DEBUG "cyc:set_modem_info raising " |
3718 | "Z DTR\n"); | ||
3790 | #endif | 3719 | #endif |
3791 | CY_UNLOCK(info, flags); | 3720 | spin_unlock_irqrestore(&card->card_lock, flags); |
3792 | } | 3721 | } |
3793 | if (clear & TIOCM_DTR) { | 3722 | if (clear & TIOCM_DTR) { |
3794 | CY_LOCK(info, flags); | 3723 | spin_lock_irqsave(&card->card_lock, flags); |
3795 | cy_writel(&ch_ctrl[channel].rs_control, | 3724 | cy_writel(&ch_ctrl[channel].rs_control, |
3796 | cy_readl(&ch_ctrl[channel]. | 3725 | readl(&ch_ctrl[channel].rs_control) & |
3797 | rs_control) & ~C_RS_DTR); | 3726 | ~C_RS_DTR); |
3798 | #ifdef CY_DEBUG_DTR | 3727 | #ifdef CY_DEBUG_DTR |
3799 | printk("cyc:set_modem_info clearing Z DTR\n"); | 3728 | printk(KERN_DEBUG "cyc:set_modem_info clearing " |
3729 | "Z DTR\n"); | ||
3800 | #endif | 3730 | #endif |
3801 | CY_UNLOCK(info, flags); | 3731 | spin_unlock_irqrestore(&card->card_lock, flags); |
3802 | } | 3732 | } |
3803 | } else { | 3733 | } else { |
3804 | return -ENODEV; | 3734 | return -ENODEV; |
3805 | } | 3735 | } |
3806 | CY_LOCK(info, flags); | 3736 | spin_lock_irqsave(&card->card_lock, flags); |
3807 | retval = cyz_issue_cmd(&cy_card[info->card], | 3737 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); |
3808 | channel, C_CM_IOCTLM, 0L); | ||
3809 | if (retval != 0) { | 3738 | if (retval != 0) { |
3810 | printk("cyc:set_modem_info retval on ttyC%d was %x\n", | 3739 | printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " |
3811 | info->line, retval); | 3740 | "was %x\n", info->line, retval); |
3812 | } | 3741 | } |
3813 | CY_UNLOCK(info, flags); | 3742 | spin_unlock_irqrestore(&card->card_lock, flags); |
3814 | } | 3743 | } |
3815 | return 0; | 3744 | return 0; |
3816 | } /* cy_tiocmset */ | 3745 | } /* cy_tiocmset */ |
@@ -3820,14 +3749,17 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3820 | */ | 3749 | */ |
3821 | static void cy_break(struct tty_struct *tty, int break_state) | 3750 | static void cy_break(struct tty_struct *tty, int break_state) |
3822 | { | 3751 | { |
3823 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3752 | struct cyclades_port *info = tty->driver_data; |
3753 | struct cyclades_card *card; | ||
3824 | unsigned long flags; | 3754 | unsigned long flags; |
3825 | 3755 | ||
3826 | if (serial_paranoia_check(info, tty->name, "cy_break")) | 3756 | if (serial_paranoia_check(info, tty->name, "cy_break")) |
3827 | return; | 3757 | return; |
3828 | 3758 | ||
3829 | CY_LOCK(info, flags); | 3759 | card = info->card; |
3830 | if (!IS_CYC_Z(cy_card[info->card])) { | 3760 | |
3761 | spin_lock_irqsave(&card->card_lock, flags); | ||
3762 | if (!IS_CYC_Z(*card)) { | ||
3831 | /* Let the transmit ISR take care of this (since it | 3763 | /* Let the transmit ISR take care of this (since it |
3832 | requires stuffing characters into the output stream). | 3764 | requires stuffing characters into the output stream). |
3833 | */ | 3765 | */ |
@@ -3835,18 +3767,18 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3835 | if (!info->breakon) { | 3767 | if (!info->breakon) { |
3836 | info->breakon = 1; | 3768 | info->breakon = 1; |
3837 | if (!info->xmit_cnt) { | 3769 | if (!info->xmit_cnt) { |
3838 | CY_UNLOCK(info, flags); | 3770 | spin_unlock_irqrestore(&card->card_lock, flags); |
3839 | start_xmit(info); | 3771 | start_xmit(info); |
3840 | CY_LOCK(info, flags); | 3772 | spin_lock_irqsave(&card->card_lock, flags); |
3841 | } | 3773 | } |
3842 | } | 3774 | } |
3843 | } else { | 3775 | } else { |
3844 | if (!info->breakoff) { | 3776 | if (!info->breakoff) { |
3845 | info->breakoff = 1; | 3777 | info->breakoff = 1; |
3846 | if (!info->xmit_cnt) { | 3778 | if (!info->xmit_cnt) { |
3847 | CY_UNLOCK(info, flags); | 3779 | spin_unlock_irqrestore(&card->card_lock, flags); |
3848 | start_xmit(info); | 3780 | start_xmit(info); |
3849 | CY_LOCK(info, flags); | 3781 | spin_lock_irqsave(&card->card_lock, flags); |
3850 | } | 3782 | } |
3851 | } | 3783 | } |
3852 | } | 3784 | } |
@@ -3854,24 +3786,25 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3854 | int retval; | 3786 | int retval; |
3855 | 3787 | ||
3856 | if (break_state == -1) { | 3788 | if (break_state == -1) { |
3857 | retval = cyz_issue_cmd(&cy_card[info->card], | 3789 | retval = cyz_issue_cmd(card, |
3858 | info->line - cy_card[info->card].first_line, | 3790 | info->line - card->first_line, |
3859 | C_CM_SET_BREAK, 0L); | 3791 | C_CM_SET_BREAK, 0L); |
3860 | if (retval != 0) { | 3792 | if (retval != 0) { |
3861 | printk("cyc:cy_break (set) retval on ttyC%d " | 3793 | printk(KERN_ERR "cyc:cy_break (set) retval on " |
3862 | "was %x\n", info->line, retval); | 3794 | "ttyC%d was %x\n", info->line, retval); |
3863 | } | 3795 | } |
3864 | } else { | 3796 | } else { |
3865 | retval = cyz_issue_cmd(&cy_card[info->card], | 3797 | retval = cyz_issue_cmd(card, |
3866 | info->line - cy_card[info->card].first_line, | 3798 | info->line - card->first_line, |
3867 | C_CM_CLR_BREAK, 0L); | 3799 | C_CM_CLR_BREAK, 0L); |
3868 | if (retval != 0) { | 3800 | if (retval != 0) { |
3869 | printk("cyc:cy_break (clr) retval on ttyC%d " | 3801 | printk(KERN_DEBUG "cyc:cy_break (clr) retval " |
3870 | "was %x\n", info->line, retval); | 3802 | "on ttyC%d was %x\n", info->line, |
3803 | retval); | ||
3871 | } | 3804 | } |
3872 | } | 3805 | } |
3873 | } | 3806 | } |
3874 | CY_UNLOCK(info, flags); | 3807 | spin_unlock_irqrestore(&card->card_lock, flags); |
3875 | } /* cy_break */ | 3808 | } /* cy_break */ |
3876 | 3809 | ||
3877 | static int | 3810 | static int |
@@ -3889,28 +3822,27 @@ get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) | |||
3889 | 3822 | ||
3890 | static int set_threshold(struct cyclades_port *info, unsigned long value) | 3823 | static int set_threshold(struct cyclades_port *info, unsigned long value) |
3891 | { | 3824 | { |
3825 | struct cyclades_card *card; | ||
3892 | void __iomem *base_addr; | 3826 | void __iomem *base_addr; |
3893 | int card, channel, chip, index; | 3827 | int channel, chip, index; |
3894 | unsigned long flags; | 3828 | unsigned long flags; |
3895 | 3829 | ||
3896 | card = info->card; | 3830 | card = info->card; |
3897 | channel = info->line - cy_card[card].first_line; | 3831 | channel = info->line - card->first_line; |
3898 | if (!IS_CYC_Z(cy_card[card])) { | 3832 | if (!IS_CYC_Z(*card)) { |
3899 | chip = channel >> 2; | 3833 | chip = channel >> 2; |
3900 | channel &= 0x03; | 3834 | channel &= 0x03; |
3901 | index = cy_card[card].bus_index; | 3835 | index = card->bus_index; |
3902 | base_addr = | 3836 | base_addr = |
3903 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | 3837 | card->base_addr + (cy_chip_offset[chip] << index); |
3904 | 3838 | ||
3905 | info->cor3 &= ~CyREC_FIFO; | 3839 | info->cor3 &= ~CyREC_FIFO; |
3906 | info->cor3 |= value & CyREC_FIFO; | 3840 | info->cor3 |= value & CyREC_FIFO; |
3907 | 3841 | ||
3908 | CY_LOCK(info, flags); | 3842 | spin_lock_irqsave(&card->card_lock, flags); |
3909 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); | 3843 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); |
3910 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); | 3844 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); |
3911 | CY_UNLOCK(info, flags); | 3845 | spin_unlock_irqrestore(&card->card_lock, flags); |
3912 | } else { | ||
3913 | /* Nothing to do! */ | ||
3914 | } | 3846 | } |
3915 | return 0; | 3847 | return 0; |
3916 | } /* set_threshold */ | 3848 | } /* set_threshold */ |
@@ -3918,25 +3850,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value) | |||
3918 | static int | 3850 | static int |
3919 | get_threshold(struct cyclades_port *info, unsigned long __user * value) | 3851 | get_threshold(struct cyclades_port *info, unsigned long __user * value) |
3920 | { | 3852 | { |
3853 | struct cyclades_card *card; | ||
3921 | void __iomem *base_addr; | 3854 | void __iomem *base_addr; |
3922 | int card, channel, chip, index; | 3855 | int channel, chip, index; |
3923 | unsigned long tmp; | 3856 | unsigned long tmp; |
3924 | 3857 | ||
3925 | card = info->card; | 3858 | card = info->card; |
3926 | channel = info->line - cy_card[card].first_line; | 3859 | channel = info->line - card->first_line; |
3927 | if (!IS_CYC_Z(cy_card[card])) { | 3860 | if (!IS_CYC_Z(*card)) { |
3928 | chip = channel >> 2; | 3861 | chip = channel >> 2; |
3929 | channel &= 0x03; | 3862 | channel &= 0x03; |
3930 | index = cy_card[card].bus_index; | 3863 | index = card->bus_index; |
3931 | base_addr = | 3864 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3932 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3933 | 3865 | ||
3934 | tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; | 3866 | tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; |
3935 | return put_user(tmp, value); | 3867 | return put_user(tmp, value); |
3936 | } else { | ||
3937 | /* Nothing to do! */ | ||
3938 | return 0; | ||
3939 | } | 3868 | } |
3869 | return 0; | ||
3940 | } /* get_threshold */ | 3870 | } /* get_threshold */ |
3941 | 3871 | ||
3942 | static int | 3872 | static int |
@@ -3954,49 +3884,45 @@ get_default_threshold(struct cyclades_port *info, unsigned long __user * value) | |||
3954 | 3884 | ||
3955 | static int set_timeout(struct cyclades_port *info, unsigned long value) | 3885 | static int set_timeout(struct cyclades_port *info, unsigned long value) |
3956 | { | 3886 | { |
3887 | struct cyclades_card *card; | ||
3957 | void __iomem *base_addr; | 3888 | void __iomem *base_addr; |
3958 | int card, channel, chip, index; | 3889 | int channel, chip, index; |
3959 | unsigned long flags; | 3890 | unsigned long flags; |
3960 | 3891 | ||
3961 | card = info->card; | 3892 | card = info->card; |
3962 | channel = info->line - cy_card[card].first_line; | 3893 | channel = info->line - card->first_line; |
3963 | if (!IS_CYC_Z(cy_card[card])) { | 3894 | if (!IS_CYC_Z(*card)) { |
3964 | chip = channel >> 2; | 3895 | chip = channel >> 2; |
3965 | channel &= 0x03; | 3896 | channel &= 0x03; |
3966 | index = cy_card[card].bus_index; | 3897 | index = card->bus_index; |
3967 | base_addr = | 3898 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3968 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3969 | 3899 | ||
3970 | CY_LOCK(info, flags); | 3900 | spin_lock_irqsave(&card->card_lock, flags); |
3971 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); | 3901 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); |
3972 | CY_UNLOCK(info, flags); | 3902 | spin_unlock_irqrestore(&card->card_lock, flags); |
3973 | } else { | ||
3974 | /* Nothing to do! */ | ||
3975 | } | 3903 | } |
3976 | return 0; | 3904 | return 0; |
3977 | } /* set_timeout */ | 3905 | } /* set_timeout */ |
3978 | 3906 | ||
3979 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) | 3907 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) |
3980 | { | 3908 | { |
3909 | struct cyclades_card *card; | ||
3981 | void __iomem *base_addr; | 3910 | void __iomem *base_addr; |
3982 | int card, channel, chip, index; | 3911 | int channel, chip, index; |
3983 | unsigned long tmp; | 3912 | unsigned long tmp; |
3984 | 3913 | ||
3985 | card = info->card; | 3914 | card = info->card; |
3986 | channel = info->line - cy_card[card].first_line; | 3915 | channel = info->line - card->first_line; |
3987 | if (!IS_CYC_Z(cy_card[card])) { | 3916 | if (!IS_CYC_Z(*card)) { |
3988 | chip = channel >> 2; | 3917 | chip = channel >> 2; |
3989 | channel &= 0x03; | 3918 | channel &= 0x03; |
3990 | index = cy_card[card].bus_index; | 3919 | index = card->bus_index; |
3991 | base_addr = | 3920 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3992 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3993 | 3921 | ||
3994 | tmp = cy_readb(base_addr + (CyRTPR << index)); | 3922 | tmp = readb(base_addr + (CyRTPR << index)); |
3995 | return put_user(tmp, value); | 3923 | return put_user(tmp, value); |
3996 | } else { | ||
3997 | /* Nothing to do! */ | ||
3998 | return 0; | ||
3999 | } | 3924 | } |
3925 | return 0; | ||
4000 | } /* get_timeout */ | 3926 | } /* get_timeout */ |
4001 | 3927 | ||
4002 | static int set_default_timeout(struct cyclades_port *info, unsigned long value) | 3928 | static int set_default_timeout(struct cyclades_port *info, unsigned long value) |
@@ -4020,7 +3946,7 @@ static int | |||
4020 | cy_ioctl(struct tty_struct *tty, struct file *file, | 3946 | cy_ioctl(struct tty_struct *tty, struct file *file, |
4021 | unsigned int cmd, unsigned long arg) | 3947 | unsigned int cmd, unsigned long arg) |
4022 | { | 3948 | { |
4023 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3949 | struct cyclades_port *info = tty->driver_data; |
4024 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ | 3950 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ |
4025 | struct serial_icounter_struct __user *p_cuser; /* user space */ | 3951 | struct serial_icounter_struct __user *p_cuser; /* user space */ |
4026 | int ret_val = 0; | 3952 | int ret_val = 0; |
@@ -4031,7 +3957,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4031 | return -ENODEV; | 3957 | return -ENODEV; |
4032 | 3958 | ||
4033 | #ifdef CY_DEBUG_OTHER | 3959 | #ifdef CY_DEBUG_OTHER |
4034 | printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */ | 3960 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", |
3961 | info->line, cmd, arg); | ||
4035 | #endif | 3962 | #endif |
4036 | 3963 | ||
4037 | switch (cmd) { | 3964 | switch (cmd) { |
@@ -4076,14 +4003,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4076 | case CYGETRTSDTR_INV: | 4003 | case CYGETRTSDTR_INV: |
4077 | ret_val = info->rtsdtr_inv; | 4004 | ret_val = info->rtsdtr_inv; |
4078 | break; | 4005 | break; |
4079 | case CYGETCARDINFO: | ||
4080 | if (copy_to_user(argp, &cy_card[info->card], | ||
4081 | sizeof(struct cyclades_card))) { | ||
4082 | ret_val = -EFAULT; | ||
4083 | break; | ||
4084 | } | ||
4085 | ret_val = 0; | ||
4086 | break; | ||
4087 | case CYGETCD1400VER: | 4006 | case CYGETCD1400VER: |
4088 | ret_val = info->chip_rev; | 4007 | ret_val = info->chip_rev; |
4089 | break; | 4008 | break; |
@@ -4119,34 +4038,22 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4119 | * Caller should use TIOCGICOUNT to see which one it was | 4038 | * Caller should use TIOCGICOUNT to see which one it was |
4120 | */ | 4039 | */ |
4121 | case TIOCMIWAIT: | 4040 | case TIOCMIWAIT: |
4122 | CY_LOCK(info, flags); | 4041 | spin_lock_irqsave(&info->card->card_lock, flags); |
4123 | /* note the counters on entry */ | 4042 | /* note the counters on entry */ |
4124 | cprev = info->icount; | 4043 | cnow = info->icount; |
4125 | CY_UNLOCK(info, flags); | 4044 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4126 | while (1) { | 4045 | ret_val = wait_event_interruptible(info->delta_msr_wait, ({ |
4127 | interruptible_sleep_on(&info->delta_msr_wait); | 4046 | cprev = cnow; |
4128 | /* see if a signal did it */ | 4047 | spin_lock_irqsave(&info->card->card_lock, flags); |
4129 | if (signal_pending(current)) { | ||
4130 | return -ERESTARTSYS; | ||
4131 | } | ||
4132 | |||
4133 | CY_LOCK(info, flags); | ||
4134 | cnow = info->icount; /* atomic copy */ | 4048 | cnow = info->icount; /* atomic copy */ |
4135 | CY_UNLOCK(info, flags); | 4049 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4136 | 4050 | ||
4137 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 4051 | ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || |
4138 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { | 4052 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || |
4139 | return -EIO; /* no change => error */ | 4053 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || |
4140 | } | 4054 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); |
4141 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | 4055 | })); |
4142 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | 4056 | break; |
4143 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
4144 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
4145 | return 0; | ||
4146 | } | ||
4147 | cprev = cnow; | ||
4148 | } | ||
4149 | /* NOTREACHED */ | ||
4150 | 4057 | ||
4151 | /* | 4058 | /* |
4152 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | 4059 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) |
@@ -4155,9 +4062,9 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4155 | * RI where only 0->1 is counted. | 4062 | * RI where only 0->1 is counted. |
4156 | */ | 4063 | */ |
4157 | case TIOCGICOUNT: | 4064 | case TIOCGICOUNT: |
4158 | CY_LOCK(info, flags); | 4065 | spin_lock_irqsave(&info->card->card_lock, flags); |
4159 | cnow = info->icount; | 4066 | cnow = info->icount; |
4160 | CY_UNLOCK(info, flags); | 4067 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4161 | p_cuser = argp; | 4068 | p_cuser = argp; |
4162 | ret_val = put_user(cnow.cts, &p_cuser->cts); | 4069 | ret_val = put_user(cnow.cts, &p_cuser->cts); |
4163 | if (ret_val) | 4070 | if (ret_val) |
@@ -4199,7 +4106,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4199 | } | 4106 | } |
4200 | 4107 | ||
4201 | #ifdef CY_DEBUG_OTHER | 4108 | #ifdef CY_DEBUG_OTHER |
4202 | printk(" cyc:cy_ioctl done\n"); | 4109 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); |
4203 | #endif | 4110 | #endif |
4204 | 4111 | ||
4205 | return ret_val; | 4112 | return ret_val; |
@@ -4213,10 +4120,10 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4213 | */ | 4120 | */ |
4214 | static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 4121 | static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
4215 | { | 4122 | { |
4216 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4123 | struct cyclades_port *info = tty->driver_data; |
4217 | 4124 | ||
4218 | #ifdef CY_DEBUG_OTHER | 4125 | #ifdef CY_DEBUG_OTHER |
4219 | printk("cyc:cy_set_termios ttyC%d\n", info->line); | 4126 | printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); |
4220 | #endif | 4127 | #endif |
4221 | 4128 | ||
4222 | if (tty->termios->c_cflag == old_termios->c_cflag && | 4129 | if (tty->termios->c_cflag == old_termios->c_cflag && |
@@ -4248,8 +4155,9 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
4248 | */ | 4155 | */ |
4249 | static void cy_send_xchar(struct tty_struct *tty, char ch) | 4156 | static void cy_send_xchar(struct tty_struct *tty, char ch) |
4250 | { | 4157 | { |
4251 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4158 | struct cyclades_port *info = tty->driver_data; |
4252 | int card, channel; | 4159 | struct cyclades_card *card; |
4160 | int channel; | ||
4253 | 4161 | ||
4254 | if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) | 4162 | if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) |
4255 | return; | 4163 | return; |
@@ -4260,15 +4168,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) | |||
4260 | cy_start(tty); | 4168 | cy_start(tty); |
4261 | 4169 | ||
4262 | card = info->card; | 4170 | card = info->card; |
4263 | channel = info->line - cy_card[card].first_line; | 4171 | channel = info->line - card->first_line; |
4264 | 4172 | ||
4265 | if (IS_CYC_Z(cy_card[card])) { | 4173 | if (IS_CYC_Z(*card)) { |
4266 | if (ch == STOP_CHAR(tty)) | 4174 | if (ch == STOP_CHAR(tty)) |
4267 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF, | 4175 | cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L); |
4268 | 0L); | ||
4269 | else if (ch == START_CHAR(tty)) | 4176 | else if (ch == START_CHAR(tty)) |
4270 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON, | 4177 | cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L); |
4271 | 0L); | ||
4272 | } | 4178 | } |
4273 | } | 4179 | } |
4274 | 4180 | ||
@@ -4278,15 +4184,16 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) | |||
4278 | */ | 4184 | */ |
4279 | static void cy_throttle(struct tty_struct *tty) | 4185 | static void cy_throttle(struct tty_struct *tty) |
4280 | { | 4186 | { |
4281 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4187 | struct cyclades_port *info = tty->driver_data; |
4188 | struct cyclades_card *card; | ||
4282 | unsigned long flags; | 4189 | unsigned long flags; |
4283 | void __iomem *base_addr; | 4190 | void __iomem *base_addr; |
4284 | int card, chip, channel, index; | 4191 | int chip, channel, index; |
4285 | 4192 | ||
4286 | #ifdef CY_DEBUG_THROTTLE | 4193 | #ifdef CY_DEBUG_THROTTLE |
4287 | char buf[64]; | 4194 | char buf[64]; |
4288 | 4195 | ||
4289 | printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf), | 4196 | printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), |
4290 | tty->ldisc.chars_in_buffer(tty), info->line); | 4197 | tty->ldisc.chars_in_buffer(tty), info->line); |
4291 | #endif | 4198 | #endif |
4292 | 4199 | ||
@@ -4297,22 +4204,22 @@ static void cy_throttle(struct tty_struct *tty) | |||
4297 | card = info->card; | 4204 | card = info->card; |
4298 | 4205 | ||
4299 | if (I_IXOFF(tty)) { | 4206 | if (I_IXOFF(tty)) { |
4300 | if (!IS_CYC_Z(cy_card[card])) | 4207 | if (!IS_CYC_Z(*card)) |
4301 | cy_send_xchar(tty, STOP_CHAR(tty)); | 4208 | cy_send_xchar(tty, STOP_CHAR(tty)); |
4302 | else | 4209 | else |
4303 | info->throttle = 1; | 4210 | info->throttle = 1; |
4304 | } | 4211 | } |
4305 | 4212 | ||
4306 | if (tty->termios->c_cflag & CRTSCTS) { | 4213 | if (tty->termios->c_cflag & CRTSCTS) { |
4307 | channel = info->line - cy_card[card].first_line; | 4214 | channel = info->line - card->first_line; |
4308 | if (!IS_CYC_Z(cy_card[card])) { | 4215 | if (!IS_CYC_Z(*card)) { |
4309 | chip = channel >> 2; | 4216 | chip = channel >> 2; |
4310 | channel &= 0x03; | 4217 | channel &= 0x03; |
4311 | index = cy_card[card].bus_index; | 4218 | index = card->bus_index; |
4312 | base_addr = cy_card[card].base_addr + | 4219 | base_addr = card->base_addr + |
4313 | (cy_chip_offset[chip] << index); | 4220 | (cy_chip_offset[chip] << index); |
4314 | 4221 | ||
4315 | CY_LOCK(info, flags); | 4222 | spin_lock_irqsave(&card->card_lock, flags); |
4316 | cy_writeb(base_addr + (CyCAR << index), | 4223 | cy_writeb(base_addr + (CyCAR << index), |
4317 | (u_char) channel); | 4224 | (u_char) channel); |
4318 | if (info->rtsdtr_inv) { | 4225 | if (info->rtsdtr_inv) { |
@@ -4322,7 +4229,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
4322 | cy_writeb(base_addr + (CyMSVR1 << index), | 4229 | cy_writeb(base_addr + (CyMSVR1 << index), |
4323 | ~CyRTS); | 4230 | ~CyRTS); |
4324 | } | 4231 | } |
4325 | CY_UNLOCK(info, flags); | 4232 | spin_unlock_irqrestore(&card->card_lock, flags); |
4326 | } else { | 4233 | } else { |
4327 | info->throttle = 1; | 4234 | info->throttle = 1; |
4328 | } | 4235 | } |
@@ -4336,16 +4243,17 @@ static void cy_throttle(struct tty_struct *tty) | |||
4336 | */ | 4243 | */ |
4337 | static void cy_unthrottle(struct tty_struct *tty) | 4244 | static void cy_unthrottle(struct tty_struct *tty) |
4338 | { | 4245 | { |
4339 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4246 | struct cyclades_port *info = tty->driver_data; |
4247 | struct cyclades_card *card; | ||
4340 | unsigned long flags; | 4248 | unsigned long flags; |
4341 | void __iomem *base_addr; | 4249 | void __iomem *base_addr; |
4342 | int card, chip, channel, index; | 4250 | int chip, channel, index; |
4343 | 4251 | ||
4344 | #ifdef CY_DEBUG_THROTTLE | 4252 | #ifdef CY_DEBUG_THROTTLE |
4345 | char buf[64]; | 4253 | char buf[64]; |
4346 | 4254 | ||
4347 | printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf), | 4255 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", |
4348 | tty->ldisc.chars_in_buffer(tty), info->line); | 4256 | tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line); |
4349 | #endif | 4257 | #endif |
4350 | 4258 | ||
4351 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { | 4259 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { |
@@ -4361,15 +4269,15 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4361 | 4269 | ||
4362 | if (tty->termios->c_cflag & CRTSCTS) { | 4270 | if (tty->termios->c_cflag & CRTSCTS) { |
4363 | card = info->card; | 4271 | card = info->card; |
4364 | channel = info->line - cy_card[card].first_line; | 4272 | channel = info->line - card->first_line; |
4365 | if (!IS_CYC_Z(cy_card[card])) { | 4273 | if (!IS_CYC_Z(*card)) { |
4366 | chip = channel >> 2; | 4274 | chip = channel >> 2; |
4367 | channel &= 0x03; | 4275 | channel &= 0x03; |
4368 | index = cy_card[card].bus_index; | 4276 | index = card->bus_index; |
4369 | base_addr = cy_card[card].base_addr + | 4277 | base_addr = card->base_addr + |
4370 | (cy_chip_offset[chip] << index); | 4278 | (cy_chip_offset[chip] << index); |
4371 | 4279 | ||
4372 | CY_LOCK(info, flags); | 4280 | spin_lock_irqsave(&card->card_lock, flags); |
4373 | cy_writeb(base_addr + (CyCAR << index), | 4281 | cy_writeb(base_addr + (CyCAR << index), |
4374 | (u_char) channel); | 4282 | (u_char) channel); |
4375 | if (info->rtsdtr_inv) { | 4283 | if (info->rtsdtr_inv) { |
@@ -4379,7 +4287,7 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4379 | cy_writeb(base_addr + (CyMSVR1 << index), | 4287 | cy_writeb(base_addr + (CyMSVR1 << index), |
4380 | CyRTS); | 4288 | CyRTS); |
4381 | } | 4289 | } |
4382 | CY_UNLOCK(info, flags); | 4290 | spin_unlock_irqrestore(&card->card_lock, flags); |
4383 | } else { | 4291 | } else { |
4384 | info->throttle = 0; | 4292 | info->throttle = 0; |
4385 | } | 4293 | } |
@@ -4392,102 +4300,96 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4392 | static void cy_stop(struct tty_struct *tty) | 4300 | static void cy_stop(struct tty_struct *tty) |
4393 | { | 4301 | { |
4394 | struct cyclades_card *cinfo; | 4302 | struct cyclades_card *cinfo; |
4395 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4303 | struct cyclades_port *info = tty->driver_data; |
4396 | void __iomem *base_addr; | 4304 | void __iomem *base_addr; |
4397 | int chip, channel, index; | 4305 | int chip, channel, index; |
4398 | unsigned long flags; | 4306 | unsigned long flags; |
4399 | 4307 | ||
4400 | #ifdef CY_DEBUG_OTHER | 4308 | #ifdef CY_DEBUG_OTHER |
4401 | printk("cyc:cy_stop ttyC%d\n", info->line); /* */ | 4309 | printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line); |
4402 | #endif | 4310 | #endif |
4403 | 4311 | ||
4404 | if (serial_paranoia_check(info, tty->name, "cy_stop")) | 4312 | if (serial_paranoia_check(info, tty->name, "cy_stop")) |
4405 | return; | 4313 | return; |
4406 | 4314 | ||
4407 | cinfo = &cy_card[info->card]; | 4315 | cinfo = info->card; |
4408 | channel = info->line - cinfo->first_line; | 4316 | channel = info->line - cinfo->first_line; |
4409 | if (!IS_CYC_Z(*cinfo)) { | 4317 | if (!IS_CYC_Z(*cinfo)) { |
4410 | index = cinfo->bus_index; | 4318 | index = cinfo->bus_index; |
4411 | chip = channel >> 2; | 4319 | chip = channel >> 2; |
4412 | channel &= 0x03; | 4320 | channel &= 0x03; |
4413 | base_addr = cy_card[info->card].base_addr + | 4321 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
4414 | (cy_chip_offset[chip] << index); | ||
4415 | 4322 | ||
4416 | CY_LOCK(info, flags); | 4323 | spin_lock_irqsave(&cinfo->card_lock, flags); |
4417 | cy_writeb(base_addr + (CyCAR << index), | 4324 | cy_writeb(base_addr + (CyCAR << index), |
4418 | (u_char)(channel & 0x0003)); /* index channel */ | 4325 | (u_char)(channel & 0x0003)); /* index channel */ |
4419 | cy_writeb(base_addr + (CySRER << index), | 4326 | cy_writeb(base_addr + (CySRER << index), |
4420 | cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); | 4327 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
4421 | CY_UNLOCK(info, flags); | 4328 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
4422 | } else { | ||
4423 | /* Nothing to do! */ | ||
4424 | } | 4329 | } |
4425 | } /* cy_stop */ | 4330 | } /* cy_stop */ |
4426 | 4331 | ||
4427 | static void cy_start(struct tty_struct *tty) | 4332 | static void cy_start(struct tty_struct *tty) |
4428 | { | 4333 | { |
4429 | struct cyclades_card *cinfo; | 4334 | struct cyclades_card *cinfo; |
4430 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4335 | struct cyclades_port *info = tty->driver_data; |
4431 | void __iomem *base_addr; | 4336 | void __iomem *base_addr; |
4432 | int chip, channel, index; | 4337 | int chip, channel, index; |
4433 | unsigned long flags; | 4338 | unsigned long flags; |
4434 | 4339 | ||
4435 | #ifdef CY_DEBUG_OTHER | 4340 | #ifdef CY_DEBUG_OTHER |
4436 | printk("cyc:cy_start ttyC%d\n", info->line); /* */ | 4341 | printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line); |
4437 | #endif | 4342 | #endif |
4438 | 4343 | ||
4439 | if (serial_paranoia_check(info, tty->name, "cy_start")) | 4344 | if (serial_paranoia_check(info, tty->name, "cy_start")) |
4440 | return; | 4345 | return; |
4441 | 4346 | ||
4442 | cinfo = &cy_card[info->card]; | 4347 | cinfo = info->card; |
4443 | channel = info->line - cinfo->first_line; | 4348 | channel = info->line - cinfo->first_line; |
4444 | index = cinfo->bus_index; | 4349 | index = cinfo->bus_index; |
4445 | if (!IS_CYC_Z(*cinfo)) { | 4350 | if (!IS_CYC_Z(*cinfo)) { |
4446 | chip = channel >> 2; | 4351 | chip = channel >> 2; |
4447 | channel &= 0x03; | 4352 | channel &= 0x03; |
4448 | base_addr = cy_card[info->card].base_addr + | 4353 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
4449 | (cy_chip_offset[chip] << index); | ||
4450 | 4354 | ||
4451 | CY_LOCK(info, flags); | 4355 | spin_lock_irqsave(&cinfo->card_lock, flags); |
4452 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ | 4356 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ |
4453 | cy_writeb(base_addr + (CySRER << index), | 4357 | cy_writeb(base_addr + (CySRER << index), |
4454 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | 4358 | readb(base_addr + (CySRER << index)) | CyTxRdy); |
4455 | CY_UNLOCK(info, flags); | 4359 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
4456 | } else { | ||
4457 | /* Nothing to do! */ | ||
4458 | } | 4360 | } |
4459 | } /* cy_start */ | 4361 | } /* cy_start */ |
4460 | 4362 | ||
4461 | static void cy_flush_buffer(struct tty_struct *tty) | 4363 | static void cy_flush_buffer(struct tty_struct *tty) |
4462 | { | 4364 | { |
4463 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4365 | struct cyclades_port *info = tty->driver_data; |
4464 | int card, channel, retval; | 4366 | struct cyclades_card *card; |
4367 | int channel, retval; | ||
4465 | unsigned long flags; | 4368 | unsigned long flags; |
4466 | 4369 | ||
4467 | #ifdef CY_DEBUG_IO | 4370 | #ifdef CY_DEBUG_IO |
4468 | printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ | 4371 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); |
4469 | #endif | 4372 | #endif |
4470 | 4373 | ||
4471 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | 4374 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) |
4472 | return; | 4375 | return; |
4473 | 4376 | ||
4474 | card = info->card; | 4377 | card = info->card; |
4475 | channel = (info->line) - (cy_card[card].first_line); | 4378 | channel = info->line - card->first_line; |
4476 | 4379 | ||
4477 | CY_LOCK(info, flags); | 4380 | spin_lock_irqsave(&card->card_lock, flags); |
4478 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 4381 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
4479 | CY_UNLOCK(info, flags); | 4382 | spin_unlock_irqrestore(&card->card_lock, flags); |
4480 | 4383 | ||
4481 | if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board | 4384 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board |
4482 | buffers as well */ | 4385 | buffers as well */ |
4483 | CY_LOCK(info, flags); | 4386 | spin_lock_irqsave(&card->card_lock, flags); |
4484 | retval = | 4387 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); |
4485 | cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L); | ||
4486 | if (retval != 0) { | 4388 | if (retval != 0) { |
4487 | printk("cyc: flush_buffer retval on ttyC%d was %x\n", | 4389 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " |
4488 | info->line, retval); | 4390 | "was %x\n", info->line, retval); |
4489 | } | 4391 | } |
4490 | CY_UNLOCK(info, flags); | 4392 | spin_unlock_irqrestore(&card->card_lock, flags); |
4491 | } | 4393 | } |
4492 | tty_wakeup(tty); | 4394 | tty_wakeup(tty); |
4493 | } /* cy_flush_buffer */ | 4395 | } /* cy_flush_buffer */ |
@@ -4497,10 +4399,10 @@ static void cy_flush_buffer(struct tty_struct *tty) | |||
4497 | */ | 4399 | */ |
4498 | static void cy_hangup(struct tty_struct *tty) | 4400 | static void cy_hangup(struct tty_struct *tty) |
4499 | { | 4401 | { |
4500 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4402 | struct cyclades_port *info = tty->driver_data; |
4501 | 4403 | ||
4502 | #ifdef CY_DEBUG_OTHER | 4404 | #ifdef CY_DEBUG_OTHER |
4503 | printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ | 4405 | printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line); |
4504 | #endif | 4406 | #endif |
4505 | 4407 | ||
4506 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) | 4408 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) |
@@ -4511,7 +4413,8 @@ static void cy_hangup(struct tty_struct *tty) | |||
4511 | info->event = 0; | 4413 | info->event = 0; |
4512 | info->count = 0; | 4414 | info->count = 0; |
4513 | #ifdef CY_DEBUG_COUNT | 4415 | #ifdef CY_DEBUG_COUNT |
4514 | printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); | 4416 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", |
4417 | current->pid); | ||
4515 | #endif | 4418 | #endif |
4516 | info->tty = NULL; | 4419 | info->tty = NULL; |
4517 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 4420 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -4526,10 +4429,107 @@ static void cy_hangup(struct tty_struct *tty) | |||
4526 | * --------------------------------------------------------------------- | 4429 | * --------------------------------------------------------------------- |
4527 | */ | 4430 | */ |
4528 | 4431 | ||
4432 | static int __devinit cy_init_card(struct cyclades_card *cinfo) | ||
4433 | { | ||
4434 | struct cyclades_port *info; | ||
4435 | u32 mailbox; | ||
4436 | unsigned int nports; | ||
4437 | unsigned short chip_number; | ||
4438 | int index, port; | ||
4439 | |||
4440 | spin_lock_init(&cinfo->card_lock); | ||
4441 | |||
4442 | if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */ | ||
4443 | mailbox = readl(&((struct RUNTIME_9060 __iomem *) | ||
4444 | cinfo->ctl_addr)->mail_box_0); | ||
4445 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; | ||
4446 | cinfo->intr_enabled = 0; | ||
4447 | cinfo->nports = 0; /* Will be correctly set later, after | ||
4448 | Z FW is loaded */ | ||
4449 | } else { | ||
4450 | index = cinfo->bus_index; | ||
4451 | nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; | ||
4452 | } | ||
4453 | |||
4454 | cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL); | ||
4455 | if (cinfo->ports == NULL) { | ||
4456 | printk(KERN_ERR "Cyclades: cannot allocate ports\n"); | ||
4457 | cinfo->nports = 0; | ||
4458 | return -ENOMEM; | ||
4459 | } | ||
4460 | |||
4461 | for (port = cinfo->first_line; port < cinfo->first_line + nports; | ||
4462 | port++) { | ||
4463 | info = &cinfo->ports[port - cinfo->first_line]; | ||
4464 | info->magic = CYCLADES_MAGIC; | ||
4465 | info->card = cinfo; | ||
4466 | info->line = port; | ||
4467 | info->flags = STD_COM_FLAGS; | ||
4468 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
4469 | info->close_delay = 5 * HZ / 10; | ||
4470 | |||
4471 | INIT_WORK(&info->tqueue, do_softint); | ||
4472 | init_waitqueue_head(&info->open_wait); | ||
4473 | init_waitqueue_head(&info->close_wait); | ||
4474 | init_completion(&info->shutdown_wait); | ||
4475 | init_waitqueue_head(&info->delta_msr_wait); | ||
4476 | |||
4477 | if (IS_CYC_Z(*cinfo)) { | ||
4478 | info->type = PORT_STARTECH; | ||
4479 | if (mailbox == ZO_V1) | ||
4480 | info->xmit_fifo_size = CYZ_FIFO_SIZE; | ||
4481 | else | ||
4482 | info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; | ||
4483 | #ifdef CONFIG_CYZ_INTR | ||
4484 | setup_timer(&cyz_rx_full_timer[port], | ||
4485 | cyz_rx_restart, (unsigned long)info); | ||
4486 | #endif | ||
4487 | } else { | ||
4488 | info->type = PORT_CIRRUS; | ||
4489 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; | ||
4490 | info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; | ||
4491 | info->cor2 = CyETC; | ||
4492 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | ||
4493 | |||
4494 | chip_number = (port - cinfo->first_line) / 4; | ||
4495 | if ((info->chip_rev = readb(cinfo->base_addr + | ||
4496 | (cy_chip_offset[chip_number] << | ||
4497 | index) + (CyGFRCR << index))) >= | ||
4498 | CD1400_REV_J) { | ||
4499 | /* It is a CD1400 rev. J or later */ | ||
4500 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | ||
4501 | info->tco = baud_co_60[13]; /* Tx CO */ | ||
4502 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ | ||
4503 | info->rco = baud_co_60[13]; /* Rx CO */ | ||
4504 | info->rtsdtr_inv = 1; | ||
4505 | } else { | ||
4506 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ | ||
4507 | info->tco = baud_co_25[13]; /* Tx CO */ | ||
4508 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ | ||
4509 | info->rco = baud_co_25[13]; /* Rx CO */ | ||
4510 | info->rtsdtr_inv = 0; | ||
4511 | } | ||
4512 | info->read_status_mask = CyTIMEOUT | CySPECHAR | | ||
4513 | CyBREAK | CyPARITY | CyFRAME | CyOVERRUN; | ||
4514 | } | ||
4515 | |||
4516 | } | ||
4517 | |||
4518 | #ifndef CONFIG_CYZ_INTR | ||
4519 | if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) { | ||
4520 | mod_timer(&cyz_timerlist, jiffies + 1); | ||
4521 | #ifdef CY_PCI_DEBUG | ||
4522 | printk(KERN_DEBUG "Cyclades-Z polling initialized\n"); | ||
4523 | #endif | ||
4524 | } | ||
4525 | #endif | ||
4526 | return 0; | ||
4527 | } | ||
4528 | |||
4529 | /* initialize chips on Cyclom-Y card -- return number of valid | 4529 | /* initialize chips on Cyclom-Y card -- return number of valid |
4530 | chips (which is number of ports/4) */ | 4530 | chips (which is number of ports/4) */ |
4531 | static unsigned short __init | 4531 | static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, |
4532 | cyy_init_card(void __iomem * true_base_addr, int index) | 4532 | int index) |
4533 | { | 4533 | { |
4534 | unsigned int chip_number; | 4534 | unsigned int chip_number; |
4535 | void __iomem *base_addr; | 4535 | void __iomem *base_addr; |
@@ -4544,7 +4544,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4544 | base_addr = | 4544 | base_addr = |
4545 | true_base_addr + (cy_chip_offset[chip_number] << index); | 4545 | true_base_addr + (cy_chip_offset[chip_number] << index); |
4546 | mdelay(1); | 4546 | mdelay(1); |
4547 | if (cy_readb(base_addr + (CyCCR << index)) != 0x00) { | 4547 | if (readb(base_addr + (CyCCR << index)) != 0x00) { |
4548 | /************* | 4548 | /************* |
4549 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", | 4549 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", |
4550 | chip_number, (unsigned long)base_addr); | 4550 | chip_number, (unsigned long)base_addr); |
@@ -4561,7 +4561,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4561 | chip 4 GFRCR register appears at chip 0, there is no chip 4 | 4561 | chip 4 GFRCR register appears at chip 0, there is no chip 4 |
4562 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. | 4562 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. |
4563 | */ | 4563 | */ |
4564 | if (chip_number == 4 && cy_readb(true_base_addr + | 4564 | if (chip_number == 4 && readb(true_base_addr + |
4565 | (cy_chip_offset[0] << index) + | 4565 | (cy_chip_offset[0] << index) + |
4566 | (CyGFRCR << index)) == 0) { | 4566 | (CyGFRCR << index)) == 0) { |
4567 | return chip_number; | 4567 | return chip_number; |
@@ -4570,7 +4570,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4570 | cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); | 4570 | cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); |
4571 | mdelay(1); | 4571 | mdelay(1); |
4572 | 4572 | ||
4573 | if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) { | 4573 | if (readb(base_addr + (CyGFRCR << index)) == 0x00) { |
4574 | /* | 4574 | /* |
4575 | printk(" chip #%d at %#6lx is not responding ", | 4575 | printk(" chip #%d at %#6lx is not responding ", |
4576 | chip_number, (unsigned long)base_addr); | 4576 | chip_number, (unsigned long)base_addr); |
@@ -4578,7 +4578,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4578 | */ | 4578 | */ |
4579 | return chip_number; | 4579 | return chip_number; |
4580 | } | 4580 | } |
4581 | if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) != | 4581 | if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) != |
4582 | 0x40) { | 4582 | 0x40) { |
4583 | /* | 4583 | /* |
4584 | printk(" chip #%d at %#6lx is not valid (GFRCR == " | 4584 | printk(" chip #%d at %#6lx is not valid (GFRCR == " |
@@ -4589,7 +4589,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4589 | return chip_number; | 4589 | return chip_number; |
4590 | } | 4590 | } |
4591 | cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); | 4591 | cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); |
4592 | if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { | 4592 | if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { |
4593 | /* It is a CD1400 rev. J or later */ | 4593 | /* It is a CD1400 rev. J or later */ |
4594 | /* Impossible to reach 5ms with this chip. | 4594 | /* Impossible to reach 5ms with this chip. |
4595 | Changed to 2ms instead (f = 500 Hz). */ | 4595 | Changed to 2ms instead (f = 500 Hz). */ |
@@ -4602,7 +4602,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4602 | /* | 4602 | /* |
4603 | printk(" chip #%d at %#6lx is rev 0x%2x\n", | 4603 | printk(" chip #%d at %#6lx is rev 0x%2x\n", |
4604 | chip_number, (unsigned long)base_addr, | 4604 | chip_number, (unsigned long)base_addr, |
4605 | cy_readb(base_addr+(CyGFRCR<<index))); | 4605 | readb(base_addr+(CyGFRCR<<index))); |
4606 | */ | 4606 | */ |
4607 | } | 4607 | } |
4608 | return chip_number; | 4608 | return chip_number; |
@@ -4647,9 +4647,15 @@ static int __init cy_detect_isa(void) | |||
4647 | 4647 | ||
4648 | /* probe for CD1400... */ | 4648 | /* probe for CD1400... */ |
4649 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); | 4649 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); |
4650 | if (cy_isa_address == NULL) { | ||
4651 | printk(KERN_ERR "Cyclom-Y/ISA: can't remap base " | ||
4652 | "address\n"); | ||
4653 | continue; | ||
4654 | } | ||
4650 | cy_isa_nchan = CyPORTS_PER_CHIP * | 4655 | cy_isa_nchan = CyPORTS_PER_CHIP * |
4651 | cyy_init_card(cy_isa_address, 0); | 4656 | cyy_init_card(cy_isa_address, 0); |
4652 | if (cy_isa_nchan == 0) { | 4657 | if (cy_isa_nchan == 0) { |
4658 | iounmap(cy_isa_address); | ||
4653 | continue; | 4659 | continue; |
4654 | } | 4660 | } |
4655 | #ifdef MODULE | 4661 | #ifdef MODULE |
@@ -4660,40 +4666,42 @@ static int __init cy_detect_isa(void) | |||
4660 | /* find out the board's irq by probing */ | 4666 | /* find out the board's irq by probing */ |
4661 | cy_isa_irq = detect_isa_irq(cy_isa_address); | 4667 | cy_isa_irq = detect_isa_irq(cy_isa_address); |
4662 | if (cy_isa_irq == 0) { | 4668 | if (cy_isa_irq == 0) { |
4663 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4669 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the " |
4670 | "IRQ could not be detected.\n", | ||
4664 | (unsigned long)cy_isa_address); | 4671 | (unsigned long)cy_isa_address); |
4665 | printk("but the IRQ could not be detected.\n"); | 4672 | iounmap(cy_isa_address); |
4666 | continue; | 4673 | continue; |
4667 | } | 4674 | } |
4668 | 4675 | ||
4669 | if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { | 4676 | if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { |
4670 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4677 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " |
4678 | "more channels are available. Change NR_PORTS " | ||
4679 | "in cyclades.c and recompile kernel.\n", | ||
4671 | (unsigned long)cy_isa_address); | 4680 | (unsigned long)cy_isa_address); |
4672 | printk("but no more channels are available.\n"); | 4681 | iounmap(cy_isa_address); |
4673 | printk("Change NR_PORTS in cyclades.c and recompile " | ||
4674 | "kernel.\n"); | ||
4675 | return nboard; | 4682 | return nboard; |
4676 | } | 4683 | } |
4677 | /* fill the next cy_card structure available */ | 4684 | /* fill the next cy_card structure available */ |
4678 | for (j = 0; j < NR_CARDS; j++) { | 4685 | for (j = 0; j < NR_CARDS; j++) { |
4679 | if (cy_card[j].base_addr == 0) | 4686 | if (cy_card[j].base_addr == NULL) |
4680 | break; | 4687 | break; |
4681 | } | 4688 | } |
4682 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4689 | if (j == NR_CARDS) { /* no more cy_cards available */ |
4683 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4690 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " |
4691 | "more cards can be used. Change NR_CARDS in " | ||
4692 | "cyclades.c and recompile kernel.\n", | ||
4684 | (unsigned long)cy_isa_address); | 4693 | (unsigned long)cy_isa_address); |
4685 | printk("but no more cards can be used .\n"); | 4694 | iounmap(cy_isa_address); |
4686 | printk("Change NR_CARDS in cyclades.c and recompile " | ||
4687 | "kernel.\n"); | ||
4688 | return nboard; | 4695 | return nboard; |
4689 | } | 4696 | } |
4690 | 4697 | ||
4691 | /* allocate IRQ */ | 4698 | /* allocate IRQ */ |
4692 | if (request_irq(cy_isa_irq, cyy_interrupt, | 4699 | if (request_irq(cy_isa_irq, cyy_interrupt, |
4693 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { | 4700 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { |
4694 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4701 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
4695 | (unsigned long)cy_isa_address); | 4702 | "could not allocate IRQ#%d.\n", |
4696 | printk("but could not allocate IRQ#%d.\n", cy_isa_irq); | 4703 | (unsigned long)cy_isa_address, cy_isa_irq); |
4704 | iounmap(cy_isa_address); | ||
4697 | return nboard; | 4705 | return nboard; |
4698 | } | 4706 | } |
4699 | 4707 | ||
@@ -4704,15 +4712,23 @@ static int __init cy_detect_isa(void) | |||
4704 | cy_card[j].bus_index = 0; | 4712 | cy_card[j].bus_index = 0; |
4705 | cy_card[j].first_line = cy_next_channel; | 4713 | cy_card[j].first_line = cy_next_channel; |
4706 | cy_card[j].num_chips = cy_isa_nchan / 4; | 4714 | cy_card[j].num_chips = cy_isa_nchan / 4; |
4715 | if (cy_init_card(&cy_card[j])) { | ||
4716 | cy_card[j].base_addr = NULL; | ||
4717 | free_irq(cy_isa_irq, &cy_card[j]); | ||
4718 | iounmap(cy_isa_address); | ||
4719 | continue; | ||
4720 | } | ||
4707 | nboard++; | 4721 | nboard++; |
4708 | 4722 | ||
4709 | /* print message */ | 4723 | printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " |
4710 | printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", | 4724 | "%d channels starting from port %d\n", |
4711 | j + 1, (unsigned long)cy_isa_address, | 4725 | j + 1, (unsigned long)cy_isa_address, |
4712 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), | 4726 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), |
4713 | cy_isa_irq); | 4727 | cy_isa_irq, cy_isa_nchan, cy_next_channel); |
4714 | printk("%d channels starting from port %d.\n", | 4728 | |
4715 | cy_isa_nchan, cy_next_channel); | 4729 | for (j = cy_next_channel; |
4730 | j < cy_next_channel + cy_isa_nchan; j++) | ||
4731 | tty_register_device(cy_serial_driver, j, NULL); | ||
4716 | cy_next_channel += cy_isa_nchan; | 4732 | cy_next_channel += cy_isa_nchan; |
4717 | } | 4733 | } |
4718 | return nboard; | 4734 | return nboard; |
@@ -4721,510 +4737,310 @@ static int __init cy_detect_isa(void) | |||
4721 | #endif /* CONFIG_ISA */ | 4737 | #endif /* CONFIG_ISA */ |
4722 | } /* cy_detect_isa */ | 4738 | } /* cy_detect_isa */ |
4723 | 4739 | ||
4724 | static void plx_init(void __iomem * addr, uclong initctl) | 4740 | #ifdef CONFIG_PCI |
4741 | static void __devinit plx_init(void __iomem * addr, __u32 initctl) | ||
4725 | { | 4742 | { |
4726 | /* Reset PLX */ | 4743 | /* Reset PLX */ |
4727 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); | 4744 | cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000); |
4728 | udelay(100L); | 4745 | udelay(100L); |
4729 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); | 4746 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000); |
4730 | 4747 | ||
4731 | /* Reload Config. Registers from EEPROM */ | 4748 | /* Reload Config. Registers from EEPROM */ |
4732 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); | 4749 | cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000); |
4733 | udelay(100L); | 4750 | udelay(100L); |
4734 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); | 4751 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000); |
4735 | } | 4752 | } |
4736 | 4753 | ||
4737 | /* | 4754 | static int __devinit cy_pci_probe(struct pci_dev *pdev, |
4738 | * --------------------------------------------------------------------- | 4755 | const struct pci_device_id *ent) |
4739 | * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI. | ||
4740 | * sets global variables and return the number of PCI boards found. | ||
4741 | * --------------------------------------------------------------------- | ||
4742 | */ | ||
4743 | static int __init cy_detect_pci(void) | ||
4744 | { | 4756 | { |
4745 | #ifdef CONFIG_PCI | 4757 | void __iomem *addr0 = NULL, *addr2 = NULL; |
4746 | 4758 | char *card_name = NULL; | |
4747 | struct pci_dev *pdev = NULL; | 4759 | u32 mailbox; |
4748 | unsigned char cyy_rev_id; | 4760 | unsigned int device_id, nchan = 0, card_no, i; |
4749 | unsigned char cy_pci_irq = 0; | 4761 | unsigned char plx_ver; |
4750 | uclong cy_pci_phys0, cy_pci_phys2; | 4762 | int retval, irq; |
4751 | void __iomem *cy_pci_addr0, *cy_pci_addr2; | 4763 | |
4752 | unsigned short i, j, cy_pci_nchan, plx_ver; | 4764 | retval = pci_enable_device(pdev); |
4753 | unsigned short device_id, dev_index = 0; | 4765 | if (retval) { |
4754 | uclong mailbox; | 4766 | dev_err(&pdev->dev, "cannot enable device\n"); |
4755 | uclong ZeIndex = 0; | 4767 | goto err; |
4756 | void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; | 4768 | } |
4757 | uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS]; | ||
4758 | unsigned char Ze_irq[NR_CARDS]; | ||
4759 | struct pci_dev *Ze_pdev[NR_CARDS]; | ||
4760 | |||
4761 | for (i = 0; i < NR_CARDS; i++) { | ||
4762 | /* look for a Cyclades card by vendor and device id */ | ||
4763 | while ((device_id = cy_pci_dev_id[dev_index].device) != 0) { | ||
4764 | if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, | ||
4765 | device_id, pdev)) == NULL) { | ||
4766 | dev_index++; /* try next device id */ | ||
4767 | } else { | ||
4768 | break; /* found a board */ | ||
4769 | } | ||
4770 | } | ||
4771 | |||
4772 | if (device_id == 0) | ||
4773 | break; | ||
4774 | |||
4775 | if (pci_enable_device(pdev)) | ||
4776 | continue; | ||
4777 | |||
4778 | /* read PCI configuration area */ | ||
4779 | cy_pci_irq = pdev->irq; | ||
4780 | cy_pci_phys0 = pci_resource_start(pdev, 0); | ||
4781 | cy_pci_phys2 = pci_resource_start(pdev, 2); | ||
4782 | pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); | ||
4783 | 4769 | ||
4784 | device_id &= ~PCI_DEVICE_ID_MASK; | 4770 | /* read PCI configuration area */ |
4771 | irq = pdev->irq; | ||
4772 | device_id = pdev->device & ~PCI_DEVICE_ID_MASK; | ||
4785 | 4773 | ||
4786 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | 4774 | #if defined(__alpha__) |
4787 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 4775 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ |
4788 | #ifdef CY_PCI_DEBUG | 4776 | dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " |
4789 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | 4777 | "addresses on Alpha systems.\n"); |
4790 | pdev->bus->number, pdev->devfn); | 4778 | retval = -EIO; |
4791 | printk("rev_id=%d) IRQ%d\n", | 4779 | goto err_dis; |
4792 | cyy_rev_id, (int)cy_pci_irq); | 4780 | } |
4793 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " | ||
4794 | "ctladdr=0x%lx\n", | ||
4795 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | ||
4796 | #endif | 4781 | #endif |
4782 | if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | ||
4783 | dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " | ||
4784 | "addresses\n"); | ||
4785 | retval = -EIO; | ||
4786 | goto err_dis; | ||
4787 | } | ||
4797 | 4788 | ||
4798 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | 4789 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { |
4799 | printk(" Warning: PCI I/O bit incorrectly " | 4790 | dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " |
4800 | "set. Ignoring it...\n"); | 4791 | "it...\n"); |
4801 | pdev->resource[2].flags &= ~IORESOURCE_IO; | 4792 | pdev->resource[2].flags &= ~IORESOURCE_IO; |
4802 | } | 4793 | } |
4803 | 4794 | ||
4804 | /* Although we don't use this I/O region, we should | 4795 | retval = pci_request_regions(pdev, "cyclades"); |
4805 | request it from the kernel anyway, to avoid problems | 4796 | if (retval) { |
4806 | with other drivers accessing it. */ | 4797 | dev_err(&pdev->dev, "failed to reserve resources\n"); |
4807 | if (pci_request_regions(pdev, "Cyclom-Y") != 0) { | 4798 | goto err_dis; |
4808 | printk(KERN_ERR "cyclades: failed to reserve " | 4799 | } |
4809 | "PCI resources\n"); | ||
4810 | continue; | ||
4811 | } | ||
4812 | #if defined(__alpha__) | ||
4813 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ | ||
4814 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | ||
4815 | pdev->bus->number, pdev->devfn); | ||
4816 | printk("rev_id=%d) IRQ%d\n", | ||
4817 | cyy_rev_id, (int)cy_pci_irq); | ||
4818 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " | ||
4819 | "ctladdr=0x%lx\n", | ||
4820 | (ulong)cy_pci_phys2, | ||
4821 | (ulong)cy_pci_phys0); | ||
4822 | printk("Cyclom-Y/PCI not supported for low " | ||
4823 | "addresses in Alpha systems.\n"); | ||
4824 | i--; | ||
4825 | continue; | ||
4826 | } | ||
4827 | #endif | ||
4828 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl); | ||
4829 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin); | ||
4830 | 4800 | ||
4831 | #ifdef CY_PCI_DEBUG | 4801 | retval = -EIO; |
4832 | printk("Cyclom-Y/PCI: relocate winaddr=0x%lx " | 4802 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
4833 | "ctladdr=0x%lx\n", | 4803 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4834 | (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); | 4804 | card_name = "Cyclom-Y"; |
4835 | #endif | ||
4836 | cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * | ||
4837 | cyy_init_card(cy_pci_addr2, 1)); | ||
4838 | if (cy_pci_nchan == 0) { | ||
4839 | printk("Cyclom-Y PCI host card with "); | ||
4840 | printk("no Serial-Modules at 0x%lx.\n", | ||
4841 | (ulong) cy_pci_phys2); | ||
4842 | i--; | ||
4843 | continue; | ||
4844 | } | ||
4845 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
4846 | printk("Cyclom-Y/PCI found at 0x%lx ", | ||
4847 | (ulong) cy_pci_phys2); | ||
4848 | printk("but no channels are available.\n"); | ||
4849 | printk("Change NR_PORTS in cyclades.c and " | ||
4850 | "recompile kernel.\n"); | ||
4851 | return i; | ||
4852 | } | ||
4853 | /* fill the next cy_card structure available */ | ||
4854 | for (j = 0; j < NR_CARDS; j++) { | ||
4855 | if (cy_card[j].base_addr == 0) | ||
4856 | break; | ||
4857 | } | ||
4858 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
4859 | printk("Cyclom-Y/PCI found at 0x%lx ", | ||
4860 | (ulong) cy_pci_phys2); | ||
4861 | printk("but no more cards can be used.\n"); | ||
4862 | printk("Change NR_CARDS in cyclades.c and " | ||
4863 | "recompile kernel.\n"); | ||
4864 | return i; | ||
4865 | } | ||
4866 | 4805 | ||
4867 | /* allocate IRQ */ | 4806 | addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); |
4868 | if (request_irq(cy_pci_irq, cyy_interrupt, | 4807 | if (addr0 == NULL) { |
4869 | IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { | 4808 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4870 | printk("Cyclom-Y/PCI found at 0x%lx ", | 4809 | goto err_reg; |
4871 | (ulong) cy_pci_phys2); | 4810 | } |
4872 | printk("but could not allocate IRQ%d.\n", | 4811 | addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); |
4873 | cy_pci_irq); | 4812 | if (addr2 == NULL) { |
4874 | return i; | 4813 | dev_err(&pdev->dev, "can't remap base region\n"); |
4875 | } | 4814 | goto err_unmap; |
4815 | } | ||
4876 | 4816 | ||
4877 | /* set cy_card */ | 4817 | nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); |
4878 | cy_card[j].base_phys = (ulong) cy_pci_phys2; | 4818 | if (nchan == 0) { |
4879 | cy_card[j].ctl_phys = (ulong) cy_pci_phys0; | 4819 | dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " |
4880 | cy_card[j].base_addr = cy_pci_addr2; | 4820 | "Serial-Modules\n"); |
4881 | cy_card[j].ctl_addr = cy_pci_addr0; | 4821 | return -EIO; |
4882 | cy_card[j].irq = (int)cy_pci_irq; | 4822 | } |
4883 | cy_card[j].bus_index = 1; | 4823 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { |
4884 | cy_card[j].first_line = cy_next_channel; | 4824 | struct RUNTIME_9060 __iomem *ctl_addr; |
4885 | cy_card[j].num_chips = cy_pci_nchan / 4; | ||
4886 | cy_card[j].pdev = pdev; | ||
4887 | |||
4888 | /* enable interrupts in the PCI interface */ | ||
4889 | plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; | ||
4890 | switch (plx_ver) { | ||
4891 | case PLX_9050: | ||
4892 | |||
4893 | cy_writeb(cy_pci_addr0 + 0x4c, 0x43); | ||
4894 | break; | ||
4895 | 4825 | ||
4896 | case PLX_9060: | 4826 | ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); |
4897 | case PLX_9080: | 4827 | if (addr0 == NULL) { |
4898 | default: /* Old boards, use PLX_9060 */ | 4828 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4899 | 4829 | goto err_reg; | |
4900 | plx_init(cy_pci_addr0, 0x6c); | 4830 | } |
4901 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4902 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4903 | re-write it to the PCI config. registers. | ||
4904 | This will remain here until we find a permanent | ||
4905 | fix. */ | ||
4906 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4907 | cy_pci_irq); | ||
4908 | |||
4909 | cy_writew(cy_pci_addr0 + 0x68, | ||
4910 | cy_readw(cy_pci_addr0 + | ||
4911 | 0x68) | 0x0900); | ||
4912 | break; | ||
4913 | } | ||
4914 | 4831 | ||
4915 | /* print message */ | 4832 | /* Disable interrupts on the PLX before resetting it */ |
4916 | printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | 4833 | cy_writew(addr0 + 0x68, |
4917 | j + 1, (ulong)cy_pci_phys2, | 4834 | readw(addr0 + 0x68) & ~0x0900); |
4918 | (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1), | 4835 | |
4919 | (int)cy_pci_irq); | 4836 | plx_init(addr0, 0x6c); |
4920 | printk("%d channels starting from port %d.\n", | 4837 | /* For some yet unknown reason, once the PLX9060 reloads |
4921 | cy_pci_nchan, cy_next_channel); | 4838 | the EEPROM, the IRQ is lost and, thus, we have to |
4922 | 4839 | re-write it to the PCI config. registers. | |
4923 | cy_next_channel += cy_pci_nchan; | 4840 | This will remain here until we find a permanent |
4924 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | 4841 | fix. */ |
4925 | /* print message */ | 4842 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); |
4926 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | 4843 | |
4927 | pdev->bus->number, pdev->devfn); | 4844 | mailbox = (u32)readl(&ctl_addr->mail_box_0); |
4928 | printk("rev_id=%d) IRQ%d\n", | 4845 | |
4929 | cyy_rev_id, (int)cy_pci_irq); | 4846 | addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? |
4930 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " | 4847 | CyPCI_Ze_win : CyPCI_Zwin); |
4931 | "ctladdr=0x%lx\n", | 4848 | if (addr2 == NULL) { |
4932 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4849 | dev_err(&pdev->dev, "can't remap base region\n"); |
4933 | printk("Cyclades-Z/PCI not supported for low " | 4850 | goto err_unmap; |
4934 | "addresses\n"); | 4851 | } |
4935 | break; | ||
4936 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | ||
4937 | #ifdef CY_PCI_DEBUG | ||
4938 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | ||
4939 | pdev->bus->number, pdev->devfn); | ||
4940 | printk("rev_id=%d) IRQ%d\n", | ||
4941 | cyy_rev_id, (int)cy_pci_irq); | ||
4942 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " | ||
4943 | "ctladdr=0x%lx\n", | ||
4944 | (ulong) cy_pci_phys2, (ulong) cy_pci_phys0); | ||
4945 | #endif | ||
4946 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl); | ||
4947 | |||
4948 | /* Disable interrupts on the PLX before resetting it */ | ||
4949 | cy_writew(cy_pci_addr0 + 0x68, | ||
4950 | cy_readw(cy_pci_addr0 + 0x68) & ~0x0900); | ||
4951 | |||
4952 | plx_init(cy_pci_addr0, 0x6c); | ||
4953 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4954 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4955 | re-write it to the PCI config. registers. | ||
4956 | This will remain here until we find a permanent | ||
4957 | fix. */ | ||
4958 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4959 | cy_pci_irq); | ||
4960 | |||
4961 | mailbox = | ||
4962 | (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
4963 | cy_pci_addr0)->mail_box_0); | ||
4964 | |||
4965 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | ||
4966 | printk(" Warning: PCI I/O bit incorrectly " | ||
4967 | "set. Ignoring it...\n"); | ||
4968 | pdev->resource[2].flags &= ~IORESOURCE_IO; | ||
4969 | } | ||
4970 | 4852 | ||
4971 | /* Although we don't use this I/O region, we should | 4853 | if (mailbox == ZE_V1) { |
4972 | request it from the kernel anyway, to avoid problems | 4854 | card_name = "Cyclades-Ze"; |
4973 | with other drivers accessing it. */ | ||
4974 | if (pci_request_regions(pdev, "Cyclades-Z") != 0) { | ||
4975 | printk(KERN_ERR "cyclades: failed to reserve " | ||
4976 | "PCI resources\n"); | ||
4977 | continue; | ||
4978 | } | ||
4979 | 4855 | ||
4980 | if (mailbox == ZE_V1) { | 4856 | readl(&ctl_addr->mail_box_0); |
4981 | cy_pci_addr2 = ioremap(cy_pci_phys2, | 4857 | nchan = ZE_V1_NPORTS; |
4982 | CyPCI_Ze_win); | 4858 | } else { |
4983 | if (ZeIndex == NR_CARDS) { | 4859 | card_name = "Cyclades-8Zo"; |
4984 | printk("Cyclades-Ze/PCI found at " | ||
4985 | "0x%lx but no more cards can " | ||
4986 | "be used.\nChange NR_CARDS in " | ||
4987 | "cyclades.c and recompile " | ||
4988 | "kernel.\n", | ||
4989 | (ulong)cy_pci_phys2); | ||
4990 | } else { | ||
4991 | Ze_phys0[ZeIndex] = cy_pci_phys0; | ||
4992 | Ze_phys2[ZeIndex] = cy_pci_phys2; | ||
4993 | Ze_addr0[ZeIndex] = cy_pci_addr0; | ||
4994 | Ze_addr2[ZeIndex] = cy_pci_addr2; | ||
4995 | Ze_irq[ZeIndex] = cy_pci_irq; | ||
4996 | Ze_pdev[ZeIndex] = pdev; | ||
4997 | ZeIndex++; | ||
4998 | } | ||
4999 | i--; | ||
5000 | continue; | ||
5001 | } else { | ||
5002 | cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin); | ||
5003 | } | ||
5004 | 4860 | ||
5005 | #ifdef CY_PCI_DEBUG | 4861 | #ifdef CY_PCI_DEBUG |
5006 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx " | ||
5007 | "ctladdr=0x%lx\n", | ||
5008 | (ulong) cy_pci_addr2, (ulong) cy_pci_addr0); | ||
5009 | if (mailbox == ZO_V1) { | 4862 | if (mailbox == ZO_V1) { |
5010 | cy_writel(&((struct RUNTIME_9060 *) | 4863 | cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); |
5011 | (cy_pci_addr0))->loc_addr_base, | 4864 | dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " |
5012 | WIN_CREG); | 4865 | "id %lx, ver %lx\n", (ulong)(0xff & |
5013 | PAUSE; | 4866 | readl(&((struct CUSTOM_REG *)addr2)-> |
5014 | printk("Cyclades-8Zo/PCI: FPGA id %lx, ver " | 4867 | fpga_id)), (ulong)(0xff & |
5015 | "%lx\n", (ulong) (0xff & | 4868 | readl(&((struct CUSTOM_REG *)addr2)-> |
5016 | cy_readl(&((struct CUSTOM_REG *) | 4869 | fpga_version))); |
5017 | (cy_pci_addr2))->fpga_id)), | 4870 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); |
5018 | (ulong)(0xff & | ||
5019 | cy_readl(&((struct CUSTOM_REG *) | ||
5020 | (cy_pci_addr2))-> | ||
5021 | fpga_version))); | ||
5022 | cy_writel(&((struct RUNTIME_9060 *) | ||
5023 | (cy_pci_addr0))->loc_addr_base, | ||
5024 | WIN_RAM); | ||
5025 | } else { | 4871 | } else { |
5026 | printk("Cyclades-Z/PCI: New Cyclades-Z board. " | 4872 | dev_info(&pdev->dev, "Cyclades-Z/PCI: New " |
5027 | "FPGA not loaded\n"); | 4873 | "Cyclades-Z board. FPGA not loaded\n"); |
5028 | } | 4874 | } |
5029 | #endif | 4875 | #endif |
5030 | /* The following clears the firmware id word. This | 4876 | /* The following clears the firmware id word. This |
5031 | ensures that the driver will not attempt to talk to | 4877 | ensures that the driver will not attempt to talk to |
5032 | the board until it has been properly initialized. | 4878 | the board until it has been properly initialized. |
5033 | */ | 4879 | */ |
5034 | PAUSE; | ||
5035 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) | 4880 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) |
5036 | cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); | 4881 | cy_writel(addr2 + ID_ADDRESS, 0L); |
5037 | 4882 | ||
5038 | /* This must be a Cyclades-8Zo/PCI. The extendable | 4883 | /* This must be a Cyclades-8Zo/PCI. The extendable |
5039 | version will have a different device_id and will | 4884 | version will have a different device_id and will |
5040 | be allocated its maximum number of ports. */ | 4885 | be allocated its maximum number of ports. */ |
5041 | cy_pci_nchan = 8; | 4886 | nchan = 8; |
5042 | |||
5043 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
5044 | printk("Cyclades-8Zo/PCI found at 0x%lx but" | ||
5045 | "no channels are available.\nChange " | ||
5046 | "NR_PORTS in cyclades.c and recompile " | ||
5047 | "kernel.\n", (ulong)cy_pci_phys2); | ||
5048 | return i; | ||
5049 | } | ||
5050 | |||
5051 | /* fill the next cy_card structure available */ | ||
5052 | for (j = 0; j < NR_CARDS; j++) { | ||
5053 | if (cy_card[j].base_addr == 0) | ||
5054 | break; | ||
5055 | } | ||
5056 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
5057 | printk("Cyclades-8Zo/PCI found at 0x%lx but" | ||
5058 | "no more cards can be used.\nChange " | ||
5059 | "NR_CARDS in cyclades.c and recompile " | ||
5060 | "kernel.\n", (ulong)cy_pci_phys2); | ||
5061 | return i; | ||
5062 | } | ||
5063 | #ifdef CONFIG_CYZ_INTR | ||
5064 | /* allocate IRQ only if board has an IRQ */ | ||
5065 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | ||
5066 | if (request_irq(cy_pci_irq, cyz_interrupt, | ||
5067 | IRQF_SHARED, "Cyclades-Z", | ||
5068 | &cy_card[j])) { | ||
5069 | printk("Cyclom-8Zo/PCI found at 0x%lx " | ||
5070 | "but could not allocate " | ||
5071 | "IRQ%d.\n", (ulong)cy_pci_phys2, | ||
5072 | cy_pci_irq); | ||
5073 | return i; | ||
5074 | } | ||
5075 | } | ||
5076 | #endif /* CONFIG_CYZ_INTR */ | ||
5077 | |||
5078 | /* set cy_card */ | ||
5079 | cy_card[j].base_phys = cy_pci_phys2; | ||
5080 | cy_card[j].ctl_phys = cy_pci_phys0; | ||
5081 | cy_card[j].base_addr = cy_pci_addr2; | ||
5082 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
5083 | cy_card[j].irq = (int)cy_pci_irq; | ||
5084 | cy_card[j].bus_index = 1; | ||
5085 | cy_card[j].first_line = cy_next_channel; | ||
5086 | cy_card[j].num_chips = -1; | ||
5087 | cy_card[j].pdev = pdev; | ||
5088 | |||
5089 | /* print message */ | ||
5090 | #ifdef CONFIG_CYZ_INTR | ||
5091 | /* don't report IRQ if board is no IRQ */ | ||
5092 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) | ||
5093 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, " | ||
5094 | "IRQ%d, ", j + 1, (ulong)cy_pci_phys2, | ||
5095 | (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1), | ||
5096 | (int)cy_pci_irq); | ||
5097 | else | ||
5098 | #endif /* CONFIG_CYZ_INTR */ | ||
5099 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ", | ||
5100 | j + 1, (ulong)cy_pci_phys2, | ||
5101 | (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1)); | ||
5102 | |||
5103 | printk("%d channels starting from port %d.\n", | ||
5104 | cy_pci_nchan, cy_next_channel); | ||
5105 | cy_next_channel += cy_pci_nchan; | ||
5106 | } | 4887 | } |
5107 | } | 4888 | } |
5108 | 4889 | ||
5109 | for (; ZeIndex != 0 && i < NR_CARDS; i++) { | 4890 | if ((cy_next_channel + nchan) > NR_PORTS) { |
5110 | cy_pci_phys0 = Ze_phys0[0]; | 4891 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " |
5111 | cy_pci_phys2 = Ze_phys2[0]; | 4892 | "channels are available. Change NR_PORTS in " |
5112 | cy_pci_addr0 = Ze_addr0[0]; | 4893 | "cyclades.c and recompile kernel.\n"); |
5113 | cy_pci_addr2 = Ze_addr2[0]; | 4894 | goto err_unmap; |
5114 | cy_pci_irq = Ze_irq[0]; | 4895 | } |
5115 | pdev = Ze_pdev[0]; | 4896 | /* fill the next cy_card structure available */ |
5116 | for (j = 0; j < ZeIndex - 1; j++) { | 4897 | for (card_no = 0; card_no < NR_CARDS; card_no++) { |
5117 | Ze_phys0[j] = Ze_phys0[j + 1]; | 4898 | if (cy_card[card_no].base_addr == NULL) |
5118 | Ze_phys2[j] = Ze_phys2[j + 1]; | 4899 | break; |
5119 | Ze_addr0[j] = Ze_addr0[j + 1]; | 4900 | } |
5120 | Ze_addr2[j] = Ze_addr2[j + 1]; | 4901 | if (card_no == NR_CARDS) { /* no more cy_cards available */ |
5121 | Ze_irq[j] = Ze_irq[j + 1]; | 4902 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " |
5122 | Ze_pdev[j] = Ze_pdev[j + 1]; | 4903 | "more cards can be used. Change NR_CARDS in " |
5123 | } | 4904 | "cyclades.c and recompile kernel.\n"); |
5124 | ZeIndex--; | 4905 | goto err_unmap; |
5125 | mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | 4906 | } |
5126 | cy_pci_addr0)->mail_box_0); | ||
5127 | #ifdef CY_PCI_DEBUG | ||
5128 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", | ||
5129 | (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); | ||
5130 | printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not " | ||
5131 | "loaded\n"); | ||
5132 | #endif | ||
5133 | PAUSE; | ||
5134 | /* This must be the new Cyclades-Ze/PCI. */ | ||
5135 | cy_pci_nchan = ZE_V1_NPORTS; | ||
5136 | |||
5137 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
5138 | printk("Cyclades-Ze/PCI found at 0x%lx but no channels " | ||
5139 | "are available.\nChange NR_PORTS in cyclades.c " | ||
5140 | "and recompile kernel.\n", | ||
5141 | (ulong) cy_pci_phys2); | ||
5142 | return i; | ||
5143 | } | ||
5144 | 4907 | ||
5145 | /* fill the next cy_card structure available */ | 4908 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
5146 | for (j = 0; j < NR_CARDS; j++) { | 4909 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
5147 | if (cy_card[j].base_addr == 0) | 4910 | /* allocate IRQ */ |
5148 | break; | 4911 | retval = request_irq(irq, cyy_interrupt, |
5149 | } | 4912 | IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); |
5150 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4913 | if (retval) { |
5151 | printk("Cyclades-Ze/PCI found at 0x%lx but no more " | 4914 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
5152 | "cards can be used.\nChange NR_CARDS in " | 4915 | goto err_unmap; |
5153 | "cyclades.c and recompile kernel.\n", | ||
5154 | (ulong) cy_pci_phys2); | ||
5155 | return i; | ||
5156 | } | 4916 | } |
4917 | cy_card[card_no].num_chips = nchan / 4; | ||
4918 | } else { | ||
5157 | #ifdef CONFIG_CYZ_INTR | 4919 | #ifdef CONFIG_CYZ_INTR |
5158 | /* allocate IRQ only if board has an IRQ */ | 4920 | /* allocate IRQ only if board has an IRQ */ |
5159 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | 4921 | if (irq != 0 && irq != 255) { |
5160 | if (request_irq(cy_pci_irq, cyz_interrupt, | 4922 | retval = request_irq(irq, cyz_interrupt, |
5161 | IRQF_SHARED, "Cyclades-Z", | 4923 | IRQF_SHARED, "Cyclades-Z", |
5162 | &cy_card[j])) { | 4924 | &cy_card[card_no]); |
5163 | printk("Cyclom-Ze/PCI found at 0x%lx ", | 4925 | if (retval) { |
5164 | (ulong) cy_pci_phys2); | 4926 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
5165 | printk("but could not allocate IRQ%d.\n", | 4927 | goto err_unmap; |
5166 | cy_pci_irq); | ||
5167 | return i; | ||
5168 | } | 4928 | } |
5169 | } | 4929 | } |
5170 | #endif /* CONFIG_CYZ_INTR */ | 4930 | #endif /* CONFIG_CYZ_INTR */ |
4931 | cy_card[card_no].num_chips = -1; | ||
4932 | } | ||
5171 | 4933 | ||
5172 | /* set cy_card */ | 4934 | /* set cy_card */ |
5173 | cy_card[j].base_phys = cy_pci_phys2; | 4935 | cy_card[card_no].base_addr = addr2; |
5174 | cy_card[j].ctl_phys = cy_pci_phys0; | 4936 | cy_card[card_no].ctl_addr = addr0; |
5175 | cy_card[j].base_addr = cy_pci_addr2; | 4937 | cy_card[card_no].irq = irq; |
5176 | cy_card[j].ctl_addr = cy_pci_addr0; | 4938 | cy_card[card_no].bus_index = 1; |
5177 | cy_card[j].irq = (int)cy_pci_irq; | 4939 | cy_card[card_no].first_line = cy_next_channel; |
5178 | cy_card[j].bus_index = 1; | 4940 | retval = cy_init_card(&cy_card[card_no]); |
5179 | cy_card[j].first_line = cy_next_channel; | 4941 | if (retval) |
5180 | cy_card[j].num_chips = -1; | 4942 | goto err_null; |
5181 | cy_card[j].pdev = pdev; | ||
5182 | 4943 | ||
5183 | /* print message */ | 4944 | pci_set_drvdata(pdev, &cy_card[card_no]); |
5184 | #ifdef CONFIG_CYZ_INTR | ||
5185 | /* don't report IRQ if board is no IRQ */ | ||
5186 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) | ||
5187 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | ||
5188 | j + 1, (ulong) cy_pci_phys2, | ||
5189 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1), | ||
5190 | (int)cy_pci_irq); | ||
5191 | else | ||
5192 | #endif /* CONFIG_CYZ_INTR */ | ||
5193 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ", | ||
5194 | j + 1, (ulong) cy_pci_phys2, | ||
5195 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1)); | ||
5196 | 4945 | ||
5197 | printk("%d channels starting from port %d.\n", | 4946 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
5198 | cy_pci_nchan, cy_next_channel); | 4947 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
5199 | cy_next_channel += cy_pci_nchan; | 4948 | /* enable interrupts in the PCI interface */ |
5200 | } | 4949 | plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; |
5201 | if (ZeIndex != 0) { | 4950 | switch (plx_ver) { |
5202 | printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be " | 4951 | case PLX_9050: |
5203 | "used.\nChange NR_CARDS in cyclades.c and recompile " | 4952 | |
5204 | "kernel.\n", (unsigned int)Ze_phys2[0]); | 4953 | cy_writeb(addr0 + 0x4c, 0x43); |
4954 | break; | ||
4955 | |||
4956 | case PLX_9060: | ||
4957 | case PLX_9080: | ||
4958 | default: /* Old boards, use PLX_9060 */ | ||
4959 | |||
4960 | plx_init(addr0, 0x6c); | ||
4961 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4962 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4963 | re-write it to the PCI config. registers. | ||
4964 | This will remain here until we find a permanent | ||
4965 | fix. */ | ||
4966 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); | ||
4967 | |||
4968 | cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900); | ||
4969 | break; | ||
4970 | } | ||
5205 | } | 4971 | } |
5206 | return i; | 4972 | |
5207 | #else | 4973 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " |
4974 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); | ||
4975 | for (i = cy_next_channel; i < cy_next_channel + nchan; i++) | ||
4976 | tty_register_device(cy_serial_driver, i, &pdev->dev); | ||
4977 | cy_next_channel += nchan; | ||
4978 | |||
5208 | return 0; | 4979 | return 0; |
5209 | #endif /* ifdef CONFIG_PCI */ | 4980 | err_null: |
5210 | } /* cy_detect_pci */ | 4981 | cy_card[card_no].base_addr = NULL; |
4982 | free_irq(irq, &cy_card[card_no]); | ||
4983 | err_unmap: | ||
4984 | pci_iounmap(pdev, addr0); | ||
4985 | if (addr2) | ||
4986 | pci_iounmap(pdev, addr2); | ||
4987 | err_reg: | ||
4988 | pci_release_regions(pdev); | ||
4989 | err_dis: | ||
4990 | pci_disable_device(pdev); | ||
4991 | err: | ||
4992 | return retval; | ||
4993 | } | ||
5211 | 4994 | ||
5212 | /* | 4995 | static void __devexit cy_pci_remove(struct pci_dev *pdev) |
5213 | * This routine prints out the appropriate serial driver version number | ||
5214 | * and identifies which options were configured into this driver. | ||
5215 | */ | ||
5216 | static inline void show_version(void) | ||
5217 | { | 4996 | { |
5218 | printk("Cyclades driver " CY_VERSION "\n"); | 4997 | struct cyclades_card *cinfo = pci_get_drvdata(pdev); |
5219 | printk(" built %s %s\n", __DATE__, __TIME__); | 4998 | unsigned int i; |
5220 | } /* show_version */ | 4999 | |
5000 | /* non-Z with old PLX */ | ||
5001 | if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == | ||
5002 | PLX_9050) | ||
5003 | cy_writeb(cinfo->ctl_addr + 0x4c, 0); | ||
5004 | else | ||
5005 | #ifndef CONFIG_CYZ_INTR | ||
5006 | if (!IS_CYC_Z(*cinfo)) | ||
5007 | #endif | ||
5008 | cy_writew(cinfo->ctl_addr + 0x68, | ||
5009 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); | ||
5010 | |||
5011 | pci_iounmap(pdev, cinfo->base_addr); | ||
5012 | if (cinfo->ctl_addr) | ||
5013 | pci_iounmap(pdev, cinfo->ctl_addr); | ||
5014 | if (cinfo->irq | ||
5015 | #ifndef CONFIG_CYZ_INTR | ||
5016 | && !IS_CYC_Z(*cinfo) | ||
5017 | #endif /* CONFIG_CYZ_INTR */ | ||
5018 | ) | ||
5019 | free_irq(cinfo->irq, cinfo); | ||
5020 | pci_release_regions(pdev); | ||
5021 | |||
5022 | cinfo->base_addr = NULL; | ||
5023 | for (i = cinfo->first_line; i < cinfo->first_line + | ||
5024 | cinfo->nports; i++) | ||
5025 | tty_unregister_device(cy_serial_driver, i); | ||
5026 | cinfo->nports = 0; | ||
5027 | kfree(cinfo->ports); | ||
5028 | } | ||
5029 | |||
5030 | static struct pci_driver cy_pci_driver = { | ||
5031 | .name = "cyclades", | ||
5032 | .id_table = cy_pci_dev_id, | ||
5033 | .probe = cy_pci_probe, | ||
5034 | .remove = __devexit_p(cy_pci_remove) | ||
5035 | }; | ||
5036 | #endif | ||
5221 | 5037 | ||
5222 | static int | 5038 | static int |
5223 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, | 5039 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, |
5224 | int *eof, void *data) | 5040 | int *eof, void *data) |
5225 | { | 5041 | { |
5226 | struct cyclades_port *info; | 5042 | struct cyclades_port *info; |
5227 | int i; | 5043 | unsigned int i, j; |
5228 | int len = 0; | 5044 | int len = 0; |
5229 | off_t begin = 0; | 5045 | off_t begin = 0; |
5230 | off_t pos = 0; | 5046 | off_t pos = 0; |
@@ -5238,33 +5054,34 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, | |||
5238 | len += size; | 5054 | len += size; |
5239 | 5055 | ||
5240 | /* Output one line for each known port */ | 5056 | /* Output one line for each known port */ |
5241 | for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { | 5057 | for (i = 0; i < NR_CARDS; i++) |
5242 | info = &cy_port[i]; | 5058 | for (j = 0; j < cy_card[i].nports; j++) { |
5243 | 5059 | info = &cy_card[i].ports[j]; | |
5244 | if (info->count) | 5060 | |
5245 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | 5061 | if (info->count) |
5246 | "%8lu %9lu %6ld\n", info->line, | 5062 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu " |
5247 | (cur_jifs - info->idle_stats.in_use) / HZ, | 5063 | "%10lu %8lu %9lu %6ld\n", info->line, |
5248 | info->idle_stats.xmit_bytes, | 5064 | (cur_jifs - info->idle_stats.in_use) / |
5249 | (cur_jifs - info->idle_stats.xmit_idle) / HZ, | 5065 | HZ, info->idle_stats.xmit_bytes, |
5250 | info->idle_stats.recv_bytes, | 5066 | (cur_jifs - info->idle_stats.xmit_idle)/ |
5251 | (cur_jifs - info->idle_stats.recv_idle) / HZ, | 5067 | HZ, info->idle_stats.recv_bytes, |
5252 | info->idle_stats.overruns, | 5068 | (cur_jifs - info->idle_stats.recv_idle)/ |
5253 | (long)info->tty->ldisc.num); | 5069 | HZ, info->idle_stats.overruns, |
5254 | else | 5070 | (long)info->tty->ldisc.num); |
5255 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | 5071 | else |
5256 | "%8lu %9lu %6ld\n", | 5072 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu " |
5257 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); | 5073 | "%10lu %8lu %9lu %6ld\n", |
5258 | len += size; | 5074 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); |
5259 | pos = begin + len; | 5075 | len += size; |
5260 | 5076 | pos = begin + len; | |
5261 | if (pos < offset) { | 5077 | |
5262 | len = 0; | 5078 | if (pos < offset) { |
5263 | begin = pos; | 5079 | len = 0; |
5080 | begin = pos; | ||
5081 | } | ||
5082 | if (pos > offset + length) | ||
5083 | goto done; | ||
5264 | } | 5084 | } |
5265 | if (pos > offset + length) | ||
5266 | goto done; | ||
5267 | } | ||
5268 | *eof = 1; | 5085 | *eof = 1; |
5269 | done: | 5086 | done: |
5270 | *start = buf + (offset - begin); /* Start of wanted data */ | 5087 | *start = buf + (offset - begin); /* Start of wanted data */ |
@@ -5319,18 +5136,15 @@ static const struct tty_operations cy_ops = { | |||
5319 | 5136 | ||
5320 | static int __init cy_init(void) | 5137 | static int __init cy_init(void) |
5321 | { | 5138 | { |
5322 | struct cyclades_port *info; | 5139 | unsigned int nboards; |
5323 | struct cyclades_card *cinfo; | 5140 | int retval = -ENOMEM; |
5324 | int number_z_boards = 0; | ||
5325 | int board, port, i, index; | ||
5326 | unsigned long mailbox; | ||
5327 | unsigned short chip_number; | ||
5328 | int nports; | ||
5329 | 5141 | ||
5330 | cy_serial_driver = alloc_tty_driver(NR_PORTS); | 5142 | cy_serial_driver = alloc_tty_driver(NR_PORTS); |
5331 | if (!cy_serial_driver) | 5143 | if (!cy_serial_driver) |
5332 | return -ENOMEM; | 5144 | goto err; |
5333 | show_version(); | 5145 | |
5146 | printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n", | ||
5147 | __DATE__, __TIME__); | ||
5334 | 5148 | ||
5335 | /* Initialize the tty_driver structure */ | 5149 | /* Initialize the tty_driver structure */ |
5336 | 5150 | ||
@@ -5344,15 +5158,13 @@ static int __init cy_init(void) | |||
5344 | cy_serial_driver->init_termios = tty_std_termios; | 5158 | cy_serial_driver->init_termios = tty_std_termios; |
5345 | cy_serial_driver->init_termios.c_cflag = | 5159 | cy_serial_driver->init_termios.c_cflag = |
5346 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 5160 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
5347 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; | 5161 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
5348 | tty_set_operations(cy_serial_driver, &cy_ops); | 5162 | tty_set_operations(cy_serial_driver, &cy_ops); |
5349 | 5163 | ||
5350 | if (tty_register_driver(cy_serial_driver)) | 5164 | retval = tty_register_driver(cy_serial_driver); |
5351 | panic("Couldn't register Cyclades serial driver\n"); | 5165 | if (retval) { |
5352 | 5166 | printk(KERN_ERR "Couldn't register Cyclades serial driver\n"); | |
5353 | for (i = 0; i < NR_CARDS; i++) { | 5167 | goto err_frtty; |
5354 | /* base_addr=0 indicates board not found */ | ||
5355 | cy_card[i].base_addr = NULL; | ||
5356 | } | 5168 | } |
5357 | 5169 | ||
5358 | /* the code below is responsible to find the boards. Each different | 5170 | /* the code below is responsible to find the boards. Each different |
@@ -5363,223 +5175,68 @@ static int __init cy_init(void) | |||
5363 | the cy_next_channel. */ | 5175 | the cy_next_channel. */ |
5364 | 5176 | ||
5365 | /* look for isa boards */ | 5177 | /* look for isa boards */ |
5366 | cy_isa_nboard = cy_detect_isa(); | 5178 | nboards = cy_detect_isa(); |
5367 | 5179 | ||
5180 | #ifdef CONFIG_PCI | ||
5368 | /* look for pci boards */ | 5181 | /* look for pci boards */ |
5369 | cy_pci_nboard = cy_detect_pci(); | 5182 | retval = pci_register_driver(&cy_pci_driver); |
5370 | 5183 | if (retval && !nboards) | |
5371 | cy_nboard = cy_isa_nboard + cy_pci_nboard; | 5184 | goto err_unr; |
5372 | |||
5373 | /* invalidate remaining cy_card structures */ | ||
5374 | for (i = 0; i < NR_CARDS; i++) { | ||
5375 | if (cy_card[i].base_addr == 0) { | ||
5376 | cy_card[i].first_line = -1; | ||
5377 | cy_card[i].ctl_addr = NULL; | ||
5378 | cy_card[i].irq = 0; | ||
5379 | cy_card[i].bus_index = 0; | ||
5380 | cy_card[i].first_line = 0; | ||
5381 | cy_card[i].num_chips = 0; | ||
5382 | } | ||
5383 | } | ||
5384 | /* invalidate remaining cy_port structures */ | ||
5385 | for (i = cy_next_channel; i < NR_PORTS; i++) { | ||
5386 | cy_port[i].line = -1; | ||
5387 | cy_port[i].magic = -1; | ||
5388 | } | ||
5389 | |||
5390 | /* initialize per-port data structures for each valid board found */ | ||
5391 | for (board = 0; board < cy_nboard; board++) { | ||
5392 | cinfo = &cy_card[board]; | ||
5393 | if (cinfo->num_chips == -1) { /* Cyclades-Z */ | ||
5394 | number_z_boards++; | ||
5395 | mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
5396 | cy_card[board].ctl_addr)-> | ||
5397 | mail_box_0); | ||
5398 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; | ||
5399 | cinfo->intr_enabled = 0; | ||
5400 | cinfo->nports = 0; /* Will be correctly set later, after | ||
5401 | Z FW is loaded */ | ||
5402 | spin_lock_init(&cinfo->card_lock); | ||
5403 | for (port = cinfo->first_line; | ||
5404 | port < cinfo->first_line + nports; port++) { | ||
5405 | info = &cy_port[port]; | ||
5406 | info->magic = CYCLADES_MAGIC; | ||
5407 | info->type = PORT_STARTECH; | ||
5408 | info->card = board; | ||
5409 | info->line = port; | ||
5410 | info->chip_rev = 0; | ||
5411 | info->flags = STD_COM_FLAGS; | ||
5412 | info->tty = NULL; | ||
5413 | if (mailbox == ZO_V1) | ||
5414 | info->xmit_fifo_size = CYZ_FIFO_SIZE; | ||
5415 | else | ||
5416 | info->xmit_fifo_size = | ||
5417 | 4 * CYZ_FIFO_SIZE; | ||
5418 | info->cor1 = 0; | ||
5419 | info->cor2 = 0; | ||
5420 | info->cor3 = 0; | ||
5421 | info->cor4 = 0; | ||
5422 | info->cor5 = 0; | ||
5423 | info->tbpr = 0; | ||
5424 | info->tco = 0; | ||
5425 | info->rbpr = 0; | ||
5426 | info->rco = 0; | ||
5427 | info->custom_divisor = 0; | ||
5428 | info->close_delay = 5 * HZ / 10; | ||
5429 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
5430 | info->icount.cts = info->icount.dsr = | ||
5431 | info->icount.rng = info->icount.dcd = 0; | ||
5432 | info->icount.rx = info->icount.tx = 0; | ||
5433 | info->icount.frame = info->icount.parity = 0; | ||
5434 | info->icount.overrun = info->icount.brk = 0; | ||
5435 | info->x_char = 0; | ||
5436 | info->event = 0; | ||
5437 | info->count = 0; | ||
5438 | info->blocked_open = 0; | ||
5439 | info->default_threshold = 0; | ||
5440 | info->default_timeout = 0; | ||
5441 | INIT_WORK(&info->tqueue, do_softint); | ||
5442 | init_waitqueue_head(&info->open_wait); | ||
5443 | init_waitqueue_head(&info->close_wait); | ||
5444 | init_waitqueue_head(&info->shutdown_wait); | ||
5445 | init_waitqueue_head(&info->delta_msr_wait); | ||
5446 | /* info->session */ | ||
5447 | /* info->pgrp */ | ||
5448 | info->read_status_mask = 0; | ||
5449 | /* info->timeout */ | ||
5450 | /* Bentson's vars */ | ||
5451 | info->jiffies[0] = 0; | ||
5452 | info->jiffies[1] = 0; | ||
5453 | info->jiffies[2] = 0; | ||
5454 | info->rflush_count = 0; | ||
5455 | #ifdef CONFIG_CYZ_INTR | ||
5456 | init_timer(&cyz_rx_full_timer[port]); | ||
5457 | cyz_rx_full_timer[port].function = NULL; | ||
5458 | #endif | 5185 | #endif |
5459 | } | ||
5460 | continue; | ||
5461 | } else { /* Cyclom-Y of some kind */ | ||
5462 | index = cinfo->bus_index; | ||
5463 | spin_lock_init(&cinfo->card_lock); | ||
5464 | cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; | ||
5465 | for (port = cinfo->first_line; | ||
5466 | port < cinfo->first_line + cinfo->nports; port++) { | ||
5467 | info = &cy_port[port]; | ||
5468 | info->magic = CYCLADES_MAGIC; | ||
5469 | info->type = PORT_CIRRUS; | ||
5470 | info->card = board; | ||
5471 | info->line = port; | ||
5472 | info->flags = STD_COM_FLAGS; | ||
5473 | info->tty = NULL; | ||
5474 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; | ||
5475 | info->cor1 = | ||
5476 | CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; | ||
5477 | info->cor2 = CyETC; | ||
5478 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | ||
5479 | info->cor4 = 0; | ||
5480 | info->cor5 = 0; | ||
5481 | info->custom_divisor = 0; | ||
5482 | info->close_delay = 5 * HZ / 10; | ||
5483 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
5484 | info->icount.cts = info->icount.dsr = | ||
5485 | info->icount.rng = info->icount.dcd = 0; | ||
5486 | info->icount.rx = info->icount.tx = 0; | ||
5487 | info->icount.frame = info->icount.parity = 0; | ||
5488 | info->icount.overrun = info->icount.brk = 0; | ||
5489 | chip_number = (port - cinfo->first_line) / 4; | ||
5490 | if ((info->chip_rev = | ||
5491 | cy_readb(cinfo->base_addr + | ||
5492 | (cy_chip_offset[chip_number] << | ||
5493 | index) + (CyGFRCR << index))) >= | ||
5494 | CD1400_REV_J) { | ||
5495 | /* It is a CD1400 rev. J or later */ | ||
5496 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | ||
5497 | info->tco = baud_co_60[13]; /* Tx CO */ | ||
5498 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ | ||
5499 | info->rco = baud_co_60[13]; /* Rx CO */ | ||
5500 | info->rflow = 0; | ||
5501 | info->rtsdtr_inv = 1; | ||
5502 | } else { | ||
5503 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ | ||
5504 | info->tco = baud_co_25[13]; /* Tx CO */ | ||
5505 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ | ||
5506 | info->rco = baud_co_25[13]; /* Rx CO */ | ||
5507 | info->rflow = 0; | ||
5508 | info->rtsdtr_inv = 0; | ||
5509 | } | ||
5510 | info->x_char = 0; | ||
5511 | info->event = 0; | ||
5512 | info->count = 0; | ||
5513 | info->blocked_open = 0; | ||
5514 | info->default_threshold = 0; | ||
5515 | info->default_timeout = 0; | ||
5516 | INIT_WORK(&info->tqueue, do_softint); | ||
5517 | init_waitqueue_head(&info->open_wait); | ||
5518 | init_waitqueue_head(&info->close_wait); | ||
5519 | init_waitqueue_head(&info->shutdown_wait); | ||
5520 | init_waitqueue_head(&info->delta_msr_wait); | ||
5521 | /* info->session */ | ||
5522 | /* info->pgrp */ | ||
5523 | info->read_status_mask = | ||
5524 | CyTIMEOUT | CySPECHAR | CyBREAK | ||
5525 | | CyPARITY | CyFRAME | CyOVERRUN; | ||
5526 | /* info->timeout */ | ||
5527 | } | ||
5528 | } | ||
5529 | } | ||
5530 | |||
5531 | #ifndef CONFIG_CYZ_INTR | ||
5532 | if (number_z_boards && !cyz_timeron) { | ||
5533 | cyz_timeron++; | ||
5534 | cyz_timerlist.expires = jiffies + 1; | ||
5535 | add_timer(&cyz_timerlist); | ||
5536 | #ifdef CY_PCI_DEBUG | ||
5537 | printk("Cyclades-Z polling initialized\n"); | ||
5538 | #endif | ||
5539 | } | ||
5540 | #endif /* CONFIG_CYZ_INTR */ | ||
5541 | 5186 | ||
5542 | return 0; | 5187 | return 0; |
5543 | 5188 | err_unr: | |
5189 | tty_unregister_driver(cy_serial_driver); | ||
5190 | err_frtty: | ||
5191 | put_tty_driver(cy_serial_driver); | ||
5192 | err: | ||
5193 | return retval; | ||
5544 | } /* cy_init */ | 5194 | } /* cy_init */ |
5545 | 5195 | ||
5546 | static void __exit cy_cleanup_module(void) | 5196 | static void __exit cy_cleanup_module(void) |
5547 | { | 5197 | { |
5198 | struct cyclades_card *card; | ||
5548 | int i, e1; | 5199 | int i, e1; |
5549 | 5200 | ||
5550 | #ifndef CONFIG_CYZ_INTR | 5201 | #ifndef CONFIG_CYZ_INTR |
5551 | if (cyz_timeron){ | 5202 | del_timer_sync(&cyz_timerlist); |
5552 | cyz_timeron = 0; | ||
5553 | del_timer(&cyz_timerlist); | ||
5554 | } | ||
5555 | #endif /* CONFIG_CYZ_INTR */ | 5203 | #endif /* CONFIG_CYZ_INTR */ |
5556 | 5204 | ||
5557 | if ((e1 = tty_unregister_driver(cy_serial_driver))) | 5205 | if ((e1 = tty_unregister_driver(cy_serial_driver))) |
5558 | printk("cyc: failed to unregister Cyclades serial driver(%d)\n", | 5206 | printk(KERN_ERR "failed to unregister Cyclades serial " |
5559 | e1); | 5207 | "driver(%d)\n", e1); |
5560 | 5208 | ||
5561 | put_tty_driver(cy_serial_driver); | 5209 | #ifdef CONFIG_PCI |
5210 | pci_unregister_driver(&cy_pci_driver); | ||
5211 | #endif | ||
5562 | 5212 | ||
5563 | for (i = 0; i < NR_CARDS; i++) { | 5213 | for (i = 0; i < NR_CARDS; i++) { |
5564 | if (cy_card[i].base_addr) { | 5214 | card = &cy_card[i]; |
5565 | iounmap(cy_card[i].base_addr); | 5215 | if (card->base_addr) { |
5566 | if (cy_card[i].ctl_addr) | 5216 | /* clear interrupt */ |
5567 | iounmap(cy_card[i].ctl_addr); | 5217 | cy_writeb(card->base_addr + Cy_ClrIntr, 0); |
5568 | if (cy_card[i].irq | 5218 | iounmap(card->base_addr); |
5219 | if (card->ctl_addr) | ||
5220 | iounmap(card->ctl_addr); | ||
5221 | if (card->irq | ||
5569 | #ifndef CONFIG_CYZ_INTR | 5222 | #ifndef CONFIG_CYZ_INTR |
5570 | && cy_card[i].num_chips != -1 /* not a Z card */ | 5223 | && !IS_CYC_Z(*card) |
5571 | #endif /* CONFIG_CYZ_INTR */ | 5224 | #endif /* CONFIG_CYZ_INTR */ |
5572 | ) | 5225 | ) |
5573 | free_irq(cy_card[i].irq, &cy_card[i]); | 5226 | free_irq(card->irq, card); |
5574 | #ifdef CONFIG_PCI | 5227 | for (e1 = card->first_line; |
5575 | if (cy_card[i].pdev) | 5228 | e1 < card->first_line + |
5576 | pci_release_regions(cy_card[i].pdev); | 5229 | card->nports; e1++) |
5577 | #endif | 5230 | tty_unregister_device(cy_serial_driver, e1); |
5231 | kfree(card->ports); | ||
5578 | } | 5232 | } |
5579 | } | 5233 | } |
5234 | |||
5235 | put_tty_driver(cy_serial_driver); | ||
5580 | } /* cy_cleanup_module */ | 5236 | } /* cy_cleanup_module */ |
5581 | 5237 | ||
5582 | module_init(cy_init); | 5238 | module_init(cy_init); |
5583 | module_exit(cy_cleanup_module); | 5239 | module_exit(cy_cleanup_module); |
5584 | 5240 | ||
5585 | MODULE_LICENSE("GPL"); | 5241 | MODULE_LICENSE("GPL"); |
5242 | MODULE_VERSION(CY_VERSION); | ||
diff --git a/drivers/char/digi.h b/drivers/char/digi.h deleted file mode 100644 index 19df0e879b1b..000000000000 --- a/drivers/char/digi.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* Definitions for DigiBoard ditty(1) command. */ | ||
2 | |||
3 | #if !defined(TIOCMODG) | ||
4 | #define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ | ||
5 | #define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ | ||
6 | #endif | ||
7 | |||
8 | #if !defined(TIOCMSET) | ||
9 | #define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ | ||
10 | #define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ | ||
11 | #endif | ||
12 | |||
13 | #if !defined(TIOCMBIC) | ||
14 | #define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ | ||
15 | #define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ | ||
16 | #endif | ||
17 | |||
18 | #if !defined(TIOCSDTR) | ||
19 | #define TIOCSDTR (('e'<<8) | 0) /* set DTR */ | ||
20 | #define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ | ||
21 | #endif | ||
22 | |||
23 | /************************************************************************ | ||
24 | * Ioctl command arguments for DIGI parameters. | ||
25 | ************************************************************************/ | ||
26 | #define DIGI_GETA (('e'<<8) | 94) /* Read params */ | ||
27 | |||
28 | #define DIGI_SETA (('e'<<8) | 95) /* Set params */ | ||
29 | #define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ | ||
30 | #define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ | ||
31 | |||
32 | #define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ | ||
33 | /* control characters */ | ||
34 | #define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ | ||
35 | /* control characters */ | ||
36 | #define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ | ||
37 | /* flow control chars */ | ||
38 | #define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ | ||
39 | /* flow control chars */ | ||
40 | |||
41 | struct digiflow_struct { | ||
42 | unsigned char startc; /* flow cntl start char */ | ||
43 | unsigned char stopc; /* flow cntl stop char */ | ||
44 | }; | ||
45 | |||
46 | typedef struct digiflow_struct digiflow_t; | ||
47 | |||
48 | |||
49 | /************************************************************************ | ||
50 | * Values for digi_flags | ||
51 | ************************************************************************/ | ||
52 | #define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ | ||
53 | #define DIGI_FAST 0x0002 /* Fast baud rates */ | ||
54 | #define RTSPACE 0x0004 /* RTS input flow control */ | ||
55 | #define CTSPACE 0x0008 /* CTS output flow control */ | ||
56 | #define DSRPACE 0x0010 /* DSR output flow control */ | ||
57 | #define DCDPACE 0x0020 /* DCD output flow control */ | ||
58 | #define DTRPACE 0x0040 /* DTR input flow control */ | ||
59 | #define DIGI_FORCEDCD 0x0100 /* Force carrier */ | ||
60 | #define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ | ||
61 | #define DIGI_AIXON 0x0400 /* Aux flow control in fep */ | ||
62 | |||
63 | |||
64 | /************************************************************************ | ||
65 | * Structure used with ioctl commands for DIGI parameters. | ||
66 | ************************************************************************/ | ||
67 | struct digi_struct { | ||
68 | unsigned short digi_flags; /* Flags (see above) */ | ||
69 | }; | ||
70 | |||
71 | typedef struct digi_struct digi_t; | ||
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 3d7efc26aad6..334ad5bbe6b6 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -4,7 +4,6 @@ | |||
4 | */ | 4 | */ |
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/miscdevice.h> | 6 | #include <linux/miscdevice.h> |
7 | #include <linux/smp_lock.h> | ||
8 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
9 | #include <linux/proc_fs.h> | 8 | #include <linux/proc_fs.h> |
10 | #include <linux/capability.h> | 9 | #include <linux/capability.h> |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index db984e481d4c..9b8278e1f4f8 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/device.h> | 35 | #include <linux/device.h> |
37 | 36 | ||
38 | #include <asm/atarihw.h> | 37 | #include <asm/atarihw.h> |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index d8dbdb916232..abde6ddefe69 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/init.h> /* for __init, module_{init,exit} */ | 62 | #include <linux/init.h> /* for __init, module_{init,exit} */ |
63 | #include <linux/poll.h> /* for POLLIN, etc. */ | 63 | #include <linux/poll.h> /* for POLLIN, etc. */ |
64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ | 64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ |
65 | #include <linux/smp_lock.h> | ||
66 | 65 | ||
67 | #ifdef TRACING | 66 | #ifdef TRACING |
68 | #define TRACE_TEXT(str) printk(str); | 67 | #define TRACE_TEXT(str) printk(str); |
@@ -325,16 +324,22 @@ static int dtlk_release(struct inode *inode, struct file *file) | |||
325 | 324 | ||
326 | static int __init dtlk_init(void) | 325 | static int __init dtlk_init(void) |
327 | { | 326 | { |
327 | int err; | ||
328 | |||
328 | dtlk_port_lpc = 0; | 329 | dtlk_port_lpc = 0; |
329 | dtlk_port_tts = 0; | 330 | dtlk_port_tts = 0; |
330 | dtlk_busy = 0; | 331 | dtlk_busy = 0; |
331 | dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); | 332 | dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); |
332 | if (dtlk_major == 0) { | 333 | if (dtlk_major < 0) { |
333 | printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); | 334 | printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); |
334 | return 0; | 335 | return dtlk_major; |
336 | } | ||
337 | err = dtlk_dev_probe(); | ||
338 | if (err) { | ||
339 | unregister_chrdev(dtlk_major, "dtlk"); | ||
340 | return err; | ||
335 | } | 341 | } |
336 | if (dtlk_dev_probe() == 0) | 342 | printk(", MAJOR %d\n", dtlk_major); |
337 | printk(", MAJOR %d\n", dtlk_major); | ||
338 | 343 | ||
339 | init_waitqueue_head(&dtlk_process_list); | 344 | init_waitqueue_head(&dtlk_process_list); |
340 | 345 | ||
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c index 77f58ed6d59a..020011495d91 100644 --- a/drivers/char/ec3104_keyb.c +++ b/drivers/char/ec3104_keyb.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/kbd_kern.h> | 43 | #include <linux/kbd_kern.h> |
44 | #include <linux/smp_lock.h> | ||
45 | #include <linux/bitops.h> | 44 | #include <linux/bitops.h> |
46 | 45 | ||
47 | #include <asm/keyboard.h> | 46 | #include <asm/keyboard.h> |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index de5be30484ad..c6c56fb8ba50 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -949,7 +949,7 @@ static int block_til_ready(struct tty_struct *tty, | |||
949 | 949 | ||
950 | } /* End forever while */ | 950 | } /* End forever while */ |
951 | 951 | ||
952 | current->state = TASK_RUNNING; | 952 | __set_current_state(TASK_RUNNING); |
953 | remove_wait_queue(&ch->open_wait, &wait); | 953 | remove_wait_queue(&ch->open_wait, &wait); |
954 | if (!tty_hung_up_p(filp)) | 954 | if (!tty_hung_up_p(filp)) |
955 | ch->count++; | 955 | ch->count++; |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 23b25ada65ea..49f914e79216 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
@@ -207,7 +207,7 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf, | |||
207 | sizeof(unsigned long); | 207 | sizeof(unsigned long); |
208 | } | 208 | } |
209 | out: | 209 | out: |
210 | current->state = TASK_RUNNING; | 210 | __set_current_state(TASK_RUNNING); |
211 | remove_wait_queue(&gen_rtc_wait, &wait); | 211 | remove_wait_queue(&gen_rtc_wait, &wait); |
212 | 212 | ||
213 | return retval; | 213 | return retval; |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index ae76a9ffe89f..f0e7263dfcde 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -44,7 +44,6 @@ | |||
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> | ||
48 | #include <linux/init.h> | 47 | #include <linux/init.h> |
49 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
50 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 0f9ed7b46a6d..322bc5f7d86b 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -111,7 +111,7 @@ static int last_hvc = -1; | |||
111 | * lock held. If successful, this function increments the kobject reference | 111 | * lock held. If successful, this function increments the kobject reference |
112 | * count against the target hvc_struct so it should be released when finished. | 112 | * count against the target hvc_struct so it should be released when finished. |
113 | */ | 113 | */ |
114 | struct hvc_struct *hvc_get_by_index(int index) | 114 | static struct hvc_struct *hvc_get_by_index(int index) |
115 | { | 115 | { |
116 | struct hvc_struct *hp; | 116 | struct hvc_struct *hp; |
117 | unsigned long flags; | 117 | unsigned long flags; |
@@ -150,7 +150,8 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = | |||
150 | * hvc_console_setup() finds adapters. | 150 | * hvc_console_setup() finds adapters. |
151 | */ | 151 | */ |
152 | 152 | ||
153 | void hvc_console_print(struct console *co, const char *b, unsigned count) | 153 | static void hvc_console_print(struct console *co, const char *b, |
154 | unsigned count) | ||
154 | { | 155 | { |
155 | char c[N_OUTBUF] __ALIGNED__; | 156 | char c[N_OUTBUF] __ALIGNED__; |
156 | unsigned i = 0, n = 0; | 157 | unsigned i = 0, n = 0; |
@@ -208,7 +209,7 @@ static int __init hvc_console_setup(struct console *co, char *options) | |||
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | 211 | ||
211 | struct console hvc_con_driver = { | 212 | static struct console hvc_con_driver = { |
212 | .name = "hvc", | 213 | .name = "hvc", |
213 | .write = hvc_console_print, | 214 | .write = hvc_console_print, |
214 | .device = hvc_console_device, | 215 | .device = hvc_console_device, |
@@ -278,7 +279,6 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) | |||
278 | 279 | ||
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
281 | EXPORT_SYMBOL(hvc_instantiate); | ||
282 | 282 | ||
283 | /* Wake the sleeping khvcd */ | 283 | /* Wake the sleeping khvcd */ |
284 | static void hvc_kick(void) | 284 | static void hvc_kick(void) |
@@ -792,7 +792,6 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
792 | 792 | ||
793 | return hp; | 793 | return hp; |
794 | } | 794 | } |
795 | EXPORT_SYMBOL(hvc_alloc); | ||
796 | 795 | ||
797 | int __devexit hvc_remove(struct hvc_struct *hp) | 796 | int __devexit hvc_remove(struct hvc_struct *hp) |
798 | { | 797 | { |
@@ -828,11 +827,10 @@ int __devexit hvc_remove(struct hvc_struct *hp) | |||
828 | tty_hangup(tty); | 827 | tty_hangup(tty); |
829 | return 0; | 828 | return 0; |
830 | } | 829 | } |
831 | EXPORT_SYMBOL(hvc_remove); | ||
832 | 830 | ||
833 | /* Driver initialization. Follow console initialization. This is where the TTY | 831 | /* Driver initialization. Follow console initialization. This is where the TTY |
834 | * interfaces start to become available. */ | 832 | * interfaces start to become available. */ |
835 | int __init hvc_init(void) | 833 | static int __init hvc_init(void) |
836 | { | 834 | { |
837 | struct tty_driver *drv; | 835 | struct tty_driver *drv; |
838 | 836 | ||
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index cc1046e6ee02..4ae9811d1a6c 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -24,10 +24,11 @@ | |||
24 | * warranty of any kind, whether express or implied. | 24 | * warranty of any kind, whether express or implied. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/hw_random.h> |
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | ||
29 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
30 | #include <linux/hw_random.h> | 31 | #include <linux/stop_machine.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | 33 | ||
33 | 34 | ||
@@ -217,30 +218,117 @@ static struct hwrng intel_rng = { | |||
217 | .data_read = intel_rng_data_read, | 218 | .data_read = intel_rng_data_read, |
218 | }; | 219 | }; |
219 | 220 | ||
221 | struct intel_rng_hw { | ||
222 | struct pci_dev *dev; | ||
223 | void __iomem *mem; | ||
224 | u8 bios_cntl_off; | ||
225 | u8 bios_cntl_val; | ||
226 | u8 fwh_dec_en1_off; | ||
227 | u8 fwh_dec_en1_val; | ||
228 | }; | ||
220 | 229 | ||
221 | #ifdef CONFIG_SMP | 230 | static int __init intel_rng_hw_init(void *_intel_rng_hw) |
222 | static char __initdata waitflag; | 231 | { |
232 | struct intel_rng_hw *intel_rng_hw = _intel_rng_hw; | ||
233 | u8 mfc, dvc; | ||
234 | |||
235 | /* interrupts disabled in stop_machine_run call */ | ||
236 | |||
237 | if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
238 | pci_write_config_byte(intel_rng_hw->dev, | ||
239 | intel_rng_hw->fwh_dec_en1_off, | ||
240 | intel_rng_hw->fwh_dec_en1_val | | ||
241 | FWH_F8_EN_MASK); | ||
242 | if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
243 | pci_write_config_byte(intel_rng_hw->dev, | ||
244 | intel_rng_hw->bios_cntl_off, | ||
245 | intel_rng_hw->bios_cntl_val | | ||
246 | BIOS_CNTL_WRITE_ENABLE_MASK); | ||
247 | |||
248 | writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); | ||
249 | writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem); | ||
250 | mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); | ||
251 | dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS); | ||
252 | writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); | ||
253 | |||
254 | if (!(intel_rng_hw->bios_cntl_val & | ||
255 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) | ||
256 | pci_write_config_byte(intel_rng_hw->dev, | ||
257 | intel_rng_hw->bios_cntl_off, | ||
258 | intel_rng_hw->bios_cntl_val); | ||
259 | if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
260 | pci_write_config_byte(intel_rng_hw->dev, | ||
261 | intel_rng_hw->fwh_dec_en1_off, | ||
262 | intel_rng_hw->fwh_dec_en1_val); | ||
223 | 263 | ||
224 | static void __init intel_init_wait(void *unused) | 264 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || |
265 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | ||
266 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | ||
267 | printk(KERN_ERR PFX "FWH not detected\n"); | ||
268 | return -ENODEV; | ||
269 | } | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, | ||
275 | struct pci_dev *dev) | ||
225 | { | 276 | { |
226 | while (waitflag) | 277 | intel_rng_hw->bios_cntl_val = 0xff; |
227 | cpu_relax(); | 278 | intel_rng_hw->fwh_dec_en1_val = 0xff; |
279 | intel_rng_hw->dev = dev; | ||
280 | |||
281 | /* Check for Intel 82802 */ | ||
282 | if (dev->device < 0x2640) { | ||
283 | intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; | ||
284 | intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD; | ||
285 | } else { | ||
286 | intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; | ||
287 | intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW; | ||
288 | } | ||
289 | |||
290 | pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off, | ||
291 | &intel_rng_hw->fwh_dec_en1_val); | ||
292 | pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off, | ||
293 | &intel_rng_hw->bios_cntl_val); | ||
294 | |||
295 | if ((intel_rng_hw->bios_cntl_val & | ||
296 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
297 | == BIOS_CNTL_LOCK_ENABLE_MASK) { | ||
298 | static __initdata /*const*/ char warning[] = | ||
299 | KERN_WARNING PFX "Firmware space is locked read-only. " | ||
300 | KERN_WARNING PFX "If you can't or\n don't want to " | ||
301 | KERN_WARNING PFX "disable this in firmware setup, and " | ||
302 | KERN_WARNING PFX "if\n you are certain that your " | ||
303 | KERN_WARNING PFX "system has a functional\n RNG, try" | ||
304 | KERN_WARNING PFX "using the 'no_fwh_detect' option.\n"; | ||
305 | |||
306 | if (no_fwh_detect) | ||
307 | return -ENODEV; | ||
308 | printk(warning); | ||
309 | return -EBUSY; | ||
310 | } | ||
311 | |||
312 | intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); | ||
313 | if (intel_rng_hw->mem == NULL) | ||
314 | return -EBUSY; | ||
315 | |||
316 | return 0; | ||
228 | } | 317 | } |
229 | #endif | 318 | |
230 | 319 | ||
231 | static int __init mod_init(void) | 320 | static int __init mod_init(void) |
232 | { | 321 | { |
233 | int err = -ENODEV; | 322 | int err = -ENODEV; |
234 | unsigned i; | 323 | int i; |
235 | struct pci_dev *dev = NULL; | 324 | struct pci_dev *dev = NULL; |
236 | void __iomem *mem; | 325 | void __iomem *mem = mem; |
237 | unsigned long flags; | 326 | u8 hw_status; |
238 | u8 bios_cntl_off, fwh_dec_en1_off; | 327 | struct intel_rng_hw *intel_rng_hw; |
239 | u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff; | ||
240 | u8 hw_status, mfc, dvc; | ||
241 | 328 | ||
242 | for (i = 0; !dev && pci_tbl[i].vendor; ++i) | 329 | for (i = 0; !dev && pci_tbl[i].vendor; ++i) |
243 | dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); | 330 | dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, |
331 | NULL); | ||
244 | 332 | ||
245 | if (!dev) | 333 | if (!dev) |
246 | goto out; /* Device not found. */ | 334 | goto out; /* Device not found. */ |
@@ -250,39 +338,18 @@ static int __init mod_init(void) | |||
250 | goto fwh_done; | 338 | goto fwh_done; |
251 | } | 339 | } |
252 | 340 | ||
253 | /* Check for Intel 82802 */ | 341 | intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); |
254 | if (dev->device < 0x2640) { | 342 | if (!intel_rng_hw) { |
255 | fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; | ||
256 | bios_cntl_off = BIOS_CNTL_REG_OLD; | ||
257 | } else { | ||
258 | fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; | ||
259 | bios_cntl_off = BIOS_CNTL_REG_NEW; | ||
260 | } | ||
261 | |||
262 | pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val); | ||
263 | pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val); | ||
264 | |||
265 | if ((bios_cntl_val & | ||
266 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
267 | == BIOS_CNTL_LOCK_ENABLE_MASK) { | ||
268 | static __initdata /*const*/ char warning[] = | ||
269 | KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" | ||
270 | KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" | ||
271 | KERN_WARNING PFX "you are certain that your system has a functional\n" | ||
272 | KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; | ||
273 | |||
274 | pci_dev_put(dev); | 343 | pci_dev_put(dev); |
275 | if (no_fwh_detect) | ||
276 | goto fwh_done; | ||
277 | printk(warning); | ||
278 | err = -EBUSY; | ||
279 | goto out; | 344 | goto out; |
280 | } | 345 | } |
281 | 346 | ||
282 | mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); | 347 | err = intel_init_hw_struct(intel_rng_hw, dev); |
283 | if (mem == NULL) { | 348 | if (err) { |
284 | pci_dev_put(dev); | 349 | pci_dev_put(dev); |
285 | err = -EBUSY; | 350 | kfree(intel_rng_hw); |
351 | if (err == -ENODEV) | ||
352 | goto fwh_done; | ||
286 | goto out; | 353 | goto out; |
287 | } | 354 | } |
288 | 355 | ||
@@ -290,59 +357,18 @@ static int __init mod_init(void) | |||
290 | * Since the BIOS code/data is going to disappear from its normal | 357 | * Since the BIOS code/data is going to disappear from its normal |
291 | * location with the Read ID command, all activity on the system | 358 | * location with the Read ID command, all activity on the system |
292 | * must be stopped until the state is back to normal. | 359 | * must be stopped until the state is back to normal. |
360 | * | ||
361 | * Use stop_machine_run because IPIs can be blocked by disabling | ||
362 | * interrupts. | ||
293 | */ | 363 | */ |
294 | #ifdef CONFIG_SMP | 364 | err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS); |
295 | set_mb(waitflag, 1); | ||
296 | if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) { | ||
297 | set_mb(waitflag, 0); | ||
298 | pci_dev_put(dev); | ||
299 | printk(KERN_ERR PFX "cannot run on all processors\n"); | ||
300 | err = -EAGAIN; | ||
301 | goto err_unmap; | ||
302 | } | ||
303 | #endif | ||
304 | local_irq_save(flags); | ||
305 | |||
306 | if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
307 | pci_write_config_byte(dev, | ||
308 | fwh_dec_en1_off, | ||
309 | fwh_dec_en1_val | FWH_F8_EN_MASK); | ||
310 | if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
311 | pci_write_config_byte(dev, | ||
312 | bios_cntl_off, | ||
313 | bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK); | ||
314 | |||
315 | writeb(INTEL_FWH_RESET_CMD, mem); | ||
316 | writeb(INTEL_FWH_READ_ID_CMD, mem); | ||
317 | mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); | ||
318 | dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS); | ||
319 | writeb(INTEL_FWH_RESET_CMD, mem); | ||
320 | |||
321 | if (!(bios_cntl_val & | ||
322 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) | ||
323 | pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val); | ||
324 | if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
325 | pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val); | ||
326 | |||
327 | local_irq_restore(flags); | ||
328 | #ifdef CONFIG_SMP | ||
329 | /* Tell other CPUs to resume. */ | ||
330 | set_mb(waitflag, 0); | ||
331 | #endif | ||
332 | |||
333 | iounmap(mem); | ||
334 | pci_dev_put(dev); | 365 | pci_dev_put(dev); |
335 | 366 | iounmap(intel_rng_hw->mem); | |
336 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || | 367 | kfree(intel_rng_hw); |
337 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | 368 | if (err) |
338 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | ||
339 | printk(KERN_ERR PFX "FWH not detected\n"); | ||
340 | err = -ENODEV; | ||
341 | goto out; | 369 | goto out; |
342 | } | ||
343 | 370 | ||
344 | fwh_done: | 371 | fwh_done: |
345 | |||
346 | err = -ENOMEM; | 372 | err = -ENOMEM; |
347 | mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); | 373 | mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); |
348 | if (!mem) | 374 | if (!mem) |
@@ -352,22 +378,21 @@ fwh_done: | |||
352 | /* Check for Random Number Generator */ | 378 | /* Check for Random Number Generator */ |
353 | err = -ENODEV; | 379 | err = -ENODEV; |
354 | hw_status = hwstatus_get(mem); | 380 | hw_status = hwstatus_get(mem); |
355 | if ((hw_status & INTEL_RNG_PRESENT) == 0) | 381 | if ((hw_status & INTEL_RNG_PRESENT) == 0) { |
356 | goto err_unmap; | 382 | iounmap(mem); |
383 | goto out; | ||
384 | } | ||
357 | 385 | ||
358 | printk(KERN_INFO "Intel 82802 RNG detected\n"); | 386 | printk(KERN_INFO "Intel 82802 RNG detected\n"); |
359 | err = hwrng_register(&intel_rng); | 387 | err = hwrng_register(&intel_rng); |
360 | if (err) { | 388 | if (err) { |
361 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 389 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
362 | err); | 390 | err); |
363 | goto err_unmap; | 391 | iounmap(mem); |
364 | } | 392 | } |
365 | out: | 393 | out: |
366 | return err; | 394 | return err; |
367 | 395 | ||
368 | err_unmap: | ||
369 | iounmap(mem); | ||
370 | goto out; | ||
371 | } | 396 | } |
372 | 397 | ||
373 | static void __exit mod_exit(void) | 398 | static void __exit mod_exit(void) |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 353d9f3cf8d7..0289705967de 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/proc_fs.h> | 22 | #include <linux/proc_fs.h> |
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/capability.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | 28 | ||
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index a48da02aad2f..932264a657d0 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/smp_lock.h> | ||
39 | 38 | ||
40 | #include <asm/m48t35.h> | 39 | #include <asm/m48t35.h> |
41 | #include <asm/sn/ioc3.h> | 40 | #include <asm/sn/ioc3.h> |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e22146546add..6c5d15de3317 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * source@mvista.com | 9 | * source@mvista.com |
10 | * | 10 | * |
11 | * Copyright 2002 MontaVista Software Inc. | 11 | * Copyright 2002 MontaVista Software Inc. |
12 | * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com> | ||
12 | * | 13 | * |
13 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
14 | * under the terms of the GNU General Public License as published by the | 15 | * under the terms of the GNU General Public License as published by the |
@@ -64,6 +65,11 @@ | |||
64 | #include <linux/string.h> | 65 | #include <linux/string.h> |
65 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
66 | 67 | ||
68 | #ifdef CONFIG_PPC_OF | ||
69 | #include <asm/of_device.h> | ||
70 | #include <asm/of_platform.h> | ||
71 | #endif | ||
72 | |||
67 | #define PFX "ipmi_si: " | 73 | #define PFX "ipmi_si: " |
68 | 74 | ||
69 | /* Measure times between events in the driver. */ | 75 | /* Measure times between events in the driver. */ |
@@ -76,6 +82,12 @@ | |||
76 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a | 82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a |
77 | short timeout */ | 83 | short timeout */ |
78 | 84 | ||
85 | /* Bit for BMC global enables. */ | ||
86 | #define IPMI_BMC_RCV_MSG_INTR 0x01 | ||
87 | #define IPMI_BMC_EVT_MSG_INTR 0x02 | ||
88 | #define IPMI_BMC_EVT_MSG_BUFF 0x04 | ||
89 | #define IPMI_BMC_SYS_LOG 0x08 | ||
90 | |||
79 | enum si_intf_state { | 91 | enum si_intf_state { |
80 | SI_NORMAL, | 92 | SI_NORMAL, |
81 | SI_GETTING_FLAGS, | 93 | SI_GETTING_FLAGS, |
@@ -84,7 +96,9 @@ enum si_intf_state { | |||
84 | SI_CLEARING_FLAGS_THEN_SET_IRQ, | 96 | SI_CLEARING_FLAGS_THEN_SET_IRQ, |
85 | SI_GETTING_MESSAGES, | 97 | SI_GETTING_MESSAGES, |
86 | SI_ENABLE_INTERRUPTS1, | 98 | SI_ENABLE_INTERRUPTS1, |
87 | SI_ENABLE_INTERRUPTS2 | 99 | SI_ENABLE_INTERRUPTS2, |
100 | SI_DISABLE_INTERRUPTS1, | ||
101 | SI_DISABLE_INTERRUPTS2 | ||
88 | /* FIXME - add watchdog stuff. */ | 102 | /* FIXME - add watchdog stuff. */ |
89 | }; | 103 | }; |
90 | 104 | ||
@@ -333,6 +347,17 @@ static void start_enable_irq(struct smi_info *smi_info) | |||
333 | smi_info->si_state = SI_ENABLE_INTERRUPTS1; | 347 | smi_info->si_state = SI_ENABLE_INTERRUPTS1; |
334 | } | 348 | } |
335 | 349 | ||
350 | static void start_disable_irq(struct smi_info *smi_info) | ||
351 | { | ||
352 | unsigned char msg[2]; | ||
353 | |||
354 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
355 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | ||
356 | |||
357 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
358 | smi_info->si_state = SI_DISABLE_INTERRUPTS1; | ||
359 | } | ||
360 | |||
336 | static void start_clear_flags(struct smi_info *smi_info) | 361 | static void start_clear_flags(struct smi_info *smi_info) |
337 | { | 362 | { |
338 | unsigned char msg[3]; | 363 | unsigned char msg[3]; |
@@ -353,7 +378,7 @@ static void start_clear_flags(struct smi_info *smi_info) | |||
353 | static inline void disable_si_irq(struct smi_info *smi_info) | 378 | static inline void disable_si_irq(struct smi_info *smi_info) |
354 | { | 379 | { |
355 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 380 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
356 | disable_irq_nosync(smi_info->irq); | 381 | start_disable_irq(smi_info); |
357 | smi_info->interrupt_disabled = 1; | 382 | smi_info->interrupt_disabled = 1; |
358 | } | 383 | } |
359 | } | 384 | } |
@@ -361,7 +386,7 @@ static inline void disable_si_irq(struct smi_info *smi_info) | |||
361 | static inline void enable_si_irq(struct smi_info *smi_info) | 386 | static inline void enable_si_irq(struct smi_info *smi_info) |
362 | { | 387 | { |
363 | if ((smi_info->irq) && (smi_info->interrupt_disabled)) { | 388 | if ((smi_info->irq) && (smi_info->interrupt_disabled)) { |
364 | enable_irq(smi_info->irq); | 389 | start_enable_irq(smi_info); |
365 | smi_info->interrupt_disabled = 0; | 390 | smi_info->interrupt_disabled = 0; |
366 | } | 391 | } |
367 | } | 392 | } |
@@ -583,7 +608,9 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
583 | } else { | 608 | } else { |
584 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 609 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
585 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | 610 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; |
586 | msg[2] = msg[3] | 1; /* enable msg queue int */ | 611 | msg[2] = (msg[3] | |
612 | IPMI_BMC_RCV_MSG_INTR | | ||
613 | IPMI_BMC_EVT_MSG_INTR); | ||
587 | smi_info->handlers->start_transaction( | 614 | smi_info->handlers->start_transaction( |
588 | smi_info->si_sm, msg, 3); | 615 | smi_info->si_sm, msg, 3); |
589 | smi_info->si_state = SI_ENABLE_INTERRUPTS2; | 616 | smi_info->si_state = SI_ENABLE_INTERRUPTS2; |
@@ -605,6 +632,45 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
605 | smi_info->si_state = SI_NORMAL; | 632 | smi_info->si_state = SI_NORMAL; |
606 | break; | 633 | break; |
607 | } | 634 | } |
635 | |||
636 | case SI_DISABLE_INTERRUPTS1: | ||
637 | { | ||
638 | unsigned char msg[4]; | ||
639 | |||
640 | /* We got the flags from the SMI, now handle them. */ | ||
641 | smi_info->handlers->get_result(smi_info->si_sm, msg, 4); | ||
642 | if (msg[2] != 0) { | ||
643 | printk(KERN_WARNING | ||
644 | "ipmi_si: Could not disable interrupts" | ||
645 | ", failed get.\n"); | ||
646 | smi_info->si_state = SI_NORMAL; | ||
647 | } else { | ||
648 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
649 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | ||
650 | msg[2] = (msg[3] & | ||
651 | ~(IPMI_BMC_RCV_MSG_INTR | | ||
652 | IPMI_BMC_EVT_MSG_INTR)); | ||
653 | smi_info->handlers->start_transaction( | ||
654 | smi_info->si_sm, msg, 3); | ||
655 | smi_info->si_state = SI_DISABLE_INTERRUPTS2; | ||
656 | } | ||
657 | break; | ||
658 | } | ||
659 | |||
660 | case SI_DISABLE_INTERRUPTS2: | ||
661 | { | ||
662 | unsigned char msg[4]; | ||
663 | |||
664 | /* We got the flags from the SMI, now handle them. */ | ||
665 | smi_info->handlers->get_result(smi_info->si_sm, msg, 4); | ||
666 | if (msg[2] != 0) { | ||
667 | printk(KERN_WARNING | ||
668 | "ipmi_si: Could not disable interrupts" | ||
669 | ", failed set.\n"); | ||
670 | } | ||
671 | smi_info->si_state = SI_NORMAL; | ||
672 | break; | ||
673 | } | ||
608 | } | 674 | } |
609 | } | 675 | } |
610 | 676 | ||
@@ -858,9 +924,6 @@ static void smi_timeout(unsigned long data) | |||
858 | struct timeval t; | 924 | struct timeval t; |
859 | #endif | 925 | #endif |
860 | 926 | ||
861 | if (atomic_read(&smi_info->stop_operation)) | ||
862 | return; | ||
863 | |||
864 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 927 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
865 | #ifdef DEBUG_TIMING | 928 | #ifdef DEBUG_TIMING |
866 | do_gettimeofday(&t); | 929 | do_gettimeofday(&t); |
@@ -916,15 +979,11 @@ static irqreturn_t si_irq_handler(int irq, void *data) | |||
916 | smi_info->interrupts++; | 979 | smi_info->interrupts++; |
917 | spin_unlock(&smi_info->count_lock); | 980 | spin_unlock(&smi_info->count_lock); |
918 | 981 | ||
919 | if (atomic_read(&smi_info->stop_operation)) | ||
920 | goto out; | ||
921 | |||
922 | #ifdef DEBUG_TIMING | 982 | #ifdef DEBUG_TIMING |
923 | do_gettimeofday(&t); | 983 | do_gettimeofday(&t); |
924 | printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 984 | printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
925 | #endif | 985 | #endif |
926 | smi_event_handler(smi_info, 0); | 986 | smi_event_handler(smi_info, 0); |
927 | out: | ||
928 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 987 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
929 | return IRQ_HANDLED; | 988 | return IRQ_HANDLED; |
930 | } | 989 | } |
@@ -1006,6 +1065,7 @@ static DEFINE_MUTEX(smi_infos_lock); | |||
1006 | static int smi_num; /* Used to sequence the SMIs */ | 1065 | static int smi_num; /* Used to sequence the SMIs */ |
1007 | 1066 | ||
1008 | #define DEFAULT_REGSPACING 1 | 1067 | #define DEFAULT_REGSPACING 1 |
1068 | #define DEFAULT_REGSIZE 1 | ||
1009 | 1069 | ||
1010 | static int si_trydefaults = 1; | 1070 | static int si_trydefaults = 1; |
1011 | static char *si_type[SI_MAX_PARMS]; | 1071 | static char *si_type[SI_MAX_PARMS]; |
@@ -1111,7 +1171,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1111 | if (info->si_type == SI_BT) { | 1171 | if (info->si_type == SI_BT) { |
1112 | rv = request_irq(info->irq, | 1172 | rv = request_irq(info->irq, |
1113 | si_bt_irq_handler, | 1173 | si_bt_irq_handler, |
1114 | IRQF_DISABLED, | 1174 | IRQF_SHARED | IRQF_DISABLED, |
1115 | DEVICE_NAME, | 1175 | DEVICE_NAME, |
1116 | info); | 1176 | info); |
1117 | if (!rv) | 1177 | if (!rv) |
@@ -1121,7 +1181,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1121 | } else | 1181 | } else |
1122 | rv = request_irq(info->irq, | 1182 | rv = request_irq(info->irq, |
1123 | si_irq_handler, | 1183 | si_irq_handler, |
1124 | IRQF_DISABLED, | 1184 | IRQF_SHARED | IRQF_DISABLED, |
1125 | DEVICE_NAME, | 1185 | DEVICE_NAME, |
1126 | info); | 1186 | info); |
1127 | if (rv) { | 1187 | if (rv) { |
@@ -1701,15 +1761,11 @@ static u32 ipmi_acpi_gpe(void *context) | |||
1701 | smi_info->interrupts++; | 1761 | smi_info->interrupts++; |
1702 | spin_unlock(&smi_info->count_lock); | 1762 | spin_unlock(&smi_info->count_lock); |
1703 | 1763 | ||
1704 | if (atomic_read(&smi_info->stop_operation)) | ||
1705 | goto out; | ||
1706 | |||
1707 | #ifdef DEBUG_TIMING | 1764 | #ifdef DEBUG_TIMING |
1708 | do_gettimeofday(&t); | 1765 | do_gettimeofday(&t); |
1709 | printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 1766 | printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
1710 | #endif | 1767 | #endif |
1711 | smi_event_handler(smi_info, 0); | 1768 | smi_event_handler(smi_info, 0); |
1712 | out: | ||
1713 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 1769 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
1714 | 1770 | ||
1715 | return ACPI_INTERRUPT_HANDLED; | 1771 | return ACPI_INTERRUPT_HANDLED; |
@@ -2133,12 +2189,15 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2133 | info->irq_setup = std_irq_setup; | 2189 | info->irq_setup = std_irq_setup; |
2134 | 2190 | ||
2135 | info->dev = &pdev->dev; | 2191 | info->dev = &pdev->dev; |
2192 | pci_set_drvdata(pdev, info); | ||
2136 | 2193 | ||
2137 | return try_smi_init(info); | 2194 | return try_smi_init(info); |
2138 | } | 2195 | } |
2139 | 2196 | ||
2140 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) | 2197 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) |
2141 | { | 2198 | { |
2199 | struct smi_info *info = pci_get_drvdata(pdev); | ||
2200 | cleanup_one_si(info); | ||
2142 | } | 2201 | } |
2143 | 2202 | ||
2144 | #ifdef CONFIG_PM | 2203 | #ifdef CONFIG_PM |
@@ -2172,6 +2231,99 @@ static struct pci_driver ipmi_pci_driver = { | |||
2172 | #endif /* CONFIG_PCI */ | 2231 | #endif /* CONFIG_PCI */ |
2173 | 2232 | ||
2174 | 2233 | ||
2234 | #ifdef CONFIG_PPC_OF | ||
2235 | static int __devinit ipmi_of_probe(struct of_device *dev, | ||
2236 | const struct of_device_id *match) | ||
2237 | { | ||
2238 | struct smi_info *info; | ||
2239 | struct resource resource; | ||
2240 | const int *regsize, *regspacing, *regshift; | ||
2241 | struct device_node *np = dev->node; | ||
2242 | int ret; | ||
2243 | int proplen; | ||
2244 | |||
2245 | dev_info(&dev->dev, PFX "probing via device tree\n"); | ||
2246 | |||
2247 | ret = of_address_to_resource(np, 0, &resource); | ||
2248 | if (ret) { | ||
2249 | dev_warn(&dev->dev, PFX "invalid address from OF\n"); | ||
2250 | return ret; | ||
2251 | } | ||
2252 | |||
2253 | regsize = get_property(np, "reg-size", &proplen); | ||
2254 | if (regsize && proplen != 4) { | ||
2255 | dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); | ||
2256 | return -EINVAL; | ||
2257 | } | ||
2258 | |||
2259 | regspacing = get_property(np, "reg-spacing", &proplen); | ||
2260 | if (regspacing && proplen != 4) { | ||
2261 | dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); | ||
2262 | return -EINVAL; | ||
2263 | } | ||
2264 | |||
2265 | regshift = get_property(np, "reg-shift", &proplen); | ||
2266 | if (regshift && proplen != 4) { | ||
2267 | dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); | ||
2268 | return -EINVAL; | ||
2269 | } | ||
2270 | |||
2271 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2272 | |||
2273 | if (!info) { | ||
2274 | dev_err(&dev->dev, | ||
2275 | PFX "could not allocate memory for OF probe\n"); | ||
2276 | return -ENOMEM; | ||
2277 | } | ||
2278 | |||
2279 | info->si_type = (enum si_type) match->data; | ||
2280 | info->addr_source = "device-tree"; | ||
2281 | info->io_setup = mem_setup; | ||
2282 | info->irq_setup = std_irq_setup; | ||
2283 | |||
2284 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2285 | info->io.addr_data = resource.start; | ||
2286 | |||
2287 | info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE; | ||
2288 | info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; | ||
2289 | info->io.regshift = regshift ? *regshift : 0; | ||
2290 | |||
2291 | info->irq = irq_of_parse_and_map(dev->node, 0); | ||
2292 | info->dev = &dev->dev; | ||
2293 | |||
2294 | dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", | ||
2295 | info->io.addr_data, info->io.regsize, info->io.regspacing, | ||
2296 | info->irq); | ||
2297 | |||
2298 | dev->dev.driver_data = (void*) info; | ||
2299 | |||
2300 | return try_smi_init(info); | ||
2301 | } | ||
2302 | |||
2303 | static int __devexit ipmi_of_remove(struct of_device *dev) | ||
2304 | { | ||
2305 | cleanup_one_si(dev->dev.driver_data); | ||
2306 | return 0; | ||
2307 | } | ||
2308 | |||
2309 | static struct of_device_id ipmi_match[] = | ||
2310 | { | ||
2311 | { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS }, | ||
2312 | { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC }, | ||
2313 | { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT }, | ||
2314 | {}, | ||
2315 | }; | ||
2316 | |||
2317 | static struct of_platform_driver ipmi_of_platform_driver = | ||
2318 | { | ||
2319 | .name = "ipmi", | ||
2320 | .match_table = ipmi_match, | ||
2321 | .probe = ipmi_of_probe, | ||
2322 | .remove = __devexit_p(ipmi_of_remove), | ||
2323 | }; | ||
2324 | #endif /* CONFIG_PPC_OF */ | ||
2325 | |||
2326 | |||
2175 | static int try_get_dev_id(struct smi_info *smi_info) | 2327 | static int try_get_dev_id(struct smi_info *smi_info) |
2176 | { | 2328 | { |
2177 | unsigned char msg[2]; | 2329 | unsigned char msg[2]; |
@@ -2801,6 +2953,10 @@ static __devinit int init_ipmi_si(void) | |||
2801 | } | 2953 | } |
2802 | #endif | 2954 | #endif |
2803 | 2955 | ||
2956 | #ifdef CONFIG_PPC_OF | ||
2957 | of_register_platform_driver(&ipmi_of_platform_driver); | ||
2958 | #endif | ||
2959 | |||
2804 | if (si_trydefaults) { | 2960 | if (si_trydefaults) { |
2805 | mutex_lock(&smi_infos_lock); | 2961 | mutex_lock(&smi_infos_lock); |
2806 | if (list_empty(&smi_infos)) { | 2962 | if (list_empty(&smi_infos)) { |
@@ -2838,28 +2994,33 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
2838 | 2994 | ||
2839 | list_del(&to_clean->link); | 2995 | list_del(&to_clean->link); |
2840 | 2996 | ||
2841 | /* Tell the timer and interrupt handlers that we are shutting | 2997 | /* Tell the driver that we are shutting down. */ |
2842 | down. */ | ||
2843 | spin_lock_irqsave(&(to_clean->si_lock), flags); | ||
2844 | spin_lock(&(to_clean->msg_lock)); | ||
2845 | |||
2846 | atomic_inc(&to_clean->stop_operation); | 2998 | atomic_inc(&to_clean->stop_operation); |
2847 | 2999 | ||
2848 | if (to_clean->irq_cleanup) | 3000 | /* Make sure the timer and thread are stopped and will not run |
2849 | to_clean->irq_cleanup(to_clean); | 3001 | again. */ |
2850 | |||
2851 | spin_unlock(&(to_clean->msg_lock)); | ||
2852 | spin_unlock_irqrestore(&(to_clean->si_lock), flags); | ||
2853 | |||
2854 | /* Wait until we know that we are out of any interrupt | ||
2855 | handlers might have been running before we freed the | ||
2856 | interrupt. */ | ||
2857 | synchronize_sched(); | ||
2858 | |||
2859 | wait_for_timer_and_thread(to_clean); | 3002 | wait_for_timer_and_thread(to_clean); |
2860 | 3003 | ||
2861 | /* Interrupts and timeouts are stopped, now make sure the | 3004 | /* Timeouts are stopped, now make sure the interrupts are off |
2862 | interface is in a clean state. */ | 3005 | for the device. A little tricky with locks to make sure |
3006 | there are no races. */ | ||
3007 | spin_lock_irqsave(&to_clean->si_lock, flags); | ||
3008 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | ||
3009 | spin_unlock_irqrestore(&to_clean->si_lock, flags); | ||
3010 | poll(to_clean); | ||
3011 | schedule_timeout_uninterruptible(1); | ||
3012 | spin_lock_irqsave(&to_clean->si_lock, flags); | ||
3013 | } | ||
3014 | disable_si_irq(to_clean); | ||
3015 | spin_unlock_irqrestore(&to_clean->si_lock, flags); | ||
3016 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | ||
3017 | poll(to_clean); | ||
3018 | schedule_timeout_uninterruptible(1); | ||
3019 | } | ||
3020 | |||
3021 | /* Clean up interrupts and make sure that everything is done. */ | ||
3022 | if (to_clean->irq_cleanup) | ||
3023 | to_clean->irq_cleanup(to_clean); | ||
2863 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | 3024 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
2864 | poll(to_clean); | 3025 | poll(to_clean); |
2865 | schedule_timeout_uninterruptible(1); | 3026 | schedule_timeout_uninterruptible(1); |
@@ -2898,6 +3059,10 @@ static __exit void cleanup_ipmi_si(void) | |||
2898 | pci_unregister_driver(&ipmi_pci_driver); | 3059 | pci_unregister_driver(&ipmi_pci_driver); |
2899 | #endif | 3060 | #endif |
2900 | 3061 | ||
3062 | #ifdef CONFIG_PPC_OF | ||
3063 | of_unregister_platform_driver(&ipmi_of_platform_driver); | ||
3064 | #endif | ||
3065 | |||
2901 | mutex_lock(&smi_infos_lock); | 3066 | mutex_lock(&smi_infos_lock); |
2902 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) | 3067 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) |
2903 | cleanup_one_si(e); | 3068 | cleanup_one_si(e); |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 6b634e8d9519..147c12047cf3 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/completion.h> | 41 | #include <linux/completion.h> |
42 | #include <linux/kdebug.h> | ||
42 | #include <linux/rwsem.h> | 43 | #include <linux/rwsem.h> |
43 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -49,9 +50,18 @@ | |||
49 | #include <linux/poll.h> | 50 | #include <linux/poll.h> |
50 | #include <linux/string.h> | 51 | #include <linux/string.h> |
51 | #include <linux/ctype.h> | 52 | #include <linux/ctype.h> |
53 | #include <linux/delay.h> | ||
52 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
53 | #ifdef CONFIG_X86_LOCAL_APIC | 55 | |
54 | #include <asm/apic.h> | 56 | #ifdef CONFIG_X86 |
57 | /* This is ugly, but I've determined that x86 is the only architecture | ||
58 | that can reasonably support the IPMI NMI watchdog timeout at this | ||
59 | time. If another architecture adds this capability somehow, it | ||
60 | will have to be a somewhat different mechanism and I have no idea | ||
61 | how it will work. So in the unlikely event that another | ||
62 | architecture supports this, we can figure out a good generic | ||
63 | mechanism for it at that time. */ | ||
64 | #define HAVE_DIE_NMI_POST | ||
55 | #endif | 65 | #endif |
56 | 66 | ||
57 | #define PFX "IPMI Watchdog: " | 67 | #define PFX "IPMI Watchdog: " |
@@ -317,6 +327,11 @@ static unsigned char ipmi_version_minor; | |||
317 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ | 327 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ |
318 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); | 328 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); |
319 | 329 | ||
330 | #ifdef HAVE_DIE_NMI_POST | ||
331 | static int testing_nmi; | ||
332 | static int nmi_handler_registered; | ||
333 | #endif | ||
334 | |||
320 | static int ipmi_heartbeat(void); | 335 | static int ipmi_heartbeat(void); |
321 | static void panic_halt_ipmi_heartbeat(void); | 336 | static void panic_halt_ipmi_heartbeat(void); |
322 | 337 | ||
@@ -358,6 +373,10 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
358 | int hbnow = 0; | 373 | int hbnow = 0; |
359 | 374 | ||
360 | 375 | ||
376 | /* These can be cleared as we are setting the timeout. */ | ||
377 | ipmi_start_timer_on_heartbeat = 0; | ||
378 | pretimeout_since_last_heartbeat = 0; | ||
379 | |||
361 | data[0] = 0; | 380 | data[0] = 0; |
362 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 381 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
363 | 382 | ||
@@ -432,13 +451,12 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
432 | 451 | ||
433 | wait_for_completion(&set_timeout_wait); | 452 | wait_for_completion(&set_timeout_wait); |
434 | 453 | ||
454 | mutex_unlock(&set_timeout_lock); | ||
455 | |||
435 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | 456 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) |
436 | || ((send_heartbeat_now) | 457 | || ((send_heartbeat_now) |
437 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | 458 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) |
438 | { | ||
439 | rv = ipmi_heartbeat(); | 459 | rv = ipmi_heartbeat(); |
440 | } | ||
441 | mutex_unlock(&set_timeout_lock); | ||
442 | 460 | ||
443 | out: | 461 | out: |
444 | return rv; | 462 | return rv; |
@@ -518,12 +536,10 @@ static int ipmi_heartbeat(void) | |||
518 | int rv; | 536 | int rv; |
519 | struct ipmi_system_interface_addr addr; | 537 | struct ipmi_system_interface_addr addr; |
520 | 538 | ||
521 | if (ipmi_ignore_heartbeat) { | 539 | if (ipmi_ignore_heartbeat) |
522 | return 0; | 540 | return 0; |
523 | } | ||
524 | 541 | ||
525 | if (ipmi_start_timer_on_heartbeat) { | 542 | if (ipmi_start_timer_on_heartbeat) { |
526 | ipmi_start_timer_on_heartbeat = 0; | ||
527 | ipmi_watchdog_state = action_val; | 543 | ipmi_watchdog_state = action_val; |
528 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 544 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
529 | } else if (pretimeout_since_last_heartbeat) { | 545 | } else if (pretimeout_since_last_heartbeat) { |
@@ -531,7 +547,6 @@ static int ipmi_heartbeat(void) | |||
531 | We don't want to set the action, though, we want to | 547 | We don't want to set the action, though, we want to |
532 | leave that alone (thus it can't be combined with the | 548 | leave that alone (thus it can't be combined with the |
533 | above operation. */ | 549 | above operation. */ |
534 | pretimeout_since_last_heartbeat = 0; | ||
535 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 550 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
536 | } | 551 | } |
537 | 552 | ||
@@ -919,6 +934,45 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
919 | printk(KERN_CRIT PFX "Unable to register misc device\n"); | 934 | printk(KERN_CRIT PFX "Unable to register misc device\n"); |
920 | } | 935 | } |
921 | 936 | ||
937 | #ifdef HAVE_DIE_NMI_POST | ||
938 | if (nmi_handler_registered) { | ||
939 | int old_pretimeout = pretimeout; | ||
940 | int old_timeout = timeout; | ||
941 | int old_preop_val = preop_val; | ||
942 | |||
943 | /* Set the pretimeout to go off in a second and give | ||
944 | ourselves plenty of time to stop the timer. */ | ||
945 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | ||
946 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | ||
947 | pretimeout = 99; | ||
948 | timeout = 100; | ||
949 | |||
950 | testing_nmi = 1; | ||
951 | |||
952 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | ||
953 | if (rv) { | ||
954 | printk(KERN_WARNING PFX "Error starting timer to" | ||
955 | " test NMI: 0x%x. The NMI pretimeout will" | ||
956 | " likely not work\n", rv); | ||
957 | rv = 0; | ||
958 | goto out_restore; | ||
959 | } | ||
960 | |||
961 | msleep(1500); | ||
962 | |||
963 | if (testing_nmi != 2) { | ||
964 | printk(KERN_WARNING PFX "IPMI NMI didn't seem to" | ||
965 | " occur. The NMI pretimeout will" | ||
966 | " likely not work\n"); | ||
967 | } | ||
968 | out_restore: | ||
969 | testing_nmi = 0; | ||
970 | preop_val = old_preop_val; | ||
971 | pretimeout = old_pretimeout; | ||
972 | timeout = old_timeout; | ||
973 | } | ||
974 | #endif | ||
975 | |||
922 | out: | 976 | out: |
923 | up_write(®ister_sem); | 977 | up_write(®ister_sem); |
924 | 978 | ||
@@ -928,6 +982,10 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
928 | ipmi_watchdog_state = action_val; | 982 | ipmi_watchdog_state = action_val; |
929 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 983 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
930 | printk(KERN_INFO PFX "Starting now!\n"); | 984 | printk(KERN_INFO PFX "Starting now!\n"); |
985 | } else { | ||
986 | /* Stop the timer now. */ | ||
987 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | ||
988 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | ||
931 | } | 989 | } |
932 | } | 990 | } |
933 | 991 | ||
@@ -964,17 +1022,28 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
964 | up_write(®ister_sem); | 1022 | up_write(®ister_sem); |
965 | } | 1023 | } |
966 | 1024 | ||
967 | #ifdef HAVE_NMI_HANDLER | 1025 | #ifdef HAVE_DIE_NMI_POST |
968 | static int | 1026 | static int |
969 | ipmi_nmi(void *dev_id, int cpu, int handled) | 1027 | ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) |
970 | { | 1028 | { |
1029 | if (val != DIE_NMI_POST) | ||
1030 | return NOTIFY_OK; | ||
1031 | |||
1032 | if (testing_nmi) { | ||
1033 | testing_nmi = 2; | ||
1034 | return NOTIFY_STOP; | ||
1035 | } | ||
1036 | |||
971 | /* If we are not expecting a timeout, ignore it. */ | 1037 | /* If we are not expecting a timeout, ignore it. */ |
972 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1038 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
973 | return NOTIFY_DONE; | 1039 | return NOTIFY_OK; |
1040 | |||
1041 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | ||
1042 | return NOTIFY_OK; | ||
974 | 1043 | ||
975 | /* If no one else handled the NMI, we assume it was the IPMI | 1044 | /* If no one else handled the NMI, we assume it was the IPMI |
976 | watchdog. */ | 1045 | watchdog. */ |
977 | if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { | 1046 | if (preop_val == WDOG_PREOP_PANIC) { |
978 | /* On some machines, the heartbeat will give | 1047 | /* On some machines, the heartbeat will give |
979 | an error and not work unless we re-enable | 1048 | an error and not work unless we re-enable |
980 | the timer. So do so. */ | 1049 | the timer. So do so. */ |
@@ -983,18 +1052,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled) | |||
983 | panic(PFX "pre-timeout"); | 1052 | panic(PFX "pre-timeout"); |
984 | } | 1053 | } |
985 | 1054 | ||
986 | return NOTIFY_DONE; | 1055 | return NOTIFY_STOP; |
987 | } | 1056 | } |
988 | 1057 | ||
989 | static struct nmi_handler ipmi_nmi_handler = | 1058 | static struct notifier_block ipmi_nmi_handler = { |
990 | { | 1059 | .notifier_call = ipmi_nmi |
991 | .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), | ||
992 | .dev_name = "ipmi_watchdog", | ||
993 | .dev_id = NULL, | ||
994 | .handler = ipmi_nmi, | ||
995 | .priority = 0, /* Call us last. */ | ||
996 | }; | 1060 | }; |
997 | int nmi_handler_registered; | ||
998 | #endif | 1061 | #endif |
999 | 1062 | ||
1000 | static int wdog_reboot_handler(struct notifier_block *this, | 1063 | static int wdog_reboot_handler(struct notifier_block *this, |
@@ -1111,7 +1174,7 @@ static int preaction_op(const char *inval, char *outval) | |||
1111 | preaction_val = WDOG_PRETIMEOUT_NONE; | 1174 | preaction_val = WDOG_PRETIMEOUT_NONE; |
1112 | else if (strcmp(inval, "pre_smi") == 0) | 1175 | else if (strcmp(inval, "pre_smi") == 0) |
1113 | preaction_val = WDOG_PRETIMEOUT_SMI; | 1176 | preaction_val = WDOG_PRETIMEOUT_SMI; |
1114 | #ifdef HAVE_NMI_HANDLER | 1177 | #ifdef HAVE_DIE_NMI_POST |
1115 | else if (strcmp(inval, "pre_nmi") == 0) | 1178 | else if (strcmp(inval, "pre_nmi") == 0) |
1116 | preaction_val = WDOG_PRETIMEOUT_NMI; | 1179 | preaction_val = WDOG_PRETIMEOUT_NMI; |
1117 | #endif | 1180 | #endif |
@@ -1145,7 +1208,7 @@ static int preop_op(const char *inval, char *outval) | |||
1145 | 1208 | ||
1146 | static void check_parms(void) | 1209 | static void check_parms(void) |
1147 | { | 1210 | { |
1148 | #ifdef HAVE_NMI_HANDLER | 1211 | #ifdef HAVE_DIE_NMI_POST |
1149 | int do_nmi = 0; | 1212 | int do_nmi = 0; |
1150 | int rv; | 1213 | int rv; |
1151 | 1214 | ||
@@ -1158,20 +1221,9 @@ static void check_parms(void) | |||
1158 | preop_op("preop_none", NULL); | 1221 | preop_op("preop_none", NULL); |
1159 | do_nmi = 0; | 1222 | do_nmi = 0; |
1160 | } | 1223 | } |
1161 | #ifdef CONFIG_X86_LOCAL_APIC | ||
1162 | if (nmi_watchdog == NMI_IO_APIC) { | ||
1163 | printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" | ||
1164 | " mode (value is %d), that is incompatible" | ||
1165 | " with using NMI in the IPMI watchdog." | ||
1166 | " Disabling IPMI nmi pretimeout.\n", | ||
1167 | nmi_watchdog); | ||
1168 | preaction_val = WDOG_PRETIMEOUT_NONE; | ||
1169 | do_nmi = 0; | ||
1170 | } | ||
1171 | #endif | ||
1172 | } | 1224 | } |
1173 | if (do_nmi && !nmi_handler_registered) { | 1225 | if (do_nmi && !nmi_handler_registered) { |
1174 | rv = request_nmi(&ipmi_nmi_handler); | 1226 | rv = register_die_notifier(&ipmi_nmi_handler); |
1175 | if (rv) { | 1227 | if (rv) { |
1176 | printk(KERN_WARNING PFX | 1228 | printk(KERN_WARNING PFX |
1177 | "Can't register nmi handler\n"); | 1229 | "Can't register nmi handler\n"); |
@@ -1179,7 +1231,7 @@ static void check_parms(void) | |||
1179 | } else | 1231 | } else |
1180 | nmi_handler_registered = 1; | 1232 | nmi_handler_registered = 1; |
1181 | } else if (!do_nmi && nmi_handler_registered) { | 1233 | } else if (!do_nmi && nmi_handler_registered) { |
1182 | release_nmi(&ipmi_nmi_handler); | 1234 | unregister_die_notifier(&ipmi_nmi_handler); |
1183 | nmi_handler_registered = 0; | 1235 | nmi_handler_registered = 0; |
1184 | } | 1236 | } |
1185 | #endif | 1237 | #endif |
@@ -1215,9 +1267,9 @@ static int __init ipmi_wdog_init(void) | |||
1215 | 1267 | ||
1216 | rv = ipmi_smi_watcher_register(&smi_watcher); | 1268 | rv = ipmi_smi_watcher_register(&smi_watcher); |
1217 | if (rv) { | 1269 | if (rv) { |
1218 | #ifdef HAVE_NMI_HANDLER | 1270 | #ifdef HAVE_DIE_NMI_POST |
1219 | if (preaction_val == WDOG_PRETIMEOUT_NMI) | 1271 | if (nmi_handler_registered) |
1220 | release_nmi(&ipmi_nmi_handler); | 1272 | unregister_die_notifier(&ipmi_nmi_handler); |
1221 | #endif | 1273 | #endif |
1222 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1274 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1223 | &wdog_panic_notifier); | 1275 | &wdog_panic_notifier); |
@@ -1236,9 +1288,9 @@ static void __exit ipmi_wdog_exit(void) | |||
1236 | ipmi_smi_watcher_unregister(&smi_watcher); | 1288 | ipmi_smi_watcher_unregister(&smi_watcher); |
1237 | ipmi_unregister_watchdog(watchdog_ifnum); | 1289 | ipmi_unregister_watchdog(watchdog_ifnum); |
1238 | 1290 | ||
1239 | #ifdef HAVE_NMI_HANDLER | 1291 | #ifdef HAVE_DIE_NMI_POST |
1240 | if (nmi_handler_registered) | 1292 | if (nmi_handler_registered) |
1241 | release_nmi(&ipmi_nmi_handler); | 1293 | unregister_die_notifier(&ipmi_nmi_handler); |
1242 | #endif | 1294 | #endif |
1243 | 1295 | ||
1244 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1296 | atomic_notifier_chain_unregister(&panic_notifier_list, |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 43ab9edc76f5..761f77740d67 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -137,11 +137,10 @@ | |||
137 | #define InterruptTheCard(base) outw(0, (base) + 0xc) | 137 | #define InterruptTheCard(base) outw(0, (base) + 0xc) |
138 | #define ClearInterrupt(base) inw((base) + 0x0a) | 138 | #define ClearInterrupt(base) inw((base) + 0x0a) |
139 | 139 | ||
140 | #define pr_dbg(str...) pr_debug("ISICOM: " str) | ||
140 | #ifdef DEBUG | 141 | #ifdef DEBUG |
141 | #define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str) | ||
142 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) | 142 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) |
143 | #else | 143 | #else |
144 | #define pr_dbg(str...) do { } while (0) | ||
145 | #define isicom_paranoia_check(a, b, c) 0 | 144 | #define isicom_paranoia_check(a, b, c) 0 |
146 | #endif | 145 | #endif |
147 | 146 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index c06e86ad1dab..1b094509b1d2 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -109,7 +109,7 @@ struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | |||
109 | static struct kbd_struct *kbd = kbd_table; | 109 | static struct kbd_struct *kbd = kbd_table; |
110 | 110 | ||
111 | struct vt_spawn_console vt_spawn_con = { | 111 | struct vt_spawn_console vt_spawn_con = { |
112 | .lock = SPIN_LOCK_UNLOCKED, | 112 | .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), |
113 | .pid = NULL, | 113 | .pid = NULL, |
114 | .sig = 0, | 114 | .sig = 0, |
115 | }; | 115 | }; |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index b51d08be0bcf..62051f8b0910 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -118,7 +118,6 @@ | |||
118 | #include <linux/kernel.h> | 118 | #include <linux/kernel.h> |
119 | #include <linux/major.h> | 119 | #include <linux/major.h> |
120 | #include <linux/sched.h> | 120 | #include <linux/sched.h> |
121 | #include <linux/smp_lock.h> | ||
122 | #include <linux/slab.h> | 121 | #include <linux/slab.h> |
123 | #include <linux/fcntl.h> | 122 | #include <linux/fcntl.h> |
124 | #include <linux/delay.h> | 123 | #include <linux/delay.h> |
@@ -139,9 +138,6 @@ | |||
139 | /* if you have more than 8 printers, remember to increase LP_NO */ | 138 | /* if you have more than 8 printers, remember to increase LP_NO */ |
140 | #define LP_NO 8 | 139 | #define LP_NO 8 |
141 | 140 | ||
142 | /* ROUND_UP macro from fs/select.c */ | ||
143 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) | ||
144 | |||
145 | static struct lp_struct lp_table[LP_NO]; | 141 | static struct lp_struct lp_table[LP_NO]; |
146 | 142 | ||
147 | static unsigned int lp_count = 0; | 143 | static unsigned int lp_count = 0; |
@@ -652,7 +648,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, | |||
652 | (par_timeout.tv_usec < 0)) { | 648 | (par_timeout.tv_usec < 0)) { |
653 | return -EINVAL; | 649 | return -EINVAL; |
654 | } | 650 | } |
655 | to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ); | 651 | to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ); |
656 | to_jiffies += par_timeout.tv_sec * (long) HZ; | 652 | to_jiffies += par_timeout.tv_sec * (long) HZ; |
657 | if (to_jiffies <= 0) { | 653 | if (to_jiffies <= 0) { |
658 | return -EINVAL; | 654 | return -EINVAL; |
@@ -803,7 +799,7 @@ static int lp_register(int nr, struct parport *port) | |||
803 | if (reset) | 799 | if (reset) |
804 | lp_reset(nr); | 800 | lp_reset(nr); |
805 | 801 | ||
806 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, | 802 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, |
807 | "lp%d", nr); | 803 | "lp%d", nr); |
808 | 804 | ||
809 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, | 805 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5f066963f171..cc9a9d0df979 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/raw.h> | 18 | #include <linux/raw.h> |
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
24 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
@@ -552,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
552 | return virtr + wrote; | 551 | return virtr + wrote; |
553 | } | 552 | } |
554 | 553 | ||
555 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 554 | #ifdef CONFIG_DEVPORT |
556 | static ssize_t read_port(struct file * file, char __user * buf, | 555 | static ssize_t read_port(struct file * file, char __user * buf, |
557 | size_t count, loff_t *ppos) | 556 | size_t count, loff_t *ppos) |
558 | { | 557 | { |
@@ -835,7 +834,7 @@ static const struct file_operations null_fops = { | |||
835 | .splice_write = splice_write_null, | 834 | .splice_write = splice_write_null, |
836 | }; | 835 | }; |
837 | 836 | ||
838 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 837 | #ifdef CONFIG_DEVPORT |
839 | static const struct file_operations port_fops = { | 838 | static const struct file_operations port_fops = { |
840 | .llseek = memory_lseek, | 839 | .llseek = memory_lseek, |
841 | .read = read_port, | 840 | .read = read_port, |
@@ -913,7 +912,7 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
913 | case 3: | 912 | case 3: |
914 | filp->f_op = &null_fops; | 913 | filp->f_op = &null_fops; |
915 | break; | 914 | break; |
916 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 915 | #ifdef CONFIG_DEVPORT |
917 | case 4: | 916 | case 4: |
918 | filp->f_op = &port_fops; | 917 | filp->f_op = &port_fops; |
919 | break; | 918 | break; |
@@ -960,7 +959,7 @@ static const struct { | |||
960 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, | 959 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, |
961 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, | 960 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, |
962 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, | 961 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, |
963 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 962 | #ifdef CONFIG_DEVPORT |
964 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, | 963 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, |
965 | #endif | 964 | #endif |
966 | {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, | 965 | {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 7e975f606924..4e6fb9651a16 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
42 | #include <linux/major.h> | 42 | #include <linux/major.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/mutex.h> | ||
44 | #include <linux/proc_fs.h> | 45 | #include <linux/proc_fs.h> |
45 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
46 | #include <linux/stat.h> | 47 | #include <linux/stat.h> |
@@ -53,7 +54,7 @@ | |||
53 | * Head entry for the doubly linked miscdevice list | 54 | * Head entry for the doubly linked miscdevice list |
54 | */ | 55 | */ |
55 | static LIST_HEAD(misc_list); | 56 | static LIST_HEAD(misc_list); |
56 | static DECLARE_MUTEX(misc_sem); | 57 | static DEFINE_MUTEX(misc_mtx); |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Assigned numbers, used for dynamic minors | 60 | * Assigned numbers, used for dynamic minors |
@@ -69,7 +70,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | |||
69 | struct miscdevice *p; | 70 | struct miscdevice *p; |
70 | loff_t off = 0; | 71 | loff_t off = 0; |
71 | 72 | ||
72 | down(&misc_sem); | 73 | mutex_lock(&misc_mtx); |
73 | list_for_each_entry(p, &misc_list, list) { | 74 | list_for_each_entry(p, &misc_list, list) { |
74 | if (*pos == off++) | 75 | if (*pos == off++) |
75 | return p; | 76 | return p; |
@@ -89,7 +90,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
89 | 90 | ||
90 | static void misc_seq_stop(struct seq_file *seq, void *v) | 91 | static void misc_seq_stop(struct seq_file *seq, void *v) |
91 | { | 92 | { |
92 | up(&misc_sem); | 93 | mutex_unlock(&misc_mtx); |
93 | } | 94 | } |
94 | 95 | ||
95 | static int misc_seq_show(struct seq_file *seq, void *v) | 96 | static int misc_seq_show(struct seq_file *seq, void *v) |
@@ -129,7 +130,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
129 | int err = -ENODEV; | 130 | int err = -ENODEV; |
130 | const struct file_operations *old_fops, *new_fops = NULL; | 131 | const struct file_operations *old_fops, *new_fops = NULL; |
131 | 132 | ||
132 | down(&misc_sem); | 133 | mutex_lock(&misc_mtx); |
133 | 134 | ||
134 | list_for_each_entry(c, &misc_list, list) { | 135 | list_for_each_entry(c, &misc_list, list) { |
135 | if (c->minor == minor) { | 136 | if (c->minor == minor) { |
@@ -139,9 +140,9 @@ static int misc_open(struct inode * inode, struct file * file) | |||
139 | } | 140 | } |
140 | 141 | ||
141 | if (!new_fops) { | 142 | if (!new_fops) { |
142 | up(&misc_sem); | 143 | mutex_unlock(&misc_mtx); |
143 | request_module("char-major-%d-%d", MISC_MAJOR, minor); | 144 | request_module("char-major-%d-%d", MISC_MAJOR, minor); |
144 | down(&misc_sem); | 145 | mutex_lock(&misc_mtx); |
145 | 146 | ||
146 | list_for_each_entry(c, &misc_list, list) { | 147 | list_for_each_entry(c, &misc_list, list) { |
147 | if (c->minor == minor) { | 148 | if (c->minor == minor) { |
@@ -165,7 +166,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
165 | } | 166 | } |
166 | fops_put(old_fops); | 167 | fops_put(old_fops); |
167 | fail: | 168 | fail: |
168 | up(&misc_sem); | 169 | mutex_unlock(&misc_mtx); |
169 | return err; | 170 | return err; |
170 | } | 171 | } |
171 | 172 | ||
@@ -201,10 +202,10 @@ int misc_register(struct miscdevice * misc) | |||
201 | 202 | ||
202 | INIT_LIST_HEAD(&misc->list); | 203 | INIT_LIST_HEAD(&misc->list); |
203 | 204 | ||
204 | down(&misc_sem); | 205 | mutex_lock(&misc_mtx); |
205 | list_for_each_entry(c, &misc_list, list) { | 206 | list_for_each_entry(c, &misc_list, list) { |
206 | if (c->minor == misc->minor) { | 207 | if (c->minor == misc->minor) { |
207 | up(&misc_sem); | 208 | mutex_unlock(&misc_mtx); |
208 | return -EBUSY; | 209 | return -EBUSY; |
209 | } | 210 | } |
210 | } | 211 | } |
@@ -215,7 +216,7 @@ int misc_register(struct miscdevice * misc) | |||
215 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) | 216 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) |
216 | break; | 217 | break; |
217 | if (i<0) { | 218 | if (i<0) { |
218 | up(&misc_sem); | 219 | mutex_unlock(&misc_mtx); |
219 | return -EBUSY; | 220 | return -EBUSY; |
220 | } | 221 | } |
221 | misc->minor = i; | 222 | misc->minor = i; |
@@ -238,7 +239,7 @@ int misc_register(struct miscdevice * misc) | |||
238 | */ | 239 | */ |
239 | list_add(&misc->list, &misc_list); | 240 | list_add(&misc->list, &misc_list); |
240 | out: | 241 | out: |
241 | up(&misc_sem); | 242 | mutex_unlock(&misc_mtx); |
242 | return err; | 243 | return err; |
243 | } | 244 | } |
244 | 245 | ||
@@ -259,13 +260,13 @@ int misc_deregister(struct miscdevice * misc) | |||
259 | if (list_empty(&misc->list)) | 260 | if (list_empty(&misc->list)) |
260 | return -EINVAL; | 261 | return -EINVAL; |
261 | 262 | ||
262 | down(&misc_sem); | 263 | mutex_lock(&misc_mtx); |
263 | list_del(&misc->list); | 264 | list_del(&misc->list); |
264 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 265 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
265 | if (i < DYNAMIC_MINORS && i>0) { | 266 | if (i < DYNAMIC_MINORS && i>0) { |
266 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 267 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); |
267 | } | 268 | } |
268 | up(&misc_sem); | 269 | mutex_unlock(&misc_mtx); |
269 | return 0; | 270 | return 0; |
270 | } | 271 | } |
271 | 272 | ||
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 7dbaee8d9402..e0d35c20c04f 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -1582,7 +1582,7 @@ copy: | |||
1582 | 1582 | ||
1583 | if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) | 1583 | if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) |
1584 | return -EFAULT; | 1584 | return -EFAULT; |
1585 | if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) | 1585 | if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0) |
1586 | return -EINVAL; | 1586 | return -EINVAL; |
1587 | 1587 | ||
1588 | switch(cmd) | 1588 | switch(cmd) |
@@ -2529,6 +2529,8 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) | |||
2529 | void __iomem *baseAddr; | 2529 | void __iomem *baseAddr; |
2530 | int i; | 2530 | int i; |
2531 | 2531 | ||
2532 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2533 | return -EINVAL; | ||
2532 | if(copy_from_user(moxaBuff, tmp, len)) | 2534 | if(copy_from_user(moxaBuff, tmp, len)) |
2533 | return -EFAULT; | 2535 | return -EFAULT; |
2534 | baseAddr = moxa_boards[cardno].basemem; | 2536 | baseAddr = moxa_boards[cardno].basemem; |
@@ -2576,7 +2578,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len) | |||
2576 | void __iomem *baseAddr; | 2578 | void __iomem *baseAddr; |
2577 | int i; | 2579 | int i; |
2578 | 2580 | ||
2579 | if(len > sizeof(moxaBuff)) | 2581 | if(len < 0 || len > sizeof(moxaBuff)) |
2580 | return -EINVAL; | 2582 | return -EINVAL; |
2581 | if(copy_from_user(moxaBuff, tmp, len)) | 2583 | if(copy_from_user(moxaBuff, tmp, len)) |
2582 | return -EFAULT; | 2584 | return -EFAULT; |
@@ -2596,6 +2598,8 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) | |||
2596 | void __iomem *baseAddr, *ofsAddr; | 2598 | void __iomem *baseAddr, *ofsAddr; |
2597 | int retval, port, i; | 2599 | int retval, port, i; |
2598 | 2600 | ||
2601 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2602 | return -EINVAL; | ||
2599 | if(copy_from_user(moxaBuff, tmp, len)) | 2603 | if(copy_from_user(moxaBuff, tmp, len)) |
2600 | return -EFAULT; | 2604 | return -EFAULT; |
2601 | baseAddr = moxa_boards[cardno].basemem; | 2605 | baseAddr = moxa_boards[cardno].basemem; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 80a01150b86c..5953a45d7e96 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/gfp.h> | 54 | #include <linux/gfp.h> |
55 | #include <linux/ioport.h> | 55 | #include <linux/ioport.h> |
56 | #include <linux/mm.h> | 56 | #include <linux/mm.h> |
57 | #include <linux/smp_lock.h> | ||
58 | #include <linux/delay.h> | 57 | #include <linux/delay.h> |
59 | #include <linux/pci.h> | 58 | #include <linux/pci.h> |
60 | 59 | ||
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index f7603b6aeb87..6cde448cd5b2 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/gfp.h> | 37 | #include <linux/gfp.h> |
38 | #include <linux/ioport.h> | 38 | #include <linux/ioport.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
43 | 42 | ||
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 65f2d3a96b85..14557a4822c0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -1088,13 +1088,13 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1088 | /* block until there is a message: */ | 1088 | /* block until there is a message: */ |
1089 | add_wait_queue(&pInfo->read_wait, &wait); | 1089 | add_wait_queue(&pInfo->read_wait, &wait); |
1090 | repeat: | 1090 | repeat: |
1091 | current->state = TASK_INTERRUPTIBLE; | 1091 | __set_current_state(TASK_INTERRUPTIBLE); |
1092 | pMsg = remove_msg(pInfo, pClient); | 1092 | pMsg = remove_msg(pInfo, pClient); |
1093 | if (!pMsg && !signal_pending(current)) { | 1093 | if (!pMsg && !signal_pending(current)) { |
1094 | schedule(); | 1094 | schedule(); |
1095 | goto repeat; | 1095 | goto repeat; |
1096 | } | 1096 | } |
1097 | current->state = TASK_RUNNING; | 1097 | __set_current_state(TASK_RUNNING); |
1098 | remove_wait_queue(&pInfo->read_wait, &wait); | 1098 | remove_wait_queue(&pInfo->read_wait, &wait); |
1099 | } | 1099 | } |
1100 | 1100 | ||
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 4abd1eff61d6..84ac64fc48a1 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <linux/poll.h> | 66 | #include <linux/poll.h> |
67 | #include <linux/major.h> | 67 | #include <linux/major.h> |
68 | #include <linux/ppdev.h> | 68 | #include <linux/ppdev.h> |
69 | #include <linux/smp_lock.h> | ||
70 | #include <linux/device.h> | 69 | #include <linux/device.h> |
71 | #include <asm/uaccess.h> | 70 | #include <asm/uaccess.h> |
72 | 71 | ||
@@ -752,7 +751,7 @@ static const struct file_operations pp_fops = { | |||
752 | 751 | ||
753 | static void pp_attach(struct parport *port) | 752 | static void pp_attach(struct parport *port) |
754 | { | 753 | { |
755 | device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), | 754 | device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), |
756 | "parport%d", port->number); | 755 | "parport%d", port->number); |
757 | } | 756 | } |
758 | 757 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 70145254fb9d..3494e3fc44bf 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -980,7 +980,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
980 | } | 980 | } |
981 | schedule(); | 981 | schedule(); |
982 | } | 982 | } |
983 | current->state = TASK_RUNNING; | 983 | __set_current_state(TASK_RUNNING); |
984 | remove_wait_queue(&port->open_wait, &wait); | 984 | remove_wait_queue(&port->open_wait, &wait); |
985 | if (!tty_hung_up_p(filp)) | 985 | if (!tty_hung_up_p(filp)) |
986 | port->count++; | 986 | port->count++; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 76357c855ce3..61a63da420c2 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -65,10 +65,6 @@ | |||
65 | 65 | ||
66 | /****** Kernel includes ******/ | 66 | /****** Kernel includes ******/ |
67 | 67 | ||
68 | #ifdef MODVERSIONS | ||
69 | #include <config/modversions.h> | ||
70 | #endif | ||
71 | |||
72 | #include <linux/module.h> | 68 | #include <linux/module.h> |
73 | #include <linux/errno.h> | 69 | #include <linux/errno.h> |
74 | #include <linux/major.h> | 70 | #include <linux/major.h> |
@@ -85,6 +81,7 @@ | |||
85 | #include <linux/string.h> | 81 | #include <linux/string.h> |
86 | #include <linux/fcntl.h> | 82 | #include <linux/fcntl.h> |
87 | #include <linux/ptrace.h> | 83 | #include <linux/ptrace.h> |
84 | #include <linux/mutex.h> | ||
88 | #include <linux/ioport.h> | 85 | #include <linux/ioport.h> |
89 | #include <linux/delay.h> | 86 | #include <linux/delay.h> |
90 | #include <linux/wait.h> | 87 | #include <linux/wait.h> |
@@ -93,7 +90,6 @@ | |||
93 | #include <asm/atomic.h> | 90 | #include <asm/atomic.h> |
94 | #include <linux/bitops.h> | 91 | #include <linux/bitops.h> |
95 | #include <linux/spinlock.h> | 92 | #include <linux/spinlock.h> |
96 | #include <asm/semaphore.h> | ||
97 | #include <linux/init.h> | 93 | #include <linux/init.h> |
98 | 94 | ||
99 | /****** RocketPort includes ******/ | 95 | /****** RocketPort includes ******/ |
@@ -702,7 +698,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
702 | } | 698 | } |
703 | } | 699 | } |
704 | spin_lock_init(&info->slock); | 700 | spin_lock_init(&info->slock); |
705 | sema_init(&info->write_sem, 1); | 701 | mutex_init(&info->write_mtx); |
706 | rp_table[line] = info; | 702 | rp_table[line] = info; |
707 | if (pci_dev) | 703 | if (pci_dev) |
708 | tty_register_device(rocket_driver, line, &pci_dev->dev); | 704 | tty_register_device(rocket_driver, line, &pci_dev->dev); |
@@ -947,7 +943,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
947 | #endif | 943 | #endif |
948 | schedule(); /* Don't hold spinlock here, will hang PC */ | 944 | schedule(); /* Don't hold spinlock here, will hang PC */ |
949 | } | 945 | } |
950 | current->state = TASK_RUNNING; | 946 | __set_current_state(TASK_RUNNING); |
951 | remove_wait_queue(&info->open_wait, &wait); | 947 | remove_wait_queue(&info->open_wait, &wait); |
952 | 948 | ||
953 | spin_lock_irqsave(&info->slock, flags); | 949 | spin_lock_irqsave(&info->slock, flags); |
@@ -1602,7 +1598,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1602 | if (signal_pending(current)) | 1598 | if (signal_pending(current)) |
1603 | break; | 1599 | break; |
1604 | } | 1600 | } |
1605 | current->state = TASK_RUNNING; | 1601 | __set_current_state(TASK_RUNNING); |
1606 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1602 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1607 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); | 1603 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); |
1608 | #endif | 1604 | #endif |
@@ -1661,8 +1657,11 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1661 | if (rocket_paranoia_check(info, "rp_put_char")) | 1657 | if (rocket_paranoia_check(info, "rp_put_char")) |
1662 | return; | 1658 | return; |
1663 | 1659 | ||
1664 | /* Grab the port write semaphore, locking out other processes that try to write to this port */ | 1660 | /* |
1665 | down(&info->write_sem); | 1661 | * Grab the port write mutex, locking out other processes that try to |
1662 | * write to this port | ||
1663 | */ | ||
1664 | mutex_lock(&info->write_mtx); | ||
1666 | 1665 | ||
1667 | #ifdef ROCKET_DEBUG_WRITE | 1666 | #ifdef ROCKET_DEBUG_WRITE |
1668 | printk(KERN_INFO "rp_put_char %c...", ch); | 1667 | printk(KERN_INFO "rp_put_char %c...", ch); |
@@ -1684,12 +1683,12 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1684 | info->xmit_fifo_room--; | 1683 | info->xmit_fifo_room--; |
1685 | } | 1684 | } |
1686 | spin_unlock_irqrestore(&info->slock, flags); | 1685 | spin_unlock_irqrestore(&info->slock, flags); |
1687 | up(&info->write_sem); | 1686 | mutex_unlock(&info->write_mtx); |
1688 | } | 1687 | } |
1689 | 1688 | ||
1690 | /* | 1689 | /* |
1691 | * Exception handler - write routine, called when user app writes to the device. | 1690 | * Exception handler - write routine, called when user app writes to the device. |
1692 | * A per port write semaphore is used to protect from another process writing to | 1691 | * A per port write mutex is used to protect from another process writing to |
1693 | * this port at the same time. This other process could be running on the other CPU | 1692 | * this port at the same time. This other process could be running on the other CPU |
1694 | * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). | 1693 | * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). |
1695 | * Spinlocks protect the info xmit members. | 1694 | * Spinlocks protect the info xmit members. |
@@ -1706,7 +1705,7 @@ static int rp_write(struct tty_struct *tty, | |||
1706 | if (count <= 0 || rocket_paranoia_check(info, "rp_write")) | 1705 | if (count <= 0 || rocket_paranoia_check(info, "rp_write")) |
1707 | return 0; | 1706 | return 0; |
1708 | 1707 | ||
1709 | down_interruptible(&info->write_sem); | 1708 | mutex_lock_interruptible(&info->write_mtx); |
1710 | 1709 | ||
1711 | #ifdef ROCKET_DEBUG_WRITE | 1710 | #ifdef ROCKET_DEBUG_WRITE |
1712 | printk(KERN_INFO "rp_write %d chars...", count); | 1711 | printk(KERN_INFO "rp_write %d chars...", count); |
@@ -1777,7 +1776,7 @@ end: | |||
1777 | wake_up_interruptible(&tty->poll_wait); | 1776 | wake_up_interruptible(&tty->poll_wait); |
1778 | #endif | 1777 | #endif |
1779 | } | 1778 | } |
1780 | up(&info->write_sem); | 1779 | mutex_unlock(&info->write_mtx); |
1781 | return retval; | 1780 | return retval; |
1782 | } | 1781 | } |
1783 | 1782 | ||
@@ -1852,6 +1851,12 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1852 | 1851 | ||
1853 | #ifdef CONFIG_PCI | 1852 | #ifdef CONFIG_PCI |
1854 | 1853 | ||
1854 | static struct pci_device_id __devinitdata rocket_pci_ids[] = { | ||
1855 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, | ||
1856 | { } | ||
1857 | }; | ||
1858 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | ||
1859 | |||
1855 | /* | 1860 | /* |
1856 | * Called when a PCI card is found. Retrieves and stores model information, | 1861 | * Called when a PCI card is found. Retrieves and stores model information, |
1857 | * init's aiopic and serial port hardware. | 1862 | * init's aiopic and serial port hardware. |
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index 3a8bcc85bc14..89b4d7b10d12 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define ROCKET_TYPE_MODEMIII 3 | 15 | #define ROCKET_TYPE_MODEMIII 3 |
16 | #define ROCKET_TYPE_PC104 4 | 16 | #define ROCKET_TYPE_PC104 4 |
17 | 17 | ||
18 | #include <linux/mutex.h> | ||
19 | |||
18 | #include <asm/io.h> | 20 | #include <asm/io.h> |
19 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
20 | 22 | ||
@@ -1171,7 +1173,7 @@ struct r_port { | |||
1171 | struct wait_queue *close_wait; | 1173 | struct wait_queue *close_wait; |
1172 | #endif | 1174 | #endif |
1173 | spinlock_t slock; | 1175 | spinlock_t slock; |
1174 | struct semaphore write_sem; | 1176 | struct mutex write_mtx; |
1175 | }; | 1177 | }; |
1176 | 1178 | ||
1177 | #define RPORT_MAGIC 0x525001 | 1179 | #define RPORT_MAGIC 0x525001 |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index c7dac9b13351..20380a2c4dee 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -388,7 +388,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
388 | if (!retval) | 388 | if (!retval) |
389 | retval = count; | 389 | retval = count; |
390 | out: | 390 | out: |
391 | current->state = TASK_RUNNING; | 391 | __set_current_state(TASK_RUNNING); |
392 | remove_wait_queue(&rtc_wait, &wait); | 392 | remove_wait_queue(&rtc_wait, &wait); |
393 | 393 | ||
394 | return retval; | 394 | return retval; |
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 74cff839c857..a69f094d1ed3 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -299,7 +299,7 @@ int paste_selection(struct tty_struct *tty) | |||
299 | pasted += count; | 299 | pasted += count; |
300 | } | 300 | } |
301 | remove_wait_queue(&vc->paste_wait, &wait); | 301 | remove_wait_queue(&vc->paste_wait, &wait); |
302 | current->state = TASK_RUNNING; | 302 | __set_current_state(TASK_RUNNING); |
303 | 303 | ||
304 | tty_ldisc_deref(ld); | 304 | tty_ldisc_deref(ld); |
305 | return 0; | 305 | return 0; |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 5fd314adc1f2..c585b4738f86 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1892,7 +1892,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
1892 | #endif | 1892 | #endif |
1893 | schedule(); | 1893 | schedule(); |
1894 | } | 1894 | } |
1895 | current->state = TASK_RUNNING; | 1895 | __set_current_state(TASK_RUNNING); |
1896 | remove_wait_queue(&info->open_wait, &wait); | 1896 | remove_wait_queue(&info->open_wait, &wait); |
1897 | if (!tty_hung_up_p(filp)) { | 1897 | if (!tty_hung_up_p(filp)) { |
1898 | info->count++; | 1898 | info->count++; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index ce4db6f52362..f02a0795983f 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -4010,8 +4010,13 @@ static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info) | |||
4010 | for ( i=0; i<info->num_tx_holding_buffers; ++i) { | 4010 | for ( i=0; i<info->num_tx_holding_buffers; ++i) { |
4011 | info->tx_holding_buffers[i].buffer = | 4011 | info->tx_holding_buffers[i].buffer = |
4012 | kmalloc(info->max_frame_size, GFP_KERNEL); | 4012 | kmalloc(info->max_frame_size, GFP_KERNEL); |
4013 | if ( info->tx_holding_buffers[i].buffer == NULL ) | 4013 | if (info->tx_holding_buffers[i].buffer == NULL) { |
4014 | for (--i; i >= 0; i--) { | ||
4015 | kfree(info->tx_holding_buffers[i].buffer); | ||
4016 | info->tx_holding_buffers[i].buffer = NULL; | ||
4017 | } | ||
4014 | return -ENOMEM; | 4018 | return -ENOMEM; |
4019 | } | ||
4015 | } | 4020 | } |
4016 | 4021 | ||
4017 | return 0; | 4022 | return 0; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 0a367cd4121f..2a7736b5f2f7 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -3415,6 +3415,9 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3415 | } | 3415 | } |
3416 | } | 3416 | } |
3417 | } | 3417 | } |
3418 | |||
3419 | for (i=0; i < port_count; ++i) | ||
3420 | tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); | ||
3418 | } | 3421 | } |
3419 | 3422 | ||
3420 | static int __devinit init_one(struct pci_dev *dev, | 3423 | static int __devinit init_one(struct pci_dev *dev, |
@@ -3466,6 +3469,8 @@ static void slgt_cleanup(void) | |||
3466 | printk("unload %s %s\n", driver_name, driver_version); | 3469 | printk("unload %s %s\n", driver_name, driver_version); |
3467 | 3470 | ||
3468 | if (serial_driver) { | 3471 | if (serial_driver) { |
3472 | for (info=slgt_device_list ; info != NULL ; info=info->next_device) | ||
3473 | tty_unregister_device(serial_driver, info->line); | ||
3469 | if ((rc = tty_unregister_driver(serial_driver))) | 3474 | if ((rc = tty_unregister_driver(serial_driver))) |
3470 | DBGERR(("tty_unregister_driver error=%d\n", rc)); | 3475 | DBGERR(("tty_unregister_driver error=%d\n", rc)); |
3471 | put_tty_driver(serial_driver); | 3476 | put_tty_driver(serial_driver); |
@@ -3506,23 +3511,10 @@ static int __init slgt_init(void) | |||
3506 | 3511 | ||
3507 | printk("%s %s\n", driver_name, driver_version); | 3512 | printk("%s %s\n", driver_name, driver_version); |
3508 | 3513 | ||
3509 | slgt_device_count = 0; | ||
3510 | if ((rc = pci_register_driver(&pci_driver)) < 0) { | ||
3511 | printk("%s pci_register_driver error=%d\n", driver_name, rc); | ||
3512 | return rc; | ||
3513 | } | ||
3514 | pci_registered = 1; | ||
3515 | |||
3516 | if (!slgt_device_list) { | ||
3517 | printk("%s no devices found\n",driver_name); | ||
3518 | pci_unregister_driver(&pci_driver); | ||
3519 | return -ENODEV; | ||
3520 | } | ||
3521 | |||
3522 | serial_driver = alloc_tty_driver(MAX_DEVICES); | 3514 | serial_driver = alloc_tty_driver(MAX_DEVICES); |
3523 | if (!serial_driver) { | 3515 | if (!serial_driver) { |
3524 | rc = -ENOMEM; | 3516 | printk("%s can't allocate tty driver\n", driver_name); |
3525 | goto error; | 3517 | return -ENOMEM; |
3526 | } | 3518 | } |
3527 | 3519 | ||
3528 | /* Initialize the tty_driver structure */ | 3520 | /* Initialize the tty_driver structure */ |
@@ -3539,7 +3531,7 @@ static int __init slgt_init(void) | |||
3539 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 3531 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
3540 | serial_driver->init_termios.c_ispeed = 9600; | 3532 | serial_driver->init_termios.c_ispeed = 9600; |
3541 | serial_driver->init_termios.c_ospeed = 9600; | 3533 | serial_driver->init_termios.c_ospeed = 9600; |
3542 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 3534 | serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
3543 | tty_set_operations(serial_driver, &ops); | 3535 | tty_set_operations(serial_driver, &ops); |
3544 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 3536 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
3545 | DBGERR(("%s can't register serial driver\n", driver_name)); | 3537 | DBGERR(("%s can't register serial driver\n", driver_name)); |
@@ -3552,6 +3544,16 @@ static int __init slgt_init(void) | |||
3552 | driver_name, driver_version, | 3544 | driver_name, driver_version, |
3553 | serial_driver->major); | 3545 | serial_driver->major); |
3554 | 3546 | ||
3547 | slgt_device_count = 0; | ||
3548 | if ((rc = pci_register_driver(&pci_driver)) < 0) { | ||
3549 | printk("%s pci_register_driver error=%d\n", driver_name, rc); | ||
3550 | goto error; | ||
3551 | } | ||
3552 | pci_registered = 1; | ||
3553 | |||
3554 | if (!slgt_device_list) | ||
3555 | printk("%s no devices found\n",driver_name); | ||
3556 | |||
3555 | return 0; | 3557 | return 0; |
3556 | 3558 | ||
3557 | error: | 3559 | error: |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1d8c4ae61551..39cc318011ea 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/sysrq.h> | 24 | #include <linux/sysrq.h> |
25 | #include <linux/kbd_kern.h> | 25 | #include <linux/kbd_kern.h> |
26 | #include <linux/quotaops.h> | 26 | #include <linux/quotaops.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/suspend.h> | 29 | #include <linux/suspend.h> |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 47fb20f69695..35b40b996534 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -442,7 +442,7 @@ tipar_register(int nr, struct parport *port) | |||
442 | } | 442 | } |
443 | 443 | ||
444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, | 444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, |
445 | TIPAR_MINOR + nr), NULL, "par%d", nr); | 445 | TIPAR_MINOR + nr), port->dev, "par%d", nr); |
446 | 446 | ||
447 | /* Display informations */ | 447 | /* Display informations */ |
448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == | 448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e5a254a434f8..9bb542913b86 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -24,7 +24,9 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | |||
28 | #include "tpm.h" | 30 | #include "tpm.h" |
29 | 31 | ||
30 | enum tpm_const { | 32 | enum tpm_const { |
@@ -328,10 +330,10 @@ static void timeout_work(struct work_struct *work) | |||
328 | { | 330 | { |
329 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); | 331 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); |
330 | 332 | ||
331 | down(&chip->buffer_mutex); | 333 | mutex_lock(&chip->buffer_mutex); |
332 | atomic_set(&chip->data_pending, 0); | 334 | atomic_set(&chip->data_pending, 0); |
333 | memset(chip->data_buffer, 0, TPM_BUFSIZE); | 335 | memset(chip->data_buffer, 0, TPM_BUFSIZE); |
334 | up(&chip->buffer_mutex); | 336 | mutex_unlock(&chip->buffer_mutex); |
335 | } | 337 | } |
336 | 338 | ||
337 | /* | 339 | /* |
@@ -380,7 +382,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
380 | return -E2BIG; | 382 | return -E2BIG; |
381 | } | 383 | } |
382 | 384 | ||
383 | down(&chip->tpm_mutex); | 385 | mutex_lock(&chip->tpm_mutex); |
384 | 386 | ||
385 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { | 387 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { |
386 | dev_err(chip->dev, | 388 | dev_err(chip->dev, |
@@ -419,7 +421,7 @@ out_recv: | |||
419 | dev_err(chip->dev, | 421 | dev_err(chip->dev, |
420 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 422 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
421 | out: | 423 | out: |
422 | up(&chip->tpm_mutex); | 424 | mutex_unlock(&chip->tpm_mutex); |
423 | return rc; | 425 | return rc; |
424 | } | 426 | } |
425 | 427 | ||
@@ -942,12 +944,12 @@ int tpm_release(struct inode *inode, struct file *file) | |||
942 | { | 944 | { |
943 | struct tpm_chip *chip = file->private_data; | 945 | struct tpm_chip *chip = file->private_data; |
944 | 946 | ||
947 | flush_scheduled_work(); | ||
945 | spin_lock(&driver_lock); | 948 | spin_lock(&driver_lock); |
946 | file->private_data = NULL; | 949 | file->private_data = NULL; |
947 | chip->num_opens--; | ||
948 | del_singleshot_timer_sync(&chip->user_read_timer); | 950 | del_singleshot_timer_sync(&chip->user_read_timer); |
949 | flush_scheduled_work(); | ||
950 | atomic_set(&chip->data_pending, 0); | 951 | atomic_set(&chip->data_pending, 0); |
952 | chip->num_opens--; | ||
951 | put_device(chip->dev); | 953 | put_device(chip->dev); |
952 | kfree(chip->data_buffer); | 954 | kfree(chip->data_buffer); |
953 | spin_unlock(&driver_lock); | 955 | spin_unlock(&driver_lock); |
@@ -966,14 +968,14 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
966 | while (atomic_read(&chip->data_pending) != 0) | 968 | while (atomic_read(&chip->data_pending) != 0) |
967 | msleep(TPM_TIMEOUT); | 969 | msleep(TPM_TIMEOUT); |
968 | 970 | ||
969 | down(&chip->buffer_mutex); | 971 | mutex_lock(&chip->buffer_mutex); |
970 | 972 | ||
971 | if (in_size > TPM_BUFSIZE) | 973 | if (in_size > TPM_BUFSIZE) |
972 | in_size = TPM_BUFSIZE; | 974 | in_size = TPM_BUFSIZE; |
973 | 975 | ||
974 | if (copy_from_user | 976 | if (copy_from_user |
975 | (chip->data_buffer, (void __user *) buf, in_size)) { | 977 | (chip->data_buffer, (void __user *) buf, in_size)) { |
976 | up(&chip->buffer_mutex); | 978 | mutex_unlock(&chip->buffer_mutex); |
977 | return -EFAULT; | 979 | return -EFAULT; |
978 | } | 980 | } |
979 | 981 | ||
@@ -981,7 +983,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
981 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); | 983 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); |
982 | 984 | ||
983 | atomic_set(&chip->data_pending, out_size); | 985 | atomic_set(&chip->data_pending, out_size); |
984 | up(&chip->buffer_mutex); | 986 | mutex_unlock(&chip->buffer_mutex); |
985 | 987 | ||
986 | /* Set a timeout by which the reader must come claim the result */ | 988 | /* Set a timeout by which the reader must come claim the result */ |
987 | mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); | 989 | mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); |
@@ -1004,10 +1006,10 @@ ssize_t tpm_read(struct file *file, char __user *buf, | |||
1004 | if (size < ret_size) | 1006 | if (size < ret_size) |
1005 | ret_size = size; | 1007 | ret_size = size; |
1006 | 1008 | ||
1007 | down(&chip->buffer_mutex); | 1009 | mutex_lock(&chip->buffer_mutex); |
1008 | if (copy_to_user(buf, chip->data_buffer, ret_size)) | 1010 | if (copy_to_user(buf, chip->data_buffer, ret_size)) |
1009 | ret_size = -EFAULT; | 1011 | ret_size = -EFAULT; |
1010 | up(&chip->buffer_mutex); | 1012 | mutex_unlock(&chip->buffer_mutex); |
1011 | } | 1013 | } |
1012 | 1014 | ||
1013 | return ret_size; | 1015 | return ret_size; |
@@ -1097,11 +1099,16 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1097 | 1099 | ||
1098 | /* Driver specific per-device data */ | 1100 | /* Driver specific per-device data */ |
1099 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1101 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1100 | if (chip == NULL) | 1102 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); |
1103 | |||
1104 | if (chip == NULL || devname == NULL) { | ||
1105 | kfree(chip); | ||
1106 | kfree(devname); | ||
1101 | return NULL; | 1107 | return NULL; |
1108 | } | ||
1102 | 1109 | ||
1103 | init_MUTEX(&chip->buffer_mutex); | 1110 | mutex_init(&chip->buffer_mutex); |
1104 | init_MUTEX(&chip->tpm_mutex); | 1111 | mutex_init(&chip->tpm_mutex); |
1105 | INIT_LIST_HEAD(&chip->list); | 1112 | INIT_LIST_HEAD(&chip->list); |
1106 | 1113 | ||
1107 | INIT_WORK(&chip->work, timeout_work); | 1114 | INIT_WORK(&chip->work, timeout_work); |
@@ -1124,7 +1131,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1124 | 1131 | ||
1125 | set_bit(chip->dev_num, dev_mask); | 1132 | set_bit(chip->dev_num, dev_mask); |
1126 | 1133 | ||
1127 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); | ||
1128 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 1134 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
1129 | chip->vendor.miscdev.name = devname; | 1135 | chip->vendor.miscdev.name = devname; |
1130 | 1136 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 9f273f032b0f..b2e2b002a1bb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/mutex.h> | ||
24 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
25 | #include <linux/miscdevice.h> | 26 | #include <linux/miscdevice.h> |
26 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
@@ -94,11 +95,11 @@ struct tpm_chip { | |||
94 | /* Data passed to and from the tpm via the read/write calls */ | 95 | /* Data passed to and from the tpm via the read/write calls */ |
95 | u8 *data_buffer; | 96 | u8 *data_buffer; |
96 | atomic_t data_pending; | 97 | atomic_t data_pending; |
97 | struct semaphore buffer_mutex; | 98 | struct mutex buffer_mutex; |
98 | 99 | ||
99 | struct timer_list user_read_timer; /* user needs to claim result */ | 100 | struct timer_list user_read_timer; /* user needs to claim result */ |
100 | struct work_struct work; | 101 | struct work_struct work; |
101 | struct semaphore tpm_mutex; /* tpm is processing */ | 102 | struct mutex tpm_mutex; /* tpm is processing */ |
102 | 103 | ||
103 | struct tpm_vendor_specific vendor; | 104 | struct tpm_vendor_specific vendor; |
104 | 105 | ||
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 1353b5a6bae8..967002a5a1e5 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -30,12 +30,60 @@ | |||
30 | #define TPM_MAX_TRIES 5000 | 30 | #define TPM_MAX_TRIES 5000 |
31 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 | 31 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
32 | 32 | ||
33 | /* These values will be filled after PnP-call */ | 33 | #define TPM_INF_IO_PORT 0x0 |
34 | static int TPM_INF_DATA; | 34 | #define TPM_INF_IO_MEM 0x1 |
35 | static int TPM_INF_ADDR; | 35 | |
36 | static int TPM_INF_BASE; | 36 | #define TPM_INF_ADDR 0x0 |
37 | static int TPM_INF_ADDR_LEN; | 37 | #define TPM_INF_DATA 0x1 |
38 | static int TPM_INF_PORT_LEN; | 38 | |
39 | struct tpm_inf_dev { | ||
40 | int iotype; | ||
41 | |||
42 | void __iomem *mem_base; /* MMIO ioremap'd addr */ | ||
43 | unsigned long map_base; /* phys MMIO base */ | ||
44 | unsigned long map_size; /* MMIO region size */ | ||
45 | unsigned int index_off; /* index register offset */ | ||
46 | |||
47 | unsigned int data_regs; /* Data registers */ | ||
48 | unsigned int data_size; | ||
49 | |||
50 | unsigned int config_port; /* IO Port config index reg */ | ||
51 | unsigned int config_size; | ||
52 | }; | ||
53 | |||
54 | static struct tpm_inf_dev tpm_dev; | ||
55 | |||
56 | static inline void tpm_data_out(unsigned char data, unsigned char offset) | ||
57 | { | ||
58 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
59 | outb(data, tpm_dev.data_regs + offset); | ||
60 | else | ||
61 | writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset); | ||
62 | } | ||
63 | |||
64 | static inline unsigned char tpm_data_in(unsigned char offset) | ||
65 | { | ||
66 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
67 | return inb(tpm_dev.data_regs + offset); | ||
68 | else | ||
69 | return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset); | ||
70 | } | ||
71 | |||
72 | static inline void tpm_config_out(unsigned char data, unsigned char offset) | ||
73 | { | ||
74 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
75 | outb(data, tpm_dev.config_port + offset); | ||
76 | else | ||
77 | writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset); | ||
78 | } | ||
79 | |||
80 | static inline unsigned char tpm_config_in(unsigned char offset) | ||
81 | { | ||
82 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
83 | return inb(tpm_dev.config_port + offset); | ||
84 | else | ||
85 | return readb(tpm_dev.mem_base + tpm_dev.index_off + offset); | ||
86 | } | ||
39 | 87 | ||
40 | /* TPM header definitions */ | 88 | /* TPM header definitions */ |
41 | enum infineon_tpm_header { | 89 | enum infineon_tpm_header { |
@@ -105,7 +153,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
105 | 153 | ||
106 | if (clear_wrfifo) { | 154 | if (clear_wrfifo) { |
107 | for (i = 0; i < 4096; i++) { | 155 | for (i = 0; i < 4096; i++) { |
108 | status = inb(chip->vendor.base + WRFIFO); | 156 | status = tpm_data_in(WRFIFO); |
109 | if (status == 0xff) { | 157 | if (status == 0xff) { |
110 | if (check == 5) | 158 | if (check == 5) |
111 | break; | 159 | break; |
@@ -125,8 +173,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
125 | */ | 173 | */ |
126 | i = 0; | 174 | i = 0; |
127 | do { | 175 | do { |
128 | status = inb(chip->vendor.base + RDFIFO); | 176 | status = tpm_data_in(RDFIFO); |
129 | status = inb(chip->vendor.base + STAT); | 177 | status = tpm_data_in(STAT); |
130 | i++; | 178 | i++; |
131 | if (i == TPM_MAX_TRIES) | 179 | if (i == TPM_MAX_TRIES) |
132 | return -EIO; | 180 | return -EIO; |
@@ -139,7 +187,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
139 | int status; | 187 | int status; |
140 | int i; | 188 | int i; |
141 | for (i = 0; i < TPM_MAX_TRIES; i++) { | 189 | for (i = 0; i < TPM_MAX_TRIES; i++) { |
142 | status = inb(chip->vendor.base + STAT); | 190 | status = tpm_data_in(STAT); |
143 | /* check the status-register if wait_for_bit is set */ | 191 | /* check the status-register if wait_for_bit is set */ |
144 | if (status & 1 << wait_for_bit) | 192 | if (status & 1 << wait_for_bit) |
145 | break; | 193 | break; |
@@ -158,7 +206,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
158 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | 206 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) |
159 | { | 207 | { |
160 | wait(chip, STAT_XFE); | 208 | wait(chip, STAT_XFE); |
161 | outb(sendbyte, chip->vendor.base + WRFIFO); | 209 | tpm_data_out(sendbyte, WRFIFO); |
162 | } | 210 | } |
163 | 211 | ||
164 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more | 212 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more |
@@ -205,7 +253,7 @@ recv_begin: | |||
205 | ret = wait(chip, STAT_RDA); | 253 | ret = wait(chip, STAT_RDA); |
206 | if (ret) | 254 | if (ret) |
207 | return -EIO; | 255 | return -EIO; |
208 | buf[i] = inb(chip->vendor.base + RDFIFO); | 256 | buf[i] = tpm_data_in(RDFIFO); |
209 | } | 257 | } |
210 | 258 | ||
211 | if (buf[0] != TPM_VL_VER) { | 259 | if (buf[0] != TPM_VL_VER) { |
@@ -220,7 +268,7 @@ recv_begin: | |||
220 | 268 | ||
221 | for (i = 0; i < size; i++) { | 269 | for (i = 0; i < size; i++) { |
222 | wait(chip, STAT_RDA); | 270 | wait(chip, STAT_RDA); |
223 | buf[i] = inb(chip->vendor.base + RDFIFO); | 271 | buf[i] = tpm_data_in(RDFIFO); |
224 | } | 272 | } |
225 | 273 | ||
226 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 274 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
@@ -269,7 +317,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
269 | u8 count_high, count_low, count_4, count_3, count_2, count_1; | 317 | u8 count_high, count_low, count_4, count_3, count_2, count_1; |
270 | 318 | ||
271 | /* Disabling Reset, LP and IRQC */ | 319 | /* Disabling Reset, LP and IRQC */ |
272 | outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); | 320 | tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); |
273 | 321 | ||
274 | ret = empty_fifo(chip, 1); | 322 | ret = empty_fifo(chip, 1); |
275 | if (ret) { | 323 | if (ret) { |
@@ -320,7 +368,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
320 | 368 | ||
321 | static u8 tpm_inf_status(struct tpm_chip *chip) | 369 | static u8 tpm_inf_status(struct tpm_chip *chip) |
322 | { | 370 | { |
323 | return inb(chip->vendor.base + STAT); | 371 | return tpm_data_in(STAT); |
324 | } | 372 | } |
325 | 373 | ||
326 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 374 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
@@ -381,51 +429,88 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
381 | /* read IO-ports through PnP */ | 429 | /* read IO-ports through PnP */ |
382 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 430 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
383 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { | 431 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
384 | TPM_INF_ADDR = pnp_port_start(dev, 0); | 432 | |
385 | TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); | 433 | tpm_dev.iotype = TPM_INF_IO_PORT; |
386 | TPM_INF_DATA = (TPM_INF_ADDR + 1); | 434 | |
387 | TPM_INF_BASE = pnp_port_start(dev, 1); | 435 | tpm_dev.config_port = pnp_port_start(dev, 0); |
388 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); | 436 | tpm_dev.config_size = pnp_port_len(dev, 0); |
389 | if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { | 437 | tpm_dev.data_regs = pnp_port_start(dev, 1); |
438 | tpm_dev.data_size = pnp_port_len(dev, 1); | ||
439 | if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) { | ||
390 | rc = -EINVAL; | 440 | rc = -EINVAL; |
391 | goto err_last; | 441 | goto err_last; |
392 | } | 442 | } |
393 | dev_info(&dev->dev, "Found %s with ID %s\n", | 443 | dev_info(&dev->dev, "Found %s with ID %s\n", |
394 | dev->name, dev_id->id); | 444 | dev->name, dev_id->id); |
395 | if (!((TPM_INF_BASE >> 8) & 0xff)) { | 445 | if (!((tpm_dev.data_regs >> 8) & 0xff)) { |
396 | rc = -EINVAL; | 446 | rc = -EINVAL; |
397 | goto err_last; | 447 | goto err_last; |
398 | } | 448 | } |
399 | /* publish my base address and request region */ | 449 | /* publish my base address and request region */ |
400 | if (request_region | 450 | if (request_region(tpm_dev.data_regs, tpm_dev.data_size, |
401 | (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 451 | "tpm_infineon0") == NULL) { |
402 | rc = -EINVAL; | 452 | rc = -EINVAL; |
403 | goto err_last; | 453 | goto err_last; |
404 | } | 454 | } |
405 | if (request_region | 455 | if (request_region(tpm_dev.config_port, tpm_dev.config_size, |
406 | (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { | 456 | "tpm_infineon0") == NULL) { |
457 | release_region(tpm_dev.data_regs, tpm_dev.data_size); | ||
407 | rc = -EINVAL; | 458 | rc = -EINVAL; |
408 | goto err_last; | 459 | goto err_last; |
409 | } | 460 | } |
461 | } else if (pnp_mem_valid(dev, 0) && | ||
462 | !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) { | ||
463 | |||
464 | tpm_dev.iotype = TPM_INF_IO_MEM; | ||
465 | |||
466 | tpm_dev.map_base = pnp_mem_start(dev, 0); | ||
467 | tpm_dev.map_size = pnp_mem_len(dev, 0); | ||
468 | |||
469 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
470 | dev->name, dev_id->id); | ||
471 | |||
472 | /* publish my base address and request region */ | ||
473 | if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size, | ||
474 | "tpm_infineon0") == NULL) { | ||
475 | rc = -EINVAL; | ||
476 | goto err_last; | ||
477 | } | ||
478 | |||
479 | tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size); | ||
480 | if (tpm_dev.mem_base == NULL) { | ||
481 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
482 | rc = -EINVAL; | ||
483 | goto err_last; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * The only known MMIO based Infineon TPM system provides | ||
488 | * a single large mem region with the device config | ||
489 | * registers at the default TPM_ADDR. The data registers | ||
490 | * seem like they could be placed anywhere within the MMIO | ||
491 | * region, but lets just put them at zero offset. | ||
492 | */ | ||
493 | tpm_dev.index_off = TPM_ADDR; | ||
494 | tpm_dev.data_regs = 0x0; | ||
410 | } else { | 495 | } else { |
411 | rc = -EINVAL; | 496 | rc = -EINVAL; |
412 | goto err_last; | 497 | goto err_last; |
413 | } | 498 | } |
414 | 499 | ||
415 | /* query chip for its vendor, its version number a.s.o. */ | 500 | /* query chip for its vendor, its version number a.s.o. */ |
416 | outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); | 501 | tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); |
417 | outb(IDVENL, TPM_INF_ADDR); | 502 | tpm_config_out(IDVENL, TPM_INF_ADDR); |
418 | vendorid[1] = inb(TPM_INF_DATA); | 503 | vendorid[1] = tpm_config_in(TPM_INF_DATA); |
419 | outb(IDVENH, TPM_INF_ADDR); | 504 | tpm_config_out(IDVENH, TPM_INF_ADDR); |
420 | vendorid[0] = inb(TPM_INF_DATA); | 505 | vendorid[0] = tpm_config_in(TPM_INF_DATA); |
421 | outb(IDPDL, TPM_INF_ADDR); | 506 | tpm_config_out(IDPDL, TPM_INF_ADDR); |
422 | productid[1] = inb(TPM_INF_DATA); | 507 | productid[1] = tpm_config_in(TPM_INF_DATA); |
423 | outb(IDPDH, TPM_INF_ADDR); | 508 | tpm_config_out(IDPDH, TPM_INF_ADDR); |
424 | productid[0] = inb(TPM_INF_DATA); | 509 | productid[0] = tpm_config_in(TPM_INF_DATA); |
425 | outb(CHIP_ID1, TPM_INF_ADDR); | 510 | tpm_config_out(CHIP_ID1, TPM_INF_ADDR); |
426 | version[1] = inb(TPM_INF_DATA); | 511 | version[1] = tpm_config_in(TPM_INF_DATA); |
427 | outb(CHIP_ID2, TPM_INF_ADDR); | 512 | tpm_config_out(CHIP_ID2, TPM_INF_ADDR); |
428 | version[0] = inb(TPM_INF_DATA); | 513 | version[0] = tpm_config_in(TPM_INF_DATA); |
429 | 514 | ||
430 | switch ((productid[0] << 8) | productid[1]) { | 515 | switch ((productid[0] << 8) | productid[1]) { |
431 | case 6: | 516 | case 6: |
@@ -442,51 +527,54 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
442 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | 527 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { |
443 | 528 | ||
444 | /* configure TPM with IO-ports */ | 529 | /* configure TPM with IO-ports */ |
445 | outb(IOLIMH, TPM_INF_ADDR); | 530 | tpm_config_out(IOLIMH, TPM_INF_ADDR); |
446 | outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); | 531 | tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA); |
447 | outb(IOLIML, TPM_INF_ADDR); | 532 | tpm_config_out(IOLIML, TPM_INF_ADDR); |
448 | outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); | 533 | tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA); |
449 | 534 | ||
450 | /* control if IO-ports are set correctly */ | 535 | /* control if IO-ports are set correctly */ |
451 | outb(IOLIMH, TPM_INF_ADDR); | 536 | tpm_config_out(IOLIMH, TPM_INF_ADDR); |
452 | ioh = inb(TPM_INF_DATA); | 537 | ioh = tpm_config_in(TPM_INF_DATA); |
453 | outb(IOLIML, TPM_INF_ADDR); | 538 | tpm_config_out(IOLIML, TPM_INF_ADDR); |
454 | iol = inb(TPM_INF_DATA); | 539 | iol = tpm_config_in(TPM_INF_DATA); |
455 | 540 | ||
456 | if ((ioh << 8 | iol) != TPM_INF_BASE) { | 541 | if ((ioh << 8 | iol) != tpm_dev.data_regs) { |
457 | dev_err(&dev->dev, | 542 | dev_err(&dev->dev, |
458 | "Could not set IO-ports to 0x%x\n", | 543 | "Could not set IO-data registers to 0x%x\n", |
459 | TPM_INF_BASE); | 544 | tpm_dev.data_regs); |
460 | rc = -EIO; | 545 | rc = -EIO; |
461 | goto err_release_region; | 546 | goto err_release_region; |
462 | } | 547 | } |
463 | 548 | ||
464 | /* activate register */ | 549 | /* activate register */ |
465 | outb(TPM_DAR, TPM_INF_ADDR); | 550 | tpm_config_out(TPM_DAR, TPM_INF_ADDR); |
466 | outb(0x01, TPM_INF_DATA); | 551 | tpm_config_out(0x01, TPM_INF_DATA); |
467 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); | 552 | tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
468 | 553 | ||
469 | /* disable RESET, LP and IRQC */ | 554 | /* disable RESET, LP and IRQC */ |
470 | outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); | 555 | tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); |
471 | 556 | ||
472 | /* Finally, we're done, print some infos */ | 557 | /* Finally, we're done, print some infos */ |
473 | dev_info(&dev->dev, "TPM found: " | 558 | dev_info(&dev->dev, "TPM found: " |
474 | "config base 0x%x, " | 559 | "config base 0x%lx, " |
475 | "io base 0x%x, " | 560 | "data base 0x%lx, " |
476 | "chip version 0x%02x%02x, " | 561 | "chip version 0x%02x%02x, " |
477 | "vendor id 0x%x%x (Infineon), " | 562 | "vendor id 0x%x%x (Infineon), " |
478 | "product id 0x%02x%02x" | 563 | "product id 0x%02x%02x" |
479 | "%s\n", | 564 | "%s\n", |
480 | TPM_INF_ADDR, | 565 | tpm_dev.iotype == TPM_INF_IO_PORT ? |
481 | TPM_INF_BASE, | 566 | tpm_dev.config_port : |
567 | tpm_dev.map_base + tpm_dev.index_off, | ||
568 | tpm_dev.iotype == TPM_INF_IO_PORT ? | ||
569 | tpm_dev.data_regs : | ||
570 | tpm_dev.map_base + tpm_dev.data_regs, | ||
482 | version[0], version[1], | 571 | version[0], version[1], |
483 | vendorid[0], vendorid[1], | 572 | vendorid[0], vendorid[1], |
484 | productid[0], productid[1], chipname); | 573 | productid[0], productid[1], chipname); |
485 | 574 | ||
486 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { | 575 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) |
487 | goto err_release_region; | 576 | goto err_release_region; |
488 | } | 577 | |
489 | chip->vendor.base = TPM_INF_BASE; | ||
490 | return 0; | 578 | return 0; |
491 | } else { | 579 | } else { |
492 | rc = -ENODEV; | 580 | rc = -ENODEV; |
@@ -494,8 +582,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
494 | } | 582 | } |
495 | 583 | ||
496 | err_release_region: | 584 | err_release_region: |
497 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); | 585 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { |
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 586 | release_region(tpm_dev.data_regs, tpm_dev.data_size); |
587 | release_region(tpm_dev.config_port, tpm_dev.config_size); | ||
588 | } else { | ||
589 | iounmap(tpm_dev.mem_base); | ||
590 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
591 | } | ||
499 | 592 | ||
500 | err_last: | 593 | err_last: |
501 | return rc; | 594 | return rc; |
@@ -506,8 +599,14 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
506 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 599 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
507 | 600 | ||
508 | if (chip) { | 601 | if (chip) { |
509 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); | 602 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { |
510 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 603 | release_region(tpm_dev.data_regs, tpm_dev.data_size); |
604 | release_region(tpm_dev.config_port, | ||
605 | tpm_dev.config_size); | ||
606 | } else { | ||
607 | iounmap(tpm_dev.mem_base); | ||
608 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
609 | } | ||
511 | tpm_remove_hardware(chip->dev); | 610 | tpm_remove_hardware(chip->dev); |
512 | } | 611 | } |
513 | } | 612 | } |
@@ -539,5 +638,5 @@ module_exit(cleanup_inf); | |||
539 | 638 | ||
540 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 639 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
541 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 640 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
542 | MODULE_VERSION("1.8"); | 641 | MODULE_VERSION("1.9"); |
543 | MODULE_LICENSE("GPL"); | 642 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 389da364e6b6..7710a6a77d97 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -141,8 +141,6 @@ static DECLARE_MUTEX(allocated_ptys_lock); | |||
141 | static int ptmx_open(struct inode *, struct file *); | 141 | static int ptmx_open(struct inode *, struct file *); |
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | extern void disable_early_printk(void); | ||
145 | |||
146 | static void initialize_tty_struct(struct tty_struct *tty); | 144 | static void initialize_tty_struct(struct tty_struct *tty); |
147 | 145 | ||
148 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 146 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
@@ -155,8 +153,8 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
155 | unsigned int cmd, unsigned long arg); | 153 | unsigned int cmd, unsigned long arg); |
156 | static int tty_fasync(int fd, struct file * filp, int on); | 154 | static int tty_fasync(int fd, struct file * filp, int on); |
157 | static void release_tty(struct tty_struct *tty, int idx); | 155 | static void release_tty(struct tty_struct *tty, int idx); |
158 | static struct pid *__proc_set_tty(struct task_struct *tsk, | 156 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
159 | struct tty_struct *tty); | 157 | static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
160 | 158 | ||
161 | /** | 159 | /** |
162 | * alloc_tty_struct - allocate a tty object | 160 | * alloc_tty_struct - allocate a tty object |
@@ -1534,10 +1532,9 @@ void disassociate_ctty(int on_exit) | |||
1534 | } | 1532 | } |
1535 | 1533 | ||
1536 | spin_lock_irq(¤t->sighand->siglock); | 1534 | spin_lock_irq(¤t->sighand->siglock); |
1537 | tty_pgrp = current->signal->tty_old_pgrp; | 1535 | put_pid(current->signal->tty_old_pgrp); |
1538 | current->signal->tty_old_pgrp = NULL; | 1536 | current->signal->tty_old_pgrp = NULL; |
1539 | spin_unlock_irq(¤t->sighand->siglock); | 1537 | spin_unlock_irq(¤t->sighand->siglock); |
1540 | put_pid(tty_pgrp); | ||
1541 | 1538 | ||
1542 | mutex_lock(&tty_mutex); | 1539 | mutex_lock(&tty_mutex); |
1543 | /* It is possible that do_tty_hangup has free'd this tty */ | 1540 | /* It is possible that do_tty_hangup has free'd this tty */ |
@@ -1562,6 +1559,18 @@ void disassociate_ctty(int on_exit) | |||
1562 | unlock_kernel(); | 1559 | unlock_kernel(); |
1563 | } | 1560 | } |
1564 | 1561 | ||
1562 | /** | ||
1563 | * | ||
1564 | * no_tty - Ensure the current process does not have a controlling tty | ||
1565 | */ | ||
1566 | void no_tty(void) | ||
1567 | { | ||
1568 | struct task_struct *tsk = current; | ||
1569 | if (tsk->signal->leader) | ||
1570 | disassociate_ctty(0); | ||
1571 | proc_clear_tty(tsk); | ||
1572 | } | ||
1573 | |||
1565 | 1574 | ||
1566 | /** | 1575 | /** |
1567 | * stop_tty - propogate flow control | 1576 | * stop_tty - propogate flow control |
@@ -2508,7 +2517,6 @@ static int tty_open(struct inode * inode, struct file * filp) | |||
2508 | int index; | 2517 | int index; |
2509 | dev_t device = inode->i_rdev; | 2518 | dev_t device = inode->i_rdev; |
2510 | unsigned short saved_flags = filp->f_flags; | 2519 | unsigned short saved_flags = filp->f_flags; |
2511 | struct pid *old_pgrp; | ||
2512 | 2520 | ||
2513 | nonseekable_open(inode, filp); | 2521 | nonseekable_open(inode, filp); |
2514 | 2522 | ||
@@ -2602,17 +2610,15 @@ got_driver: | |||
2602 | goto retry_open; | 2610 | goto retry_open; |
2603 | } | 2611 | } |
2604 | 2612 | ||
2605 | old_pgrp = NULL; | ||
2606 | mutex_lock(&tty_mutex); | 2613 | mutex_lock(&tty_mutex); |
2607 | spin_lock_irq(¤t->sighand->siglock); | 2614 | spin_lock_irq(¤t->sighand->siglock); |
2608 | if (!noctty && | 2615 | if (!noctty && |
2609 | current->signal->leader && | 2616 | current->signal->leader && |
2610 | !current->signal->tty && | 2617 | !current->signal->tty && |
2611 | tty->session == NULL) | 2618 | tty->session == NULL) |
2612 | old_pgrp = __proc_set_tty(current, tty); | 2619 | __proc_set_tty(current, tty); |
2613 | spin_unlock_irq(¤t->sighand->siglock); | 2620 | spin_unlock_irq(¤t->sighand->siglock); |
2614 | mutex_unlock(&tty_mutex); | 2621 | mutex_unlock(&tty_mutex); |
2615 | put_pid(old_pgrp); | ||
2616 | return 0; | 2622 | return 0; |
2617 | } | 2623 | } |
2618 | 2624 | ||
@@ -3287,9 +3293,7 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3287 | case TIOCNOTTY: | 3293 | case TIOCNOTTY: |
3288 | if (current->signal->tty != tty) | 3294 | if (current->signal->tty != tty) |
3289 | return -ENOTTY; | 3295 | return -ENOTTY; |
3290 | if (current->signal->leader) | 3296 | no_tty(); |
3291 | disassociate_ctty(0); | ||
3292 | proc_clear_tty(current); | ||
3293 | return 0; | 3297 | return 0; |
3294 | case TIOCSCTTY: | 3298 | case TIOCSCTTY: |
3295 | return tiocsctty(tty, arg); | 3299 | return tiocsctty(tty, arg); |
@@ -3766,7 +3770,9 @@ int tty_register_driver(struct tty_driver *driver) | |||
3766 | if (!driver->put_char) | 3770 | if (!driver->put_char) |
3767 | driver->put_char = tty_default_put_char; | 3771 | driver->put_char = tty_default_put_char; |
3768 | 3772 | ||
3773 | mutex_lock(&tty_mutex); | ||
3769 | list_add(&driver->tty_drivers, &tty_drivers); | 3774 | list_add(&driver->tty_drivers, &tty_drivers); |
3775 | mutex_unlock(&tty_mutex); | ||
3770 | 3776 | ||
3771 | if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { | 3777 | if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { |
3772 | for(i = 0; i < driver->num; i++) | 3778 | for(i = 0; i < driver->num; i++) |
@@ -3792,8 +3798,9 @@ int tty_unregister_driver(struct tty_driver *driver) | |||
3792 | 3798 | ||
3793 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3799 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3794 | driver->num); | 3800 | driver->num); |
3795 | 3801 | mutex_lock(&tty_mutex); | |
3796 | list_del(&driver->tty_drivers); | 3802 | list_del(&driver->tty_drivers); |
3803 | mutex_unlock(&tty_mutex); | ||
3797 | 3804 | ||
3798 | /* | 3805 | /* |
3799 | * Free the termios and termios_locked structures because | 3806 | * Free the termios and termios_locked structures because |
@@ -3836,11 +3843,9 @@ void proc_clear_tty(struct task_struct *p) | |||
3836 | p->signal->tty = NULL; | 3843 | p->signal->tty = NULL; |
3837 | spin_unlock_irq(&p->sighand->siglock); | 3844 | spin_unlock_irq(&p->sighand->siglock); |
3838 | } | 3845 | } |
3839 | EXPORT_SYMBOL(proc_clear_tty); | ||
3840 | 3846 | ||
3841 | static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3847 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3842 | { | 3848 | { |
3843 | struct pid *old_pgrp; | ||
3844 | if (tty) { | 3849 | if (tty) { |
3845 | /* We should not have a session or pgrp to here but.... */ | 3850 | /* We should not have a session or pgrp to here but.... */ |
3846 | put_pid(tty->session); | 3851 | put_pid(tty->session); |
@@ -3848,21 +3853,16 @@ static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tt | |||
3848 | tty->session = get_pid(task_session(tsk)); | 3853 | tty->session = get_pid(task_session(tsk)); |
3849 | tty->pgrp = get_pid(task_pgrp(tsk)); | 3854 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3850 | } | 3855 | } |
3851 | old_pgrp = tsk->signal->tty_old_pgrp; | 3856 | put_pid(tsk->signal->tty_old_pgrp); |
3852 | tsk->signal->tty = tty; | 3857 | tsk->signal->tty = tty; |
3853 | tsk->signal->tty_old_pgrp = NULL; | 3858 | tsk->signal->tty_old_pgrp = NULL; |
3854 | return old_pgrp; | ||
3855 | } | 3859 | } |
3856 | 3860 | ||
3857 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3861 | static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3858 | { | 3862 | { |
3859 | struct pid *old_pgrp; | ||
3860 | |||
3861 | spin_lock_irq(&tsk->sighand->siglock); | 3863 | spin_lock_irq(&tsk->sighand->siglock); |
3862 | old_pgrp = __proc_set_tty(tsk, tty); | 3864 | __proc_set_tty(tsk, tty); |
3863 | spin_unlock_irq(&tsk->sighand->siglock); | 3865 | spin_unlock_irq(&tsk->sighand->siglock); |
3864 | |||
3865 | put_pid(old_pgrp); | ||
3866 | } | 3866 | } |
3867 | 3867 | ||
3868 | struct tty_struct *get_current_tty(void) | 3868 | struct tty_struct *get_current_tty(void) |
@@ -3897,9 +3897,6 @@ void __init console_init(void) | |||
3897 | * set up the console device so that later boot sequences can | 3897 | * set up the console device so that later boot sequences can |
3898 | * inform about problems etc.. | 3898 | * inform about problems etc.. |
3899 | */ | 3899 | */ |
3900 | #ifdef CONFIG_EARLY_PRINTK | ||
3901 | disable_early_printk(); | ||
3902 | #endif | ||
3903 | call = __con_initcall_start; | 3900 | call = __con_initcall_start; |
3904 | while (call < __con_initcall_end) { | 3901 | while (call < __con_initcall_end) { |
3905 | (*call)(); | 3902 | (*call)(); |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 791930320a13..83aeedda200c 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -28,12 +28,13 @@ | |||
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/mutex.h> | ||
31 | #include <linux/vt_kern.h> | 32 | #include <linux/vt_kern.h> |
32 | #include <linux/selection.h> | 33 | #include <linux/selection.h> |
33 | #include <linux/kbd_kern.h> | 34 | #include <linux/kbd_kern.h> |
34 | #include <linux/console.h> | 35 | #include <linux/console.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | |||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | #include <asm/byteorder.h> | 39 | #include <asm/byteorder.h> |
39 | #include <asm/unaligned.h> | 40 | #include <asm/unaligned.h> |
@@ -70,11 +71,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
70 | { | 71 | { |
71 | int size; | 72 | int size; |
72 | 73 | ||
73 | down(&con_buf_sem); | 74 | mutex_lock(&con_buf_mtx); |
74 | size = vcs_size(file->f_path.dentry->d_inode); | 75 | size = vcs_size(file->f_path.dentry->d_inode); |
75 | switch (orig) { | 76 | switch (orig) { |
76 | default: | 77 | default: |
77 | up(&con_buf_sem); | 78 | mutex_unlock(&con_buf_mtx); |
78 | return -EINVAL; | 79 | return -EINVAL; |
79 | case 2: | 80 | case 2: |
80 | offset += size; | 81 | offset += size; |
@@ -85,11 +86,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
85 | break; | 86 | break; |
86 | } | 87 | } |
87 | if (offset < 0 || offset > size) { | 88 | if (offset < 0 || offset > size) { |
88 | up(&con_buf_sem); | 89 | mutex_unlock(&con_buf_mtx); |
89 | return -EINVAL; | 90 | return -EINVAL; |
90 | } | 91 | } |
91 | file->f_pos = offset; | 92 | file->f_pos = offset; |
92 | up(&con_buf_sem); | 93 | mutex_unlock(&con_buf_mtx); |
93 | return file->f_pos; | 94 | return file->f_pos; |
94 | } | 95 | } |
95 | 96 | ||
@@ -106,7 +107,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
106 | unsigned short *org = NULL; | 107 | unsigned short *org = NULL; |
107 | ssize_t ret; | 108 | ssize_t ret; |
108 | 109 | ||
109 | down(&con_buf_sem); | 110 | mutex_lock(&con_buf_mtx); |
110 | 111 | ||
111 | pos = *ppos; | 112 | pos = *ppos; |
112 | 113 | ||
@@ -263,7 +264,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
263 | ret = read; | 264 | ret = read; |
264 | unlock_out: | 265 | unlock_out: |
265 | release_console_sem(); | 266 | release_console_sem(); |
266 | up(&con_buf_sem); | 267 | mutex_unlock(&con_buf_mtx); |
267 | return ret; | 268 | return ret; |
268 | } | 269 | } |
269 | 270 | ||
@@ -280,7 +281,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
280 | u16 *org0 = NULL, *org = NULL; | 281 | u16 *org0 = NULL, *org = NULL; |
281 | size_t ret; | 282 | size_t ret; |
282 | 283 | ||
283 | down(&con_buf_sem); | 284 | mutex_lock(&con_buf_mtx); |
284 | 285 | ||
285 | pos = *ppos; | 286 | pos = *ppos; |
286 | 287 | ||
@@ -450,7 +451,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
450 | unlock_out: | 451 | unlock_out: |
451 | release_console_sem(); | 452 | release_console_sem(); |
452 | 453 | ||
453 | up(&con_buf_sem); | 454 | mutex_unlock(&con_buf_mtx); |
454 | 455 | ||
455 | return ret; | 456 | return ret; |
456 | } | 457 | } |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1bbb45b937fd..bbd9fc412877 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/mm.h> | 86 | #include <linux/mm.h> |
87 | #include <linux/console.h> | 87 | #include <linux/console.h> |
88 | #include <linux/init.h> | 88 | #include <linux/init.h> |
89 | #include <linux/mutex.h> | ||
89 | #include <linux/vt_kern.h> | 90 | #include <linux/vt_kern.h> |
90 | #include <linux/selection.h> | 91 | #include <linux/selection.h> |
91 | #include <linux/tiocl.h> | 92 | #include <linux/tiocl.h> |
@@ -157,6 +158,8 @@ static void blank_screen_t(unsigned long dummy); | |||
157 | static void set_palette(struct vc_data *vc); | 158 | static void set_palette(struct vc_data *vc); |
158 | 159 | ||
159 | static int printable; /* Is console ready for printing? */ | 160 | static int printable; /* Is console ready for printing? */ |
161 | static int default_utf8; | ||
162 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | ||
160 | 163 | ||
161 | /* | 164 | /* |
162 | * ignore_poke: don't unblank the screen when things are typed. This is | 165 | * ignore_poke: don't unblank the screen when things are typed. This is |
@@ -348,10 +351,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count) | |||
348 | 351 | ||
349 | /* Structure of attributes is hardware-dependent */ | 352 | /* Structure of attributes is hardware-dependent */ |
350 | 353 | ||
351 | static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) | 354 | static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, |
355 | u8 _underline, u8 _reverse, u8 _italic) | ||
352 | { | 356 | { |
353 | if (vc->vc_sw->con_build_attr) | 357 | if (vc->vc_sw->con_build_attr) |
354 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse); | 358 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, |
359 | _blink, _underline, _reverse, _italic); | ||
355 | 360 | ||
356 | #ifndef VT_BUF_VRAM_ONLY | 361 | #ifndef VT_BUF_VRAM_ONLY |
357 | /* | 362 | /* |
@@ -368,10 +373,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 | |||
368 | u8 a = vc->vc_color; | 373 | u8 a = vc->vc_color; |
369 | if (!vc->vc_can_do_color) | 374 | if (!vc->vc_can_do_color) |
370 | return _intensity | | 375 | return _intensity | |
376 | (_italic ? 2 : 0) | | ||
371 | (_underline ? 4 : 0) | | 377 | (_underline ? 4 : 0) | |
372 | (_reverse ? 8 : 0) | | 378 | (_reverse ? 8 : 0) | |
373 | (_blink ? 0x80 : 0); | 379 | (_blink ? 0x80 : 0); |
374 | if (_underline) | 380 | if (_italic) |
381 | a = (a & 0xF0) | vc->vc_itcolor; | ||
382 | else if (_underline) | ||
375 | a = (a & 0xf0) | vc->vc_ulcolor; | 383 | a = (a & 0xf0) | vc->vc_ulcolor; |
376 | else if (_intensity == 0) | 384 | else if (_intensity == 0) |
377 | a = (a & 0xf0) | vc->vc_ulcolor; | 385 | a = (a & 0xf0) | vc->vc_ulcolor; |
@@ -392,8 +400,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 | |||
392 | 400 | ||
393 | static void update_attr(struct vc_data *vc) | 401 | static void update_attr(struct vc_data *vc) |
394 | { | 402 | { |
395 | vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm); | 403 | vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, |
396 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' '; | 404 | vc->vc_blink, vc->vc_underline, |
405 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); | ||
406 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; | ||
397 | } | 407 | } |
398 | 408 | ||
399 | /* Note: inverting the screen twice should revert to the original state */ | 409 | /* Note: inverting the screen twice should revert to the original state */ |
@@ -934,6 +944,10 @@ int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, | |||
934 | int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, | 944 | int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, |
935 | 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; | 945 | 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; |
936 | 946 | ||
947 | module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR); | ||
948 | module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR); | ||
949 | module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR); | ||
950 | |||
937 | /* | 951 | /* |
938 | * gotoxy() must verify all boundaries, because the arguments | 952 | * gotoxy() must verify all boundaries, because the arguments |
939 | * might also be negative. If the given position is out of | 953 | * might also be negative. If the given position is out of |
@@ -1132,6 +1146,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi | |||
1132 | static void default_attr(struct vc_data *vc) | 1146 | static void default_attr(struct vc_data *vc) |
1133 | { | 1147 | { |
1134 | vc->vc_intensity = 1; | 1148 | vc->vc_intensity = 1; |
1149 | vc->vc_italic = 0; | ||
1135 | vc->vc_underline = 0; | 1150 | vc->vc_underline = 0; |
1136 | vc->vc_reverse = 0; | 1151 | vc->vc_reverse = 0; |
1137 | vc->vc_blink = 0; | 1152 | vc->vc_blink = 0; |
@@ -1154,6 +1169,9 @@ static void csi_m(struct vc_data *vc) | |||
1154 | case 2: | 1169 | case 2: |
1155 | vc->vc_intensity = 0; | 1170 | vc->vc_intensity = 0; |
1156 | break; | 1171 | break; |
1172 | case 3: | ||
1173 | vc->vc_italic = 1; | ||
1174 | break; | ||
1157 | case 4: | 1175 | case 4: |
1158 | vc->vc_underline = 1; | 1176 | vc->vc_underline = 1; |
1159 | break; | 1177 | break; |
@@ -1194,6 +1212,9 @@ static void csi_m(struct vc_data *vc) | |||
1194 | case 22: | 1212 | case 22: |
1195 | vc->vc_intensity = 1; | 1213 | vc->vc_intensity = 1; |
1196 | break; | 1214 | break; |
1215 | case 23: | ||
1216 | vc->vc_italic = 0; | ||
1217 | break; | ||
1197 | case 24: | 1218 | case 24: |
1198 | vc->vc_underline = 0; | 1219 | vc->vc_underline = 0; |
1199 | break; | 1220 | break; |
@@ -1454,6 +1475,7 @@ static void save_cur(struct vc_data *vc) | |||
1454 | vc->vc_saved_x = vc->vc_x; | 1475 | vc->vc_saved_x = vc->vc_x; |
1455 | vc->vc_saved_y = vc->vc_y; | 1476 | vc->vc_saved_y = vc->vc_y; |
1456 | vc->vc_s_intensity = vc->vc_intensity; | 1477 | vc->vc_s_intensity = vc->vc_intensity; |
1478 | vc->vc_s_italic = vc->vc_italic; | ||
1457 | vc->vc_s_underline = vc->vc_underline; | 1479 | vc->vc_s_underline = vc->vc_underline; |
1458 | vc->vc_s_blink = vc->vc_blink; | 1480 | vc->vc_s_blink = vc->vc_blink; |
1459 | vc->vc_s_reverse = vc->vc_reverse; | 1481 | vc->vc_s_reverse = vc->vc_reverse; |
@@ -1468,6 +1490,7 @@ static void restore_cur(struct vc_data *vc) | |||
1468 | { | 1490 | { |
1469 | gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); | 1491 | gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); |
1470 | vc->vc_intensity = vc->vc_s_intensity; | 1492 | vc->vc_intensity = vc->vc_s_intensity; |
1493 | vc->vc_italic = vc->vc_s_italic; | ||
1471 | vc->vc_underline = vc->vc_s_underline; | 1494 | vc->vc_underline = vc->vc_s_underline; |
1472 | vc->vc_blink = vc->vc_s_blink; | 1495 | vc->vc_blink = vc->vc_s_blink; |
1473 | vc->vc_reverse = vc->vc_s_reverse; | 1496 | vc->vc_reverse = vc->vc_s_reverse; |
@@ -1497,7 +1520,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1497 | vc->vc_charset = 0; | 1520 | vc->vc_charset = 0; |
1498 | vc->vc_need_wrap = 0; | 1521 | vc->vc_need_wrap = 0; |
1499 | vc->vc_report_mouse = 0; | 1522 | vc->vc_report_mouse = 0; |
1500 | vc->vc_utf = 0; | 1523 | vc->vc_utf = default_utf8; |
1501 | vc->vc_utf_count = 0; | 1524 | vc->vc_utf_count = 0; |
1502 | 1525 | ||
1503 | vc->vc_disp_ctrl = 0; | 1526 | vc->vc_disp_ctrl = 0; |
@@ -1930,7 +1953,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1930 | * kernel memory allocation is available. | 1953 | * kernel memory allocation is available. |
1931 | */ | 1954 | */ |
1932 | char con_buf[CON_BUF_SIZE]; | 1955 | char con_buf[CON_BUF_SIZE]; |
1933 | DECLARE_MUTEX(con_buf_sem); | 1956 | DEFINE_MUTEX(con_buf_mtx); |
1957 | |||
1958 | /* is_double_width() is based on the wcwidth() implementation by | ||
1959 | * Markus Kuhn -- 2003-05-20 (Unicode 4.0) | ||
1960 | * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c | ||
1961 | */ | ||
1962 | struct interval { | ||
1963 | uint32_t first; | ||
1964 | uint32_t last; | ||
1965 | }; | ||
1966 | |||
1967 | static int bisearch(uint32_t ucs, const struct interval *table, int max) | ||
1968 | { | ||
1969 | int min = 0; | ||
1970 | int mid; | ||
1971 | |||
1972 | if (ucs < table[0].first || ucs > table[max].last) | ||
1973 | return 0; | ||
1974 | while (max >= min) { | ||
1975 | mid = (min + max) / 2; | ||
1976 | if (ucs > table[mid].last) | ||
1977 | min = mid + 1; | ||
1978 | else if (ucs < table[mid].first) | ||
1979 | max = mid - 1; | ||
1980 | else | ||
1981 | return 1; | ||
1982 | } | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | static int is_double_width(uint32_t ucs) | ||
1987 | { | ||
1988 | static const struct interval double_width[] = { | ||
1989 | { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E }, | ||
1990 | { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF }, | ||
1991 | { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 }, | ||
1992 | { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } | ||
1993 | }; | ||
1994 | return bisearch(ucs, double_width, | ||
1995 | sizeof(double_width) / sizeof(*double_width) - 1); | ||
1996 | } | ||
1934 | 1997 | ||
1935 | /* acquires console_sem */ | 1998 | /* acquires console_sem */ |
1936 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) | 1999 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) |
@@ -1948,6 +2011,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
1948 | unsigned int currcons; | 2011 | unsigned int currcons; |
1949 | unsigned long draw_from = 0, draw_to = 0; | 2012 | unsigned long draw_from = 0, draw_to = 0; |
1950 | struct vc_data *vc; | 2013 | struct vc_data *vc; |
2014 | unsigned char vc_attr; | ||
2015 | uint8_t rescan; | ||
2016 | uint8_t inverse; | ||
2017 | uint8_t width; | ||
1951 | u16 himask, charmask; | 2018 | u16 himask, charmask; |
1952 | const unsigned char *orig_buf = NULL; | 2019 | const unsigned char *orig_buf = NULL; |
1953 | int orig_count; | 2020 | int orig_count; |
@@ -1983,7 +2050,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
1983 | 2050 | ||
1984 | /* At this point 'buf' is guaranteed to be a kernel buffer | 2051 | /* At this point 'buf' is guaranteed to be a kernel buffer |
1985 | * and therefore no access to userspace (and therefore sleeping) | 2052 | * and therefore no access to userspace (and therefore sleeping) |
1986 | * will be needed. The con_buf_sem serializes all tty based | 2053 | * will be needed. The con_buf_mtx serializes all tty based |
1987 | * console rendering and vcs write/read operations. We hold | 2054 | * console rendering and vcs write/read operations. We hold |
1988 | * the console spinlock during the entire write. | 2055 | * the console spinlock during the entire write. |
1989 | */ | 2056 | */ |
@@ -2010,53 +2077,86 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2010 | buf++; | 2077 | buf++; |
2011 | n++; | 2078 | n++; |
2012 | count--; | 2079 | count--; |
2080 | rescan = 0; | ||
2081 | inverse = 0; | ||
2082 | width = 1; | ||
2013 | 2083 | ||
2014 | /* Do no translation at all in control states */ | 2084 | /* Do no translation at all in control states */ |
2015 | if (vc->vc_state != ESnormal) { | 2085 | if (vc->vc_state != ESnormal) { |
2016 | tc = c; | 2086 | tc = c; |
2017 | } else if (vc->vc_utf && !vc->vc_disp_ctrl) { | 2087 | } else if (vc->vc_utf && !vc->vc_disp_ctrl) { |
2018 | /* Combine UTF-8 into Unicode */ | 2088 | /* Combine UTF-8 into Unicode in vc_utf_char. |
2019 | /* Malformed sequences as sequences of replacement glyphs */ | 2089 | * vc_utf_count is the number of continuation bytes still |
2090 | * expected to arrive. | ||
2091 | * vc_npar is the number of continuation bytes arrived so | ||
2092 | * far | ||
2093 | */ | ||
2020 | rescan_last_byte: | 2094 | rescan_last_byte: |
2021 | if(c > 0x7f) { | 2095 | if ((c & 0xc0) == 0x80) { |
2096 | /* Continuation byte received */ | ||
2097 | static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff }; | ||
2022 | if (vc->vc_utf_count) { | 2098 | if (vc->vc_utf_count) { |
2023 | if ((c & 0xc0) == 0x80) { | 2099 | vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); |
2024 | vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); | 2100 | vc->vc_npar++; |
2025 | if (--vc->vc_utf_count) { | 2101 | if (--vc->vc_utf_count) { |
2026 | vc->vc_npar++; | 2102 | /* Still need some bytes */ |
2027 | continue; | ||
2028 | } | ||
2029 | tc = c = vc->vc_utf_char; | ||
2030 | } else | ||
2031 | goto replacement_glyph; | ||
2032 | } else { | ||
2033 | vc->vc_npar = 0; | ||
2034 | if ((c & 0xe0) == 0xc0) { | ||
2035 | vc->vc_utf_count = 1; | ||
2036 | vc->vc_utf_char = (c & 0x1f); | ||
2037 | } else if ((c & 0xf0) == 0xe0) { | ||
2038 | vc->vc_utf_count = 2; | ||
2039 | vc->vc_utf_char = (c & 0x0f); | ||
2040 | } else if ((c & 0xf8) == 0xf0) { | ||
2041 | vc->vc_utf_count = 3; | ||
2042 | vc->vc_utf_char = (c & 0x07); | ||
2043 | } else if ((c & 0xfc) == 0xf8) { | ||
2044 | vc->vc_utf_count = 4; | ||
2045 | vc->vc_utf_char = (c & 0x03); | ||
2046 | } else if ((c & 0xfe) == 0xfc) { | ||
2047 | vc->vc_utf_count = 5; | ||
2048 | vc->vc_utf_char = (c & 0x01); | ||
2049 | } else | ||
2050 | goto replacement_glyph; | ||
2051 | continue; | 2103 | continue; |
2052 | } | 2104 | } |
2105 | /* Got a whole character */ | ||
2106 | c = vc->vc_utf_char; | ||
2107 | /* Reject overlong sequences */ | ||
2108 | if (c <= utf8_length_changes[vc->vc_npar - 1] || | ||
2109 | c > utf8_length_changes[vc->vc_npar]) | ||
2110 | c = 0xfffd; | ||
2111 | } else { | ||
2112 | /* Unexpected continuation byte */ | ||
2113 | vc->vc_utf_count = 0; | ||
2114 | c = 0xfffd; | ||
2115 | } | ||
2053 | } else { | 2116 | } else { |
2054 | if (vc->vc_utf_count) | 2117 | /* Single ASCII byte or first byte of a sequence received */ |
2055 | goto replacement_glyph; | 2118 | if (vc->vc_utf_count) { |
2056 | tc = c; | 2119 | /* Continuation byte expected */ |
2120 | rescan = 1; | ||
2121 | vc->vc_utf_count = 0; | ||
2122 | c = 0xfffd; | ||
2123 | } else if (c > 0x7f) { | ||
2124 | /* First byte of a multibyte sequence received */ | ||
2125 | vc->vc_npar = 0; | ||
2126 | if ((c & 0xe0) == 0xc0) { | ||
2127 | vc->vc_utf_count = 1; | ||
2128 | vc->vc_utf_char = (c & 0x1f); | ||
2129 | } else if ((c & 0xf0) == 0xe0) { | ||
2130 | vc->vc_utf_count = 2; | ||
2131 | vc->vc_utf_char = (c & 0x0f); | ||
2132 | } else if ((c & 0xf8) == 0xf0) { | ||
2133 | vc->vc_utf_count = 3; | ||
2134 | vc->vc_utf_char = (c & 0x07); | ||
2135 | } else if ((c & 0xfc) == 0xf8) { | ||
2136 | vc->vc_utf_count = 4; | ||
2137 | vc->vc_utf_char = (c & 0x03); | ||
2138 | } else if ((c & 0xfe) == 0xfc) { | ||
2139 | vc->vc_utf_count = 5; | ||
2140 | vc->vc_utf_char = (c & 0x01); | ||
2141 | } else { | ||
2142 | /* 254 and 255 are invalid */ | ||
2143 | c = 0xfffd; | ||
2144 | } | ||
2145 | if (vc->vc_utf_count) { | ||
2146 | /* Still need some bytes */ | ||
2147 | continue; | ||
2148 | } | ||
2149 | } | ||
2150 | /* Nothing to do if an ASCII byte was received */ | ||
2057 | } | 2151 | } |
2152 | /* End of UTF-8 decoding. */ | ||
2153 | /* c is the received character, or U+FFFD for invalid sequences. */ | ||
2154 | /* Replace invalid Unicode code points with U+FFFD too */ | ||
2155 | if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) | ||
2156 | c = 0xfffd; | ||
2157 | tc = c; | ||
2058 | } else { /* no utf or alternate charset mode */ | 2158 | } else { /* no utf or alternate charset mode */ |
2059 | tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; | 2159 | tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; |
2060 | } | 2160 | } |
2061 | 2161 | ||
2062 | /* If the original code was a control character we | 2162 | /* If the original code was a control character we |
@@ -2076,56 +2176,80 @@ rescan_last_byte: | |||
2076 | && (c != 128+27); | 2176 | && (c != 128+27); |
2077 | 2177 | ||
2078 | if (vc->vc_state == ESnormal && ok) { | 2178 | if (vc->vc_state == ESnormal && ok) { |
2179 | if (vc->vc_utf && !vc->vc_disp_ctrl) { | ||
2180 | if (is_double_width(c)) | ||
2181 | width = 2; | ||
2182 | } | ||
2079 | /* Now try to find out how to display it */ | 2183 | /* Now try to find out how to display it */ |
2080 | tc = conv_uni_to_pc(vc, tc); | 2184 | tc = conv_uni_to_pc(vc, tc); |
2081 | if (tc & ~charmask) { | 2185 | if (tc & ~charmask) { |
2082 | if ( tc == -4 ) { | 2186 | if (tc == -1 || tc == -2) { |
2083 | /* If we got -4 (not found) then see if we have | 2187 | continue; /* nothing to display */ |
2084 | defined a replacement character (U+FFFD) */ | 2188 | } |
2085 | replacement_glyph: | 2189 | /* Glyph not found */ |
2086 | tc = conv_uni_to_pc(vc, 0xfffd); | 2190 | if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) { |
2087 | if (!(tc & ~charmask)) | 2191 | /* In legacy mode use the glyph we get by a 1:1 mapping. |
2088 | goto display_glyph; | 2192 | This would make absolutely no sense with Unicode in mind. */ |
2089 | } else if ( tc != -3 ) | 2193 | tc = c; |
2090 | continue; /* nothing to display */ | 2194 | } else { |
2091 | /* no hash table or no replacement -- | 2195 | /* Display U+FFFD. If it's not found, display an inverse question mark. */ |
2092 | * hope for the best */ | 2196 | tc = conv_uni_to_pc(vc, 0xfffd); |
2093 | if ( c & ~charmask ) | 2197 | if (tc < 0) { |
2094 | tc = '?'; | 2198 | inverse = 1; |
2095 | else | 2199 | tc = conv_uni_to_pc(vc, '?'); |
2096 | tc = c; | 2200 | if (tc < 0) tc = '?'; |
2201 | } | ||
2202 | } | ||
2097 | } | 2203 | } |
2098 | 2204 | ||
2099 | display_glyph: | 2205 | if (!inverse) { |
2100 | if (vc->vc_need_wrap || vc->vc_decim) | 2206 | vc_attr = vc->vc_attr; |
2101 | FLUSH | ||
2102 | if (vc->vc_need_wrap) { | ||
2103 | cr(vc); | ||
2104 | lf(vc); | ||
2105 | } | ||
2106 | if (vc->vc_decim) | ||
2107 | insert_char(vc, 1); | ||
2108 | scr_writew(himask ? | ||
2109 | ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : | ||
2110 | (vc->vc_attr << 8) + tc, | ||
2111 | (u16 *) vc->vc_pos); | ||
2112 | if (DO_UPDATE(vc) && draw_x < 0) { | ||
2113 | draw_x = vc->vc_x; | ||
2114 | draw_from = vc->vc_pos; | ||
2115 | } | ||
2116 | if (vc->vc_x == vc->vc_cols - 1) { | ||
2117 | vc->vc_need_wrap = vc->vc_decawm; | ||
2118 | draw_to = vc->vc_pos + 2; | ||
2119 | } else { | 2207 | } else { |
2120 | vc->vc_x++; | 2208 | /* invert vc_attr */ |
2121 | draw_to = (vc->vc_pos += 2); | 2209 | if (!vc->vc_can_do_color) { |
2210 | vc_attr = (vc->vc_attr) ^ 0x08; | ||
2211 | } else if (vc->vc_hi_font_mask == 0x100) { | ||
2212 | vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4); | ||
2213 | } else { | ||
2214 | vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); | ||
2215 | } | ||
2122 | } | 2216 | } |
2123 | if (vc->vc_utf_count) { | 2217 | |
2124 | if (vc->vc_npar) { | 2218 | while (1) { |
2125 | vc->vc_npar--; | 2219 | if (vc->vc_need_wrap || vc->vc_decim) |
2126 | goto display_glyph; | 2220 | FLUSH |
2221 | if (vc->vc_need_wrap) { | ||
2222 | cr(vc); | ||
2223 | lf(vc); | ||
2224 | } | ||
2225 | if (vc->vc_decim) | ||
2226 | insert_char(vc, 1); | ||
2227 | scr_writew(himask ? | ||
2228 | ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : | ||
2229 | (vc_attr << 8) + tc, | ||
2230 | (u16 *) vc->vc_pos); | ||
2231 | if (DO_UPDATE(vc) && draw_x < 0) { | ||
2232 | draw_x = vc->vc_x; | ||
2233 | draw_from = vc->vc_pos; | ||
2234 | } | ||
2235 | if (vc->vc_x == vc->vc_cols - 1) { | ||
2236 | vc->vc_need_wrap = vc->vc_decawm; | ||
2237 | draw_to = vc->vc_pos + 2; | ||
2238 | } else { | ||
2239 | vc->vc_x++; | ||
2240 | draw_to = (vc->vc_pos += 2); | ||
2127 | } | 2241 | } |
2128 | vc->vc_utf_count = 0; | 2242 | |
2243 | if (!--width) break; | ||
2244 | |||
2245 | tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */ | ||
2246 | if (tc < 0) tc = ' '; | ||
2247 | } | ||
2248 | |||
2249 | if (rescan) { | ||
2250 | rescan = 0; | ||
2251 | inverse = 0; | ||
2252 | width = 1; | ||
2129 | c = orig; | 2253 | c = orig; |
2130 | goto rescan_last_byte; | 2254 | goto rescan_last_byte; |
2131 | } | 2255 | } |
@@ -2581,6 +2705,11 @@ static void con_close(struct tty_struct *tty, struct file *filp) | |||
2581 | mutex_unlock(&tty_mutex); | 2705 | mutex_unlock(&tty_mutex); |
2582 | } | 2706 | } |
2583 | 2707 | ||
2708 | static int default_italic_color = 2; // green (ASCII) | ||
2709 | static int default_underline_color = 3; // cyan (ASCII) | ||
2710 | module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR); | ||
2711 | module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR); | ||
2712 | |||
2584 | static void vc_init(struct vc_data *vc, unsigned int rows, | 2713 | static void vc_init(struct vc_data *vc, unsigned int rows, |
2585 | unsigned int cols, int do_clear) | 2714 | unsigned int cols, int do_clear) |
2586 | { | 2715 | { |
@@ -2600,7 +2729,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows, | |||
2600 | vc->vc_palette[k++] = default_blu[j] ; | 2729 | vc->vc_palette[k++] = default_blu[j] ; |
2601 | } | 2730 | } |
2602 | vc->vc_def_color = 0x07; /* white */ | 2731 | vc->vc_def_color = 0x07; /* white */ |
2603 | vc->vc_ulcolor = 0x0f; /* bold white */ | 2732 | vc->vc_ulcolor = default_underline_color; |
2733 | vc->vc_itcolor = default_italic_color; | ||
2604 | vc->vc_halfcolor = 0x08; /* grey */ | 2734 | vc->vc_halfcolor = 0x08; /* grey */ |
2605 | init_waitqueue_head(&vc->paste_wait); | 2735 | init_waitqueue_head(&vc->paste_wait); |
2606 | reset_terminal(vc, do_clear); | 2736 | reset_terminal(vc, do_clear); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c9f2dd620e87..c6f6f4209739 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -1061,7 +1061,7 @@ int vt_waitactive(int vt) | |||
1061 | schedule(); | 1061 | schedule(); |
1062 | } | 1062 | } |
1063 | remove_wait_queue(&vt_activate_queue, &wait); | 1063 | remove_wait_queue(&vt_activate_queue, &wait); |
1064 | current->state = TASK_RUNNING; | 1064 | __set_current_state(TASK_RUNNING); |
1065 | return retval; | 1065 | return retval; |
1066 | } | 1066 | } |
1067 | 1067 | ||
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c index 84074a697dce..b36fa8de2131 100644 --- a/drivers/char/watchdog/omap_wdt.c +++ b/drivers/char/watchdog/omap_wdt.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
35 | #include <linux/watchdog.h> | 35 | #include <linux/watchdog.h> |
36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/err.h> | 38 | #include <linux/err.h> |
40 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8d053f500fc2..8532bb79e5fc 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -470,7 +470,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) | |||
470 | dbs_info->enable = 1; | 470 | dbs_info->enable = 1; |
471 | ondemand_powersave_bias_init(); | 471 | ondemand_powersave_bias_init(); |
472 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | 472 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
473 | INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer); | 473 | INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); |
474 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, | 474 | queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, |
475 | delay); | 475 | delay); |
476 | } | 476 | } |
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 161fe09a6d38..2800b3e614a9 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
@@ -261,10 +261,6 @@ static void i82875p_check(struct mem_ctl_info *mci) | |||
261 | i82875p_process_error_info(mci, &info, 1); | 261 | i82875p_process_error_info(mci, &info, 1); |
262 | } | 262 | } |
263 | 263 | ||
264 | #ifdef CONFIG_PROC_FS | ||
265 | extern int pci_proc_attach_device(struct pci_dev *); | ||
266 | #endif | ||
267 | |||
268 | /* Return 0 on success or 1 on failure. */ | 264 | /* Return 0 on success or 1 on failure. */ |
269 | static int i82875p_setup_overfl_dev(struct pci_dev *pdev, | 265 | static int i82875p_setup_overfl_dev(struct pci_dev *pdev, |
270 | struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window) | 266 | struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window) |
@@ -287,17 +283,12 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev, | |||
287 | 283 | ||
288 | if (dev == NULL) | 284 | if (dev == NULL) |
289 | return 1; | 285 | return 1; |
286 | |||
287 | pci_bus_add_device(dev); | ||
290 | } | 288 | } |
291 | 289 | ||
292 | *ovrfl_pdev = dev; | 290 | *ovrfl_pdev = dev; |
293 | 291 | ||
294 | #ifdef CONFIG_PROC_FS | ||
295 | if ((dev->procent == NULL) && pci_proc_attach_device(dev)) { | ||
296 | i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow " | ||
297 | "device\n", __func__); | ||
298 | return 1; | ||
299 | } | ||
300 | #endif /* CONFIG_PROC_FS */ | ||
301 | if (pci_enable_device(dev)) { | 292 | if (pci_enable_device(dev)) { |
302 | i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow " | 293 | i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow " |
303 | "device\n", __func__); | 294 | "device\n", __func__); |
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c index 9b4fcac03ad5..3074879f231f 100644 --- a/drivers/eisa/virtual_root.c +++ b/drivers/eisa/virtual_root.c | |||
@@ -47,7 +47,7 @@ static void virtual_eisa_release (struct device *dev) | |||
47 | /* nothing really to do here */ | 47 | /* nothing really to do here */ |
48 | } | 48 | } |
49 | 49 | ||
50 | static int virtual_eisa_root_init (void) | 50 | static int __init virtual_eisa_root_init (void) |
51 | { | 51 | { |
52 | int r; | 52 | int r; |
53 | 53 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 62e21cc73938..6ec04e79f685 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/smp_lock.h> | ||
24 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
25 | #include <asm/unaligned.h> | 24 | #include <asm/unaligned.h> |
26 | #include <asm/byteorder.h> | 25 | #include <asm/byteorder.h> |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6d105a1d41b1..25b72a491702 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -594,6 +594,30 @@ config SENSORS_HDAPS | |||
594 | Say Y here if you have an applicable laptop and want to experience | 594 | Say Y here if you have an applicable laptop and want to experience |
595 | the awesome power of hdaps. | 595 | the awesome power of hdaps. |
596 | 596 | ||
597 | config SENSORS_APPLESMC | ||
598 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" | ||
599 | depends on HWMON && INPUT && X86 | ||
600 | select NEW_LEDS | ||
601 | select LEDS_CLASS | ||
602 | default n | ||
603 | help | ||
604 | This driver provides support for the Apple System Management | ||
605 | Controller, which provides an accelerometer (Apple Sudden Motion | ||
606 | Sensor), light sensors, temperature sensors, keyboard backlight | ||
607 | control and fan control. | ||
608 | |||
609 | Only Intel-based Apple's computers are supported (MacBook Pro, | ||
610 | MacBook, MacMini). | ||
611 | |||
612 | Data from the different sensors, keyboard backlight control and fan | ||
613 | control are accessible via sysfs. | ||
614 | |||
615 | This driver also provides an absolute input class device, allowing | ||
616 | the laptop to act as a pinball machine-esque joystick. | ||
617 | |||
618 | Say Y here if you have an applicable laptop and want to experience | ||
619 | the awesome power of applesmc. | ||
620 | |||
597 | config HWMON_DEBUG_CHIP | 621 | config HWMON_DEBUG_CHIP |
598 | bool "Hardware Monitoring Chip debugging messages" | 622 | bool "Hardware Monitoring Chip debugging messages" |
599 | depends on HWMON | 623 | depends on HWMON |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 4165c27a2f25..544f8d8dff4e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | |||
20 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | 20 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o |
21 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 21 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
22 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 22 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
23 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | ||
23 | obj-$(CONFIG_SENSORS_AMS) += ams/ | 24 | obj-$(CONFIG_SENSORS_AMS) += ams/ |
24 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 25 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
25 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 26 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c new file mode 100644 index 000000000000..3215f9c87f32 --- /dev/null +++ b/drivers/hwmon/applesmc.c | |||
@@ -0,0 +1,1339 @@ | |||
1 | /* | ||
2 | * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature | ||
3 | * sensors, fan control, keyboard backlight control) used in Intel-based Apple | ||
4 | * computers. | ||
5 | * | ||
6 | * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch> | ||
7 | * | ||
8 | * Based on hdaps.c driver: | ||
9 | * Copyright (C) 2005 Robert Love <rml@novell.com> | ||
10 | * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> | ||
11 | * | ||
12 | * Fan control based on smcFanControl: | ||
13 | * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License v2 as published by the | ||
17 | * Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
20 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
22 | * more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along with | ||
25 | * this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
27 | */ | ||
28 | |||
29 | #include <linux/delay.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/dmi.h> | ||
36 | #include <linux/mutex.h> | ||
37 | #include <linux/hwmon-sysfs.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <linux/leds.h> | ||
40 | #include <linux/hwmon.h> | ||
41 | #include <linux/workqueue.h> | ||
42 | |||
43 | /* data port used by Apple SMC */ | ||
44 | #define APPLESMC_DATA_PORT 0x300 | ||
45 | /* command/status port used by Apple SMC */ | ||
46 | #define APPLESMC_CMD_PORT 0x304 | ||
47 | |||
48 | #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ | ||
49 | |||
50 | #define APPLESMC_MAX_DATA_LENGTH 32 | ||
51 | |||
52 | #define APPLESMC_STATUS_MASK 0x0f | ||
53 | #define APPLESMC_READ_CMD 0x10 | ||
54 | #define APPLESMC_WRITE_CMD 0x11 | ||
55 | #define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 | ||
56 | #define APPLESMC_GET_KEY_TYPE_CMD 0x13 | ||
57 | |||
58 | #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ | ||
59 | |||
60 | #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ | ||
61 | #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ | ||
62 | #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ | ||
63 | |||
64 | #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ | ||
65 | |||
66 | #define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */ | ||
67 | #define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */ | ||
68 | #define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */ | ||
69 | #define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */ | ||
70 | |||
71 | #define FANS_COUNT "FNum" /* r-o ui8 */ | ||
72 | #define FANS_MANUAL "FS! " /* r-w ui16 */ | ||
73 | #define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ | ||
74 | #define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */ | ||
75 | #define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */ | ||
76 | #define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */ | ||
77 | #define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */ | ||
78 | #define FAN_POSITION "F0ID" /* r-o char[16] */ | ||
79 | |||
80 | /* | ||
81 | * Temperature sensors keys (sp78 - 2 bytes). | ||
82 | * First set for Macbook(Pro), second for Macmini. | ||
83 | */ | ||
84 | static const char* temperature_sensors_sets[][13] = { | ||
85 | { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", | ||
86 | "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, | ||
87 | { "TC0D", "TC0P", NULL } | ||
88 | }; | ||
89 | |||
90 | /* List of keys used to read/write fan speeds */ | ||
91 | static const char* fan_speed_keys[] = { | ||
92 | FAN_ACTUAL_SPEED, | ||
93 | FAN_MIN_SPEED, | ||
94 | FAN_MAX_SPEED, | ||
95 | FAN_SAFE_SPEED, | ||
96 | FAN_TARGET_SPEED | ||
97 | }; | ||
98 | |||
99 | #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ | ||
100 | #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ | ||
101 | |||
102 | #define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */ | ||
103 | #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ | ||
104 | #define APPLESMC_INPUT_FLAT 4 | ||
105 | |||
106 | #define SENSOR_X 0 | ||
107 | #define SENSOR_Y 1 | ||
108 | #define SENSOR_Z 2 | ||
109 | |||
110 | /* Structure to be passed to DMI_MATCH function */ | ||
111 | struct dmi_match_data { | ||
112 | /* Indicates whether this computer has an accelerometer. */ | ||
113 | int accelerometer; | ||
114 | /* Indicates whether this computer has light sensors and keyboard backlight. */ | ||
115 | int light; | ||
116 | /* Indicates which temperature sensors set to use. */ | ||
117 | int temperature_set; | ||
118 | }; | ||
119 | |||
120 | static const int debug; | ||
121 | static struct platform_device *pdev; | ||
122 | static s16 rest_x; | ||
123 | static s16 rest_y; | ||
124 | static struct timer_list applesmc_timer; | ||
125 | static struct input_dev *applesmc_idev; | ||
126 | static struct class_device *hwmon_class_dev; | ||
127 | |||
128 | /* Indicates whether this computer has an accelerometer. */ | ||
129 | static unsigned int applesmc_accelerometer; | ||
130 | |||
131 | /* Indicates whether this computer has light sensors and keyboard backlight. */ | ||
132 | static unsigned int applesmc_light; | ||
133 | |||
134 | /* Indicates which temperature sensors set to use. */ | ||
135 | static unsigned int applesmc_temperature_set; | ||
136 | |||
137 | static struct mutex applesmc_lock; | ||
138 | |||
139 | /* | ||
140 | * Last index written to key_at_index sysfs file, and value to use for all other | ||
141 | * key_at_index_* sysfs files. | ||
142 | */ | ||
143 | static unsigned int key_at_index; | ||
144 | |||
145 | static struct workqueue_struct *applesmc_led_wq; | ||
146 | |||
147 | /* | ||
148 | * __wait_status - Wait up to 2ms for the status port to get a certain value | ||
149 | * (masked with 0x0f), returning zero if the value is obtained. Callers must | ||
150 | * hold applesmc_lock. | ||
151 | */ | ||
152 | static int __wait_status(u8 val) | ||
153 | { | ||
154 | unsigned int i; | ||
155 | |||
156 | val = val & APPLESMC_STATUS_MASK; | ||
157 | |||
158 | for (i = 0; i < 200; i++) { | ||
159 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { | ||
160 | if (debug) | ||
161 | printk(KERN_DEBUG | ||
162 | "Waited %d us for status %x\n", | ||
163 | i*10, val); | ||
164 | return 0; | ||
165 | } | ||
166 | udelay(10); | ||
167 | } | ||
168 | |||
169 | printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", | ||
170 | val, inb(APPLESMC_CMD_PORT)); | ||
171 | |||
172 | return -EIO; | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. | ||
177 | * Returns zero on success or a negative error on failure. Callers must | ||
178 | * hold applesmc_lock. | ||
179 | */ | ||
180 | static int applesmc_read_key(const char* key, u8* buffer, u8 len) | ||
181 | { | ||
182 | int i; | ||
183 | |||
184 | if (len > APPLESMC_MAX_DATA_LENGTH) { | ||
185 | printk(KERN_ERR "applesmc_read_key: cannot read more than " | ||
186 | "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); | ||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); | ||
191 | if (__wait_status(0x0c)) | ||
192 | return -EIO; | ||
193 | |||
194 | for (i = 0; i < 4; i++) { | ||
195 | outb(key[i], APPLESMC_DATA_PORT); | ||
196 | if (__wait_status(0x04)) | ||
197 | return -EIO; | ||
198 | } | ||
199 | if (debug) | ||
200 | printk(KERN_DEBUG "<%s", key); | ||
201 | |||
202 | outb(len, APPLESMC_DATA_PORT); | ||
203 | if (debug) | ||
204 | printk(KERN_DEBUG ">%x", len); | ||
205 | |||
206 | for (i = 0; i < len; i++) { | ||
207 | if (__wait_status(0x05)) | ||
208 | return -EIO; | ||
209 | buffer[i] = inb(APPLESMC_DATA_PORT); | ||
210 | if (debug) | ||
211 | printk(KERN_DEBUG "<%x", buffer[i]); | ||
212 | } | ||
213 | if (debug) | ||
214 | printk(KERN_DEBUG "\n"); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * applesmc_write_key - writes len bytes from buffer to a given key. | ||
221 | * Returns zero on success or a negative error on failure. Callers must | ||
222 | * hold applesmc_lock. | ||
223 | */ | ||
224 | static int applesmc_write_key(const char* key, u8* buffer, u8 len) | ||
225 | { | ||
226 | int i; | ||
227 | |||
228 | if (len > APPLESMC_MAX_DATA_LENGTH) { | ||
229 | printk(KERN_ERR "applesmc_write_key: cannot write more than " | ||
230 | "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | |||
234 | outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); | ||
235 | if (__wait_status(0x0c)) | ||
236 | return -EIO; | ||
237 | |||
238 | for (i = 0; i < 4; i++) { | ||
239 | outb(key[i], APPLESMC_DATA_PORT); | ||
240 | if (__wait_status(0x04)) | ||
241 | return -EIO; | ||
242 | } | ||
243 | |||
244 | outb(len, APPLESMC_DATA_PORT); | ||
245 | |||
246 | for (i = 0; i < len; i++) { | ||
247 | if (__wait_status(0x04)) | ||
248 | return -EIO; | ||
249 | outb(buffer[i], APPLESMC_DATA_PORT); | ||
250 | } | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * applesmc_get_key_at_index - get key at index, and put the result in key | ||
257 | * (char[6]). Returns zero on success or a negative error on failure. Callers | ||
258 | * must hold applesmc_lock. | ||
259 | */ | ||
260 | static int applesmc_get_key_at_index(int index, char* key) | ||
261 | { | ||
262 | int i; | ||
263 | u8 readkey[4]; | ||
264 | readkey[0] = index >> 24; | ||
265 | readkey[1] = index >> 16; | ||
266 | readkey[2] = index >> 8; | ||
267 | readkey[3] = index; | ||
268 | |||
269 | outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); | ||
270 | if (__wait_status(0x0c)) | ||
271 | return -EIO; | ||
272 | |||
273 | for (i = 0; i < 4; i++) { | ||
274 | outb(readkey[i], APPLESMC_DATA_PORT); | ||
275 | if (__wait_status(0x04)) | ||
276 | return -EIO; | ||
277 | } | ||
278 | |||
279 | outb(4, APPLESMC_DATA_PORT); | ||
280 | |||
281 | for (i = 0; i < 4; i++) { | ||
282 | if (__wait_status(0x05)) | ||
283 | return -EIO; | ||
284 | key[i] = inb(APPLESMC_DATA_PORT); | ||
285 | } | ||
286 | key[4] = 0; | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * applesmc_get_key_type - get key type, and put the result in type (char[6]). | ||
293 | * Returns zero on success or a negative error on failure. Callers must | ||
294 | * hold applesmc_lock. | ||
295 | */ | ||
296 | static int applesmc_get_key_type(char* key, char* type) | ||
297 | { | ||
298 | int i; | ||
299 | |||
300 | outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT); | ||
301 | if (__wait_status(0x0c)) | ||
302 | return -EIO; | ||
303 | |||
304 | for (i = 0; i < 4; i++) { | ||
305 | outb(key[i], APPLESMC_DATA_PORT); | ||
306 | if (__wait_status(0x04)) | ||
307 | return -EIO; | ||
308 | } | ||
309 | |||
310 | outb(5, APPLESMC_DATA_PORT); | ||
311 | |||
312 | for (i = 0; i < 6; i++) { | ||
313 | if (__wait_status(0x05)) | ||
314 | return -EIO; | ||
315 | type[i] = inb(APPLESMC_DATA_PORT); | ||
316 | } | ||
317 | type[5] = 0; | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must | ||
324 | * hold applesmc_lock. | ||
325 | */ | ||
326 | static int applesmc_read_motion_sensor(int index, s16* value) | ||
327 | { | ||
328 | u8 buffer[2]; | ||
329 | int ret; | ||
330 | |||
331 | switch (index) { | ||
332 | case SENSOR_X: | ||
333 | ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2); | ||
334 | break; | ||
335 | case SENSOR_Y: | ||
336 | ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2); | ||
337 | break; | ||
338 | case SENSOR_Z: | ||
339 | ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2); | ||
340 | break; | ||
341 | default: | ||
342 | ret = -EINVAL; | ||
343 | } | ||
344 | |||
345 | *value = ((s16)buffer[0] << 8) | buffer[1]; | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * applesmc_device_init - initialize the accelerometer. Returns zero on success | ||
352 | * and negative error code on failure. Can sleep. | ||
353 | */ | ||
354 | static int applesmc_device_init(void) | ||
355 | { | ||
356 | int total, ret = -ENXIO; | ||
357 | u8 buffer[2]; | ||
358 | |||
359 | if (!applesmc_accelerometer) | ||
360 | return 0; | ||
361 | |||
362 | mutex_lock(&applesmc_lock); | ||
363 | |||
364 | for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { | ||
365 | if (debug) | ||
366 | printk(KERN_DEBUG "applesmc try %d\n", total); | ||
367 | if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && | ||
368 | (buffer[0] != 0x00 || buffer[1] != 0x00)) { | ||
369 | if (total == INIT_TIMEOUT_MSECS) { | ||
370 | printk(KERN_DEBUG "applesmc: device has" | ||
371 | " already been initialized" | ||
372 | " (0x%02x, 0x%02x).\n", | ||
373 | buffer[0], buffer[1]); | ||
374 | } else { | ||
375 | printk(KERN_DEBUG "applesmc: device" | ||
376 | " successfully initialized" | ||
377 | " (0x%02x, 0x%02x).\n", | ||
378 | buffer[0], buffer[1]); | ||
379 | } | ||
380 | ret = 0; | ||
381 | goto out; | ||
382 | } | ||
383 | buffer[0] = 0xe0; | ||
384 | buffer[1] = 0x00; | ||
385 | applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); | ||
386 | msleep(INIT_WAIT_MSECS); | ||
387 | } | ||
388 | |||
389 | printk(KERN_WARNING "applesmc: failed to init the device\n"); | ||
390 | |||
391 | out: | ||
392 | mutex_unlock(&applesmc_lock); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * applesmc_get_fan_count - get the number of fans. Callers must NOT hold | ||
398 | * applesmc_lock. | ||
399 | */ | ||
400 | static int applesmc_get_fan_count(void) | ||
401 | { | ||
402 | int ret; | ||
403 | u8 buffer[1]; | ||
404 | |||
405 | mutex_lock(&applesmc_lock); | ||
406 | |||
407 | ret = applesmc_read_key(FANS_COUNT, buffer, 1); | ||
408 | |||
409 | mutex_unlock(&applesmc_lock); | ||
410 | if (ret) | ||
411 | return ret; | ||
412 | else | ||
413 | return buffer[0]; | ||
414 | } | ||
415 | |||
416 | /* Device model stuff */ | ||
417 | static int applesmc_probe(struct platform_device *dev) | ||
418 | { | ||
419 | int ret; | ||
420 | |||
421 | ret = applesmc_device_init(); | ||
422 | if (ret) | ||
423 | return ret; | ||
424 | |||
425 | printk(KERN_INFO "applesmc: device successfully initialized.\n"); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int applesmc_resume(struct platform_device *dev) | ||
430 | { | ||
431 | return applesmc_device_init(); | ||
432 | } | ||
433 | |||
434 | static struct platform_driver applesmc_driver = { | ||
435 | .probe = applesmc_probe, | ||
436 | .resume = applesmc_resume, | ||
437 | .driver = { | ||
438 | .name = "applesmc", | ||
439 | .owner = THIS_MODULE, | ||
440 | }, | ||
441 | }; | ||
442 | |||
443 | /* | ||
444 | * applesmc_calibrate - Set our "resting" values. Callers must | ||
445 | * hold applesmc_lock. | ||
446 | */ | ||
447 | static void applesmc_calibrate(void) | ||
448 | { | ||
449 | applesmc_read_motion_sensor(SENSOR_X, &rest_x); | ||
450 | applesmc_read_motion_sensor(SENSOR_Y, &rest_y); | ||
451 | rest_x = -rest_x; | ||
452 | } | ||
453 | |||
454 | static int applesmc_idev_open(struct input_dev *dev) | ||
455 | { | ||
456 | add_timer(&applesmc_timer); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static void applesmc_idev_close(struct input_dev *dev) | ||
462 | { | ||
463 | del_timer_sync(&applesmc_timer); | ||
464 | } | ||
465 | |||
466 | static void applesmc_idev_poll(unsigned long unused) | ||
467 | { | ||
468 | s16 x, y; | ||
469 | |||
470 | /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ | ||
471 | if (!mutex_trylock(&applesmc_lock)) { | ||
472 | mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | if (applesmc_read_motion_sensor(SENSOR_X, &x)) | ||
477 | goto out; | ||
478 | if (applesmc_read_motion_sensor(SENSOR_Y, &y)) | ||
479 | goto out; | ||
480 | |||
481 | x = -x; | ||
482 | input_report_abs(applesmc_idev, ABS_X, x - rest_x); | ||
483 | input_report_abs(applesmc_idev, ABS_Y, y - rest_y); | ||
484 | input_sync(applesmc_idev); | ||
485 | |||
486 | out: | ||
487 | mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); | ||
488 | |||
489 | mutex_unlock(&applesmc_lock); | ||
490 | } | ||
491 | |||
492 | /* Sysfs Files */ | ||
493 | |||
494 | static ssize_t applesmc_position_show(struct device *dev, | ||
495 | struct device_attribute *attr, char *buf) | ||
496 | { | ||
497 | int ret; | ||
498 | s16 x, y, z; | ||
499 | |||
500 | mutex_lock(&applesmc_lock); | ||
501 | |||
502 | ret = applesmc_read_motion_sensor(SENSOR_X, &x); | ||
503 | if (ret) | ||
504 | goto out; | ||
505 | ret = applesmc_read_motion_sensor(SENSOR_Y, &y); | ||
506 | if (ret) | ||
507 | goto out; | ||
508 | ret = applesmc_read_motion_sensor(SENSOR_Z, &z); | ||
509 | if (ret) | ||
510 | goto out; | ||
511 | |||
512 | out: | ||
513 | mutex_unlock(&applesmc_lock); | ||
514 | if (ret) | ||
515 | return ret; | ||
516 | else | ||
517 | return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z); | ||
518 | } | ||
519 | |||
520 | static ssize_t applesmc_light_show(struct device *dev, | ||
521 | struct device_attribute *attr, char *sysfsbuf) | ||
522 | { | ||
523 | int ret; | ||
524 | u8 left = 0, right = 0; | ||
525 | u8 buffer[6]; | ||
526 | |||
527 | mutex_lock(&applesmc_lock); | ||
528 | |||
529 | ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6); | ||
530 | left = buffer[2]; | ||
531 | if (ret) | ||
532 | goto out; | ||
533 | ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6); | ||
534 | right = buffer[2]; | ||
535 | |||
536 | out: | ||
537 | mutex_unlock(&applesmc_lock); | ||
538 | if (ret) | ||
539 | return ret; | ||
540 | else | ||
541 | return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); | ||
542 | } | ||
543 | |||
544 | /* Displays degree Celsius * 1000 */ | ||
545 | static ssize_t applesmc_show_temperature(struct device *dev, | ||
546 | struct device_attribute *devattr, char *sysfsbuf) | ||
547 | { | ||
548 | int ret; | ||
549 | u8 buffer[2]; | ||
550 | unsigned int temp; | ||
551 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
552 | const char* key = | ||
553 | temperature_sensors_sets[applesmc_temperature_set][attr->index]; | ||
554 | |||
555 | mutex_lock(&applesmc_lock); | ||
556 | |||
557 | ret = applesmc_read_key(key, buffer, 2); | ||
558 | temp = buffer[0]*1000; | ||
559 | temp += (buffer[1] >> 6) * 250; | ||
560 | |||
561 | mutex_unlock(&applesmc_lock); | ||
562 | |||
563 | if (ret) | ||
564 | return ret; | ||
565 | else | ||
566 | return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); | ||
567 | } | ||
568 | |||
569 | static ssize_t applesmc_show_fan_speed(struct device *dev, | ||
570 | struct device_attribute *attr, char *sysfsbuf) | ||
571 | { | ||
572 | int ret; | ||
573 | unsigned int speed = 0; | ||
574 | char newkey[5]; | ||
575 | u8 buffer[2]; | ||
576 | struct sensor_device_attribute_2 *sensor_attr = | ||
577 | to_sensor_dev_attr_2(attr); | ||
578 | |||
579 | newkey[0] = fan_speed_keys[sensor_attr->nr][0]; | ||
580 | newkey[1] = '0' + sensor_attr->index; | ||
581 | newkey[2] = fan_speed_keys[sensor_attr->nr][2]; | ||
582 | newkey[3] = fan_speed_keys[sensor_attr->nr][3]; | ||
583 | newkey[4] = 0; | ||
584 | |||
585 | mutex_lock(&applesmc_lock); | ||
586 | |||
587 | ret = applesmc_read_key(newkey, buffer, 2); | ||
588 | speed = ((buffer[0] << 8 | buffer[1]) >> 2); | ||
589 | |||
590 | mutex_unlock(&applesmc_lock); | ||
591 | if (ret) | ||
592 | return ret; | ||
593 | else | ||
594 | return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); | ||
595 | } | ||
596 | |||
597 | static ssize_t applesmc_store_fan_speed(struct device *dev, | ||
598 | struct device_attribute *attr, | ||
599 | const char *sysfsbuf, size_t count) | ||
600 | { | ||
601 | int ret; | ||
602 | u32 speed; | ||
603 | char newkey[5]; | ||
604 | u8 buffer[2]; | ||
605 | struct sensor_device_attribute_2 *sensor_attr = | ||
606 | to_sensor_dev_attr_2(attr); | ||
607 | |||
608 | speed = simple_strtoul(sysfsbuf, NULL, 10); | ||
609 | |||
610 | if (speed > 0x4000) /* Bigger than a 14-bit value */ | ||
611 | return -EINVAL; | ||
612 | |||
613 | newkey[0] = fan_speed_keys[sensor_attr->nr][0]; | ||
614 | newkey[1] = '0' + sensor_attr->index; | ||
615 | newkey[2] = fan_speed_keys[sensor_attr->nr][2]; | ||
616 | newkey[3] = fan_speed_keys[sensor_attr->nr][3]; | ||
617 | newkey[4] = 0; | ||
618 | |||
619 | mutex_lock(&applesmc_lock); | ||
620 | |||
621 | buffer[0] = (speed >> 6) & 0xff; | ||
622 | buffer[1] = (speed << 2) & 0xff; | ||
623 | ret = applesmc_write_key(newkey, buffer, 2); | ||
624 | |||
625 | mutex_unlock(&applesmc_lock); | ||
626 | if (ret) | ||
627 | return ret; | ||
628 | else | ||
629 | return count; | ||
630 | } | ||
631 | |||
632 | static ssize_t applesmc_show_fan_manual(struct device *dev, | ||
633 | struct device_attribute *devattr, char *sysfsbuf) | ||
634 | { | ||
635 | int ret; | ||
636 | u16 manual = 0; | ||
637 | u8 buffer[2]; | ||
638 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
639 | |||
640 | mutex_lock(&applesmc_lock); | ||
641 | |||
642 | ret = applesmc_read_key(FANS_MANUAL, buffer, 2); | ||
643 | manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; | ||
644 | |||
645 | mutex_unlock(&applesmc_lock); | ||
646 | if (ret) | ||
647 | return ret; | ||
648 | else | ||
649 | return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); | ||
650 | } | ||
651 | |||
652 | static ssize_t applesmc_store_fan_manual(struct device *dev, | ||
653 | struct device_attribute *devattr, | ||
654 | const char *sysfsbuf, size_t count) | ||
655 | { | ||
656 | int ret; | ||
657 | u8 buffer[2]; | ||
658 | u32 input; | ||
659 | u16 val; | ||
660 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
661 | |||
662 | input = simple_strtoul(sysfsbuf, NULL, 10); | ||
663 | |||
664 | mutex_lock(&applesmc_lock); | ||
665 | |||
666 | ret = applesmc_read_key(FANS_MANUAL, buffer, 2); | ||
667 | val = (buffer[0] << 8 | buffer[1]); | ||
668 | if (ret) | ||
669 | goto out; | ||
670 | |||
671 | if (input) | ||
672 | val = val | (0x01 << attr->index); | ||
673 | else | ||
674 | val = val & ~(0x01 << attr->index); | ||
675 | |||
676 | buffer[0] = (val >> 8) & 0xFF; | ||
677 | buffer[1] = val & 0xFF; | ||
678 | |||
679 | ret = applesmc_write_key(FANS_MANUAL, buffer, 2); | ||
680 | |||
681 | out: | ||
682 | mutex_unlock(&applesmc_lock); | ||
683 | if (ret) | ||
684 | return ret; | ||
685 | else | ||
686 | return count; | ||
687 | } | ||
688 | |||
689 | static ssize_t applesmc_show_fan_position(struct device *dev, | ||
690 | struct device_attribute *attr, char *sysfsbuf) | ||
691 | { | ||
692 | int ret; | ||
693 | char newkey[5]; | ||
694 | u8 buffer[17]; | ||
695 | struct sensor_device_attribute_2 *sensor_attr = | ||
696 | to_sensor_dev_attr_2(attr); | ||
697 | |||
698 | newkey[0] = FAN_POSITION[0]; | ||
699 | newkey[1] = '0' + sensor_attr->index; | ||
700 | newkey[2] = FAN_POSITION[2]; | ||
701 | newkey[3] = FAN_POSITION[3]; | ||
702 | newkey[4] = 0; | ||
703 | |||
704 | mutex_lock(&applesmc_lock); | ||
705 | |||
706 | ret = applesmc_read_key(newkey, buffer, 16); | ||
707 | buffer[16] = 0; | ||
708 | |||
709 | mutex_unlock(&applesmc_lock); | ||
710 | if (ret) | ||
711 | return ret; | ||
712 | else | ||
713 | return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4); | ||
714 | } | ||
715 | |||
716 | static ssize_t applesmc_calibrate_show(struct device *dev, | ||
717 | struct device_attribute *attr, char *sysfsbuf) | ||
718 | { | ||
719 | return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y); | ||
720 | } | ||
721 | |||
722 | static ssize_t applesmc_calibrate_store(struct device *dev, | ||
723 | struct device_attribute *attr, const char *sysfsbuf, size_t count) | ||
724 | { | ||
725 | mutex_lock(&applesmc_lock); | ||
726 | applesmc_calibrate(); | ||
727 | mutex_unlock(&applesmc_lock); | ||
728 | |||
729 | return count; | ||
730 | } | ||
731 | |||
732 | /* Store the next backlight value to be written by the work */ | ||
733 | static unsigned int backlight_value; | ||
734 | |||
735 | static void applesmc_backlight_set(struct work_struct *work) | ||
736 | { | ||
737 | u8 buffer[2]; | ||
738 | |||
739 | mutex_lock(&applesmc_lock); | ||
740 | buffer[0] = backlight_value; | ||
741 | buffer[1] = 0x00; | ||
742 | applesmc_write_key(BACKLIGHT_KEY, buffer, 2); | ||
743 | mutex_unlock(&applesmc_lock); | ||
744 | } | ||
745 | static DECLARE_WORK(backlight_work, &applesmc_backlight_set); | ||
746 | |||
747 | static void applesmc_brightness_set(struct led_classdev *led_cdev, | ||
748 | enum led_brightness value) | ||
749 | { | ||
750 | int ret; | ||
751 | |||
752 | backlight_value = value; | ||
753 | ret = queue_work(applesmc_led_wq, &backlight_work); | ||
754 | |||
755 | if (debug && (!ret)) | ||
756 | printk(KERN_DEBUG "applesmc: work was already on the queue.\n"); | ||
757 | } | ||
758 | |||
759 | static ssize_t applesmc_key_count_show(struct device *dev, | ||
760 | struct device_attribute *attr, char *sysfsbuf) | ||
761 | { | ||
762 | int ret; | ||
763 | u8 buffer[4]; | ||
764 | u32 count; | ||
765 | |||
766 | mutex_lock(&applesmc_lock); | ||
767 | |||
768 | ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); | ||
769 | count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + | ||
770 | ((u32)buffer[2]<<8) + buffer[3]; | ||
771 | |||
772 | mutex_unlock(&applesmc_lock); | ||
773 | if (ret) | ||
774 | return ret; | ||
775 | else | ||
776 | return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); | ||
777 | } | ||
778 | |||
779 | static ssize_t applesmc_key_at_index_read_show(struct device *dev, | ||
780 | struct device_attribute *attr, char *sysfsbuf) | ||
781 | { | ||
782 | char key[5]; | ||
783 | char info[6]; | ||
784 | int ret; | ||
785 | |||
786 | mutex_lock(&applesmc_lock); | ||
787 | |||
788 | ret = applesmc_get_key_at_index(key_at_index, key); | ||
789 | |||
790 | if (ret || !key[0]) { | ||
791 | mutex_unlock(&applesmc_lock); | ||
792 | |||
793 | return -EINVAL; | ||
794 | } | ||
795 | |||
796 | ret = applesmc_get_key_type(key, info); | ||
797 | |||
798 | if (ret) { | ||
799 | mutex_unlock(&applesmc_lock); | ||
800 | |||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | /* | ||
805 | * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than | ||
806 | * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf. | ||
807 | */ | ||
808 | ret = applesmc_read_key(key, sysfsbuf, info[0]); | ||
809 | |||
810 | mutex_unlock(&applesmc_lock); | ||
811 | |||
812 | if (!ret) { | ||
813 | return info[0]; | ||
814 | } | ||
815 | else { | ||
816 | return ret; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, | ||
821 | struct device_attribute *attr, char *sysfsbuf) | ||
822 | { | ||
823 | char key[5]; | ||
824 | char info[6]; | ||
825 | int ret; | ||
826 | |||
827 | mutex_lock(&applesmc_lock); | ||
828 | |||
829 | ret = applesmc_get_key_at_index(key_at_index, key); | ||
830 | |||
831 | if (ret || !key[0]) { | ||
832 | mutex_unlock(&applesmc_lock); | ||
833 | |||
834 | return -EINVAL; | ||
835 | } | ||
836 | |||
837 | ret = applesmc_get_key_type(key, info); | ||
838 | |||
839 | mutex_unlock(&applesmc_lock); | ||
840 | |||
841 | if (!ret) | ||
842 | return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]); | ||
843 | else | ||
844 | return ret; | ||
845 | } | ||
846 | |||
847 | static ssize_t applesmc_key_at_index_type_show(struct device *dev, | ||
848 | struct device_attribute *attr, char *sysfsbuf) | ||
849 | { | ||
850 | char key[5]; | ||
851 | char info[6]; | ||
852 | int ret; | ||
853 | |||
854 | mutex_lock(&applesmc_lock); | ||
855 | |||
856 | ret = applesmc_get_key_at_index(key_at_index, key); | ||
857 | |||
858 | if (ret || !key[0]) { | ||
859 | mutex_unlock(&applesmc_lock); | ||
860 | |||
861 | return -EINVAL; | ||
862 | } | ||
863 | |||
864 | ret = applesmc_get_key_type(key, info); | ||
865 | |||
866 | mutex_unlock(&applesmc_lock); | ||
867 | |||
868 | if (!ret) | ||
869 | return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1); | ||
870 | else | ||
871 | return ret; | ||
872 | } | ||
873 | |||
874 | static ssize_t applesmc_key_at_index_name_show(struct device *dev, | ||
875 | struct device_attribute *attr, char *sysfsbuf) | ||
876 | { | ||
877 | char key[5]; | ||
878 | int ret; | ||
879 | |||
880 | mutex_lock(&applesmc_lock); | ||
881 | |||
882 | ret = applesmc_get_key_at_index(key_at_index, key); | ||
883 | |||
884 | mutex_unlock(&applesmc_lock); | ||
885 | |||
886 | if (!ret && key[0]) | ||
887 | return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); | ||
888 | else | ||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
892 | static ssize_t applesmc_key_at_index_show(struct device *dev, | ||
893 | struct device_attribute *attr, char *sysfsbuf) | ||
894 | { | ||
895 | return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index); | ||
896 | } | ||
897 | |||
898 | static ssize_t applesmc_key_at_index_store(struct device *dev, | ||
899 | struct device_attribute *attr, const char *sysfsbuf, size_t count) | ||
900 | { | ||
901 | mutex_lock(&applesmc_lock); | ||
902 | |||
903 | key_at_index = simple_strtoul(sysfsbuf, NULL, 10); | ||
904 | |||
905 | mutex_unlock(&applesmc_lock); | ||
906 | |||
907 | return count; | ||
908 | } | ||
909 | |||
910 | static struct led_classdev applesmc_backlight = { | ||
911 | .name = "smc:kbd_backlight", | ||
912 | .default_trigger = "nand-disk", | ||
913 | .brightness_set = applesmc_brightness_set, | ||
914 | }; | ||
915 | |||
916 | static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); | ||
917 | static DEVICE_ATTR(calibrate, 0644, | ||
918 | applesmc_calibrate_show, applesmc_calibrate_store); | ||
919 | |||
920 | static struct attribute *accelerometer_attributes[] = { | ||
921 | &dev_attr_position.attr, | ||
922 | &dev_attr_calibrate.attr, | ||
923 | NULL | ||
924 | }; | ||
925 | |||
926 | static const struct attribute_group accelerometer_attributes_group = | ||
927 | { .attrs = accelerometer_attributes }; | ||
928 | |||
929 | static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); | ||
930 | |||
931 | static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL); | ||
932 | static DEVICE_ATTR(key_at_index, 0644, | ||
933 | applesmc_key_at_index_show, applesmc_key_at_index_store); | ||
934 | static DEVICE_ATTR(key_at_index_name, 0444, | ||
935 | applesmc_key_at_index_name_show, NULL); | ||
936 | static DEVICE_ATTR(key_at_index_type, 0444, | ||
937 | applesmc_key_at_index_type_show, NULL); | ||
938 | static DEVICE_ATTR(key_at_index_data_length, 0444, | ||
939 | applesmc_key_at_index_data_length_show, NULL); | ||
940 | static DEVICE_ATTR(key_at_index_data, 0444, | ||
941 | applesmc_key_at_index_read_show, NULL); | ||
942 | |||
943 | static struct attribute *key_enumeration_attributes[] = { | ||
944 | &dev_attr_key_count.attr, | ||
945 | &dev_attr_key_at_index.attr, | ||
946 | &dev_attr_key_at_index_name.attr, | ||
947 | &dev_attr_key_at_index_type.attr, | ||
948 | &dev_attr_key_at_index_data_length.attr, | ||
949 | &dev_attr_key_at_index_data.attr, | ||
950 | NULL | ||
951 | }; | ||
952 | |||
953 | static const struct attribute_group key_enumeration_group = | ||
954 | { .attrs = key_enumeration_attributes }; | ||
955 | |||
956 | /* | ||
957 | * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries. | ||
958 | * - show actual speed | ||
959 | * - show/store minimum speed | ||
960 | * - show maximum speed | ||
961 | * - show safe speed | ||
962 | * - show/store target speed | ||
963 | * - show/store manual mode | ||
964 | */ | ||
965 | #define sysfs_fan_speeds_offset(offset) \ | ||
966 | static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \ | ||
967 | applesmc_show_fan_speed, NULL, 0, offset-1); \ | ||
968 | \ | ||
969 | static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
970 | applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \ | ||
971 | \ | ||
972 | static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \ | ||
973 | applesmc_show_fan_speed, NULL, 2, offset-1); \ | ||
974 | \ | ||
975 | static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \ | ||
976 | applesmc_show_fan_speed, NULL, 3, offset-1); \ | ||
977 | \ | ||
978 | static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \ | ||
979 | applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \ | ||
980 | \ | ||
981 | static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \ | ||
982 | applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \ | ||
983 | \ | ||
984 | static SENSOR_DEVICE_ATTR(fan##offset##_position, S_IRUGO, \ | ||
985 | applesmc_show_fan_position, NULL, offset-1); \ | ||
986 | \ | ||
987 | static struct attribute *fan##offset##_attributes[] = { \ | ||
988 | &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \ | ||
989 | &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \ | ||
990 | &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \ | ||
991 | &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \ | ||
992 | &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \ | ||
993 | &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \ | ||
994 | &sensor_dev_attr_fan##offset##_position.dev_attr.attr, \ | ||
995 | NULL \ | ||
996 | }; | ||
997 | |||
998 | /* | ||
999 | * Create the needed functions for each fan using the macro defined above | ||
1000 | * (2 fans are supported) | ||
1001 | */ | ||
1002 | sysfs_fan_speeds_offset(1); | ||
1003 | sysfs_fan_speeds_offset(2); | ||
1004 | |||
1005 | static const struct attribute_group fan_attribute_groups[] = { | ||
1006 | { .attrs = fan1_attributes }, | ||
1007 | { .attrs = fan2_attributes } | ||
1008 | }; | ||
1009 | |||
1010 | /* | ||
1011 | * Temperature sensors sysfs entries. | ||
1012 | */ | ||
1013 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
1014 | applesmc_show_temperature, NULL, 0); | ||
1015 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, | ||
1016 | applesmc_show_temperature, NULL, 1); | ||
1017 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, | ||
1018 | applesmc_show_temperature, NULL, 2); | ||
1019 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, | ||
1020 | applesmc_show_temperature, NULL, 3); | ||
1021 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, | ||
1022 | applesmc_show_temperature, NULL, 4); | ||
1023 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, | ||
1024 | applesmc_show_temperature, NULL, 5); | ||
1025 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, | ||
1026 | applesmc_show_temperature, NULL, 6); | ||
1027 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, | ||
1028 | applesmc_show_temperature, NULL, 7); | ||
1029 | static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, | ||
1030 | applesmc_show_temperature, NULL, 8); | ||
1031 | static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, | ||
1032 | applesmc_show_temperature, NULL, 9); | ||
1033 | static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, | ||
1034 | applesmc_show_temperature, NULL, 10); | ||
1035 | static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, | ||
1036 | applesmc_show_temperature, NULL, 11); | ||
1037 | |||
1038 | static struct attribute *temperature_attributes[] = { | ||
1039 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1040 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1041 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1042 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
1043 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
1044 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
1045 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
1046 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
1047 | &sensor_dev_attr_temp9_input.dev_attr.attr, | ||
1048 | &sensor_dev_attr_temp10_input.dev_attr.attr, | ||
1049 | &sensor_dev_attr_temp11_input.dev_attr.attr, | ||
1050 | &sensor_dev_attr_temp12_input.dev_attr.attr, | ||
1051 | NULL | ||
1052 | }; | ||
1053 | |||
1054 | static const struct attribute_group temperature_attributes_group = | ||
1055 | { .attrs = temperature_attributes }; | ||
1056 | |||
1057 | /* Module stuff */ | ||
1058 | |||
1059 | /* | ||
1060 | * applesmc_dmi_match - found a match. return one, short-circuiting the hunt. | ||
1061 | */ | ||
1062 | static int applesmc_dmi_match(struct dmi_system_id *id) | ||
1063 | { | ||
1064 | int i = 0; | ||
1065 | struct dmi_match_data* dmi_data = id->driver_data; | ||
1066 | printk(KERN_INFO "applesmc: %s detected:\n", id->ident); | ||
1067 | applesmc_accelerometer = dmi_data->accelerometer; | ||
1068 | printk(KERN_INFO "applesmc: - Model %s accelerometer\n", | ||
1069 | applesmc_accelerometer ? "with" : "without"); | ||
1070 | applesmc_light = dmi_data->light; | ||
1071 | printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n", | ||
1072 | applesmc_light ? "with" : "without"); | ||
1073 | |||
1074 | applesmc_temperature_set = dmi_data->temperature_set; | ||
1075 | while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL) | ||
1076 | i++; | ||
1077 | printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i); | ||
1078 | return 1; | ||
1079 | } | ||
1080 | |||
1081 | /* Create accelerometer ressources */ | ||
1082 | static int applesmc_create_accelerometer(void) | ||
1083 | { | ||
1084 | int ret; | ||
1085 | |||
1086 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1087 | &accelerometer_attributes_group); | ||
1088 | if (ret) | ||
1089 | goto out; | ||
1090 | |||
1091 | applesmc_idev = input_allocate_device(); | ||
1092 | if (!applesmc_idev) { | ||
1093 | ret = -ENOMEM; | ||
1094 | goto out_sysfs; | ||
1095 | } | ||
1096 | |||
1097 | /* initial calibrate for the input device */ | ||
1098 | applesmc_calibrate(); | ||
1099 | |||
1100 | /* initialize the input class */ | ||
1101 | applesmc_idev->name = "applesmc"; | ||
1102 | applesmc_idev->id.bustype = BUS_HOST; | ||
1103 | applesmc_idev->cdev.dev = &pdev->dev; | ||
1104 | applesmc_idev->evbit[0] = BIT(EV_ABS); | ||
1105 | applesmc_idev->open = applesmc_idev_open; | ||
1106 | applesmc_idev->close = applesmc_idev_close; | ||
1107 | input_set_abs_params(applesmc_idev, ABS_X, | ||
1108 | -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); | ||
1109 | input_set_abs_params(applesmc_idev, ABS_Y, | ||
1110 | -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); | ||
1111 | |||
1112 | ret = input_register_device(applesmc_idev); | ||
1113 | if (ret) | ||
1114 | goto out_idev; | ||
1115 | |||
1116 | /* start up our timer for the input device */ | ||
1117 | init_timer(&applesmc_timer); | ||
1118 | applesmc_timer.function = applesmc_idev_poll; | ||
1119 | applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD; | ||
1120 | |||
1121 | return 0; | ||
1122 | |||
1123 | out_idev: | ||
1124 | input_free_device(applesmc_idev); | ||
1125 | |||
1126 | out_sysfs: | ||
1127 | sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); | ||
1128 | |||
1129 | out: | ||
1130 | printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); | ||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | /* Release all ressources used by the accelerometer */ | ||
1135 | static void applesmc_release_accelerometer(void) | ||
1136 | { | ||
1137 | del_timer_sync(&applesmc_timer); | ||
1138 | input_unregister_device(applesmc_idev); | ||
1139 | sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); | ||
1140 | } | ||
1141 | |||
1142 | static __initdata struct dmi_match_data applesmc_dmi_data[] = { | ||
1143 | /* MacBook Pro: accelerometer, backlight and temperature set 0 */ | ||
1144 | { .accelerometer = 1, .light = 1, .temperature_set = 0 }, | ||
1145 | /* MacBook: accelerometer and temperature set 0 */ | ||
1146 | { .accelerometer = 1, .light = 0, .temperature_set = 0 }, | ||
1147 | /* MacBook: temperature set 1 */ | ||
1148 | { .accelerometer = 0, .light = 0, .temperature_set = 1 } | ||
1149 | }; | ||
1150 | |||
1151 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | ||
1152 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ | ||
1153 | static __initdata struct dmi_system_id applesmc_whitelist[] = { | ||
1154 | { applesmc_dmi_match, "Apple MacBook Pro", { | ||
1155 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1156 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, | ||
1157 | (void*)&applesmc_dmi_data[0]}, | ||
1158 | { applesmc_dmi_match, "Apple MacBook", { | ||
1159 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1160 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | ||
1161 | (void*)&applesmc_dmi_data[1]}, | ||
1162 | { applesmc_dmi_match, "Apple Macmini", { | ||
1163 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1164 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, | ||
1165 | (void*)&applesmc_dmi_data[2]}, | ||
1166 | { .ident = NULL } | ||
1167 | }; | ||
1168 | |||
1169 | static int __init applesmc_init(void) | ||
1170 | { | ||
1171 | int ret; | ||
1172 | int count; | ||
1173 | int i; | ||
1174 | |||
1175 | mutex_init(&applesmc_lock); | ||
1176 | |||
1177 | if (!dmi_check_system(applesmc_whitelist)) { | ||
1178 | printk(KERN_WARNING "applesmc: supported laptop not found!\n"); | ||
1179 | ret = -ENODEV; | ||
1180 | goto out; | ||
1181 | } | ||
1182 | |||
1183 | if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, | ||
1184 | "applesmc")) { | ||
1185 | ret = -ENXIO; | ||
1186 | goto out; | ||
1187 | } | ||
1188 | |||
1189 | ret = platform_driver_register(&applesmc_driver); | ||
1190 | if (ret) | ||
1191 | goto out_region; | ||
1192 | |||
1193 | pdev = platform_device_register_simple("applesmc", -1, NULL, 0); | ||
1194 | if (IS_ERR(pdev)) { | ||
1195 | ret = PTR_ERR(pdev); | ||
1196 | goto out_driver; | ||
1197 | } | ||
1198 | |||
1199 | /* Create key enumeration sysfs files */ | ||
1200 | ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); | ||
1201 | if (ret) | ||
1202 | goto out_device; | ||
1203 | |||
1204 | /* create fan files */ | ||
1205 | count = applesmc_get_fan_count(); | ||
1206 | if (count < 0) { | ||
1207 | printk(KERN_ERR "applesmc: Cannot get the number of fans.\n"); | ||
1208 | } else { | ||
1209 | printk(KERN_INFO "applesmc: %d fans found.\n", count); | ||
1210 | |||
1211 | switch (count) { | ||
1212 | default: | ||
1213 | printk(KERN_WARNING "applesmc: More than 2 fans found," | ||
1214 | " but at most 2 fans are supported" | ||
1215 | " by the driver.\n"); | ||
1216 | case 2: | ||
1217 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1218 | &fan_attribute_groups[1]); | ||
1219 | if (ret) | ||
1220 | goto out_key_enumeration; | ||
1221 | case 1: | ||
1222 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1223 | &fan_attribute_groups[0]); | ||
1224 | if (ret) | ||
1225 | goto out_fan_1; | ||
1226 | case 0: | ||
1227 | ; | ||
1228 | } | ||
1229 | } | ||
1230 | |||
1231 | for (i = 0; | ||
1232 | temperature_sensors_sets[applesmc_temperature_set][i] != NULL; | ||
1233 | i++) { | ||
1234 | if (temperature_attributes[i] == NULL) { | ||
1235 | printk(KERN_ERR "applesmc: More temperature sensors " | ||
1236 | "in temperature_sensors_sets (at least %i)" | ||
1237 | "than available sysfs files in " | ||
1238 | "temperature_attributes (%i), please report " | ||
1239 | "this bug.\n", i, i-1); | ||
1240 | goto out_temperature; | ||
1241 | } | ||
1242 | ret = sysfs_create_file(&pdev->dev.kobj, | ||
1243 | temperature_attributes[i]); | ||
1244 | if (ret) | ||
1245 | goto out_temperature; | ||
1246 | } | ||
1247 | |||
1248 | if (applesmc_accelerometer) { | ||
1249 | ret = applesmc_create_accelerometer(); | ||
1250 | if (ret) | ||
1251 | goto out_temperature; | ||
1252 | } | ||
1253 | |||
1254 | if (applesmc_light) { | ||
1255 | /* Add light sensor file */ | ||
1256 | ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr); | ||
1257 | if (ret) | ||
1258 | goto out_accelerometer; | ||
1259 | |||
1260 | /* Create the workqueue */ | ||
1261 | applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); | ||
1262 | if (!applesmc_led_wq) { | ||
1263 | ret = -ENOMEM; | ||
1264 | goto out_light_sysfs; | ||
1265 | } | ||
1266 | |||
1267 | /* register as a led device */ | ||
1268 | ret = led_classdev_register(&pdev->dev, &applesmc_backlight); | ||
1269 | if (ret < 0) | ||
1270 | goto out_light_wq; | ||
1271 | } | ||
1272 | |||
1273 | hwmon_class_dev = hwmon_device_register(&pdev->dev); | ||
1274 | if (IS_ERR(hwmon_class_dev)) { | ||
1275 | ret = PTR_ERR(hwmon_class_dev); | ||
1276 | goto out_light_ledclass; | ||
1277 | } | ||
1278 | |||
1279 | printk(KERN_INFO "applesmc: driver successfully loaded.\n"); | ||
1280 | |||
1281 | return 0; | ||
1282 | |||
1283 | out_light_ledclass: | ||
1284 | if (applesmc_light) | ||
1285 | led_classdev_unregister(&applesmc_backlight); | ||
1286 | out_light_wq: | ||
1287 | if (applesmc_light) | ||
1288 | destroy_workqueue(applesmc_led_wq); | ||
1289 | out_light_sysfs: | ||
1290 | if (applesmc_light) | ||
1291 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); | ||
1292 | out_accelerometer: | ||
1293 | if (applesmc_accelerometer) | ||
1294 | applesmc_release_accelerometer(); | ||
1295 | out_temperature: | ||
1296 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); | ||
1297 | sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); | ||
1298 | out_fan_1: | ||
1299 | sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); | ||
1300 | out_key_enumeration: | ||
1301 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); | ||
1302 | out_device: | ||
1303 | platform_device_unregister(pdev); | ||
1304 | out_driver: | ||
1305 | platform_driver_unregister(&applesmc_driver); | ||
1306 | out_region: | ||
1307 | release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); | ||
1308 | out: | ||
1309 | printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); | ||
1310 | return ret; | ||
1311 | } | ||
1312 | |||
1313 | static void __exit applesmc_exit(void) | ||
1314 | { | ||
1315 | hwmon_device_unregister(hwmon_class_dev); | ||
1316 | if (applesmc_light) { | ||
1317 | led_classdev_unregister(&applesmc_backlight); | ||
1318 | destroy_workqueue(applesmc_led_wq); | ||
1319 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); | ||
1320 | } | ||
1321 | if (applesmc_accelerometer) | ||
1322 | applesmc_release_accelerometer(); | ||
1323 | sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); | ||
1324 | sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); | ||
1325 | sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); | ||
1326 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); | ||
1327 | platform_device_unregister(pdev); | ||
1328 | platform_driver_unregister(&applesmc_driver); | ||
1329 | release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); | ||
1330 | |||
1331 | printk(KERN_INFO "applesmc: driver unloaded.\n"); | ||
1332 | } | ||
1333 | |||
1334 | module_init(applesmc_init); | ||
1335 | module_exit(applesmc_exit); | ||
1336 | |||
1337 | MODULE_AUTHOR("Nicolas Boichat"); | ||
1338 | MODULE_DESCRIPTION("Apple SMC"); | ||
1339 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index bf759ea545ac..f82fa2d23f95 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c | |||
@@ -30,10 +30,12 @@ | |||
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/mutex.h> | ||
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
34 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
35 | #include <linux/dmi.h> | 36 | #include <linux/dmi.h> |
36 | #include <linux/jiffies.h> | 37 | #include <linux/jiffies.h> |
38 | |||
37 | #include <asm/io.h> | 39 | #include <asm/io.h> |
38 | 40 | ||
39 | #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ | 41 | #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ |
@@ -71,10 +73,10 @@ static u8 km_activity; | |||
71 | static int rest_x; | 73 | static int rest_x; |
72 | static int rest_y; | 74 | static int rest_y; |
73 | 75 | ||
74 | static DECLARE_MUTEX(hdaps_sem); | 76 | static DEFINE_MUTEX(hdaps_mtx); |
75 | 77 | ||
76 | /* | 78 | /* |
77 | * __get_latch - Get the value from a given port. Callers must hold hdaps_sem. | 79 | * __get_latch - Get the value from a given port. Callers must hold hdaps_mtx. |
78 | */ | 80 | */ |
79 | static inline u8 __get_latch(u16 port) | 81 | static inline u8 __get_latch(u16 port) |
80 | { | 82 | { |
@@ -83,7 +85,7 @@ static inline u8 __get_latch(u16 port) | |||
83 | 85 | ||
84 | /* | 86 | /* |
85 | * __check_latch - Check a port latch for a given value. Returns zero if the | 87 | * __check_latch - Check a port latch for a given value. Returns zero if the |
86 | * port contains the given value. Callers must hold hdaps_sem. | 88 | * port contains the given value. Callers must hold hdaps_mtx. |
87 | */ | 89 | */ |
88 | static inline int __check_latch(u16 port, u8 val) | 90 | static inline int __check_latch(u16 port, u8 val) |
89 | { | 91 | { |
@@ -94,7 +96,7 @@ static inline int __check_latch(u16 port, u8 val) | |||
94 | 96 | ||
95 | /* | 97 | /* |
96 | * __wait_latch - Wait up to 100us for a port latch to get a certain value, | 98 | * __wait_latch - Wait up to 100us for a port latch to get a certain value, |
97 | * returning zero if the value is obtained. Callers must hold hdaps_sem. | 99 | * returning zero if the value is obtained. Callers must hold hdaps_mtx. |
98 | */ | 100 | */ |
99 | static int __wait_latch(u16 port, u8 val) | 101 | static int __wait_latch(u16 port, u8 val) |
100 | { | 102 | { |
@@ -111,7 +113,7 @@ static int __wait_latch(u16 port, u8 val) | |||
111 | 113 | ||
112 | /* | 114 | /* |
113 | * __device_refresh - request a refresh from the accelerometer. Does not wait | 115 | * __device_refresh - request a refresh from the accelerometer. Does not wait |
114 | * for refresh to complete. Callers must hold hdaps_sem. | 116 | * for refresh to complete. Callers must hold hdaps_mtx. |
115 | */ | 117 | */ |
116 | static void __device_refresh(void) | 118 | static void __device_refresh(void) |
117 | { | 119 | { |
@@ -125,7 +127,7 @@ static void __device_refresh(void) | |||
125 | /* | 127 | /* |
126 | * __device_refresh_sync - request a synchronous refresh from the | 128 | * __device_refresh_sync - request a synchronous refresh from the |
127 | * accelerometer. We wait for the refresh to complete. Returns zero if | 129 | * accelerometer. We wait for the refresh to complete. Returns zero if |
128 | * successful and nonzero on error. Callers must hold hdaps_sem. | 130 | * successful and nonzero on error. Callers must hold hdaps_mtx. |
129 | */ | 131 | */ |
130 | static int __device_refresh_sync(void) | 132 | static int __device_refresh_sync(void) |
131 | { | 133 | { |
@@ -135,7 +137,7 @@ static int __device_refresh_sync(void) | |||
135 | 137 | ||
136 | /* | 138 | /* |
137 | * __device_complete - indicate to the accelerometer that we are done reading | 139 | * __device_complete - indicate to the accelerometer that we are done reading |
138 | * data, and then initiate an async refresh. Callers must hold hdaps_sem. | 140 | * data, and then initiate an async refresh. Callers must hold hdaps_mtx. |
139 | */ | 141 | */ |
140 | static inline void __device_complete(void) | 142 | static inline void __device_complete(void) |
141 | { | 143 | { |
@@ -153,7 +155,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val) | |||
153 | { | 155 | { |
154 | int ret; | 156 | int ret; |
155 | 157 | ||
156 | down(&hdaps_sem); | 158 | mutex_lock(&hdaps_mtx); |
157 | 159 | ||
158 | /* do a sync refresh -- we need to be sure that we read fresh data */ | 160 | /* do a sync refresh -- we need to be sure that we read fresh data */ |
159 | ret = __device_refresh_sync(); | 161 | ret = __device_refresh_sync(); |
@@ -164,7 +166,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val) | |||
164 | __device_complete(); | 166 | __device_complete(); |
165 | 167 | ||
166 | out: | 168 | out: |
167 | up(&hdaps_sem); | 169 | mutex_unlock(&hdaps_mtx); |
168 | return ret; | 170 | return ret; |
169 | } | 171 | } |
170 | 172 | ||
@@ -199,9 +201,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2, | |||
199 | { | 201 | { |
200 | int ret; | 202 | int ret; |
201 | 203 | ||
202 | down(&hdaps_sem); | 204 | mutex_lock(&hdaps_mtx); |
203 | ret = __hdaps_read_pair(port1, port2, val1, val2); | 205 | ret = __hdaps_read_pair(port1, port2, val1, val2); |
204 | up(&hdaps_sem); | 206 | mutex_unlock(&hdaps_mtx); |
205 | 207 | ||
206 | return ret; | 208 | return ret; |
207 | } | 209 | } |
@@ -214,7 +216,7 @@ static int hdaps_device_init(void) | |||
214 | { | 216 | { |
215 | int total, ret = -ENXIO; | 217 | int total, ret = -ENXIO; |
216 | 218 | ||
217 | down(&hdaps_sem); | 219 | mutex_lock(&hdaps_mtx); |
218 | 220 | ||
219 | outb(0x13, 0x1610); | 221 | outb(0x13, 0x1610); |
220 | outb(0x01, 0x161f); | 222 | outb(0x01, 0x161f); |
@@ -280,7 +282,7 @@ static int hdaps_device_init(void) | |||
280 | } | 282 | } |
281 | 283 | ||
282 | out: | 284 | out: |
283 | up(&hdaps_sem); | 285 | mutex_unlock(&hdaps_mtx); |
284 | return ret; | 286 | return ret; |
285 | } | 287 | } |
286 | 288 | ||
@@ -314,7 +316,7 @@ static struct platform_driver hdaps_driver = { | |||
314 | }; | 316 | }; |
315 | 317 | ||
316 | /* | 318 | /* |
317 | * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem. | 319 | * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mtx. |
318 | */ | 320 | */ |
319 | static void hdaps_calibrate(void) | 321 | static void hdaps_calibrate(void) |
320 | { | 322 | { |
@@ -326,7 +328,7 @@ static void hdaps_mousedev_poll(unsigned long unused) | |||
326 | int x, y; | 328 | int x, y; |
327 | 329 | ||
328 | /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ | 330 | /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ |
329 | if (down_trylock(&hdaps_sem)) { | 331 | if (mutex_trylock(&hdaps_mtx)) { |
330 | mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); | 332 | mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); |
331 | return; | 333 | return; |
332 | } | 334 | } |
@@ -341,7 +343,7 @@ static void hdaps_mousedev_poll(unsigned long unused) | |||
341 | mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); | 343 | mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); |
342 | 344 | ||
343 | out: | 345 | out: |
344 | up(&hdaps_sem); | 346 | mutex_unlock(&hdaps_mtx); |
345 | } | 347 | } |
346 | 348 | ||
347 | 349 | ||
@@ -421,9 +423,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev, | |||
421 | struct device_attribute *attr, | 423 | struct device_attribute *attr, |
422 | const char *buf, size_t count) | 424 | const char *buf, size_t count) |
423 | { | 425 | { |
424 | down(&hdaps_sem); | 426 | mutex_lock(&hdaps_mtx); |
425 | hdaps_calibrate(); | 427 | hdaps_calibrate(); |
426 | up(&hdaps_sem); | 428 | mutex_unlock(&hdaps_mtx); |
427 | 429 | ||
428 | return count; | 430 | return count; |
429 | } | 431 | } |
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 8c953707253f..039a07fde908 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -175,6 +175,7 @@ static void i2c_parport_attach (struct parport *port) | |||
175 | } | 175 | } |
176 | adapter->algo_data.data = port; | 176 | adapter->algo_data.data = port; |
177 | adapter->adapter.algo_data = &adapter->algo_data; | 177 | adapter->adapter.algo_data = &adapter->algo_data; |
178 | adapter->adapter.dev.parent = port->physport->dev; | ||
178 | 179 | ||
179 | if (parport_claim_or_block(adapter->pdev) < 0) { | 180 | if (parport_claim_or_block(adapter->pdev) < 0) { |
180 | printk(KERN_ERR "i2c-parport: Could not claim parallel port\n"); | 181 | printk(KERN_ERR "i2c-parport: Could not claim parallel port\n"); |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 0db56e7bc34e..0d6bd4f7b7fa 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
33 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index cb4fa9bef8cd..e7a709710592 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/list.h> | 34 | #include <linux/list.h> |
36 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 026e38face5c..208141377612 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
@@ -94,7 +94,6 @@ | |||
94 | #include <linux/pci.h> | 94 | #include <linux/pci.h> |
95 | #include <linux/fs.h> | 95 | #include <linux/fs.h> |
96 | #include <linux/poll.h> | 96 | #include <linux/poll.h> |
97 | #include <linux/smp_lock.h> | ||
98 | #include <linux/mutex.h> | 97 | #include <linux/mutex.h> |
99 | #include <linux/bitops.h> | 98 | #include <linux/bitops.h> |
100 | #include <asm/byteorder.h> | 99 | #include <asm/byteorder.h> |
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index c6aefd9ad0e8..d382500f4210 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
40 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
41 | #include <linux/cdev.h> | 40 | #include <linux/cdev.h> |
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 95ca26d75272..87ebd0846c34 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
41 | #include <linux/poll.h> | 41 | #include <linux/poll.h> |
42 | #include <linux/smp_lock.h> | ||
43 | #include <linux/delay.h> | 42 | #include <linux/delay.h> |
44 | #include <linux/bitops.h> | 43 | #include <linux/bitops.h> |
45 | #include <linux/types.h> | 44 | #include <linux/types.h> |
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 036ed1ef1796..ebd5c7bd2cdb 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
@@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, | |||
523 | int ret; | 523 | int ret; |
524 | 524 | ||
525 | static struct tree_descr files[] = { | 525 | static struct tree_descr files[] = { |
526 | [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, | 526 | [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, |
527 | {""}, | 527 | {""}, |
528 | }; | 528 | }; |
529 | 529 | ||
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 89d6008bb673..3702e2375553 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/smp_lock.h> | ||
39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
40 | #include <linux/version.h> | 39 | #include <linux/version.h> |
41 | 40 | ||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 1f6fcec0c6fc..be3dbc1ae67d 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/major.h> | 20 | #include <linux/major.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/device.h> | 21 | #include <linux/device.h> |
23 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
24 | 23 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 915e9ab7cab0..ccd8abafcb70 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/input.h> | 14 | #include <linux/input.h> |
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/random.h> | 16 | #include <linux/random.h> |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9bcc5425049b..06f0541b24da 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/poll.h> | 25 | #include <linux/poll.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/device.h> | 27 | #include <linux/device.h> |
29 | 28 | ||
30 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 7678e9876550..8675f9509393 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/random.h> | 22 | #include <linux/random.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 5e5b5c91d75b..8238b13874c2 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/input.h> | 49 | #include <linux/input.h> |
50 | #include <linux/major.h> | 50 | #include <linux/major.h> |
51 | #include <linux/smp_lock.h> | ||
52 | #include <linux/random.h> | 51 | #include <linux/random.h> |
53 | #include <linux/time.h> | 52 | #include <linux/time.h> |
54 | #include <linux/device.h> | 53 | #include <linux/device.h> |
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index db1260f73f10..81661b8bd3a8 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -18,8 +18,8 @@ | |||
18 | #include <linux/fcntl.h> | 18 | #include <linux/fcntl.h> |
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
21 | #include <linux/mutex.h> | ||
21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 25 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
@@ -147,7 +147,7 @@ struct capidev { | |||
147 | 147 | ||
148 | struct capincci *nccis; | 148 | struct capincci *nccis; |
149 | 149 | ||
150 | struct semaphore ncci_list_sem; | 150 | struct mutex ncci_list_mtx; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | /* -------- global variables ---------------------------------------- */ | 153 | /* -------- global variables ---------------------------------------- */ |
@@ -395,7 +395,7 @@ static struct capidev *capidev_alloc(void) | |||
395 | if (!cdev) | 395 | if (!cdev) |
396 | return NULL; | 396 | return NULL; |
397 | 397 | ||
398 | init_MUTEX(&cdev->ncci_list_sem); | 398 | mutex_init(&cdev->ncci_list_mtx); |
399 | skb_queue_head_init(&cdev->recvqueue); | 399 | skb_queue_head_init(&cdev->recvqueue); |
400 | init_waitqueue_head(&cdev->recvwait); | 400 | init_waitqueue_head(&cdev->recvwait); |
401 | write_lock_irqsave(&capidev_list_lock, flags); | 401 | write_lock_irqsave(&capidev_list_lock, flags); |
@@ -414,9 +414,9 @@ static void capidev_free(struct capidev *cdev) | |||
414 | } | 414 | } |
415 | skb_queue_purge(&cdev->recvqueue); | 415 | skb_queue_purge(&cdev->recvqueue); |
416 | 416 | ||
417 | down(&cdev->ncci_list_sem); | 417 | mutex_lock(&cdev->ncci_list_mtx); |
418 | capincci_free(cdev, 0xffffffff); | 418 | capincci_free(cdev, 0xffffffff); |
419 | up(&cdev->ncci_list_sem); | 419 | mutex_unlock(&cdev->ncci_list_mtx); |
420 | 420 | ||
421 | write_lock_irqsave(&capidev_list_lock, flags); | 421 | write_lock_irqsave(&capidev_list_lock, flags); |
422 | list_del(&cdev->list); | 422 | list_del(&cdev->list); |
@@ -603,15 +603,15 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) | |||
603 | if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { | 603 | if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { |
604 | u16 info = CAPIMSG_U16(skb->data, 12); // Info field | 604 | u16 info = CAPIMSG_U16(skb->data, 12); // Info field |
605 | if (info == 0) { | 605 | if (info == 0) { |
606 | down(&cdev->ncci_list_sem); | 606 | mutex_lock(&cdev->ncci_list_mtx); |
607 | capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); | 607 | capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); |
608 | up(&cdev->ncci_list_sem); | 608 | mutex_unlock(&cdev->ncci_list_mtx); |
609 | } | 609 | } |
610 | } | 610 | } |
611 | if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { | 611 | if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { |
612 | down(&cdev->ncci_list_sem); | 612 | mutex_lock(&cdev->ncci_list_mtx); |
613 | capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); | 613 | capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); |
614 | up(&cdev->ncci_list_sem); | 614 | mutex_unlock(&cdev->ncci_list_mtx); |
615 | } | 615 | } |
616 | spin_lock_irqsave(&workaround_lock, flags); | 616 | spin_lock_irqsave(&workaround_lock, flags); |
617 | if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { | 617 | if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { |
@@ -752,9 +752,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos | |||
752 | CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); | 752 | CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); |
753 | 753 | ||
754 | if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { | 754 | if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { |
755 | down(&cdev->ncci_list_sem); | 755 | mutex_lock(&cdev->ncci_list_mtx); |
756 | capincci_free(cdev, CAPIMSG_NCCI(skb->data)); | 756 | capincci_free(cdev, CAPIMSG_NCCI(skb->data)); |
757 | up(&cdev->ncci_list_sem); | 757 | mutex_unlock(&cdev->ncci_list_mtx); |
758 | } | 758 | } |
759 | 759 | ||
760 | cdev->errcode = capi20_put_message(&cdev->ap, skb); | 760 | cdev->errcode = capi20_put_message(&cdev->ap, skb); |
@@ -939,9 +939,9 @@ capi_ioctl(struct inode *inode, struct file *file, | |||
939 | if (copy_from_user(&ncci, argp, sizeof(ncci))) | 939 | if (copy_from_user(&ncci, argp, sizeof(ncci))) |
940 | return -EFAULT; | 940 | return -EFAULT; |
941 | 941 | ||
942 | down(&cdev->ncci_list_sem); | 942 | mutex_lock(&cdev->ncci_list_mtx); |
943 | if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) { | 943 | if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) { |
944 | up(&cdev->ncci_list_sem); | 944 | mutex_unlock(&cdev->ncci_list_mtx); |
945 | return 0; | 945 | return 0; |
946 | } | 946 | } |
947 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 947 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
@@ -949,7 +949,7 @@ capi_ioctl(struct inode *inode, struct file *file, | |||
949 | count += atomic_read(&mp->ttyopencount); | 949 | count += atomic_read(&mp->ttyopencount); |
950 | } | 950 | } |
951 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | 951 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ |
952 | up(&cdev->ncci_list_sem); | 952 | mutex_unlock(&cdev->ncci_list_mtx); |
953 | return count; | 953 | return count; |
954 | } | 954 | } |
955 | return 0; | 955 | return 0; |
@@ -964,14 +964,14 @@ capi_ioctl(struct inode *inode, struct file *file, | |||
964 | if (copy_from_user(&ncci, argp, | 964 | if (copy_from_user(&ncci, argp, |
965 | sizeof(ncci))) | 965 | sizeof(ncci))) |
966 | return -EFAULT; | 966 | return -EFAULT; |
967 | down(&cdev->ncci_list_sem); | 967 | mutex_lock(&cdev->ncci_list_mtx); |
968 | nccip = capincci_find(cdev, (u32) ncci); | 968 | nccip = capincci_find(cdev, (u32) ncci); |
969 | if (!nccip || (mp = nccip->minorp) == 0) { | 969 | if (!nccip || (mp = nccip->minorp) == 0) { |
970 | up(&cdev->ncci_list_sem); | 970 | mutex_unlock(&cdev->ncci_list_mtx); |
971 | return -ESRCH; | 971 | return -ESRCH; |
972 | } | 972 | } |
973 | unit = mp->minor; | 973 | unit = mp->minor; |
974 | up(&cdev->ncci_list_sem); | 974 | mutex_unlock(&cdev->ncci_list_mtx); |
975 | return unit; | 975 | return unit; |
976 | } | 976 | } |
977 | return 0; | 977 | return 0; |
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index ad1e2702c2d1..22379b94e88f 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c | |||
@@ -855,7 +855,7 @@ static _cdebbuf *g_debbuf; | |||
855 | static u_long g_debbuf_lock; | 855 | static u_long g_debbuf_lock; |
856 | static _cmsg *g_cmsg; | 856 | static _cmsg *g_cmsg; |
857 | 857 | ||
858 | _cdebbuf *cdebbuf_alloc(void) | 858 | static _cdebbuf *cdebbuf_alloc(void) |
859 | { | 859 | { |
860 | _cdebbuf *cdb; | 860 | _cdebbuf *cdb; |
861 | 861 | ||
@@ -989,11 +989,6 @@ _cdebbuf *capi_cmsg2str(_cmsg * cmsg) | |||
989 | return &g_debbuf; | 989 | return &g_debbuf; |
990 | } | 990 | } |
991 | 991 | ||
992 | _cdebbuf *cdebbuf_alloc(void) | ||
993 | { | ||
994 | return &g_debbuf; | ||
995 | } | ||
996 | |||
997 | void cdebbuf_free(_cdebbuf *cdb) | 992 | void cdebbuf_free(_cdebbuf *cdb) |
998 | { | 993 | { |
999 | } | 994 | } |
@@ -1009,7 +1004,6 @@ void __exit cdebug_exit(void) | |||
1009 | 1004 | ||
1010 | #endif | 1005 | #endif |
1011 | 1006 | ||
1012 | EXPORT_SYMBOL(cdebbuf_alloc); | ||
1013 | EXPORT_SYMBOL(cdebbuf_free); | 1007 | EXPORT_SYMBOL(cdebbuf_free); |
1014 | EXPORT_SYMBOL(capi_cmsg2message); | 1008 | EXPORT_SYMBOL(capi_cmsg2message); |
1015 | EXPORT_SYMBOL(capi_message2cmsg); | 1009 | EXPORT_SYMBOL(capi_message2cmsg); |
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 53a189003355..be77ee625bb7 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/poll.h> | 13 | #include <linux/poll.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #ifdef CONFIG_PROC_FS | 14 | #ifdef CONFIG_PROC_FS |
16 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
17 | #else | 16 | #else |
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c index 7a74ed35b1bf..98fcdfc7ca55 100644 --- a/drivers/isdn/hardware/eicon/capimain.c +++ b/drivers/isdn/hardware/eicon/capimain.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
18 | 17 | ||
19 | #include "os_capi.h" | 18 | #include "os_capi.h" |
diff --git a/drivers/isdn/hardware/eicon/dbgioctl.h b/drivers/isdn/hardware/eicon/dbgioctl.h deleted file mode 100644 index 0fb6f5e88b60..000000000000 --- a/drivers/isdn/hardware/eicon/dbgioctl.h +++ /dev/null | |||
@@ -1,198 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | * | ||
4 | Copyright (c) Eicon Technology Corporation, 2000. | ||
5 | * | ||
6 | This source file is supplied for the use with Eicon | ||
7 | Technology Corporation's range of DIVA Server Adapters. | ||
8 | * | ||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2, or (at your option) | ||
12 | any later version. | ||
13 | * | ||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY | ||
16 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | See the GNU General Public License for more details. | ||
18 | * | ||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | /*------------------------------------------------------------------*/ | ||
25 | /* file: dbgioctl.h */ | ||
26 | /*------------------------------------------------------------------*/ | ||
27 | |||
28 | #if !defined(__DBGIOCTL_H__) | ||
29 | |||
30 | #define __DBGIOCTL_H__ | ||
31 | |||
32 | #ifdef NOT_YET_NEEDED | ||
33 | /* | ||
34 | * The requested operation is passed in arg0 of DbgIoctlArgs, | ||
35 | * additional arguments (if any) in arg1, arg2 and arg3. | ||
36 | */ | ||
37 | |||
38 | typedef struct | ||
39 | { ULONG arg0 ; | ||
40 | ULONG arg1 ; | ||
41 | ULONG arg2 ; | ||
42 | ULONG arg3 ; | ||
43 | } DbgIoctlArgs ; | ||
44 | |||
45 | #define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */ | ||
46 | /* arg1: size threshold */ | ||
47 | /* arg2: timeout in milliseconds */ | ||
48 | |||
49 | #define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */ | ||
50 | /* arg1: internal driver id */ | ||
51 | |||
52 | #define DBG_LIST_DRVS 2 /* return the list of registered drivers */ | ||
53 | |||
54 | #define DBG_GET_MASK 3 /* get current debug mask of driver */ | ||
55 | /* arg1: internal driver id */ | ||
56 | |||
57 | #define DBG_SET_MASK 4 /* set/change debug mask of driver */ | ||
58 | /* arg1: internal driver id */ | ||
59 | /* arg2: new debug mask */ | ||
60 | |||
61 | #define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */ | ||
62 | /* arg1: internal driver id */ | ||
63 | /* arg2: new debug mask */ | ||
64 | |||
65 | #define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */ | ||
66 | /* arg1: new buffer size */ | ||
67 | |||
68 | /* | ||
69 | * common internal debug message structure | ||
70 | */ | ||
71 | |||
72 | typedef struct | ||
73 | { unsigned short id ; /* virtual driver id */ | ||
74 | unsigned short type ; /* special message type */ | ||
75 | unsigned long seq ; /* sequence number of message */ | ||
76 | unsigned long size ; /* size of message in bytes */ | ||
77 | unsigned long next ; /* offset to next buffered message */ | ||
78 | LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ | ||
79 | unsigned char data[4] ;/* message data */ | ||
80 | } OldDbgMessage ; | ||
81 | |||
82 | typedef struct | ||
83 | { LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ | ||
84 | unsigned short size ; /* size of message in bytes */ | ||
85 | unsigned short ffff ; /* always 0xffff to indicate new msg */ | ||
86 | unsigned short id ; /* virtual driver id */ | ||
87 | unsigned short type ; /* special message type */ | ||
88 | unsigned long seq ; /* sequence number of message */ | ||
89 | unsigned char data[4] ;/* message data */ | ||
90 | } DbgMessage ; | ||
91 | |||
92 | #endif | ||
93 | |||
94 | #define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */ | ||
95 | |||
96 | #define MSG_PROC_FLAG 0x80 | ||
97 | #define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1) | ||
98 | #define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4)) | ||
99 | |||
100 | #define MSG_TYPE_DRV_ID 0x0001 | ||
101 | #define MSG_TYPE_FLAGS 0x0002 | ||
102 | #define MSG_TYPE_STRING 0x0003 | ||
103 | #define MSG_TYPE_BINARY 0x0004 | ||
104 | |||
105 | #define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0])) | ||
106 | #define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3) | ||
107 | #define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size) | ||
108 | #define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) )) | ||
109 | |||
110 | #define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0])) | ||
111 | #define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3) | ||
112 | |||
113 | /* | ||
114 | * manifest constants | ||
115 | */ | ||
116 | |||
117 | #define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */ | ||
118 | #define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */ | ||
119 | #define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE) | ||
120 | #define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */ | ||
121 | #define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */ | ||
122 | #define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */ | ||
123 | |||
124 | #define DBGDRV_NAME "Diehl_DIMAINT" | ||
125 | #define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */ | ||
126 | #define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */ | ||
127 | #define DBGVXD_NAME "DIMAINT" | ||
128 | #define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */ | ||
129 | |||
130 | /* | ||
131 | * Special IDI interface debug construction | ||
132 | */ | ||
133 | |||
134 | #define DBG_IDI_SIG_REQ (unsigned long)0xF479C402 | ||
135 | #define DBG_IDI_SIG_IND (unsigned long)0xF479C403 | ||
136 | #define DBG_IDI_NL_REQ (unsigned long)0xF479C404 | ||
137 | #define DBG_IDI_NL_IND (unsigned long)0xF479C405 | ||
138 | |||
139 | typedef struct | ||
140 | { unsigned long magic_type ; | ||
141 | unsigned short data_len ; | ||
142 | unsigned char layer_ID ; | ||
143 | unsigned char entity_ID ; | ||
144 | unsigned char request ; | ||
145 | unsigned char ret_code ; | ||
146 | unsigned char indication ; | ||
147 | unsigned char complete ; | ||
148 | unsigned char data[4] ; | ||
149 | } DbgIdiAct, *DbgIdiAction ; | ||
150 | |||
151 | /* | ||
152 | * We want to use the same IOCTL codes in Win95 and WinNT. | ||
153 | * The official constructor for IOCTL codes is the CTL_CODE macro | ||
154 | * from <winoctl.h> (<devioctl.h> in WinNT DDK environment). | ||
155 | * The problem here is that we don't know how to get <winioctl.h> | ||
156 | * working in a Win95 DDK environment! | ||
157 | */ | ||
158 | |||
159 | # ifdef CTL_CODE /*{*/ | ||
160 | |||
161 | /* Assert that we have the same idea of the CTL_CODE macro. */ | ||
162 | |||
163 | #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ | ||
164 | ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ | ||
165 | ) | ||
166 | |||
167 | # else /* !CTL_CODE */ /*}{*/ | ||
168 | |||
169 | /* Use the definitions stolen from <winioctl.h>. */ | ||
170 | |||
171 | #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ | ||
172 | ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ | ||
173 | ) | ||
174 | |||
175 | #define METHOD_BUFFERED 0 | ||
176 | #define METHOD_IN_DIRECT 1 | ||
177 | #define METHOD_OUT_DIRECT 2 | ||
178 | #define METHOD_NEITHER 3 | ||
179 | |||
180 | #define FILE_ANY_ACCESS 0 | ||
181 | #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe | ||
182 | #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe | ||
183 | |||
184 | # endif /* CTL_CODE */ /*}*/ | ||
185 | |||
186 | /* | ||
187 | * Now we can define WinNT/Win95 DeviceIoControl codes. | ||
188 | * | ||
189 | * These codes are defined in di_defs.h too, a possible mismatch will be | ||
190 | * detected when the dbgtool is compiled. | ||
191 | */ | ||
192 | |||
193 | #define IOCTL_DRIVER_LNK \ | ||
194 | CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) | ||
195 | #define IOCTL_DRIVER_DBG \ | ||
196 | CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) | ||
197 | |||
198 | #endif /* __DBGIOCTL_H__ */ | ||
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c index 4aba5c502d8e..c90928974249 100644 --- a/drivers/isdn/hardware/eicon/divamnt.c +++ b/drivers/isdn/hardware/eicon/divamnt.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
19 | 18 | ||
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c index 556b19615bc7..78f141e77466 100644 --- a/drivers/isdn/hardware/eicon/divasi.c +++ b/drivers/isdn/hardware/eicon/divasi.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/poll.h> | 17 | #include <linux/poll.h> |
19 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
20 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index 5e862e244117..6d39f9360766 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
22 | #include <linux/list.h> | 21 | #include <linux/list.h> |
23 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
diff --git a/drivers/isdn/hardware/eicon/main_if.h b/drivers/isdn/hardware/eicon/main_if.h deleted file mode 100644 index 0ea339afd424..000000000000 --- a/drivers/isdn/hardware/eicon/main_if.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | Copyright (c) Eicon Technology Corporation, 2000. | ||
4 | * | ||
5 | This source file is supplied for the use with Eicon | ||
6 | Technology Corporation's range of DIVA Server Adapters. | ||
7 | * | ||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2, or (at your option) | ||
11 | any later version. | ||
12 | * | ||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY | ||
15 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
16 | See the GNU General Public License for more details. | ||
17 | * | ||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | */ | ||
23 | /*------------------------------------------------------------------*/ | ||
24 | /* file: main_if.h */ | ||
25 | /*------------------------------------------------------------------*/ | ||
26 | # ifndef MAIN_IF___H | ||
27 | # define MAIN_IF___H | ||
28 | |||
29 | # include "debug_if.h" | ||
30 | |||
31 | void DI_lock (void) ; | ||
32 | void DI_unlock (void) ; | ||
33 | |||
34 | #ifdef NOT_YET_NEEDED | ||
35 | void DI_nttime (LARGE_INTEGER *NTtime) ; | ||
36 | void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ; | ||
37 | void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields); | ||
38 | unsigned long DI_wintime(LARGE_INTEGER *NTtime) ; | ||
39 | |||
40 | unsigned short DiInsertProcessorNumber (int type) ; | ||
41 | void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap); | ||
42 | |||
43 | void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ; | ||
44 | void StopIoctlTimer (void) ; | ||
45 | void UnpendIoctl (DbgRequest *pDbgReq) ; | ||
46 | #endif | ||
47 | |||
48 | void add_to_q(int, char* , unsigned int); | ||
49 | # endif /* MAIN_IF___H */ | ||
50 | |||
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h index ff09f07f440a..15d4942de53b 100644 --- a/drivers/isdn/hardware/eicon/platform.h +++ b/drivers/isdn/hardware/eicon/platform.h | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
31 | #include <linux/list.h> | 30 | #include <linux/list.h> |
32 | #include <asm/types.h> | 31 | #include <asm/types.h> |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 9f44d3e69fb0..99e70d4103b6 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
38 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include "hisax.h" | 40 | #include "hisax.h" |
42 | #include "hisax_if.h" | 41 | #include "hisax_if.h" |
43 | #include "hfc_usb.h" | 42 | #include "hfc_usb.h" |
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 84dccd526ac0..6cdbad3a9926 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c | |||
@@ -443,7 +443,7 @@ ergo_inithardware(hysdn_card * card) | |||
443 | card->waitpofready = ergo_waitpofready; | 443 | card->waitpofready = ergo_waitpofready; |
444 | card->set_errlog_state = ergo_set_errlog_state; | 444 | card->set_errlog_state = ergo_set_errlog_state; |
445 | INIT_WORK(&card->irq_queue, ergo_irq_bh); | 445 | INIT_WORK(&card->irq_queue, ergo_irq_bh); |
446 | card->hysdn_lock = SPIN_LOCK_UNLOCKED; | 446 | spin_lock_init(&card->hysdn_lock); |
447 | 447 | ||
448 | return (0); | 448 | return (0); |
449 | } /* ergo_inithardware */ | 449 | } /* ergo_inithardware */ |
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 4c7dedac0e51..27b3991fb0ec 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c | |||
@@ -297,8 +297,6 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
297 | struct procdata *pd; | 297 | struct procdata *pd; |
298 | hysdn_card *card; | 298 | hysdn_card *card; |
299 | int retval = 0; | 299 | int retval = 0; |
300 | unsigned long flags; | ||
301 | spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED; | ||
302 | 300 | ||
303 | lock_kernel(); | 301 | lock_kernel(); |
304 | if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { | 302 | if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { |
@@ -308,7 +306,6 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
308 | /* read access -> log/debug read, mark one further file as closed */ | 306 | /* read access -> log/debug read, mark one further file as closed */ |
309 | 307 | ||
310 | pd = NULL; | 308 | pd = NULL; |
311 | spin_lock_irqsave(&hysdn_lock, flags); | ||
312 | inf = *((struct log_data **) filep->private_data); /* get first log entry */ | 309 | inf = *((struct log_data **) filep->private_data); /* get first log entry */ |
313 | if (inf) | 310 | if (inf) |
314 | pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ | 311 | pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ |
@@ -331,7 +328,6 @@ hysdn_log_close(struct inode *ino, struct file *filep) | |||
331 | inf->usage_cnt--; /* decrement usage count for buffers */ | 328 | inf->usage_cnt--; /* decrement usage count for buffers */ |
332 | inf = inf->next; | 329 | inf = inf->next; |
333 | } | 330 | } |
334 | spin_unlock_irqrestore(&hysdn_lock, flags); | ||
335 | 331 | ||
336 | if (pd) | 332 | if (pd) |
337 | if (pd->if_used <= 0) /* delete buffers if last file closed */ | 333 | if (pd->if_used <= 0) /* delete buffers if last file closed */ |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index e93ad59f60bf..bb92e3cd9334 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
@@ -1462,7 +1462,7 @@ isdnloop_initcard(char *id) | |||
1462 | skb_queue_head_init(&card->bqueue[i]); | 1462 | skb_queue_head_init(&card->bqueue[i]); |
1463 | } | 1463 | } |
1464 | skb_queue_head_init(&card->dqueue); | 1464 | skb_queue_head_init(&card->dqueue); |
1465 | card->isdnloop_lock = SPIN_LOCK_UNLOCKED; | 1465 | spin_lock_init(&card->isdnloop_lock); |
1466 | card->next = cards; | 1466 | card->next = cards; |
1467 | cards = card; | 1467 | cards = card; |
1468 | if (!register_isdn(&card->interface)) { | 1468 | if (!register_isdn(&card->interface)) { |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 178afa1fd56c..bd55e6ab99fc 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
24 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
25 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 78ff18617139..dbb22403979f 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -117,7 +117,6 @@ | |||
117 | #include <linux/slab.h> | 117 | #include <linux/slab.h> |
118 | #include <linux/init.h> | 118 | #include <linux/init.h> |
119 | #include <linux/spinlock.h> | 119 | #include <linux/spinlock.h> |
120 | #include <linux/smp_lock.h> | ||
121 | #include <linux/wait.h> | 120 | #include <linux/wait.h> |
122 | #include <linux/reboot.h> | 121 | #include <linux/reboot.h> |
123 | #include <linux/kmod.h> | 122 | #include <linux/kmod.h> |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 94c117ef20c1..192b26e97777 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
32 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
33 | #include <linux/reboot.h> | 32 | #include <linux/reboot.h> |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index e61e0efe9ec7..5a4a74c1097c 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1456,10 +1456,10 @@ int bitmap_create(mddev_t *mddev) | |||
1456 | bitmap->offset = mddev->bitmap_offset; | 1456 | bitmap->offset = mddev->bitmap_offset; |
1457 | if (file) { | 1457 | if (file) { |
1458 | get_file(file); | 1458 | get_file(file); |
1459 | do_sync_file_range(file, 0, LLONG_MAX, | 1459 | do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX, |
1460 | SYNC_FILE_RANGE_WAIT_BEFORE | | 1460 | SYNC_FILE_RANGE_WAIT_BEFORE | |
1461 | SYNC_FILE_RANGE_WRITE | | 1461 | SYNC_FILE_RANGE_WRITE | |
1462 | SYNC_FILE_RANGE_WAIT_AFTER); | 1462 | SYNC_FILE_RANGE_WAIT_AFTER); |
1463 | } | 1463 | } |
1464 | /* read superblock from bitmap file (this sets bitmap->chunksize) */ | 1464 | /* read superblock from bitmap file (this sets bitmap->chunksize) */ |
1465 | err = bitmap_read_sb(bitmap); | 1465 | err = bitmap_read_sb(bitmap); |
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 3bf084f2e522..87623d203a89 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -22,7 +22,6 @@ | |||
22 | #ifndef DST_COMMON_H | 22 | #ifndef DST_COMMON_H |
23 | #define DST_COMMON_H | 23 | #define DST_COMMON_H |
24 | 24 | ||
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/dvb/frontend.h> | 25 | #include <linux/dvb/frontend.h> |
27 | #include <linux/device.h> | 26 | #include <linux/device.h> |
28 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 654c9e919e04..58678c05aa53 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/fs.h> | 35 | #include <linux/fs.h> |
37 | 36 | ||
38 | #include "av7110.h" | 37 | #include "av7110.h" |
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index e9b4e88e7932..e1c1294bb767 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
36 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
37 | #include <linux/smp_lock.h> | ||
38 | 37 | ||
39 | #include "av7110.h" | 38 | #include "av7110.h" |
40 | #include "av7110_hw.h" | 39 | #include "av7110_hw.h" |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 4d7150e15d1e..70aee4eb5da4 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/smp_lock.h> | ||
37 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
38 | 37 | ||
39 | #include "av7110.h" | 38 | #include "av7110.h" |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index cde5d3ae7ec7..fcd9994058d0 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
33 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
34 | #include <linux/smp_lock.h> | ||
35 | 34 | ||
36 | #include "av7110.h" | 35 | #include "av7110.h" |
37 | #include "av7110_hw.h" | 36 | #include "av7110_hw.h" |
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index df8d0520d1d1..449df1bb00d3 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c | |||
@@ -79,7 +79,6 @@ | |||
79 | #include <linux/videodev2.h> | 79 | #include <linux/videodev2.h> |
80 | #include <media/v4l2-common.h> | 80 | #include <media/v4l2-common.h> |
81 | #include <linux/usb.h> | 81 | #include <linux/usb.h> |
82 | #include <linux/smp_lock.h> | ||
83 | 82 | ||
84 | /* | 83 | /* |
85 | * Version Information | 84 | * Version Information |
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index 6eaa692021c5..78392fb6f94e 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/videodev.h> | 47 | #include <linux/videodev.h> |
48 | #include <media/v4l2-common.h> | 48 | #include <media/v4l2-common.h> |
49 | #include <linux/list.h> | 49 | #include <linux/list.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
52 | 51 | ||
53 | struct cpia_camera_ops | 52 | struct cpia_camera_ops |
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index 19711aaf9a3e..c431df8248d6 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
39 | 38 | ||
40 | #include <linux/kmod.h> | 39 | #include <linux/kmod.h> |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index e627062fde3a..259ea08e784f 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/interrupt.h> | 49 | #include <linux/interrupt.h> |
50 | #include <linux/vmalloc.h> | 50 | #include <linux/vmalloc.h> |
51 | #include <linux/init.h> | 51 | #include <linux/init.h> |
52 | #include <linux/smp_lock.h> | ||
53 | #include <linux/delay.h> | 52 | #include <linux/delay.h> |
54 | #include <linux/kthread.h> | 53 | #include <linux/kthread.h> |
55 | 54 | ||
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index ff4b238090ac..a5731f90be0f 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/atomic.h> | 37 | #include <asm/atomic.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/usb.h> | 39 | #include <linux/usb.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
42 | 41 | ||
43 | #include "dabusb.h" | 42 | #include "dabusb.h" |
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 68b082bcee1d..18c64222dd11 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h | |||
@@ -4,7 +4,6 @@ | |||
4 | #include <asm/uaccess.h> | 4 | #include <asm/uaccess.h> |
5 | #include <linux/videodev.h> | 5 | #include <linux/videodev.h> |
6 | #include <media/v4l2-common.h> | 6 | #include <media/v4l2-common.h> |
7 | #include <linux/smp_lock.h> | ||
8 | #include <linux/usb.h> | 7 | #include <linux/usb.h> |
9 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
10 | 9 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index e976c484c058..9ea41c6699bb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
30 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
31 | 30 | ||
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index dd759d6d8d25..7b56041186dc 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <asm/div64.h> | 30 | #include <asm/div64.h> |
32 | 31 | ||
33 | #include "saa7134-reg.h" | 32 | #include "saa7134-reg.h" |
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h index c0891b3e0018..835ef872e803 100644 --- a/drivers/media/video/se401.h +++ b/drivers/media/video/se401.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <asm/uaccess.h> | 5 | #include <asm/uaccess.h> |
6 | #include <linux/videodev.h> | 6 | #include <linux/videodev.h> |
7 | #include <media/v4l2-common.h> | 7 | #include <media/v4l2-common.h> |
8 | #include <linux/smp_lock.h> | ||
9 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
10 | 9 | ||
11 | #define se401_DEBUG /* Turn on debug messages */ | 10 | #define se401_DEBUG /* Turn on debug messages */ |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index a2da5d2affff..c9bf9dbc2ea3 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/videodev.h> | 26 | #include <linux/videodev.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
31 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
32 | 31 | ||
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 687f026753b2..37ce36b9e587 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/smp_lock.h> | ||
24 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
25 | #include <linux/init.h> | 24 | #include <linux/init.h> |
26 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index bcb551adb7e6..9118a6227ea6 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <linux/utsname.h> | 31 | #include <linux/utsname.h> |
32 | #include <linux/highmem.h> | 32 | #include <linux/highmem.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/videodev.h> | 33 | #include <linux/videodev.h> |
35 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
36 | #include <linux/module.h> | 35 | #include <linux/module.h> |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 216704170a4c..aa3258bbb4af 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
53 | #include <linux/utsname.h> | 53 | #include <linux/utsname.h> |
54 | #include <linux/highmem.h> | 54 | #include <linux/highmem.h> |
55 | #include <linux/smp_lock.h> | ||
56 | #include <linux/videodev.h> | 55 | #include <linux/videodev.h> |
57 | #include <linux/vmalloc.h> | 56 | #include <linux/vmalloc.h> |
58 | #include <linux/module.h> | 57 | #include <linux/module.h> |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index d2c1ae0dbfba..a861e150865e 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
28 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
29 | #include <linux/file.h> | 28 | #include <linux/file.h> |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 49f1df74aa21..13ee550d3215 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
48 | #include <linux/types.h> | 48 | #include <linux/types.h> |
49 | #include <linux/kernel.h> | 49 | #include <linux/kernel.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
52 | #include <linux/string.h> | 51 | #include <linux/string.h> |
53 | #include <linux/errno.h> | 52 | #include <linux/errno.h> |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 80ac5f86d9e5..5263b50463e1 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
35 | #include <linux/string.h> | 34 | #include <linux/string.h> |
36 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 074323733352..cf0ed6cbb0e3 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -2034,7 +2034,7 @@ zoran_do_ioctl (struct inode *inode, | |||
2034 | * but moving the free code outside the munmap() handler fixes | 2034 | * but moving the free code outside the munmap() handler fixes |
2035 | * all this... If someone knows why, please explain me (Ronald) | 2035 | * all this... If someone knows why, please explain me (Ronald) |
2036 | */ | 2036 | */ |
2037 | if (!!mutex_trylock(&zr->resource_lock)) { | 2037 | if (mutex_trylock(&zr->resource_lock)) { |
2038 | /* we obtained it! Let's try to free some things */ | 2038 | /* we obtained it! Let's try to free some things */ |
2039 | if (fh->jpg_buffers.ready_to_be_freed) | 2039 | if (fh->jpg_buffers.ready_to_be_freed) |
2040 | jpg_fbuffer_free(file); | 2040 | jpg_fbuffer_free(file); |
diff --git a/drivers/message/i2o/i2o_lan.h b/drivers/message/i2o/i2o_lan.h deleted file mode 100644 index 6502b817df58..000000000000 --- a/drivers/message/i2o/i2o_lan.h +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | * i2o_lan.h I2O LAN Class definitions | ||
3 | * | ||
4 | * I2O LAN CLASS OSM May 26th 2000 | ||
5 | * | ||
6 | * (C) Copyright 1999, 2000 University of Helsinki, | ||
7 | * Department of Computer Science | ||
8 | * | ||
9 | * This code is still under development / test. | ||
10 | * | ||
11 | * Author: Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> | ||
12 | * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> | ||
13 | * Taneli Vähäkangas <Taneli.Vahakangas@cs.Helsinki.FI> | ||
14 | */ | ||
15 | |||
16 | #ifndef _I2O_LAN_H | ||
17 | #define _I2O_LAN_H | ||
18 | |||
19 | /* Default values for tunable parameters first */ | ||
20 | |||
21 | #define I2O_LAN_MAX_BUCKETS_OUT 96 | ||
22 | #define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */ | ||
23 | #define I2O_LAN_RX_COPYBREAK 200 | ||
24 | #define I2O_LAN_TX_TIMEOUT (1*HZ) | ||
25 | #define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */ | ||
26 | #define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */ | ||
27 | |||
28 | /* LAN types */ | ||
29 | #define I2O_LAN_ETHERNET 0x0030 | ||
30 | #define I2O_LAN_100VG 0x0040 | ||
31 | #define I2O_LAN_TR 0x0050 | ||
32 | #define I2O_LAN_FDDI 0x0060 | ||
33 | #define I2O_LAN_FIBRE_CHANNEL 0x0070 | ||
34 | #define I2O_LAN_UNKNOWN 0x00000000 | ||
35 | |||
36 | /* Connector types */ | ||
37 | |||
38 | /* Ethernet */ | ||
39 | #define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001 | ||
40 | #define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002 | ||
41 | #define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003 | ||
42 | #define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004 | ||
43 | #define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005 | ||
44 | #define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006 | ||
45 | #define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007 | ||
46 | #define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008 | ||
47 | #define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009 | ||
48 | #define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A | ||
49 | #define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B | ||
50 | #define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C | ||
51 | #define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D | ||
52 | #define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E | ||
53 | #define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F | ||
54 | #define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010 | ||
55 | |||
56 | /* AnyLAN */ | ||
57 | #define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001 | ||
58 | #define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002 | ||
59 | |||
60 | /* Token Ring */ | ||
61 | #define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001 | ||
62 | #define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002 | ||
63 | |||
64 | /* FDDI */ | ||
65 | #define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001 | ||
66 | |||
67 | /* Fibre Channel */ | ||
68 | #define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001 | ||
69 | #define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002 | ||
70 | #define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003 | ||
71 | #define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004 | ||
72 | |||
73 | #define I2O_LAN_EMULATION 0x00000F00 | ||
74 | #define I2O_LAN_OTHER 0x00000F01 | ||
75 | #define I2O_LAN_DEFAULT 0xFFFFFFFF | ||
76 | |||
77 | /* LAN class functions */ | ||
78 | |||
79 | #define LAN_PACKET_SEND 0x3B | ||
80 | #define LAN_SDU_SEND 0x3D | ||
81 | #define LAN_RECEIVE_POST 0x3E | ||
82 | #define LAN_RESET 0x35 | ||
83 | #define LAN_SUSPEND 0x37 | ||
84 | |||
85 | /* LAN DetailedStatusCode defines */ | ||
86 | #define I2O_LAN_DSC_SUCCESS 0x00 | ||
87 | #define I2O_LAN_DSC_DEVICE_FAILURE 0x01 | ||
88 | #define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02 | ||
89 | #define I2O_LAN_DSC_TRANSMIT_ERROR 0x03 | ||
90 | #define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04 | ||
91 | #define I2O_LAN_DSC_RECEIVE_ERROR 0x05 | ||
92 | #define I2O_LAN_DSC_RECEIVE_ABORTED 0x06 | ||
93 | #define I2O_LAN_DSC_DMA_ERROR 0x07 | ||
94 | #define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08 | ||
95 | #define I2O_LAN_DSC_OUT_OF_MEMORY 0x09 | ||
96 | #define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A | ||
97 | #define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B | ||
98 | #define I2O_LAN_DSC_CANCELED 0x0C | ||
99 | #define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D | ||
100 | #define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E | ||
101 | #define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F | ||
102 | #define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10 | ||
103 | #define I2O_LAN_DSC_SUSPENDED 0x11 | ||
104 | |||
105 | struct i2o_packet_info { | ||
106 | u32 offset:24; | ||
107 | u32 flags:8; | ||
108 | u32 len:24; | ||
109 | u32 status:8; | ||
110 | }; | ||
111 | |||
112 | struct i2o_bucket_descriptor { | ||
113 | u32 context; /* FIXME: 64bit support */ | ||
114 | struct i2o_packet_info packet_info[1]; | ||
115 | }; | ||
116 | |||
117 | /* Event Indicator Mask Flags for LAN OSM */ | ||
118 | |||
119 | #define I2O_LAN_EVT_LINK_DOWN 0x01 | ||
120 | #define I2O_LAN_EVT_LINK_UP 0x02 | ||
121 | #define I2O_LAN_EVT_MEDIA_CHANGE 0x04 | ||
122 | |||
123 | #include <linux/netdevice.h> | ||
124 | #include <linux/fddidevice.h> | ||
125 | |||
126 | struct i2o_lan_local { | ||
127 | u8 unit; | ||
128 | struct i2o_device *i2o_dev; | ||
129 | |||
130 | struct fddi_statistics stats; /* see also struct net_device_stats */ | ||
131 | unsigned short (*type_trans) (struct sk_buff *, struct net_device *); | ||
132 | atomic_t buckets_out; /* nbr of unused buckets on DDM */ | ||
133 | atomic_t tx_out; /* outstanding TXes */ | ||
134 | u8 tx_count; /* packets in one TX message frame */ | ||
135 | u16 tx_max_out; /* DDM's Tx queue len */ | ||
136 | u8 sgl_max; /* max SGLs in one message frame */ | ||
137 | u32 m; /* IOP address of the batch msg frame */ | ||
138 | |||
139 | struct work_struct i2o_batch_send_task; | ||
140 | int send_active; | ||
141 | struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */ | ||
142 | int i2o_fbl_tail; | ||
143 | spinlock_t fbl_lock; | ||
144 | |||
145 | spinlock_t tx_lock; | ||
146 | |||
147 | u32 max_size_mc_table; /* max number of multicast addresses */ | ||
148 | |||
149 | /* LAN OSM configurable parameters are here: */ | ||
150 | |||
151 | u16 max_buckets_out; /* max nbr of buckets to send to DDM */ | ||
152 | u16 bucket_thresh; /* send more when this many used */ | ||
153 | u16 rx_copybreak; | ||
154 | |||
155 | u8 tx_batch_mode; /* Set when using batch mode sends */ | ||
156 | u32 i2o_event_mask; /* To turn on interesting event flags */ | ||
157 | }; | ||
158 | |||
159 | #endif /* _I2O_LAN_H */ | ||
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index ce1a48108210..cb8c264eaff0 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
26 | #include <linux/completion.h> | 25 | #include <linux/completion.h> |
27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a3c525b2616a..877e7909a0e5 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -25,6 +25,15 @@ config IBM_ASM | |||
25 | information on the specific driver level and support statement | 25 | information on the specific driver level and support statement |
26 | for your IBM server. | 26 | for your IBM server. |
27 | 27 | ||
28 | config PHANTOM | ||
29 | tristate "Sensable PHANToM" | ||
30 | depends on PCI | ||
31 | help | ||
32 | Say Y here if you want to build a driver for Sensable PHANToM device. | ||
33 | |||
34 | If you choose to build module, its name will be phantom. If unsure, | ||
35 | say N here. | ||
36 | |||
28 | 37 | ||
29 | If unsure, say N. | 38 | If unsure, say N. |
30 | 39 | ||
@@ -178,4 +187,13 @@ config THINKPAD_ACPI_BAY | |||
178 | 187 | ||
179 | If you are not sure, say Y here. | 188 | If you are not sure, say Y here. |
180 | 189 | ||
190 | config BLINK | ||
191 | tristate "Keyboard blink driver" | ||
192 | help | ||
193 | Driver that when loaded will blink the keyboard LEDs continuously. | ||
194 | This is useful for debugging and for kernels that cannot necessarily | ||
195 | output something to the screen like kexec kernels to give the user | ||
196 | a visual indication that the kernel is doing something. | ||
197 | |||
198 | |||
181 | endmenu | 199 | endmenu |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index e32516459138..5b6d46de005c 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -7,9 +7,11 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ | |||
7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ | 7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ |
8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | 8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o |
9 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o | 9 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o |
10 | obj-$(CONFIG_BLINK) += blink.o | ||
10 | obj-$(CONFIG_LKDTM) += lkdtm.o | 11 | obj-$(CONFIG_LKDTM) += lkdtm.o |
11 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | 12 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o |
12 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o | 13 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o |
14 | obj-$(CONFIG_PHANTOM) += phantom.o | ||
13 | obj-$(CONFIG_SGI_IOC4) += ioc4.o | 15 | obj-$(CONFIG_SGI_IOC4) += ioc4.o |
14 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o | 16 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o |
15 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o | 17 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o |
diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c new file mode 100644 index 000000000000..634431ce1184 --- /dev/null +++ b/drivers/misc/blink.c | |||
@@ -0,0 +1,27 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/timer.h> | ||
4 | #include <linux/jiffies.h> | ||
5 | |||
6 | static void do_blink(unsigned long data); | ||
7 | |||
8 | static DEFINE_TIMER(blink_timer, do_blink, 0 ,0); | ||
9 | |||
10 | static void do_blink(unsigned long data) | ||
11 | { | ||
12 | static long count; | ||
13 | if (panic_blink) | ||
14 | panic_blink(count++); | ||
15 | blink_timer.expires = jiffies + msecs_to_jiffies(1); | ||
16 | add_timer(&blink_timer); | ||
17 | } | ||
18 | |||
19 | static int blink_init(void) | ||
20 | { | ||
21 | printk(KERN_INFO "Enabling keyboard blinking\n"); | ||
22 | do_blink(0); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | module_init(blink_init); | ||
27 | |||
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c new file mode 100644 index 000000000000..35b139b0e5f2 --- /dev/null +++ b/drivers/misc/phantom.c | |||
@@ -0,0 +1,463 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * You need an userspace library to cooperate with this driver. It (and other | ||
10 | * info) may be obtained here: | ||
11 | * http://www.fi.muni.cz/~xslaby/phantom.html | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/fs.h> | ||
19 | #include <linux/poll.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/cdev.h> | ||
22 | #include <linux/phantom.h> | ||
23 | |||
24 | #include <asm/atomic.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #define PHANTOM_VERSION "n0.9.5" | ||
28 | |||
29 | #define PHANTOM_MAX_MINORS 8 | ||
30 | |||
31 | #define PHN_IRQCTL 0x4c /* irq control in caddr space */ | ||
32 | |||
33 | #define PHB_RUNNING 1 | ||
34 | |||
35 | static struct class *phantom_class; | ||
36 | static int phantom_major; | ||
37 | |||
38 | struct phantom_device { | ||
39 | unsigned int opened; | ||
40 | void __iomem *caddr; | ||
41 | u32 __iomem *iaddr; | ||
42 | u32 __iomem *oaddr; | ||
43 | unsigned long status; | ||
44 | atomic_t counter; | ||
45 | |||
46 | wait_queue_head_t wait; | ||
47 | struct cdev cdev; | ||
48 | |||
49 | struct mutex open_lock; | ||
50 | }; | ||
51 | |||
52 | static unsigned char phantom_devices[PHANTOM_MAX_MINORS]; | ||
53 | |||
54 | static int phantom_status(struct phantom_device *dev, unsigned long newstat) | ||
55 | { | ||
56 | pr_debug("phantom_status %lx %lx\n", dev->status, newstat); | ||
57 | |||
58 | if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) { | ||
59 | atomic_set(&dev->counter, 0); | ||
60 | iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL); | ||
61 | iowrite32(0x43, dev->caddr + PHN_IRQCTL); | ||
62 | } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) | ||
63 | iowrite32(0, dev->caddr + PHN_IRQCTL); | ||
64 | |||
65 | dev->status = newstat; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * File ops | ||
72 | */ | ||
73 | |||
74 | static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, | ||
75 | u_long arg) | ||
76 | { | ||
77 | struct phantom_device *dev = file->private_data; | ||
78 | struct phm_regs rs; | ||
79 | struct phm_reg r; | ||
80 | void __user *argp = (void __user *)arg; | ||
81 | unsigned int i; | ||
82 | |||
83 | if (_IOC_TYPE(cmd) != PH_IOC_MAGIC || | ||
84 | _IOC_NR(cmd) > PH_IOC_MAXNR) | ||
85 | return -ENOTTY; | ||
86 | |||
87 | switch (cmd) { | ||
88 | case PHN_SET_REG: | ||
89 | if (copy_from_user(&r, argp, sizeof(r))) | ||
90 | return -EFAULT; | ||
91 | |||
92 | if (r.reg > 7) | ||
93 | return -EINVAL; | ||
94 | |||
95 | if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) && | ||
96 | phantom_status(dev, dev->status | PHB_RUNNING)) | ||
97 | return -ENODEV; | ||
98 | |||
99 | pr_debug("phantom: writing %x to %u\n", r.value, r.reg); | ||
100 | iowrite32(r.value, dev->iaddr + r.reg); | ||
101 | |||
102 | if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ)) | ||
103 | phantom_status(dev, dev->status & ~PHB_RUNNING); | ||
104 | break; | ||
105 | case PHN_SET_REGS: | ||
106 | if (copy_from_user(&rs, argp, sizeof(rs))) | ||
107 | return -EFAULT; | ||
108 | |||
109 | pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask); | ||
110 | for (i = 0; i < min(rs.count, 8U); i++) | ||
111 | if ((1 << i) & rs.mask) | ||
112 | iowrite32(rs.values[i], dev->oaddr + i); | ||
113 | break; | ||
114 | case PHN_GET_REG: | ||
115 | if (copy_from_user(&r, argp, sizeof(r))) | ||
116 | return -EFAULT; | ||
117 | |||
118 | if (r.reg > 7) | ||
119 | return -EINVAL; | ||
120 | |||
121 | r.value = ioread32(dev->iaddr + r.reg); | ||
122 | |||
123 | if (copy_to_user(argp, &r, sizeof(r))) | ||
124 | return -EFAULT; | ||
125 | break; | ||
126 | case PHN_GET_REGS: | ||
127 | if (copy_from_user(&rs, argp, sizeof(rs))) | ||
128 | return -EFAULT; | ||
129 | |||
130 | pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask); | ||
131 | for (i = 0; i < min(rs.count, 8U); i++) | ||
132 | if ((1 << i) & rs.mask) | ||
133 | rs.values[i] = ioread32(dev->iaddr + i); | ||
134 | |||
135 | if (copy_to_user(argp, &rs, sizeof(rs))) | ||
136 | return -EFAULT; | ||
137 | break; | ||
138 | default: | ||
139 | return -ENOTTY; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int phantom_open(struct inode *inode, struct file *file) | ||
146 | { | ||
147 | struct phantom_device *dev = container_of(inode->i_cdev, | ||
148 | struct phantom_device, cdev); | ||
149 | |||
150 | nonseekable_open(inode, file); | ||
151 | |||
152 | if (mutex_lock_interruptible(&dev->open_lock)) | ||
153 | return -ERESTARTSYS; | ||
154 | |||
155 | if (dev->opened) { | ||
156 | mutex_unlock(&dev->open_lock); | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
160 | file->private_data = dev; | ||
161 | |||
162 | dev->opened++; | ||
163 | mutex_unlock(&dev->open_lock); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int phantom_release(struct inode *inode, struct file *file) | ||
169 | { | ||
170 | struct phantom_device *dev = file->private_data; | ||
171 | |||
172 | mutex_lock(&dev->open_lock); | ||
173 | |||
174 | dev->opened = 0; | ||
175 | phantom_status(dev, dev->status & ~PHB_RUNNING); | ||
176 | |||
177 | mutex_unlock(&dev->open_lock); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static unsigned int phantom_poll(struct file *file, poll_table *wait) | ||
183 | { | ||
184 | struct phantom_device *dev = file->private_data; | ||
185 | unsigned int mask = 0; | ||
186 | |||
187 | pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter)); | ||
188 | poll_wait(file, &dev->wait, wait); | ||
189 | if (atomic_read(&dev->counter)) { | ||
190 | mask = POLLIN | POLLRDNORM; | ||
191 | atomic_dec(&dev->counter); | ||
192 | } else if ((dev->status & PHB_RUNNING) == 0) | ||
193 | mask = POLLIN | POLLRDNORM | POLLERR; | ||
194 | pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter)); | ||
195 | |||
196 | return mask; | ||
197 | } | ||
198 | |||
199 | static struct file_operations phantom_file_ops = { | ||
200 | .open = phantom_open, | ||
201 | .release = phantom_release, | ||
202 | .ioctl = phantom_ioctl, | ||
203 | .poll = phantom_poll, | ||
204 | }; | ||
205 | |||
206 | static irqreturn_t phantom_isr(int irq, void *data) | ||
207 | { | ||
208 | struct phantom_device *dev = data; | ||
209 | |||
210 | if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ)) | ||
211 | return IRQ_NONE; | ||
212 | |||
213 | iowrite32(0, dev->iaddr); | ||
214 | iowrite32(0xc0, dev->iaddr); | ||
215 | |||
216 | atomic_inc(&dev->counter); | ||
217 | wake_up_interruptible(&dev->wait); | ||
218 | |||
219 | return IRQ_HANDLED; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Init and deinit driver | ||
224 | */ | ||
225 | |||
226 | static unsigned int __devinit phantom_get_free(void) | ||
227 | { | ||
228 | unsigned int i; | ||
229 | |||
230 | for (i = 0; i < PHANTOM_MAX_MINORS; i++) | ||
231 | if (phantom_devices[i] == 0) | ||
232 | break; | ||
233 | |||
234 | return i; | ||
235 | } | ||
236 | |||
237 | static int __devinit phantom_probe(struct pci_dev *pdev, | ||
238 | const struct pci_device_id *pci_id) | ||
239 | { | ||
240 | struct phantom_device *pht; | ||
241 | unsigned int minor; | ||
242 | int retval; | ||
243 | |||
244 | retval = pci_enable_device(pdev); | ||
245 | if (retval) | ||
246 | goto err; | ||
247 | |||
248 | minor = phantom_get_free(); | ||
249 | if (minor == PHANTOM_MAX_MINORS) { | ||
250 | dev_err(&pdev->dev, "too many devices found!\n"); | ||
251 | retval = -EIO; | ||
252 | goto err_dis; | ||
253 | } | ||
254 | |||
255 | phantom_devices[minor] = 1; | ||
256 | |||
257 | retval = pci_request_regions(pdev, "phantom"); | ||
258 | if (retval) | ||
259 | goto err_null; | ||
260 | |||
261 | retval = -ENOMEM; | ||
262 | pht = kzalloc(sizeof(*pht), GFP_KERNEL); | ||
263 | if (pht == NULL) { | ||
264 | dev_err(&pdev->dev, "unable to allocate device\n"); | ||
265 | goto err_reg; | ||
266 | } | ||
267 | |||
268 | pht->caddr = pci_iomap(pdev, 0, 0); | ||
269 | if (pht->caddr == NULL) { | ||
270 | dev_err(&pdev->dev, "can't remap conf space\n"); | ||
271 | goto err_fr; | ||
272 | } | ||
273 | pht->iaddr = pci_iomap(pdev, 2, 0); | ||
274 | if (pht->iaddr == NULL) { | ||
275 | dev_err(&pdev->dev, "can't remap input space\n"); | ||
276 | goto err_unmc; | ||
277 | } | ||
278 | pht->oaddr = pci_iomap(pdev, 3, 0); | ||
279 | if (pht->oaddr == NULL) { | ||
280 | dev_err(&pdev->dev, "can't remap output space\n"); | ||
281 | goto err_unmi; | ||
282 | } | ||
283 | |||
284 | mutex_init(&pht->open_lock); | ||
285 | init_waitqueue_head(&pht->wait); | ||
286 | cdev_init(&pht->cdev, &phantom_file_ops); | ||
287 | pht->cdev.owner = THIS_MODULE; | ||
288 | |||
289 | iowrite32(0, pht->caddr + PHN_IRQCTL); | ||
290 | retval = request_irq(pdev->irq, phantom_isr, | ||
291 | IRQF_SHARED | IRQF_DISABLED, "phantom", pht); | ||
292 | if (retval) { | ||
293 | dev_err(&pdev->dev, "can't establish ISR\n"); | ||
294 | goto err_unmo; | ||
295 | } | ||
296 | |||
297 | retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1); | ||
298 | if (retval) { | ||
299 | dev_err(&pdev->dev, "chardev registration failed\n"); | ||
300 | goto err_irq; | ||
301 | } | ||
302 | |||
303 | if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major, | ||
304 | minor), "phantom%u", minor))) | ||
305 | dev_err(&pdev->dev, "can't create device\n"); | ||
306 | |||
307 | pci_set_drvdata(pdev, pht); | ||
308 | |||
309 | return 0; | ||
310 | err_irq: | ||
311 | free_irq(pdev->irq, pht); | ||
312 | err_unmo: | ||
313 | pci_iounmap(pdev, pht->oaddr); | ||
314 | err_unmi: | ||
315 | pci_iounmap(pdev, pht->iaddr); | ||
316 | err_unmc: | ||
317 | pci_iounmap(pdev, pht->caddr); | ||
318 | err_fr: | ||
319 | kfree(pht); | ||
320 | err_reg: | ||
321 | pci_release_regions(pdev); | ||
322 | err_null: | ||
323 | phantom_devices[minor] = 0; | ||
324 | err_dis: | ||
325 | pci_disable_device(pdev); | ||
326 | err: | ||
327 | return retval; | ||
328 | } | ||
329 | |||
330 | static void __devexit phantom_remove(struct pci_dev *pdev) | ||
331 | { | ||
332 | struct phantom_device *pht = pci_get_drvdata(pdev); | ||
333 | unsigned int minor = MINOR(pht->cdev.dev); | ||
334 | |||
335 | device_destroy(phantom_class, MKDEV(phantom_major, minor)); | ||
336 | |||
337 | cdev_del(&pht->cdev); | ||
338 | |||
339 | iowrite32(0, pht->caddr + PHN_IRQCTL); | ||
340 | free_irq(pdev->irq, pht); | ||
341 | |||
342 | pci_iounmap(pdev, pht->oaddr); | ||
343 | pci_iounmap(pdev, pht->iaddr); | ||
344 | pci_iounmap(pdev, pht->caddr); | ||
345 | |||
346 | kfree(pht); | ||
347 | |||
348 | pci_release_regions(pdev); | ||
349 | |||
350 | phantom_devices[minor] = 0; | ||
351 | |||
352 | pci_disable_device(pdev); | ||
353 | } | ||
354 | |||
355 | #ifdef CONFIG_PM | ||
356 | static int phantom_suspend(struct pci_dev *pdev, pm_message_t state) | ||
357 | { | ||
358 | struct phantom_device *dev = pci_get_drvdata(pdev); | ||
359 | |||
360 | iowrite32(0, dev->caddr + PHN_IRQCTL); | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static int phantom_resume(struct pci_dev *pdev) | ||
366 | { | ||
367 | struct phantom_device *dev = pci_get_drvdata(pdev); | ||
368 | |||
369 | iowrite32(0, dev->caddr + PHN_IRQCTL); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | #else | ||
374 | #define phantom_suspend NULL | ||
375 | #define phantom_resume NULL | ||
376 | #endif | ||
377 | |||
378 | static struct pci_device_id phantom_pci_tbl[] __devinitdata = { | ||
379 | { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), | ||
380 | .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 }, | ||
381 | { 0, } | ||
382 | }; | ||
383 | MODULE_DEVICE_TABLE(pci, phantom_pci_tbl); | ||
384 | |||
385 | static struct pci_driver phantom_pci_driver = { | ||
386 | .name = "phantom", | ||
387 | .id_table = phantom_pci_tbl, | ||
388 | .probe = phantom_probe, | ||
389 | .remove = __devexit_p(phantom_remove), | ||
390 | .suspend = phantom_suspend, | ||
391 | .resume = phantom_resume | ||
392 | }; | ||
393 | |||
394 | static ssize_t phantom_show_version(struct class *cls, char *buf) | ||
395 | { | ||
396 | return sprintf(buf, PHANTOM_VERSION "\n"); | ||
397 | } | ||
398 | |||
399 | static CLASS_ATTR(version, 0444, phantom_show_version, NULL); | ||
400 | |||
401 | static int __init phantom_init(void) | ||
402 | { | ||
403 | int retval; | ||
404 | dev_t dev; | ||
405 | |||
406 | phantom_class = class_create(THIS_MODULE, "phantom"); | ||
407 | if (IS_ERR(phantom_class)) { | ||
408 | retval = PTR_ERR(phantom_class); | ||
409 | printk(KERN_ERR "phantom: can't register phantom class\n"); | ||
410 | goto err; | ||
411 | } | ||
412 | retval = class_create_file(phantom_class, &class_attr_version); | ||
413 | if (retval) { | ||
414 | printk(KERN_ERR "phantom: can't create sysfs version file\n"); | ||
415 | goto err_class; | ||
416 | } | ||
417 | |||
418 | retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom"); | ||
419 | if (retval) { | ||
420 | printk(KERN_ERR "phantom: can't register character device\n"); | ||
421 | goto err_attr; | ||
422 | } | ||
423 | phantom_major = MAJOR(dev); | ||
424 | |||
425 | retval = pci_register_driver(&phantom_pci_driver); | ||
426 | if (retval) { | ||
427 | printk(KERN_ERR "phantom: can't register pci driver\n"); | ||
428 | goto err_unchr; | ||
429 | } | ||
430 | |||
431 | printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", " | ||
432 | "init OK\n"); | ||
433 | |||
434 | return 0; | ||
435 | err_unchr: | ||
436 | unregister_chrdev_region(dev, PHANTOM_MAX_MINORS); | ||
437 | err_attr: | ||
438 | class_remove_file(phantom_class, &class_attr_version); | ||
439 | err_class: | ||
440 | class_destroy(phantom_class); | ||
441 | err: | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | static void __exit phantom_exit(void) | ||
446 | { | ||
447 | pci_unregister_driver(&phantom_pci_driver); | ||
448 | |||
449 | unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS); | ||
450 | |||
451 | class_remove_file(phantom_class, &class_attr_version); | ||
452 | class_destroy(phantom_class); | ||
453 | |||
454 | pr_debug("phantom: module successfully removed\n"); | ||
455 | } | ||
456 | |||
457 | module_init(phantom_init); | ||
458 | module_exit(phantom_exit); | ||
459 | |||
460 | MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>"); | ||
461 | MODULE_DESCRIPTION("Sensable Phantom driver"); | ||
462 | MODULE_LICENSE("GPL"); | ||
463 | MODULE_VERSION(PHANTOM_VERSION); | ||
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 524b83b5ebf5..51bc7e2f1f22 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c | |||
@@ -216,7 +216,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | |||
216 | int last_devnum = -1; | 216 | int last_devnum = -1; |
217 | struct gendisk *gd; | 217 | struct gendisk *gd; |
218 | 218 | ||
219 | if (!!mutex_trylock(&mtd_table_mutex)) { | 219 | if (mutex_trylock(&mtd_table_mutex)) { |
220 | mutex_unlock(&mtd_table_mutex); | 220 | mutex_unlock(&mtd_table_mutex); |
221 | BUG(); | 221 | BUG(); |
222 | } | 222 | } |
@@ -294,7 +294,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | |||
294 | 294 | ||
295 | int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) | 295 | int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) |
296 | { | 296 | { |
297 | if (!!mutex_trylock(&mtd_table_mutex)) { | 297 | if (mutex_trylock(&mtd_table_mutex)) { |
298 | mutex_unlock(&mtd_table_mutex); | 298 | mutex_unlock(&mtd_table_mutex); |
299 | BUG(); | 299 | BUG(); |
300 | } | 300 | } |
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 17b0c3ab6201..9d6c8f391b2d 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
19 | 18 | ||
20 | #include <net/irda/irda.h> | 19 | #include <net/irda/irda.h> |
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c index d7e32d9554fc..25d5b8a96bdc 100644 --- a/drivers/net/irda/sir_dongle.c +++ b/drivers/net/irda/sir_dongle.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/kmod.h> | 17 | #include <linux/kmod.h> |
19 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
20 | 19 | ||
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 198bf3bfa70f..9043bf4aa49e 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -79,11 +79,17 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>"); | |||
79 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); | 79 | MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); |
80 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
81 | 81 | ||
82 | static int ircc_dma = 255; | 82 | static int smsc_nopnp; |
83 | module_param_named(nopnp, smsc_nopnp, bool, 0); | ||
84 | MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); | ||
85 | |||
86 | #define DMA_INVAL 255 | ||
87 | static int ircc_dma = DMA_INVAL; | ||
83 | module_param(ircc_dma, int, 0); | 88 | module_param(ircc_dma, int, 0); |
84 | MODULE_PARM_DESC(ircc_dma, "DMA channel"); | 89 | MODULE_PARM_DESC(ircc_dma, "DMA channel"); |
85 | 90 | ||
86 | static int ircc_irq = 255; | 91 | #define IRQ_INVAL 255 |
92 | static int ircc_irq = IRQ_INVAL; | ||
87 | module_param(ircc_irq, int, 0); | 93 | module_param(ircc_irq, int, 0); |
88 | MODULE_PARM_DESC(ircc_irq, "IRQ line"); | 94 | MODULE_PARM_DESC(ircc_irq, "IRQ line"); |
89 | 95 | ||
@@ -360,7 +366,6 @@ static inline void register_bank(int iobase, int bank) | |||
360 | iobase + IRCC_MASTER); | 366 | iobase + IRCC_MASTER); |
361 | } | 367 | } |
362 | 368 | ||
363 | #ifdef CONFIG_PNP | ||
364 | /* PNP hotplug support */ | 369 | /* PNP hotplug support */ |
365 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { | 370 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { |
366 | { .id = "SMCf010", .driver_data = 0 }, | 371 | { .id = "SMCf010", .driver_data = 0 }, |
@@ -368,7 +373,35 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = { | |||
368 | { } | 373 | { } |
369 | }; | 374 | }; |
370 | MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | 375 | MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); |
371 | #endif | 376 | |
377 | static int pnp_driver_registered; | ||
378 | |||
379 | static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, | ||
380 | const struct pnp_device_id *dev_id) | ||
381 | { | ||
382 | unsigned int firbase, sirbase; | ||
383 | u8 dma, irq; | ||
384 | |||
385 | if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | ||
386 | pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0))) | ||
387 | return -EINVAL; | ||
388 | |||
389 | sirbase = pnp_port_start(dev, 0); | ||
390 | firbase = pnp_port_start(dev, 1); | ||
391 | dma = pnp_dma(dev, 0); | ||
392 | irq = pnp_irq(dev, 0); | ||
393 | |||
394 | if (smsc_ircc_open(firbase, sirbase, dma, irq)) | ||
395 | return -ENODEV; | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static struct pnp_driver smsc_ircc_pnp_driver = { | ||
401 | .name = "smsc-ircc2", | ||
402 | .id_table = smsc_ircc_pnp_table, | ||
403 | .probe = smsc_ircc_pnp_probe, | ||
404 | }; | ||
372 | 405 | ||
373 | 406 | ||
374 | /******************************************************************************* | 407 | /******************************************************************************* |
@@ -379,6 +412,35 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); | |||
379 | * | 412 | * |
380 | *******************************************************************************/ | 413 | *******************************************************************************/ |
381 | 414 | ||
415 | static int __init smsc_ircc_legacy_probe(void) | ||
416 | { | ||
417 | int ret = 0; | ||
418 | |||
419 | if (ircc_fir > 0 && ircc_sir > 0) { | ||
420 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); | ||
421 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); | ||
422 | |||
423 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) | ||
424 | ret = -ENODEV; | ||
425 | } else { | ||
426 | ret = -ENODEV; | ||
427 | |||
428 | /* try user provided configuration register base address */ | ||
429 | if (ircc_cfg > 0) { | ||
430 | IRDA_MESSAGE(" Overriding configuration address " | ||
431 | "0x%04x\n", ircc_cfg); | ||
432 | if (!smsc_superio_fdc(ircc_cfg)) | ||
433 | ret = 0; | ||
434 | if (!smsc_superio_lpc(ircc_cfg)) | ||
435 | ret = 0; | ||
436 | } | ||
437 | |||
438 | if (smsc_ircc_look_for_chips() > 0) | ||
439 | ret = 0; | ||
440 | } | ||
441 | return ret; | ||
442 | } | ||
443 | |||
382 | /* | 444 | /* |
383 | * Function smsc_ircc_init () | 445 | * Function smsc_ircc_init () |
384 | * | 446 | * |
@@ -406,31 +468,20 @@ static int __init smsc_ircc_init(void) | |||
406 | 468 | ||
407 | dev_count = 0; | 469 | dev_count = 0; |
408 | 470 | ||
409 | if (ircc_fir > 0 && ircc_sir > 0) { | 471 | if (smsc_nopnp || !pnp_platform_devices || |
410 | IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); | 472 | ircc_cfg || ircc_fir || ircc_sir || |
411 | IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); | 473 | ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) { |
412 | 474 | ret = smsc_ircc_legacy_probe(); | |
413 | if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) | ||
414 | ret = -ENODEV; | ||
415 | } else { | 475 | } else { |
416 | ret = -ENODEV; | 476 | if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0) |
417 | 477 | pnp_driver_registered = 1; | |
418 | /* try user provided configuration register base address */ | ||
419 | if (ircc_cfg > 0) { | ||
420 | IRDA_MESSAGE(" Overriding configuration address " | ||
421 | "0x%04x\n", ircc_cfg); | ||
422 | if (!smsc_superio_fdc(ircc_cfg)) | ||
423 | ret = 0; | ||
424 | if (!smsc_superio_lpc(ircc_cfg)) | ||
425 | ret = 0; | ||
426 | } | ||
427 | |||
428 | if (smsc_ircc_look_for_chips() > 0) | ||
429 | ret = 0; | ||
430 | } | 478 | } |
431 | 479 | ||
432 | if (ret) | 480 | if (ret) { |
481 | if (pnp_driver_registered) | ||
482 | pnp_unregister_driver(&smsc_ircc_pnp_driver); | ||
433 | platform_driver_unregister(&smsc_ircc_driver); | 483 | platform_driver_unregister(&smsc_ircc_driver); |
484 | } | ||
434 | 485 | ||
435 | return ret; | 486 | return ret; |
436 | } | 487 | } |
@@ -646,7 +697,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, | |||
646 | self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; | 697 | self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; |
647 | self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; | 698 | self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; |
648 | 699 | ||
649 | if (irq < 255) { | 700 | if (irq != IRQ_INVAL) { |
650 | if (irq != chip_irq) | 701 | if (irq != chip_irq) |
651 | IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", | 702 | IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", |
652 | driver_name, chip_irq, irq); | 703 | driver_name, chip_irq, irq); |
@@ -654,7 +705,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, | |||
654 | } else | 705 | } else |
655 | self->io.irq = chip_irq; | 706 | self->io.irq = chip_irq; |
656 | 707 | ||
657 | if (dma < 255) { | 708 | if (dma != DMA_INVAL) { |
658 | if (dma != chip_dma) | 709 | if (dma != chip_dma) |
659 | IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", | 710 | IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", |
660 | driver_name, chip_dma, dma); | 711 | driver_name, chip_dma, dma); |
@@ -1840,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(void) | |||
1840 | smsc_ircc_close(dev_self[i]); | 1891 | smsc_ircc_close(dev_self[i]); |
1841 | } | 1892 | } |
1842 | 1893 | ||
1894 | if (pnp_driver_registered) | ||
1895 | pnp_unregister_driver(&smsc_ircc_pnp_driver); | ||
1896 | |||
1843 | platform_driver_unregister(&smsc_ircc_driver); | 1897 | platform_driver_unregister(&smsc_ircc_driver); |
1844 | } | 1898 | } |
1845 | 1899 | ||
@@ -2836,9 +2890,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | |||
2836 | tmpconf.fir_io = ircc_fir; | 2890 | tmpconf.fir_io = ircc_fir; |
2837 | if (ircc_sir != 0) | 2891 | if (ircc_sir != 0) |
2838 | tmpconf.sir_io = ircc_sir; | 2892 | tmpconf.sir_io = ircc_sir; |
2839 | if (ircc_dma != 0xff) | 2893 | if (ircc_dma != DMA_INVAL) |
2840 | tmpconf.fir_dma = ircc_dma; | 2894 | tmpconf.fir_dma = ircc_dma; |
2841 | if (ircc_irq != 0xff) | 2895 | if (ircc_irq != IRQ_INVAL) |
2842 | tmpconf.fir_irq = ircc_irq; | 2896 | tmpconf.fir_irq = ircc_irq; |
2843 | 2897 | ||
2844 | IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); | 2898 | IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); |
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index c4be973867a6..bf78ef1120ad 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c | |||
@@ -44,7 +44,6 @@ MODULE_LICENSE("GPL"); | |||
44 | #include <linux/time.h> | 44 | #include <linux/time.h> |
45 | #include <linux/proc_fs.h> | 45 | #include <linux/proc_fs.h> |
46 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
47 | #include <linux/smp_lock.h> | ||
48 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
49 | #include <asm/byteorder.h> | 48 | #include <asm/byteorder.h> |
50 | 49 | ||
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 6a32338623f1..3439f8c649f9 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -104,7 +104,6 @@ | |||
104 | #include <linux/netdevice.h> | 104 | #include <linux/netdevice.h> |
105 | #include <linux/etherdevice.h> | 105 | #include <linux/etherdevice.h> |
106 | #include <linux/delay.h> | 106 | #include <linux/delay.h> |
107 | #include <linux/smp_lock.h> | ||
108 | #include <linux/workqueue.h> | 107 | #include <linux/workqueue.h> |
109 | #include <linux/init.h> | 108 | #include <linux/init.h> |
110 | #include <linux/ip.h> /* for iph */ | 109 | #include <linux/ip.h> /* for iph */ |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 6d596ca50cfd..541168713f1f 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/ip.h> | 40 | #include <linux/ip.h> |
41 | #include <linux/tcp.h> | 41 | #include <linux/tcp.h> |
42 | #include <linux/spinlock.h> | 42 | #include <linux/spinlock.h> |
43 | #include <linux/smp_lock.h> | ||
44 | #include <linux/rwsem.h> | 43 | #include <linux/rwsem.h> |
45 | #include <linux/stddef.h> | 44 | #include <linux/stddef.h> |
46 | #include <linux/device.h> | 45 | #include <linux/device.h> |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 23464735fa88..9ef49ce148b2 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -90,7 +90,6 @@ | |||
90 | #include <linux/ioport.h> | 90 | #include <linux/ioport.h> |
91 | #include <linux/netdevice.h> | 91 | #include <linux/netdevice.h> |
92 | #include <linux/spinlock.h> | 92 | #include <linux/spinlock.h> |
93 | #include <linux/smp_lock.h> | ||
94 | #include <linux/device.h> | 93 | #include <linux/device.h> |
95 | 94 | ||
96 | #undef COSA_SLOW_IO /* for testing purposes only */ | 95 | #undef COSA_SLOW_IO /* for testing purposes only */ |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index f21bbafcb728..2d3a180dada0 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/proc_fs.h> | 27 | #include <linux/proc_fs.h> |
28 | #include <linux/smp_lock.h> | ||
29 | 28 | ||
30 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
31 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index cb08bc5db2bd..cdea7f71b9eb 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ | 1 | /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ |
2 | 2 | ||
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/smp_lock.h> | ||
5 | #include <linux/ethtool.h> | 4 | #include <linux/ethtool.h> |
6 | #include <net/ieee80211_crypt.h> | 5 | #include <net/ieee80211_crypt.h> |
7 | 6 | ||
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 21c4c299b3d6..5b86ee5c1eeb 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/ioport.h> | 39 | #include <linux/ioport.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/smp_lock.h> | ||
42 | 41 | ||
43 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
44 | #include <asm/pdc.h> | 43 | #include <asm/pdc.h> |
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 316c06f4423c..8b7d84eca05d 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c | |||
@@ -201,7 +201,7 @@ static int parport_config(struct pcmcia_device *link) | |||
201 | 201 | ||
202 | p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, | 202 | p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, |
203 | link->irq.AssignedIRQ, PARPORT_DMA_NONE, | 203 | link->irq.AssignedIRQ, PARPORT_DMA_NONE, |
204 | NULL); | 204 | &link->dev); |
205 | if (p == NULL) { | 205 | if (p == NULL) { |
206 | printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " | 206 | printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " |
207 | "0x%3x, irq %u failed\n", link->io.BasePort1, | 207 | "0x%3x, irq %u failed\n", link->io.BasePort1, |
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c index e5b0a544de40..77726fc49766 100644 --- a/drivers/parport/parport_mfc3.c +++ b/drivers/parport/parport_mfc3.c | |||
@@ -356,6 +356,7 @@ static int __init parport_mfc3_init(void) | |||
356 | if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops)) | 356 | if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops)) |
357 | goto out_irq; | 357 | goto out_irq; |
358 | } | 358 | } |
359 | p->dev = &z->dev; | ||
359 | 360 | ||
360 | this_port[pias++] = p; | 361 | this_port[pias++] = p; |
361 | printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); | 362 | printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 3de2623afa13..02c0d52c9f76 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/pnp.h> | 55 | #include <linux/pnp.h> |
56 | #include <linux/platform_device.h> | ||
56 | #include <linux/sysctl.h> | 57 | #include <linux/sysctl.h> |
57 | 58 | ||
58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
@@ -620,6 +621,7 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port, | |||
620 | unsigned long dmaflag; | 621 | unsigned long dmaflag; |
621 | size_t left = length; | 622 | size_t left = length; |
622 | const struct parport_pc_private *priv = port->physport->private_data; | 623 | const struct parport_pc_private *priv = port->physport->private_data; |
624 | struct device *dev = port->physport->dev; | ||
623 | dma_addr_t dma_addr, dma_handle; | 625 | dma_addr_t dma_addr, dma_handle; |
624 | size_t maxlen = 0x10000; /* max 64k per DMA transfer */ | 626 | size_t maxlen = 0x10000; /* max 64k per DMA transfer */ |
625 | unsigned long start = (unsigned long) buf; | 627 | unsigned long start = (unsigned long) buf; |
@@ -631,8 +633,8 @@ dump_parport_state ("enter fifo_write_block_dma", port); | |||
631 | if ((start ^ end) & ~0xffffUL) | 633 | if ((start ^ end) & ~0xffffUL) |
632 | maxlen = 0x10000 - (start & 0xffff); | 634 | maxlen = 0x10000 - (start & 0xffff); |
633 | 635 | ||
634 | dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length, | 636 | dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length, |
635 | PCI_DMA_TODEVICE); | 637 | DMA_TO_DEVICE); |
636 | } else { | 638 | } else { |
637 | /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ | 639 | /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ |
638 | maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ | 640 | maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ |
@@ -728,9 +730,9 @@ dump_parport_state ("enter fifo_write_block_dma", port); | |||
728 | 730 | ||
729 | /* Turn off DMA mode */ | 731 | /* Turn off DMA mode */ |
730 | frob_econtrol (port, 1<<3, 0); | 732 | frob_econtrol (port, 1<<3, 0); |
731 | 733 | ||
732 | if (dma_handle) | 734 | if (dma_handle) |
733 | pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE); | 735 | dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE); |
734 | 736 | ||
735 | dump_parport_state ("leave fifo_write_block_dma", port); | 737 | dump_parport_state ("leave fifo_write_block_dma", port); |
736 | return length - left; | 738 | return length - left; |
@@ -2146,7 +2148,7 @@ static DEFINE_SPINLOCK(ports_lock); | |||
2146 | struct parport *parport_pc_probe_port (unsigned long int base, | 2148 | struct parport *parport_pc_probe_port (unsigned long int base, |
2147 | unsigned long int base_hi, | 2149 | unsigned long int base_hi, |
2148 | int irq, int dma, | 2150 | int irq, int dma, |
2149 | struct pci_dev *dev) | 2151 | struct device *dev) |
2150 | { | 2152 | { |
2151 | struct parport_pc_private *priv; | 2153 | struct parport_pc_private *priv; |
2152 | struct parport_operations *ops; | 2154 | struct parport_operations *ops; |
@@ -2155,6 +2157,17 @@ struct parport *parport_pc_probe_port (unsigned long int base, | |||
2155 | struct resource *base_res; | 2157 | struct resource *base_res; |
2156 | struct resource *ECR_res = NULL; | 2158 | struct resource *ECR_res = NULL; |
2157 | struct resource *EPP_res = NULL; | 2159 | struct resource *EPP_res = NULL; |
2160 | struct platform_device *pdev = NULL; | ||
2161 | |||
2162 | if (!dev) { | ||
2163 | /* We need a physical device to attach to, but none was | ||
2164 | * provided. Create our own. */ | ||
2165 | pdev = platform_device_register_simple("parport_pc", | ||
2166 | base, NULL, 0); | ||
2167 | if (IS_ERR(pdev)) | ||
2168 | return NULL; | ||
2169 | dev = &pdev->dev; | ||
2170 | } | ||
2158 | 2171 | ||
2159 | ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); | 2172 | ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); |
2160 | if (!ops) | 2173 | if (!ops) |
@@ -2180,9 +2193,10 @@ struct parport *parport_pc_probe_port (unsigned long int base, | |||
2180 | priv->fifo_depth = 0; | 2193 | priv->fifo_depth = 0; |
2181 | priv->dma_buf = NULL; | 2194 | priv->dma_buf = NULL; |
2182 | priv->dma_handle = 0; | 2195 | priv->dma_handle = 0; |
2183 | priv->dev = dev; | ||
2184 | INIT_LIST_HEAD(&priv->list); | 2196 | INIT_LIST_HEAD(&priv->list); |
2185 | priv->port = p; | 2197 | priv->port = p; |
2198 | |||
2199 | p->dev = dev; | ||
2186 | p->base_hi = base_hi; | 2200 | p->base_hi = base_hi; |
2187 | p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; | 2201 | p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; |
2188 | p->private_data = priv; | 2202 | p->private_data = priv; |
@@ -2305,9 +2319,10 @@ struct parport *parport_pc_probe_port (unsigned long int base, | |||
2305 | p->dma = PARPORT_DMA_NONE; | 2319 | p->dma = PARPORT_DMA_NONE; |
2306 | } else { | 2320 | } else { |
2307 | priv->dma_buf = | 2321 | priv->dma_buf = |
2308 | pci_alloc_consistent(priv->dev, | 2322 | dma_alloc_coherent(dev, |
2309 | PAGE_SIZE, | 2323 | PAGE_SIZE, |
2310 | &priv->dma_handle); | 2324 | &priv->dma_handle, |
2325 | GFP_KERNEL); | ||
2311 | if (! priv->dma_buf) { | 2326 | if (! priv->dma_buf) { |
2312 | printk (KERN_WARNING "%s: " | 2327 | printk (KERN_WARNING "%s: " |
2313 | "cannot get buffer for DMA, " | 2328 | "cannot get buffer for DMA, " |
@@ -2356,6 +2371,8 @@ out3: | |||
2356 | out2: | 2371 | out2: |
2357 | kfree (ops); | 2372 | kfree (ops); |
2358 | out1: | 2373 | out1: |
2374 | if (pdev) | ||
2375 | platform_device_unregister(pdev); | ||
2359 | return NULL; | 2376 | return NULL; |
2360 | } | 2377 | } |
2361 | 2378 | ||
@@ -2383,7 +2400,7 @@ void parport_pc_unregister_port (struct parport *p) | |||
2383 | release_region(p->base_hi, 3); | 2400 | release_region(p->base_hi, 3); |
2384 | #if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) | 2401 | #if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) |
2385 | if (priv->dma_buf) | 2402 | if (priv->dma_buf) |
2386 | pci_free_consistent(priv->dev, PAGE_SIZE, | 2403 | dma_free_coherent(p->physport->dev, PAGE_SIZE, |
2387 | priv->dma_buf, | 2404 | priv->dma_buf, |
2388 | priv->dma_handle); | 2405 | priv->dma_handle); |
2389 | #endif | 2406 | #endif |
@@ -2489,7 +2506,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, | |||
2489 | */ | 2506 | */ |
2490 | release_resource(base_res); | 2507 | release_resource(base_res); |
2491 | if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, | 2508 | if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, |
2492 | irq, PARPORT_DMA_NONE, NULL)) { | 2509 | irq, PARPORT_DMA_NONE, &pdev->dev)) { |
2493 | printk (KERN_INFO | 2510 | printk (KERN_INFO |
2494 | "parport_pc: ITE 8872 parallel port: io=0x%X", | 2511 | "parport_pc: ITE 8872 parallel port: io=0x%X", |
2495 | ite8872_lpt); | 2512 | ite8872_lpt); |
@@ -2672,7 +2689,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq, | |||
2672 | } | 2689 | } |
2673 | 2690 | ||
2674 | /* finally, do the probe with values obtained */ | 2691 | /* finally, do the probe with values obtained */ |
2675 | if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) { | 2692 | if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) { |
2676 | printk (KERN_INFO | 2693 | printk (KERN_INFO |
2677 | "parport_pc: VIA parallel port: io=0x%X", port1); | 2694 | "parport_pc: VIA parallel port: io=0x%X", port1); |
2678 | if (irq != PARPORT_IRQ_NONE) | 2695 | if (irq != PARPORT_IRQ_NONE) |
@@ -2970,7 +2987,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev, | |||
2970 | parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); | 2987 | parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); |
2971 | data->ports[count] = | 2988 | data->ports[count] = |
2972 | parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, | 2989 | parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, |
2973 | PARPORT_DMA_NONE, dev); | 2990 | PARPORT_DMA_NONE, &dev->dev); |
2974 | if (data->ports[count]) | 2991 | if (data->ports[count]) |
2975 | count++; | 2992 | count++; |
2976 | } | 2993 | } |
@@ -3077,8 +3094,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id | |||
3077 | } else | 3094 | } else |
3078 | dma = PARPORT_DMA_NONE; | 3095 | dma = PARPORT_DMA_NONE; |
3079 | 3096 | ||
3080 | printk(KERN_INFO "parport: PnPBIOS parport detected.\n"); | 3097 | dev_info(&dev->dev, "reported by %s\n", dev->protocol->name); |
3081 | if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL))) | 3098 | if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev))) |
3082 | return -ENODEV; | 3099 | return -ENODEV; |
3083 | 3100 | ||
3084 | pnp_set_drvdata(dev,pdata); | 3101 | pnp_set_drvdata(dev,pdata); |
@@ -3103,6 +3120,21 @@ static struct pnp_driver parport_pc_pnp_driver = { | |||
3103 | }; | 3120 | }; |
3104 | 3121 | ||
3105 | 3122 | ||
3123 | static int __devinit parport_pc_platform_probe(struct platform_device *pdev) | ||
3124 | { | ||
3125 | /* Always succeed, the actual probing is done in | ||
3126 | * parport_pc_probe_port(). */ | ||
3127 | return 0; | ||
3128 | } | ||
3129 | |||
3130 | static struct platform_driver parport_pc_platform_driver = { | ||
3131 | .driver = { | ||
3132 | .owner = THIS_MODULE, | ||
3133 | .name = "parport_pc", | ||
3134 | }, | ||
3135 | .probe = parport_pc_platform_probe, | ||
3136 | }; | ||
3137 | |||
3106 | /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ | 3138 | /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ |
3107 | static int __devinit __attribute__((unused)) | 3139 | static int __devinit __attribute__((unused)) |
3108 | parport_pc_find_isa_ports (int autoirq, int autodma) | 3140 | parport_pc_find_isa_ports (int autoirq, int autodma) |
@@ -3378,9 +3410,15 @@ __setup("parport_init_mode=",parport_init_mode_setup); | |||
3378 | 3410 | ||
3379 | static int __init parport_pc_init(void) | 3411 | static int __init parport_pc_init(void) |
3380 | { | 3412 | { |
3413 | int err; | ||
3414 | |||
3381 | if (parse_parport_params()) | 3415 | if (parse_parport_params()) |
3382 | return -EINVAL; | 3416 | return -EINVAL; |
3383 | 3417 | ||
3418 | err = platform_driver_register(&parport_pc_platform_driver); | ||
3419 | if (err) | ||
3420 | return err; | ||
3421 | |||
3384 | if (io[0]) { | 3422 | if (io[0]) { |
3385 | int i; | 3423 | int i; |
3386 | /* Only probe the ports we were given. */ | 3424 | /* Only probe the ports we were given. */ |
@@ -3405,6 +3443,7 @@ static void __exit parport_pc_exit(void) | |||
3405 | pci_unregister_driver (&parport_pc_pci_driver); | 3443 | pci_unregister_driver (&parport_pc_pci_driver); |
3406 | if (pnp_registered_parport) | 3444 | if (pnp_registered_parport) |
3407 | pnp_unregister_driver (&parport_pc_pnp_driver); | 3445 | pnp_unregister_driver (&parport_pc_pnp_driver); |
3446 | platform_driver_unregister(&parport_pc_platform_driver); | ||
3408 | 3447 | ||
3409 | spin_lock(&ports_lock); | 3448 | spin_lock(&ports_lock); |
3410 | while (!list_empty(&ports_list)) { | 3449 | while (!list_empty(&ports_list)) { |
@@ -3413,6 +3452,9 @@ static void __exit parport_pc_exit(void) | |||
3413 | priv = list_entry(ports_list.next, | 3452 | priv = list_entry(ports_list.next, |
3414 | struct parport_pc_private, list); | 3453 | struct parport_pc_private, list); |
3415 | port = priv->port; | 3454 | port = priv->port; |
3455 | if (port->dev && port->dev->bus == &platform_bus_type) | ||
3456 | platform_device_unregister( | ||
3457 | to_platform_device(port->dev)); | ||
3416 | spin_unlock(&ports_lock); | 3458 | spin_unlock(&ports_lock); |
3417 | parport_pc_unregister_port(port); | 3459 | parport_pc_unregister_port(port); |
3418 | spin_lock(&ports_lock); | 3460 | spin_lock(&ports_lock); |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 78c0a269a2ba..90ea3b8b99b0 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -305,7 +305,7 @@ static int __devinit parport_register (struct pci_dev *dev, | |||
305 | dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " | 305 | dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " |
306 | "%#lx(%#lx)\n", io_lo, io_hi); | 306 | "%#lx(%#lx)\n", io_lo, io_hi); |
307 | port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, | 307 | port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, |
308 | PARPORT_DMA_NONE, dev); | 308 | PARPORT_DMA_NONE, &dev->dev); |
309 | if (port) { | 309 | if (port) { |
310 | priv->port[priv->num_par++] = port; | 310 | priv->port[priv->num_par++] = port; |
311 | success = 1; | 311 | success = 1; |
@@ -392,6 +392,7 @@ static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) | |||
392 | static int parport_serial_pci_resume(struct pci_dev *dev) | 392 | static int parport_serial_pci_resume(struct pci_dev *dev) |
393 | { | 393 | { |
394 | struct parport_serial_private *priv = pci_get_drvdata(dev); | 394 | struct parport_serial_private *priv = pci_get_drvdata(dev); |
395 | int err; | ||
395 | 396 | ||
396 | pci_set_power_state(dev, PCI_D0); | 397 | pci_set_power_state(dev, PCI_D0); |
397 | pci_restore_state(dev); | 398 | pci_restore_state(dev); |
@@ -399,7 +400,12 @@ static int parport_serial_pci_resume(struct pci_dev *dev) | |||
399 | /* | 400 | /* |
400 | * The device may have been disabled. Re-enable it. | 401 | * The device may have been disabled. Re-enable it. |
401 | */ | 402 | */ |
402 | pci_enable_device(dev); | 403 | err = pci_enable_device(dev); |
404 | if (err) { | ||
405 | printk(KERN_ERR "parport_serial: %s: error enabling " | ||
406 | "device for resume (%d)\n", pci_name(dev), err); | ||
407 | return err; | ||
408 | } | ||
403 | 409 | ||
404 | if (priv->serial) | 410 | if (priv->serial) |
405 | pciserial_resume_ports(priv->serial); | 411 | pciserial_resume_ports(priv->serial); |
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 400bb90084cf..d27019c2f860 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c | |||
@@ -322,6 +322,7 @@ static int __devinit init_one_port(struct sbus_dev *sdev) | |||
322 | goto out_free_ops; | 322 | goto out_free_ops; |
323 | 323 | ||
324 | p->size = size; | 324 | p->size = size; |
325 | p->dev = &sdev->ofdev.dev; | ||
325 | 326 | ||
326 | if ((err = request_irq(p->irq, parport_sunbpp_interrupt, | 327 | if ((err = request_irq(p->irq, parport_sunbpp_interrupt, |
327 | IRQF_SHARED, p->name, p)) != 0) { | 328 | IRQF_SHARED, p->name, p)) != 0) { |
diff --git a/drivers/parport/share.c b/drivers/parport/share.c index fd9129e424f9..cd66442acfee 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c | |||
@@ -365,6 +365,11 @@ void parport_announce_port (struct parport *port) | |||
365 | parport_daisy_init(port); | 365 | parport_daisy_init(port); |
366 | #endif | 366 | #endif |
367 | 367 | ||
368 | if (!port->dev) | ||
369 | printk(KERN_WARNING "%s: fix this legacy " | ||
370 | "no-device port driver!\n", | ||
371 | port->name); | ||
372 | |||
368 | parport_proc_register(port); | 373 | parport_proc_register(port); |
369 | mutex_lock(®istration_lock); | 374 | mutex_lock(®istration_lock); |
370 | spin_lock_irq(&parportlist_lock); | 375 | spin_lock_irq(&parportlist_lock); |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 40c79b03c7ef..fa5c0197d571 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/pci_hotplug.h> | 40 | #include <linux/pci_hotplug.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/smp.h> | 42 | #include <linux/smp.h> |
43 | #include <linux/smp_lock.h> | ||
44 | #include "acpiphp.h" | 43 | #include "acpiphp.h" |
45 | 44 | ||
46 | #define MY_NAME "acpiphp" | 45 | #define MY_NAME "acpiphp" |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fca978fb158e..9ef4e989afc4 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/pci_hotplug.h> | 48 | #include <linux/pci_hotplug.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
51 | 50 | ||
52 | #include "../pci.h" | 51 | #include "../pci.h" |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 59392946c2bd..0316eeaaeb29 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include "../pci.h" | 37 | #include "../pci.h" |
39 | #include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */ | 38 | #include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */ |
40 | #include "ibmphp.h" | 39 | #include "ibmphp.h" |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index f55ac3885cb3..46abaa8c41f1 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/init.h> | 35 | #include <linux/init.h> |
37 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
38 | 37 | ||
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 63f3bd1eecc4..bd433ef6bfc6 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/sysfs.h> | 34 | #include <linux/sysfs.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/mount.h> | 38 | #include <linux/mount.h> |
40 | #include <linux/namei.h> | 39 | #include <linux/namei.h> |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 899eed002748..458c08ef2654 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/pci_hotplug.h> | 29 | #include <linux/pci_hotplug.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <asm/eeh.h> /* for eeh_add_device() */ | 33 | #include <asm/eeh.h> /* for eeh_add_device() */ |
35 | #include <asm/rtas.h> /* rtas_call */ | 34 | #include <asm/rtas.h> /* rtas_call */ |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 2c94d44279a3..d2fc35598cdd 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
36 | #include "../pci.h" | 35 | #include "../pci.h" |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 9e1321d0d5e6..e6740d1a0824 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
17 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
18 | #include <linux/msi.h> | 17 | #include <linux/msi.h> |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index ed87aa59f0b1..0425a7b7350d 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
14 | #include <linux/smp_lock.h> | ||
15 | 14 | ||
16 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
17 | #include <asm/byteorder.h> | 16 | #include <asm/byteorder.h> |
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index fda06941e730..383107ba4bd3 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c | |||
@@ -175,6 +175,7 @@ static int __init mst_pcmcia_init(void) | |||
175 | if (!mst_pcmcia_device) | 175 | if (!mst_pcmcia_device) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | 177 | ||
178 | mst_pcmcia_device->dev.uevent_suppress = 0; | ||
178 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; | 179 | mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; |
179 | 180 | ||
180 | ret = platform_device_add(mst_pcmcia_device); | 181 | ret = platform_device_add(mst_pcmcia_device); |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index b7b9e149c5b9..a2daa3f531b2 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -261,6 +261,7 @@ static int __init sharpsl_pcmcia_init(void) | |||
261 | if (!sharpsl_pcmcia_device) | 261 | if (!sharpsl_pcmcia_device) |
262 | return -ENOMEM; | 262 | return -ENOMEM; |
263 | 263 | ||
264 | sharpsl_pcmcia_device->dev.uevent_suppress = 0; | ||
264 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; | 265 | sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; |
265 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; | 266 | sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; |
266 | 267 | ||
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index aec83ec5ea23..3e20b1cc7778 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/dma-mapping.h> | ||
17 | 18 | ||
18 | #include "base.h" | 19 | #include "base.h" |
19 | 20 | ||
@@ -22,6 +23,14 @@ static LIST_HEAD(pnp_protocols); | |||
22 | LIST_HEAD(pnp_global); | 23 | LIST_HEAD(pnp_global); |
23 | DEFINE_SPINLOCK(pnp_lock); | 24 | DEFINE_SPINLOCK(pnp_lock); |
24 | 25 | ||
26 | /* | ||
27 | * ACPI or PNPBIOS should tell us about all platform devices, so we can | ||
28 | * skip some blind probes. ISAPNP typically enumerates only plug-in ISA | ||
29 | * devices, not built-in things like COM ports. | ||
30 | */ | ||
31 | int pnp_platform_devices; | ||
32 | EXPORT_SYMBOL(pnp_platform_devices); | ||
33 | |||
25 | void *pnp_alloc(long size) | 34 | void *pnp_alloc(long size) |
26 | { | 35 | { |
27 | void *result; | 36 | void *result; |
@@ -114,6 +123,8 @@ int __pnp_add_device(struct pnp_dev *dev) | |||
114 | int ret; | 123 | int ret; |
115 | pnp_fixup_device(dev); | 124 | pnp_fixup_device(dev); |
116 | dev->dev.bus = &pnp_bus_type; | 125 | dev->dev.bus = &pnp_bus_type; |
126 | dev->dev.dma_mask = &dev->dma_mask; | ||
127 | dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK; | ||
117 | dev->dev.release = &pnp_release_device; | 128 | dev->dev.release = &pnp_release_device; |
118 | dev->status = PNP_READY; | 129 | dev->status = PNP_READY; |
119 | spin_lock(&pnp_lock); | 130 | spin_lock(&pnp_lock); |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 62eda5d59024..a00548799e98 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> | 4 | * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> |
5 | * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> | 5 | * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
9 | * Free Software Foundation; either version 2, or (at your option) any | 9 | * Free Software Foundation; either version 2, or (at your option) any |
@@ -18,7 +18,7 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/acpi.h> | 22 | #include <linux/acpi.h> |
23 | #include <linux/pnp.h> | 23 | #include <linux/pnp.h> |
24 | #include <acpi/acpi_bus.h> | 24 | #include <acpi/acpi_bus.h> |
@@ -82,7 +82,7 @@ static void __init pnpidacpi_to_pnpid(char *id, char *str) | |||
82 | static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) | 82 | static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) |
83 | { | 83 | { |
84 | acpi_status status; | 84 | acpi_status status; |
85 | status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, | 85 | status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, |
86 | &dev->res); | 86 | &dev->res); |
87 | return ACPI_FAILURE(status) ? -ENODEV : 0; | 87 | return ACPI_FAILURE(status) ? -ENODEV : 0; |
88 | } | 88 | } |
@@ -112,9 +112,9 @@ static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table | |||
112 | static int pnpacpi_disable_resources(struct pnp_dev *dev) | 112 | static int pnpacpi_disable_resources(struct pnp_dev *dev) |
113 | { | 113 | { |
114 | acpi_status status; | 114 | acpi_status status; |
115 | 115 | ||
116 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 116 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
117 | status = acpi_evaluate_object((acpi_handle)dev->data, | 117 | status = acpi_evaluate_object((acpi_handle)dev->data, |
118 | "_DIS", NULL, NULL); | 118 | "_DIS", NULL, NULL); |
119 | return ACPI_FAILURE(status) ? -ENODEV : 0; | 119 | return ACPI_FAILURE(status) ? -ENODEV : 0; |
120 | } | 120 | } |
@@ -167,7 +167,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
167 | strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); | 167 | strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); |
168 | 168 | ||
169 | dev->number = num; | 169 | dev->number = num; |
170 | 170 | ||
171 | /* set the initial values for the PnP device */ | 171 | /* set the initial values for the PnP device */ |
172 | dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); | 172 | dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); |
173 | if (!dev_id) | 173 | if (!dev_id) |
@@ -185,14 +185,14 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | if(dev->capabilities & PNP_CONFIGURABLE) { | 187 | if(dev->capabilities & PNP_CONFIGURABLE) { |
188 | status = pnpacpi_parse_resource_option_data(device->handle, | 188 | status = pnpacpi_parse_resource_option_data(device->handle, |
189 | dev); | 189 | dev); |
190 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { | 190 | if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { |
191 | pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); | 191 | pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); |
192 | goto err1; | 192 | goto err1; |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | /* parse compatible ids */ | 196 | /* parse compatible ids */ |
197 | if (device->flags.compatible_ids) { | 197 | if (device->flags.compatible_ids) { |
198 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 198 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; |
@@ -236,6 +236,42 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, | |||
236 | return AE_OK; | 236 | return AE_OK; |
237 | } | 237 | } |
238 | 238 | ||
239 | static int __init acpi_pnp_match(struct device *dev, void *_pnp) | ||
240 | { | ||
241 | struct acpi_device *acpi = to_acpi_device(dev); | ||
242 | struct pnp_dev *pnp = _pnp; | ||
243 | |||
244 | /* true means it matched */ | ||
245 | return acpi->flags.hardware_id | ||
246 | && !acpi_get_physical_device(acpi->handle) | ||
247 | && compare_pnp_id(pnp->id, acpi->pnp.hardware_id); | ||
248 | } | ||
249 | |||
250 | static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle) | ||
251 | { | ||
252 | struct device *adev; | ||
253 | struct acpi_device *acpi; | ||
254 | |||
255 | adev = bus_find_device(&acpi_bus_type, NULL, | ||
256 | to_pnp_dev(dev), | ||
257 | acpi_pnp_match); | ||
258 | if (!adev) | ||
259 | return -ENODEV; | ||
260 | |||
261 | acpi = to_acpi_device(adev); | ||
262 | *handle = acpi->handle; | ||
263 | put_device(adev); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* complete initialization of a PNPACPI device includes having | ||
268 | * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. | ||
269 | */ | ||
270 | static struct acpi_bus_type __initdata acpi_pnp_bus = { | ||
271 | .bus = &pnp_bus_type, | ||
272 | .find_device = acpi_pnp_find_device, | ||
273 | }; | ||
274 | |||
239 | int pnpacpi_disabled __initdata; | 275 | int pnpacpi_disabled __initdata; |
240 | static int __init pnpacpi_init(void) | 276 | static int __init pnpacpi_init(void) |
241 | { | 277 | { |
@@ -245,8 +281,11 @@ static int __init pnpacpi_init(void) | |||
245 | } | 281 | } |
246 | pnp_info("PnP ACPI init"); | 282 | pnp_info("PnP ACPI init"); |
247 | pnp_register_protocol(&pnpacpi_protocol); | 283 | pnp_register_protocol(&pnpacpi_protocol); |
284 | register_acpi_bus_type(&acpi_pnp_bus); | ||
248 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); | 285 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); |
249 | pnp_info("PnP ACPI: found %d devices", num); | 286 | pnp_info("PnP ACPI: found %d devices", num); |
287 | unregister_acpi_bus_type(&acpi_pnp_bus); | ||
288 | pnp_platform_devices = 1; | ||
250 | return 0; | 289 | return 0; |
251 | } | 290 | } |
252 | subsys_initcall(pnpacpi_init); | 291 | subsys_initcall(pnpacpi_init); |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 95738dbd5d45..3a201b77b963 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/delay.h> | 62 | #include <linux/delay.h> |
63 | #include <linux/acpi.h> | 63 | #include <linux/acpi.h> |
64 | #include <linux/freezer.h> | 64 | #include <linux/freezer.h> |
65 | #include <linux/kthread.h> | ||
65 | 66 | ||
66 | #include <asm/page.h> | 67 | #include <asm/page.h> |
67 | #include <asm/desc.h> | 68 | #include <asm/desc.h> |
@@ -159,9 +160,7 @@ static int pnp_dock_thread(void * unused) | |||
159 | { | 160 | { |
160 | static struct pnp_docking_station_info now; | 161 | static struct pnp_docking_station_info now; |
161 | int docked = -1, d = 0; | 162 | int docked = -1, d = 0; |
162 | daemonize("kpnpbiosd"); | 163 | while (!unloading) |
163 | allow_signal(SIGKILL); | ||
164 | while(!unloading && !signal_pending(current)) | ||
165 | { | 164 | { |
166 | int status; | 165 | int status; |
167 | 166 | ||
@@ -170,11 +169,8 @@ static int pnp_dock_thread(void * unused) | |||
170 | */ | 169 | */ |
171 | msleep_interruptible(2000); | 170 | msleep_interruptible(2000); |
172 | 171 | ||
173 | if(signal_pending(current)) { | 172 | if (try_to_freeze()) |
174 | if (try_to_freeze()) | 173 | continue; |
175 | continue; | ||
176 | break; | ||
177 | } | ||
178 | 174 | ||
179 | status = pnp_bios_dock_station_info(&now); | 175 | status = pnp_bios_dock_station_info(&now); |
180 | 176 | ||
@@ -574,6 +570,7 @@ static int __init pnpbios_init(void) | |||
574 | /* scan for pnpbios devices */ | 570 | /* scan for pnpbios devices */ |
575 | build_devlist(); | 571 | build_devlist(); |
576 | 572 | ||
573 | pnp_platform_devices = 1; | ||
577 | return 0; | 574 | return 0; |
578 | } | 575 | } |
579 | 576 | ||
@@ -581,6 +578,7 @@ subsys_initcall(pnpbios_init); | |||
581 | 578 | ||
582 | static int __init pnpbios_thread_init(void) | 579 | static int __init pnpbios_thread_init(void) |
583 | { | 580 | { |
581 | struct task_struct *task; | ||
584 | #if defined(CONFIG_PPC_MERGE) | 582 | #if defined(CONFIG_PPC_MERGE) |
585 | if (check_legacy_ioport(PNPBIOS_BASE)) | 583 | if (check_legacy_ioport(PNPBIOS_BASE)) |
586 | return 0; | 584 | return 0; |
@@ -589,7 +587,8 @@ static int __init pnpbios_thread_init(void) | |||
589 | return 0; | 587 | return 0; |
590 | #ifdef CONFIG_HOTPLUG | 588 | #ifdef CONFIG_HOTPLUG |
591 | init_completion(&unload_sem); | 589 | init_completion(&unload_sem); |
592 | if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0) | 590 | task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd"); |
591 | if (!IS_ERR(task)) | ||
593 | unloading = 0; | 592 | unloading = 0; |
594 | #endif | 593 | #endif |
595 | return 0; | 594 | return 0; |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e97ecefe8584..277df50c89ae 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pnp.h> | 18 | #include <linux/pnp.h> |
19 | #include <linux/io.h> | ||
19 | #include "base.h" | 20 | #include "base.h" |
20 | 21 | ||
21 | 22 | ||
@@ -106,6 +107,34 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) | |||
106 | return; | 107 | return; |
107 | } | 108 | } |
108 | 109 | ||
110 | static void quirk_smc_enable(struct pnp_dev *dev) | ||
111 | { | ||
112 | unsigned int firbase; | ||
113 | |||
114 | if (!dev->active || !pnp_port_valid(dev, 1)) | ||
115 | return; | ||
116 | |||
117 | /* | ||
118 | * On the HP/Compaq nw8240 (and probably other similar machines), | ||
119 | * there is an SMCF010 device with two I/O port regions: | ||
120 | * | ||
121 | * 0x3e8-0x3ef SIR | ||
122 | * 0x100-0x10f FIR | ||
123 | * | ||
124 | * _STA reports the device is enabled, but in fact, the BIOS | ||
125 | * neglects to enable the FIR range. Fortunately, it does fully | ||
126 | * enable the device if we call _SRS. | ||
127 | */ | ||
128 | firbase = pnp_port_start(dev, 1); | ||
129 | if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) { | ||
130 | pnp_err("%s (%s) enabled but not responding, disabling and " | ||
131 | "re-enabling", dev->dev.bus_id, pnp_dev_name(dev)); | ||
132 | pnp_disable_dev(dev); | ||
133 | pnp_activate_dev(dev); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | |||
109 | /* | 138 | /* |
110 | * PnP Quirks | 139 | * PnP Quirks |
111 | * Cards or devices that need some tweaking due to incomplete resource info | 140 | * Cards or devices that need some tweaking due to incomplete resource info |
@@ -126,6 +155,7 @@ static struct pnp_fixup pnp_fixups[] = { | |||
126 | { "CTL0043", quirk_sb16audio_resources }, | 155 | { "CTL0043", quirk_sb16audio_resources }, |
127 | { "CTL0044", quirk_sb16audio_resources }, | 156 | { "CTL0044", quirk_sb16audio_resources }, |
128 | { "CTL0045", quirk_sb16audio_resources }, | 157 | { "CTL0045", quirk_sb16audio_resources }, |
158 | { "SMCf010", quirk_smc_enable }, | ||
129 | { "" } | 159 | { "" } |
130 | }; | 160 | }; |
131 | 161 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index ef1eae98ba44..5e439836db2d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -21,21 +21,31 @@ config RTC_CLASS | |||
21 | will be called rtc-class. | 21 | will be called rtc-class. |
22 | 22 | ||
23 | config RTC_HCTOSYS | 23 | config RTC_HCTOSYS |
24 | bool "Set system time from RTC on startup" | 24 | bool "Set system time from RTC on startup and resume" |
25 | depends on RTC_CLASS = y | 25 | depends on RTC_CLASS = y |
26 | default y | 26 | default y |
27 | help | 27 | help |
28 | If you say yes here, the system time will be set using | 28 | If you say yes here, the system time (wall clock) will be set using |
29 | the value read from the specified RTC device. This is useful | 29 | the value read from a specified RTC device. This is useful to avoid |
30 | in order to avoid unnecessary fsck runs. | 30 | unnecessary fsck runs at boot time, and to network better. |
31 | 31 | ||
32 | config RTC_HCTOSYS_DEVICE | 32 | config RTC_HCTOSYS_DEVICE |
33 | string "The RTC to read the time from" | 33 | string "RTC used to set the system time" |
34 | depends on RTC_HCTOSYS = y | 34 | depends on RTC_HCTOSYS = y |
35 | default "rtc0" | 35 | default "rtc0" |
36 | help | 36 | help |
37 | The RTC device that will be used as the source for | 37 | The RTC device that will be used to (re)initialize the system |
38 | the system time, usually rtc0. | 38 | clock, usually rtc0. Initialization is done when the system |
39 | starts up, and when it resumes from a low power state. | ||
40 | |||
41 | This clock should be battery-backed, so that it reads the correct | ||
42 | time when the system boots from a power-off state. Otherwise, your | ||
43 | system will need an external clock source (like an NTP server). | ||
44 | |||
45 | If the clock you specify here is not battery backed, it may still | ||
46 | be useful to reinitialize system time when resuming from system | ||
47 | sleep states. Do not specify an RTC here unless it stays powered | ||
48 | during all this system's supported sleep states. | ||
39 | 49 | ||
40 | config RTC_DEBUG | 50 | config RTC_DEBUG |
41 | bool "RTC debug support" | 51 | bool "RTC debug support" |
@@ -48,7 +58,7 @@ comment "RTC interfaces" | |||
48 | depends on RTC_CLASS | 58 | depends on RTC_CLASS |
49 | 59 | ||
50 | config RTC_INTF_SYSFS | 60 | config RTC_INTF_SYSFS |
51 | tristate "sysfs" | 61 | boolean "sysfs" |
52 | depends on RTC_CLASS && SYSFS | 62 | depends on RTC_CLASS && SYSFS |
53 | default RTC_CLASS | 63 | default RTC_CLASS |
54 | help | 64 | help |
@@ -59,7 +69,7 @@ config RTC_INTF_SYSFS | |||
59 | will be called rtc-sysfs. | 69 | will be called rtc-sysfs. |
60 | 70 | ||
61 | config RTC_INTF_PROC | 71 | config RTC_INTF_PROC |
62 | tristate "proc" | 72 | boolean "proc" |
63 | depends on RTC_CLASS && PROC_FS | 73 | depends on RTC_CLASS && PROC_FS |
64 | default RTC_CLASS | 74 | default RTC_CLASS |
65 | help | 75 | help |
@@ -71,7 +81,7 @@ config RTC_INTF_PROC | |||
71 | will be called rtc-proc. | 81 | will be called rtc-proc. |
72 | 82 | ||
73 | config RTC_INTF_DEV | 83 | config RTC_INTF_DEV |
74 | tristate "dev" | 84 | boolean "dev" |
75 | depends on RTC_CLASS | 85 | depends on RTC_CLASS |
76 | default RTC_CLASS | 86 | default RTC_CLASS |
77 | help | 87 | help |
@@ -92,44 +102,26 @@ config RTC_INTF_DEV_UIE_EMUL | |||
92 | driver does not expose RTC_UIE ioctls. Those requests generate | 102 | driver does not expose RTC_UIE ioctls. Those requests generate |
93 | once-per-second update interrupts, used for synchronization. | 103 | once-per-second update interrupts, used for synchronization. |
94 | 104 | ||
95 | comment "RTC drivers" | 105 | config RTC_DRV_TEST |
106 | tristate "Test driver/device" | ||
96 | depends on RTC_CLASS | 107 | depends on RTC_CLASS |
97 | |||
98 | # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h> | ||
99 | # requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a | ||
100 | # global rtc_lock ... it's not yet just another platform_device. | ||
101 | |||
102 | config RTC_DRV_CMOS | ||
103 | tristate "PC-style 'CMOS' real time clock" | ||
104 | depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ | ||
105 | || M32R || ATARI || POWERPC) | ||
106 | help | ||
107 | Say "yes" here to get direct support for the real time clock | ||
108 | found in every PC or ACPI-based system, and some other boards. | ||
109 | Specifically the original MC146818, compatibles like those in | ||
110 | PC south bridges, the DS12887 or M48T86, some multifunction | ||
111 | or LPC bus chips, and so on. | ||
112 | |||
113 | Your system will need to define the platform device used by | ||
114 | this driver, otherwise it won't be accessible. This means | ||
115 | you can safely enable this driver if you don't know whether | ||
116 | or not your board has this kind of hardware. | ||
117 | |||
118 | This driver can also be built as a module. If so, the module | ||
119 | will be called rtc-cmos. | ||
120 | |||
121 | config RTC_DRV_X1205 | ||
122 | tristate "Xicor/Intersil X1205" | ||
123 | depends on RTC_CLASS && I2C | ||
124 | help | 108 | help |
125 | If you say yes here you get support for the | 109 | If you say yes here you get support for the |
126 | Xicor/Intersil X1205 RTC chip. | 110 | RTC test driver. It's a software RTC which can be |
111 | used to test the RTC subsystem APIs. It gets | ||
112 | the time from the system clock. | ||
113 | You want this driver only if you are doing development | ||
114 | on the RTC subsystem. Please read the source code | ||
115 | for further details. | ||
127 | 116 | ||
128 | This driver can also be built as a module. If so, the module | 117 | This driver can also be built as a module. If so, the module |
129 | will be called rtc-x1205. | 118 | will be called rtc-test. |
119 | |||
120 | comment "I2C RTC drivers" | ||
121 | depends on RTC_CLASS | ||
130 | 122 | ||
131 | config RTC_DRV_DS1307 | 123 | config RTC_DRV_DS1307 |
132 | tristate "Dallas/Maxim DS1307 and similar I2C RTC chips" | 124 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" |
133 | depends on RTC_CLASS && I2C | 125 | depends on RTC_CLASS && I2C |
134 | help | 126 | help |
135 | If you say yes here you get support for various compatible RTC | 127 | If you say yes here you get support for various compatible RTC |
@@ -146,53 +138,55 @@ config RTC_DRV_DS1307 | |||
146 | This driver can also be built as a module. If so, the module | 138 | This driver can also be built as a module. If so, the module |
147 | will be called rtc-ds1307. | 139 | will be called rtc-ds1307. |
148 | 140 | ||
149 | config RTC_DRV_DS1553 | 141 | config RTC_DRV_DS1672 |
150 | tristate "Dallas DS1553" | 142 | tristate "Dallas/Maxim DS1672" |
151 | depends on RTC_CLASS | 143 | depends on RTC_CLASS && I2C |
152 | help | 144 | help |
153 | If you say yes here you get support for the | 145 | If you say yes here you get support for the |
154 | Dallas DS1553 timekeeping chip. | 146 | Dallas/Maxim DS1672 timekeeping chip. |
155 | 147 | ||
156 | This driver can also be built as a module. If so, the module | 148 | This driver can also be built as a module. If so, the module |
157 | will be called rtc-ds1553. | 149 | will be called rtc-ds1672. |
158 | 150 | ||
159 | config RTC_DRV_ISL1208 | 151 | config RTC_DRV_MAX6900 |
160 | tristate "Intersil 1208" | 152 | tristate "Maxim 6900" |
161 | depends on RTC_CLASS && I2C | 153 | depends on RTC_CLASS && I2C |
162 | help | 154 | help |
163 | If you say yes here you get support for the | 155 | If you say yes here you will get support for the |
164 | Intersil 1208 RTC chip. | 156 | Maxim MAX6900 I2C RTC chip. |
165 | 157 | ||
166 | This driver can also be built as a module. If so, the module | 158 | This driver can also be built as a module. If so, the module |
167 | will be called rtc-isl1208. | 159 | will be called rtc-max6900. |
168 | 160 | ||
169 | config RTC_DRV_DS1672 | 161 | config RTC_DRV_RS5C372 |
170 | tristate "Dallas/Maxim DS1672" | 162 | tristate "Ricoh RS5C372A/B" |
171 | depends on RTC_CLASS && I2C | 163 | depends on RTC_CLASS && I2C |
172 | help | 164 | help |
173 | If you say yes here you get support for the | 165 | If you say yes here you get support for the |
174 | Dallas/Maxim DS1672 timekeeping chip. | 166 | Ricoh RS5C372A and RS5C372B RTC chips. |
175 | 167 | ||
176 | This driver can also be built as a module. If so, the module | 168 | This driver can also be built as a module. If so, the module |
177 | will be called rtc-ds1672. | 169 | will be called rtc-rs5c372. |
178 | 170 | ||
179 | config RTC_DRV_DS1742 | 171 | config RTC_DRV_ISL1208 |
180 | tristate "Dallas DS1742/1743" | 172 | tristate "Intersil 1208" |
181 | depends on RTC_CLASS | 173 | depends on RTC_CLASS && I2C |
182 | help | 174 | help |
183 | If you say yes here you get support for the | 175 | If you say yes here you get support for the |
184 | Dallas DS1742/1743 timekeeping chip. | 176 | Intersil 1208 RTC chip. |
185 | 177 | ||
186 | This driver can also be built as a module. If so, the module | 178 | This driver can also be built as a module. If so, the module |
187 | will be called rtc-ds1742. | 179 | will be called rtc-isl1208. |
188 | 180 | ||
189 | config RTC_DRV_OMAP | 181 | config RTC_DRV_X1205 |
190 | tristate "TI OMAP1" | 182 | tristate "Xicor/Intersil X1205" |
191 | depends on RTC_CLASS && ( \ | 183 | depends on RTC_CLASS && I2C |
192 | ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 ) | ||
193 | help | 184 | help |
194 | Say "yes" here to support the real time clock on TI OMAP1 chips. | 185 | If you say yes here you get support for the |
195 | This driver can also be built as a module called rtc-omap. | 186 | Xicor/Intersil X1205 RTC chip. |
187 | |||
188 | This driver can also be built as a module. If so, the module | ||
189 | will be called rtc-x1205. | ||
196 | 190 | ||
197 | config RTC_DRV_PCF8563 | 191 | config RTC_DRV_PCF8563 |
198 | tristate "Philips PCF8563/Epson RTC8564" | 192 | tristate "Philips PCF8563/Epson RTC8564" |
@@ -207,16 +201,20 @@ config RTC_DRV_PCF8563 | |||
207 | 201 | ||
208 | config RTC_DRV_PCF8583 | 202 | config RTC_DRV_PCF8583 |
209 | tristate "Philips PCF8583" | 203 | tristate "Philips PCF8583" |
210 | depends on RTC_CLASS && I2C && ARCH_RPC | 204 | depends on RTC_CLASS && I2C |
211 | help | 205 | help |
212 | If you say yes here you get support for the Philips PCF8583 | 206 | If you say yes here you get support for the Philips PCF8583 |
213 | RTC chip found on Acorn RiscPCs. This driver supports the | 207 | RTC chip found on Acorn RiscPCs. This driver supports the |
214 | platform specific method of retrieving the current year from | 208 | platform specific method of retrieving the current year from |
215 | the RTC's SRAM. | 209 | the RTC's SRAM. It will work on other platforms with the same |
210 | chip, but the year will probably have to be tweaked. | ||
216 | 211 | ||
217 | This driver can also be built as a module. If so, the module | 212 | This driver can also be built as a module. If so, the module |
218 | will be called rtc-pcf8583. | 213 | will be called rtc-pcf8583. |
219 | 214 | ||
215 | comment "SPI RTC drivers" | ||
216 | depends on RTC_CLASS | ||
217 | |||
220 | config RTC_DRV_RS5C348 | 218 | config RTC_DRV_RS5C348 |
221 | tristate "Ricoh RS5C348A/B" | 219 | tristate "Ricoh RS5C348A/B" |
222 | depends on RTC_CLASS && SPI | 220 | depends on RTC_CLASS && SPI |
@@ -227,15 +225,92 @@ config RTC_DRV_RS5C348 | |||
227 | This driver can also be built as a module. If so, the module | 225 | This driver can also be built as a module. If so, the module |
228 | will be called rtc-rs5c348. | 226 | will be called rtc-rs5c348. |
229 | 227 | ||
230 | config RTC_DRV_RS5C372 | 228 | config RTC_DRV_MAX6902 |
231 | tristate "Ricoh RS5C372A/B" | 229 | tristate "Maxim 6902" |
232 | depends on RTC_CLASS && I2C | 230 | depends on RTC_CLASS && SPI |
231 | help | ||
232 | If you say yes here you will get support for the | ||
233 | Maxim MAX6902 SPI RTC chip. | ||
234 | |||
235 | This driver can also be built as a module. If so, the module | ||
236 | will be called rtc-max6902. | ||
237 | |||
238 | comment "Platform RTC drivers" | ||
239 | depends on RTC_CLASS | ||
240 | |||
241 | # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h> | ||
242 | # requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a | ||
243 | # global rtc_lock ... it's not yet just another platform_device. | ||
244 | |||
245 | config RTC_DRV_CMOS | ||
246 | tristate "PC-style 'CMOS'" | ||
247 | depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ | ||
248 | || M32R || ATARI || POWERPC) | ||
249 | help | ||
250 | Say "yes" here to get direct support for the real time clock | ||
251 | found in every PC or ACPI-based system, and some other boards. | ||
252 | Specifically the original MC146818, compatibles like those in | ||
253 | PC south bridges, the DS12887 or M48T86, some multifunction | ||
254 | or LPC bus chips, and so on. | ||
255 | |||
256 | Your system will need to define the platform device used by | ||
257 | this driver, otherwise it won't be accessible. This means | ||
258 | you can safely enable this driver if you don't know whether | ||
259 | or not your board has this kind of hardware. | ||
260 | |||
261 | This driver can also be built as a module. If so, the module | ||
262 | will be called rtc-cmos. | ||
263 | |||
264 | config RTC_DRV_DS1553 | ||
265 | tristate "Dallas DS1553" | ||
266 | depends on RTC_CLASS | ||
233 | help | 267 | help |
234 | If you say yes here you get support for the | 268 | If you say yes here you get support for the |
235 | Ricoh RS5C372A and RS5C372B RTC chips. | 269 | Dallas DS1553 timekeeping chip. |
236 | 270 | ||
237 | This driver can also be built as a module. If so, the module | 271 | This driver can also be built as a module. If so, the module |
238 | will be called rtc-rs5c372. | 272 | will be called rtc-ds1553. |
273 | |||
274 | config RTC_DRV_DS1742 | ||
275 | tristate "Dallas DS1742/1743" | ||
276 | depends on RTC_CLASS | ||
277 | help | ||
278 | If you say yes here you get support for the | ||
279 | Dallas DS1742/1743 timekeeping chip. | ||
280 | |||
281 | This driver can also be built as a module. If so, the module | ||
282 | will be called rtc-ds1742. | ||
283 | |||
284 | config RTC_DRV_M48T86 | ||
285 | tristate "ST M48T86/Dallas DS12887" | ||
286 | depends on RTC_CLASS | ||
287 | help | ||
288 | If you say Y here you will get support for the | ||
289 | ST M48T86 and Dallas DS12887 RTC chips. | ||
290 | |||
291 | This driver can also be built as a module. If so, the module | ||
292 | will be called rtc-m48t86. | ||
293 | |||
294 | config RTC_DRV_V3020 | ||
295 | tristate "EM Microelectronic V3020" | ||
296 | depends on RTC_CLASS | ||
297 | help | ||
298 | If you say yes here you will get support for the | ||
299 | EM Microelectronic v3020 RTC chip. | ||
300 | |||
301 | This driver can also be built as a module. If so, the module | ||
302 | will be called rtc-v3020. | ||
303 | |||
304 | comment "on-CPU RTC drivers" | ||
305 | depends on RTC_CLASS | ||
306 | |||
307 | config RTC_DRV_OMAP | ||
308 | tristate "TI OMAP1" | ||
309 | depends on RTC_CLASS && ( \ | ||
310 | ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 ) | ||
311 | help | ||
312 | Say "yes" here to support the real time clock on TI OMAP1 chips. | ||
313 | This driver can also be built as a module called rtc-omap. | ||
239 | 314 | ||
240 | config RTC_DRV_S3C | 315 | config RTC_DRV_S3C |
241 | tristate "Samsung S3C series SoC RTC" | 316 | tristate "Samsung S3C series SoC RTC" |
@@ -253,16 +328,6 @@ config RTC_DRV_S3C | |||
253 | This driver can also be build as a module. If so, the module | 328 | This driver can also be build as a module. If so, the module |
254 | will be called rtc-s3c. | 329 | will be called rtc-s3c. |
255 | 330 | ||
256 | config RTC_DRV_M48T86 | ||
257 | tristate "ST M48T86/Dallas DS12887" | ||
258 | depends on RTC_CLASS | ||
259 | help | ||
260 | If you say Y here you will get support for the | ||
261 | ST M48T86 and Dallas DS12887 RTC chips. | ||
262 | |||
263 | This driver can also be built as a module. If so, the module | ||
264 | will be called rtc-m48t86. | ||
265 | |||
266 | config RTC_DRV_EP93XX | 331 | config RTC_DRV_EP93XX |
267 | tristate "Cirrus Logic EP93XX" | 332 | tristate "Cirrus Logic EP93XX" |
268 | depends on RTC_CLASS && ARCH_EP93XX | 333 | depends on RTC_CLASS && ARCH_EP93XX |
@@ -308,7 +373,7 @@ config RTC_DRV_PL031 | |||
308 | depends on RTC_CLASS && ARM_AMBA | 373 | depends on RTC_CLASS && ARM_AMBA |
309 | help | 374 | help |
310 | If you say Y here you will get access to ARM AMBA | 375 | If you say Y here you will get access to ARM AMBA |
311 | PrimeCell PL031 UART found on certain ARM SOCs. | 376 | PrimeCell PL031 RTC found on certain ARM SOCs. |
312 | 377 | ||
313 | To compile this driver as a module, choose M here: the | 378 | To compile this driver as a module, choose M here: the |
314 | module will be called rtc-pl031. | 379 | module will be called rtc-pl031. |
@@ -319,41 +384,6 @@ config RTC_DRV_AT91RM9200 | |||
319 | help | 384 | help |
320 | Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). | 385 | Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). |
321 | 386 | ||
322 | config RTC_DRV_TEST | ||
323 | tristate "Test driver/device" | ||
324 | depends on RTC_CLASS | ||
325 | help | ||
326 | If you say yes here you get support for the | ||
327 | RTC test driver. It's a software RTC which can be | ||
328 | used to test the RTC subsystem APIs. It gets | ||
329 | the time from the system clock. | ||
330 | You want this driver only if you are doing development | ||
331 | on the RTC subsystem. Please read the source code | ||
332 | for further details. | ||
333 | |||
334 | This driver can also be built as a module. If so, the module | ||
335 | will be called rtc-test. | ||
336 | |||
337 | config RTC_DRV_MAX6902 | ||
338 | tristate "Maxim 6902" | ||
339 | depends on RTC_CLASS && SPI | ||
340 | help | ||
341 | If you say yes here you will get support for the | ||
342 | Maxim MAX6902 spi RTC chip. | ||
343 | |||
344 | This driver can also be built as a module. If so, the module | ||
345 | will be called rtc-max6902. | ||
346 | |||
347 | config RTC_DRV_V3020 | ||
348 | tristate "EM Microelectronic V3020" | ||
349 | depends on RTC_CLASS | ||
350 | help | ||
351 | If you say yes here you will get support for the | ||
352 | EM Microelectronic v3020 RTC chip. | ||
353 | |||
354 | This driver can also be built as a module. If so, the module | ||
355 | will be called rtc-v3020. | ||
356 | |||
357 | config RTC_DRV_BFIN | 387 | config RTC_DRV_BFIN |
358 | tristate "Blackfin On-Chip RTC" | 388 | tristate "Blackfin On-Chip RTC" |
359 | depends on RTC_CLASS && BFIN | 389 | depends on RTC_CLASS && BFIN |
@@ -364,4 +394,10 @@ config RTC_DRV_BFIN | |||
364 | This driver can also be built as a module. If so, the module | 394 | This driver can also be built as a module. If so, the module |
365 | will be called rtc-bfin. | 395 | will be called rtc-bfin. |
366 | 396 | ||
397 | config RTC_DRV_RS5C313 | ||
398 | tristate "Ricoh RS5C313" | ||
399 | depends on RTC_CLASS && BROKEN | ||
400 | help | ||
401 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. | ||
402 | |||
367 | endmenu | 403 | endmenu |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9218cf28d6ed..a1afbc236073 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -11,9 +11,9 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o | |||
11 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o | 11 | obj-$(CONFIG_RTC_CLASS) += rtc-core.o |
12 | rtc-core-y := class.o interface.o | 12 | rtc-core-y := class.o interface.o |
13 | 13 | ||
14 | obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | 14 | rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o |
15 | obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o | 15 | rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o |
16 | obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o | 16 | rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o |
17 | 17 | ||
18 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 18 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
19 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 19 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
@@ -30,10 +30,12 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | |||
30 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 30 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
31 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 31 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
32 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 32 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
33 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | ||
33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 34 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
34 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 35 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
35 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 36 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
36 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 37 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
38 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | ||
37 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 39 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
38 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 40 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
39 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 41 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 04aaa6347234..8b3cd31d6a61 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -16,19 +16,94 @@ | |||
16 | #include <linux/kdev_t.h> | 16 | #include <linux/kdev_t.h> |
17 | #include <linux/idr.h> | 17 | #include <linux/idr.h> |
18 | 18 | ||
19 | #include "rtc-core.h" | ||
20 | |||
21 | |||
19 | static DEFINE_IDR(rtc_idr); | 22 | static DEFINE_IDR(rtc_idr); |
20 | static DEFINE_MUTEX(idr_lock); | 23 | static DEFINE_MUTEX(idr_lock); |
21 | struct class *rtc_class; | 24 | struct class *rtc_class; |
22 | 25 | ||
23 | static void rtc_device_release(struct class_device *class_dev) | 26 | static void rtc_device_release(struct device *dev) |
24 | { | 27 | { |
25 | struct rtc_device *rtc = to_rtc_device(class_dev); | 28 | struct rtc_device *rtc = to_rtc_device(dev); |
26 | mutex_lock(&idr_lock); | 29 | mutex_lock(&idr_lock); |
27 | idr_remove(&rtc_idr, rtc->id); | 30 | idr_remove(&rtc_idr, rtc->id); |
28 | mutex_unlock(&idr_lock); | 31 | mutex_unlock(&idr_lock); |
29 | kfree(rtc); | 32 | kfree(rtc); |
30 | } | 33 | } |
31 | 34 | ||
35 | #if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) | ||
36 | |||
37 | /* | ||
38 | * On suspend(), measure the delta between one RTC and the | ||
39 | * system's wall clock; restore it on resume(). | ||
40 | */ | ||
41 | |||
42 | static struct timespec delta; | ||
43 | static time_t oldtime; | ||
44 | |||
45 | static int rtc_suspend(struct device *dev, pm_message_t mesg) | ||
46 | { | ||
47 | struct rtc_device *rtc = to_rtc_device(dev); | ||
48 | struct rtc_time tm; | ||
49 | |||
50 | if (strncmp(rtc->dev.bus_id, | ||
51 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
52 | BUS_ID_SIZE) != 0) | ||
53 | return 0; | ||
54 | |||
55 | rtc_read_time(rtc, &tm); | ||
56 | rtc_tm_to_time(&tm, &oldtime); | ||
57 | |||
58 | /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ | ||
59 | set_normalized_timespec(&delta, | ||
60 | xtime.tv_sec - oldtime, | ||
61 | xtime.tv_nsec - (NSEC_PER_SEC >> 1)); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int rtc_resume(struct device *dev) | ||
67 | { | ||
68 | struct rtc_device *rtc = to_rtc_device(dev); | ||
69 | struct rtc_time tm; | ||
70 | time_t newtime; | ||
71 | struct timespec time; | ||
72 | |||
73 | if (strncmp(rtc->dev.bus_id, | ||
74 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
75 | BUS_ID_SIZE) != 0) | ||
76 | return 0; | ||
77 | |||
78 | rtc_read_time(rtc, &tm); | ||
79 | if (rtc_valid_tm(&tm) != 0) { | ||
80 | pr_debug("%s: bogus resume time\n", rtc->dev.bus_id); | ||
81 | return 0; | ||
82 | } | ||
83 | rtc_tm_to_time(&tm, &newtime); | ||
84 | if (newtime <= oldtime) { | ||
85 | if (newtime < oldtime) | ||
86 | pr_debug("%s: time travel!\n", rtc->dev.bus_id); | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /* restore wall clock using delta against this RTC; | ||
91 | * adjust again for avg 1/2 second RTC sampling error | ||
92 | */ | ||
93 | set_normalized_timespec(&time, | ||
94 | newtime + delta.tv_sec, | ||
95 | (NSEC_PER_SEC >> 1) + delta.tv_nsec); | ||
96 | do_settimeofday(&time); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | #else | ||
102 | #define rtc_suspend NULL | ||
103 | #define rtc_resume NULL | ||
104 | #endif | ||
105 | |||
106 | |||
32 | /** | 107 | /** |
33 | * rtc_device_register - register w/ RTC class | 108 | * rtc_device_register - register w/ RTC class |
34 | * @dev: the device to register | 109 | * @dev: the device to register |
@@ -70,23 +145,29 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
70 | rtc->ops = ops; | 145 | rtc->ops = ops; |
71 | rtc->owner = owner; | 146 | rtc->owner = owner; |
72 | rtc->max_user_freq = 64; | 147 | rtc->max_user_freq = 64; |
73 | rtc->class_dev.dev = dev; | 148 | rtc->dev.parent = dev; |
74 | rtc->class_dev.class = rtc_class; | 149 | rtc->dev.class = rtc_class; |
75 | rtc->class_dev.release = rtc_device_release; | 150 | rtc->dev.release = rtc_device_release; |
76 | 151 | ||
77 | mutex_init(&rtc->ops_lock); | 152 | mutex_init(&rtc->ops_lock); |
78 | spin_lock_init(&rtc->irq_lock); | 153 | spin_lock_init(&rtc->irq_lock); |
79 | spin_lock_init(&rtc->irq_task_lock); | 154 | spin_lock_init(&rtc->irq_task_lock); |
80 | 155 | ||
81 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | 156 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); |
82 | snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); | 157 | snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); |
83 | 158 | ||
84 | err = class_device_register(&rtc->class_dev); | 159 | rtc_dev_prepare(rtc); |
160 | |||
161 | err = device_register(&rtc->dev); | ||
85 | if (err) | 162 | if (err) |
86 | goto exit_kfree; | 163 | goto exit_kfree; |
87 | 164 | ||
165 | rtc_dev_add_device(rtc); | ||
166 | rtc_sysfs_add_device(rtc); | ||
167 | rtc_proc_add_device(rtc); | ||
168 | |||
88 | dev_info(dev, "rtc core: registered %s as %s\n", | 169 | dev_info(dev, "rtc core: registered %s as %s\n", |
89 | rtc->name, rtc->class_dev.class_id); | 170 | rtc->name, rtc->dev.bus_id); |
90 | 171 | ||
91 | return rtc; | 172 | return rtc; |
92 | 173 | ||
@@ -113,26 +194,22 @@ EXPORT_SYMBOL_GPL(rtc_device_register); | |||
113 | */ | 194 | */ |
114 | void rtc_device_unregister(struct rtc_device *rtc) | 195 | void rtc_device_unregister(struct rtc_device *rtc) |
115 | { | 196 | { |
116 | if (class_device_get(&rtc->class_dev) != NULL) { | 197 | if (get_device(&rtc->dev) != NULL) { |
117 | mutex_lock(&rtc->ops_lock); | 198 | mutex_lock(&rtc->ops_lock); |
118 | /* remove innards of this RTC, then disable it, before | 199 | /* remove innards of this RTC, then disable it, before |
119 | * letting any rtc_class_open() users access it again | 200 | * letting any rtc_class_open() users access it again |
120 | */ | 201 | */ |
121 | class_device_unregister(&rtc->class_dev); | 202 | rtc_sysfs_del_device(rtc); |
203 | rtc_dev_del_device(rtc); | ||
204 | rtc_proc_del_device(rtc); | ||
205 | device_unregister(&rtc->dev); | ||
122 | rtc->ops = NULL; | 206 | rtc->ops = NULL; |
123 | mutex_unlock(&rtc->ops_lock); | 207 | mutex_unlock(&rtc->ops_lock); |
124 | class_device_put(&rtc->class_dev); | 208 | put_device(&rtc->dev); |
125 | } | 209 | } |
126 | } | 210 | } |
127 | EXPORT_SYMBOL_GPL(rtc_device_unregister); | 211 | EXPORT_SYMBOL_GPL(rtc_device_unregister); |
128 | 212 | ||
129 | int rtc_interface_register(struct class_interface *intf) | ||
130 | { | ||
131 | intf->class = rtc_class; | ||
132 | return class_interface_register(intf); | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(rtc_interface_register); | ||
135 | |||
136 | static int __init rtc_init(void) | 213 | static int __init rtc_init(void) |
137 | { | 214 | { |
138 | rtc_class = class_create(THIS_MODULE, "rtc"); | 215 | rtc_class = class_create(THIS_MODULE, "rtc"); |
@@ -140,11 +217,16 @@ static int __init rtc_init(void) | |||
140 | printk(KERN_ERR "%s: couldn't create class\n", __FILE__); | 217 | printk(KERN_ERR "%s: couldn't create class\n", __FILE__); |
141 | return PTR_ERR(rtc_class); | 218 | return PTR_ERR(rtc_class); |
142 | } | 219 | } |
220 | rtc_class->suspend = rtc_suspend; | ||
221 | rtc_class->resume = rtc_resume; | ||
222 | rtc_dev_init(); | ||
223 | rtc_sysfs_init(rtc_class); | ||
143 | return 0; | 224 | return 0; |
144 | } | 225 | } |
145 | 226 | ||
146 | static void __exit rtc_exit(void) | 227 | static void __exit rtc_exit(void) |
147 | { | 228 | { |
229 | rtc_dev_exit(); | ||
148 | class_destroy(rtc_class); | 230 | class_destroy(rtc_class); |
149 | } | 231 | } |
150 | 232 | ||
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index d02fe9a0001f..178527252c6a 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c | |||
@@ -26,15 +26,15 @@ static int __init rtc_hctosys(void) | |||
26 | { | 26 | { |
27 | int err; | 27 | int err; |
28 | struct rtc_time tm; | 28 | struct rtc_time tm; |
29 | struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | 29 | struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
30 | 30 | ||
31 | if (class_dev == NULL) { | 31 | if (rtc == NULL) { |
32 | printk("%s: unable to open rtc device (%s)\n", | 32 | printk("%s: unable to open rtc device (%s)\n", |
33 | __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); | 33 | __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); |
34 | return -ENODEV; | 34 | return -ENODEV; |
35 | } | 35 | } |
36 | 36 | ||
37 | err = rtc_read_time(class_dev, &tm); | 37 | err = rtc_read_time(rtc, &tm); |
38 | if (err == 0) { | 38 | if (err == 0) { |
39 | err = rtc_valid_tm(&tm); | 39 | err = rtc_valid_tm(&tm); |
40 | if (err == 0) { | 40 | if (err == 0) { |
@@ -46,7 +46,7 @@ static int __init rtc_hctosys(void) | |||
46 | 46 | ||
47 | do_settimeofday(&tv); | 47 | do_settimeofday(&tv); |
48 | 48 | ||
49 | dev_info(class_dev->dev, | 49 | dev_info(rtc->dev.parent, |
50 | "setting the system clock to " | 50 | "setting the system clock to " |
51 | "%d-%02d-%02d %02d:%02d:%02d (%u)\n", | 51 | "%d-%02d-%02d %02d:%02d:%02d (%u)\n", |
52 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, | 52 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, |
@@ -54,14 +54,14 @@ static int __init rtc_hctosys(void) | |||
54 | (unsigned int) tv.tv_sec); | 54 | (unsigned int) tv.tv_sec); |
55 | } | 55 | } |
56 | else | 56 | else |
57 | dev_err(class_dev->dev, | 57 | dev_err(rtc->dev.parent, |
58 | "hctosys: invalid date/time\n"); | 58 | "hctosys: invalid date/time\n"); |
59 | } | 59 | } |
60 | else | 60 | else |
61 | dev_err(class_dev->dev, | 61 | dev_err(rtc->dev.parent, |
62 | "hctosys: unable to read the hardware clock\n"); | 62 | "hctosys: unable to read the hardware clock\n"); |
63 | 63 | ||
64 | rtc_class_close(class_dev); | 64 | rtc_class_close(rtc); |
65 | 65 | ||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index ef40df0f169d..ad66c6ecf365 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -13,10 +13,9 @@ | |||
13 | 13 | ||
14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
15 | 15 | ||
16 | int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) | 16 | int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) |
17 | { | 17 | { |
18 | int err; | 18 | int err; |
19 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
20 | 19 | ||
21 | err = mutex_lock_interruptible(&rtc->ops_lock); | 20 | err = mutex_lock_interruptible(&rtc->ops_lock); |
22 | if (err) | 21 | if (err) |
@@ -28,7 +27,7 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) | |||
28 | err = -EINVAL; | 27 | err = -EINVAL; |
29 | else { | 28 | else { |
30 | memset(tm, 0, sizeof(struct rtc_time)); | 29 | memset(tm, 0, sizeof(struct rtc_time)); |
31 | err = rtc->ops->read_time(class_dev->dev, tm); | 30 | err = rtc->ops->read_time(rtc->dev.parent, tm); |
32 | } | 31 | } |
33 | 32 | ||
34 | mutex_unlock(&rtc->ops_lock); | 33 | mutex_unlock(&rtc->ops_lock); |
@@ -36,10 +35,9 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) | |||
36 | } | 35 | } |
37 | EXPORT_SYMBOL_GPL(rtc_read_time); | 36 | EXPORT_SYMBOL_GPL(rtc_read_time); |
38 | 37 | ||
39 | int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) | 38 | int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) |
40 | { | 39 | { |
41 | int err; | 40 | int err; |
42 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
43 | 41 | ||
44 | err = rtc_valid_tm(tm); | 42 | err = rtc_valid_tm(tm); |
45 | if (err != 0) | 43 | if (err != 0) |
@@ -54,17 +52,16 @@ int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) | |||
54 | else if (!rtc->ops->set_time) | 52 | else if (!rtc->ops->set_time) |
55 | err = -EINVAL; | 53 | err = -EINVAL; |
56 | else | 54 | else |
57 | err = rtc->ops->set_time(class_dev->dev, tm); | 55 | err = rtc->ops->set_time(rtc->dev.parent, tm); |
58 | 56 | ||
59 | mutex_unlock(&rtc->ops_lock); | 57 | mutex_unlock(&rtc->ops_lock); |
60 | return err; | 58 | return err; |
61 | } | 59 | } |
62 | EXPORT_SYMBOL_GPL(rtc_set_time); | 60 | EXPORT_SYMBOL_GPL(rtc_set_time); |
63 | 61 | ||
64 | int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) | 62 | int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) |
65 | { | 63 | { |
66 | int err; | 64 | int err; |
67 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
68 | 65 | ||
69 | err = mutex_lock_interruptible(&rtc->ops_lock); | 66 | err = mutex_lock_interruptible(&rtc->ops_lock); |
70 | if (err) | 67 | if (err) |
@@ -73,11 +70,11 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) | |||
73 | if (!rtc->ops) | 70 | if (!rtc->ops) |
74 | err = -ENODEV; | 71 | err = -ENODEV; |
75 | else if (rtc->ops->set_mmss) | 72 | else if (rtc->ops->set_mmss) |
76 | err = rtc->ops->set_mmss(class_dev->dev, secs); | 73 | err = rtc->ops->set_mmss(rtc->dev.parent, secs); |
77 | else if (rtc->ops->read_time && rtc->ops->set_time) { | 74 | else if (rtc->ops->read_time && rtc->ops->set_time) { |
78 | struct rtc_time new, old; | 75 | struct rtc_time new, old; |
79 | 76 | ||
80 | err = rtc->ops->read_time(class_dev->dev, &old); | 77 | err = rtc->ops->read_time(rtc->dev.parent, &old); |
81 | if (err == 0) { | 78 | if (err == 0) { |
82 | rtc_time_to_tm(secs, &new); | 79 | rtc_time_to_tm(secs, &new); |
83 | 80 | ||
@@ -89,7 +86,8 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) | |||
89 | */ | 86 | */ |
90 | if (!((old.tm_hour == 23 && old.tm_min == 59) || | 87 | if (!((old.tm_hour == 23 && old.tm_min == 59) || |
91 | (new.tm_hour == 23 && new.tm_min == 59))) | 88 | (new.tm_hour == 23 && new.tm_min == 59))) |
92 | err = rtc->ops->set_time(class_dev->dev, &new); | 89 | err = rtc->ops->set_time(rtc->dev.parent, |
90 | &new); | ||
93 | } | 91 | } |
94 | } | 92 | } |
95 | else | 93 | else |
@@ -101,10 +99,9 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) | |||
101 | } | 99 | } |
102 | EXPORT_SYMBOL_GPL(rtc_set_mmss); | 100 | EXPORT_SYMBOL_GPL(rtc_set_mmss); |
103 | 101 | ||
104 | int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) | 102 | int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
105 | { | 103 | { |
106 | int err; | 104 | int err; |
107 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
108 | 105 | ||
109 | err = mutex_lock_interruptible(&rtc->ops_lock); | 106 | err = mutex_lock_interruptible(&rtc->ops_lock); |
110 | if (err) | 107 | if (err) |
@@ -116,7 +113,7 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) | |||
116 | err = -EINVAL; | 113 | err = -EINVAL; |
117 | else { | 114 | else { |
118 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); | 115 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); |
119 | err = rtc->ops->read_alarm(class_dev->dev, alarm); | 116 | err = rtc->ops->read_alarm(rtc->dev.parent, alarm); |
120 | } | 117 | } |
121 | 118 | ||
122 | mutex_unlock(&rtc->ops_lock); | 119 | mutex_unlock(&rtc->ops_lock); |
@@ -124,10 +121,13 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) | |||
124 | } | 121 | } |
125 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | 122 | EXPORT_SYMBOL_GPL(rtc_read_alarm); |
126 | 123 | ||
127 | int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) | 124 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
128 | { | 125 | { |
129 | int err; | 126 | int err; |
130 | struct rtc_device *rtc = to_rtc_device(class_dev); | 127 | |
128 | err = rtc_valid_tm(&alarm->time); | ||
129 | if (err != 0) | ||
130 | return err; | ||
131 | 131 | ||
132 | err = mutex_lock_interruptible(&rtc->ops_lock); | 132 | err = mutex_lock_interruptible(&rtc->ops_lock); |
133 | if (err) | 133 | if (err) |
@@ -138,7 +138,7 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) | |||
138 | else if (!rtc->ops->set_alarm) | 138 | else if (!rtc->ops->set_alarm) |
139 | err = -EINVAL; | 139 | err = -EINVAL; |
140 | else | 140 | else |
141 | err = rtc->ops->set_alarm(class_dev->dev, alarm); | 141 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); |
142 | 142 | ||
143 | mutex_unlock(&rtc->ops_lock); | 143 | mutex_unlock(&rtc->ops_lock); |
144 | return err; | 144 | return err; |
@@ -147,16 +147,14 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); | |||
147 | 147 | ||
148 | /** | 148 | /** |
149 | * rtc_update_irq - report RTC periodic, alarm, and/or update irqs | 149 | * rtc_update_irq - report RTC periodic, alarm, and/or update irqs |
150 | * @class_dev: the rtc's class device | 150 | * @rtc: the rtc device |
151 | * @num: how many irqs are being reported (usually one) | 151 | * @num: how many irqs are being reported (usually one) |
152 | * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF | 152 | * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF |
153 | * Context: in_interrupt(), irqs blocked | 153 | * Context: in_interrupt(), irqs blocked |
154 | */ | 154 | */ |
155 | void rtc_update_irq(struct class_device *class_dev, | 155 | void rtc_update_irq(struct rtc_device *rtc, |
156 | unsigned long num, unsigned long events) | 156 | unsigned long num, unsigned long events) |
157 | { | 157 | { |
158 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
159 | |||
160 | spin_lock(&rtc->irq_lock); | 158 | spin_lock(&rtc->irq_lock); |
161 | rtc->irq_data = (rtc->irq_data + (num << 8)) | events; | 159 | rtc->irq_data = (rtc->irq_data + (num << 8)) | events; |
162 | spin_unlock(&rtc->irq_lock); | 160 | spin_unlock(&rtc->irq_lock); |
@@ -171,40 +169,43 @@ void rtc_update_irq(struct class_device *class_dev, | |||
171 | } | 169 | } |
172 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 170 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
173 | 171 | ||
174 | struct class_device *rtc_class_open(char *name) | 172 | struct rtc_device *rtc_class_open(char *name) |
175 | { | 173 | { |
176 | struct class_device *class_dev = NULL, | 174 | struct device *dev; |
177 | *class_dev_tmp; | 175 | struct rtc_device *rtc = NULL; |
178 | 176 | ||
179 | down(&rtc_class->sem); | 177 | down(&rtc_class->sem); |
180 | list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { | 178 | list_for_each_entry(dev, &rtc_class->devices, node) { |
181 | if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { | 179 | if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) { |
182 | class_dev = class_device_get(class_dev_tmp); | 180 | dev = get_device(dev); |
181 | if (dev) | ||
182 | rtc = to_rtc_device(dev); | ||
183 | break; | 183 | break; |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | if (class_dev) { | 187 | if (rtc) { |
188 | if (!try_module_get(to_rtc_device(class_dev)->owner)) | 188 | if (!try_module_get(rtc->owner)) { |
189 | class_dev = NULL; | 189 | put_device(dev); |
190 | rtc = NULL; | ||
191 | } | ||
190 | } | 192 | } |
191 | up(&rtc_class->sem); | 193 | up(&rtc_class->sem); |
192 | 194 | ||
193 | return class_dev; | 195 | return rtc; |
194 | } | 196 | } |
195 | EXPORT_SYMBOL_GPL(rtc_class_open); | 197 | EXPORT_SYMBOL_GPL(rtc_class_open); |
196 | 198 | ||
197 | void rtc_class_close(struct class_device *class_dev) | 199 | void rtc_class_close(struct rtc_device *rtc) |
198 | { | 200 | { |
199 | module_put(to_rtc_device(class_dev)->owner); | 201 | module_put(rtc->owner); |
200 | class_device_put(class_dev); | 202 | put_device(&rtc->dev); |
201 | } | 203 | } |
202 | EXPORT_SYMBOL_GPL(rtc_class_close); | 204 | EXPORT_SYMBOL_GPL(rtc_class_close); |
203 | 205 | ||
204 | int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) | 206 | int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) |
205 | { | 207 | { |
206 | int retval = -EBUSY; | 208 | int retval = -EBUSY; |
207 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
208 | 209 | ||
209 | if (task == NULL || task->func == NULL) | 210 | if (task == NULL || task->func == NULL) |
210 | return -EINVAL; | 211 | return -EINVAL; |
@@ -220,9 +221,8 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) | |||
220 | } | 221 | } |
221 | EXPORT_SYMBOL_GPL(rtc_irq_register); | 222 | EXPORT_SYMBOL_GPL(rtc_irq_register); |
222 | 223 | ||
223 | void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) | 224 | void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) |
224 | { | 225 | { |
225 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
226 | 226 | ||
227 | spin_lock_irq(&rtc->irq_task_lock); | 227 | spin_lock_irq(&rtc->irq_task_lock); |
228 | if (rtc->irq_task == task) | 228 | if (rtc->irq_task == task) |
@@ -231,11 +231,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) | |||
231 | } | 231 | } |
232 | EXPORT_SYMBOL_GPL(rtc_irq_unregister); | 232 | EXPORT_SYMBOL_GPL(rtc_irq_unregister); |
233 | 233 | ||
234 | int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) | 234 | int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled) |
235 | { | 235 | { |
236 | int err = 0; | 236 | int err = 0; |
237 | unsigned long flags; | 237 | unsigned long flags; |
238 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
239 | 238 | ||
240 | if (rtc->ops->irq_set_state == NULL) | 239 | if (rtc->ops->irq_set_state == NULL) |
241 | return -ENXIO; | 240 | return -ENXIO; |
@@ -246,17 +245,16 @@ int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int | |||
246 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | 245 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
247 | 246 | ||
248 | if (err == 0) | 247 | if (err == 0) |
249 | err = rtc->ops->irq_set_state(class_dev->dev, enabled); | 248 | err = rtc->ops->irq_set_state(rtc->dev.parent, enabled); |
250 | 249 | ||
251 | return err; | 250 | return err; |
252 | } | 251 | } |
253 | EXPORT_SYMBOL_GPL(rtc_irq_set_state); | 252 | EXPORT_SYMBOL_GPL(rtc_irq_set_state); |
254 | 253 | ||
255 | int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) | 254 | int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) |
256 | { | 255 | { |
257 | int err = 0; | 256 | int err = 0; |
258 | unsigned long flags; | 257 | unsigned long flags; |
259 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
260 | 258 | ||
261 | if (rtc->ops->irq_set_freq == NULL) | 259 | if (rtc->ops->irq_set_freq == NULL) |
262 | return -ENXIO; | 260 | return -ENXIO; |
@@ -267,7 +265,7 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int | |||
267 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | 265 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); |
268 | 266 | ||
269 | if (err == 0) { | 267 | if (err == 0) { |
270 | err = rtc->ops->irq_set_freq(class_dev->dev, freq); | 268 | err = rtc->ops->irq_set_freq(rtc->dev.parent, freq); |
271 | if (err == 0) | 269 | if (err == 0) |
272 | rtc->irq_freq = freq; | 270 | rtc->irq_freq = freq; |
273 | } | 271 | } |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index ac0e68e2f025..33795e5a5595 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -263,7 +263,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) | |||
263 | 263 | ||
264 | at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ | 264 | at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ |
265 | 265 | ||
266 | rtc_update_irq(&rtc->class_dev, 1, events); | 266 | rtc_update_irq(rtc, 1, events); |
267 | 267 | ||
268 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, | 268 | pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, |
269 | events >> 8, events & 0x000000FF); | 269 | events >> 8, events & 0x000000FF); |
@@ -348,21 +348,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) | |||
348 | 348 | ||
349 | /* AT91RM9200 RTC Power management control */ | 349 | /* AT91RM9200 RTC Power management control */ |
350 | 350 | ||
351 | static struct timespec at91_rtc_delta; | ||
352 | static u32 at91_rtc_imr; | 351 | static u32 at91_rtc_imr; |
353 | 352 | ||
354 | static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 353 | static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
355 | { | 354 | { |
356 | struct rtc_time tm; | ||
357 | struct timespec time; | ||
358 | |||
359 | time.tv_nsec = 0; | ||
360 | |||
361 | /* calculate time delta for suspend */ | ||
362 | at91_rtc_readtime(&pdev->dev, &tm); | ||
363 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
364 | save_time_delta(&at91_rtc_delta, &time); | ||
365 | |||
366 | /* this IRQ is shared with DBGU and other hardware which isn't | 355 | /* this IRQ is shared with DBGU and other hardware which isn't |
367 | * necessarily doing PM like we are... | 356 | * necessarily doing PM like we are... |
368 | */ | 357 | */ |
@@ -374,36 +363,17 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
374 | else | 363 | else |
375 | at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); | 364 | at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); |
376 | } | 365 | } |
377 | |||
378 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | ||
379 | 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, | ||
380 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
381 | |||
382 | return 0; | 366 | return 0; |
383 | } | 367 | } |
384 | 368 | ||
385 | static int at91_rtc_resume(struct platform_device *pdev) | 369 | static int at91_rtc_resume(struct platform_device *pdev) |
386 | { | 370 | { |
387 | struct rtc_time tm; | ||
388 | struct timespec time; | ||
389 | |||
390 | time.tv_nsec = 0; | ||
391 | |||
392 | at91_rtc_readtime(&pdev->dev, &tm); | ||
393 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
394 | restore_time_delta(&at91_rtc_delta, &time); | ||
395 | |||
396 | if (at91_rtc_imr) { | 371 | if (at91_rtc_imr) { |
397 | if (device_may_wakeup(&pdev->dev)) | 372 | if (device_may_wakeup(&pdev->dev)) |
398 | disable_irq_wake(AT91_ID_SYS); | 373 | disable_irq_wake(AT91_ID_SYS); |
399 | else | 374 | else |
400 | at91_sys_write(AT91_RTC_IER, at91_rtc_imr); | 375 | at91_sys_write(AT91_RTC_IER, at91_rtc_imr); |
401 | } | 376 | } |
402 | |||
403 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | ||
404 | 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, | ||
405 | tm.tm_hour, tm.tm_min, tm.tm_sec); | ||
406 | |||
407 | return 0; | 377 | return 0; |
408 | } | 378 | } |
409 | #else | 379 | #else |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 7c0d60910077..6085261aa2c1 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -46,6 +46,10 @@ struct cmos_rtc { | |||
46 | int irq; | 46 | int irq; |
47 | struct resource *iomem; | 47 | struct resource *iomem; |
48 | 48 | ||
49 | void (*wake_on)(struct device *); | ||
50 | void (*wake_off)(struct device *); | ||
51 | |||
52 | u8 enabled_wake; | ||
49 | u8 suspend_ctrl; | 53 | u8 suspend_ctrl; |
50 | 54 | ||
51 | /* newer hardware extends the original register set */ | 55 | /* newer hardware extends the original register set */ |
@@ -203,7 +207,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
203 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 207 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
204 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 208 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
205 | if (is_intr(rtc_intr)) | 209 | if (is_intr(rtc_intr)) |
206 | rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); | 210 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
207 | 211 | ||
208 | /* update alarm */ | 212 | /* update alarm */ |
209 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); | 213 | CMOS_WRITE(hrs, RTC_HOURS_ALARM); |
@@ -223,7 +227,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
223 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 227 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
224 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 228 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
225 | if (is_intr(rtc_intr)) | 229 | if (is_intr(rtc_intr)) |
226 | rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); | 230 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
227 | } | 231 | } |
228 | 232 | ||
229 | spin_unlock_irq(&rtc_lock); | 233 | spin_unlock_irq(&rtc_lock); |
@@ -304,7 +308,7 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
304 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 308 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
305 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 309 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
306 | if (is_intr(rtc_intr)) | 310 | if (is_intr(rtc_intr)) |
307 | rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); | 311 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
308 | spin_unlock_irqrestore(&rtc_lock, flags); | 312 | spin_unlock_irqrestore(&rtc_lock, flags); |
309 | return 0; | 313 | return 0; |
310 | } | 314 | } |
@@ -379,12 +383,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
379 | return IRQ_NONE; | 383 | return IRQ_NONE; |
380 | } | 384 | } |
381 | 385 | ||
382 | #ifdef CONFIG_PNPACPI | 386 | #ifdef CONFIG_PNP |
383 | #define is_pnpacpi() 1 | 387 | #define is_pnp() 1 |
384 | #define INITSECTION | 388 | #define INITSECTION |
385 | 389 | ||
386 | #else | 390 | #else |
387 | #define is_pnpacpi() 0 | 391 | #define is_pnp() 0 |
388 | #define INITSECTION __init | 392 | #define INITSECTION __init |
389 | #endif | 393 | #endif |
390 | 394 | ||
@@ -405,13 +409,20 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
405 | cmos_rtc.irq = rtc_irq; | 409 | cmos_rtc.irq = rtc_irq; |
406 | cmos_rtc.iomem = ports; | 410 | cmos_rtc.iomem = ports; |
407 | 411 | ||
408 | /* For ACPI systems the info comes from the FADT. On others, | 412 | /* For ACPI systems extension info comes from the FADT. On others, |
409 | * board specific setup provides it as appropriate. | 413 | * board specific setup provides it as appropriate. Systems where |
414 | * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and | ||
415 | * some almost-clones) can provide hooks to make that behave. | ||
410 | */ | 416 | */ |
411 | if (info) { | 417 | if (info) { |
412 | cmos_rtc.day_alrm = info->rtc_day_alarm; | 418 | cmos_rtc.day_alrm = info->rtc_day_alarm; |
413 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; | 419 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; |
414 | cmos_rtc.century = info->rtc_century; | 420 | cmos_rtc.century = info->rtc_century; |
421 | |||
422 | if (info->wake_on && info->wake_off) { | ||
423 | cmos_rtc.wake_on = info->wake_on; | ||
424 | cmos_rtc.wake_off = info->wake_off; | ||
425 | } | ||
415 | } | 426 | } |
416 | 427 | ||
417 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, | 428 | cmos_rtc.rtc = rtc_device_register(driver_name, dev, |
@@ -427,14 +438,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
427 | * REVISIT for non-x86 systems we may need to handle io memory | 438 | * REVISIT for non-x86 systems we may need to handle io memory |
428 | * resources: ioremap them, and request_mem_region(). | 439 | * resources: ioremap them, and request_mem_region(). |
429 | */ | 440 | */ |
430 | if (is_pnpacpi()) { | 441 | if (is_pnp()) { |
431 | retval = request_resource(&ioport_resource, ports); | 442 | retval = request_resource(&ioport_resource, ports); |
432 | if (retval < 0) { | 443 | if (retval < 0) { |
433 | dev_dbg(dev, "i/o registers already in use\n"); | 444 | dev_dbg(dev, "i/o registers already in use\n"); |
434 | goto cleanup0; | 445 | goto cleanup0; |
435 | } | 446 | } |
436 | } | 447 | } |
437 | rename_region(ports, cmos_rtc.rtc->class_dev.class_id); | 448 | rename_region(ports, cmos_rtc.rtc->dev.bus_id); |
438 | 449 | ||
439 | spin_lock_irq(&rtc_lock); | 450 | spin_lock_irq(&rtc_lock); |
440 | 451 | ||
@@ -470,8 +481,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
470 | 481 | ||
471 | if (is_valid_irq(rtc_irq)) | 482 | if (is_valid_irq(rtc_irq)) |
472 | retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, | 483 | retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, |
473 | cmos_rtc.rtc->class_dev.class_id, | 484 | cmos_rtc.rtc->dev.bus_id, |
474 | &cmos_rtc.rtc->class_dev); | 485 | cmos_rtc.rtc); |
475 | if (retval < 0) { | 486 | if (retval < 0) { |
476 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 487 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
477 | goto cleanup1; | 488 | goto cleanup1; |
@@ -483,7 +494,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
483 | */ | 494 | */ |
484 | 495 | ||
485 | pr_info("%s: alarms up to one %s%s\n", | 496 | pr_info("%s: alarms up to one %s%s\n", |
486 | cmos_rtc.rtc->class_dev.class_id, | 497 | cmos_rtc.rtc->dev.bus_id, |
487 | is_valid_irq(rtc_irq) | 498 | is_valid_irq(rtc_irq) |
488 | ? (cmos_rtc.mon_alrm | 499 | ? (cmos_rtc.mon_alrm |
489 | ? "year" | 500 | ? "year" |
@@ -520,12 +531,12 @@ static void __exit cmos_do_remove(struct device *dev) | |||
520 | 531 | ||
521 | cmos_do_shutdown(); | 532 | cmos_do_shutdown(); |
522 | 533 | ||
523 | if (is_pnpacpi()) | 534 | if (is_pnp()) |
524 | release_resource(cmos->iomem); | 535 | release_resource(cmos->iomem); |
525 | rename_region(cmos->iomem, NULL); | 536 | rename_region(cmos->iomem, NULL); |
526 | 537 | ||
527 | if (is_valid_irq(cmos->irq)) | 538 | if (is_valid_irq(cmos->irq)) |
528 | free_irq(cmos->irq, &cmos_rtc.rtc->class_dev); | 539 | free_irq(cmos->irq, cmos_rtc.rtc); |
529 | 540 | ||
530 | rtc_device_unregister(cmos_rtc.rtc); | 541 | rtc_device_unregister(cmos_rtc.rtc); |
531 | 542 | ||
@@ -555,16 +566,20 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
555 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | 566 | irqstat = CMOS_READ(RTC_INTR_FLAGS); |
556 | irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; | 567 | irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; |
557 | if (is_intr(irqstat)) | 568 | if (is_intr(irqstat)) |
558 | rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat); | 569 | rtc_update_irq(cmos->rtc, 1, irqstat); |
559 | } | 570 | } |
560 | spin_unlock_irq(&rtc_lock); | 571 | spin_unlock_irq(&rtc_lock); |
561 | 572 | ||
562 | /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE) | 573 | if (tmp & RTC_AIE) { |
563 | * ... it'd be best if we could do that under rtc_lock. | 574 | cmos->enabled_wake = 1; |
564 | */ | 575 | if (cmos->wake_on) |
576 | cmos->wake_on(dev); | ||
577 | else | ||
578 | enable_irq_wake(cmos->irq); | ||
579 | } | ||
565 | 580 | ||
566 | pr_debug("%s: suspend%s, ctrl %02x\n", | 581 | pr_debug("%s: suspend%s, ctrl %02x\n", |
567 | cmos_rtc.rtc->class_dev.class_id, | 582 | cmos_rtc.rtc->dev.bus_id, |
568 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 583 | (tmp & RTC_AIE) ? ", alarm may wake" : "", |
569 | tmp); | 584 | tmp); |
570 | 585 | ||
@@ -576,26 +591,28 @@ static int cmos_resume(struct device *dev) | |||
576 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 591 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
577 | unsigned char tmp = cmos->suspend_ctrl; | 592 | unsigned char tmp = cmos->suspend_ctrl; |
578 | 593 | ||
579 | /* REVISIT: a mechanism to resync the system clock (jiffies) | ||
580 | * on resume should be portable between platforms ... | ||
581 | */ | ||
582 | |||
583 | /* re-enable any irqs previously active */ | 594 | /* re-enable any irqs previously active */ |
584 | if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { | 595 | if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { |
585 | 596 | ||
586 | /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */ | 597 | if (cmos->enabled_wake) { |
598 | if (cmos->wake_off) | ||
599 | cmos->wake_off(dev); | ||
600 | else | ||
601 | disable_irq_wake(cmos->irq); | ||
602 | cmos->enabled_wake = 0; | ||
603 | } | ||
587 | 604 | ||
588 | spin_lock_irq(&rtc_lock); | 605 | spin_lock_irq(&rtc_lock); |
589 | CMOS_WRITE(tmp, RTC_CONTROL); | 606 | CMOS_WRITE(tmp, RTC_CONTROL); |
590 | tmp = CMOS_READ(RTC_INTR_FLAGS); | 607 | tmp = CMOS_READ(RTC_INTR_FLAGS); |
591 | tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; | 608 | tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; |
592 | if (is_intr(tmp)) | 609 | if (is_intr(tmp)) |
593 | rtc_update_irq(&cmos->rtc->class_dev, 1, tmp); | 610 | rtc_update_irq(cmos->rtc, 1, tmp); |
594 | spin_unlock_irq(&rtc_lock); | 611 | spin_unlock_irq(&rtc_lock); |
595 | } | 612 | } |
596 | 613 | ||
597 | pr_debug("%s: resume, ctrl %02x\n", | 614 | pr_debug("%s: resume, ctrl %02x\n", |
598 | cmos_rtc.rtc->class_dev.class_id, | 615 | cmos_rtc.rtc->dev.bus_id, |
599 | cmos->suspend_ctrl); | 616 | cmos->suspend_ctrl); |
600 | 617 | ||
601 | 618 | ||
@@ -613,7 +630,7 @@ static int cmos_resume(struct device *dev) | |||
613 | * the device node will always be created as a PNPACPI device. | 630 | * the device node will always be created as a PNPACPI device. |
614 | */ | 631 | */ |
615 | 632 | ||
616 | #ifdef CONFIG_PNPACPI | 633 | #ifdef CONFIG_PNP |
617 | 634 | ||
618 | #include <linux/pnp.h> | 635 | #include <linux/pnp.h> |
619 | 636 | ||
@@ -684,11 +701,11 @@ static void __exit cmos_exit(void) | |||
684 | } | 701 | } |
685 | module_exit(cmos_exit); | 702 | module_exit(cmos_exit); |
686 | 703 | ||
687 | #else /* no PNPACPI */ | 704 | #else /* no PNP */ |
688 | 705 | ||
689 | /*----------------------------------------------------------------*/ | 706 | /*----------------------------------------------------------------*/ |
690 | 707 | ||
691 | /* Platform setup should have set up an RTC device, when PNPACPI is | 708 | /* Platform setup should have set up an RTC device, when PNP is |
692 | * unavailable ... this could happen even on (older) PCs. | 709 | * unavailable ... this could happen even on (older) PCs. |
693 | */ | 710 | */ |
694 | 711 | ||
@@ -734,7 +751,7 @@ static void __exit cmos_exit(void) | |||
734 | module_exit(cmos_exit); | 751 | module_exit(cmos_exit); |
735 | 752 | ||
736 | 753 | ||
737 | #endif /* !PNPACPI */ | 754 | #endif /* !PNP */ |
738 | 755 | ||
739 | MODULE_AUTHOR("David Brownell"); | 756 | MODULE_AUTHOR("David Brownell"); |
740 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); | 757 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); |
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h new file mode 100644 index 000000000000..5f9df7430a22 --- /dev/null +++ b/drivers/rtc/rtc-core.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifdef CONFIG_RTC_INTF_DEV | ||
2 | |||
3 | extern void __init rtc_dev_init(void); | ||
4 | extern void __exit rtc_dev_exit(void); | ||
5 | extern void rtc_dev_prepare(struct rtc_device *rtc); | ||
6 | extern void rtc_dev_add_device(struct rtc_device *rtc); | ||
7 | extern void rtc_dev_del_device(struct rtc_device *rtc); | ||
8 | |||
9 | #else | ||
10 | |||
11 | static inline void rtc_dev_init(void) | ||
12 | { | ||
13 | } | ||
14 | |||
15 | static inline void rtc_dev_exit(void) | ||
16 | { | ||
17 | } | ||
18 | |||
19 | static inline void rtc_dev_prepare(struct rtc_device *rtc) | ||
20 | { | ||
21 | } | ||
22 | |||
23 | static inline void rtc_dev_add_device(struct rtc_device *rtc) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | static inline void rtc_dev_del_device(struct rtc_device *rtc) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | #endif | ||
32 | |||
33 | #ifdef CONFIG_RTC_INTF_PROC | ||
34 | |||
35 | extern void rtc_proc_add_device(struct rtc_device *rtc); | ||
36 | extern void rtc_proc_del_device(struct rtc_device *rtc); | ||
37 | |||
38 | #else | ||
39 | |||
40 | static inline void rtc_proc_add_device(struct rtc_device *rtc) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | static inline void rtc_proc_del_device(struct rtc_device *rtc) | ||
45 | { | ||
46 | } | ||
47 | |||
48 | #endif | ||
49 | |||
50 | #ifdef CONFIG_RTC_INTF_SYSFS | ||
51 | |||
52 | extern void __init rtc_sysfs_init(struct class *); | ||
53 | extern void rtc_sysfs_add_device(struct rtc_device *rtc); | ||
54 | extern void rtc_sysfs_del_device(struct rtc_device *rtc); | ||
55 | |||
56 | #else | ||
57 | |||
58 | static inline void rtc_sysfs_init(struct class *rtc) | ||
59 | { | ||
60 | } | ||
61 | |||
62 | static inline void rtc_sysfs_add_device(struct rtc_device *rtc) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | static inline void rtc_sysfs_del_device(struct rtc_device *rtc) | ||
67 | { | ||
68 | } | ||
69 | |||
70 | #endif | ||
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 137330b8636b..f4e5f0040ff7 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -13,8 +13,8 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> |
16 | #include "rtc-core.h" | ||
16 | 17 | ||
17 | static struct class *rtc_dev_class; | ||
18 | static dev_t rtc_devt; | 18 | static dev_t rtc_devt; |
19 | 19 | ||
20 | #define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ | 20 | #define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ |
@@ -32,9 +32,9 @@ static int rtc_dev_open(struct inode *inode, struct file *file) | |||
32 | if (!(mutex_trylock(&rtc->char_lock))) | 32 | if (!(mutex_trylock(&rtc->char_lock))) |
33 | return -EBUSY; | 33 | return -EBUSY; |
34 | 34 | ||
35 | file->private_data = &rtc->class_dev; | 35 | file->private_data = rtc; |
36 | 36 | ||
37 | err = ops->open ? ops->open(rtc->class_dev.dev) : 0; | 37 | err = ops->open ? ops->open(rtc->dev.parent) : 0; |
38 | if (err == 0) { | 38 | if (err == 0) { |
39 | spin_lock_irq(&rtc->irq_lock); | 39 | spin_lock_irq(&rtc->irq_lock); |
40 | rtc->irq_data = 0; | 40 | rtc->irq_data = 0; |
@@ -61,7 +61,7 @@ static void rtc_uie_task(struct work_struct *work) | |||
61 | int num = 0; | 61 | int num = 0; |
62 | int err; | 62 | int err; |
63 | 63 | ||
64 | err = rtc_read_time(&rtc->class_dev, &tm); | 64 | err = rtc_read_time(rtc, &tm); |
65 | 65 | ||
66 | local_irq_disable(); | 66 | local_irq_disable(); |
67 | spin_lock(&rtc->irq_lock); | 67 | spin_lock(&rtc->irq_lock); |
@@ -79,7 +79,7 @@ static void rtc_uie_task(struct work_struct *work) | |||
79 | } | 79 | } |
80 | spin_unlock(&rtc->irq_lock); | 80 | spin_unlock(&rtc->irq_lock); |
81 | if (num) | 81 | if (num) |
82 | rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); | 82 | rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); |
83 | local_irq_enable(); | 83 | local_irq_enable(); |
84 | } | 84 | } |
85 | static void rtc_uie_timer(unsigned long data) | 85 | static void rtc_uie_timer(unsigned long data) |
@@ -121,7 +121,7 @@ static int set_uie(struct rtc_device *rtc) | |||
121 | struct rtc_time tm; | 121 | struct rtc_time tm; |
122 | int err; | 122 | int err; |
123 | 123 | ||
124 | err = rtc_read_time(&rtc->class_dev, &tm); | 124 | err = rtc_read_time(rtc, &tm); |
125 | if (err) | 125 | if (err) |
126 | return err; | 126 | return err; |
127 | spin_lock_irq(&rtc->irq_lock); | 127 | spin_lock_irq(&rtc->irq_lock); |
@@ -180,7 +180,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
180 | if (ret == 0) { | 180 | if (ret == 0) { |
181 | /* Check for any data updates */ | 181 | /* Check for any data updates */ |
182 | if (rtc->ops->read_callback) | 182 | if (rtc->ops->read_callback) |
183 | data = rtc->ops->read_callback(rtc->class_dev.dev, | 183 | data = rtc->ops->read_callback(rtc->dev.parent, |
184 | data); | 184 | data); |
185 | 185 | ||
186 | if (sizeof(int) != sizeof(long) && | 186 | if (sizeof(int) != sizeof(long) && |
@@ -210,8 +210,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
210 | unsigned int cmd, unsigned long arg) | 210 | unsigned int cmd, unsigned long arg) |
211 | { | 211 | { |
212 | int err = 0; | 212 | int err = 0; |
213 | struct class_device *class_dev = file->private_data; | 213 | struct rtc_device *rtc = file->private_data; |
214 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
215 | const struct rtc_class_ops *ops = rtc->ops; | 214 | const struct rtc_class_ops *ops = rtc->ops; |
216 | struct rtc_time tm; | 215 | struct rtc_time tm; |
217 | struct rtc_wkalrm alarm; | 216 | struct rtc_wkalrm alarm; |
@@ -252,7 +251,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
252 | 251 | ||
253 | /* try the driver's ioctl interface */ | 252 | /* try the driver's ioctl interface */ |
254 | if (ops->ioctl) { | 253 | if (ops->ioctl) { |
255 | err = ops->ioctl(class_dev->dev, cmd, arg); | 254 | err = ops->ioctl(rtc->dev.parent, cmd, arg); |
256 | if (err != -ENOIOCTLCMD) | 255 | if (err != -ENOIOCTLCMD) |
257 | return err; | 256 | return err; |
258 | } | 257 | } |
@@ -264,7 +263,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
264 | 263 | ||
265 | switch (cmd) { | 264 | switch (cmd) { |
266 | case RTC_ALM_READ: | 265 | case RTC_ALM_READ: |
267 | err = rtc_read_alarm(class_dev, &alarm); | 266 | err = rtc_read_alarm(rtc, &alarm); |
268 | if (err < 0) | 267 | if (err < 0) |
269 | return err; | 268 | return err; |
270 | 269 | ||
@@ -278,17 +277,53 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
278 | 277 | ||
279 | alarm.enabled = 0; | 278 | alarm.enabled = 0; |
280 | alarm.pending = 0; | 279 | alarm.pending = 0; |
281 | alarm.time.tm_mday = -1; | ||
282 | alarm.time.tm_mon = -1; | ||
283 | alarm.time.tm_year = -1; | ||
284 | alarm.time.tm_wday = -1; | 280 | alarm.time.tm_wday = -1; |
285 | alarm.time.tm_yday = -1; | 281 | alarm.time.tm_yday = -1; |
286 | alarm.time.tm_isdst = -1; | 282 | alarm.time.tm_isdst = -1; |
287 | err = rtc_set_alarm(class_dev, &alarm); | 283 | |
284 | /* RTC_ALM_SET alarms may be up to 24 hours in the future. | ||
285 | * Rather than expecting every RTC to implement "don't care" | ||
286 | * for day/month/year fields, just force the alarm to have | ||
287 | * the right values for those fields. | ||
288 | * | ||
289 | * RTC_WKALM_SET should be used instead. Not only does it | ||
290 | * eliminate the need for a separate RTC_AIE_ON call, it | ||
291 | * doesn't have the "alarm 23:59:59 in the future" race. | ||
292 | * | ||
293 | * NOTE: some legacy code may have used invalid fields as | ||
294 | * wildcards, exposing hardware "periodic alarm" capabilities. | ||
295 | * Not supported here. | ||
296 | */ | ||
297 | { | ||
298 | unsigned long now, then; | ||
299 | |||
300 | err = rtc_read_time(rtc, &tm); | ||
301 | if (err < 0) | ||
302 | return err; | ||
303 | rtc_tm_to_time(&tm, &now); | ||
304 | |||
305 | alarm.time.tm_mday = tm.tm_mday; | ||
306 | alarm.time.tm_mon = tm.tm_mon; | ||
307 | alarm.time.tm_year = tm.tm_year; | ||
308 | err = rtc_valid_tm(&alarm.time); | ||
309 | if (err < 0) | ||
310 | return err; | ||
311 | rtc_tm_to_time(&alarm.time, &then); | ||
312 | |||
313 | /* alarm may need to wrap into tomorrow */ | ||
314 | if (then < now) { | ||
315 | rtc_time_to_tm(now + 24 * 60 * 60, &tm); | ||
316 | alarm.time.tm_mday = tm.tm_mday; | ||
317 | alarm.time.tm_mon = tm.tm_mon; | ||
318 | alarm.time.tm_year = tm.tm_year; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | err = rtc_set_alarm(rtc, &alarm); | ||
288 | break; | 323 | break; |
289 | 324 | ||
290 | case RTC_RD_TIME: | 325 | case RTC_RD_TIME: |
291 | err = rtc_read_time(class_dev, &tm); | 326 | err = rtc_read_time(rtc, &tm); |
292 | if (err < 0) | 327 | if (err < 0) |
293 | return err; | 328 | return err; |
294 | 329 | ||
@@ -300,7 +335,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
300 | if (copy_from_user(&tm, uarg, sizeof(tm))) | 335 | if (copy_from_user(&tm, uarg, sizeof(tm))) |
301 | return -EFAULT; | 336 | return -EFAULT; |
302 | 337 | ||
303 | err = rtc_set_time(class_dev, &tm); | 338 | err = rtc_set_time(rtc, &tm); |
304 | break; | 339 | break; |
305 | 340 | ||
306 | case RTC_IRQP_READ: | 341 | case RTC_IRQP_READ: |
@@ -310,7 +345,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
310 | 345 | ||
311 | case RTC_IRQP_SET: | 346 | case RTC_IRQP_SET: |
312 | if (ops->irq_set_freq) | 347 | if (ops->irq_set_freq) |
313 | err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg); | 348 | err = rtc_irq_set_freq(rtc, rtc->irq_task, arg); |
314 | break; | 349 | break; |
315 | 350 | ||
316 | #if 0 | 351 | #if 0 |
@@ -336,11 +371,11 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
336 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) | 371 | if (copy_from_user(&alarm, uarg, sizeof(alarm))) |
337 | return -EFAULT; | 372 | return -EFAULT; |
338 | 373 | ||
339 | err = rtc_set_alarm(class_dev, &alarm); | 374 | err = rtc_set_alarm(rtc, &alarm); |
340 | break; | 375 | break; |
341 | 376 | ||
342 | case RTC_WKALM_RD: | 377 | case RTC_WKALM_RD: |
343 | err = rtc_read_alarm(class_dev, &alarm); | 378 | err = rtc_read_alarm(rtc, &alarm); |
344 | if (err < 0) | 379 | if (err < 0) |
345 | return err; | 380 | return err; |
346 | 381 | ||
@@ -372,7 +407,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
372 | clear_uie(rtc); | 407 | clear_uie(rtc); |
373 | #endif | 408 | #endif |
374 | if (rtc->ops->release) | 409 | if (rtc->ops->release) |
375 | rtc->ops->release(rtc->class_dev.dev); | 410 | rtc->ops->release(rtc->dev.parent); |
376 | 411 | ||
377 | mutex_unlock(&rtc->char_lock); | 412 | mutex_unlock(&rtc->char_lock); |
378 | return 0; | 413 | return 0; |
@@ -397,17 +432,18 @@ static const struct file_operations rtc_dev_fops = { | |||
397 | 432 | ||
398 | /* insertion/removal hooks */ | 433 | /* insertion/removal hooks */ |
399 | 434 | ||
400 | static int rtc_dev_add_device(struct class_device *class_dev, | 435 | void rtc_dev_prepare(struct rtc_device *rtc) |
401 | struct class_interface *class_intf) | ||
402 | { | 436 | { |
403 | int err = 0; | 437 | if (!rtc_devt) |
404 | struct rtc_device *rtc = to_rtc_device(class_dev); | 438 | return; |
405 | 439 | ||
406 | if (rtc->id >= RTC_DEV_MAX) { | 440 | if (rtc->id >= RTC_DEV_MAX) { |
407 | dev_err(class_dev->dev, "too many RTCs\n"); | 441 | pr_debug("%s: too many RTC devices\n", rtc->name); |
408 | return -EINVAL; | 442 | return; |
409 | } | 443 | } |
410 | 444 | ||
445 | rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); | ||
446 | |||
411 | mutex_init(&rtc->char_lock); | 447 | mutex_init(&rtc->char_lock); |
412 | spin_lock_init(&rtc->irq_lock); | 448 | spin_lock_init(&rtc->irq_lock); |
413 | init_waitqueue_head(&rtc->irq_queue); | 449 | init_waitqueue_head(&rtc->irq_queue); |
@@ -418,100 +454,36 @@ static int rtc_dev_add_device(struct class_device *class_dev, | |||
418 | 454 | ||
419 | cdev_init(&rtc->char_dev, &rtc_dev_fops); | 455 | cdev_init(&rtc->char_dev, &rtc_dev_fops); |
420 | rtc->char_dev.owner = rtc->owner; | 456 | rtc->char_dev.owner = rtc->owner; |
457 | } | ||
421 | 458 | ||
422 | if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { | 459 | void rtc_dev_add_device(struct rtc_device *rtc) |
423 | dev_err(class_dev->dev, | 460 | { |
424 | "failed to add char device %d:%d\n", | 461 | if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) |
462 | printk(KERN_WARNING "%s: failed to add char device %d:%d\n", | ||
463 | rtc->name, MAJOR(rtc_devt), rtc->id); | ||
464 | else | ||
465 | pr_debug("%s: dev (%d:%d)\n", rtc->name, | ||
425 | MAJOR(rtc_devt), rtc->id); | 466 | MAJOR(rtc_devt), rtc->id); |
426 | return -ENODEV; | ||
427 | } | ||
428 | |||
429 | rtc->rtc_dev = class_device_create(rtc_dev_class, NULL, | ||
430 | MKDEV(MAJOR(rtc_devt), rtc->id), | ||
431 | class_dev->dev, "rtc%d", rtc->id); | ||
432 | if (IS_ERR(rtc->rtc_dev)) { | ||
433 | dev_err(class_dev->dev, "cannot create rtc_dev device\n"); | ||
434 | err = PTR_ERR(rtc->rtc_dev); | ||
435 | goto err_cdev_del; | ||
436 | } | ||
437 | |||
438 | dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n", | ||
439 | MAJOR(rtc->rtc_dev->devt), | ||
440 | MINOR(rtc->rtc_dev->devt)); | ||
441 | |||
442 | return 0; | ||
443 | |||
444 | err_cdev_del: | ||
445 | |||
446 | cdev_del(&rtc->char_dev); | ||
447 | return err; | ||
448 | } | 467 | } |
449 | 468 | ||
450 | static void rtc_dev_remove_device(struct class_device *class_dev, | 469 | void rtc_dev_del_device(struct rtc_device *rtc) |
451 | struct class_interface *class_intf) | ||
452 | { | 470 | { |
453 | struct rtc_device *rtc = to_rtc_device(class_dev); | 471 | if (rtc->dev.devt) |
454 | |||
455 | if (rtc->rtc_dev) { | ||
456 | dev_dbg(class_dev->dev, "removing char %d:%d\n", | ||
457 | MAJOR(rtc->rtc_dev->devt), | ||
458 | MINOR(rtc->rtc_dev->devt)); | ||
459 | |||
460 | class_device_unregister(rtc->rtc_dev); | ||
461 | cdev_del(&rtc->char_dev); | 472 | cdev_del(&rtc->char_dev); |
462 | } | ||
463 | } | 473 | } |
464 | 474 | ||
465 | /* interface registration */ | 475 | void __init rtc_dev_init(void) |
466 | |||
467 | static struct class_interface rtc_dev_interface = { | ||
468 | .add = &rtc_dev_add_device, | ||
469 | .remove = &rtc_dev_remove_device, | ||
470 | }; | ||
471 | |||
472 | static int __init rtc_dev_init(void) | ||
473 | { | 476 | { |
474 | int err; | 477 | int err; |
475 | 478 | ||
476 | rtc_dev_class = class_create(THIS_MODULE, "rtc-dev"); | ||
477 | if (IS_ERR(rtc_dev_class)) | ||
478 | return PTR_ERR(rtc_dev_class); | ||
479 | |||
480 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); | 479 | err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); |
481 | if (err < 0) { | 480 | if (err < 0) |
482 | printk(KERN_ERR "%s: failed to allocate char dev region\n", | 481 | printk(KERN_ERR "%s: failed to allocate char dev region\n", |
483 | __FILE__); | 482 | __FILE__); |
484 | goto err_destroy_class; | ||
485 | } | ||
486 | |||
487 | err = rtc_interface_register(&rtc_dev_interface); | ||
488 | if (err < 0) { | ||
489 | printk(KERN_ERR "%s: failed to register the interface\n", | ||
490 | __FILE__); | ||
491 | goto err_unregister_chrdev; | ||
492 | } | ||
493 | |||
494 | return 0; | ||
495 | |||
496 | err_unregister_chrdev: | ||
497 | unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); | ||
498 | |||
499 | err_destroy_class: | ||
500 | class_destroy(rtc_dev_class); | ||
501 | |||
502 | return err; | ||
503 | } | 483 | } |
504 | 484 | ||
505 | static void __exit rtc_dev_exit(void) | 485 | void __exit rtc_dev_exit(void) |
506 | { | 486 | { |
507 | class_interface_unregister(&rtc_dev_interface); | 487 | if (rtc_devt) |
508 | class_destroy(rtc_dev_class); | 488 | unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); |
509 | unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); | ||
510 | } | 489 | } |
511 | |||
512 | subsys_initcall(rtc_dev_init); | ||
513 | module_exit(rtc_dev_exit); | ||
514 | |||
515 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | ||
516 | MODULE_DESCRIPTION("RTC class dev interface"); | ||
517 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index e27176c0e18f..afa64c7fa2e2 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -203,7 +203,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) | |||
203 | events |= RTC_UF; | 203 | events |= RTC_UF; |
204 | else | 204 | else |
205 | events |= RTC_AF; | 205 | events |= RTC_AF; |
206 | rtc_update_irq(&pdata->rtc->class_dev, 1, events); | 206 | rtc_update_irq(pdata->rtc, 1, events); |
207 | return IRQ_HANDLED; | 207 | return IRQ_HANDLED; |
208 | } | 208 | } |
209 | 209 | ||
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 7bbc26a34bd2..ba795a4db1e9 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c | |||
@@ -117,85 +117,4 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) | |||
117 | } | 117 | } |
118 | EXPORT_SYMBOL(rtc_tm_to_time); | 118 | EXPORT_SYMBOL(rtc_tm_to_time); |
119 | 119 | ||
120 | |||
121 | /* Merge the valid (i.e. non-negative) fields of alarm into the current | ||
122 | * time. If the valid alarm fields are earlier than the equivalent | ||
123 | * fields in the time, carry one into the least significant invalid | ||
124 | * field, so that the alarm expiry is in the future. It assumes that the | ||
125 | * least significant invalid field is more significant than the most | ||
126 | * significant valid field, and that the seconds field is valid. | ||
127 | * | ||
128 | * This is used by alarms that take relative (rather than absolute) | ||
129 | * times, and/or have a simple binary second counter instead of | ||
130 | * day/hour/minute/sec registers. | ||
131 | */ | ||
132 | void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm) | ||
133 | { | ||
134 | int *alarmp = &alarm->tm_sec; | ||
135 | int *timep = &now->tm_sec; | ||
136 | int carry_into, i; | ||
137 | |||
138 | /* Ignore everything past the 6th element (tm_year). */ | ||
139 | for (i = 5; i > 0; i--) { | ||
140 | if (alarmp[i] < 0) | ||
141 | alarmp[i] = timep[i]; | ||
142 | else | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | /* No carry needed if all fields are valid. */ | ||
147 | if (i == 5) | ||
148 | return; | ||
149 | |||
150 | for (carry_into = i + 1; i >= 0; i--) { | ||
151 | if (alarmp[i] < timep[i]) | ||
152 | break; | ||
153 | |||
154 | if (alarmp[i] > timep[i]) | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | switch (carry_into) { | ||
159 | case 1: | ||
160 | alarm->tm_min++; | ||
161 | |||
162 | if (alarm->tm_min < 60) | ||
163 | return; | ||
164 | |||
165 | alarm->tm_min = 0; | ||
166 | /* fall-through */ | ||
167 | |||
168 | case 2: | ||
169 | alarm->tm_hour++; | ||
170 | |||
171 | if (alarm->tm_hour < 60) | ||
172 | return; | ||
173 | |||
174 | alarm->tm_hour = 0; | ||
175 | /* fall-through */ | ||
176 | |||
177 | case 3: | ||
178 | alarm->tm_mday++; | ||
179 | |||
180 | if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon]) | ||
181 | return; | ||
182 | |||
183 | alarm->tm_mday = 1; | ||
184 | /* fall-through */ | ||
185 | |||
186 | case 4: | ||
187 | alarm->tm_mon++; | ||
188 | |||
189 | if (alarm->tm_mon <= 12) | ||
190 | return; | ||
191 | |||
192 | alarm->tm_mon = 1; | ||
193 | /* fall-through */ | ||
194 | |||
195 | case 5: | ||
196 | alarm->tm_year++; | ||
197 | } | ||
198 | } | ||
199 | EXPORT_SYMBOL(rtc_merge_alarm); | ||
200 | |||
201 | MODULE_LICENSE("GPL"); | 120 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c new file mode 100644 index 000000000000..eee4ee5bb75a --- /dev/null +++ b/drivers/rtc/rtc-max6900.c | |||
@@ -0,0 +1,311 @@ | |||
1 | /* | ||
2 | * rtc class driver for the Maxim MAX6900 chip | ||
3 | * | ||
4 | * Author: Dale Farnsworth <dale@farnsworth.org> | ||
5 | * | ||
6 | * based on previously existing rtc class drivers | ||
7 | * | ||
8 | * 2007 (c) MontaVista, Software, Inc. This file is licensed under | ||
9 | * the terms of the GNU General Public License version 2. This program | ||
10 | * is licensed "as is" without any warranty of any kind, whether express | ||
11 | * or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/bcd.h> | ||
17 | #include <linux/rtc.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #define DRV_NAME "max6900" | ||
21 | #define DRV_VERSION "0.1" | ||
22 | |||
23 | /* | ||
24 | * register indices | ||
25 | */ | ||
26 | #define MAX6900_REG_SC 0 /* seconds 00-59 */ | ||
27 | #define MAX6900_REG_MN 1 /* minutes 00-59 */ | ||
28 | #define MAX6900_REG_HR 2 /* hours 00-23 */ | ||
29 | #define MAX6900_REG_DT 3 /* day of month 00-31 */ | ||
30 | #define MAX6900_REG_MO 4 /* month 01-12 */ | ||
31 | #define MAX6900_REG_DW 5 /* day of week 1-7 */ | ||
32 | #define MAX6900_REG_YR 6 /* year 00-99 */ | ||
33 | #define MAX6900_REG_CT 7 /* control */ | ||
34 | #define MAX6900_REG_LEN 8 | ||
35 | |||
36 | #define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */ | ||
37 | |||
38 | /* | ||
39 | * register read/write commands | ||
40 | */ | ||
41 | #define MAX6900_REG_CONTROL_WRITE 0x8e | ||
42 | #define MAX6900_REG_BURST_READ 0xbf | ||
43 | #define MAX6900_REG_BURST_WRITE 0xbe | ||
44 | #define MAX6900_REG_RESERVED_READ 0x96 | ||
45 | |||
46 | #define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ | ||
47 | |||
48 | #define MAX6900_I2C_ADDR 0xa0 | ||
49 | |||
50 | static unsigned short normal_i2c[] = { | ||
51 | MAX6900_I2C_ADDR >> 1, | ||
52 | I2C_CLIENT_END | ||
53 | }; | ||
54 | |||
55 | I2C_CLIENT_INSMOD; /* defines addr_data */ | ||
56 | |||
57 | static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind); | ||
58 | |||
59 | static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) | ||
60 | { | ||
61 | u8 reg_addr[1] = { MAX6900_REG_BURST_READ }; | ||
62 | struct i2c_msg msgs[2] = { | ||
63 | { | ||
64 | .addr = client->addr, | ||
65 | .flags = 0, /* write */ | ||
66 | .len = sizeof(reg_addr), | ||
67 | .buf = reg_addr | ||
68 | }, | ||
69 | { | ||
70 | .addr = client->addr, | ||
71 | .flags = I2C_M_RD, | ||
72 | .len = MAX6900_REG_LEN, | ||
73 | .buf = buf | ||
74 | } | ||
75 | }; | ||
76 | int rc; | ||
77 | |||
78 | rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
79 | if (rc != ARRAY_SIZE(msgs)) { | ||
80 | dev_err(&client->dev, "%s: register read failed\n", | ||
81 | __FUNCTION__); | ||
82 | return -EIO; | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) | ||
88 | { | ||
89 | u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE }; | ||
90 | struct i2c_msg msgs[1] = { | ||
91 | { | ||
92 | .addr = client->addr, | ||
93 | .flags = 0, /* write */ | ||
94 | .len = MAX6900_REG_LEN + 1, | ||
95 | .buf = i2c_buf | ||
96 | } | ||
97 | }; | ||
98 | int rc; | ||
99 | |||
100 | memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN); | ||
101 | |||
102 | rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
103 | if (rc != ARRAY_SIZE(msgs)) { | ||
104 | dev_err(&client->dev, "%s: register write failed\n", | ||
105 | __FUNCTION__); | ||
106 | return -EIO; | ||
107 | } | ||
108 | msleep(MAX6900_IDLE_TIME_AFTER_WRITE); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int max6900_i2c_validate_client(struct i2c_client *client) | ||
113 | { | ||
114 | u8 regs[MAX6900_REG_LEN]; | ||
115 | u8 zero_mask[MAX6900_REG_LEN] = { | ||
116 | 0x80, /* seconds */ | ||
117 | 0x80, /* minutes */ | ||
118 | 0x40, /* hours */ | ||
119 | 0xc0, /* day of month */ | ||
120 | 0xe0, /* month */ | ||
121 | 0xf8, /* day of week */ | ||
122 | 0x00, /* year */ | ||
123 | 0x7f, /* control */ | ||
124 | }; | ||
125 | int i; | ||
126 | int rc; | ||
127 | int reserved; | ||
128 | |||
129 | reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ); | ||
130 | if (reserved != 0x07) | ||
131 | return -ENODEV; | ||
132 | |||
133 | rc = max6900_i2c_read_regs(client, regs); | ||
134 | if (rc < 0) | ||
135 | return rc; | ||
136 | |||
137 | for (i = 0; i < MAX6900_REG_LEN; ++i) { | ||
138 | if (regs[i] & zero_mask[i]) | ||
139 | return -ENODEV; | ||
140 | } | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) | ||
146 | { | ||
147 | int rc; | ||
148 | u8 regs[MAX6900_REG_LEN]; | ||
149 | |||
150 | rc = max6900_i2c_read_regs(client, regs); | ||
151 | if (rc < 0) | ||
152 | return rc; | ||
153 | |||
154 | tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]); | ||
155 | tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]); | ||
156 | tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f); | ||
157 | tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]); | ||
158 | tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1; | ||
159 | tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100; | ||
160 | tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int max6900_i2c_clear_write_protect(struct i2c_client *client) | ||
166 | { | ||
167 | int rc; | ||
168 | rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); | ||
169 | if (rc < 0) { | ||
170 | dev_err(&client->dev, "%s: control register write failed\n", | ||
171 | __FUNCTION__); | ||
172 | return -EIO; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int max6900_i2c_set_time(struct i2c_client *client, | ||
178 | struct rtc_time const *tm) | ||
179 | { | ||
180 | u8 regs[MAX6900_REG_LEN]; | ||
181 | int rc; | ||
182 | |||
183 | rc = max6900_i2c_clear_write_protect(client); | ||
184 | if (rc < 0) | ||
185 | return rc; | ||
186 | |||
187 | regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec); | ||
188 | regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min); | ||
189 | regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour); | ||
190 | regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday); | ||
191 | regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1); | ||
192 | regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100); | ||
193 | regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday); | ||
194 | regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; /* set write protect */ | ||
195 | |||
196 | rc = max6900_i2c_write_regs(client, regs); | ||
197 | if (rc < 0) | ||
198 | return rc; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
204 | { | ||
205 | return max6900_i2c_read_time(to_i2c_client(dev), tm); | ||
206 | } | ||
207 | |||
208 | static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
209 | { | ||
210 | return max6900_i2c_set_time(to_i2c_client(dev), tm); | ||
211 | } | ||
212 | |||
213 | static int max6900_attach_adapter(struct i2c_adapter *adapter) | ||
214 | { | ||
215 | return i2c_probe(adapter, &addr_data, max6900_probe); | ||
216 | } | ||
217 | |||
218 | static int max6900_detach_client(struct i2c_client *client) | ||
219 | { | ||
220 | struct rtc_device *const rtc = i2c_get_clientdata(client); | ||
221 | |||
222 | if (rtc) | ||
223 | rtc_device_unregister(rtc); | ||
224 | |||
225 | return i2c_detach_client(client); | ||
226 | } | ||
227 | |||
228 | static struct i2c_driver max6900_driver = { | ||
229 | .driver = { | ||
230 | .name = DRV_NAME, | ||
231 | }, | ||
232 | .id = I2C_DRIVERID_MAX6900, | ||
233 | .attach_adapter = max6900_attach_adapter, | ||
234 | .detach_client = max6900_detach_client, | ||
235 | }; | ||
236 | |||
237 | static const struct rtc_class_ops max6900_rtc_ops = { | ||
238 | .read_time = max6900_rtc_read_time, | ||
239 | .set_time = max6900_rtc_set_time, | ||
240 | }; | ||
241 | |||
242 | static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind) | ||
243 | { | ||
244 | int rc = 0; | ||
245 | struct i2c_client *client = NULL; | ||
246 | struct rtc_device *rtc = NULL; | ||
247 | |||
248 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { | ||
249 | rc = -ENODEV; | ||
250 | goto failout; | ||
251 | } | ||
252 | |||
253 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
254 | if (client == NULL) { | ||
255 | rc = -ENOMEM; | ||
256 | goto failout; | ||
257 | } | ||
258 | |||
259 | client->addr = addr; | ||
260 | client->adapter = adapter; | ||
261 | client->driver = &max6900_driver; | ||
262 | strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE); | ||
263 | |||
264 | if (kind < 0) { | ||
265 | rc = max6900_i2c_validate_client(client); | ||
266 | if (rc < 0) | ||
267 | goto failout; | ||
268 | } | ||
269 | |||
270 | rc = i2c_attach_client(client); | ||
271 | if (rc < 0) | ||
272 | goto failout; | ||
273 | |||
274 | dev_info(&client->dev, | ||
275 | "chip found, driver version " DRV_VERSION "\n"); | ||
276 | |||
277 | rtc = rtc_device_register(max6900_driver.driver.name, | ||
278 | &client->dev, | ||
279 | &max6900_rtc_ops, THIS_MODULE); | ||
280 | if (IS_ERR(rtc)) { | ||
281 | rc = PTR_ERR(rtc); | ||
282 | goto failout_detach; | ||
283 | } | ||
284 | |||
285 | i2c_set_clientdata(client, rtc); | ||
286 | |||
287 | return 0; | ||
288 | |||
289 | failout_detach: | ||
290 | i2c_detach_client(client); | ||
291 | failout: | ||
292 | kfree(client); | ||
293 | return rc; | ||
294 | } | ||
295 | |||
296 | static int __init max6900_init(void) | ||
297 | { | ||
298 | return i2c_add_driver(&max6900_driver); | ||
299 | } | ||
300 | |||
301 | static void __exit max6900_exit(void) | ||
302 | { | ||
303 | i2c_del_driver(&max6900_driver); | ||
304 | } | ||
305 | |||
306 | MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); | ||
307 | MODULE_LICENSE("GPL"); | ||
308 | MODULE_VERSION(DRV_VERSION); | ||
309 | |||
310 | module_init(max6900_init); | ||
311 | module_exit(max6900_exit); | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 9de8d67f4f8d..60a8a4bb8bd2 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -124,7 +124,7 @@ static void rtc_wait_not_busy(void) | |||
124 | /* now we have ~15 usec to read/write various registers */ | 124 | /* now we have ~15 usec to read/write various registers */ |
125 | } | 125 | } |
126 | 126 | ||
127 | static irqreturn_t rtc_irq(int irq, void *class_dev) | 127 | static irqreturn_t rtc_irq(int irq, void *rtc) |
128 | { | 128 | { |
129 | unsigned long events = 0; | 129 | unsigned long events = 0; |
130 | u8 irq_data; | 130 | u8 irq_data; |
@@ -141,7 +141,7 @@ static irqreturn_t rtc_irq(int irq, void *class_dev) | |||
141 | if (irq_data & OMAP_RTC_STATUS_1S_EVENT) | 141 | if (irq_data & OMAP_RTC_STATUS_1S_EVENT) |
142 | events |= RTC_IRQF | RTC_UF; | 142 | events |= RTC_IRQF | RTC_UF; |
143 | 143 | ||
144 | rtc_update_irq(class_dev, 1, events); | 144 | rtc_update_irq(rtc, 1, events); |
145 | 145 | ||
146 | return IRQ_HANDLED; | 146 | return IRQ_HANDLED; |
147 | } | 147 | } |
@@ -289,34 +289,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
289 | { | 289 | { |
290 | u8 reg; | 290 | u8 reg; |
291 | 291 | ||
292 | /* Much userspace code uses RTC_ALM_SET, thus "don't care" for | ||
293 | * day/month/year specifies alarms up to 24 hours in the future. | ||
294 | * So we need to handle that ... but let's ignore the "don't care" | ||
295 | * values for hours/minutes/seconds. | ||
296 | */ | ||
297 | if (alm->time.tm_mday <= 0 | ||
298 | && alm->time.tm_mon < 0 | ||
299 | && alm->time.tm_year < 0) { | ||
300 | struct rtc_time tm; | ||
301 | unsigned long now, then; | ||
302 | |||
303 | omap_rtc_read_time(dev, &tm); | ||
304 | rtc_tm_to_time(&tm, &now); | ||
305 | |||
306 | alm->time.tm_mday = tm.tm_mday; | ||
307 | alm->time.tm_mon = tm.tm_mon; | ||
308 | alm->time.tm_year = tm.tm_year; | ||
309 | rtc_tm_to_time(&alm->time, &then); | ||
310 | |||
311 | /* sometimes the alarm wraps into tomorrow */ | ||
312 | if (then < now) { | ||
313 | rtc_time_to_tm(now + 24 * 60 * 60, &tm); | ||
314 | alm->time.tm_mday = tm.tm_mday; | ||
315 | alm->time.tm_mon = tm.tm_mon; | ||
316 | alm->time.tm_year = tm.tm_year; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | if (tm2bcd(&alm->time) < 0) | 292 | if (tm2bcd(&alm->time) < 0) |
321 | return -EINVAL; | 293 | return -EINVAL; |
322 | 294 | ||
@@ -399,7 +371,7 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev) | |||
399 | goto fail; | 371 | goto fail; |
400 | } | 372 | } |
401 | platform_set_drvdata(pdev, rtc); | 373 | platform_set_drvdata(pdev, rtc); |
402 | class_set_devdata(&rtc->class_dev, mem); | 374 | dev_set_devdata(&rtc->dev, mem); |
403 | 375 | ||
404 | /* clear pending irqs, and set 1/second periodic, | 376 | /* clear pending irqs, and set 1/second periodic, |
405 | * which we'll use instead of update irqs | 377 | * which we'll use instead of update irqs |
@@ -418,13 +390,13 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev) | |||
418 | 390 | ||
419 | /* handle periodic and alarm irqs */ | 391 | /* handle periodic and alarm irqs */ |
420 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, | 392 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, |
421 | rtc->class_dev.class_id, &rtc->class_dev)) { | 393 | rtc->dev.bus_id, rtc)) { |
422 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", | 394 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", |
423 | pdev->name, omap_rtc_timer); | 395 | pdev->name, omap_rtc_timer); |
424 | goto fail0; | 396 | goto fail0; |
425 | } | 397 | } |
426 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, | 398 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, |
427 | rtc->class_dev.class_id, &rtc->class_dev)) { | 399 | rtc->dev.bus_id, rtc)) { |
428 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", | 400 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", |
429 | pdev->name, omap_rtc_alarm); | 401 | pdev->name, omap_rtc_alarm); |
430 | goto fail1; | 402 | goto fail1; |
@@ -481,26 +453,17 @@ static int __devexit omap_rtc_remove(struct platform_device *pdev) | |||
481 | free_irq(omap_rtc_timer, rtc); | 453 | free_irq(omap_rtc_timer, rtc); |
482 | free_irq(omap_rtc_alarm, rtc); | 454 | free_irq(omap_rtc_alarm, rtc); |
483 | 455 | ||
484 | release_resource(class_get_devdata(&rtc->class_dev)); | 456 | release_resource(dev_get_devdata(&rtc->dev)); |
485 | rtc_device_unregister(rtc); | 457 | rtc_device_unregister(rtc); |
486 | return 0; | 458 | return 0; |
487 | } | 459 | } |
488 | 460 | ||
489 | #ifdef CONFIG_PM | 461 | #ifdef CONFIG_PM |
490 | 462 | ||
491 | static struct timespec rtc_delta; | ||
492 | static u8 irqstat; | 463 | static u8 irqstat; |
493 | 464 | ||
494 | static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 465 | static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
495 | { | 466 | { |
496 | struct rtc_time rtc_tm; | ||
497 | struct timespec time; | ||
498 | |||
499 | time.tv_nsec = 0; | ||
500 | omap_rtc_read_time(NULL, &rtc_tm); | ||
501 | rtc_tm_to_time(&rtc_tm, &time.tv_sec); | ||
502 | |||
503 | save_time_delta(&rtc_delta, &time); | ||
504 | irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); | 467 | irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); |
505 | 468 | ||
506 | /* FIXME the RTC alarm is not currently acting as a wakeup event | 469 | /* FIXME the RTC alarm is not currently acting as a wakeup event |
@@ -517,14 +480,6 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
517 | 480 | ||
518 | static int omap_rtc_resume(struct platform_device *pdev) | 481 | static int omap_rtc_resume(struct platform_device *pdev) |
519 | { | 482 | { |
520 | struct rtc_time rtc_tm; | ||
521 | struct timespec time; | ||
522 | |||
523 | time.tv_nsec = 0; | ||
524 | omap_rtc_read_time(NULL, &rtc_tm); | ||
525 | rtc_tm_to_time(&rtc_tm, &time.tv_sec); | ||
526 | |||
527 | restore_time_delta(&rtc_delta, &time); | ||
528 | if (device_may_wakeup(&pdev->dev)) | 483 | if (device_may_wakeup(&pdev->dev)) |
529 | disable_irq_wake(omap_rtc_alarm); | 484 | disable_irq_wake(omap_rtc_alarm); |
530 | else | 485 | else |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index f13daa9fecaa..e4bf68ca96f7 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -51,7 +51,7 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id) | |||
51 | { | 51 | { |
52 | struct rtc_device *rtc = dev_id; | 52 | struct rtc_device *rtc = dev_id; |
53 | 53 | ||
54 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF); | 54 | rtc_update_irq(rtc, 1, RTC_AF); |
55 | 55 | ||
56 | return IRQ_HANDLED; | 56 | return IRQ_HANDLED; |
57 | } | 57 | } |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 1bd624fc685c..8d300e6d0d9e 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -16,18 +16,18 @@ | |||
16 | #include <linux/proc_fs.h> | 16 | #include <linux/proc_fs.h> |
17 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
18 | 18 | ||
19 | static struct class_device *rtc_dev = NULL; | 19 | #include "rtc-core.h" |
20 | static DEFINE_MUTEX(rtc_lock); | 20 | |
21 | 21 | ||
22 | static int rtc_proc_show(struct seq_file *seq, void *offset) | 22 | static int rtc_proc_show(struct seq_file *seq, void *offset) |
23 | { | 23 | { |
24 | int err; | 24 | int err; |
25 | struct class_device *class_dev = seq->private; | 25 | struct rtc_device *rtc = seq->private; |
26 | const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; | 26 | const struct rtc_class_ops *ops = rtc->ops; |
27 | struct rtc_wkalrm alrm; | 27 | struct rtc_wkalrm alrm; |
28 | struct rtc_time tm; | 28 | struct rtc_time tm; |
29 | 29 | ||
30 | err = rtc_read_time(class_dev, &tm); | 30 | err = rtc_read_time(rtc, &tm); |
31 | if (err == 0) { | 31 | if (err == 0) { |
32 | seq_printf(seq, | 32 | seq_printf(seq, |
33 | "rtc_time\t: %02d:%02d:%02d\n" | 33 | "rtc_time\t: %02d:%02d:%02d\n" |
@@ -36,7 +36,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
36 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); | 36 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); |
37 | } | 37 | } |
38 | 38 | ||
39 | err = rtc_read_alarm(class_dev, &alrm); | 39 | err = rtc_read_alarm(rtc, &alrm); |
40 | if (err == 0) { | 40 | if (err == 0) { |
41 | seq_printf(seq, "alrm_time\t: "); | 41 | seq_printf(seq, "alrm_time\t: "); |
42 | if ((unsigned int)alrm.time.tm_hour <= 24) | 42 | if ((unsigned int)alrm.time.tm_hour <= 24) |
@@ -74,19 +74,19 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) | |||
74 | seq_printf(seq, "24hr\t\t: yes\n"); | 74 | seq_printf(seq, "24hr\t\t: yes\n"); |
75 | 75 | ||
76 | if (ops->proc) | 76 | if (ops->proc) |
77 | ops->proc(class_dev->dev, seq); | 77 | ops->proc(rtc->dev.parent, seq); |
78 | 78 | ||
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int rtc_proc_open(struct inode *inode, struct file *file) | 82 | static int rtc_proc_open(struct inode *inode, struct file *file) |
83 | { | 83 | { |
84 | struct class_device *class_dev = PDE(inode)->data; | 84 | struct rtc_device *rtc = PDE(inode)->data; |
85 | 85 | ||
86 | if (!try_module_get(THIS_MODULE)) | 86 | if (!try_module_get(THIS_MODULE)) |
87 | return -ENODEV; | 87 | return -ENODEV; |
88 | 88 | ||
89 | return single_open(file, rtc_proc_show, class_dev); | 89 | return single_open(file, rtc_proc_show, rtc); |
90 | } | 90 | } |
91 | 91 | ||
92 | static int rtc_proc_release(struct inode *inode, struct file *file) | 92 | static int rtc_proc_release(struct inode *inode, struct file *file) |
@@ -103,62 +103,22 @@ static const struct file_operations rtc_proc_fops = { | |||
103 | .release = rtc_proc_release, | 103 | .release = rtc_proc_release, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static int rtc_proc_add_device(struct class_device *class_dev, | 106 | void rtc_proc_add_device(struct rtc_device *rtc) |
107 | struct class_interface *class_intf) | ||
108 | { | 107 | { |
109 | mutex_lock(&rtc_lock); | 108 | if (rtc->id == 0) { |
110 | if (rtc_dev == NULL) { | ||
111 | struct proc_dir_entry *ent; | 109 | struct proc_dir_entry *ent; |
112 | 110 | ||
113 | rtc_dev = class_dev; | ||
114 | |||
115 | ent = create_proc_entry("driver/rtc", 0, NULL); | 111 | ent = create_proc_entry("driver/rtc", 0, NULL); |
116 | if (ent) { | 112 | if (ent) { |
117 | struct rtc_device *rtc = to_rtc_device(class_dev); | ||
118 | |||
119 | ent->proc_fops = &rtc_proc_fops; | 113 | ent->proc_fops = &rtc_proc_fops; |
120 | ent->owner = rtc->owner; | 114 | ent->owner = rtc->owner; |
121 | ent->data = class_dev; | 115 | ent->data = rtc; |
122 | |||
123 | dev_dbg(class_dev->dev, "rtc intf: proc\n"); | ||
124 | } | 116 | } |
125 | else | ||
126 | rtc_dev = NULL; | ||
127 | } | 117 | } |
128 | mutex_unlock(&rtc_lock); | ||
129 | |||
130 | return 0; | ||
131 | } | 118 | } |
132 | 119 | ||
133 | static void rtc_proc_remove_device(struct class_device *class_dev, | 120 | void rtc_proc_del_device(struct rtc_device *rtc) |
134 | struct class_interface *class_intf) | ||
135 | { | 121 | { |
136 | mutex_lock(&rtc_lock); | 122 | if (rtc->id == 0) |
137 | if (rtc_dev == class_dev) { | ||
138 | remove_proc_entry("driver/rtc", NULL); | 123 | remove_proc_entry("driver/rtc", NULL); |
139 | rtc_dev = NULL; | ||
140 | } | ||
141 | mutex_unlock(&rtc_lock); | ||
142 | } | ||
143 | |||
144 | static struct class_interface rtc_proc_interface = { | ||
145 | .add = &rtc_proc_add_device, | ||
146 | .remove = &rtc_proc_remove_device, | ||
147 | }; | ||
148 | |||
149 | static int __init rtc_proc_init(void) | ||
150 | { | ||
151 | return rtc_interface_register(&rtc_proc_interface); | ||
152 | } | 124 | } |
153 | |||
154 | static void __exit rtc_proc_exit(void) | ||
155 | { | ||
156 | class_interface_unregister(&rtc_proc_interface); | ||
157 | } | ||
158 | |||
159 | subsys_initcall(rtc_proc_init); | ||
160 | module_exit(rtc_proc_exit); | ||
161 | |||
162 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | ||
163 | MODULE_DESCRIPTION("RTC class proc interface"); | ||
164 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c new file mode 100644 index 000000000000..9d6de371495b --- /dev/null +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* | ||
2 | * Ricoh RS5C313 RTC device/driver | ||
3 | * Copyright (C) 2007 Nobuhiro Iwamatsu | ||
4 | * | ||
5 | * 2005-09-19 modifed by kogiidena | ||
6 | * | ||
7 | * Based on the old drivers/char/rs5c313_rtc.c by: | ||
8 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
9 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | ||
10 | * | ||
11 | * Based on code written by Paul Gortmaker. | ||
12 | * Copyright (C) 1996 Paul Gortmaker | ||
13 | * | ||
14 | * This file is subject to the terms and conditions of the GNU General Public | ||
15 | * License. See the file "COPYING" in the main directory of this archive | ||
16 | * for more details. | ||
17 | * | ||
18 | * Based on other minimal char device drivers, like Alan's | ||
19 | * watchdog, Ted's random, etc. etc. | ||
20 | * | ||
21 | * 1.07 Paul Gortmaker. | ||
22 | * 1.08 Miquel van Smoorenburg: disallow certain things on the | ||
23 | * DEC Alpha as the CMOS clock is also used for other things. | ||
24 | * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup. | ||
25 | * 1.09a Pete Zaitcev: Sun SPARC | ||
26 | * 1.09b Jeff Garzik: Modularize, init cleanup | ||
27 | * 1.09c Jeff Garzik: SMP cleanup | ||
28 | * 1.10 Paul Barton-Davis: add support for async I/O | ||
29 | * 1.10a Andrea Arcangeli: Alpha updates | ||
30 | * 1.10b Andrew Morton: SMP lock fix | ||
31 | * 1.10c Cesar Barros: SMP locking fixes and cleanup | ||
32 | * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit | ||
33 | * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. | ||
34 | * 1.11 Takashi Iwai: Kernel access functions | ||
35 | * rtc_register/rtc_unregister/rtc_control | ||
36 | * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init | ||
37 | * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer | ||
38 | * CONFIG_HPET_EMULATE_RTC | ||
39 | * 1.13 Nobuhiro Iwamatsu: Updata driver. | ||
40 | */ | ||
41 | |||
42 | #include <linux/module.h> | ||
43 | #include <linux/err.h> | ||
44 | #include <linux/rtc.h> | ||
45 | #include <linux/platform_device.h> | ||
46 | #include <linux/bcd.h> | ||
47 | #include <linux/delay.h> | ||
48 | #include <asm/io.h> | ||
49 | |||
50 | #define DRV_NAME "rs5c313" | ||
51 | #define DRV_VERSION "1.13" | ||
52 | |||
53 | #ifdef CONFIG_SH_LANDISK | ||
54 | /*****************************************************/ | ||
55 | /* LANDISK dependence part of RS5C313 */ | ||
56 | /*****************************************************/ | ||
57 | |||
58 | #define SCSMR1 0xFFE00000 | ||
59 | #define SCSCR1 0xFFE00008 | ||
60 | #define SCSMR1_CA 0x80 | ||
61 | #define SCSCR1_CKE 0x03 | ||
62 | #define SCSPTR1 0xFFE0001C | ||
63 | #define SCSPTR1_EIO 0x80 | ||
64 | #define SCSPTR1_SPB1IO 0x08 | ||
65 | #define SCSPTR1_SPB1DT 0x04 | ||
66 | #define SCSPTR1_SPB0IO 0x02 | ||
67 | #define SCSPTR1_SPB0DT 0x01 | ||
68 | |||
69 | #define SDA_OEN SCSPTR1_SPB1IO | ||
70 | #define SDA SCSPTR1_SPB1DT | ||
71 | #define SCL_OEN SCSPTR1_SPB0IO | ||
72 | #define SCL SCSPTR1_SPB0DT | ||
73 | |||
74 | /* RICOH RS5C313 CE port */ | ||
75 | #define RS5C313_CE 0xB0000003 | ||
76 | |||
77 | /* RICOH RS5C313 CE port bit */ | ||
78 | #define RS5C313_CE_RTCCE 0x02 | ||
79 | |||
80 | /* SCSPTR1 data */ | ||
81 | unsigned char scsptr1_data; | ||
82 | |||
83 | #define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE); | ||
84 | #define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE) | ||
85 | #define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008) | ||
86 | |||
87 | static void rs5c313_init_port(void) | ||
88 | { | ||
89 | /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */ | ||
90 | ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1); | ||
91 | ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1); | ||
92 | |||
93 | /* And Initialize SCL for RS5C313 clock */ | ||
94 | scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */ | ||
95 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
96 | scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */ | ||
97 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
98 | RS5C313_CEDISABLE; /* CE:L */ | ||
99 | } | ||
100 | |||
101 | static void rs5c313_write_data(unsigned char data) | ||
102 | { | ||
103 | int i; | ||
104 | |||
105 | for (i = 0; i < 8; i++) { | ||
106 | /* SDA:Write Data */ | ||
107 | scsptr1_data = (scsptr1_data & ~SDA) | | ||
108 | ((((0x80 >> i) & data) >> (7 - i)) << 2); | ||
109 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
110 | if (i == 0) { | ||
111 | scsptr1_data |= SDA_OEN; /* SDA:output enable */ | ||
112 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
113 | } | ||
114 | ndelay(700); | ||
115 | scsptr1_data &= ~SCL; /* SCL:L */ | ||
116 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
117 | ndelay(700); | ||
118 | scsptr1_data |= SCL; /* SCL:H */ | ||
119 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
120 | } | ||
121 | |||
122 | scsptr1_data &= ~SDA_OEN; /* SDA:output disable */ | ||
123 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
124 | } | ||
125 | |||
126 | static unsigned char rs5c313_read_data(void) | ||
127 | { | ||
128 | int i; | ||
129 | unsigned char data; | ||
130 | |||
131 | for (i = 0; i < 8; i++) { | ||
132 | ndelay(700); | ||
133 | /* SDA:Read Data */ | ||
134 | data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i); | ||
135 | scsptr1_data &= ~SCL; /* SCL:L */ | ||
136 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
137 | ndelay(700); | ||
138 | scsptr1_data |= SCL; /* SCL:H */ | ||
139 | ctrl_outb(scsptr1_data, SCSPTR1); | ||
140 | } | ||
141 | return data & 0x0F; | ||
142 | } | ||
143 | |||
144 | #endif /* CONFIG_SH_LANDISK */ | ||
145 | |||
146 | /*****************************************************/ | ||
147 | /* machine independence part of RS5C313 */ | ||
148 | /*****************************************************/ | ||
149 | |||
150 | /* RICOH RS5C313 address */ | ||
151 | #define RS5C313_ADDR_SEC 0x00 | ||
152 | #define RS5C313_ADDR_SEC10 0x01 | ||
153 | #define RS5C313_ADDR_MIN 0x02 | ||
154 | #define RS5C313_ADDR_MIN10 0x03 | ||
155 | #define RS5C313_ADDR_HOUR 0x04 | ||
156 | #define RS5C313_ADDR_HOUR10 0x05 | ||
157 | #define RS5C313_ADDR_WEEK 0x06 | ||
158 | #define RS5C313_ADDR_INTINTVREG 0x07 | ||
159 | #define RS5C313_ADDR_DAY 0x08 | ||
160 | #define RS5C313_ADDR_DAY10 0x09 | ||
161 | #define RS5C313_ADDR_MON 0x0A | ||
162 | #define RS5C313_ADDR_MON10 0x0B | ||
163 | #define RS5C313_ADDR_YEAR 0x0C | ||
164 | #define RS5C313_ADDR_YEAR10 0x0D | ||
165 | #define RS5C313_ADDR_CNTREG 0x0E | ||
166 | #define RS5C313_ADDR_TESTREG 0x0F | ||
167 | |||
168 | /* RICOH RS5C313 control register */ | ||
169 | #define RS5C313_CNTREG_ADJ_BSY 0x01 | ||
170 | #define RS5C313_CNTREG_WTEN_XSTP 0x02 | ||
171 | #define RS5C313_CNTREG_12_24 0x04 | ||
172 | #define RS5C313_CNTREG_CTFG 0x08 | ||
173 | |||
174 | /* RICOH RS5C313 test register */ | ||
175 | #define RS5C313_TESTREG_TEST 0x01 | ||
176 | |||
177 | /* RICOH RS5C313 control bit */ | ||
178 | #define RS5C313_CNTBIT_READ 0x40 | ||
179 | #define RS5C313_CNTBIT_AD 0x20 | ||
180 | #define RS5C313_CNTBIT_DT 0x10 | ||
181 | |||
182 | static unsigned char rs5c313_read_reg(unsigned char addr) | ||
183 | { | ||
184 | |||
185 | rs5c313_write_data(addr | RS5C313_CNTBIT_READ | RS5C313_CNTBIT_AD); | ||
186 | return rs5c313_read_data(); | ||
187 | } | ||
188 | |||
189 | static void rs5c313_write_reg(unsigned char addr, unsigned char data) | ||
190 | { | ||
191 | data &= 0x0f; | ||
192 | rs5c313_write_data(addr | RS5C313_CNTBIT_AD); | ||
193 | rs5c313_write_data(data | RS5C313_CNTBIT_DT); | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | static inline unsigned char rs5c313_read_cntreg(unsigned char addr) | ||
198 | { | ||
199 | return rs5c313_read_reg(RS5C313_ADDR_CNTREG); | ||
200 | } | ||
201 | |||
202 | static inline void rs5c313_write_cntreg(unsigned char data) | ||
203 | { | ||
204 | rs5c313_write_reg(RS5C313_ADDR_CNTREG, data); | ||
205 | } | ||
206 | |||
207 | static inline void rs5c313_write_intintvreg(unsigned char data) | ||
208 | { | ||
209 | rs5c313_write_reg(RS5C313_ADDR_INTINTVREG, data); | ||
210 | } | ||
211 | |||
212 | static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
213 | { | ||
214 | int data; | ||
215 | |||
216 | while (1) { | ||
217 | RS5C313_CEENABLE; /* CE:H */ | ||
218 | |||
219 | /* Initialize control reg. 24 hour */ | ||
220 | rs5c313_write_cntreg(0x04); | ||
221 | |||
222 | if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) | ||
223 | break; | ||
224 | |||
225 | RS5C313_CEDISABLE; | ||
226 | ndelay(700); /* CE:L */ | ||
227 | |||
228 | } | ||
229 | |||
230 | data = rs5c313_read_reg(RS5C313_ADDR_SEC); | ||
231 | data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4); | ||
232 | tm->tm_sec = BCD2BIN(data); | ||
233 | |||
234 | data = rs5c313_read_reg(RS5C313_ADDR_MIN); | ||
235 | data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4); | ||
236 | tm->tm_min = BCD2BIN(data); | ||
237 | |||
238 | data = rs5c313_read_reg(RS5C313_ADDR_HOUR); | ||
239 | data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4); | ||
240 | tm->tm_hour = BCD2BIN(data); | ||
241 | |||
242 | data = rs5c313_read_reg(RS5C313_ADDR_DAY); | ||
243 | data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4); | ||
244 | tm->tm_mday = BCD2BIN(data); | ||
245 | |||
246 | data = rs5c313_read_reg(RS5C313_ADDR_MON); | ||
247 | data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4); | ||
248 | tm->tm_mon = BCD2BIN(data) - 1; | ||
249 | |||
250 | data = rs5c313_read_reg(RS5C313_ADDR_YEAR); | ||
251 | data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4); | ||
252 | tm->tm_year = BCD2BIN(data); | ||
253 | |||
254 | if (tm->tm_year < 70) | ||
255 | tm->tm_year += 100; | ||
256 | |||
257 | data = rs5c313_read_reg(RS5C313_ADDR_WEEK); | ||
258 | tm->tm_wday = BCD2BIN(data); | ||
259 | |||
260 | RS5C313_CEDISABLE; | ||
261 | ndelay(700); /* CE:L */ | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
267 | { | ||
268 | int data; | ||
269 | |||
270 | /* busy check. */ | ||
271 | while (1) { | ||
272 | RS5C313_CEENABLE; /* CE:H */ | ||
273 | |||
274 | /* Initiatlize control reg. 24 hour */ | ||
275 | rs5c313_write_cntreg(0x04); | ||
276 | |||
277 | if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) | ||
278 | break; | ||
279 | RS5C313_MISCOP; | ||
280 | RS5C313_CEDISABLE; | ||
281 | ndelay(700); /* CE:L */ | ||
282 | } | ||
283 | |||
284 | data = BIN2BCD(tm->tm_sec); | ||
285 | rs5c313_write_reg(RS5C313_ADDR_SEC, data); | ||
286 | rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4)); | ||
287 | |||
288 | data = BIN2BCD(tm->tm_min); | ||
289 | rs5c313_write_reg(RS5C313_ADDR_MIN, data ); | ||
290 | rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4)); | ||
291 | |||
292 | data = BIN2BCD(tm->tm_hour); | ||
293 | rs5c313_write_reg(RS5C313_ADDR_HOUR, data); | ||
294 | rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4)); | ||
295 | |||
296 | data = BIN2BCD(tm->tm_mday); | ||
297 | rs5c313_write_reg(RS5C313_ADDR_DAY, data); | ||
298 | rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4)); | ||
299 | |||
300 | data = BIN2BCD(tm->tm_mon + 1); | ||
301 | rs5c313_write_reg(RS5C313_ADDR_MON, data); | ||
302 | rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4)); | ||
303 | |||
304 | data = BIN2BCD(tm->tm_year % 100); | ||
305 | rs5c313_write_reg(RS5C313_ADDR_YEAR, data); | ||
306 | rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4)); | ||
307 | |||
308 | data = BIN2BCD(tm->tm_wday); | ||
309 | rs5c313_write_reg(RS5C313_ADDR_WEEK, data); | ||
310 | |||
311 | RS5C313_CEDISABLE; /* CE:H */ | ||
312 | ndelay(700); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void rs5c313_check_xstp_bit(void) | ||
318 | { | ||
319 | struct rtc_time tm; | ||
320 | |||
321 | RS5C313_CEENABLE; /* CE:H */ | ||
322 | if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) { | ||
323 | /* INT interval reg. OFF */ | ||
324 | rs5c313_write_intintvreg(0x00); | ||
325 | /* Initialize control reg. 24 hour & adjust */ | ||
326 | rs5c313_write_cntreg(0x07); | ||
327 | |||
328 | /* busy check. */ | ||
329 | while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY) | ||
330 | RS5C313_MISCOP; | ||
331 | |||
332 | memset(&tm, 0, sizeof(struct rtc_time)); | ||
333 | tm.tm_mday = 1; | ||
334 | tm.tm_mon = 1; | ||
335 | |||
336 | rs5c313_rtc_set_time(NULL, &tm); | ||
337 | printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to " | ||
338 | "1 Jan 2000\n"); | ||
339 | } | ||
340 | RS5C313_CEDISABLE; | ||
341 | ndelay(700); /* CE:L */ | ||
342 | } | ||
343 | |||
344 | static const struct rtc_class_ops rs5c313_rtc_ops = { | ||
345 | .read_time = rs5c313_rtc_read_time, | ||
346 | .set_time = rs5c313_rtc_set_time, | ||
347 | }; | ||
348 | |||
349 | static int rs5c313_rtc_probe(struct platform_device *pdev) | ||
350 | { | ||
351 | struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev, | ||
352 | &rs5c313_rtc_ops, THIS_MODULE); | ||
353 | |||
354 | if (IS_ERR(rtc)) | ||
355 | return PTR_ERR(rtc); | ||
356 | |||
357 | platform_set_drvdata(pdev, rtc); | ||
358 | |||
359 | return err; | ||
360 | } | ||
361 | |||
362 | static int __devexit rs5c313_rtc_remove(struct platform_device *pdev) | ||
363 | { | ||
364 | struct rtc_device *rtc = platform_get_drvdata( pdev ); | ||
365 | |||
366 | rtc_device_unregister(rtc); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static struct platform_driver rs5c313_rtc_platform_driver = { | ||
372 | .driver = { | ||
373 | .name = DRV_NAME, | ||
374 | .owner = THIS_MODULE, | ||
375 | }, | ||
376 | .probe = rs5c313_rtc_probe, | ||
377 | .remove = __devexit_p( rs5c313_rtc_remove ), | ||
378 | }; | ||
379 | |||
380 | static int __init rs5c313_rtc_init(void) | ||
381 | { | ||
382 | int err; | ||
383 | |||
384 | err = platform_driver_register(&rs5c313_rtc_platform_driver); | ||
385 | if (err) | ||
386 | return err; | ||
387 | |||
388 | rs5c313_init_port(); | ||
389 | rs5c313_check_xstp_bit(); | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void __exit rs5c313_rtc_exit(void) | ||
395 | { | ||
396 | platform_driver_unregister( &rs5c313_rtc_platform_driver ); | ||
397 | } | ||
398 | |||
399 | module_init(rs5c313_rtc_init); | ||
400 | module_exit(rs5c313_rtc_exit); | ||
401 | |||
402 | MODULE_VERSION(DRV_VERSION); | ||
403 | MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>"); | ||
404 | MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); | ||
405 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 9a79a24a7487..54b613053468 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -50,7 +50,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) | |||
50 | { | 50 | { |
51 | struct rtc_device *rdev = id; | 51 | struct rtc_device *rdev = id; |
52 | 52 | ||
53 | rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF); | 53 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); |
54 | return IRQ_HANDLED; | 54 | return IRQ_HANDLED; |
55 | } | 55 | } |
56 | 56 | ||
@@ -58,7 +58,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |||
58 | { | 58 | { |
59 | struct rtc_device *rdev = id; | 59 | struct rtc_device *rdev = id; |
60 | 60 | ||
61 | rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF); | 61 | rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); |
62 | return IRQ_HANDLED; | 62 | return IRQ_HANDLED; |
63 | } | 63 | } |
64 | 64 | ||
@@ -548,37 +548,15 @@ static int ticnt_save; | |||
548 | 548 | ||
549 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 549 | static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
550 | { | 550 | { |
551 | struct rtc_time tm; | ||
552 | struct timespec time; | ||
553 | |||
554 | time.tv_nsec = 0; | ||
555 | |||
556 | /* save TICNT for anyone using periodic interrupts */ | 551 | /* save TICNT for anyone using periodic interrupts */ |
557 | |||
558 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 552 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
559 | |||
560 | /* calculate time delta for suspend */ | ||
561 | |||
562 | s3c_rtc_gettime(&pdev->dev, &tm); | ||
563 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
564 | save_time_delta(&s3c_rtc_delta, &time); | ||
565 | s3c_rtc_enable(pdev, 0); | 553 | s3c_rtc_enable(pdev, 0); |
566 | |||
567 | return 0; | 554 | return 0; |
568 | } | 555 | } |
569 | 556 | ||
570 | static int s3c_rtc_resume(struct platform_device *pdev) | 557 | static int s3c_rtc_resume(struct platform_device *pdev) |
571 | { | 558 | { |
572 | struct rtc_time tm; | ||
573 | struct timespec time; | ||
574 | |||
575 | time.tv_nsec = 0; | ||
576 | |||
577 | s3c_rtc_enable(pdev, 1); | 559 | s3c_rtc_enable(pdev, 1); |
578 | s3c_rtc_gettime(&pdev->dev, &tm); | ||
579 | rtc_tm_to_time(&tm, &time.tv_sec); | ||
580 | restore_time_delta(&s3c_rtc_delta, &time); | ||
581 | |||
582 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 560 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
583 | return 0; | 561 | return 0; |
584 | } | 562 | } |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 677bae820dc3..0918b787c4dd 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -93,7 +93,7 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
93 | if (rtsr & RTSR_HZ) | 93 | if (rtsr & RTSR_HZ) |
94 | events |= RTC_UF | RTC_IRQF; | 94 | events |= RTC_UF | RTC_IRQF; |
95 | 95 | ||
96 | rtc_update_irq(&rtc->class_dev, 1, events); | 96 | rtc_update_irq(rtc, 1, events); |
97 | 97 | ||
98 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) | 98 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) |
99 | rtc_update_alarm(&rtc_alarm); | 99 | rtc_update_alarm(&rtc_alarm); |
@@ -119,7 +119,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) | |||
119 | */ | 119 | */ |
120 | OSSR = OSSR_M1; /* clear match on timer1 */ | 120 | OSSR = OSSR_M1; /* clear match on timer1 */ |
121 | 121 | ||
122 | rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF); | 122 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
123 | 123 | ||
124 | if (rtc_timer1_count == 1) | 124 | if (rtc_timer1_count == 1) |
125 | rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); | 125 | rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 198b9f22fbff..6abf4811958c 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -104,7 +104,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | |||
104 | 104 | ||
105 | writeb(tmp, rtc->regbase + RCR1); | 105 | writeb(tmp, rtc->regbase + RCR1); |
106 | 106 | ||
107 | rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); | 107 | rtc_update_irq(&rtc->rtc_dev, 1, events); |
108 | 108 | ||
109 | spin_unlock(&rtc->lock); | 109 | spin_unlock(&rtc->lock); |
110 | 110 | ||
@@ -139,7 +139,7 @@ static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | |||
139 | 139 | ||
140 | rtc->rearm_aie = 1; | 140 | rtc->rearm_aie = 1; |
141 | 141 | ||
142 | rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); | 142 | rtc_update_irq(&rtc->rtc_dev, 1, events); |
143 | } | 143 | } |
144 | 144 | ||
145 | spin_unlock(&rtc->lock); | 145 | spin_unlock(&rtc->lock); |
@@ -153,7 +153,7 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | |||
153 | 153 | ||
154 | spin_lock(&rtc->lock); | 154 | spin_lock(&rtc->lock); |
155 | 155 | ||
156 | rtc_update_irq(&rtc->rtc_dev->class_dev, 1, RTC_PF | RTC_IRQF); | 156 | rtc_update_irq(&rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); |
157 | 157 | ||
158 | spin_unlock(&rtc->lock); | 158 | spin_unlock(&rtc->lock); |
159 | 159 | ||
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 899ab8c514fa..69df94b44841 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -12,20 +12,26 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
14 | 14 | ||
15 | #include "rtc-core.h" | ||
16 | |||
17 | |||
15 | /* device attributes */ | 18 | /* device attributes */ |
16 | 19 | ||
17 | static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf) | 20 | static ssize_t |
21 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, | ||
22 | char *buf) | ||
18 | { | 23 | { |
19 | return sprintf(buf, "%s\n", to_rtc_device(dev)->name); | 24 | return sprintf(buf, "%s\n", to_rtc_device(dev)->name); |
20 | } | 25 | } |
21 | static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL); | ||
22 | 26 | ||
23 | static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) | 27 | static ssize_t |
28 | rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, | ||
29 | char *buf) | ||
24 | { | 30 | { |
25 | ssize_t retval; | 31 | ssize_t retval; |
26 | struct rtc_time tm; | 32 | struct rtc_time tm; |
27 | 33 | ||
28 | retval = rtc_read_time(dev, &tm); | 34 | retval = rtc_read_time(to_rtc_device(dev), &tm); |
29 | if (retval == 0) { | 35 | if (retval == 0) { |
30 | retval = sprintf(buf, "%04d-%02d-%02d\n", | 36 | retval = sprintf(buf, "%04d-%02d-%02d\n", |
31 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); | 37 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); |
@@ -33,14 +39,15 @@ static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) | |||
33 | 39 | ||
34 | return retval; | 40 | return retval; |
35 | } | 41 | } |
36 | static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL); | ||
37 | 42 | ||
38 | static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) | 43 | static ssize_t |
44 | rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, | ||
45 | char *buf) | ||
39 | { | 46 | { |
40 | ssize_t retval; | 47 | ssize_t retval; |
41 | struct rtc_time tm; | 48 | struct rtc_time tm; |
42 | 49 | ||
43 | retval = rtc_read_time(dev, &tm); | 50 | retval = rtc_read_time(to_rtc_device(dev), &tm); |
44 | if (retval == 0) { | 51 | if (retval == 0) { |
45 | retval = sprintf(buf, "%02d:%02d:%02d\n", | 52 | retval = sprintf(buf, "%02d:%02d:%02d\n", |
46 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 53 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
@@ -48,14 +55,15 @@ static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) | |||
48 | 55 | ||
49 | return retval; | 56 | return retval; |
50 | } | 57 | } |
51 | static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL); | ||
52 | 58 | ||
53 | static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) | 59 | static ssize_t |
60 | rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, | ||
61 | char *buf) | ||
54 | { | 62 | { |
55 | ssize_t retval; | 63 | ssize_t retval; |
56 | struct rtc_time tm; | 64 | struct rtc_time tm; |
57 | 65 | ||
58 | retval = rtc_read_time(dev, &tm); | 66 | retval = rtc_read_time(to_rtc_device(dev), &tm); |
59 | if (retval == 0) { | 67 | if (retval == 0) { |
60 | unsigned long time; | 68 | unsigned long time; |
61 | rtc_tm_to_time(&tm, &time); | 69 | rtc_tm_to_time(&tm, &time); |
@@ -64,23 +72,18 @@ static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) | |||
64 | 72 | ||
65 | return retval; | 73 | return retval; |
66 | } | 74 | } |
67 | static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); | ||
68 | |||
69 | static struct attribute *rtc_attrs[] = { | ||
70 | &class_device_attr_name.attr, | ||
71 | &class_device_attr_date.attr, | ||
72 | &class_device_attr_time.attr, | ||
73 | &class_device_attr_since_epoch.attr, | ||
74 | NULL, | ||
75 | }; | ||
76 | 75 | ||
77 | static struct attribute_group rtc_attr_group = { | 76 | static struct device_attribute rtc_attrs[] = { |
78 | .attrs = rtc_attrs, | 77 | __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), |
78 | __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), | ||
79 | __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), | ||
80 | __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), | ||
81 | { }, | ||
79 | }; | 82 | }; |
80 | 83 | ||
81 | |||
82 | static ssize_t | 84 | static ssize_t |
83 | rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf) | 85 | rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, |
86 | char *buf) | ||
84 | { | 87 | { |
85 | ssize_t retval; | 88 | ssize_t retval; |
86 | unsigned long alarm; | 89 | unsigned long alarm; |
@@ -94,7 +97,7 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf) | |||
94 | * REVISIT maybe we should require RTC implementations to | 97 | * REVISIT maybe we should require RTC implementations to |
95 | * disable the RTC alarm after it triggers, for uniformity. | 98 | * disable the RTC alarm after it triggers, for uniformity. |
96 | */ | 99 | */ |
97 | retval = rtc_read_alarm(dev, &alm); | 100 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); |
98 | if (retval == 0 && alm.enabled) { | 101 | if (retval == 0 && alm.enabled) { |
99 | rtc_tm_to_time(&alm.time, &alarm); | 102 | rtc_tm_to_time(&alm.time, &alarm); |
100 | retval = sprintf(buf, "%lu\n", alarm); | 103 | retval = sprintf(buf, "%lu\n", alarm); |
@@ -104,16 +107,18 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf) | |||
104 | } | 107 | } |
105 | 108 | ||
106 | static ssize_t | 109 | static ssize_t |
107 | rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n) | 110 | rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, |
111 | const char *buf, size_t n) | ||
108 | { | 112 | { |
109 | ssize_t retval; | 113 | ssize_t retval; |
110 | unsigned long now, alarm; | 114 | unsigned long now, alarm; |
111 | struct rtc_wkalrm alm; | 115 | struct rtc_wkalrm alm; |
116 | struct rtc_device *rtc = to_rtc_device(dev); | ||
112 | 117 | ||
113 | /* Only request alarms that trigger in the future. Disable them | 118 | /* Only request alarms that trigger in the future. Disable them |
114 | * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. | 119 | * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. |
115 | */ | 120 | */ |
116 | retval = rtc_read_time(dev, &alm.time); | 121 | retval = rtc_read_time(rtc, &alm.time); |
117 | if (retval < 0) | 122 | if (retval < 0) |
118 | return retval; | 123 | return retval; |
119 | rtc_tm_to_time(&alm.time, &now); | 124 | rtc_tm_to_time(&alm.time, &now); |
@@ -124,7 +129,7 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n) | |||
124 | * entirely prevent that here, without even the minimal | 129 | * entirely prevent that here, without even the minimal |
125 | * locking from the /dev/rtcN api. | 130 | * locking from the /dev/rtcN api. |
126 | */ | 131 | */ |
127 | retval = rtc_read_alarm(dev, &alm); | 132 | retval = rtc_read_alarm(rtc, &alm); |
128 | if (retval < 0) | 133 | if (retval < 0) |
129 | return retval; | 134 | return retval; |
130 | if (alm.enabled) | 135 | if (alm.enabled) |
@@ -141,10 +146,10 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n) | |||
141 | } | 146 | } |
142 | rtc_time_to_tm(alarm, &alm.time); | 147 | rtc_time_to_tm(alarm, &alm.time); |
143 | 148 | ||
144 | retval = rtc_set_alarm(dev, &alm); | 149 | retval = rtc_set_alarm(rtc, &alm); |
145 | return (retval < 0) ? retval : n; | 150 | return (retval < 0) ? retval : n; |
146 | } | 151 | } |
147 | static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, | 152 | static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, |
148 | rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); | 153 | rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); |
149 | 154 | ||
150 | 155 | ||
@@ -153,71 +158,37 @@ static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, | |||
153 | * suspend-to-disk. So: no attribute unless that side effect is possible. | 158 | * suspend-to-disk. So: no attribute unless that side effect is possible. |
154 | * (Userspace may disable that mechanism later.) | 159 | * (Userspace may disable that mechanism later.) |
155 | */ | 160 | */ |
156 | static inline int rtc_does_wakealarm(struct class_device *class_dev) | 161 | static inline int rtc_does_wakealarm(struct rtc_device *rtc) |
157 | { | 162 | { |
158 | struct rtc_device *rtc; | 163 | if (!device_can_wakeup(rtc->dev.parent)) |
159 | |||
160 | if (!device_can_wakeup(class_dev->dev)) | ||
161 | return 0; | 164 | return 0; |
162 | rtc = to_rtc_device(class_dev); | ||
163 | return rtc->ops->set_alarm != NULL; | 165 | return rtc->ops->set_alarm != NULL; |
164 | } | 166 | } |
165 | 167 | ||
166 | 168 | ||
167 | static int rtc_sysfs_add_device(struct class_device *class_dev, | 169 | void rtc_sysfs_add_device(struct rtc_device *rtc) |
168 | struct class_interface *class_intf) | ||
169 | { | 170 | { |
170 | int err; | 171 | int err; |
171 | 172 | ||
172 | dev_dbg(class_dev->dev, "rtc intf: sysfs\n"); | 173 | /* not all RTCs support both alarms and wakeup */ |
174 | if (!rtc_does_wakealarm(rtc)) | ||
175 | return; | ||
173 | 176 | ||
174 | err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group); | 177 | err = device_create_file(&rtc->dev, &dev_attr_wakealarm); |
175 | if (err) | 178 | if (err) |
176 | dev_err(class_dev->dev, "failed to create %s\n", | 179 | dev_err(rtc->dev.parent, "failed to create " |
177 | "sysfs attributes"); | 180 | "alarm attribute, %d", |
178 | else if (rtc_does_wakealarm(class_dev)) { | 181 | err); |
179 | /* not all RTCs support both alarms and wakeup */ | ||
180 | err = class_device_create_file(class_dev, | ||
181 | &class_device_attr_wakealarm); | ||
182 | if (err) { | ||
183 | dev_err(class_dev->dev, "failed to create %s\n", | ||
184 | "alarm attribute"); | ||
185 | sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | return err; | ||
190 | } | 182 | } |
191 | 183 | ||
192 | static void rtc_sysfs_remove_device(struct class_device *class_dev, | 184 | void rtc_sysfs_del_device(struct rtc_device *rtc) |
193 | struct class_interface *class_intf) | ||
194 | { | 185 | { |
195 | if (rtc_does_wakealarm(class_dev)) | 186 | /* REVISIT did we add it successfully? */ |
196 | class_device_remove_file(class_dev, | 187 | if (rtc_does_wakealarm(rtc)) |
197 | &class_device_attr_wakealarm); | 188 | device_remove_file(&rtc->dev, &dev_attr_wakealarm); |
198 | sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); | ||
199 | } | 189 | } |
200 | 190 | ||
201 | /* interface registration */ | 191 | void __init rtc_sysfs_init(struct class *rtc_class) |
202 | |||
203 | static struct class_interface rtc_sysfs_interface = { | ||
204 | .add = &rtc_sysfs_add_device, | ||
205 | .remove = &rtc_sysfs_remove_device, | ||
206 | }; | ||
207 | |||
208 | static int __init rtc_sysfs_init(void) | ||
209 | { | 192 | { |
210 | return rtc_interface_register(&rtc_sysfs_interface); | 193 | rtc_class->dev_attrs = rtc_attrs; |
211 | } | 194 | } |
212 | |||
213 | static void __exit rtc_sysfs_exit(void) | ||
214 | { | ||
215 | class_interface_unregister(&rtc_sysfs_interface); | ||
216 | } | ||
217 | |||
218 | subsys_initcall(rtc_sysfs_init); | ||
219 | module_exit(rtc_sysfs_exit); | ||
220 | |||
221 | MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); | ||
222 | MODULE_DESCRIPTION("RTC class sysfs interface"); | ||
223 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index f50a1b8e1607..254c9fce27da 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -101,11 +101,11 @@ static ssize_t test_irq_store(struct device *dev, | |||
101 | retval = count; | 101 | retval = count; |
102 | local_irq_disable(); | 102 | local_irq_disable(); |
103 | if (strncmp(buf, "tick", 4) == 0) | 103 | if (strncmp(buf, "tick", 4) == 0) |
104 | rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); | 104 | rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF); |
105 | else if (strncmp(buf, "alarm", 5) == 0) | 105 | else if (strncmp(buf, "alarm", 5) == 0) |
106 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF); | 106 | rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); |
107 | else if (strncmp(buf, "update", 6) == 0) | 107 | else if (strncmp(buf, "update", 6) == 0) |
108 | rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); | 108 | rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF); |
109 | else | 109 | else |
110 | retval = -EINVAL; | 110 | retval = -EINVAL; |
111 | local_irq_enable(); | 111 | local_irq_enable(); |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index e40322b71938..af7596ef29e2 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(rtc_lock); | |||
97 | static char rtc_name[] = "RTC"; | 97 | static char rtc_name[] = "RTC"; |
98 | static unsigned long periodic_frequency; | 98 | static unsigned long periodic_frequency; |
99 | static unsigned long periodic_count; | 99 | static unsigned long periodic_count; |
100 | static unsigned int alarm_enabled; | ||
100 | 101 | ||
101 | struct resource rtc_resource[2] = { | 102 | struct resource rtc_resource[2] = { |
102 | { .name = rtc_name, | 103 | { .name = rtc_name, |
@@ -188,6 +189,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
188 | low = rtc1_read(ECMPLREG); | 189 | low = rtc1_read(ECMPLREG); |
189 | mid = rtc1_read(ECMPMREG); | 190 | mid = rtc1_read(ECMPMREG); |
190 | high = rtc1_read(ECMPHREG); | 191 | high = rtc1_read(ECMPHREG); |
192 | wkalrm->enabled = alarm_enabled; | ||
191 | 193 | ||
192 | spin_unlock_irq(&rtc_lock); | 194 | spin_unlock_irq(&rtc_lock); |
193 | 195 | ||
@@ -206,10 +208,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
206 | 208 | ||
207 | spin_lock_irq(&rtc_lock); | 209 | spin_lock_irq(&rtc_lock); |
208 | 210 | ||
211 | if (alarm_enabled) | ||
212 | disable_irq(ELAPSEDTIME_IRQ); | ||
213 | |||
209 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); | 214 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); |
210 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); | 215 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); |
211 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); | 216 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); |
212 | 217 | ||
218 | if (wkalrm->enabled) | ||
219 | enable_irq(ELAPSEDTIME_IRQ); | ||
220 | |||
221 | alarm_enabled = wkalrm->enabled; | ||
222 | |||
213 | spin_unlock_irq(&rtc_lock); | 223 | spin_unlock_irq(&rtc_lock); |
214 | 224 | ||
215 | return 0; | 225 | return 0; |
@@ -221,10 +231,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
221 | 231 | ||
222 | switch (cmd) { | 232 | switch (cmd) { |
223 | case RTC_AIE_ON: | 233 | case RTC_AIE_ON: |
224 | enable_irq(ELAPSEDTIME_IRQ); | 234 | spin_lock_irq(&rtc_lock); |
235 | |||
236 | if (!alarm_enabled) { | ||
237 | enable_irq(ELAPSEDTIME_IRQ); | ||
238 | alarm_enabled = 1; | ||
239 | } | ||
240 | |||
241 | spin_unlock_irq(&rtc_lock); | ||
225 | break; | 242 | break; |
226 | case RTC_AIE_OFF: | 243 | case RTC_AIE_OFF: |
227 | disable_irq(ELAPSEDTIME_IRQ); | 244 | spin_lock_irq(&rtc_lock); |
245 | |||
246 | if (alarm_enabled) { | ||
247 | disable_irq(ELAPSEDTIME_IRQ); | ||
248 | alarm_enabled = 0; | ||
249 | } | ||
250 | |||
251 | spin_unlock_irq(&rtc_lock); | ||
228 | break; | 252 | break; |
229 | case RTC_PIE_ON: | 253 | case RTC_PIE_ON: |
230 | enable_irq(RTCLONG1_IRQ); | 254 | enable_irq(RTCLONG1_IRQ); |
@@ -275,7 +299,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) | |||
275 | 299 | ||
276 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); | 300 | rtc2_write(RTCINTREG, ELAPSEDTIME_INT); |
277 | 301 | ||
278 | rtc_update_irq(&rtc->class_dev, 1, RTC_AF); | 302 | rtc_update_irq(rtc, 1, RTC_AF); |
279 | 303 | ||
280 | return IRQ_HANDLED; | 304 | return IRQ_HANDLED; |
281 | } | 305 | } |
@@ -291,7 +315,7 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id) | |||
291 | rtc1_write(RTCL1LREG, count); | 315 | rtc1_write(RTCL1LREG, count); |
292 | rtc1_write(RTCL1HREG, count >> 16); | 316 | rtc1_write(RTCL1HREG, count >> 16); |
293 | 317 | ||
294 | rtc_update_irq(&rtc->class_dev, 1, RTC_PF); | 318 | rtc_update_irq(rtc, 1, RTC_PF); |
295 | 319 | ||
296 | return IRQ_HANDLED; | 320 | return IRQ_HANDLED; |
297 | } | 321 | } |
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index a39ee80c9715..74b999d77bbf 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
20 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
21 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c index 94d185829119..18d18f1a114e 100644 --- a/drivers/sbus/char/rtc.c +++ b/drivers/sbus/char/rtc.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/fcntl.h> | 19 | #include <linux/fcntl.h> |
20 | #include <linux/poll.h> | 20 | #include <linux/poll.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <asm/io.h> | 22 | #include <asm/io.h> |
24 | #include <asm/mostek.h> | 23 | #include <asm/mostek.h> |
25 | #include <asm/system.h> | 24 | #include <asm/system.h> |
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index c3135e2fbd5a..6afc7e5df0d4 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/smp_lock.h> | ||
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
26 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 9218f29314fa..ad9761b237dc 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/delay.h> | 47 | #include <linux/delay.h> |
48 | #include <linux/ioport.h> | 48 | #include <linux/ioport.h> |
49 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/interrupt.h> | 50 | #include <linux/interrupt.h> |
52 | #include <linux/module.h> | 51 | #include <linux/module.h> |
53 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 85ae5d836fa4..8fee7edc6eb3 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h | |||
@@ -64,7 +64,6 @@ | |||
64 | #include <linux/delay.h> | 64 | #include <linux/delay.h> |
65 | #include <linux/ioport.h> | 65 | #include <linux/ioport.h> |
66 | #include <linux/pci.h> | 66 | #include <linux/pci.h> |
67 | #include <linux/smp_lock.h> | ||
68 | #include <linux/interrupt.h> | 67 | #include <linux/interrupt.h> |
69 | #include <linux/module.h> | 68 | #include <linux/module.h> |
70 | #include <linux/slab.h> | 69 | #include <linux/slab.h> |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index f7b9dbd64a96..fb6433a56989 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -55,7 +55,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); | |||
55 | #include <linux/sched.h> | 55 | #include <linux/sched.h> |
56 | #include <linux/reboot.h> | 56 | #include <linux/reboot.h> |
57 | #include <linux/spinlock.h> | 57 | #include <linux/spinlock.h> |
58 | #include <linux/smp_lock.h> | ||
59 | #include <linux/dma-mapping.h> | 58 | #include <linux/dma-mapping.h> |
60 | 59 | ||
61 | #include <linux/timer.h> | 60 | #include <linux/timer.h> |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3e2930b7ee23..06229f225ee9 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/smp_lock.h> | ||
40 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
41 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
42 | 41 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 570977cf9efb..0c691a60a756 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -41,7 +41,6 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
41 | #include <linux/fcntl.h> | 41 | #include <linux/fcntl.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/poll.h> | 43 | #include <linux/poll.h> |
44 | #include <linux/smp_lock.h> | ||
45 | #include <linux/moduleparam.h> | 44 | #include <linux/moduleparam.h> |
46 | #include <linux/cdev.h> | 45 | #include <linux/cdev.h> |
47 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index 6bc505115841..a7dfb65fb842 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c | |||
@@ -98,7 +98,7 @@ static int __init snirm710_probe(struct platform_device *dev) | |||
98 | host->this_id = 7; | 98 | host->this_id = 7; |
99 | host->base = base; | 99 | host->base = base; |
100 | host->irq = platform_get_irq(dev, 0); | 100 | host->irq = platform_get_irq(dev, 0); |
101 | if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) { | 101 | if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) { |
102 | printk(KERN_ERR "snirm710: request_irq failed!\n"); | 102 | printk(KERN_ERR "snirm710: request_irq failed!\n"); |
103 | goto out_put_host; | 103 | goto out_put_host; |
104 | } | 104 | } |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c9832d963f1e..48e259a0167d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -994,7 +994,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
994 | * be frobbing the chips IRQ enable register to see if it exists. | 994 | * be frobbing the chips IRQ enable register to see if it exists. |
995 | */ | 995 | */ |
996 | spin_lock_irqsave(&up->port.lock, flags); | 996 | spin_lock_irqsave(&up->port.lock, flags); |
997 | // save_flags(flags); cli(); | ||
998 | 997 | ||
999 | up->capabilities = 0; | 998 | up->capabilities = 0; |
1000 | up->bugs = 0; | 999 | up->bugs = 0; |
@@ -1151,7 +1150,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) | |||
1151 | 1150 | ||
1152 | out: | 1151 | out: |
1153 | spin_unlock_irqrestore(&up->port.lock, flags); | 1152 | spin_unlock_irqrestore(&up->port.lock, flags); |
1154 | // restore_flags(flags); | ||
1155 | DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); | 1153 | DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); |
1156 | } | 1154 | } |
1157 | 1155 | ||
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 924e9bd757f0..e8efe938c4e7 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -73,17 +73,21 @@ config SERIAL_8250_PCI | |||
73 | depends on SERIAL_8250 && PCI | 73 | depends on SERIAL_8250 && PCI |
74 | default SERIAL_8250 | 74 | default SERIAL_8250 |
75 | help | 75 | help |
76 | This builds standard PCI serial support. You may be able to | 76 | Say Y here if you have PCI serial ports. |
77 | disable this feature if you only need legacy serial support. | 77 | |
78 | Saves about 9K. | 78 | To compile this driver as a module, choose M here: the module |
79 | will be called 8250_pci. | ||
79 | 80 | ||
80 | config SERIAL_8250_PNP | 81 | config SERIAL_8250_PNP |
81 | tristate "8250/16550 PNP device support" if EMBEDDED | 82 | tristate "8250/16550 PNP device support" if EMBEDDED |
82 | depends on SERIAL_8250 && PNP | 83 | depends on SERIAL_8250 && PNP |
83 | default SERIAL_8250 | 84 | default SERIAL_8250 |
84 | help | 85 | help |
85 | This builds standard PNP serial support. You may be able to | 86 | Say Y here if you have serial ports described by PNPBIOS or ACPI. |
86 | disable this feature if you only need legacy serial support. | 87 | These are typically ports built into the system board. |
88 | |||
89 | To compile this driver as a module, choose M here: the module | ||
90 | will be called 8250_pnp. | ||
87 | 91 | ||
88 | config SERIAL_8250_HP300 | 92 | config SERIAL_8250_HP300 |
89 | tristate | 93 | tristate |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 7a3b97fdf8d1..f23972bc00c0 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -934,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
934 | .irq = SMC1_IRQ, | 934 | .irq = SMC1_IRQ, |
935 | .ops = &cpm_uart_pops, | 935 | .ops = &cpm_uart_pops, |
936 | .iotype = UPIO_MEM, | 936 | .iotype = UPIO_MEM, |
937 | .lock = SPIN_LOCK_UNLOCKED, | 937 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock), |
938 | }, | 938 | }, |
939 | .flags = FLAG_SMC, | 939 | .flags = FLAG_SMC, |
940 | .tx_nrfifos = TX_NUM_FIFO, | 940 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -948,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
948 | .irq = SMC2_IRQ, | 948 | .irq = SMC2_IRQ, |
949 | .ops = &cpm_uart_pops, | 949 | .ops = &cpm_uart_pops, |
950 | .iotype = UPIO_MEM, | 950 | .iotype = UPIO_MEM, |
951 | .lock = SPIN_LOCK_UNLOCKED, | 951 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock), |
952 | }, | 952 | }, |
953 | .flags = FLAG_SMC, | 953 | .flags = FLAG_SMC, |
954 | .tx_nrfifos = TX_NUM_FIFO, | 954 | .tx_nrfifos = TX_NUM_FIFO, |
@@ -965,7 +965,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
965 | .irq = SCC1_IRQ, | 965 | .irq = SCC1_IRQ, |
966 | .ops = &cpm_uart_pops, | 966 | .ops = &cpm_uart_pops, |
967 | .iotype = UPIO_MEM, | 967 | .iotype = UPIO_MEM, |
968 | .lock = SPIN_LOCK_UNLOCKED, | 968 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock), |
969 | }, | 969 | }, |
970 | .tx_nrfifos = TX_NUM_FIFO, | 970 | .tx_nrfifos = TX_NUM_FIFO, |
971 | .tx_fifosize = TX_BUF_SIZE, | 971 | .tx_fifosize = TX_BUF_SIZE, |
@@ -979,7 +979,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
979 | .irq = SCC2_IRQ, | 979 | .irq = SCC2_IRQ, |
980 | .ops = &cpm_uart_pops, | 980 | .ops = &cpm_uart_pops, |
981 | .iotype = UPIO_MEM, | 981 | .iotype = UPIO_MEM, |
982 | .lock = SPIN_LOCK_UNLOCKED, | 982 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock), |
983 | }, | 983 | }, |
984 | .tx_nrfifos = TX_NUM_FIFO, | 984 | .tx_nrfifos = TX_NUM_FIFO, |
985 | .tx_fifosize = TX_BUF_SIZE, | 985 | .tx_fifosize = TX_BUF_SIZE, |
@@ -993,7 +993,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
993 | .irq = SCC3_IRQ, | 993 | .irq = SCC3_IRQ, |
994 | .ops = &cpm_uart_pops, | 994 | .ops = &cpm_uart_pops, |
995 | .iotype = UPIO_MEM, | 995 | .iotype = UPIO_MEM, |
996 | .lock = SPIN_LOCK_UNLOCKED, | 996 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock), |
997 | }, | 997 | }, |
998 | .tx_nrfifos = TX_NUM_FIFO, | 998 | .tx_nrfifos = TX_NUM_FIFO, |
999 | .tx_fifosize = TX_BUF_SIZE, | 999 | .tx_fifosize = TX_BUF_SIZE, |
@@ -1007,7 +1007,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
1007 | .irq = SCC4_IRQ, | 1007 | .irq = SCC4_IRQ, |
1008 | .ops = &cpm_uart_pops, | 1008 | .ops = &cpm_uart_pops, |
1009 | .iotype = UPIO_MEM, | 1009 | .iotype = UPIO_MEM, |
1010 | .lock = SPIN_LOCK_UNLOCKED, | 1010 | .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock), |
1011 | }, | 1011 | }, |
1012 | .tx_nrfifos = TX_NUM_FIFO, | 1012 | .tx_nrfifos = TX_NUM_FIFO, |
1013 | .tx_fifosize = TX_BUF_SIZE, | 1013 | .tx_fifosize = TX_BUF_SIZE, |
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 246c5572667b..6202995e8211 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
49 | #include <linux/smp.h> | 49 | #include <linux/smp.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
52 | #include <linux/kobject.h> | 51 | #include <linux/kobject.h> |
53 | #include <linux/firmware.h> | 52 | #include <linux/firmware.h> |
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c index 8be8da37f629..b2d6f5b1a7c2 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/serial/jsm/jsm_neo.c | |||
@@ -581,8 +581,13 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) | |||
581 | return; | 581 | return; |
582 | 582 | ||
583 | /* Scrub off lower bits. They signify delta's, which I don't care about */ | 583 | /* Scrub off lower bits. They signify delta's, which I don't care about */ |
584 | msignals &= 0xf0; | 584 | /* Keep DDCD and DDSR though */ |
585 | msignals &= 0xf8; | ||
585 | 586 | ||
587 | if (msignals & UART_MSR_DDCD) | ||
588 | uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD); | ||
589 | if (msignals & UART_MSR_DDSR) | ||
590 | uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS); | ||
586 | if (msignals & UART_MSR_DCD) | 591 | if (msignals & UART_MSR_DCD) |
587 | ch->ch_mistat |= UART_MSR_DCD; | 592 | ch->ch_mistat |= UART_MSR_DCD; |
588 | else | 593 | else |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index be22bbdbc8e5..281f23a371b2 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
@@ -448,6 +448,7 @@ int jsm_uart_port_init(struct jsm_board *brd) | |||
448 | continue; | 448 | continue; |
449 | 449 | ||
450 | brd->channels[i]->uart_port.irq = brd->irq; | 450 | brd->channels[i]->uart_port.irq = brd->irq; |
451 | brd->channels[i]->uart_port.uartclk = 14745600; | ||
451 | brd->channels[i]->uart_port.type = PORT_JSM; | 452 | brd->channels[i]->uart_port.type = PORT_JSM; |
452 | brd->channels[i]->uart_port.iotype = UPIO_MEM; | 453 | brd->channels[i]->uart_port.iotype = UPIO_MEM; |
453 | brd->channels[i]->uart_port.membase = brd->re_map_membase; | 454 | brd->channels[i]->uart_port.membase = brd->re_map_membase; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 3ba9208ebd0c..10bc0209cd66 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -957,7 +957,7 @@ static struct uart_driver s3c24xx_uart_drv = { | |||
957 | static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { | 957 | static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { |
958 | [0] = { | 958 | [0] = { |
959 | .port = { | 959 | .port = { |
960 | .lock = SPIN_LOCK_UNLOCKED, | 960 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), |
961 | .iotype = UPIO_MEM, | 961 | .iotype = UPIO_MEM, |
962 | .irq = IRQ_S3CUART_RX0, | 962 | .irq = IRQ_S3CUART_RX0, |
963 | .uartclk = 0, | 963 | .uartclk = 0, |
@@ -969,7 +969,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { | |||
969 | }, | 969 | }, |
970 | [1] = { | 970 | [1] = { |
971 | .port = { | 971 | .port = { |
972 | .lock = SPIN_LOCK_UNLOCKED, | 972 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), |
973 | .iotype = UPIO_MEM, | 973 | .iotype = UPIO_MEM, |
974 | .irq = IRQ_S3CUART_RX1, | 974 | .irq = IRQ_S3CUART_RX1, |
975 | .uartclk = 0, | 975 | .uartclk = 0, |
@@ -983,7 +983,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { | |||
983 | 983 | ||
984 | [2] = { | 984 | [2] = { |
985 | .port = { | 985 | .port = { |
986 | .lock = SPIN_LOCK_UNLOCKED, | 986 | .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), |
987 | .iotype = UPIO_MEM, | 987 | .iotype = UPIO_MEM, |
988 | .irq = IRQ_S3CUART_RX2, | 988 | .irq = IRQ_S3CUART_RX2, |
989 | .uartclk = 0, | 989 | .uartclk = 0, |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 509ace7e6881..1deb5764326d 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -15,31 +15,6 @@ | |||
15 | * published by the Free Software Foundation. | 15 | * published by the Free Software Foundation. |
16 | * | 16 | * |
17 | * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller | 17 | * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller |
18 | * | ||
19 | * Revision History: | ||
20 | * 0.30 Initial revision. (Renamed from serial_txx927.c) | ||
21 | * 0.31 Use save_flags instead of local_irq_save. | ||
22 | * 0.32 Support SCLK. | ||
23 | * 0.33 Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL. | ||
24 | * Support TIOCSERGETLSR. | ||
25 | * 0.34 Support slow baudrate. | ||
26 | * 0.40 Merge codes from mainstream kernel (2.4.22). | ||
27 | * 0.41 Fix console checking in rs_shutdown_port(). | ||
28 | * Disable flow-control in serial_console_write(). | ||
29 | * 0.42 Fix minor compiler warning. | ||
30 | * 1.00 Kernel 2.6. Converted to new serial core (based on 8250.c). | ||
31 | * 1.01 Set fifosize to make tx_empry called properly. | ||
32 | * Use standard uart_get_divisor. | ||
33 | * 1.02 Cleanup. (import 8250.c changes) | ||
34 | * 1.03 Fix low-latency mode. (import 8250.c changes) | ||
35 | * 1.04 Remove usage of deprecated functions, cleanup. | ||
36 | * 1.05 More strict check in verify_port. Cleanup. | ||
37 | * 1.06 Do not insert a char caused previous overrun. | ||
38 | * Fix some spin_locks. | ||
39 | * Do not call uart_add_one_port for absent ports. | ||
40 | * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. | ||
41 | * 1.08 Use platform_device. | ||
42 | * Fix and cleanup suspend/resume/initialization codes. | ||
43 | */ | 18 | */ |
44 | 19 | ||
45 | #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 20 | #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
@@ -62,7 +37,7 @@ | |||
62 | 37 | ||
63 | #include <asm/io.h> | 38 | #include <asm/io.h> |
64 | 39 | ||
65 | static char *serial_version = "1.08"; | 40 | static char *serial_version = "1.09"; |
66 | static char *serial_name = "TX39/49 Serial driver"; | 41 | static char *serial_name = "TX39/49 Serial driver"; |
67 | 42 | ||
68 | #define PASS_LIMIT 256 | 43 | #define PASS_LIMIT 256 |
@@ -70,13 +45,14 @@ static char *serial_name = "TX39/49 Serial driver"; | |||
70 | #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) | 45 | #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) |
71 | /* "ttyS" is used for standard serial driver */ | 46 | /* "ttyS" is used for standard serial driver */ |
72 | #define TXX9_TTY_NAME "ttyTX" | 47 | #define TXX9_TTY_NAME "ttyTX" |
73 | #define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ | 48 | #define TXX9_TTY_MINOR_START 196 |
49 | #define TXX9_TTY_MAJOR 204 | ||
74 | #else | 50 | #else |
75 | /* acts like standard serial driver */ | 51 | /* acts like standard serial driver */ |
76 | #define TXX9_TTY_NAME "ttyS" | 52 | #define TXX9_TTY_NAME "ttyS" |
77 | #define TXX9_TTY_MINOR_START 64 | 53 | #define TXX9_TTY_MINOR_START 64 |
78 | #endif | ||
79 | #define TXX9_TTY_MAJOR TTY_MAJOR | 54 | #define TXX9_TTY_MAJOR TTY_MAJOR |
55 | #endif | ||
80 | 56 | ||
81 | /* flag aliases */ | 57 | /* flag aliases */ |
82 | #define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART | 58 | #define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4a012d9acbff..07c587ec71be 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -64,6 +64,17 @@ config SPI_BFIN | |||
64 | help | 64 | help |
65 | This is the SPI controller master driver for Blackfin 5xx processor. | 65 | This is the SPI controller master driver for Blackfin 5xx processor. |
66 | 66 | ||
67 | config SPI_AU1550 | ||
68 | tristate "Au1550/Au12x0 SPI Controller" | ||
69 | depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL | ||
70 | select SPI_BITBANG | ||
71 | help | ||
72 | If you say yes to this option, support will be included for the | ||
73 | Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). | ||
74 | |||
75 | This driver can also be built as a module. If so, the module | ||
76 | will be called au1550_spi. | ||
77 | |||
67 | config SPI_BITBANG | 78 | config SPI_BITBANG |
68 | tristate "Bitbanging SPI master" | 79 | tristate "Bitbanging SPI master" |
69 | depends on SPI_MASTER && EXPERIMENTAL | 80 | depends on SPI_MASTER && EXPERIMENTAL |
@@ -159,6 +170,15 @@ config SPI_AT25 | |||
159 | This driver can also be built as a module. If so, the module | 170 | This driver can also be built as a module. If so, the module |
160 | will be called at25. | 171 | will be called at25. |
161 | 172 | ||
173 | config SPI_SPIDEV | ||
174 | tristate "User mode SPI device driver support" | ||
175 | depends on SPI_MASTER && EXPERIMENTAL | ||
176 | help | ||
177 | This supports user mode SPI protocol drivers. | ||
178 | |||
179 | Note that this application programming interface is EXPERIMENTAL | ||
180 | and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. | ||
181 | |||
162 | # | 182 | # |
163 | # Add new SPI protocol masters in alphabetical order above this line | 183 | # Add new SPI protocol masters in alphabetical order above this line |
164 | # | 184 | # |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a95ade857a2f..624b6363f490 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o | |||
14 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o | 14 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o |
15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o | 15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o |
16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o | 16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o |
17 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o | ||
17 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o | 18 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o |
18 | obj-$(CONFIG_SPI_IMX) += spi_imx.o | 19 | obj-$(CONFIG_SPI_IMX) += spi_imx.o |
19 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o | 20 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o |
@@ -25,6 +26,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o | |||
25 | 26 | ||
26 | # SPI protocol drivers (device/link on bus) | 27 | # SPI protocol drivers (device/link on bus) |
27 | obj-$(CONFIG_SPI_AT25) += at25.o | 28 | obj-$(CONFIG_SPI_AT25) += at25.o |
29 | obj-$(CONFIG_SPI_SPIDEV) += spidev.o | ||
28 | # ... add above this line ... | 30 | # ... add above this line ... |
29 | 31 | ||
30 | # SPI slave controller drivers (upstream link) | 32 | # SPI slave controller drivers (upstream link) |
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c new file mode 100644 index 000000000000..ae2b1af0dba4 --- /dev/null +++ b/drivers/spi/au1550_spi.c | |||
@@ -0,0 +1,974 @@ | |||
1 | /* | ||
2 | * au1550_spi.c - au1550 psc spi controller driver | ||
3 | * may work also with au1200, au1210, au1250 | ||
4 | * will not work on au1000, au1100 and au1500 (no full spi controller there) | ||
5 | * | ||
6 | * Copyright (c) 2006 ATRON electronic GmbH | ||
7 | * Author: Jan Nikitenko <jan.nikitenko@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/spi/spi.h> | ||
30 | #include <linux/spi/spi_bitbang.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/completion.h> | ||
33 | #include <asm/mach-au1x00/au1000.h> | ||
34 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
35 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
36 | |||
37 | #include <asm/mach-au1x00/au1550_spi.h> | ||
38 | |||
39 | static unsigned usedma = 1; | ||
40 | module_param(usedma, uint, 0644); | ||
41 | |||
42 | /* | ||
43 | #define AU1550_SPI_DEBUG_LOOPBACK | ||
44 | */ | ||
45 | |||
46 | |||
47 | #define AU1550_SPI_DBDMA_DESCRIPTORS 1 | ||
48 | #define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U | ||
49 | |||
50 | struct au1550_spi { | ||
51 | struct spi_bitbang bitbang; | ||
52 | |||
53 | volatile psc_spi_t __iomem *regs; | ||
54 | int irq; | ||
55 | unsigned freq_max; | ||
56 | unsigned freq_min; | ||
57 | |||
58 | unsigned len; | ||
59 | unsigned tx_count; | ||
60 | unsigned rx_count; | ||
61 | const u8 *tx; | ||
62 | u8 *rx; | ||
63 | |||
64 | void (*rx_word)(struct au1550_spi *hw); | ||
65 | void (*tx_word)(struct au1550_spi *hw); | ||
66 | int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); | ||
67 | irqreturn_t (*irq_callback)(struct au1550_spi *hw); | ||
68 | |||
69 | struct completion master_done; | ||
70 | |||
71 | unsigned usedma; | ||
72 | u32 dma_tx_id; | ||
73 | u32 dma_rx_id; | ||
74 | u32 dma_tx_ch; | ||
75 | u32 dma_rx_ch; | ||
76 | |||
77 | u8 *dma_rx_tmpbuf; | ||
78 | unsigned dma_rx_tmpbuf_size; | ||
79 | u32 dma_rx_tmpbuf_addr; | ||
80 | |||
81 | struct spi_master *master; | ||
82 | struct device *dev; | ||
83 | struct au1550_spi_info *pdata; | ||
84 | }; | ||
85 | |||
86 | |||
87 | /* we use an 8-bit memory device for dma transfers to/from spi fifo */ | ||
88 | static dbdev_tab_t au1550_spi_mem_dbdev = | ||
89 | { | ||
90 | .dev_id = DBDMA_MEM_CHAN, | ||
91 | .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC, | ||
92 | .dev_tsize = 0, | ||
93 | .dev_devwidth = 8, | ||
94 | .dev_physaddr = 0x00000000, | ||
95 | .dev_intlevel = 0, | ||
96 | .dev_intpolarity = 0 | ||
97 | }; | ||
98 | |||
99 | static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); | ||
100 | |||
101 | |||
102 | /** | ||
103 | * compute BRG and DIV bits to setup spi clock based on main input clock rate | ||
104 | * that was specified in platform data structure | ||
105 | * according to au1550 datasheet: | ||
106 | * psc_tempclk = psc_mainclk / (2 << DIV) | ||
107 | * spiclk = psc_tempclk / (2 * (BRG + 1)) | ||
108 | * BRG valid range is 4..63 | ||
109 | * DIV valid range is 0..3 | ||
110 | */ | ||
111 | static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz) | ||
112 | { | ||
113 | u32 mainclk_hz = hw->pdata->mainclk_hz; | ||
114 | u32 div, brg; | ||
115 | |||
116 | for (div = 0; div < 4; div++) { | ||
117 | brg = mainclk_hz / speed_hz / (4 << div); | ||
118 | /* now we have BRG+1 in brg, so count with that */ | ||
119 | if (brg < (4 + 1)) { | ||
120 | brg = (4 + 1); /* speed_hz too big */ | ||
121 | break; /* set lowest brg (div is == 0) */ | ||
122 | } | ||
123 | if (brg <= (63 + 1)) | ||
124 | break; /* we have valid brg and div */ | ||
125 | } | ||
126 | if (div == 4) { | ||
127 | div = 3; /* speed_hz too small */ | ||
128 | brg = (63 + 1); /* set highest brg and div */ | ||
129 | } | ||
130 | brg--; | ||
131 | return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div); | ||
132 | } | ||
133 | |||
134 | static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) | ||
135 | { | ||
136 | hw->regs->psc_spimsk = | ||
137 | PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO | ||
138 | | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO | ||
139 | | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; | ||
140 | au_sync(); | ||
141 | |||
142 | hw->regs->psc_spievent = | ||
143 | PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO | ||
144 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO | ||
145 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; | ||
146 | au_sync(); | ||
147 | } | ||
148 | |||
149 | static void au1550_spi_reset_fifos(struct au1550_spi *hw) | ||
150 | { | ||
151 | u32 pcr; | ||
152 | |||
153 | hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; | ||
154 | au_sync(); | ||
155 | do { | ||
156 | pcr = hw->regs->psc_spipcr; | ||
157 | au_sync(); | ||
158 | } while (pcr != 0); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * dma transfers are used for the most common spi word size of 8-bits | ||
163 | * we cannot easily change already set up dma channels' width, so if we wanted | ||
164 | * dma support for more than 8-bit words (up to 24 bits), we would need to | ||
165 | * setup dma channels from scratch on each spi transfer, based on bits_per_word | ||
166 | * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits | ||
167 | * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode | ||
168 | * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set() | ||
169 | */ | ||
170 | static void au1550_spi_chipsel(struct spi_device *spi, int value) | ||
171 | { | ||
172 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
173 | unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; | ||
174 | u32 cfg, stat; | ||
175 | |||
176 | switch (value) { | ||
177 | case BITBANG_CS_INACTIVE: | ||
178 | if (hw->pdata->deactivate_cs) | ||
179 | hw->pdata->deactivate_cs(hw->pdata, spi->chip_select, | ||
180 | cspol); | ||
181 | break; | ||
182 | |||
183 | case BITBANG_CS_ACTIVE: | ||
184 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); | ||
185 | |||
186 | cfg = hw->regs->psc_spicfg; | ||
187 | au_sync(); | ||
188 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; | ||
189 | au_sync(); | ||
190 | |||
191 | if (spi->mode & SPI_CPOL) | ||
192 | cfg |= PSC_SPICFG_BI; | ||
193 | else | ||
194 | cfg &= ~PSC_SPICFG_BI; | ||
195 | if (spi->mode & SPI_CPHA) | ||
196 | cfg &= ~PSC_SPICFG_CDE; | ||
197 | else | ||
198 | cfg |= PSC_SPICFG_CDE; | ||
199 | |||
200 | if (spi->mode & SPI_LSB_FIRST) | ||
201 | cfg |= PSC_SPICFG_MLF; | ||
202 | else | ||
203 | cfg &= ~PSC_SPICFG_MLF; | ||
204 | |||
205 | if (hw->usedma && spi->bits_per_word <= 8) | ||
206 | cfg &= ~PSC_SPICFG_DD_DISABLE; | ||
207 | else | ||
208 | cfg |= PSC_SPICFG_DD_DISABLE; | ||
209 | cfg = PSC_SPICFG_CLR_LEN(cfg); | ||
210 | cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word); | ||
211 | |||
212 | cfg = PSC_SPICFG_CLR_BAUD(cfg); | ||
213 | cfg &= ~PSC_SPICFG_SET_DIV(3); | ||
214 | cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); | ||
215 | |||
216 | hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; | ||
217 | au_sync(); | ||
218 | do { | ||
219 | stat = hw->regs->psc_spistat; | ||
220 | au_sync(); | ||
221 | } while ((stat & PSC_SPISTAT_DR) == 0); | ||
222 | |||
223 | if (hw->pdata->activate_cs) | ||
224 | hw->pdata->activate_cs(hw->pdata, spi->chip_select, | ||
225 | cspol); | ||
226 | break; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | ||
231 | { | ||
232 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
233 | unsigned bpw, hz; | ||
234 | u32 cfg, stat; | ||
235 | |||
236 | bpw = t ? t->bits_per_word : spi->bits_per_word; | ||
237 | hz = t ? t->speed_hz : spi->max_speed_hz; | ||
238 | |||
239 | if (bpw < 4 || bpw > 24) { | ||
240 | dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n", | ||
241 | bpw); | ||
242 | return -EINVAL; | ||
243 | } | ||
244 | if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) { | ||
245 | dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n", | ||
246 | hz); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); | ||
251 | |||
252 | cfg = hw->regs->psc_spicfg; | ||
253 | au_sync(); | ||
254 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; | ||
255 | au_sync(); | ||
256 | |||
257 | if (hw->usedma && bpw <= 8) | ||
258 | cfg &= ~PSC_SPICFG_DD_DISABLE; | ||
259 | else | ||
260 | cfg |= PSC_SPICFG_DD_DISABLE; | ||
261 | cfg = PSC_SPICFG_CLR_LEN(cfg); | ||
262 | cfg |= PSC_SPICFG_SET_LEN(bpw); | ||
263 | |||
264 | cfg = PSC_SPICFG_CLR_BAUD(cfg); | ||
265 | cfg &= ~PSC_SPICFG_SET_DIV(3); | ||
266 | cfg |= au1550_spi_baudcfg(hw, hz); | ||
267 | |||
268 | hw->regs->psc_spicfg = cfg; | ||
269 | au_sync(); | ||
270 | |||
271 | if (cfg & PSC_SPICFG_DE_ENABLE) { | ||
272 | do { | ||
273 | stat = hw->regs->psc_spistat; | ||
274 | au_sync(); | ||
275 | } while ((stat & PSC_SPISTAT_DR) == 0); | ||
276 | } | ||
277 | |||
278 | au1550_spi_reset_fifos(hw); | ||
279 | au1550_spi_mask_ack_all(hw); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int au1550_spi_setup(struct spi_device *spi) | ||
284 | { | ||
285 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
286 | |||
287 | if (spi->bits_per_word == 0) | ||
288 | spi->bits_per_word = 8; | ||
289 | if (spi->bits_per_word < 4 || spi->bits_per_word > 24) { | ||
290 | dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n", | ||
291 | spi->bits_per_word); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
295 | if (spi->max_speed_hz == 0) | ||
296 | spi->max_speed_hz = hw->freq_max; | ||
297 | if (spi->max_speed_hz > hw->freq_max | ||
298 | || spi->max_speed_hz < hw->freq_min) | ||
299 | return -EINVAL; | ||
300 | /* | ||
301 | * NOTE: cannot change speed and other hw settings immediately, | ||
302 | * otherwise sharing of spi bus is not possible, | ||
303 | * so do not call setupxfer(spi, NULL) here | ||
304 | */ | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * for dma spi transfers, we have to setup rx channel, otherwise there is | ||
310 | * no reliable way how to recognize that spi transfer is done | ||
311 | * dma complete callbacks are called before real spi transfer is finished | ||
312 | * and if only tx dma channel is set up (and rx fifo overflow event masked) | ||
313 | * spi master done event irq is not generated unless rx fifo is empty (emptied) | ||
314 | * so we need rx tmp buffer to use for rx dma if user does not provide one | ||
315 | */ | ||
316 | static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) | ||
317 | { | ||
318 | hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL); | ||
319 | if (!hw->dma_rx_tmpbuf) | ||
320 | return -ENOMEM; | ||
321 | hw->dma_rx_tmpbuf_size = size; | ||
322 | hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, | ||
323 | size, DMA_FROM_DEVICE); | ||
324 | if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { | ||
325 | kfree(hw->dma_rx_tmpbuf); | ||
326 | hw->dma_rx_tmpbuf = 0; | ||
327 | hw->dma_rx_tmpbuf_size = 0; | ||
328 | return -EFAULT; | ||
329 | } | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw) | ||
334 | { | ||
335 | dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr, | ||
336 | hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE); | ||
337 | kfree(hw->dma_rx_tmpbuf); | ||
338 | hw->dma_rx_tmpbuf = 0; | ||
339 | hw->dma_rx_tmpbuf_size = 0; | ||
340 | } | ||
341 | |||
342 | static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) | ||
343 | { | ||
344 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
345 | dma_addr_t dma_tx_addr; | ||
346 | dma_addr_t dma_rx_addr; | ||
347 | u32 res; | ||
348 | |||
349 | hw->len = t->len; | ||
350 | hw->tx_count = 0; | ||
351 | hw->rx_count = 0; | ||
352 | |||
353 | hw->tx = t->tx_buf; | ||
354 | hw->rx = t->rx_buf; | ||
355 | dma_tx_addr = t->tx_dma; | ||
356 | dma_rx_addr = t->rx_dma; | ||
357 | |||
358 | /* | ||
359 | * check if buffers are already dma mapped, map them otherwise | ||
360 | * use rx buffer in place of tx if tx buffer was not provided | ||
361 | * use temp rx buffer (preallocated or realloc to fit) for rx dma | ||
362 | */ | ||
363 | if (t->rx_buf) { | ||
364 | if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ | ||
365 | dma_rx_addr = dma_map_single(hw->dev, | ||
366 | (void *)t->rx_buf, | ||
367 | t->len, DMA_FROM_DEVICE); | ||
368 | if (dma_mapping_error(dma_rx_addr)) | ||
369 | dev_err(hw->dev, "rx dma map error\n"); | ||
370 | } | ||
371 | } else { | ||
372 | if (t->len > hw->dma_rx_tmpbuf_size) { | ||
373 | int ret; | ||
374 | |||
375 | au1550_spi_dma_rxtmp_free(hw); | ||
376 | ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len, | ||
377 | AU1550_SPI_DMA_RXTMP_MINSIZE)); | ||
378 | if (ret < 0) | ||
379 | return ret; | ||
380 | } | ||
381 | hw->rx = hw->dma_rx_tmpbuf; | ||
382 | dma_rx_addr = hw->dma_rx_tmpbuf_addr; | ||
383 | dma_sync_single_for_device(hw->dev, dma_rx_addr, | ||
384 | t->len, DMA_FROM_DEVICE); | ||
385 | } | ||
386 | if (t->tx_buf) { | ||
387 | if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ | ||
388 | dma_tx_addr = dma_map_single(hw->dev, | ||
389 | (void *)t->tx_buf, | ||
390 | t->len, DMA_TO_DEVICE); | ||
391 | if (dma_mapping_error(dma_tx_addr)) | ||
392 | dev_err(hw->dev, "tx dma map error\n"); | ||
393 | } | ||
394 | } else { | ||
395 | dma_sync_single_for_device(hw->dev, dma_rx_addr, | ||
396 | t->len, DMA_BIDIRECTIONAL); | ||
397 | hw->tx = hw->rx; | ||
398 | } | ||
399 | |||
400 | /* put buffers on the ring */ | ||
401 | res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len); | ||
402 | if (!res) | ||
403 | dev_err(hw->dev, "rx dma put dest error\n"); | ||
404 | |||
405 | res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len); | ||
406 | if (!res) | ||
407 | dev_err(hw->dev, "tx dma put source error\n"); | ||
408 | |||
409 | au1xxx_dbdma_start(hw->dma_rx_ch); | ||
410 | au1xxx_dbdma_start(hw->dma_tx_ch); | ||
411 | |||
412 | /* by default enable nearly all events interrupt */ | ||
413 | hw->regs->psc_spimsk = PSC_SPIMSK_SD; | ||
414 | au_sync(); | ||
415 | |||
416 | /* start the transfer */ | ||
417 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; | ||
418 | au_sync(); | ||
419 | |||
420 | wait_for_completion(&hw->master_done); | ||
421 | |||
422 | au1xxx_dbdma_stop(hw->dma_tx_ch); | ||
423 | au1xxx_dbdma_stop(hw->dma_rx_ch); | ||
424 | |||
425 | if (!t->rx_buf) { | ||
426 | /* using the temporal preallocated and premapped buffer */ | ||
427 | dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len, | ||
428 | DMA_FROM_DEVICE); | ||
429 | } | ||
430 | /* unmap buffers if mapped above */ | ||
431 | if (t->rx_buf && t->rx_dma == 0 ) | ||
432 | dma_unmap_single(hw->dev, dma_rx_addr, t->len, | ||
433 | DMA_FROM_DEVICE); | ||
434 | if (t->tx_buf && t->tx_dma == 0 ) | ||
435 | dma_unmap_single(hw->dev, dma_tx_addr, t->len, | ||
436 | DMA_TO_DEVICE); | ||
437 | |||
438 | return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; | ||
439 | } | ||
440 | |||
441 | static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) | ||
442 | { | ||
443 | u32 stat, evnt; | ||
444 | |||
445 | stat = hw->regs->psc_spistat; | ||
446 | evnt = hw->regs->psc_spievent; | ||
447 | au_sync(); | ||
448 | if ((stat & PSC_SPISTAT_DI) == 0) { | ||
449 | dev_err(hw->dev, "Unexpected IRQ!\n"); | ||
450 | return IRQ_NONE; | ||
451 | } | ||
452 | |||
453 | if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO | ||
454 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO | ||
455 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) | ||
456 | != 0) { | ||
457 | /* | ||
458 | * due to an spi error we consider transfer as done, | ||
459 | * so mask all events until before next transfer start | ||
460 | * and stop the possibly running dma immediatelly | ||
461 | */ | ||
462 | au1550_spi_mask_ack_all(hw); | ||
463 | au1xxx_dbdma_stop(hw->dma_rx_ch); | ||
464 | au1xxx_dbdma_stop(hw->dma_tx_ch); | ||
465 | |||
466 | /* get number of transfered bytes */ | ||
467 | hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch); | ||
468 | hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch); | ||
469 | |||
470 | au1xxx_dbdma_reset(hw->dma_rx_ch); | ||
471 | au1xxx_dbdma_reset(hw->dma_tx_ch); | ||
472 | au1550_spi_reset_fifos(hw); | ||
473 | |||
474 | dev_err(hw->dev, | ||
475 | "Unexpected SPI error: event=0x%x stat=0x%x!\n", | ||
476 | evnt, stat); | ||
477 | |||
478 | complete(&hw->master_done); | ||
479 | return IRQ_HANDLED; | ||
480 | } | ||
481 | |||
482 | if ((evnt & PSC_SPIEVNT_MD) != 0) { | ||
483 | /* transfer completed successfully */ | ||
484 | au1550_spi_mask_ack_all(hw); | ||
485 | hw->rx_count = hw->len; | ||
486 | hw->tx_count = hw->len; | ||
487 | complete(&hw->master_done); | ||
488 | } | ||
489 | return IRQ_HANDLED; | ||
490 | } | ||
491 | |||
492 | |||
493 | /* routines to handle different word sizes in pio mode */ | ||
494 | #define AU1550_SPI_RX_WORD(size, mask) \ | ||
495 | static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ | ||
496 | { \ | ||
497 | u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ | ||
498 | au_sync(); \ | ||
499 | if (hw->rx) { \ | ||
500 | *(u##size *)hw->rx = (u##size)fifoword; \ | ||
501 | hw->rx += (size) / 8; \ | ||
502 | } \ | ||
503 | hw->rx_count += (size) / 8; \ | ||
504 | } | ||
505 | |||
506 | #define AU1550_SPI_TX_WORD(size, mask) \ | ||
507 | static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ | ||
508 | { \ | ||
509 | u32 fifoword = 0; \ | ||
510 | if (hw->tx) { \ | ||
511 | fifoword = *(u##size *)hw->tx & (u32)(mask); \ | ||
512 | hw->tx += (size) / 8; \ | ||
513 | } \ | ||
514 | hw->tx_count += (size) / 8; \ | ||
515 | if (hw->tx_count >= hw->len) \ | ||
516 | fifoword |= PSC_SPITXRX_LC; \ | ||
517 | hw->regs->psc_spitxrx = fifoword; \ | ||
518 | au_sync(); \ | ||
519 | } | ||
520 | |||
521 | AU1550_SPI_RX_WORD(8,0xff) | ||
522 | AU1550_SPI_RX_WORD(16,0xffff) | ||
523 | AU1550_SPI_RX_WORD(32,0xffffff) | ||
524 | AU1550_SPI_TX_WORD(8,0xff) | ||
525 | AU1550_SPI_TX_WORD(16,0xffff) | ||
526 | AU1550_SPI_TX_WORD(32,0xffffff) | ||
527 | |||
528 | static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) | ||
529 | { | ||
530 | u32 stat, mask; | ||
531 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
532 | |||
533 | hw->tx = t->tx_buf; | ||
534 | hw->rx = t->rx_buf; | ||
535 | hw->len = t->len; | ||
536 | hw->tx_count = 0; | ||
537 | hw->rx_count = 0; | ||
538 | |||
539 | /* by default enable nearly all events after filling tx fifo */ | ||
540 | mask = PSC_SPIMSK_SD; | ||
541 | |||
542 | /* fill the transmit FIFO */ | ||
543 | while (hw->tx_count < hw->len) { | ||
544 | |||
545 | hw->tx_word(hw); | ||
546 | |||
547 | if (hw->tx_count >= hw->len) { | ||
548 | /* mask tx fifo request interrupt as we are done */ | ||
549 | mask |= PSC_SPIMSK_TR; | ||
550 | } | ||
551 | |||
552 | stat = hw->regs->psc_spistat; | ||
553 | au_sync(); | ||
554 | if (stat & PSC_SPISTAT_TF) | ||
555 | break; | ||
556 | } | ||
557 | |||
558 | /* enable event interrupts */ | ||
559 | hw->regs->psc_spimsk = mask; | ||
560 | au_sync(); | ||
561 | |||
562 | /* start the transfer */ | ||
563 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; | ||
564 | au_sync(); | ||
565 | |||
566 | wait_for_completion(&hw->master_done); | ||
567 | |||
568 | return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; | ||
569 | } | ||
570 | |||
571 | static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) | ||
572 | { | ||
573 | int busy; | ||
574 | u32 stat, evnt; | ||
575 | |||
576 | stat = hw->regs->psc_spistat; | ||
577 | evnt = hw->regs->psc_spievent; | ||
578 | au_sync(); | ||
579 | if ((stat & PSC_SPISTAT_DI) == 0) { | ||
580 | dev_err(hw->dev, "Unexpected IRQ!\n"); | ||
581 | return IRQ_NONE; | ||
582 | } | ||
583 | |||
584 | if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO | ||
585 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO | ||
586 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) | ||
587 | != 0) { | ||
588 | dev_err(hw->dev, | ||
589 | "Unexpected SPI error: event=0x%x stat=0x%x!\n", | ||
590 | evnt, stat); | ||
591 | /* | ||
592 | * due to an error we consider transfer as done, | ||
593 | * so mask all events until before next transfer start | ||
594 | */ | ||
595 | au1550_spi_mask_ack_all(hw); | ||
596 | au1550_spi_reset_fifos(hw); | ||
597 | complete(&hw->master_done); | ||
598 | return IRQ_HANDLED; | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | * while there is something to read from rx fifo | ||
603 | * or there is a space to write to tx fifo: | ||
604 | */ | ||
605 | do { | ||
606 | busy = 0; | ||
607 | stat = hw->regs->psc_spistat; | ||
608 | au_sync(); | ||
609 | |||
610 | if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) { | ||
611 | hw->rx_word(hw); | ||
612 | /* ack the receive request event */ | ||
613 | hw->regs->psc_spievent = PSC_SPIEVNT_RR; | ||
614 | au_sync(); | ||
615 | busy = 1; | ||
616 | } | ||
617 | |||
618 | if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) { | ||
619 | hw->tx_word(hw); | ||
620 | /* ack the transmit request event */ | ||
621 | hw->regs->psc_spievent = PSC_SPIEVNT_TR; | ||
622 | au_sync(); | ||
623 | busy = 1; | ||
624 | } | ||
625 | } while (busy); | ||
626 | |||
627 | evnt = hw->regs->psc_spievent; | ||
628 | au_sync(); | ||
629 | |||
630 | if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) { | ||
631 | /* transfer completed successfully */ | ||
632 | au1550_spi_mask_ack_all(hw); | ||
633 | complete(&hw->master_done); | ||
634 | } | ||
635 | return IRQ_HANDLED; | ||
636 | } | ||
637 | |||
638 | static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | ||
639 | { | ||
640 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
641 | return hw->txrx_bufs(spi, t); | ||
642 | } | ||
643 | |||
644 | static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs) | ||
645 | { | ||
646 | struct au1550_spi *hw = dev; | ||
647 | return hw->irq_callback(hw); | ||
648 | } | ||
649 | |||
650 | static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw) | ||
651 | { | ||
652 | if (bpw <= 8) { | ||
653 | if (hw->usedma) { | ||
654 | hw->txrx_bufs = &au1550_spi_dma_txrxb; | ||
655 | hw->irq_callback = &au1550_spi_dma_irq_callback; | ||
656 | } else { | ||
657 | hw->rx_word = &au1550_spi_rx_word_8; | ||
658 | hw->tx_word = &au1550_spi_tx_word_8; | ||
659 | hw->txrx_bufs = &au1550_spi_pio_txrxb; | ||
660 | hw->irq_callback = &au1550_spi_pio_irq_callback; | ||
661 | } | ||
662 | } else if (bpw <= 16) { | ||
663 | hw->rx_word = &au1550_spi_rx_word_16; | ||
664 | hw->tx_word = &au1550_spi_tx_word_16; | ||
665 | hw->txrx_bufs = &au1550_spi_pio_txrxb; | ||
666 | hw->irq_callback = &au1550_spi_pio_irq_callback; | ||
667 | } else { | ||
668 | hw->rx_word = &au1550_spi_rx_word_32; | ||
669 | hw->tx_word = &au1550_spi_tx_word_32; | ||
670 | hw->txrx_bufs = &au1550_spi_pio_txrxb; | ||
671 | hw->irq_callback = &au1550_spi_pio_irq_callback; | ||
672 | } | ||
673 | } | ||
674 | |||
675 | static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) | ||
676 | { | ||
677 | u32 stat, cfg; | ||
678 | |||
679 | /* set up the PSC for SPI mode */ | ||
680 | hw->regs->psc_ctrl = PSC_CTRL_DISABLE; | ||
681 | au_sync(); | ||
682 | hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; | ||
683 | au_sync(); | ||
684 | |||
685 | hw->regs->psc_spicfg = 0; | ||
686 | au_sync(); | ||
687 | |||
688 | hw->regs->psc_ctrl = PSC_CTRL_ENABLE; | ||
689 | au_sync(); | ||
690 | |||
691 | do { | ||
692 | stat = hw->regs->psc_spistat; | ||
693 | au_sync(); | ||
694 | } while ((stat & PSC_SPISTAT_SR) == 0); | ||
695 | |||
696 | |||
697 | cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE; | ||
698 | cfg |= PSC_SPICFG_SET_LEN(8); | ||
699 | cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8; | ||
700 | /* use minimal allowed brg and div values as initial setting: */ | ||
701 | cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0); | ||
702 | |||
703 | #ifdef AU1550_SPI_DEBUG_LOOPBACK | ||
704 | cfg |= PSC_SPICFG_LB; | ||
705 | #endif | ||
706 | |||
707 | hw->regs->psc_spicfg = cfg; | ||
708 | au_sync(); | ||
709 | |||
710 | au1550_spi_mask_ack_all(hw); | ||
711 | |||
712 | hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; | ||
713 | au_sync(); | ||
714 | |||
715 | do { | ||
716 | stat = hw->regs->psc_spistat; | ||
717 | au_sync(); | ||
718 | } while ((stat & PSC_SPISTAT_DR) == 0); | ||
719 | } | ||
720 | |||
721 | |||
722 | static int __init au1550_spi_probe(struct platform_device *pdev) | ||
723 | { | ||
724 | struct au1550_spi *hw; | ||
725 | struct spi_master *master; | ||
726 | int err = 0; | ||
727 | |||
728 | master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); | ||
729 | if (master == NULL) { | ||
730 | dev_err(&pdev->dev, "No memory for spi_master\n"); | ||
731 | err = -ENOMEM; | ||
732 | goto err_nomem; | ||
733 | } | ||
734 | |||
735 | hw = spi_master_get_devdata(master); | ||
736 | |||
737 | hw->master = spi_master_get(master); | ||
738 | hw->pdata = pdev->dev.platform_data; | ||
739 | hw->dev = &pdev->dev; | ||
740 | |||
741 | if (hw->pdata == NULL) { | ||
742 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
743 | err = -ENOENT; | ||
744 | goto err_no_pdata; | ||
745 | } | ||
746 | |||
747 | platform_set_drvdata(pdev, hw); | ||
748 | |||
749 | init_completion(&hw->master_done); | ||
750 | |||
751 | hw->bitbang.master = hw->master; | ||
752 | hw->bitbang.setup_transfer = au1550_spi_setupxfer; | ||
753 | hw->bitbang.chipselect = au1550_spi_chipsel; | ||
754 | hw->bitbang.master->setup = au1550_spi_setup; | ||
755 | hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; | ||
756 | |||
757 | switch (hw->pdata->bus_num) { | ||
758 | case 0: | ||
759 | hw->irq = AU1550_PSC0_INT; | ||
760 | hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR; | ||
761 | hw->dma_rx_id = DSCR_CMD0_PSC0_RX; | ||
762 | hw->dma_tx_id = DSCR_CMD0_PSC0_TX; | ||
763 | break; | ||
764 | case 1: | ||
765 | hw->irq = AU1550_PSC1_INT; | ||
766 | hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR; | ||
767 | hw->dma_rx_id = DSCR_CMD0_PSC1_RX; | ||
768 | hw->dma_tx_id = DSCR_CMD0_PSC1_TX; | ||
769 | break; | ||
770 | case 2: | ||
771 | hw->irq = AU1550_PSC2_INT; | ||
772 | hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR; | ||
773 | hw->dma_rx_id = DSCR_CMD0_PSC2_RX; | ||
774 | hw->dma_tx_id = DSCR_CMD0_PSC2_TX; | ||
775 | break; | ||
776 | case 3: | ||
777 | hw->irq = AU1550_PSC3_INT; | ||
778 | hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR; | ||
779 | hw->dma_rx_id = DSCR_CMD0_PSC3_RX; | ||
780 | hw->dma_tx_id = DSCR_CMD0_PSC3_TX; | ||
781 | break; | ||
782 | default: | ||
783 | dev_err(&pdev->dev, "Wrong bus_num of SPI\n"); | ||
784 | err = -ENOENT; | ||
785 | goto err_no_pdata; | ||
786 | } | ||
787 | |||
788 | if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t), | ||
789 | pdev->name) == NULL) { | ||
790 | dev_err(&pdev->dev, "Cannot reserve iomem region\n"); | ||
791 | err = -ENXIO; | ||
792 | goto err_no_iores; | ||
793 | } | ||
794 | |||
795 | |||
796 | if (usedma) { | ||
797 | if (pdev->dev.dma_mask == NULL) | ||
798 | dev_warn(&pdev->dev, "no dma mask\n"); | ||
799 | else | ||
800 | hw->usedma = 1; | ||
801 | } | ||
802 | |||
803 | if (hw->usedma) { | ||
804 | /* | ||
805 | * create memory device with 8 bits dev_devwidth | ||
806 | * needed for proper byte ordering to spi fifo | ||
807 | */ | ||
808 | int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); | ||
809 | if (!memid) { | ||
810 | dev_err(&pdev->dev, | ||
811 | "Cannot create dma 8 bit mem device\n"); | ||
812 | err = -ENXIO; | ||
813 | goto err_dma_add_dev; | ||
814 | } | ||
815 | |||
816 | hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid, | ||
817 | hw->dma_tx_id, NULL, (void *)hw); | ||
818 | if (hw->dma_tx_ch == 0) { | ||
819 | dev_err(&pdev->dev, | ||
820 | "Cannot allocate tx dma channel\n"); | ||
821 | err = -ENXIO; | ||
822 | goto err_no_txdma; | ||
823 | } | ||
824 | au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8); | ||
825 | if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch, | ||
826 | AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { | ||
827 | dev_err(&pdev->dev, | ||
828 | "Cannot allocate tx dma descriptors\n"); | ||
829 | err = -ENXIO; | ||
830 | goto err_no_txdma_descr; | ||
831 | } | ||
832 | |||
833 | |||
834 | hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, | ||
835 | memid, NULL, (void *)hw); | ||
836 | if (hw->dma_rx_ch == 0) { | ||
837 | dev_err(&pdev->dev, | ||
838 | "Cannot allocate rx dma channel\n"); | ||
839 | err = -ENXIO; | ||
840 | goto err_no_rxdma; | ||
841 | } | ||
842 | au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8); | ||
843 | if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch, | ||
844 | AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { | ||
845 | dev_err(&pdev->dev, | ||
846 | "Cannot allocate rx dma descriptors\n"); | ||
847 | err = -ENXIO; | ||
848 | goto err_no_rxdma_descr; | ||
849 | } | ||
850 | |||
851 | err = au1550_spi_dma_rxtmp_alloc(hw, | ||
852 | AU1550_SPI_DMA_RXTMP_MINSIZE); | ||
853 | if (err < 0) { | ||
854 | dev_err(&pdev->dev, | ||
855 | "Cannot allocate initial rx dma tmp buffer\n"); | ||
856 | goto err_dma_rxtmp_alloc; | ||
857 | } | ||
858 | } | ||
859 | |||
860 | au1550_spi_bits_handlers_set(hw, 8); | ||
861 | |||
862 | err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw); | ||
863 | if (err) { | ||
864 | dev_err(&pdev->dev, "Cannot claim IRQ\n"); | ||
865 | goto err_no_irq; | ||
866 | } | ||
867 | |||
868 | master->bus_num = hw->pdata->bus_num; | ||
869 | master->num_chipselect = hw->pdata->num_chipselect; | ||
870 | |||
871 | /* | ||
872 | * precompute valid range for spi freq - from au1550 datasheet: | ||
873 | * psc_tempclk = psc_mainclk / (2 << DIV) | ||
874 | * spiclk = psc_tempclk / (2 * (BRG + 1)) | ||
875 | * BRG valid range is 4..63 | ||
876 | * DIV valid range is 0..3 | ||
877 | * round the min and max frequencies to values that would still | ||
878 | * produce valid brg and div | ||
879 | */ | ||
880 | { | ||
881 | int min_div = (2 << 0) * (2 * (4 + 1)); | ||
882 | int max_div = (2 << 3) * (2 * (63 + 1)); | ||
883 | hw->freq_max = hw->pdata->mainclk_hz / min_div; | ||
884 | hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1; | ||
885 | } | ||
886 | |||
887 | au1550_spi_setup_psc_as_spi(hw); | ||
888 | |||
889 | err = spi_bitbang_start(&hw->bitbang); | ||
890 | if (err) { | ||
891 | dev_err(&pdev->dev, "Failed to register SPI master\n"); | ||
892 | goto err_register; | ||
893 | } | ||
894 | |||
895 | dev_info(&pdev->dev, | ||
896 | "spi master registered: bus_num=%d num_chipselect=%d\n", | ||
897 | master->bus_num, master->num_chipselect); | ||
898 | |||
899 | return 0; | ||
900 | |||
901 | err_register: | ||
902 | free_irq(hw->irq, hw); | ||
903 | |||
904 | err_no_irq: | ||
905 | au1550_spi_dma_rxtmp_free(hw); | ||
906 | |||
907 | err_dma_rxtmp_alloc: | ||
908 | err_no_rxdma_descr: | ||
909 | if (hw->usedma) | ||
910 | au1xxx_dbdma_chan_free(hw->dma_rx_ch); | ||
911 | |||
912 | err_no_rxdma: | ||
913 | err_no_txdma_descr: | ||
914 | if (hw->usedma) | ||
915 | au1xxx_dbdma_chan_free(hw->dma_tx_ch); | ||
916 | |||
917 | err_no_txdma: | ||
918 | err_dma_add_dev: | ||
919 | release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); | ||
920 | |||
921 | err_no_iores: | ||
922 | err_no_pdata: | ||
923 | spi_master_put(hw->master); | ||
924 | |||
925 | err_nomem: | ||
926 | return err; | ||
927 | } | ||
928 | |||
929 | static int __exit au1550_spi_remove(struct platform_device *pdev) | ||
930 | { | ||
931 | struct au1550_spi *hw = platform_get_drvdata(pdev); | ||
932 | |||
933 | dev_info(&pdev->dev, "spi master remove: bus_num=%d\n", | ||
934 | hw->master->bus_num); | ||
935 | |||
936 | spi_bitbang_stop(&hw->bitbang); | ||
937 | free_irq(hw->irq, hw); | ||
938 | release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); | ||
939 | |||
940 | if (hw->usedma) { | ||
941 | au1550_spi_dma_rxtmp_free(hw); | ||
942 | au1xxx_dbdma_chan_free(hw->dma_rx_ch); | ||
943 | au1xxx_dbdma_chan_free(hw->dma_tx_ch); | ||
944 | } | ||
945 | |||
946 | platform_set_drvdata(pdev, NULL); | ||
947 | |||
948 | spi_master_put(hw->master); | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static struct platform_driver au1550_spi_drv = { | ||
953 | .remove = __exit_p(au1550_spi_remove), | ||
954 | .driver = { | ||
955 | .name = "au1550-spi", | ||
956 | .owner = THIS_MODULE, | ||
957 | }, | ||
958 | }; | ||
959 | |||
960 | static int __init au1550_spi_init(void) | ||
961 | { | ||
962 | return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); | ||
963 | } | ||
964 | module_init(au1550_spi_init); | ||
965 | |||
966 | static void __exit au1550_spi_exit(void) | ||
967 | { | ||
968 | platform_driver_unregister(&au1550_spi_drv); | ||
969 | } | ||
970 | module_exit(au1550_spi_exit); | ||
971 | |||
972 | MODULE_DESCRIPTION("Au1550 PSC SPI Driver"); | ||
973 | MODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>"); | ||
974 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6657331eed93..c3219b29b5ac 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -152,6 +152,11 @@ static void spi_drv_shutdown(struct device *dev) | |||
152 | sdrv->shutdown(to_spi_device(dev)); | 152 | sdrv->shutdown(to_spi_device(dev)); |
153 | } | 153 | } |
154 | 154 | ||
155 | /** | ||
156 | * spi_register_driver - register a SPI driver | ||
157 | * @sdrv: the driver to register | ||
158 | * Context: can sleep | ||
159 | */ | ||
155 | int spi_register_driver(struct spi_driver *sdrv) | 160 | int spi_register_driver(struct spi_driver *sdrv) |
156 | { | 161 | { |
157 | sdrv->driver.bus = &spi_bus_type; | 162 | sdrv->driver.bus = &spi_bus_type; |
@@ -183,7 +188,13 @@ static LIST_HEAD(board_list); | |||
183 | static DECLARE_MUTEX(board_lock); | 188 | static DECLARE_MUTEX(board_lock); |
184 | 189 | ||
185 | 190 | ||
186 | /* On typical mainboards, this is purely internal; and it's not needed | 191 | /** |
192 | * spi_new_device - instantiate one new SPI device | ||
193 | * @master: Controller to which device is connected | ||
194 | * @chip: Describes the SPI device | ||
195 | * Context: can sleep | ||
196 | * | ||
197 | * On typical mainboards, this is purely internal; and it's not needed | ||
187 | * after board init creates the hard-wired devices. Some development | 198 | * after board init creates the hard-wired devices. Some development |
188 | * platforms may not be able to use spi_register_board_info though, and | 199 | * platforms may not be able to use spi_register_board_info though, and |
189 | * this is exported so that for example a USB or parport based adapter | 200 | * this is exported so that for example a USB or parport based adapter |
@@ -251,7 +262,12 @@ fail: | |||
251 | } | 262 | } |
252 | EXPORT_SYMBOL_GPL(spi_new_device); | 263 | EXPORT_SYMBOL_GPL(spi_new_device); |
253 | 264 | ||
254 | /* | 265 | /** |
266 | * spi_register_board_info - register SPI devices for a given board | ||
267 | * @info: array of chip descriptors | ||
268 | * @n: how many descriptors are provided | ||
269 | * Context: can sleep | ||
270 | * | ||
255 | * Board-specific early init code calls this (probably during arch_initcall) | 271 | * Board-specific early init code calls this (probably during arch_initcall) |
256 | * with segments of the SPI device table. Any device nodes are created later, | 272 | * with segments of the SPI device table. Any device nodes are created later, |
257 | * after the relevant parent SPI controller (bus_num) is defined. We keep | 273 | * after the relevant parent SPI controller (bus_num) is defined. We keep |
@@ -337,9 +353,10 @@ static struct class spi_master_class = { | |||
337 | /** | 353 | /** |
338 | * spi_alloc_master - allocate SPI master controller | 354 | * spi_alloc_master - allocate SPI master controller |
339 | * @dev: the controller, possibly using the platform_bus | 355 | * @dev: the controller, possibly using the platform_bus |
340 | * @size: how much driver-private data to preallocate; the pointer to this | 356 | * @size: how much zeroed driver-private data to allocate; the pointer to this |
341 | * memory is in the class_data field of the returned class_device, | 357 | * memory is in the class_data field of the returned class_device, |
342 | * accessible with spi_master_get_devdata(). | 358 | * accessible with spi_master_get_devdata(). |
359 | * Context: can sleep | ||
343 | * | 360 | * |
344 | * This call is used only by SPI master controller drivers, which are the | 361 | * This call is used only by SPI master controller drivers, which are the |
345 | * only ones directly touching chip registers. It's how they allocate | 362 | * only ones directly touching chip registers. It's how they allocate |
@@ -375,6 +392,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); | |||
375 | /** | 392 | /** |
376 | * spi_register_master - register SPI master controller | 393 | * spi_register_master - register SPI master controller |
377 | * @master: initialized master, originally from spi_alloc_master() | 394 | * @master: initialized master, originally from spi_alloc_master() |
395 | * Context: can sleep | ||
378 | * | 396 | * |
379 | * SPI master controllers connect to their drivers using some non-SPI bus, | 397 | * SPI master controllers connect to their drivers using some non-SPI bus, |
380 | * such as the platform bus. The final stage of probe() in that code | 398 | * such as the platform bus. The final stage of probe() in that code |
@@ -437,6 +455,7 @@ static int __unregister(struct device *dev, void *unused) | |||
437 | /** | 455 | /** |
438 | * spi_unregister_master - unregister SPI master controller | 456 | * spi_unregister_master - unregister SPI master controller |
439 | * @master: the master being unregistered | 457 | * @master: the master being unregistered |
458 | * Context: can sleep | ||
440 | * | 459 | * |
441 | * This call is used only by SPI master controller drivers, which are the | 460 | * This call is used only by SPI master controller drivers, which are the |
442 | * only ones directly touching chip registers. | 461 | * only ones directly touching chip registers. |
@@ -455,6 +474,7 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); | |||
455 | /** | 474 | /** |
456 | * spi_busnum_to_master - look up master associated with bus_num | 475 | * spi_busnum_to_master - look up master associated with bus_num |
457 | * @bus_num: the master's bus number | 476 | * @bus_num: the master's bus number |
477 | * Context: can sleep | ||
458 | * | 478 | * |
459 | * This call may be used with devices that are registered after | 479 | * This call may be used with devices that are registered after |
460 | * arch init time. It returns a refcounted pointer to the relevant | 480 | * arch init time. It returns a refcounted pointer to the relevant |
@@ -492,6 +512,7 @@ static void spi_complete(void *arg) | |||
492 | * spi_sync - blocking/synchronous SPI data transfers | 512 | * spi_sync - blocking/synchronous SPI data transfers |
493 | * @spi: device with which data will be exchanged | 513 | * @spi: device with which data will be exchanged |
494 | * @message: describes the data transfers | 514 | * @message: describes the data transfers |
515 | * Context: can sleep | ||
495 | * | 516 | * |
496 | * This call may only be used from a context that may sleep. The sleep | 517 | * This call may only be used from a context that may sleep. The sleep |
497 | * is non-interruptible, and has no timeout. Low-overhead controller | 518 | * is non-interruptible, and has no timeout. Low-overhead controller |
@@ -508,7 +529,7 @@ static void spi_complete(void *arg) | |||
508 | * | 529 | * |
509 | * The return value is a negative error code if the message could not be | 530 | * The return value is a negative error code if the message could not be |
510 | * submitted, else zero. When the value is zero, then message->status is | 531 | * submitted, else zero. When the value is zero, then message->status is |
511 | * also defined: it's the completion code for the transfer, either zero | 532 | * also defined; it's the completion code for the transfer, either zero |
512 | * or a negative error code from the controller driver. | 533 | * or a negative error code from the controller driver. |
513 | */ | 534 | */ |
514 | int spi_sync(struct spi_device *spi, struct spi_message *message) | 535 | int spi_sync(struct spi_device *spi, struct spi_message *message) |
@@ -538,6 +559,7 @@ static u8 *buf; | |||
538 | * @n_tx: size of txbuf, in bytes | 559 | * @n_tx: size of txbuf, in bytes |
539 | * @rxbuf: buffer into which data will be read | 560 | * @rxbuf: buffer into which data will be read |
540 | * @n_rx: size of rxbuf, in bytes (need not be dma-safe) | 561 | * @n_rx: size of rxbuf, in bytes (need not be dma-safe) |
562 | * Context: can sleep | ||
541 | * | 563 | * |
542 | * This performs a half duplex MicroWire style transaction with the | 564 | * This performs a half duplex MicroWire style transaction with the |
543 | * device, sending txbuf and then reading rxbuf. The return value | 565 | * device, sending txbuf and then reading rxbuf. The return value |
@@ -545,7 +567,8 @@ static u8 *buf; | |||
545 | * This call may only be used from a context that may sleep. | 567 | * This call may only be used from a context that may sleep. |
546 | * | 568 | * |
547 | * Parameters to this routine are always copied using a small buffer; | 569 | * Parameters to this routine are always copied using a small buffer; |
548 | * performance-sensitive or bulk transfer code should instead use | 570 | * portable code should never use this for more than 32 bytes. |
571 | * Performance-sensitive or bulk transfer code should instead use | ||
549 | * spi_{async,sync}() calls with dma-safe buffers. | 572 | * spi_{async,sync}() calls with dma-safe buffers. |
550 | */ | 573 | */ |
551 | int spi_write_then_read(struct spi_device *spi, | 574 | int spi_write_then_read(struct spi_device *spi, |
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 312987a03210..0ee2b2090252 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/device.h> |
24 | #include <linux/parport.h> | 24 | #include <linux/parport.h> |
25 | 25 | ||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
@@ -40,8 +40,6 @@ | |||
40 | * and use this custom parallel port cable. | 40 | * and use this custom parallel port cable. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #undef HAVE_USI /* nyet */ | ||
44 | |||
45 | 43 | ||
46 | /* DATA output bits (pins 2..9 == D0..D7) */ | 44 | /* DATA output bits (pins 2..9 == D0..D7) */ |
47 | #define butterfly_nreset (1 << 1) /* pin 3 */ | 45 | #define butterfly_nreset (1 << 1) /* pin 3 */ |
@@ -49,19 +47,13 @@ | |||
49 | #define spi_sck_bit (1 << 0) /* pin 2 */ | 47 | #define spi_sck_bit (1 << 0) /* pin 2 */ |
50 | #define spi_mosi_bit (1 << 7) /* pin 9 */ | 48 | #define spi_mosi_bit (1 << 7) /* pin 9 */ |
51 | 49 | ||
52 | #define usi_sck_bit (1 << 3) /* pin 5 */ | ||
53 | #define usi_mosi_bit (1 << 4) /* pin 6 */ | ||
54 | |||
55 | #define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ | 50 | #define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ |
56 | 51 | ||
57 | /* STATUS input bits */ | 52 | /* STATUS input bits */ |
58 | #define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ | 53 | #define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ |
59 | 54 | ||
60 | #define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */ | ||
61 | |||
62 | /* CONTROL output bits */ | 55 | /* CONTROL output bits */ |
63 | #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ | 56 | #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ |
64 | /* USI uses no chipselect */ | ||
65 | 57 | ||
66 | 58 | ||
67 | 59 | ||
@@ -70,15 +62,6 @@ static inline struct butterfly *spidev_to_pp(struct spi_device *spi) | |||
70 | return spi->controller_data; | 62 | return spi->controller_data; |
71 | } | 63 | } |
72 | 64 | ||
73 | static inline int is_usidev(struct spi_device *spi) | ||
74 | { | ||
75 | #ifdef HAVE_USI | ||
76 | return spi->chip_select != 1; | ||
77 | #else | ||
78 | return 0; | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | 65 | ||
83 | struct butterfly { | 66 | struct butterfly { |
84 | /* REVISIT ... for now, this must be first */ | 67 | /* REVISIT ... for now, this must be first */ |
@@ -97,23 +80,13 @@ struct butterfly { | |||
97 | 80 | ||
98 | /*----------------------------------------------------------------------*/ | 81 | /*----------------------------------------------------------------------*/ |
99 | 82 | ||
100 | /* | ||
101 | * these routines may be slower than necessary because they're hiding | ||
102 | * the fact that there are two different SPI busses on this cable: one | ||
103 | * to the DataFlash chip (or AVR SPI controller), the other to the | ||
104 | * AVR USI controller. | ||
105 | */ | ||
106 | |||
107 | static inline void | 83 | static inline void |
108 | setsck(struct spi_device *spi, int is_on) | 84 | setsck(struct spi_device *spi, int is_on) |
109 | { | 85 | { |
110 | struct butterfly *pp = spidev_to_pp(spi); | 86 | struct butterfly *pp = spidev_to_pp(spi); |
111 | u8 bit, byte = pp->lastbyte; | 87 | u8 bit, byte = pp->lastbyte; |
112 | 88 | ||
113 | if (is_usidev(spi)) | 89 | bit = spi_sck_bit; |
114 | bit = usi_sck_bit; | ||
115 | else | ||
116 | bit = spi_sck_bit; | ||
117 | 90 | ||
118 | if (is_on) | 91 | if (is_on) |
119 | byte |= bit; | 92 | byte |= bit; |
@@ -129,10 +102,7 @@ setmosi(struct spi_device *spi, int is_on) | |||
129 | struct butterfly *pp = spidev_to_pp(spi); | 102 | struct butterfly *pp = spidev_to_pp(spi); |
130 | u8 bit, byte = pp->lastbyte; | 103 | u8 bit, byte = pp->lastbyte; |
131 | 104 | ||
132 | if (is_usidev(spi)) | 105 | bit = spi_mosi_bit; |
133 | bit = usi_mosi_bit; | ||
134 | else | ||
135 | bit = spi_mosi_bit; | ||
136 | 106 | ||
137 | if (is_on) | 107 | if (is_on) |
138 | byte |= bit; | 108 | byte |= bit; |
@@ -148,10 +118,7 @@ static inline int getmiso(struct spi_device *spi) | |||
148 | int value; | 118 | int value; |
149 | u8 bit; | 119 | u8 bit; |
150 | 120 | ||
151 | if (is_usidev(spi)) | 121 | bit = spi_miso_bit; |
152 | bit = usi_miso_bit; | ||
153 | else | ||
154 | bit = spi_miso_bit; | ||
155 | 122 | ||
156 | /* only STATUS_BUSY is NOT negated */ | 123 | /* only STATUS_BUSY is NOT negated */ |
157 | value = !(parport_read_status(pp->port) & bit); | 124 | value = !(parport_read_status(pp->port) & bit); |
@@ -166,10 +133,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
166 | if (value != BITBANG_CS_INACTIVE) | 133 | if (value != BITBANG_CS_INACTIVE) |
167 | setsck(spi, spi->mode & SPI_CPOL); | 134 | setsck(spi, spi->mode & SPI_CPOL); |
168 | 135 | ||
169 | /* no chipselect on this USI link config */ | ||
170 | if (is_usidev(spi)) | ||
171 | return; | ||
172 | |||
173 | /* here, value == "activate or not"; | 136 | /* here, value == "activate or not"; |
174 | * most PARPORT_CONTROL_* bits are negated, so we must | 137 | * most PARPORT_CONTROL_* bits are negated, so we must |
175 | * morph it to value == "bit value to write in control register" | 138 | * morph it to value == "bit value to write in control register" |
@@ -237,24 +200,16 @@ static void butterfly_attach(struct parport *p) | |||
237 | int status; | 200 | int status; |
238 | struct butterfly *pp; | 201 | struct butterfly *pp; |
239 | struct spi_master *master; | 202 | struct spi_master *master; |
240 | struct platform_device *pdev; | 203 | struct device *dev = p->physport->dev; |
241 | 204 | ||
242 | if (butterfly) | 205 | if (butterfly || !dev) |
243 | return; | 206 | return; |
244 | 207 | ||
245 | /* REVISIT: this just _assumes_ a butterfly is there ... no probe, | 208 | /* REVISIT: this just _assumes_ a butterfly is there ... no probe, |
246 | * and no way to be selective about what it binds to. | 209 | * and no way to be selective about what it binds to. |
247 | */ | 210 | */ |
248 | 211 | ||
249 | /* FIXME where should master->cdev.dev come from? | 212 | master = spi_alloc_master(dev, sizeof *pp); |
250 | * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc | ||
251 | * setting up a platform device like this is an ugly kluge... | ||
252 | */ | ||
253 | pdev = platform_device_register_simple("butterfly", -1, NULL, 0); | ||
254 | if (IS_ERR(pdev)) | ||
255 | return; | ||
256 | |||
257 | master = spi_alloc_master(&pdev->dev, sizeof *pp); | ||
258 | if (!master) { | 213 | if (!master) { |
259 | status = -ENOMEM; | 214 | status = -ENOMEM; |
260 | goto done; | 215 | goto done; |
@@ -300,7 +255,7 @@ static void butterfly_attach(struct parport *p) | |||
300 | parport_frob_control(pp->port, spi_cs_bit, 0); | 255 | parport_frob_control(pp->port, spi_cs_bit, 0); |
301 | 256 | ||
302 | /* stabilize power with chip in reset (nRESET), and | 257 | /* stabilize power with chip in reset (nRESET), and |
303 | * both spi_sck_bit and usi_sck_bit clear (CPOL=0) | 258 | * spi_sck_bit clear (CPOL=0) |
304 | */ | 259 | */ |
305 | pp->lastbyte |= vcc_bits; | 260 | pp->lastbyte |= vcc_bits; |
306 | parport_write_data(pp->port, pp->lastbyte); | 261 | parport_write_data(pp->port, pp->lastbyte); |
@@ -334,23 +289,6 @@ static void butterfly_attach(struct parport *p) | |||
334 | pr_debug("%s: dataflash at %s\n", p->name, | 289 | pr_debug("%s: dataflash at %s\n", p->name, |
335 | pp->dataflash->dev.bus_id); | 290 | pp->dataflash->dev.bus_id); |
336 | 291 | ||
337 | #ifdef HAVE_USI | ||
338 | /* Bus 2 is only for talking to the AVR, and it can work no | ||
339 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
340 | */ | ||
341 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | ||
342 | strcpy(pp->info[1].modalias, "butterfly"); | ||
343 | // pp->info[1].platform_data = ... TBD ... ; | ||
344 | pp->info[1].chip_select = 2, | ||
345 | pp->info[1].controller_data = pp; | ||
346 | pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]); | ||
347 | if (pp->butterfly) | ||
348 | pr_debug("%s: butterfly at %s\n", p->name, | ||
349 | pp->butterfly->dev.bus_id); | ||
350 | |||
351 | /* FIXME setup ACK for the IRQ line ... */ | ||
352 | #endif | ||
353 | |||
354 | // dev_info(_what?_, ...) | 292 | // dev_info(_what?_, ...) |
355 | pr_info("%s: AVR Butterfly\n", p->name); | 293 | pr_info("%s: AVR Butterfly\n", p->name); |
356 | butterfly = pp; | 294 | butterfly = pp; |
@@ -366,14 +304,12 @@ clean1: | |||
366 | clean0: | 304 | clean0: |
367 | (void) spi_master_put(pp->bitbang.master); | 305 | (void) spi_master_put(pp->bitbang.master); |
368 | done: | 306 | done: |
369 | platform_device_unregister(pdev); | ||
370 | pr_debug("%s: butterfly probe, fail %d\n", p->name, status); | 307 | pr_debug("%s: butterfly probe, fail %d\n", p->name, status); |
371 | } | 308 | } |
372 | 309 | ||
373 | static void butterfly_detach(struct parport *p) | 310 | static void butterfly_detach(struct parport *p) |
374 | { | 311 | { |
375 | struct butterfly *pp; | 312 | struct butterfly *pp; |
376 | struct platform_device *pdev; | ||
377 | int status; | 313 | int status; |
378 | 314 | ||
379 | /* FIXME this global is ugly ... but, how to quickly get from | 315 | /* FIXME this global is ugly ... but, how to quickly get from |
@@ -386,7 +322,6 @@ static void butterfly_detach(struct parport *p) | |||
386 | butterfly = NULL; | 322 | butterfly = NULL; |
387 | 323 | ||
388 | /* stop() unregisters child devices too */ | 324 | /* stop() unregisters child devices too */ |
389 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
390 | status = spi_bitbang_stop(&pp->bitbang); | 325 | status = spi_bitbang_stop(&pp->bitbang); |
391 | 326 | ||
392 | /* turn off VCC */ | 327 | /* turn off VCC */ |
@@ -397,8 +332,6 @@ static void butterfly_detach(struct parport *p) | |||
397 | parport_unregister_device(pp->pd); | 332 | parport_unregister_device(pp->pd); |
398 | 333 | ||
399 | (void) spi_master_put(pp->bitbang.master); | 334 | (void) spi_master_put(pp->bitbang.master); |
400 | |||
401 | platform_device_unregister(pdev); | ||
402 | } | 335 | } |
403 | 336 | ||
404 | static struct parport_driver butterfly_driver = { | 337 | static struct parport_driver butterfly_driver = { |
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c new file mode 100644 index 000000000000..c0a6dce800a3 --- /dev/null +++ b/drivers/spi/spidev.c | |||
@@ -0,0 +1,584 @@ | |||
1 | /* | ||
2 | * spidev.c -- simple synchronous userspace interface to SPI devices | ||
3 | * | ||
4 | * Copyright (C) 2006 SWAPP | ||
5 | * Andrea Paterniani <a.paterniani@swapp-eng.it> | ||
6 | * Copyright (C) 2007 David Brownell (simplification, cleanup) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/ioctl.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/device.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/slab.h> | ||
32 | |||
33 | #include <linux/spi/spi.h> | ||
34 | #include <linux/spi/spidev.h> | ||
35 | |||
36 | #include <asm/uaccess.h> | ||
37 | |||
38 | |||
39 | /* | ||
40 | * This supports acccess to SPI devices using normal userspace I/O calls. | ||
41 | * Note that while traditional UNIX/POSIX I/O semantics are half duplex, | ||
42 | * and often mask message boundaries, full SPI support requires full duplex | ||
43 | * transfers. There are several kinds of of internal message boundaries to | ||
44 | * handle chipselect management and other protocol options. | ||
45 | * | ||
46 | * SPI has a character major number assigned. We allocate minor numbers | ||
47 | * dynamically using a bitmask. You must use hotplug tools, such as udev | ||
48 | * (or mdev with busybox) to create and destroy the /dev/spidevB.C device | ||
49 | * nodes, since there is no fixed association of minor numbers with any | ||
50 | * particular SPI bus or device. | ||
51 | */ | ||
52 | #define SPIDEV_MAJOR 153 /* assigned */ | ||
53 | #define N_SPI_MINORS 32 /* ... up to 256 */ | ||
54 | |||
55 | static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; | ||
56 | |||
57 | |||
58 | /* Bit masks for spi_device.mode management */ | ||
59 | #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL) | ||
60 | |||
61 | |||
62 | struct spidev_data { | ||
63 | struct device dev; | ||
64 | struct spi_device *spi; | ||
65 | struct list_head device_entry; | ||
66 | |||
67 | struct mutex buf_lock; | ||
68 | unsigned users; | ||
69 | u8 *buffer; | ||
70 | }; | ||
71 | |||
72 | static LIST_HEAD(device_list); | ||
73 | static DEFINE_MUTEX(device_list_lock); | ||
74 | |||
75 | static unsigned bufsiz = 4096; | ||
76 | module_param(bufsiz, uint, S_IRUGO); | ||
77 | MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); | ||
78 | |||
79 | /*-------------------------------------------------------------------------*/ | ||
80 | |||
81 | /* Read-only message with current device setup */ | ||
82 | static ssize_t | ||
83 | spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) | ||
84 | { | ||
85 | struct spidev_data *spidev; | ||
86 | struct spi_device *spi; | ||
87 | ssize_t status = 0; | ||
88 | |||
89 | /* chipselect only toggles at start or end of operation */ | ||
90 | if (count > bufsiz) | ||
91 | return -EMSGSIZE; | ||
92 | |||
93 | spidev = filp->private_data; | ||
94 | spi = spidev->spi; | ||
95 | |||
96 | mutex_lock(&spidev->buf_lock); | ||
97 | status = spi_read(spi, spidev->buffer, count); | ||
98 | if (status == 0) { | ||
99 | unsigned long missing; | ||
100 | |||
101 | missing = copy_to_user(buf, spidev->buffer, count); | ||
102 | if (count && missing == count) | ||
103 | status = -EFAULT; | ||
104 | else | ||
105 | status = count - missing; | ||
106 | } | ||
107 | mutex_unlock(&spidev->buf_lock); | ||
108 | |||
109 | return status; | ||
110 | } | ||
111 | |||
112 | /* Write-only message with current device setup */ | ||
113 | static ssize_t | ||
114 | spidev_write(struct file *filp, const char __user *buf, | ||
115 | size_t count, loff_t *f_pos) | ||
116 | { | ||
117 | struct spidev_data *spidev; | ||
118 | struct spi_device *spi; | ||
119 | ssize_t status = 0; | ||
120 | unsigned long missing; | ||
121 | |||
122 | /* chipselect only toggles at start or end of operation */ | ||
123 | if (count > bufsiz) | ||
124 | return -EMSGSIZE; | ||
125 | |||
126 | spidev = filp->private_data; | ||
127 | spi = spidev->spi; | ||
128 | |||
129 | mutex_lock(&spidev->buf_lock); | ||
130 | missing = copy_from_user(spidev->buffer, buf, count); | ||
131 | if (missing == 0) { | ||
132 | status = spi_write(spi, spidev->buffer, count); | ||
133 | if (status == 0) | ||
134 | status = count; | ||
135 | } else | ||
136 | status = -EFAULT; | ||
137 | mutex_unlock(&spidev->buf_lock); | ||
138 | |||
139 | return status; | ||
140 | } | ||
141 | |||
142 | static int spidev_message(struct spidev_data *spidev, | ||
143 | struct spi_ioc_transfer *u_xfers, unsigned n_xfers) | ||
144 | { | ||
145 | struct spi_message msg; | ||
146 | struct spi_transfer *k_xfers; | ||
147 | struct spi_transfer *k_tmp; | ||
148 | struct spi_ioc_transfer *u_tmp; | ||
149 | struct spi_device *spi = spidev->spi; | ||
150 | unsigned n, total; | ||
151 | u8 *buf; | ||
152 | int status = -EFAULT; | ||
153 | |||
154 | spi_message_init(&msg); | ||
155 | k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL); | ||
156 | if (k_xfers == NULL) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | /* Construct spi_message, copying any tx data to bounce buffer. | ||
160 | * We walk the array of user-provided transfers, using each one | ||
161 | * to initialize a kernel version of the same transfer. | ||
162 | */ | ||
163 | mutex_lock(&spidev->buf_lock); | ||
164 | buf = spidev->buffer; | ||
165 | total = 0; | ||
166 | for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; | ||
167 | n; | ||
168 | n--, k_tmp++, u_tmp++) { | ||
169 | k_tmp->len = u_tmp->len; | ||
170 | |||
171 | if (u_tmp->rx_buf) { | ||
172 | k_tmp->rx_buf = buf; | ||
173 | if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) | ||
174 | goto done; | ||
175 | } | ||
176 | if (u_tmp->tx_buf) { | ||
177 | k_tmp->tx_buf = buf; | ||
178 | if (copy_from_user(buf, (const u8 __user *)u_tmp->tx_buf, | ||
179 | u_tmp->len)) | ||
180 | goto done; | ||
181 | } | ||
182 | |||
183 | total += k_tmp->len; | ||
184 | if (total > bufsiz) { | ||
185 | status = -EMSGSIZE; | ||
186 | goto done; | ||
187 | } | ||
188 | buf += k_tmp->len; | ||
189 | |||
190 | k_tmp->cs_change = !!u_tmp->cs_change; | ||
191 | k_tmp->bits_per_word = u_tmp->bits_per_word; | ||
192 | k_tmp->delay_usecs = u_tmp->delay_usecs; | ||
193 | k_tmp->speed_hz = u_tmp->speed_hz; | ||
194 | #ifdef VERBOSE | ||
195 | dev_dbg(&spi->dev, | ||
196 | " xfer len %zd %s%s%s%dbits %u usec %uHz\n", | ||
197 | u_tmp->len, | ||
198 | u_tmp->rx_buf ? "rx " : "", | ||
199 | u_tmp->tx_buf ? "tx " : "", | ||
200 | u_tmp->cs_change ? "cs " : "", | ||
201 | u_tmp->bits_per_word ? : spi->bits_per_word, | ||
202 | u_tmp->delay_usecs, | ||
203 | u_tmp->speed_hz ? : spi->max_speed_hz); | ||
204 | #endif | ||
205 | spi_message_add_tail(k_tmp, &msg); | ||
206 | } | ||
207 | |||
208 | status = spi_sync(spi, &msg); | ||
209 | if (status < 0) | ||
210 | goto done; | ||
211 | |||
212 | /* copy any rx data out of bounce buffer */ | ||
213 | buf = spidev->buffer; | ||
214 | for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { | ||
215 | if (u_tmp->rx_buf) { | ||
216 | if (__copy_to_user((u8 __user *)u_tmp->rx_buf, buf, | ||
217 | u_tmp->len)) { | ||
218 | status = -EFAULT; | ||
219 | goto done; | ||
220 | } | ||
221 | } | ||
222 | buf += u_tmp->len; | ||
223 | } | ||
224 | status = total; | ||
225 | |||
226 | done: | ||
227 | mutex_unlock(&spidev->buf_lock); | ||
228 | kfree(k_xfers); | ||
229 | return status; | ||
230 | } | ||
231 | |||
232 | static int | ||
233 | spidev_ioctl(struct inode *inode, struct file *filp, | ||
234 | unsigned int cmd, unsigned long arg) | ||
235 | { | ||
236 | int err = 0; | ||
237 | int retval = 0; | ||
238 | struct spidev_data *spidev; | ||
239 | struct spi_device *spi; | ||
240 | u32 tmp; | ||
241 | unsigned n_ioc; | ||
242 | struct spi_ioc_transfer *ioc; | ||
243 | |||
244 | /* Check type and command number */ | ||
245 | if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC) | ||
246 | return -ENOTTY; | ||
247 | |||
248 | /* Check access direction once here; don't repeat below. | ||
249 | * IOC_DIR is from the user perspective, while access_ok is | ||
250 | * from the kernel perspective; so they look reversed. | ||
251 | */ | ||
252 | if (_IOC_DIR(cmd) & _IOC_READ) | ||
253 | err = !access_ok(VERIFY_WRITE, | ||
254 | (void __user *)arg, _IOC_SIZE(cmd)); | ||
255 | if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) | ||
256 | err = !access_ok(VERIFY_READ, | ||
257 | (void __user *)arg, _IOC_SIZE(cmd)); | ||
258 | if (err) | ||
259 | return -EFAULT; | ||
260 | |||
261 | spidev = filp->private_data; | ||
262 | spi = spidev->spi; | ||
263 | |||
264 | switch (cmd) { | ||
265 | /* read requests */ | ||
266 | case SPI_IOC_RD_MODE: | ||
267 | retval = __put_user(spi->mode & SPI_MODE_MASK, | ||
268 | (__u8 __user *)arg); | ||
269 | break; | ||
270 | case SPI_IOC_RD_LSB_FIRST: | ||
271 | retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, | ||
272 | (__u8 __user *)arg); | ||
273 | break; | ||
274 | case SPI_IOC_RD_BITS_PER_WORD: | ||
275 | retval = __put_user(spi->bits_per_word, (__u8 __user *)arg); | ||
276 | break; | ||
277 | case SPI_IOC_RD_MAX_SPEED_HZ: | ||
278 | retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg); | ||
279 | break; | ||
280 | |||
281 | /* write requests */ | ||
282 | case SPI_IOC_WR_MODE: | ||
283 | retval = __get_user(tmp, (u8 __user *)arg); | ||
284 | if (retval == 0) { | ||
285 | u8 save = spi->mode; | ||
286 | |||
287 | if (tmp & ~SPI_MODE_MASK) { | ||
288 | retval = -EINVAL; | ||
289 | break; | ||
290 | } | ||
291 | |||
292 | tmp |= spi->mode & ~SPI_MODE_MASK; | ||
293 | spi->mode = (u8)tmp; | ||
294 | retval = spi_setup(spi); | ||
295 | if (retval < 0) | ||
296 | spi->mode = save; | ||
297 | else | ||
298 | dev_dbg(&spi->dev, "spi mode %02x\n", tmp); | ||
299 | } | ||
300 | break; | ||
301 | case SPI_IOC_WR_LSB_FIRST: | ||
302 | retval = __get_user(tmp, (__u8 __user *)arg); | ||
303 | if (retval == 0) { | ||
304 | u8 save = spi->mode; | ||
305 | |||
306 | if (tmp) | ||
307 | spi->mode |= SPI_LSB_FIRST; | ||
308 | else | ||
309 | spi->mode &= ~SPI_LSB_FIRST; | ||
310 | retval = spi_setup(spi); | ||
311 | if (retval < 0) | ||
312 | spi->mode = save; | ||
313 | else | ||
314 | dev_dbg(&spi->dev, "%csb first\n", | ||
315 | tmp ? 'l' : 'm'); | ||
316 | } | ||
317 | break; | ||
318 | case SPI_IOC_WR_BITS_PER_WORD: | ||
319 | retval = __get_user(tmp, (__u8 __user *)arg); | ||
320 | if (retval == 0) { | ||
321 | u8 save = spi->bits_per_word; | ||
322 | |||
323 | spi->bits_per_word = tmp; | ||
324 | retval = spi_setup(spi); | ||
325 | if (retval < 0) | ||
326 | spi->bits_per_word = save; | ||
327 | else | ||
328 | dev_dbg(&spi->dev, "%d bits per word\n", tmp); | ||
329 | } | ||
330 | break; | ||
331 | case SPI_IOC_WR_MAX_SPEED_HZ: | ||
332 | retval = __get_user(tmp, (__u32 __user *)arg); | ||
333 | if (retval == 0) { | ||
334 | u32 save = spi->max_speed_hz; | ||
335 | |||
336 | spi->max_speed_hz = tmp; | ||
337 | retval = spi_setup(spi); | ||
338 | if (retval < 0) | ||
339 | spi->max_speed_hz = save; | ||
340 | else | ||
341 | dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); | ||
342 | } | ||
343 | break; | ||
344 | |||
345 | default: | ||
346 | /* segmented and/or full-duplex I/O request */ | ||
347 | if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) | ||
348 | || _IOC_DIR(cmd) != _IOC_WRITE) | ||
349 | return -ENOTTY; | ||
350 | |||
351 | tmp = _IOC_SIZE(cmd); | ||
352 | if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { | ||
353 | retval = -EINVAL; | ||
354 | break; | ||
355 | } | ||
356 | n_ioc = tmp / sizeof(struct spi_ioc_transfer); | ||
357 | if (n_ioc == 0) | ||
358 | break; | ||
359 | |||
360 | /* copy into scratch area */ | ||
361 | ioc = kmalloc(tmp, GFP_KERNEL); | ||
362 | if (!ioc) { | ||
363 | retval = -ENOMEM; | ||
364 | break; | ||
365 | } | ||
366 | if (__copy_from_user(ioc, (void __user *)arg, tmp)) { | ||
367 | retval = -EFAULT; | ||
368 | break; | ||
369 | } | ||
370 | |||
371 | /* translate to spi_message, execute */ | ||
372 | retval = spidev_message(spidev, ioc, n_ioc); | ||
373 | kfree(ioc); | ||
374 | break; | ||
375 | } | ||
376 | return retval; | ||
377 | } | ||
378 | |||
379 | static int spidev_open(struct inode *inode, struct file *filp) | ||
380 | { | ||
381 | struct spidev_data *spidev; | ||
382 | int status = -ENXIO; | ||
383 | |||
384 | mutex_lock(&device_list_lock); | ||
385 | |||
386 | list_for_each_entry(spidev, &device_list, device_entry) { | ||
387 | if (spidev->dev.devt == inode->i_rdev) { | ||
388 | status = 0; | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | if (status == 0) { | ||
393 | if (!spidev->buffer) { | ||
394 | spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); | ||
395 | if (!spidev->buffer) { | ||
396 | dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); | ||
397 | status = -ENOMEM; | ||
398 | } | ||
399 | } | ||
400 | if (status == 0) { | ||
401 | spidev->users++; | ||
402 | filp->private_data = spidev; | ||
403 | nonseekable_open(inode, filp); | ||
404 | } | ||
405 | } else | ||
406 | pr_debug("spidev: nothing for minor %d\n", iminor(inode)); | ||
407 | |||
408 | mutex_unlock(&device_list_lock); | ||
409 | return status; | ||
410 | } | ||
411 | |||
412 | static int spidev_release(struct inode *inode, struct file *filp) | ||
413 | { | ||
414 | struct spidev_data *spidev; | ||
415 | int status = 0; | ||
416 | |||
417 | mutex_lock(&device_list_lock); | ||
418 | spidev = filp->private_data; | ||
419 | filp->private_data = NULL; | ||
420 | spidev->users--; | ||
421 | if (!spidev->users) { | ||
422 | kfree(spidev->buffer); | ||
423 | spidev->buffer = NULL; | ||
424 | } | ||
425 | mutex_unlock(&device_list_lock); | ||
426 | |||
427 | return status; | ||
428 | } | ||
429 | |||
430 | static struct file_operations spidev_fops = { | ||
431 | .owner = THIS_MODULE, | ||
432 | /* REVISIT switch to aio primitives, so that userspace | ||
433 | * gets more complete API coverage. It'll simplify things | ||
434 | * too, except for the locking. | ||
435 | */ | ||
436 | .write = spidev_write, | ||
437 | .read = spidev_read, | ||
438 | .ioctl = spidev_ioctl, | ||
439 | .open = spidev_open, | ||
440 | .release = spidev_release, | ||
441 | }; | ||
442 | |||
443 | /*-------------------------------------------------------------------------*/ | ||
444 | |||
445 | /* The main reason to have this class is to make mdev/udev create the | ||
446 | * /dev/spidevB.C character device nodes exposing our userspace API. | ||
447 | * It also simplifies memory management. | ||
448 | */ | ||
449 | |||
450 | static void spidev_classdev_release(struct device *dev) | ||
451 | { | ||
452 | struct spidev_data *spidev; | ||
453 | |||
454 | spidev = container_of(dev, struct spidev_data, dev); | ||
455 | kfree(spidev); | ||
456 | } | ||
457 | |||
458 | static struct class spidev_class = { | ||
459 | .name = "spidev", | ||
460 | .owner = THIS_MODULE, | ||
461 | .dev_release = spidev_classdev_release, | ||
462 | }; | ||
463 | |||
464 | /*-------------------------------------------------------------------------*/ | ||
465 | |||
466 | static int spidev_probe(struct spi_device *spi) | ||
467 | { | ||
468 | struct spidev_data *spidev; | ||
469 | int status; | ||
470 | unsigned long minor; | ||
471 | |||
472 | /* Allocate driver data */ | ||
473 | spidev = kzalloc(sizeof(*spidev), GFP_KERNEL); | ||
474 | if (!spidev) | ||
475 | return -ENOMEM; | ||
476 | |||
477 | /* Initialize the driver data */ | ||
478 | spidev->spi = spi; | ||
479 | mutex_init(&spidev->buf_lock); | ||
480 | |||
481 | INIT_LIST_HEAD(&spidev->device_entry); | ||
482 | |||
483 | /* If we can allocate a minor number, hook up this device. | ||
484 | * Reusing minors is fine so long as udev or mdev is working. | ||
485 | */ | ||
486 | mutex_lock(&device_list_lock); | ||
487 | minor = find_first_zero_bit(minors, ARRAY_SIZE(minors)); | ||
488 | if (minor < N_SPI_MINORS) { | ||
489 | spidev->dev.parent = &spi->dev; | ||
490 | spidev->dev.class = &spidev_class; | ||
491 | spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor); | ||
492 | snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id, | ||
493 | "spidev%d.%d", | ||
494 | spi->master->bus_num, spi->chip_select); | ||
495 | status = device_register(&spidev->dev); | ||
496 | } else { | ||
497 | dev_dbg(&spi->dev, "no minor number available!\n"); | ||
498 | status = -ENODEV; | ||
499 | } | ||
500 | if (status == 0) { | ||
501 | set_bit(minor, minors); | ||
502 | dev_set_drvdata(&spi->dev, spidev); | ||
503 | list_add(&spidev->device_entry, &device_list); | ||
504 | } | ||
505 | mutex_unlock(&device_list_lock); | ||
506 | |||
507 | if (status != 0) | ||
508 | kfree(spidev); | ||
509 | |||
510 | return status; | ||
511 | } | ||
512 | |||
513 | static int spidev_remove(struct spi_device *spi) | ||
514 | { | ||
515 | struct spidev_data *spidev = dev_get_drvdata(&spi->dev); | ||
516 | |||
517 | mutex_lock(&device_list_lock); | ||
518 | |||
519 | list_del(&spidev->device_entry); | ||
520 | dev_set_drvdata(&spi->dev, NULL); | ||
521 | clear_bit(MINOR(spidev->dev.devt), minors); | ||
522 | device_unregister(&spidev->dev); | ||
523 | |||
524 | mutex_unlock(&device_list_lock); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static struct spi_driver spidev_spi = { | ||
530 | .driver = { | ||
531 | .name = "spidev", | ||
532 | .owner = THIS_MODULE, | ||
533 | }, | ||
534 | .probe = spidev_probe, | ||
535 | .remove = __devexit_p(spidev_remove), | ||
536 | |||
537 | /* NOTE: suspend/resume methods are not necessary here. | ||
538 | * We don't do anything except pass the requests to/from | ||
539 | * the underlying controller. The refrigerator handles | ||
540 | * most issues; the controller driver handles the rest. | ||
541 | */ | ||
542 | }; | ||
543 | |||
544 | /*-------------------------------------------------------------------------*/ | ||
545 | |||
546 | static int __init spidev_init(void) | ||
547 | { | ||
548 | int status; | ||
549 | |||
550 | /* Claim our 256 reserved device numbers. Then register a class | ||
551 | * that will key udev/mdev to add/remove /dev nodes. Last, register | ||
552 | * the driver which manages those device numbers. | ||
553 | */ | ||
554 | BUILD_BUG_ON(N_SPI_MINORS > 256); | ||
555 | status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops); | ||
556 | if (status < 0) | ||
557 | return status; | ||
558 | |||
559 | status = class_register(&spidev_class); | ||
560 | if (status < 0) { | ||
561 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | ||
562 | return status; | ||
563 | } | ||
564 | |||
565 | status = spi_register_driver(&spidev_spi); | ||
566 | if (status < 0) { | ||
567 | class_unregister(&spidev_class); | ||
568 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | ||
569 | } | ||
570 | return status; | ||
571 | } | ||
572 | module_init(spidev_init); | ||
573 | |||
574 | static void __exit spidev_exit(void) | ||
575 | { | ||
576 | spi_unregister_driver(&spidev_spi); | ||
577 | class_unregister(&spidev_class); | ||
578 | unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); | ||
579 | } | ||
580 | module_exit(spidev_exit); | ||
581 | |||
582 | MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>"); | ||
583 | MODULE_DESCRIPTION("User mode SPI device interface"); | ||
584 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 71cb64e41a1b..c7b0a357b04a 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -7692,7 +7692,7 @@ static int __init ixj_probe_pci(int *cnt) | |||
7692 | IXJ *j = NULL; | 7692 | IXJ *j = NULL; |
7693 | 7693 | ||
7694 | for (i = 0; i < IXJMAX - *cnt; i++) { | 7694 | for (i = 0; i < IXJMAX - *cnt; i++) { |
7695 | pci = pci_find_device(PCI_VENDOR_ID_QUICKNET, | 7695 | pci = pci_get_device(PCI_VENDOR_ID_QUICKNET, |
7696 | PCI_DEVICE_ID_QUICKNET_XJ, pci); | 7696 | PCI_DEVICE_ID_QUICKNET_XJ, pci); |
7697 | if (!pci) | 7697 | if (!pci) |
7698 | break; | 7698 | break; |
@@ -7712,6 +7712,7 @@ static int __init ixj_probe_pci(int *cnt) | |||
7712 | printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); | 7712 | printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); |
7713 | ++*cnt; | 7713 | ++*cnt; |
7714 | } | 7714 | } |
7715 | pci_dev_put(pci); | ||
7715 | return probe; | 7716 | return probe; |
7716 | } | 7717 | } |
7717 | 7718 | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index b3f779f5933a..b082d95bbbaa 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -77,7 +77,6 @@ | |||
77 | #include <linux/sched.h> | 77 | #include <linux/sched.h> |
78 | #include <linux/signal.h> | 78 | #include <linux/signal.h> |
79 | #include <linux/slab.h> | 79 | #include <linux/slab.h> |
80 | #include <linux/smp_lock.h> | ||
81 | #include <linux/stat.h> | 80 | #include <linux/stat.h> |
82 | #include <linux/timer.h> | 81 | #include <linux/timer.h> |
83 | #include <linux/wait.h> | 82 | #include <linux/wait.h> |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 14de3b1b6a20..0081c1d12687 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <linux/tty_driver.h> | 59 | #include <linux/tty_driver.h> |
60 | #include <linux/tty_flip.h> | 60 | #include <linux/tty_flip.h> |
61 | #include <linux/module.h> | 61 | #include <linux/module.h> |
62 | #include <linux/smp_lock.h> | ||
63 | #include <linux/mutex.h> | 62 | #include <linux/mutex.h> |
64 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
65 | #include <linux/usb.h> | 64 | #include <linux/usb.h> |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6584cf00f7f3..15e740e3a5c4 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/kernel.h> | 50 | #include <linux/kernel.h> |
51 | #include <linux/sched.h> | 51 | #include <linux/sched.h> |
52 | #include <linux/smp_lock.h> | ||
53 | #include <linux/signal.h> | 52 | #include <linux/signal.h> |
54 | #include <linux/poll.h> | 53 | #include <linux/poll.h> |
55 | #include <linux/init.h> | 54 | #include <linux/init.h> |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index bde29ab2b504..f6b74a678de5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/ioctl.h> | 19 | #include <linux/ioctl.h> |
21 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
22 | #include <linux/usbdevice_fs.h> | 21 | #include <linux/usbdevice_fs.h> |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index cddfc62c4611..cd4f11157280 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | #include <linux/namei.h> | 37 | #include <linux/namei.h> |
38 | #include <linux/usbdevice_fs.h> | 38 | #include <linux/usbdevice_fs.h> |
39 | #include <linux/smp_lock.h> | ||
40 | #include <linux/parser.h> | 39 | #include <linux/parser.h> |
41 | #include <linux/notifier.h> | 40 | #include <linux/notifier.h> |
42 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index dfd1b5c87ca3..18ddc5e67e39 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
36 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
37 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 2a6e3163d944..ba163f35bf21 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
36 | #include <linux/init.h> | 35 | #include <linux/init.h> |
37 | #include <linux/list.h> | 36 | #include <linux/list.h> |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 7d7909cf2558..fcb5526cb085 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/smp_lock.h> | ||
45 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
46 | #include <linux/init.h> | 45 | #include <linux/init.h> |
47 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 1dd8b57f4420..325bf7cfb83f 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 65c91d3735de..ae931af05cef 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
35 | #include <linux/init.h> | 34 | #include <linux/init.h> |
36 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 49d737725f70..52779c52b56d 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/delay.h> | 54 | #include <linux/delay.h> |
55 | #include <linux/ioport.h> | 55 | #include <linux/ioport.h> |
56 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
57 | #include <linux/smp_lock.h> | ||
58 | #include <linux/errno.h> | 57 | #include <linux/errno.h> |
59 | #include <linux/init.h> | 58 | #include <linux/init.h> |
60 | #include <linux/timer.h> | 59 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index e552668d36b3..f847c3414be3 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
28 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 8c85e33f74a4..7078374d0b79 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -67,7 +67,6 @@ | |||
67 | #include <linux/delay.h> | 67 | #include <linux/delay.h> |
68 | #include <linux/ioport.h> | 68 | #include <linux/ioport.h> |
69 | #include <linux/slab.h> | 69 | #include <linux/slab.h> |
70 | #include <linux/smp_lock.h> | ||
71 | #include <linux/errno.h> | 70 | #include <linux/errno.h> |
72 | #include <linux/init.h> | 71 | #include <linux/init.h> |
73 | #include <linux/timer.h> | 72 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c7458f7e56cc..099aff64f536 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
29 | #include <linux/init.h> | 28 | #include <linux/init.h> |
30 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index e8bbe8bc2598..a66637e725f3 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 5fa5647ea095..4cfa3ff2c993 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/ioport.h> | 38 | #include <linux/ioport.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/smp_lock.h> | ||
42 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
43 | #include <linux/init.h> | 42 | #include <linux/init.h> |
44 | #include <linux/timer.h> | 43 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index a7fa0d75567d..ff0dba01f1c7 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/pci_ids.h> | 43 | #include <linux/pci_ids.h> |
44 | #include <linux/sched.h> | 44 | #include <linux/sched.h> |
45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/errno.h> | 46 | #include <linux/errno.h> |
48 | #include <linux/init.h> | 47 | #include <linux/init.h> |
49 | #include <linux/timer.h> | 48 | #include <linux/timer.h> |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index d308afd06935..36502a06f73a 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -94,7 +94,6 @@ | |||
94 | #include <linux/init.h> | 94 | #include <linux/init.h> |
95 | #include <linux/slab.h> | 95 | #include <linux/slab.h> |
96 | #include <linux/module.h> | 96 | #include <linux/module.h> |
97 | #include <linux/smp_lock.h> | ||
98 | #include <linux/wait.h> | 97 | #include <linux/wait.h> |
99 | #include <linux/mutex.h> | 98 | #include <linux/mutex.h> |
100 | 99 | ||
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 896cb2b71020..51bd80d2b8cc 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -128,7 +128,6 @@ | |||
128 | #include <linux/init.h> | 128 | #include <linux/init.h> |
129 | #include <linux/slab.h> | 129 | #include <linux/slab.h> |
130 | #include <linux/spinlock.h> | 130 | #include <linux/spinlock.h> |
131 | #include <linux/smp_lock.h> | ||
132 | #include <linux/usb.h> | 131 | #include <linux/usb.h> |
133 | #include <linux/proc_fs.h> | 132 | #include <linux/proc_fs.h> |
134 | 133 | ||
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 735723912950..8c8cd95a6989 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #include <linux/stat.h> | 74 | #include <linux/stat.h> |
75 | #include <linux/module.h> | 75 | #include <linux/module.h> |
76 | #include <linux/moduleparam.h> | 76 | #include <linux/moduleparam.h> |
77 | #include <linux/smp_lock.h> | ||
78 | #include <linux/usb/input.h> | 77 | #include <linux/usb/input.h> |
79 | 78 | ||
80 | #define DRIVER_VERSION "v0.0.6" | 79 | #define DRIVER_VERSION "v0.0.6" |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 15c70bd048c4..8d0e360636e6 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/completion.h> | 25 | #include <linux/completion.h> |
27 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
28 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 5dce797bddb7..1713e19a7899 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -80,7 +80,6 @@ | |||
80 | #include <linux/init.h> | 80 | #include <linux/init.h> |
81 | #include <linux/slab.h> | 81 | #include <linux/slab.h> |
82 | #include <linux/module.h> | 82 | #include <linux/module.h> |
83 | #include <linux/smp_lock.h> | ||
84 | #include <linux/completion.h> | 83 | #include <linux/completion.h> |
85 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
86 | #include <asm/uaccess.h> | 85 | #include <asm/uaccess.h> |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index fdf68479a166..88f6abe73624 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/usb.h> | 41 | #include <linux/usb.h> |
42 | #include <linux/smp_lock.h> | ||
43 | #include <linux/wait.h> | 42 | #include <linux/wait.h> |
44 | 43 | ||
45 | #include "rio500_usb.h" | 44 | #include "rio500_usb.h" |
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 1730d8642a47..5947afb0017e 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/selection.h> | 62 | #include <linux/selection.h> |
63 | #include <linux/spinlock.h> | 63 | #include <linux/spinlock.h> |
64 | #include <linux/kref.h> | 64 | #include <linux/kref.h> |
65 | #include <linux/smp_lock.h> | ||
66 | #include <linux/ioport.h> | 65 | #include <linux/ioport.h> |
67 | #include <linux/interrupt.h> | 66 | #include <linux/interrupt.h> |
68 | #include <linux/vmalloc.h> | 67 | #include <linux/vmalloc.h> |
@@ -322,7 +321,7 @@ sisusbcon_deinit(struct vc_data *c) | |||
322 | /* interface routine */ | 321 | /* interface routine */ |
323 | static u8 | 322 | static u8 |
324 | sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity, | 323 | sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity, |
325 | u8 blink, u8 underline, u8 reverse) | 324 | u8 blink, u8 underline, u8 reverse, u8 unused) |
326 | { | 325 | { |
327 | u8 attr = color; | 326 | u8 attr = color; |
328 | 327 | ||
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 8a1df2c9c73e..8977ec0d0f99 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/notifier.h> | 12 | #include <linux/notifier.h> |
14 | #include <linux/mutex.h> | 13 | #include <linux/mutex.h> |
15 | 14 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 7639022cdf84..87f378806db6 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
33 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
34 | #include <linux/usb/serial.h> | 33 | #include <linux/usb/serial.h> |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 21f3ddbc9080..6dac1ffdde86 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/usb_usual.h> | 48 | #include <linux/usb_usual.h> |
49 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
50 | #include <linux/smp_lock.h> | ||
51 | #include <linux/completion.h> | 50 | #include <linux/completion.h> |
52 | #include <linux/mutex.h> | 51 | #include <linux/mutex.h> |
53 | #include <scsi/scsi_host.h> | 52 | #include <scsi/scsi_host.h> |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 344c37595305..1132ba5ff391 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -5,6 +5,11 @@ | |||
5 | menu "Graphics support" | 5 | menu "Graphics support" |
6 | 6 | ||
7 | source "drivers/video/backlight/Kconfig" | 7 | source "drivers/video/backlight/Kconfig" |
8 | source "drivers/video/display/Kconfig" | ||
9 | |||
10 | config VGASTATE | ||
11 | tristate | ||
12 | default n | ||
8 | 13 | ||
9 | config FB | 14 | config FB |
10 | tristate "Support for frame buffer devices" | 15 | tristate "Support for frame buffer devices" |
@@ -90,6 +95,43 @@ config FB_CFB_IMAGEBLIT | |||
90 | blitting. This is used by drivers that don't provide their own | 95 | blitting. This is used by drivers that don't provide their own |
91 | (accelerated) version. | 96 | (accelerated) version. |
92 | 97 | ||
98 | config FB_SYS_FILLRECT | ||
99 | tristate | ||
100 | depends on FB | ||
101 | default n | ||
102 | ---help--- | ||
103 | Include the sys_fillrect function for generic software rectangle | ||
104 | filling. This is used by drivers that don't provide their own | ||
105 | (accelerated) version and the framebuffer is in system RAM. | ||
106 | |||
107 | config FB_SYS_COPYAREA | ||
108 | tristate | ||
109 | depends on FB | ||
110 | default n | ||
111 | ---help--- | ||
112 | Include the sys_copyarea function for generic software area copying. | ||
113 | This is used by drivers that don't provide their own (accelerated) | ||
114 | version and the framebuffer is in system RAM. | ||
115 | |||
116 | config FB_SYS_IMAGEBLIT | ||
117 | tristate | ||
118 | depends on FB | ||
119 | default n | ||
120 | ---help--- | ||
121 | Include the sys_imageblit function for generic software image | ||
122 | blitting. This is used by drivers that don't provide their own | ||
123 | (accelerated) version and the framebuffer is in system RAM. | ||
124 | |||
125 | config FB_SYS_FOPS | ||
126 | tristate | ||
127 | depends on FB | ||
128 | default n | ||
129 | |||
130 | config FB_DEFERRED_IO | ||
131 | bool | ||
132 | depends on FB | ||
133 | default y | ||
134 | |||
93 | config FB_SVGALIB | 135 | config FB_SVGALIB |
94 | tristate | 136 | tristate |
95 | depends on FB | 137 | depends on FB |
@@ -375,9 +417,10 @@ config FB_FM2 | |||
375 | config FB_ARC | 417 | config FB_ARC |
376 | tristate "Arc Monochrome LCD board support" | 418 | tristate "Arc Monochrome LCD board support" |
377 | depends on FB && X86 | 419 | depends on FB && X86 |
378 | select FB_CFB_FILLRECT | 420 | select FB_SYS_FILLRECT |
379 | select FB_CFB_COPYAREA | 421 | select FB_SYS_COPYAREA |
380 | select FB_CFB_IMAGEBLIT | 422 | select FB_SYS_IMAGEBLIT |
423 | select FB_SYS_FOPS | ||
381 | help | 424 | help |
382 | This enables support for the Arc Monochrome LCD board. The board | 425 | This enables support for the Arc Monochrome LCD board. The board |
383 | is based on the KS-108 lcd controller and is typically a matrix | 426 | is based on the KS-108 lcd controller and is typically a matrix |
@@ -475,6 +518,8 @@ config FB_VGA16 | |||
475 | select FB_CFB_FILLRECT | 518 | select FB_CFB_FILLRECT |
476 | select FB_CFB_COPYAREA | 519 | select FB_CFB_COPYAREA |
477 | select FB_CFB_IMAGEBLIT | 520 | select FB_CFB_IMAGEBLIT |
521 | select VGASTATE | ||
522 | select FONT_8x16 if FRAMEBUFFER_CONSOLE | ||
478 | help | 523 | help |
479 | This is the frame buffer device driver for VGA 16 color graphic | 524 | This is the frame buffer device driver for VGA 16 color graphic |
480 | cards. Say Y if you have such a card. | 525 | cards. Say Y if you have such a card. |
@@ -519,15 +564,25 @@ config FB_HP300 | |||
519 | default y | 564 | default y |
520 | 565 | ||
521 | config FB_TGA | 566 | config FB_TGA |
522 | tristate "TGA framebuffer support" | 567 | tristate "TGA/SFB+ framebuffer support" |
523 | depends on FB && ALPHA | 568 | depends on FB && (ALPHA || TC) |
524 | select FB_CFB_FILLRECT | 569 | select FB_CFB_FILLRECT |
525 | select FB_CFB_COPYAREA | 570 | select FB_CFB_COPYAREA |
526 | select FB_CFB_IMAGEBLIT | 571 | select FB_CFB_IMAGEBLIT |
527 | select BITREVERSE | 572 | select BITREVERSE |
528 | help | 573 | ---help--- |
529 | This is the frame buffer device driver for generic TGA graphic | 574 | This is the frame buffer device driver for generic TGA and SFB+ |
530 | cards. Say Y if you have one of those. | 575 | graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, |
576 | also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 | ||
577 | TURBOchannel cards, also known as PMAGD-A, -B and -C. | ||
578 | |||
579 | Due to hardware limitations ZLX-E2 and E3 cards are not supported | ||
580 | for DECstation 5000/200 systems. Additionally due to firmware | ||
581 | limitations these cards may cause troubles with booting DECstation | ||
582 | 5000/240 and /260 systems, but are fully supported under Linux if | ||
583 | you manage to get it going. ;-) | ||
584 | |||
585 | Say Y if you have one of those. | ||
531 | 586 | ||
532 | config FB_VESA | 587 | config FB_VESA |
533 | bool "VESA VGA graphics support" | 588 | bool "VESA VGA graphics support" |
@@ -551,6 +606,21 @@ config FB_IMAC | |||
551 | help | 606 | help |
552 | This is the frame buffer device driver for the Intel-based Macintosh | 607 | This is the frame buffer device driver for the Intel-based Macintosh |
553 | 608 | ||
609 | config FB_HECUBA | ||
610 | tristate "Hecuba board support" | ||
611 | depends on FB && X86 && MMU | ||
612 | select FB_SYS_FILLRECT | ||
613 | select FB_SYS_COPYAREA | ||
614 | select FB_SYS_IMAGEBLIT | ||
615 | select FB_SYS_FOPS | ||
616 | select FB_DEFERRED_IO | ||
617 | help | ||
618 | This enables support for the Hecuba board. This driver was tested | ||
619 | with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO | ||
620 | interface (8 bit data, 4 bit control). If you anticpate using | ||
621 | this driver, say Y or M; otherwise say N. You must specify the | ||
622 | GPIO IO address to be used for setting control and data. | ||
623 | |||
554 | config FB_HGA | 624 | config FB_HGA |
555 | tristate "Hercules mono graphics support" | 625 | tristate "Hercules mono graphics support" |
556 | depends on FB && X86 | 626 | depends on FB && X86 |
@@ -686,6 +756,7 @@ config FB_NVIDIA | |||
686 | select FB_CFB_COPYAREA | 756 | select FB_CFB_COPYAREA |
687 | select FB_CFB_IMAGEBLIT | 757 | select FB_CFB_IMAGEBLIT |
688 | select BITREVERSE | 758 | select BITREVERSE |
759 | select VGASTATE | ||
689 | help | 760 | help |
690 | This driver supports graphics boards with the nVidia chips, TNT | 761 | This driver supports graphics boards with the nVidia chips, TNT |
691 | and newer. For very old chipsets, such as the RIVA128, then use | 762 | and newer. For very old chipsets, such as the RIVA128, then use |
@@ -724,6 +795,7 @@ config FB_RIVA | |||
724 | select FB_CFB_COPYAREA | 795 | select FB_CFB_COPYAREA |
725 | select FB_CFB_IMAGEBLIT | 796 | select FB_CFB_IMAGEBLIT |
726 | select BITREVERSE | 797 | select BITREVERSE |
798 | select VGASTATE | ||
727 | help | 799 | help |
728 | This driver supports graphics boards with the nVidia Riva/Geforce | 800 | This driver supports graphics boards with the nVidia Riva/Geforce |
729 | chips. | 801 | chips. |
@@ -770,6 +842,7 @@ config FB_I810 | |||
770 | select FB_CFB_FILLRECT | 842 | select FB_CFB_FILLRECT |
771 | select FB_CFB_COPYAREA | 843 | select FB_CFB_COPYAREA |
772 | select FB_CFB_IMAGEBLIT | 844 | select FB_CFB_IMAGEBLIT |
845 | select VGASTATE | ||
773 | help | 846 | help |
774 | This driver supports the on-board graphics built in to the Intel 810 | 847 | This driver supports the on-board graphics built in to the Intel 810 |
775 | and 815 chipsets. Say Y if you have and plan to use such a board. | 848 | and 815 chipsets. Say Y if you have and plan to use such a board. |
@@ -809,6 +882,22 @@ config FB_I810_I2C | |||
809 | select FB_DDC | 882 | select FB_DDC |
810 | help | 883 | help |
811 | 884 | ||
885 | config FB_LE80578 | ||
886 | tristate "Intel LE80578 (Vermilion) support" | ||
887 | depends on FB && PCI && X86 | ||
888 | select FB_MODE_HELPERS | ||
889 | select FB_CFB_FILLRECT | ||
890 | select FB_CFB_COPYAREA | ||
891 | select FB_CFB_IMAGEBLIT | ||
892 | help | ||
893 | This driver supports the LE80578 (Vermilion Range) chipset | ||
894 | |||
895 | config FB_CARILLO_RANCH | ||
896 | tristate "Intel Carillo Ranch support" | ||
897 | depends on FB_LE80578 && FB && PCI && X86 | ||
898 | help | ||
899 | This driver supports the LE80578 (Carillo Ranch) board | ||
900 | |||
812 | config FB_INTEL | 901 | config FB_INTEL |
813 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" | 902 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" |
814 | depends on FB && EXPERIMENTAL && PCI && X86 | 903 | depends on FB && EXPERIMENTAL && PCI && X86 |
@@ -1120,6 +1209,8 @@ config FB_S3 | |||
1120 | select FB_CFB_IMAGEBLIT | 1209 | select FB_CFB_IMAGEBLIT |
1121 | select FB_TILEBLITTING | 1210 | select FB_TILEBLITTING |
1122 | select FB_SVGALIB | 1211 | select FB_SVGALIB |
1212 | select VGASTATE | ||
1213 | select FONT_8x16 if FRAMEBUFFER_CONSOLE | ||
1123 | ---help--- | 1214 | ---help--- |
1124 | Driver for graphics boards with S3 Trio / S3 Virge chip. | 1215 | Driver for graphics boards with S3 Trio / S3 Virge chip. |
1125 | 1216 | ||
@@ -1130,6 +1221,7 @@ config FB_SAVAGE | |||
1130 | select FB_CFB_FILLRECT | 1221 | select FB_CFB_FILLRECT |
1131 | select FB_CFB_COPYAREA | 1222 | select FB_CFB_COPYAREA |
1132 | select FB_CFB_IMAGEBLIT | 1223 | select FB_CFB_IMAGEBLIT |
1224 | select VGASTATE | ||
1133 | help | 1225 | help |
1134 | This driver supports notebooks and computers with S3 Savage PCI/AGP | 1226 | This driver supports notebooks and computers with S3 Savage PCI/AGP |
1135 | chips. | 1227 | chips. |
@@ -1196,6 +1288,7 @@ config FB_NEOMAGIC | |||
1196 | select FB_CFB_FILLRECT | 1288 | select FB_CFB_FILLRECT |
1197 | select FB_CFB_COPYAREA | 1289 | select FB_CFB_COPYAREA |
1198 | select FB_CFB_IMAGEBLIT | 1290 | select FB_CFB_IMAGEBLIT |
1291 | select VGASTATE | ||
1199 | help | 1292 | help |
1200 | This driver supports notebooks with NeoMagic PCI chips. | 1293 | This driver supports notebooks with NeoMagic PCI chips. |
1201 | Say Y if you have such a graphics card. | 1294 | Say Y if you have such a graphics card. |
@@ -1662,13 +1755,25 @@ config FB_PS3_DEFAULT_SIZE_M | |||
1662 | The default value can be overridden on the kernel command line | 1755 | The default value can be overridden on the kernel command line |
1663 | using the "ps3fb" option (e.g. "ps3fb=9M"); | 1756 | using the "ps3fb" option (e.g. "ps3fb=9M"); |
1664 | 1757 | ||
1665 | config FB_VIRTUAL | 1758 | config FB_XILINX |
1666 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" | 1759 | tristate "Xilinx frame buffer support" |
1667 | depends on FB | 1760 | depends on FB && XILINX_VIRTEX |
1668 | select FB_CFB_FILLRECT | 1761 | select FB_CFB_FILLRECT |
1669 | select FB_CFB_COPYAREA | 1762 | select FB_CFB_COPYAREA |
1670 | select FB_CFB_IMAGEBLIT | 1763 | select FB_CFB_IMAGEBLIT |
1671 | ---help--- | 1764 | ---help--- |
1765 | Include support for the Xilinx ML300/ML403 reference design | ||
1766 | framebuffer. ML300 carries a 640*480 LCD display on the board, | ||
1767 | ML403 uses a standard DB15 VGA connector. | ||
1768 | |||
1769 | config FB_VIRTUAL | ||
1770 | tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" | ||
1771 | depends on FB | ||
1772 | select FB_SYS_FILLRECT | ||
1773 | select FB_SYS_COPYAREA | ||
1774 | select FB_SYS_IMAGEBLIT | ||
1775 | select FB_SYS_FOPS | ||
1776 | ---help--- | ||
1672 | This is a `virtual' frame buffer device. It operates on a chunk of | 1777 | This is a `virtual' frame buffer device. It operates on a chunk of |
1673 | unswappable kernel memory instead of on the memory of a graphics | 1778 | unswappable kernel memory instead of on the memory of a graphics |
1674 | board. This means you cannot see any output sent to this frame | 1779 | board. This means you cannot see any output sent to this frame |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 558473d040d6..a916c204274f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_VGASTATE) += vgastate.o | ||
7 | obj-y += fb_notify.o | 8 | obj-y += fb_notify.o |
8 | obj-$(CONFIG_FB) += fb.o | 9 | obj-$(CONFIG_FB) += fb.o |
9 | fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ | 10 | fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ |
@@ -12,14 +13,19 @@ fb-objs := $(fb-y) | |||
12 | 13 | ||
13 | obj-$(CONFIG_VT) += console/ | 14 | obj-$(CONFIG_VT) += console/ |
14 | obj-$(CONFIG_LOGO) += logo/ | 15 | obj-$(CONFIG_LOGO) += logo/ |
15 | obj-y += backlight/ | 16 | obj-y += backlight/ display/ |
16 | 17 | ||
17 | obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o | 18 | obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o |
18 | obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o | 19 | obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o |
19 | obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o | 20 | obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o |
21 | obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o | ||
22 | obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o | ||
23 | obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o | ||
24 | obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o | ||
20 | obj-$(CONFIG_FB_SVGALIB) += svgalib.o | 25 | obj-$(CONFIG_FB_SVGALIB) += svgalib.o |
21 | obj-$(CONFIG_FB_MACMODES) += macmodes.o | 26 | obj-$(CONFIG_FB_MACMODES) += macmodes.o |
22 | obj-$(CONFIG_FB_DDC) += fb_ddc.o | 27 | obj-$(CONFIG_FB_DDC) += fb_ddc.o |
28 | obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o | ||
23 | 29 | ||
24 | # Hardware specific drivers go first | 30 | # Hardware specific drivers go first |
25 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o | 31 | obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o |
@@ -30,7 +36,7 @@ obj-$(CONFIG_FB_PM2) += pm2fb.o | |||
30 | obj-$(CONFIG_FB_PM3) += pm3fb.o | 36 | obj-$(CONFIG_FB_PM3) += pm3fb.o |
31 | 37 | ||
32 | obj-$(CONFIG_FB_MATROX) += matrox/ | 38 | obj-$(CONFIG_FB_MATROX) += matrox/ |
33 | obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o | 39 | obj-$(CONFIG_FB_RIVA) += riva/ |
34 | obj-$(CONFIG_FB_NVIDIA) += nvidia/ | 40 | obj-$(CONFIG_FB_NVIDIA) += nvidia/ |
35 | obj-$(CONFIG_FB_ATY) += aty/ macmodes.o | 41 | obj-$(CONFIG_FB_ATY) += aty/ macmodes.o |
36 | obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o | 42 | obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o |
@@ -40,8 +46,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/ | |||
40 | obj-$(CONFIG_FB_SAVAGE) += savage/ | 46 | obj-$(CONFIG_FB_SAVAGE) += savage/ |
41 | obj-$(CONFIG_FB_GEODE) += geode/ | 47 | obj-$(CONFIG_FB_GEODE) += geode/ |
42 | obj-$(CONFIG_FB_MBX) += mbx/ | 48 | obj-$(CONFIG_FB_MBX) += mbx/ |
43 | obj-$(CONFIG_FB_I810) += vgastate.o | 49 | obj-$(CONFIG_FB_NEOMAGIC) += neofb.o |
44 | obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o | ||
45 | obj-$(CONFIG_FB_3DFX) += tdfxfb.o | 50 | obj-$(CONFIG_FB_3DFX) += tdfxfb.o |
46 | obj-$(CONFIG_FB_CONTROL) += controlfb.o | 51 | obj-$(CONFIG_FB_CONTROL) += controlfb.o |
47 | obj-$(CONFIG_FB_PLATINUM) += platinumfb.o | 52 | obj-$(CONFIG_FB_PLATINUM) += platinumfb.o |
@@ -51,7 +56,8 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o | |||
51 | obj-$(CONFIG_FB_FM2) += fm2fb.o | 56 | obj-$(CONFIG_FB_FM2) += fm2fb.o |
52 | obj-$(CONFIG_FB_CYBLA) += cyblafb.o | 57 | obj-$(CONFIG_FB_CYBLA) += cyblafb.o |
53 | obj-$(CONFIG_FB_TRIDENT) += tridentfb.o | 58 | obj-$(CONFIG_FB_TRIDENT) += tridentfb.o |
54 | obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o | 59 | obj-$(CONFIG_FB_LE80578) += vermilion/ |
60 | obj-$(CONFIG_FB_S3) += s3fb.o | ||
55 | obj-$(CONFIG_FB_STI) += stifb.o | 61 | obj-$(CONFIG_FB_STI) += stifb.o |
56 | obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o | 62 | obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o |
57 | obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o | 63 | obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o |
@@ -66,6 +72,7 @@ obj-$(CONFIG_FB_ACORN) += acornfb.o | |||
66 | obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \ | 72 | obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \ |
67 | atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o | 73 | atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o |
68 | obj-$(CONFIG_FB_MAC) += macfb.o | 74 | obj-$(CONFIG_FB_MAC) += macfb.o |
75 | obj-$(CONFIG_FB_HECUBA) += hecubafb.o | ||
69 | obj-$(CONFIG_FB_HGA) += hgafb.o | 76 | obj-$(CONFIG_FB_HGA) += hgafb.o |
70 | obj-$(CONFIG_FB_XVR500) += sunxvr500.o | 77 | obj-$(CONFIG_FB_XVR500) += sunxvr500.o |
71 | obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o | 78 | obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o |
@@ -102,11 +109,12 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ | |||
102 | obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o | 109 | obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o |
103 | obj-$(CONFIG_FB_PS3) += ps3fb.o | 110 | obj-$(CONFIG_FB_PS3) += ps3fb.o |
104 | obj-$(CONFIG_FB_SM501) += sm501fb.o | 111 | obj-$(CONFIG_FB_SM501) += sm501fb.o |
112 | obj-$(CONFIG_FB_XILINX) += xilinxfb.o | ||
105 | 113 | ||
106 | # Platform or fallback drivers go here | 114 | # Platform or fallback drivers go here |
107 | obj-$(CONFIG_FB_VESA) += vesafb.o | 115 | obj-$(CONFIG_FB_VESA) += vesafb.o |
108 | obj-$(CONFIG_FB_IMAC) += imacfb.o | 116 | obj-$(CONFIG_FB_IMAC) += imacfb.o |
109 | obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o | 117 | obj-$(CONFIG_FB_VGA16) += vga16fb.o |
110 | obj-$(CONFIG_FB_OF) += offb.o | 118 | obj-$(CONFIG_FB_OF) += offb.o |
111 | 119 | ||
112 | # the test framebuffer is last | 120 | # the test framebuffer is last |
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 30a8369757e7..db15baca3f7b 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c | |||
@@ -262,7 +262,8 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper, | |||
262 | ks108_set_yaddr(par, chipindex, upper/8); | 262 | ks108_set_yaddr(par, chipindex, upper/8); |
263 | 263 | ||
264 | linesize = par->info->var.xres/8; | 264 | linesize = par->info->var.xres/8; |
265 | src = par->info->screen_base + (left/8) + (upper * linesize); | 265 | src = (unsigned char __force *) par->info->screen_base + (left/8) + |
266 | (upper * linesize); | ||
266 | ks108_set_xaddr(par, chipindex, left); | 267 | ks108_set_xaddr(par, chipindex, left); |
267 | 268 | ||
268 | bitmask=1; | 269 | bitmask=1; |
@@ -368,7 +369,7 @@ static void arcfb_fillrect(struct fb_info *info, | |||
368 | { | 369 | { |
369 | struct arcfb_par *par = info->par; | 370 | struct arcfb_par *par = info->par; |
370 | 371 | ||
371 | cfb_fillrect(info, rect); | 372 | sys_fillrect(info, rect); |
372 | 373 | ||
373 | /* update the physical lcd */ | 374 | /* update the physical lcd */ |
374 | arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); | 375 | arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); |
@@ -379,7 +380,7 @@ static void arcfb_copyarea(struct fb_info *info, | |||
379 | { | 380 | { |
380 | struct arcfb_par *par = info->par; | 381 | struct arcfb_par *par = info->par; |
381 | 382 | ||
382 | cfb_copyarea(info, area); | 383 | sys_copyarea(info, area); |
383 | 384 | ||
384 | /* update the physical lcd */ | 385 | /* update the physical lcd */ |
385 | arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); | 386 | arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); |
@@ -389,7 +390,7 @@ static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
389 | { | 390 | { |
390 | struct arcfb_par *par = info->par; | 391 | struct arcfb_par *par = info->par; |
391 | 392 | ||
392 | cfb_imageblit(info, image); | 393 | sys_imageblit(info, image); |
393 | 394 | ||
394 | /* update the physical lcd */ | 395 | /* update the physical lcd */ |
395 | arcfb_lcd_update(par, image->dx, image->dy, image->width, | 396 | arcfb_lcd_update(par, image->dx, image->dy, image->width, |
@@ -439,14 +440,11 @@ static int arcfb_ioctl(struct fb_info *info, | |||
439 | * the fb. it's inefficient for them to do anything less than 64*8 | 440 | * the fb. it's inefficient for them to do anything less than 64*8 |
440 | * writes since we update the lcd in each write() anyway. | 441 | * writes since we update the lcd in each write() anyway. |
441 | */ | 442 | */ |
442 | static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count, | 443 | static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, |
443 | loff_t *ppos) | 444 | size_t count, loff_t *ppos) |
444 | { | 445 | { |
445 | /* modded from epson 1355 */ | 446 | /* modded from epson 1355 */ |
446 | 447 | ||
447 | struct inode *inode; | ||
448 | int fbidx; | ||
449 | struct fb_info *info; | ||
450 | unsigned long p; | 448 | unsigned long p; |
451 | int err=-EINVAL; | 449 | int err=-EINVAL; |
452 | unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; | 450 | unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; |
@@ -454,13 +452,6 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou | |||
454 | unsigned int xres; | 452 | unsigned int xres; |
455 | 453 | ||
456 | p = *ppos; | 454 | p = *ppos; |
457 | inode = file->f_path.dentry->d_inode; | ||
458 | fbidx = iminor(inode); | ||
459 | info = registered_fb[fbidx]; | ||
460 | |||
461 | if (!info || !info->screen_base) | ||
462 | return -ENODEV; | ||
463 | |||
464 | par = info->par; | 455 | par = info->par; |
465 | xres = info->var.xres; | 456 | xres = info->var.xres; |
466 | fbmemlength = (xres * info->var.yres)/8; | 457 | fbmemlength = (xres * info->var.yres)/8; |
@@ -477,7 +468,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou | |||
477 | if (count) { | 468 | if (count) { |
478 | char *base_addr; | 469 | char *base_addr; |
479 | 470 | ||
480 | base_addr = info->screen_base; | 471 | base_addr = (char __force *)info->screen_base; |
481 | count -= copy_from_user(base_addr + p, buf, count); | 472 | count -= copy_from_user(base_addr + p, buf, count); |
482 | *ppos += count; | 473 | *ppos += count; |
483 | err = -EFAULT; | 474 | err = -EFAULT; |
@@ -503,6 +494,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou | |||
503 | static struct fb_ops arcfb_ops = { | 494 | static struct fb_ops arcfb_ops = { |
504 | .owner = THIS_MODULE, | 495 | .owner = THIS_MODULE, |
505 | .fb_open = arcfb_open, | 496 | .fb_open = arcfb_open, |
497 | .fb_read = fb_sys_read, | ||
506 | .fb_write = arcfb_write, | 498 | .fb_write = arcfb_write, |
507 | .fb_release = arcfb_release, | 499 | .fb_release = arcfb_release, |
508 | .fb_pan_display = arcfb_pan_display, | 500 | .fb_pan_display = arcfb_pan_display, |
@@ -603,7 +595,7 @@ static int arcfb_remove(struct platform_device *dev) | |||
603 | 595 | ||
604 | if (info) { | 596 | if (info) { |
605 | unregister_framebuffer(info); | 597 | unregister_framebuffer(info); |
606 | vfree(info->screen_base); | 598 | vfree((void __force *)info->screen_base); |
607 | framebuffer_release(info); | 599 | framebuffer_release(info); |
608 | } | 600 | } |
609 | return 0; | 601 | return 0; |
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h index 39ab483fc250..90e7df22f508 100644 --- a/drivers/video/aty/ati_ids.h +++ b/drivers/video/aty/ati_ids.h | |||
@@ -209,4 +209,4 @@ | |||
209 | #define PCI_CHIP_R423_5D57 0x5D57 | 209 | #define PCI_CHIP_R423_5D57 0x5D57 |
210 | #define PCI_CHIP_RS350_7834 0x7834 | 210 | #define PCI_CHIP_RS350_7834 0x7834 |
211 | #define PCI_CHIP_RS350_7835 0x7835 | 211 | #define PCI_CHIP_RS350_7835 0x7835 |
212 | 212 | #define PCI_CHIP_RS480_5955 0x5955 | |
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index e86d7e0c9825..7fea4d8ae8e2 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -2165,18 +2165,29 @@ static void __devexit aty128_remove(struct pci_dev *pdev) | |||
2165 | static int aty128fb_blank(int blank, struct fb_info *fb) | 2165 | static int aty128fb_blank(int blank, struct fb_info *fb) |
2166 | { | 2166 | { |
2167 | struct aty128fb_par *par = fb->par; | 2167 | struct aty128fb_par *par = fb->par; |
2168 | u8 state = 0; | 2168 | u8 state; |
2169 | 2169 | ||
2170 | if (par->lock_blank || par->asleep) | 2170 | if (par->lock_blank || par->asleep) |
2171 | return 0; | 2171 | return 0; |
2172 | 2172 | ||
2173 | if (blank & FB_BLANK_VSYNC_SUSPEND) | 2173 | switch (blank) { |
2174 | state |= 2; | 2174 | case FB_BLANK_NORMAL: |
2175 | if (blank & FB_BLANK_HSYNC_SUSPEND) | 2175 | state = 4; |
2176 | state |= 1; | 2176 | break; |
2177 | if (blank & FB_BLANK_POWERDOWN) | 2177 | case FB_BLANK_VSYNC_SUSPEND: |
2178 | state |= 4; | 2178 | state = 6; |
2179 | 2179 | break; | |
2180 | case FB_BLANK_HSYNC_SUSPEND: | ||
2181 | state = 5; | ||
2182 | break; | ||
2183 | case FB_BLANK_POWERDOWN: | ||
2184 | state = 7; | ||
2185 | break; | ||
2186 | case FB_BLANK_UNBLANK: | ||
2187 | default: | ||
2188 | state = 0; | ||
2189 | break; | ||
2190 | } | ||
2180 | aty_st_8(CRTC_EXT_CNTL+1, state); | 2191 | aty_st_8(CRTC_EXT_CNTL+1, state); |
2181 | 2192 | ||
2182 | if (par->chip_gen == rage_M3) { | 2193 | if (par->chip_gen == rage_M3) { |
@@ -2430,7 +2441,7 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2430 | wait_for_idle(par); | 2441 | wait_for_idle(par); |
2431 | 2442 | ||
2432 | /* Blank display and LCD */ | 2443 | /* Blank display and LCD */ |
2433 | aty128fb_blank(VESA_POWERDOWN, info); | 2444 | aty128fb_blank(FB_BLANK_POWERDOWN, info); |
2434 | 2445 | ||
2435 | /* Sleep */ | 2446 | /* Sleep */ |
2436 | par->asleep = 1; | 2447 | par->asleep = 1; |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 8514f2a6f060..ea67dd902d4e 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2297,20 +2297,6 @@ static int __devinit aty_init(struct fb_info *info) | |||
2297 | par->pll_limits.xclk = 53; | 2297 | par->pll_limits.xclk = 53; |
2298 | } | 2298 | } |
2299 | #endif | 2299 | #endif |
2300 | if (pll) | ||
2301 | par->pll_limits.pll_max = pll; | ||
2302 | if (mclk) | ||
2303 | par->pll_limits.mclk = mclk; | ||
2304 | if (xclk) | ||
2305 | par->pll_limits.xclk = xclk; | ||
2306 | |||
2307 | aty_calc_mem_refresh(par, par->pll_limits.xclk); | ||
2308 | par->pll_per = 1000000/par->pll_limits.pll_max; | ||
2309 | par->mclk_per = 1000000/par->pll_limits.mclk; | ||
2310 | par->xclk_per = 1000000/par->pll_limits.xclk; | ||
2311 | |||
2312 | par->ref_clk_per = 1000000000000ULL / 14318180; | ||
2313 | xtal = "14.31818"; | ||
2314 | 2300 | ||
2315 | #ifdef CONFIG_FB_ATY_GX | 2301 | #ifdef CONFIG_FB_ATY_GX |
2316 | if (!M64_HAS(INTEGRATED)) { | 2302 | if (!M64_HAS(INTEGRATED)) { |
@@ -2338,6 +2324,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
2338 | case DAC_IBMRGB514: | 2324 | case DAC_IBMRGB514: |
2339 | par->dac_ops = &aty_dac_ibm514; | 2325 | par->dac_ops = &aty_dac_ibm514; |
2340 | break; | 2326 | break; |
2327 | #ifdef CONFIG_ATARI | ||
2341 | case DAC_ATI68860_B: | 2328 | case DAC_ATI68860_B: |
2342 | case DAC_ATI68860_C: | 2329 | case DAC_ATI68860_C: |
2343 | par->dac_ops = &aty_dac_ati68860b; | 2330 | par->dac_ops = &aty_dac_ati68860b; |
@@ -2346,6 +2333,7 @@ static int __devinit aty_init(struct fb_info *info) | |||
2346 | case DAC_ATT21C498: | 2333 | case DAC_ATT21C498: |
2347 | par->dac_ops = &aty_dac_att21c498; | 2334 | par->dac_ops = &aty_dac_att21c498; |
2348 | break; | 2335 | break; |
2336 | #endif | ||
2349 | default: | 2337 | default: |
2350 | PRINTKI("aty_init: DAC type not implemented yet!\n"); | 2338 | PRINTKI("aty_init: DAC type not implemented yet!\n"); |
2351 | par->dac_ops = &aty_dac_unsupported; | 2339 | par->dac_ops = &aty_dac_unsupported; |
@@ -2389,8 +2377,29 @@ static int __devinit aty_init(struct fb_info *info) | |||
2389 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ | 2377 | /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ |
2390 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) | 2378 | if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) |
2391 | par->pll_limits.mclk = 63; | 2379 | par->pll_limits.mclk = 63; |
2380 | /* Mobility + 32bit memory interface need halved XCLK. */ | ||
2381 | if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32) | ||
2382 | par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1; | ||
2392 | } | 2383 | } |
2384 | #endif | ||
2393 | 2385 | ||
2386 | /* Allow command line to override clocks. */ | ||
2387 | if (pll) | ||
2388 | par->pll_limits.pll_max = pll; | ||
2389 | if (mclk) | ||
2390 | par->pll_limits.mclk = mclk; | ||
2391 | if (xclk) | ||
2392 | par->pll_limits.xclk = xclk; | ||
2393 | |||
2394 | aty_calc_mem_refresh(par, par->pll_limits.xclk); | ||
2395 | par->pll_per = 1000000/par->pll_limits.pll_max; | ||
2396 | par->mclk_per = 1000000/par->pll_limits.mclk; | ||
2397 | par->xclk_per = 1000000/par->pll_limits.xclk; | ||
2398 | |||
2399 | par->ref_clk_per = 1000000000000ULL / 14318180; | ||
2400 | xtal = "14.31818"; | ||
2401 | |||
2402 | #ifdef CONFIG_FB_ATY_CT | ||
2394 | if (M64_HAS(GTB_DSP)) { | 2403 | if (M64_HAS(GTB_DSP)) { |
2395 | u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par); | 2404 | u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par); |
2396 | 2405 | ||
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index 1fdcfdbf669b..cc9e9779b75f 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c | |||
@@ -608,12 +608,10 @@ static void aty_resume_pll_ct(const struct fb_info *info, | |||
608 | aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par); | 608 | aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par); |
609 | aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par); | 609 | aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par); |
610 | /* | 610 | /* |
611 | * The sclk has been started. However, I believe the first clock | 611 | * SCLK has been started. Wait for the PLL to lock. 5 ms |
612 | * ticks it generates are not very stable. Hope this primitive loop | 612 | * should be enough according to mach64 programmer's guide. |
613 | * helps for Rage Mobilities that sometimes crash when | ||
614 | * we switch to sclk. (Daniel Mantione, 13-05-2003) | ||
615 | */ | 613 | */ |
616 | udelay(500); | 614 | mdelay(5); |
617 | } | 615 | } |
618 | 616 | ||
619 | aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par); | 617 | aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par); |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 9d629fe1709d..2ce050193018 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -100,6 +100,8 @@ | |||
100 | { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } | 100 | { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } |
101 | 101 | ||
102 | static struct pci_device_id radeonfb_pci_table[] = { | 102 | static struct pci_device_id radeonfb_pci_table[] = { |
103 | /* Radeon Xpress 200m */ | ||
104 | CHIP_DEF(PCI_CHIP_RS480_5955, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | ||
103 | /* Mobility M6 */ | 105 | /* Mobility M6 */ |
104 | CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | 106 | CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), |
105 | CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | 107 | CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), |
@@ -1994,7 +1996,8 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) | |||
1994 | /* framebuffer size */ | 1996 | /* framebuffer size */ |
1995 | if ((rinfo->family == CHIP_FAMILY_RS100) || | 1997 | if ((rinfo->family == CHIP_FAMILY_RS100) || |
1996 | (rinfo->family == CHIP_FAMILY_RS200) || | 1998 | (rinfo->family == CHIP_FAMILY_RS200) || |
1997 | (rinfo->family == CHIP_FAMILY_RS300)) { | 1999 | (rinfo->family == CHIP_FAMILY_RS300) || |
2000 | (rinfo->family == CHIP_FAMILY_RS480) ) { | ||
1998 | u32 tom = INREG(NB_TOM); | 2001 | u32 tom = INREG(NB_TOM); |
1999 | tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); | 2002 | tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); |
2000 | 2003 | ||
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 1786ae188322..be1d57bf9dc8 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -2826,11 +2826,15 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis | |||
2826 | rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); | 2826 | rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); |
2827 | 2827 | ||
2828 | /* Enable/Disable dynamic clocks: TODO add sysfs access */ | 2828 | /* Enable/Disable dynamic clocks: TODO add sysfs access */ |
2829 | rinfo->dynclk = dynclk; | 2829 | if (rinfo->family == CHIP_FAMILY_RS480) |
2830 | if (dynclk == 1) { | 2830 | rinfo->dynclk = -1; |
2831 | else | ||
2832 | rinfo->dynclk = dynclk; | ||
2833 | |||
2834 | if (rinfo->dynclk == 1) { | ||
2831 | radeon_pm_enable_dynamic_mode(rinfo); | 2835 | radeon_pm_enable_dynamic_mode(rinfo); |
2832 | printk("radeonfb: Dynamic Clock Power Management enabled\n"); | 2836 | printk("radeonfb: Dynamic Clock Power Management enabled\n"); |
2833 | } else if (dynclk == 0) { | 2837 | } else if (rinfo->dynclk == 0) { |
2834 | radeon_pm_disable_dynamic_mode(rinfo); | 2838 | radeon_pm_disable_dynamic_mode(rinfo); |
2835 | printk("radeonfb: Dynamic Clock Power Management disabled\n"); | 2839 | printk("radeonfb: Dynamic Clock Power Management disabled\n"); |
2836 | } | 2840 | } |
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 319000360285..7ebffcdfd1e3 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h | |||
@@ -48,6 +48,7 @@ enum radeon_family { | |||
48 | CHIP_FAMILY_RV350, | 48 | CHIP_FAMILY_RV350, |
49 | CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ | 49 | CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ |
50 | CHIP_FAMILY_R420, /* R420/R423/M18 */ | 50 | CHIP_FAMILY_R420, /* R420/R423/M18 */ |
51 | CHIP_FAMILY_RS480, | ||
51 | CHIP_FAMILY_LAST, | 52 | CHIP_FAMILY_LAST, |
52 | }; | 53 | }; |
53 | 54 | ||
@@ -64,7 +65,8 @@ enum radeon_family { | |||
64 | ((rinfo)->family == CHIP_FAMILY_RV350) || \ | 65 | ((rinfo)->family == CHIP_FAMILY_RV350) || \ |
65 | ((rinfo)->family == CHIP_FAMILY_R350) || \ | 66 | ((rinfo)->family == CHIP_FAMILY_R350) || \ |
66 | ((rinfo)->family == CHIP_FAMILY_RV380) || \ | 67 | ((rinfo)->family == CHIP_FAMILY_RV380) || \ |
67 | ((rinfo)->family == CHIP_FAMILY_R420)) | 68 | ((rinfo)->family == CHIP_FAMILY_R420) || \ |
69 | ((rinfo)->family == CHIP_FAMILY_RS480) ) | ||
68 | 70 | ||
69 | /* | 71 | /* |
70 | * Chip flags | 72 | * Chip flags |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 47d15b5d985a..fbef663fc057 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -63,3 +63,11 @@ config BACKLIGHT_PROGEAR | |||
63 | help | 63 | help |
64 | If you have a Frontpath ProGear say Y to enable the | 64 | If you have a Frontpath ProGear say Y to enable the |
65 | backlight driver. | 65 | backlight driver. |
66 | |||
67 | config BACKLIGHT_CARILLO_RANCH | ||
68 | tristate "Intel Carillo Ranch Backlight Driver" | ||
69 | depends on BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 | ||
70 | default n | ||
71 | help | ||
72 | If you have a Intel LE80578 (Carillo Ranch) say Y to enable the | ||
73 | backlight driver. | ||
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 0c3ce46f5094..c6e2266f63e2 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -6,3 +6,4 @@ obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o | |||
6 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 6 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
7 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o | 7 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o |
8 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o | 8 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o |
9 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | ||
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c new file mode 100644 index 000000000000..e9bbc3455c94 --- /dev/null +++ b/drivers/video/backlight/cr_bllcd.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | * Copyright (c) Intel Corp. 2007. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||
6 | * develop this driver. | ||
7 | * | ||
8 | * This file is part of the Carillo Ranch video subsystem driver. | ||
9 | * The Carillo Ranch video subsystem driver is free software; | ||
10 | * you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * The Carillo Ranch video subsystem driver is distributed | ||
16 | * in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this driver; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | ||
27 | * Alan Hourihane <alanh-at-tungstengraphics-dot-com> | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/mutex.h> | ||
35 | #include <linux/fb.h> | ||
36 | #include <linux/backlight.h> | ||
37 | #include <linux/lcd.h> | ||
38 | #include <linux/pci.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* The LVDS- and panel power controls sits on the | ||
42 | * GPIO port of the ISA bridge. | ||
43 | */ | ||
44 | |||
45 | #define CRVML_DEVICE_LPC 0x27B8 | ||
46 | #define CRVML_REG_GPIOBAR 0x48 | ||
47 | #define CRVML_REG_GPIOEN 0x4C | ||
48 | #define CRVML_GPIOEN_BIT (1 << 4) | ||
49 | #define CRVML_PANEL_PORT 0x38 | ||
50 | #define CRVML_LVDS_ON 0x00000001 | ||
51 | #define CRVML_PANEL_ON 0x00000002 | ||
52 | #define CRVML_BACKLIGHT_OFF 0x00000004 | ||
53 | |||
54 | /* The PLL Clock register sits on Host bridge */ | ||
55 | #define CRVML_DEVICE_MCH 0x5001 | ||
56 | #define CRVML_REG_MCHBAR 0x44 | ||
57 | #define CRVML_REG_MCHEN 0x54 | ||
58 | #define CRVML_MCHEN_BIT (1 << 28) | ||
59 | #define CRVML_MCHMAP_SIZE 4096 | ||
60 | #define CRVML_REG_CLOCK 0xc3c | ||
61 | #define CRVML_CLOCK_SHIFT 8 | ||
62 | #define CRVML_CLOCK_MASK 0x00000f00 | ||
63 | |||
64 | static struct pci_dev *lpc_dev; | ||
65 | static u32 gpio_bar; | ||
66 | |||
67 | struct cr_panel { | ||
68 | struct backlight_device *cr_backlight_device; | ||
69 | struct lcd_device *cr_lcd_device; | ||
70 | }; | ||
71 | |||
72 | static int cr_backlight_set_intensity(struct backlight_device *bd) | ||
73 | { | ||
74 | int intensity = bd->props.brightness; | ||
75 | u32 addr = gpio_bar + CRVML_PANEL_PORT; | ||
76 | u32 cur = inl(addr); | ||
77 | |||
78 | if (bd->props.power == FB_BLANK_UNBLANK) | ||
79 | intensity = FB_BLANK_UNBLANK; | ||
80 | if (bd->props.fb_blank == FB_BLANK_UNBLANK) | ||
81 | intensity = FB_BLANK_UNBLANK; | ||
82 | if (bd->props.power == FB_BLANK_POWERDOWN) | ||
83 | intensity = FB_BLANK_POWERDOWN; | ||
84 | if (bd->props.fb_blank == FB_BLANK_POWERDOWN) | ||
85 | intensity = FB_BLANK_POWERDOWN; | ||
86 | |||
87 | if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */ | ||
88 | cur &= ~CRVML_BACKLIGHT_OFF; | ||
89 | outl(cur, addr); | ||
90 | } else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */ | ||
91 | cur |= CRVML_BACKLIGHT_OFF; | ||
92 | outl(cur, addr); | ||
93 | } /* anything else, don't bother */ | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int cr_backlight_get_intensity(struct backlight_device *bd) | ||
99 | { | ||
100 | u32 addr = gpio_bar + CRVML_PANEL_PORT; | ||
101 | u32 cur = inl(addr); | ||
102 | u8 intensity; | ||
103 | |||
104 | if (cur & CRVML_BACKLIGHT_OFF) | ||
105 | intensity = FB_BLANK_POWERDOWN; | ||
106 | else | ||
107 | intensity = FB_BLANK_UNBLANK; | ||
108 | |||
109 | return intensity; | ||
110 | } | ||
111 | |||
112 | static struct backlight_ops cr_backlight_ops = { | ||
113 | .get_brightness = cr_backlight_get_intensity, | ||
114 | .update_status = cr_backlight_set_intensity, | ||
115 | }; | ||
116 | |||
117 | static void cr_panel_on(void) | ||
118 | { | ||
119 | u32 addr = gpio_bar + CRVML_PANEL_PORT; | ||
120 | u32 cur = inl(addr); | ||
121 | |||
122 | if (!(cur & CRVML_PANEL_ON)) { | ||
123 | /* Make sure LVDS controller is down. */ | ||
124 | if (cur & 0x00000001) { | ||
125 | cur &= ~CRVML_LVDS_ON; | ||
126 | outl(cur, addr); | ||
127 | } | ||
128 | /* Power up Panel */ | ||
129 | schedule_timeout(HZ / 10); | ||
130 | cur |= CRVML_PANEL_ON; | ||
131 | outl(cur, addr); | ||
132 | } | ||
133 | |||
134 | /* Power up LVDS controller */ | ||
135 | |||
136 | if (!(cur & CRVML_LVDS_ON)) { | ||
137 | schedule_timeout(HZ / 10); | ||
138 | outl(cur | CRVML_LVDS_ON, addr); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static void cr_panel_off(void) | ||
143 | { | ||
144 | u32 addr = gpio_bar + CRVML_PANEL_PORT; | ||
145 | u32 cur = inl(addr); | ||
146 | |||
147 | /* Power down LVDS controller first to avoid high currents */ | ||
148 | if (cur & CRVML_LVDS_ON) { | ||
149 | cur &= ~CRVML_LVDS_ON; | ||
150 | outl(cur, addr); | ||
151 | } | ||
152 | if (cur & CRVML_PANEL_ON) { | ||
153 | schedule_timeout(HZ / 10); | ||
154 | outl(cur & ~CRVML_PANEL_ON, addr); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int cr_lcd_set_power(struct lcd_device *ld, int power) | ||
159 | { | ||
160 | if (power == FB_BLANK_UNBLANK) | ||
161 | cr_panel_on(); | ||
162 | if (power == FB_BLANK_POWERDOWN) | ||
163 | cr_panel_off(); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static struct lcd_ops cr_lcd_ops = { | ||
169 | .set_power = cr_lcd_set_power, | ||
170 | }; | ||
171 | |||
172 | static int cr_backlight_probe(struct platform_device *pdev) | ||
173 | { | ||
174 | struct cr_panel *crp; | ||
175 | u8 dev_en; | ||
176 | |||
177 | crp = kzalloc(sizeof(crp), GFP_KERNEL); | ||
178 | if (crp == NULL) | ||
179 | return -ENOMEM; | ||
180 | |||
181 | lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
182 | CRVML_DEVICE_LPC, NULL); | ||
183 | if (!lpc_dev) { | ||
184 | printk("INTEL CARILLO RANCH LPC not found.\n"); | ||
185 | return -ENODEV; | ||
186 | } | ||
187 | |||
188 | pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en); | ||
189 | if (!(dev_en & CRVML_GPIOEN_BIT)) { | ||
190 | printk(KERN_ERR | ||
191 | "Carillo Ranch GPIO device was not enabled.\n"); | ||
192 | pci_dev_put(lpc_dev); | ||
193 | return -ENODEV; | ||
194 | } | ||
195 | |||
196 | crp->cr_backlight_device = backlight_device_register("cr-backlight", | ||
197 | &pdev->dev, NULL, | ||
198 | &cr_backlight_ops); | ||
199 | if (IS_ERR(crp->cr_backlight_device)) { | ||
200 | pci_dev_put(lpc_dev); | ||
201 | return PTR_ERR(crp->cr_backlight_device); | ||
202 | } | ||
203 | |||
204 | crp->cr_lcd_device = lcd_device_register("cr-lcd", | ||
205 | &pdev->dev, | ||
206 | &cr_lcd_ops); | ||
207 | |||
208 | if (IS_ERR(crp->cr_lcd_device)) { | ||
209 | pci_dev_put(lpc_dev); | ||
210 | return PTR_ERR(crp->cr_backlight_device); | ||
211 | } | ||
212 | |||
213 | pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, | ||
214 | &gpio_bar); | ||
215 | gpio_bar &= ~0x3F; | ||
216 | |||
217 | crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; | ||
218 | crp->cr_backlight_device->props.brightness = 0; | ||
219 | crp->cr_backlight_device->props.max_brightness = 0; | ||
220 | cr_backlight_set_intensity(crp->cr_backlight_device); | ||
221 | |||
222 | cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); | ||
223 | |||
224 | platform_set_drvdata(pdev, crp); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int cr_backlight_remove(struct platform_device *pdev) | ||
230 | { | ||
231 | struct cr_panel *crp = platform_get_drvdata(pdev); | ||
232 | crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN; | ||
233 | crp->cr_backlight_device->props.brightness = 0; | ||
234 | crp->cr_backlight_device->props.max_brightness = 0; | ||
235 | cr_backlight_set_intensity(crp->cr_backlight_device); | ||
236 | cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN); | ||
237 | backlight_device_unregister(crp->cr_backlight_device); | ||
238 | lcd_device_unregister(crp->cr_lcd_device); | ||
239 | pci_dev_put(lpc_dev); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static struct platform_driver cr_backlight_driver = { | ||
245 | .probe = cr_backlight_probe, | ||
246 | .remove = cr_backlight_remove, | ||
247 | .driver = { | ||
248 | .name = "cr_backlight", | ||
249 | }, | ||
250 | }; | ||
251 | |||
252 | static struct platform_device *crp; | ||
253 | |||
254 | static int __init cr_backlight_init(void) | ||
255 | { | ||
256 | int ret = platform_driver_register(&cr_backlight_driver); | ||
257 | |||
258 | if (!ret) { | ||
259 | crp = platform_device_alloc("cr_backlight", -1); | ||
260 | if (!crp) | ||
261 | return -ENOMEM; | ||
262 | |||
263 | ret = platform_device_add(crp); | ||
264 | |||
265 | if (ret) { | ||
266 | platform_device_put(crp); | ||
267 | platform_driver_unregister(&cr_backlight_driver); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | printk("Carillo Ranch Backlight Driver Initialized.\n"); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | static void __exit cr_backlight_exit(void) | ||
277 | { | ||
278 | platform_device_unregister(crp); | ||
279 | platform_driver_unregister(&cr_backlight_driver); | ||
280 | } | ||
281 | |||
282 | module_init(cr_backlight_init); | ||
283 | module_exit(cr_backlight_exit); | ||
284 | |||
285 | MODULE_AUTHOR("Tungsten Graphics Inc."); | ||
286 | MODULE_DESCRIPTION("Carillo Ranch Backlight Driver"); | ||
287 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index 6faea4034e3d..032210f45be3 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c | |||
@@ -22,8 +22,6 @@ | |||
22 | * help moving some redundant computations and branches out of the loop, too. | 22 | * help moving some redundant computations and branches out of the loop, too. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | |||
26 | |||
27 | #include <linux/module.h> | 25 | #include <linux/module.h> |
28 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
29 | #include <linux/string.h> | 27 | #include <linux/string.h> |
@@ -31,6 +29,7 @@ | |||
31 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
32 | #include <asm/types.h> | 30 | #include <asm/types.h> |
33 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include "fb_draw.h" | ||
34 | 33 | ||
35 | #if BITS_PER_LONG == 32 | 34 | #if BITS_PER_LONG == 32 |
36 | # define FB_WRITEL fb_writel | 35 | # define FB_WRITEL fb_writel |
@@ -41,17 +40,6 @@ | |||
41 | #endif | 40 | #endif |
42 | 41 | ||
43 | /* | 42 | /* |
44 | * Compose two values, using a bitmask as decision value | ||
45 | * This is equivalent to (a & mask) | (b & ~mask) | ||
46 | */ | ||
47 | |||
48 | static inline unsigned long | ||
49 | comp(unsigned long a, unsigned long b, unsigned long mask) | ||
50 | { | ||
51 | return ((a ^ b) & mask) ^ b; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Generic bitwise copy algorithm | 43 | * Generic bitwise copy algorithm |
56 | */ | 44 | */ |
57 | 45 | ||
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index f00b50aab606..71623b4f8ca2 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/fb.h> | 22 | #include <linux/fb.h> |
23 | #include <asm/types.h> | 23 | #include <asm/types.h> |
24 | #include "fb_draw.h" | ||
24 | 25 | ||
25 | #if BITS_PER_LONG == 32 | 26 | #if BITS_PER_LONG == 32 |
26 | # define FB_WRITEL fb_writel | 27 | # define FB_WRITEL fb_writel |
@@ -31,73 +32,6 @@ | |||
31 | #endif | 32 | #endif |
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Compose two values, using a bitmask as decision value | ||
35 | * This is equivalent to (a & mask) | (b & ~mask) | ||
36 | */ | ||
37 | |||
38 | static inline unsigned long | ||
39 | comp(unsigned long a, unsigned long b, unsigned long mask) | ||
40 | { | ||
41 | return ((a ^ b) & mask) ^ b; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * Create a pattern with the given pixel's color | ||
46 | */ | ||
47 | |||
48 | #if BITS_PER_LONG == 64 | ||
49 | static inline unsigned long | ||
50 | pixel_to_pat( u32 bpp, u32 pixel) | ||
51 | { | ||
52 | switch (bpp) { | ||
53 | case 1: | ||
54 | return 0xfffffffffffffffful*pixel; | ||
55 | case 2: | ||
56 | return 0x5555555555555555ul*pixel; | ||
57 | case 4: | ||
58 | return 0x1111111111111111ul*pixel; | ||
59 | case 8: | ||
60 | return 0x0101010101010101ul*pixel; | ||
61 | case 12: | ||
62 | return 0x0001001001001001ul*pixel; | ||
63 | case 16: | ||
64 | return 0x0001000100010001ul*pixel; | ||
65 | case 24: | ||
66 | return 0x0000000001000001ul*pixel; | ||
67 | case 32: | ||
68 | return 0x0000000100000001ul*pixel; | ||
69 | default: | ||
70 | panic("pixel_to_pat(): unsupported pixelformat\n"); | ||
71 | } | ||
72 | } | ||
73 | #else | ||
74 | static inline unsigned long | ||
75 | pixel_to_pat( u32 bpp, u32 pixel) | ||
76 | { | ||
77 | switch (bpp) { | ||
78 | case 1: | ||
79 | return 0xfffffffful*pixel; | ||
80 | case 2: | ||
81 | return 0x55555555ul*pixel; | ||
82 | case 4: | ||
83 | return 0x11111111ul*pixel; | ||
84 | case 8: | ||
85 | return 0x01010101ul*pixel; | ||
86 | case 12: | ||
87 | return 0x00001001ul*pixel; | ||
88 | case 16: | ||
89 | return 0x00010001ul*pixel; | ||
90 | case 24: | ||
91 | return 0x00000001ul*pixel; | ||
92 | case 32: | ||
93 | return 0x00000001ul*pixel; | ||
94 | default: | ||
95 | panic("pixel_to_pat(): unsupported pixelformat\n"); | ||
96 | } | ||
97 | } | ||
98 | #endif | ||
99 | |||
100 | /* | ||
101 | * Aligned pattern fill using 32/64-bit memory accesses | 35 | * Aligned pattern fill using 32/64-bit memory accesses |
102 | */ | 36 | */ |
103 | 37 | ||
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 2c4bc6205738..8269d704ab2a 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -98,15 +98,6 @@ | |||
98 | #define assert(expr) | 98 | #define assert(expr) |
99 | #endif | 99 | #endif |
100 | 100 | ||
101 | #ifdef TRUE | ||
102 | #undef TRUE | ||
103 | #endif | ||
104 | #ifdef FALSE | ||
105 | #undef FALSE | ||
106 | #endif | ||
107 | #define TRUE 1 | ||
108 | #define FALSE 0 | ||
109 | |||
110 | #define MB_ (1024*1024) | 101 | #define MB_ (1024*1024) |
111 | #define KB_ (1024) | 102 | #define KB_ (1024) |
112 | 103 | ||
@@ -146,9 +137,9 @@ static const struct cirrusfb_board_info_rec { | |||
146 | char *name; /* ASCII name of chipset */ | 137 | char *name; /* ASCII name of chipset */ |
147 | long maxclock[5]; /* maximum video clock */ | 138 | long maxclock[5]; /* maximum video clock */ |
148 | /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ | 139 | /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ |
149 | unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */ | 140 | bool init_sr07 : 1; /* init SR07 during init_vgachip() */ |
150 | unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */ | 141 | bool init_sr1f : 1; /* write SR1F during init_vgachip() */ |
151 | unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ | 142 | bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ |
152 | 143 | ||
153 | /* initial SR07 value, then for each mode */ | 144 | /* initial SR07 value, then for each mode */ |
154 | unsigned char sr07; | 145 | unsigned char sr07; |
@@ -166,9 +157,9 @@ static const struct cirrusfb_board_info_rec { | |||
166 | /* the SD64/P4 have a higher max. videoclock */ | 157 | /* the SD64/P4 have a higher max. videoclock */ |
167 | 140000, 140000, 140000, 140000, 140000, | 158 | 140000, 140000, 140000, 140000, 140000, |
168 | }, | 159 | }, |
169 | .init_sr07 = TRUE, | 160 | .init_sr07 = true, |
170 | .init_sr1f = TRUE, | 161 | .init_sr1f = true, |
171 | .scrn_start_bit19 = TRUE, | 162 | .scrn_start_bit19 = true, |
172 | .sr07 = 0xF0, | 163 | .sr07 = 0xF0, |
173 | .sr07_1bpp = 0xF0, | 164 | .sr07_1bpp = 0xF0, |
174 | .sr07_8bpp = 0xF1, | 165 | .sr07_8bpp = 0xF1, |
@@ -180,9 +171,9 @@ static const struct cirrusfb_board_info_rec { | |||
180 | /* guess */ | 171 | /* guess */ |
181 | 90000, 90000, 90000, 90000, 90000 | 172 | 90000, 90000, 90000, 90000, 90000 |
182 | }, | 173 | }, |
183 | .init_sr07 = TRUE, | 174 | .init_sr07 = true, |
184 | .init_sr1f = TRUE, | 175 | .init_sr1f = true, |
185 | .scrn_start_bit19 = FALSE, | 176 | .scrn_start_bit19 = false, |
186 | .sr07 = 0x80, | 177 | .sr07 = 0x80, |
187 | .sr07_1bpp = 0x80, | 178 | .sr07_1bpp = 0x80, |
188 | .sr07_8bpp = 0x81, | 179 | .sr07_8bpp = 0x81, |
@@ -194,9 +185,9 @@ static const struct cirrusfb_board_info_rec { | |||
194 | /* guess */ | 185 | /* guess */ |
195 | 90000, 90000, 90000, 90000, 90000 | 186 | 90000, 90000, 90000, 90000, 90000 |
196 | }, | 187 | }, |
197 | .init_sr07 = TRUE, | 188 | .init_sr07 = true, |
198 | .init_sr1f = TRUE, | 189 | .init_sr1f = true, |
199 | .scrn_start_bit19 = FALSE, | 190 | .scrn_start_bit19 = false, |
200 | .sr07 = 0x20, | 191 | .sr07 = 0x20, |
201 | .sr07_1bpp = 0x20, | 192 | .sr07_1bpp = 0x20, |
202 | .sr07_8bpp = 0x21, | 193 | .sr07_8bpp = 0x21, |
@@ -208,9 +199,9 @@ static const struct cirrusfb_board_info_rec { | |||
208 | /* guess */ | 199 | /* guess */ |
209 | 90000, 90000, 90000, 90000, 90000 | 200 | 90000, 90000, 90000, 90000, 90000 |
210 | }, | 201 | }, |
211 | .init_sr07 = TRUE, | 202 | .init_sr07 = true, |
212 | .init_sr1f = TRUE, | 203 | .init_sr1f = true, |
213 | .scrn_start_bit19 = FALSE, | 204 | .scrn_start_bit19 = false, |
214 | .sr07 = 0x80, | 205 | .sr07 = 0x80, |
215 | .sr07_1bpp = 0x80, | 206 | .sr07_1bpp = 0x80, |
216 | .sr07_8bpp = 0x81, | 207 | .sr07_8bpp = 0x81, |
@@ -221,9 +212,9 @@ static const struct cirrusfb_board_info_rec { | |||
221 | .maxclock = { | 212 | .maxclock = { |
222 | 135100, 135100, 85500, 85500, 0 | 213 | 135100, 135100, 85500, 85500, 0 |
223 | }, | 214 | }, |
224 | .init_sr07 = TRUE, | 215 | .init_sr07 = true, |
225 | .init_sr1f = FALSE, | 216 | .init_sr1f = false, |
226 | .scrn_start_bit19 = TRUE, | 217 | .scrn_start_bit19 = true, |
227 | .sr07 = 0x20, | 218 | .sr07 = 0x20, |
228 | .sr07_1bpp = 0x20, | 219 | .sr07_1bpp = 0x20, |
229 | .sr07_8bpp = 0x21, | 220 | .sr07_8bpp = 0x21, |
@@ -235,9 +226,9 @@ static const struct cirrusfb_board_info_rec { | |||
235 | /* for the GD5430. GD5446 can do more... */ | 226 | /* for the GD5430. GD5446 can do more... */ |
236 | 85500, 85500, 50000, 28500, 0 | 227 | 85500, 85500, 50000, 28500, 0 |
237 | }, | 228 | }, |
238 | .init_sr07 = TRUE, | 229 | .init_sr07 = true, |
239 | .init_sr1f = TRUE, | 230 | .init_sr1f = true, |
240 | .scrn_start_bit19 = TRUE, | 231 | .scrn_start_bit19 = true, |
241 | .sr07 = 0xA0, | 232 | .sr07 = 0xA0, |
242 | .sr07_1bpp = 0xA1, | 233 | .sr07_1bpp = 0xA1, |
243 | .sr07_1bpp_mux = 0xA7, | 234 | .sr07_1bpp_mux = 0xA7, |
@@ -250,9 +241,9 @@ static const struct cirrusfb_board_info_rec { | |||
250 | .maxclock = { | 241 | .maxclock = { |
251 | 135100, 200000, 200000, 135100, 135100 | 242 | 135100, 200000, 200000, 135100, 135100 |
252 | }, | 243 | }, |
253 | .init_sr07 = TRUE, | 244 | .init_sr07 = true, |
254 | .init_sr1f = TRUE, | 245 | .init_sr1f = true, |
255 | .scrn_start_bit19 = TRUE, | 246 | .scrn_start_bit19 = true, |
256 | .sr07 = 0x10, | 247 | .sr07 = 0x10, |
257 | .sr07_1bpp = 0x11, | 248 | .sr07_1bpp = 0x11, |
258 | .sr07_8bpp = 0x11, | 249 | .sr07_8bpp = 0x11, |
@@ -264,9 +255,9 @@ static const struct cirrusfb_board_info_rec { | |||
264 | /* guess */ | 255 | /* guess */ |
265 | 135100, 135100, 135100, 135100, 135100, | 256 | 135100, 135100, 135100, 135100, 135100, |
266 | }, | 257 | }, |
267 | .init_sr07 = FALSE, | 258 | .init_sr07 = false, |
268 | .init_sr1f = FALSE, | 259 | .init_sr1f = false, |
269 | .scrn_start_bit19 = TRUE, | 260 | .scrn_start_bit19 = true, |
270 | } | 261 | } |
271 | }; | 262 | }; |
272 | 263 | ||
@@ -815,7 +806,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, | |||
815 | 806 | ||
816 | default: | 807 | default: |
817 | DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); | 808 | DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); |
818 | assert (FALSE); | 809 | assert(false); |
819 | /* should never occur */ | 810 | /* should never occur */ |
820 | break; | 811 | break; |
821 | } | 812 | } |
@@ -886,7 +877,7 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var, | |||
886 | 877 | ||
887 | default: | 878 | default: |
888 | DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); | 879 | DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); |
889 | assert (FALSE); | 880 | assert(false); |
890 | /* should never occur */ | 881 | /* should never occur */ |
891 | break; | 882 | break; |
892 | } | 883 | } |
@@ -3203,7 +3194,7 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas | |||
3203 | break; | 3194 | break; |
3204 | default: | 3195 | default: |
3205 | /* should never occur */ | 3196 | /* should never occur */ |
3206 | assert (FALSE); | 3197 | assert(false); |
3207 | break; | 3198 | break; |
3208 | } | 3199 | } |
3209 | 3200 | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 0429fd2cece0..73813c60d03a 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -107,7 +107,9 @@ static struct display fb_display[MAX_NR_CONSOLES]; | |||
107 | 107 | ||
108 | static signed char con2fb_map[MAX_NR_CONSOLES]; | 108 | static signed char con2fb_map[MAX_NR_CONSOLES]; |
109 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; | 109 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; |
110 | #ifndef MODULE | ||
110 | static int logo_height; | 111 | static int logo_height; |
112 | #endif | ||
111 | static int logo_lines; | 113 | static int logo_lines; |
112 | /* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO | 114 | /* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO |
113 | enums. */ | 115 | enums. */ |
@@ -576,6 +578,13 @@ static int fbcon_takeover(int show_logo) | |||
576 | return err; | 578 | return err; |
577 | } | 579 | } |
578 | 580 | ||
581 | #ifdef MODULE | ||
582 | static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | ||
583 | int cols, int rows, int new_cols, int new_rows) | ||
584 | { | ||
585 | logo_shown = FBCON_LOGO_DONTSHOW; | ||
586 | } | ||
587 | #else | ||
579 | static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | 588 | static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, |
580 | int cols, int rows, int new_cols, int new_rows) | 589 | int cols, int rows, int new_cols, int new_rows) |
581 | { | 590 | { |
@@ -584,6 +593,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | |||
584 | int cnt, erase = vc->vc_video_erase_char, step; | 593 | int cnt, erase = vc->vc_video_erase_char, step; |
585 | unsigned short *save = NULL, *r, *q; | 594 | unsigned short *save = NULL, *r, *q; |
586 | 595 | ||
596 | if (info->flags & FBINFO_MODULE) { | ||
597 | logo_shown = FBCON_LOGO_DONTSHOW; | ||
598 | return; | ||
599 | } | ||
600 | |||
587 | /* | 601 | /* |
588 | * remove underline attribute from erase character | 602 | * remove underline attribute from erase character |
589 | * if black and white framebuffer. | 603 | * if black and white framebuffer. |
@@ -618,8 +632,13 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | |||
618 | r -= cols; | 632 | r -= cols; |
619 | } | 633 | } |
620 | if (!save) { | 634 | if (!save) { |
621 | vc->vc_y += logo_lines; | 635 | int lines; |
622 | vc->vc_pos += logo_lines * vc->vc_size_row; | 636 | if (vc->vc_y + logo_lines >= rows) |
637 | lines = rows - vc->vc_y - 1; | ||
638 | else | ||
639 | lines = logo_lines; | ||
640 | vc->vc_y += lines; | ||
641 | vc->vc_pos += lines * vc->vc_size_row; | ||
623 | } | 642 | } |
624 | } | 643 | } |
625 | scr_memsetw((unsigned short *) vc->vc_origin, | 644 | scr_memsetw((unsigned short *) vc->vc_origin, |
@@ -650,6 +669,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | |||
650 | vc->vc_top = logo_lines; | 669 | vc->vc_top = logo_lines; |
651 | } | 670 | } |
652 | } | 671 | } |
672 | #endif /* MODULE */ | ||
653 | 673 | ||
654 | #ifdef CONFIG_FB_TILEBLITTING | 674 | #ifdef CONFIG_FB_TILEBLITTING |
655 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) | 675 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) |
@@ -665,6 +685,17 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info) | |||
665 | fbcon_set_bitops(ops); | 685 | fbcon_set_bitops(ops); |
666 | } | 686 | } |
667 | } | 687 | } |
688 | |||
689 | static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) | ||
690 | { | ||
691 | int err = 0; | ||
692 | |||
693 | if (info->flags & FBINFO_MISC_TILEBLITTING && | ||
694 | info->tileops->fb_get_tilemax(info) < charcount) | ||
695 | err = 1; | ||
696 | |||
697 | return err; | ||
698 | } | ||
668 | #else | 699 | #else |
669 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) | 700 | static void set_blitting_type(struct vc_data *vc, struct fb_info *info) |
670 | { | 701 | { |
@@ -675,6 +706,12 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info) | |||
675 | fbcon_set_rotation(info); | 706 | fbcon_set_rotation(info); |
676 | fbcon_set_bitops(ops); | 707 | fbcon_set_bitops(ops); |
677 | } | 708 | } |
709 | |||
710 | static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) | ||
711 | { | ||
712 | return 0; | ||
713 | } | ||
714 | |||
678 | #endif /* CONFIG_MISC_TILEBLITTING */ | 715 | #endif /* CONFIG_MISC_TILEBLITTING */ |
679 | 716 | ||
680 | 717 | ||
@@ -968,7 +1005,9 @@ static const char *fbcon_startup(void) | |||
968 | if (!p->fontdata) { | 1005 | if (!p->fontdata) { |
969 | if (!fontname[0] || !(font = find_font(fontname))) | 1006 | if (!fontname[0] || !(font = find_font(fontname))) |
970 | font = get_default_font(info->var.xres, | 1007 | font = get_default_font(info->var.xres, |
971 | info->var.yres); | 1008 | info->var.yres, |
1009 | info->pixmap.blit_x, | ||
1010 | info->pixmap.blit_y); | ||
972 | vc->vc_font.width = font->width; | 1011 | vc->vc_font.width = font->width; |
973 | vc->vc_font.height = font->height; | 1012 | vc->vc_font.height = font->height; |
974 | vc->vc_font.data = (void *)(p->fontdata = font->data); | 1013 | vc->vc_font.data = (void *)(p->fontdata = font->data); |
@@ -1088,7 +1127,9 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1088 | 1127 | ||
1089 | if (!fontname[0] || !(font = find_font(fontname))) | 1128 | if (!fontname[0] || !(font = find_font(fontname))) |
1090 | font = get_default_font(info->var.xres, | 1129 | font = get_default_font(info->var.xres, |
1091 | info->var.yres); | 1130 | info->var.yres, |
1131 | info->pixmap.blit_x, | ||
1132 | info->pixmap.blit_y); | ||
1092 | vc->vc_font.width = font->width; | 1133 | vc->vc_font.width = font->width; |
1093 | vc->vc_font.height = font->height; | 1134 | vc->vc_font.height = font->height; |
1094 | vc->vc_font.data = (void *)(p->fontdata = font->data); | 1135 | vc->vc_font.data = (void *)(p->fontdata = font->data); |
@@ -1305,7 +1346,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) | |||
1305 | int y; | 1346 | int y; |
1306 | int c = scr_readw((u16 *) vc->vc_pos); | 1347 | int c = scr_readw((u16 *) vc->vc_pos); |
1307 | 1348 | ||
1308 | if (fbcon_is_inactive(vc, info)) | 1349 | if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1) |
1309 | return; | 1350 | return; |
1310 | 1351 | ||
1311 | ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; | 1352 | ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; |
@@ -2475,6 +2516,7 @@ static int fbcon_copy_font(struct vc_data *vc, int con) | |||
2475 | 2516 | ||
2476 | static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags) | 2517 | static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags) |
2477 | { | 2518 | { |
2519 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | ||
2478 | unsigned charcount = font->charcount; | 2520 | unsigned charcount = font->charcount; |
2479 | int w = font->width; | 2521 | int w = font->width; |
2480 | int h = font->height; | 2522 | int h = font->height; |
@@ -2488,6 +2530,15 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne | |||
2488 | if (charcount != 256 && charcount != 512) | 2530 | if (charcount != 256 && charcount != 512) |
2489 | return -EINVAL; | 2531 | return -EINVAL; |
2490 | 2532 | ||
2533 | /* Make sure drawing engine can handle the font */ | ||
2534 | if (!(info->pixmap.blit_x & (1 << (font->width - 1))) || | ||
2535 | !(info->pixmap.blit_y & (1 << (font->height - 1)))) | ||
2536 | return -EINVAL; | ||
2537 | |||
2538 | /* Make sure driver can handle the font length */ | ||
2539 | if (fbcon_invalid_charcount(info, charcount)) | ||
2540 | return -EINVAL; | ||
2541 | |||
2491 | size = h * pitch * charcount; | 2542 | size = h * pitch * charcount; |
2492 | 2543 | ||
2493 | new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER); | 2544 | new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER); |
@@ -2532,7 +2583,8 @@ static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, cha | |||
2532 | const struct font_desc *f; | 2583 | const struct font_desc *f; |
2533 | 2584 | ||
2534 | if (!name) | 2585 | if (!name) |
2535 | f = get_default_font(info->var.xres, info->var.yres); | 2586 | f = get_default_font(info->var.xres, info->var.yres, |
2587 | info->pixmap.blit_x, info->pixmap.blit_y); | ||
2536 | else if (!(f = find_font(name))) | 2588 | else if (!(f = find_font(name))) |
2537 | return -ENOENT; | 2589 | return -ENOENT; |
2538 | 2590 | ||
@@ -2829,7 +2881,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2829 | struct fbcon_ops *ops = info->fbcon_par; | 2881 | struct fbcon_ops *ops = info->fbcon_par; |
2830 | struct vc_data *vc; | 2882 | struct vc_data *vc; |
2831 | struct display *p; | 2883 | struct display *p; |
2832 | int i, rows, cols; | 2884 | int i, rows, cols, fg = -1; |
2833 | 2885 | ||
2834 | if (!ops || ops->currcon < 0) | 2886 | if (!ops || ops->currcon < 0) |
2835 | return; | 2887 | return; |
@@ -2840,34 +2892,23 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2840 | registered_fb[con2fb_map[i]] != info) | 2892 | registered_fb[con2fb_map[i]] != info) |
2841 | continue; | 2893 | continue; |
2842 | 2894 | ||
2895 | if (CON_IS_VISIBLE(vc)) { | ||
2896 | fg = i; | ||
2897 | continue; | ||
2898 | } | ||
2899 | |||
2843 | p = &fb_display[vc->vc_num]; | 2900 | p = &fb_display[vc->vc_num]; |
2844 | set_blitting_type(vc, info); | 2901 | set_blitting_type(vc, info); |
2845 | var_to_display(p, &info->var, info); | 2902 | var_to_display(p, &info->var, info); |
2846 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); | 2903 | cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres); |
2847 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); | 2904 | rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres); |
2848 | cols /= vc->vc_font.width; | 2905 | cols /= vc->vc_font.width; |
2849 | rows /= vc->vc_font.height; | 2906 | rows /= vc->vc_font.height; |
2850 | vc_resize(vc, cols, rows); | 2907 | vc_resize(vc, cols, rows); |
2851 | |||
2852 | if (CON_IS_VISIBLE(vc)) { | ||
2853 | updatescrollmode(p, info, vc); | ||
2854 | scrollback_max = 0; | ||
2855 | scrollback_current = 0; | ||
2856 | |||
2857 | if (!fbcon_is_inactive(vc, info)) { | ||
2858 | ops->var.xoffset = ops->var.yoffset = | ||
2859 | p->yscroll = 0; | ||
2860 | ops->update_start(info); | ||
2861 | } | ||
2862 | |||
2863 | fbcon_set_palette(vc, color_table); | ||
2864 | update_screen(vc); | ||
2865 | if (softback_buf) | ||
2866 | fbcon_update_softback(vc); | ||
2867 | } | ||
2868 | } | 2908 | } |
2869 | 2909 | ||
2870 | ops->p = &fb_display[ops->currcon]; | 2910 | if (fg != -1) |
2911 | fbcon_modechanged(info); | ||
2871 | } | 2912 | } |
2872 | 2913 | ||
2873 | static int fbcon_mode_deleted(struct fb_info *info, | 2914 | static int fbcon_mode_deleted(struct fb_info *info, |
@@ -3002,6 +3043,42 @@ static void fbcon_new_modelist(struct fb_info *info) | |||
3002 | } | 3043 | } |
3003 | } | 3044 | } |
3004 | 3045 | ||
3046 | static void fbcon_get_requirement(struct fb_info *info, | ||
3047 | struct fb_blit_caps *caps) | ||
3048 | { | ||
3049 | struct vc_data *vc; | ||
3050 | struct display *p; | ||
3051 | |||
3052 | if (caps->flags) { | ||
3053 | int i, charcnt; | ||
3054 | |||
3055 | for (i = first_fb_vc; i <= last_fb_vc; i++) { | ||
3056 | vc = vc_cons[i].d; | ||
3057 | if (vc && vc->vc_mode == KD_TEXT && | ||
3058 | info->node == con2fb_map[i]) { | ||
3059 | p = &fb_display[i]; | ||
3060 | caps->x |= 1 << (vc->vc_font.width - 1); | ||
3061 | caps->y |= 1 << (vc->vc_font.height - 1); | ||
3062 | charcnt = (p->userfont) ? | ||
3063 | FNTCHARCNT(p->fontdata) : 256; | ||
3064 | if (caps->len < charcnt) | ||
3065 | caps->len = charcnt; | ||
3066 | } | ||
3067 | } | ||
3068 | } else { | ||
3069 | vc = vc_cons[fg_console].d; | ||
3070 | |||
3071 | if (vc && vc->vc_mode == KD_TEXT && | ||
3072 | info->node == con2fb_map[fg_console]) { | ||
3073 | p = &fb_display[fg_console]; | ||
3074 | caps->x = 1 << (vc->vc_font.width - 1); | ||
3075 | caps->y = 1 << (vc->vc_font.height - 1); | ||
3076 | caps->len = (p->userfont) ? | ||
3077 | FNTCHARCNT(p->fontdata) : 256; | ||
3078 | } | ||
3079 | } | ||
3080 | } | ||
3081 | |||
3005 | static int fbcon_event_notify(struct notifier_block *self, | 3082 | static int fbcon_event_notify(struct notifier_block *self, |
3006 | unsigned long action, void *data) | 3083 | unsigned long action, void *data) |
3007 | { | 3084 | { |
@@ -3009,6 +3086,7 @@ static int fbcon_event_notify(struct notifier_block *self, | |||
3009 | struct fb_info *info = event->info; | 3086 | struct fb_info *info = event->info; |
3010 | struct fb_videomode *mode; | 3087 | struct fb_videomode *mode; |
3011 | struct fb_con2fbmap *con2fb; | 3088 | struct fb_con2fbmap *con2fb; |
3089 | struct fb_blit_caps *caps; | ||
3012 | int ret = 0; | 3090 | int ret = 0; |
3013 | 3091 | ||
3014 | /* | 3092 | /* |
@@ -3057,6 +3135,10 @@ static int fbcon_event_notify(struct notifier_block *self, | |||
3057 | case FB_EVENT_NEW_MODELIST: | 3135 | case FB_EVENT_NEW_MODELIST: |
3058 | fbcon_new_modelist(info); | 3136 | fbcon_new_modelist(info); |
3059 | break; | 3137 | break; |
3138 | case FB_EVENT_GET_REQ: | ||
3139 | caps = event->data; | ||
3140 | fbcon_get_requirement(info, caps); | ||
3141 | break; | ||
3060 | } | 3142 | } |
3061 | 3143 | ||
3062 | done: | 3144 | done: |
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index c960728b7e82..a6828d0a4c56 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c | |||
@@ -98,6 +98,8 @@ const struct font_desc *find_font(const char *name) | |||
98 | * get_default_font - get default font | 98 | * get_default_font - get default font |
99 | * @xres: screen size of X | 99 | * @xres: screen size of X |
100 | * @yres: screen size of Y | 100 | * @yres: screen size of Y |
101 | * @font_w: bit array of supported widths (1 - 32) | ||
102 | * @font_h: bit array of supported heights (1 - 32) | ||
101 | * | 103 | * |
102 | * Get the default font for a specified screen size. | 104 | * Get the default font for a specified screen size. |
103 | * Dimensions are in pixels. | 105 | * Dimensions are in pixels. |
@@ -107,7 +109,8 @@ const struct font_desc *find_font(const char *name) | |||
107 | * | 109 | * |
108 | */ | 110 | */ |
109 | 111 | ||
110 | const struct font_desc *get_default_font(int xres, int yres) | 112 | const struct font_desc *get_default_font(int xres, int yres, u32 font_w, |
113 | u32 font_h) | ||
111 | { | 114 | { |
112 | int i, c, cc; | 115 | int i, c, cc; |
113 | const struct font_desc *f, *g; | 116 | const struct font_desc *f, *g; |
@@ -129,6 +132,11 @@ const struct font_desc *get_default_font(int xres, int yres) | |||
129 | #endif | 132 | #endif |
130 | if ((yres < 400) == (f->height <= 8)) | 133 | if ((yres < 400) == (f->height <= 8)) |
131 | c += 1000; | 134 | c += 1000; |
135 | |||
136 | if (!(font_w & (1 << (f->width - 1))) || | ||
137 | !(font_w & (1 << (f->height - 1)))) | ||
138 | c += 1000; | ||
139 | |||
132 | if (c > cc) { | 140 | if (c > cc) { |
133 | cc = c; | 141 | cc = c; |
134 | g = f; | 142 | g = f; |
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 124ecbe6f88c..bd8d995fe25d 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c | |||
@@ -384,7 +384,7 @@ static inline u16 mda_convert_attr(u16 ch) | |||
384 | } | 384 | } |
385 | 385 | ||
386 | static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, | 386 | static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, |
387 | u8 blink, u8 underline, u8 reverse) | 387 | u8 blink, u8 underline, u8 reverse, u8 italic) |
388 | { | 388 | { |
389 | /* The attribute is just a bit vector: | 389 | /* The attribute is just a bit vector: |
390 | * | 390 | * |
@@ -397,6 +397,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, | |||
397 | return (intensity & 3) | | 397 | return (intensity & 3) | |
398 | ((underline & 1) << 2) | | 398 | ((underline & 1) << 2) | |
399 | ((reverse & 1) << 3) | | 399 | ((reverse & 1) << 3) | |
400 | (!!italic << 4) | | ||
400 | ((blink & 1) << 7); | 401 | ((blink & 1) << 7); |
401 | } | 402 | } |
402 | 403 | ||
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c index b78eac63459f..ae02e4eb18e7 100644 --- a/drivers/video/console/promcon.c +++ b/drivers/video/console/promcon.c | |||
@@ -548,7 +548,8 @@ promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | #if !(PROMCON_COLOR) | 550 | #if !(PROMCON_COLOR) |
551 | static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) | 551 | static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, |
552 | u8 _blink, u8 _underline, u8 _reverse, u8 _italic) | ||
552 | { | 553 | { |
553 | return (_reverse) ? 0xf : 0x7; | 554 | return (_reverse) ? 0xf : 0x7; |
554 | } | 555 | } |
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 57b21e533036..67a682d6cc7b 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c | |||
@@ -314,7 +314,7 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, | |||
314 | } | 314 | } |
315 | 315 | ||
316 | static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, | 316 | static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, |
317 | u8 blink, u8 underline, u8 reverse) | 317 | u8 blink, u8 underline, u8 reverse, u8 italic) |
318 | { | 318 | { |
319 | u8 attr = ((color & 0x70) >> 1) | ((color & 7)); | 319 | u8 attr = ((color & 0x70) >> 1) | ((color & 7)); |
320 | 320 | ||
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 88e7038eab88..717b360d0415 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c | |||
@@ -495,7 +495,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) | |||
495 | return NULL; | 495 | return NULL; |
496 | fbfont = find_font(fbfont_name); | 496 | fbfont = find_font(fbfont_name); |
497 | if (!fbfont) | 497 | if (!fbfont) |
498 | fbfont = get_default_font(1024,768); | 498 | fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0); |
499 | if (!fbfont) | 499 | if (!fbfont) |
500 | return NULL; | 500 | return NULL; |
501 | 501 | ||
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 3e67c34df9a5..2460b82a1d93 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -86,8 +86,6 @@ static int vgacon_set_origin(struct vc_data *c); | |||
86 | static void vgacon_save_screen(struct vc_data *c); | 86 | static void vgacon_save_screen(struct vc_data *c); |
87 | static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, | 87 | static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, |
88 | int lines); | 88 | int lines); |
89 | static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, | ||
90 | u8 blink, u8 underline, u8 reverse); | ||
91 | static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); | 89 | static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); |
92 | static unsigned long vgacon_uni_pagedir[2]; | 90 | static unsigned long vgacon_uni_pagedir[2]; |
93 | 91 | ||
@@ -578,12 +576,14 @@ static void vgacon_deinit(struct vc_data *c) | |||
578 | } | 576 | } |
579 | 577 | ||
580 | static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, | 578 | static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, |
581 | u8 blink, u8 underline, u8 reverse) | 579 | u8 blink, u8 underline, u8 reverse, u8 italic) |
582 | { | 580 | { |
583 | u8 attr = color; | 581 | u8 attr = color; |
584 | 582 | ||
585 | if (vga_can_do_color) { | 583 | if (vga_can_do_color) { |
586 | if (underline) | 584 | if (italic) |
585 | attr = (attr & 0xF0) | c->vc_itcolor; | ||
586 | else if (underline) | ||
587 | attr = (attr & 0xf0) | c->vc_ulcolor; | 587 | attr = (attr & 0xf0) | c->vc_ulcolor; |
588 | else if (intensity == 0) | 588 | else if (intensity == 0) |
589 | attr = (attr & 0xf0) | c->vc_halfcolor; | 589 | attr = (attr & 0xf0) | c->vc_halfcolor; |
@@ -597,7 +597,9 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, | |||
597 | if (intensity == 2) | 597 | if (intensity == 2) |
598 | attr ^= 0x08; | 598 | attr ^= 0x08; |
599 | if (!vga_can_do_color) { | 599 | if (!vga_can_do_color) { |
600 | if (underline) | 600 | if (italic) |
601 | attr = (attr & 0xF8) | 0x02; | ||
602 | else if (underline) | ||
601 | attr = (attr & 0xf8) | 0x01; | 603 | attr = (attr & 0xf8) | 0x01; |
602 | else if (intensity == 0) | 604 | else if (intensity == 0) |
603 | attr = (attr & 0xf0) | 0x08; | 605 | attr = (attr & 0xf0) | 0x08; |
@@ -658,6 +660,9 @@ static void vgacon_set_cursor_size(int xpos, int from, int to) | |||
658 | 660 | ||
659 | static void vgacon_cursor(struct vc_data *c, int mode) | 661 | static void vgacon_cursor(struct vc_data *c, int mode) |
660 | { | 662 | { |
663 | if (c->vc_mode != KD_TEXT) | ||
664 | return; | ||
665 | |||
661 | vgacon_restore_screen(c); | 666 | vgacon_restore_screen(c); |
662 | 667 | ||
663 | switch (mode) { | 668 | switch (mode) { |
@@ -1316,7 +1321,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, | |||
1316 | unsigned long oldo; | 1321 | unsigned long oldo; |
1317 | unsigned int delta; | 1322 | unsigned int delta; |
1318 | 1323 | ||
1319 | if (t || b != c->vc_rows || vga_is_gfx) | 1324 | if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT) |
1320 | return 0; | 1325 | return 0; |
1321 | 1326 | ||
1322 | if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) | 1327 | if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) |
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig new file mode 100644 index 000000000000..f99af931d4f8 --- /dev/null +++ b/drivers/video/display/Kconfig | |||
@@ -0,0 +1,24 @@ | |||
1 | # | ||
2 | # Display drivers configuration | ||
3 | # | ||
4 | |||
5 | menu "Display device support" | ||
6 | |||
7 | config DISPLAY_SUPPORT | ||
8 | tristate "Display panel/monitor support" | ||
9 | ---help--- | ||
10 | This framework adds support for low-level control of a display. | ||
11 | This includes support for power. | ||
12 | |||
13 | Enable this to be able to choose the drivers for controlling the | ||
14 | physical display panel/monitor on some platforms. This not only | ||
15 | covers LCD displays for PDAs but also other types of displays | ||
16 | such as CRT, TVout etc. | ||
17 | |||
18 | To have support for your specific display panel you will have to | ||
19 | select the proper drivers which depend on this option. | ||
20 | |||
21 | comment "Display hardware drivers" | ||
22 | depends on DISPLAY_SUPPORT | ||
23 | |||
24 | endmenu | ||
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile new file mode 100644 index 000000000000..c0ea832bf171 --- /dev/null +++ b/drivers/video/display/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # Display drivers | ||
2 | |||
3 | display-objs := display-sysfs.o | ||
4 | |||
5 | obj-$(CONFIG_DISPLAY_SUPPORT) += display.o | ||
6 | |||
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c new file mode 100644 index 000000000000..35477177bef4 --- /dev/null +++ b/drivers/video/display/display-sysfs.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | * display-sysfs.c - Display output driver sysfs interface | ||
3 | * | ||
4 | * Copyright (C) 2007 James Simmons <jsimmons@infradead.org> | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/display.h> | ||
26 | #include <linux/ctype.h> | ||
27 | #include <linux/idr.h> | ||
28 | #include <linux/err.h> | ||
29 | |||
30 | static ssize_t display_show_name(struct device *dev, | ||
31 | struct device_attribute *attr, char *buf) | ||
32 | { | ||
33 | struct display_device *dsp = dev_get_drvdata(dev); | ||
34 | return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name); | ||
35 | } | ||
36 | |||
37 | static ssize_t display_show_type(struct device *dev, | ||
38 | struct device_attribute *attr, char *buf) | ||
39 | { | ||
40 | struct display_device *dsp = dev_get_drvdata(dev); | ||
41 | return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type); | ||
42 | } | ||
43 | |||
44 | static ssize_t display_show_contrast(struct device *dev, | ||
45 | struct device_attribute *attr, char *buf) | ||
46 | { | ||
47 | struct display_device *dsp = dev_get_drvdata(dev); | ||
48 | ssize_t rc = -ENXIO; | ||
49 | |||
50 | mutex_lock(&dsp->lock); | ||
51 | if (likely(dsp->driver) && dsp->driver->get_contrast) | ||
52 | rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp)); | ||
53 | mutex_unlock(&dsp->lock); | ||
54 | return rc; | ||
55 | } | ||
56 | |||
57 | static ssize_t display_store_contrast(struct device *dev, | ||
58 | struct device_attribute *attr, | ||
59 | const char *buf, size_t count) | ||
60 | { | ||
61 | struct display_device *dsp = dev_get_drvdata(dev); | ||
62 | ssize_t ret = -EINVAL, size; | ||
63 | int contrast; | ||
64 | char *endp; | ||
65 | |||
66 | contrast = simple_strtoul(buf, &endp, 0); | ||
67 | size = endp - buf; | ||
68 | |||
69 | if (*endp && isspace(*endp)) | ||
70 | size++; | ||
71 | |||
72 | if (size != count) | ||
73 | return ret; | ||
74 | |||
75 | mutex_lock(&dsp->lock); | ||
76 | if (likely(dsp->driver && dsp->driver->set_contrast)) { | ||
77 | pr_debug("display: set contrast to %d\n", contrast); | ||
78 | dsp->driver->set_contrast(dsp, contrast); | ||
79 | ret = count; | ||
80 | } | ||
81 | mutex_unlock(&dsp->lock); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static ssize_t display_show_max_contrast(struct device *dev, | ||
86 | struct device_attribute *attr, | ||
87 | char *buf) | ||
88 | { | ||
89 | struct display_device *dsp = dev_get_drvdata(dev); | ||
90 | ssize_t rc = -ENXIO; | ||
91 | |||
92 | mutex_lock(&dsp->lock); | ||
93 | if (likely(dsp->driver)) | ||
94 | rc = sprintf(buf, "%d\n", dsp->driver->max_contrast); | ||
95 | mutex_unlock(&dsp->lock); | ||
96 | return rc; | ||
97 | } | ||
98 | |||
99 | static struct device_attribute display_attrs[] = { | ||
100 | __ATTR(name, S_IRUGO, display_show_name, NULL), | ||
101 | __ATTR(type, S_IRUGO, display_show_type, NULL), | ||
102 | __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast), | ||
103 | __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL), | ||
104 | }; | ||
105 | |||
106 | static int display_suspend(struct device *dev, pm_message_t state) | ||
107 | { | ||
108 | struct display_device *dsp = dev_get_drvdata(dev); | ||
109 | |||
110 | mutex_lock(&dsp->lock); | ||
111 | if (likely(dsp->driver->suspend)) | ||
112 | dsp->driver->suspend(dsp, state); | ||
113 | mutex_unlock(&dsp->lock); | ||
114 | return 0; | ||
115 | }; | ||
116 | |||
117 | static int display_resume(struct device *dev) | ||
118 | { | ||
119 | struct display_device *dsp = dev_get_drvdata(dev); | ||
120 | |||
121 | mutex_lock(&dsp->lock); | ||
122 | if (likely(dsp->driver->resume)) | ||
123 | dsp->driver->resume(dsp); | ||
124 | mutex_unlock(&dsp->lock); | ||
125 | return 0; | ||
126 | }; | ||
127 | |||
128 | static struct mutex allocated_dsp_lock; | ||
129 | static DEFINE_IDR(allocated_dsp); | ||
130 | static struct class *display_class; | ||
131 | |||
132 | struct display_device *display_device_register(struct display_driver *driver, | ||
133 | struct device *parent, void *devdata) | ||
134 | { | ||
135 | struct display_device *new_dev = NULL; | ||
136 | int ret = -EINVAL; | ||
137 | |||
138 | if (unlikely(!driver)) | ||
139 | return ERR_PTR(ret); | ||
140 | |||
141 | mutex_lock(&allocated_dsp_lock); | ||
142 | ret = idr_pre_get(&allocated_dsp, GFP_KERNEL); | ||
143 | mutex_unlock(&allocated_dsp_lock); | ||
144 | if (!ret) | ||
145 | return ERR_PTR(ret); | ||
146 | |||
147 | new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL); | ||
148 | if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) { | ||
149 | // Reserve the index for this display | ||
150 | mutex_lock(&allocated_dsp_lock); | ||
151 | ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx); | ||
152 | mutex_unlock(&allocated_dsp_lock); | ||
153 | |||
154 | if (!ret) { | ||
155 | new_dev->dev = device_create(display_class, parent, 0, | ||
156 | "display%d", new_dev->idx); | ||
157 | if (!IS_ERR(new_dev->dev)) { | ||
158 | dev_set_drvdata(new_dev->dev, new_dev); | ||
159 | new_dev->parent = parent; | ||
160 | new_dev->driver = driver; | ||
161 | mutex_init(&new_dev->lock); | ||
162 | return new_dev; | ||
163 | } | ||
164 | mutex_lock(&allocated_dsp_lock); | ||
165 | idr_remove(&allocated_dsp, new_dev->idx); | ||
166 | mutex_unlock(&allocated_dsp_lock); | ||
167 | ret = -EINVAL; | ||
168 | } | ||
169 | } | ||
170 | kfree(new_dev); | ||
171 | return ERR_PTR(ret); | ||
172 | } | ||
173 | EXPORT_SYMBOL(display_device_register); | ||
174 | |||
175 | void display_device_unregister(struct display_device *ddev) | ||
176 | { | ||
177 | if (!ddev) | ||
178 | return; | ||
179 | // Free device | ||
180 | mutex_lock(&ddev->lock); | ||
181 | device_unregister(ddev->dev); | ||
182 | mutex_unlock(&ddev->lock); | ||
183 | // Mark device index as avaliable | ||
184 | mutex_lock(&allocated_dsp_lock); | ||
185 | idr_remove(&allocated_dsp, ddev->idx); | ||
186 | mutex_unlock(&allocated_dsp_lock); | ||
187 | kfree(ddev); | ||
188 | } | ||
189 | EXPORT_SYMBOL(display_device_unregister); | ||
190 | |||
191 | static int __init display_class_init(void) | ||
192 | { | ||
193 | display_class = class_create(THIS_MODULE, "display"); | ||
194 | if (IS_ERR(display_class)) { | ||
195 | printk(KERN_ERR "Failed to create display class\n"); | ||
196 | display_class = NULL; | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | display_class->dev_attrs = display_attrs; | ||
200 | display_class->suspend = display_suspend; | ||
201 | display_class->resume = display_resume; | ||
202 | mutex_init(&allocated_dsp_lock); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static void __exit display_class_exit(void) | ||
207 | { | ||
208 | class_destroy(display_class); | ||
209 | } | ||
210 | |||
211 | module_init(display_class_init); | ||
212 | module_exit(display_class_exit); | ||
213 | |||
214 | MODULE_DESCRIPTION("Display Hardware handling"); | ||
215 | MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>"); | ||
216 | MODULE_LICENSE("GPL"); | ||
217 | |||
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 29e07c109887..ca2c54ce508e 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c | |||
@@ -403,17 +403,10 @@ static inline unsigned long copy_to_user16(void *to, const void *from, | |||
403 | 403 | ||
404 | 404 | ||
405 | static ssize_t | 405 | static ssize_t |
406 | epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos) | 406 | epson1355fb_read(struct fb_info *info, char *buf, size_t count, loff_t * ppos) |
407 | { | 407 | { |
408 | struct inode *inode = file->f_path.dentry->d_inode; | ||
409 | int fbidx = iminor(inode); | ||
410 | struct fb_info *info = registered_fb[fbidx]; | ||
411 | unsigned long p = *ppos; | 408 | unsigned long p = *ppos; |
412 | 409 | ||
413 | /* from fbmem.c except for our own copy_*_user */ | ||
414 | if (!info || !info->screen_base) | ||
415 | return -ENODEV; | ||
416 | |||
417 | if (p >= info->fix.smem_len) | 410 | if (p >= info->fix.smem_len) |
418 | return 0; | 411 | return 0; |
419 | if (count >= info->fix.smem_len) | 412 | if (count >= info->fix.smem_len) |
@@ -434,20 +427,13 @@ epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos) | |||
434 | } | 427 | } |
435 | 428 | ||
436 | static ssize_t | 429 | static ssize_t |
437 | epson1355fb_write(struct file *file, const char *buf, | 430 | epson1355fb_write(struct fb_info *info, const char *buf, |
438 | size_t count, loff_t * ppos) | 431 | size_t count, loff_t * ppos) |
439 | { | 432 | { |
440 | struct inode *inode = file->f_path.dentry->d_inode; | ||
441 | int fbidx = iminor(inode); | ||
442 | struct fb_info *info = registered_fb[fbidx]; | ||
443 | unsigned long p = *ppos; | 433 | unsigned long p = *ppos; |
444 | int err; | 434 | int err; |
445 | 435 | ||
446 | /* from fbmem.c except for our own copy_*_user */ | 436 | /* from fbmem.c except for our own copy_*_user */ |
447 | if (!info || !info->screen_base) | ||
448 | return -ENODEV; | ||
449 | |||
450 | /* from fbmem.c except for our own copy_*_user */ | ||
451 | if (p > info->fix.smem_len) | 437 | if (p > info->fix.smem_len) |
452 | return -ENOSPC; | 438 | return -ENOSPC; |
453 | if (count >= info->fix.smem_len) | 439 | if (count >= info->fix.smem_len) |
@@ -650,9 +636,10 @@ int __init epson1355fb_probe(struct platform_device *dev) | |||
650 | } | 636 | } |
651 | 637 | ||
652 | info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev); | 638 | info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev); |
653 | if (!info) | 639 | if (!info) { |
654 | rc = -ENOMEM; | 640 | rc = -ENOMEM; |
655 | goto bail; | 641 | goto bail; |
642 | } | ||
656 | 643 | ||
657 | default_par = info->par; | 644 | default_par = info->par; |
658 | default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN); | 645 | default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN); |
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c new file mode 100644 index 000000000000..1a8643f053d8 --- /dev/null +++ b/drivers/video/fb_defio.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/fb_defio.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Jaya Kumar | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/vmalloc.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/fb.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <asm/uaccess.h> | ||
23 | |||
24 | /* to support deferred IO */ | ||
25 | #include <linux/rmap.h> | ||
26 | #include <linux/pagemap.h> | ||
27 | |||
28 | /* this is to find and return the vmalloc-ed fb pages */ | ||
29 | static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma, | ||
30 | unsigned long vaddr, int *type) | ||
31 | { | ||
32 | unsigned long offset; | ||
33 | struct page *page; | ||
34 | struct fb_info *info = vma->vm_private_data; | ||
35 | /* info->screen_base is in System RAM */ | ||
36 | void *screen_base = (void __force *) info->screen_base; | ||
37 | |||
38 | offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | ||
39 | if (offset >= info->fix.smem_len) | ||
40 | return NOPAGE_SIGBUS; | ||
41 | |||
42 | page = vmalloc_to_page(screen_base + offset); | ||
43 | if (!page) | ||
44 | return NOPAGE_OOM; | ||
45 | |||
46 | get_page(page); | ||
47 | if (type) | ||
48 | *type = VM_FAULT_MINOR; | ||
49 | return page; | ||
50 | } | ||
51 | |||
52 | int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) | ||
53 | { | ||
54 | struct fb_info *info = file->private_data; | ||
55 | |||
56 | /* Kill off the delayed work */ | ||
57 | cancel_rearming_delayed_work(&info->deferred_work); | ||
58 | |||
59 | /* Run it immediately */ | ||
60 | return schedule_delayed_work(&info->deferred_work, 0); | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); | ||
63 | |||
64 | /* vm_ops->page_mkwrite handler */ | ||
65 | static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, | ||
66 | struct page *page) | ||
67 | { | ||
68 | struct fb_info *info = vma->vm_private_data; | ||
69 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
70 | |||
71 | /* this is a callback we get when userspace first tries to | ||
72 | write to the page. we schedule a workqueue. that workqueue | ||
73 | will eventually mkclean the touched pages and execute the | ||
74 | deferred framebuffer IO. then if userspace touches a page | ||
75 | again, we repeat the same scheme */ | ||
76 | |||
77 | /* protect against the workqueue changing the page list */ | ||
78 | mutex_lock(&fbdefio->lock); | ||
79 | list_add(&page->lru, &fbdefio->pagelist); | ||
80 | mutex_unlock(&fbdefio->lock); | ||
81 | |||
82 | /* come back after delay to process the deferred IO */ | ||
83 | schedule_delayed_work(&info->deferred_work, fbdefio->delay); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct vm_operations_struct fb_deferred_io_vm_ops = { | ||
88 | .nopage = fb_deferred_io_nopage, | ||
89 | .page_mkwrite = fb_deferred_io_mkwrite, | ||
90 | }; | ||
91 | |||
92 | static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
93 | { | ||
94 | vma->vm_ops = &fb_deferred_io_vm_ops; | ||
95 | vma->vm_flags |= ( VM_IO | VM_RESERVED | VM_DONTEXPAND ); | ||
96 | vma->vm_private_data = info; | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* workqueue callback */ | ||
101 | static void fb_deferred_io_work(struct work_struct *work) | ||
102 | { | ||
103 | struct fb_info *info = container_of(work, struct fb_info, | ||
104 | deferred_work.work); | ||
105 | struct list_head *node, *next; | ||
106 | struct page *cur; | ||
107 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
108 | |||
109 | /* here we mkclean the pages, then do all deferred IO */ | ||
110 | mutex_lock(&fbdefio->lock); | ||
111 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { | ||
112 | lock_page(cur); | ||
113 | page_mkclean(cur); | ||
114 | unlock_page(cur); | ||
115 | } | ||
116 | |||
117 | /* driver's callback with pagelist */ | ||
118 | fbdefio->deferred_io(info, &fbdefio->pagelist); | ||
119 | |||
120 | /* clear the list */ | ||
121 | list_for_each_safe(node, next, &fbdefio->pagelist) { | ||
122 | list_del(node); | ||
123 | } | ||
124 | mutex_unlock(&fbdefio->lock); | ||
125 | } | ||
126 | |||
127 | void fb_deferred_io_init(struct fb_info *info) | ||
128 | { | ||
129 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
130 | |||
131 | BUG_ON(!fbdefio); | ||
132 | mutex_init(&fbdefio->lock); | ||
133 | info->fbops->fb_mmap = fb_deferred_io_mmap; | ||
134 | INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work); | ||
135 | INIT_LIST_HEAD(&fbdefio->pagelist); | ||
136 | if (fbdefio->delay == 0) /* set a default of 1 s */ | ||
137 | fbdefio->delay = HZ; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(fb_deferred_io_init); | ||
140 | |||
141 | void fb_deferred_io_cleanup(struct fb_info *info) | ||
142 | { | ||
143 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
144 | |||
145 | BUG_ON(!fbdefio); | ||
146 | cancel_delayed_work(&info->deferred_work); | ||
147 | flush_scheduled_work(); | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); | ||
150 | |||
151 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h new file mode 100644 index 000000000000..c5c45203833b --- /dev/null +++ b/drivers/video/fb_draw.h | |||
@@ -0,0 +1,72 @@ | |||
1 | #ifndef _FB_DRAW_H | ||
2 | #define _FB_DRAW_H | ||
3 | |||
4 | #include <asm/types.h> | ||
5 | |||
6 | /* | ||
7 | * Compose two values, using a bitmask as decision value | ||
8 | * This is equivalent to (a & mask) | (b & ~mask) | ||
9 | */ | ||
10 | |||
11 | static inline unsigned long | ||
12 | comp(unsigned long a, unsigned long b, unsigned long mask) | ||
13 | { | ||
14 | return ((a ^ b) & mask) ^ b; | ||
15 | } | ||
16 | |||
17 | /* | ||
18 | * Create a pattern with the given pixel's color | ||
19 | */ | ||
20 | |||
21 | #if BITS_PER_LONG == 64 | ||
22 | static inline unsigned long | ||
23 | pixel_to_pat( u32 bpp, u32 pixel) | ||
24 | { | ||
25 | switch (bpp) { | ||
26 | case 1: | ||
27 | return 0xfffffffffffffffful*pixel; | ||
28 | case 2: | ||
29 | return 0x5555555555555555ul*pixel; | ||
30 | case 4: | ||
31 | return 0x1111111111111111ul*pixel; | ||
32 | case 8: | ||
33 | return 0x0101010101010101ul*pixel; | ||
34 | case 12: | ||
35 | return 0x0001001001001001ul*pixel; | ||
36 | case 16: | ||
37 | return 0x0001000100010001ul*pixel; | ||
38 | case 24: | ||
39 | return 0x0000000001000001ul*pixel; | ||
40 | case 32: | ||
41 | return 0x0000000100000001ul*pixel; | ||
42 | default: | ||
43 | panic("pixel_to_pat(): unsupported pixelformat\n"); | ||
44 | } | ||
45 | } | ||
46 | #else | ||
47 | static inline unsigned long | ||
48 | pixel_to_pat( u32 bpp, u32 pixel) | ||
49 | { | ||
50 | switch (bpp) { | ||
51 | case 1: | ||
52 | return 0xfffffffful*pixel; | ||
53 | case 2: | ||
54 | return 0x55555555ul*pixel; | ||
55 | case 4: | ||
56 | return 0x11111111ul*pixel; | ||
57 | case 8: | ||
58 | return 0x01010101ul*pixel; | ||
59 | case 12: | ||
60 | return 0x00001001ul*pixel; | ||
61 | case 16: | ||
62 | return 0x00010001ul*pixel; | ||
63 | case 24: | ||
64 | return 0x00000001ul*pixel; | ||
65 | case 32: | ||
66 | return 0x00000001ul*pixel; | ||
67 | default: | ||
68 | panic("pixel_to_pat(): unsupported pixelformat\n"); | ||
69 | } | ||
70 | } | ||
71 | #endif | ||
72 | #endif /* FB_DRAW_H */ | ||
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c new file mode 100644 index 000000000000..cf2538d669cd --- /dev/null +++ b/drivers/video/fb_sys_fops.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/fb_sys_read.c - Generic file operations where | ||
3 | * framebuffer is in system RAM | ||
4 | * | ||
5 | * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file COPYING in the main directory of this archive | ||
9 | * for more details. | ||
10 | * | ||
11 | */ | ||
12 | #include <linux/fb.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <asm/uaccess.h> | ||
15 | |||
16 | ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, | ||
17 | loff_t *ppos) | ||
18 | { | ||
19 | unsigned long p = *ppos; | ||
20 | void *src; | ||
21 | int err = 0; | ||
22 | unsigned long total_size; | ||
23 | |||
24 | if (info->state != FBINFO_STATE_RUNNING) | ||
25 | return -EPERM; | ||
26 | |||
27 | total_size = info->screen_size; | ||
28 | |||
29 | if (total_size == 0) | ||
30 | total_size = info->fix.smem_len; | ||
31 | |||
32 | if (p >= total_size) | ||
33 | return 0; | ||
34 | |||
35 | if (count >= total_size) | ||
36 | count = total_size; | ||
37 | |||
38 | if (count + p > total_size) | ||
39 | count = total_size - p; | ||
40 | |||
41 | src = (void __force *)(info->screen_base + p); | ||
42 | |||
43 | if (info->fbops->fb_sync) | ||
44 | info->fbops->fb_sync(info); | ||
45 | |||
46 | if (copy_to_user(buf, src, count)) | ||
47 | err = -EFAULT; | ||
48 | |||
49 | if (!err) | ||
50 | *ppos += count; | ||
51 | |||
52 | return (err) ? err : count; | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(fb_sys_read); | ||
55 | |||
56 | ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, | ||
57 | size_t count, loff_t *ppos) | ||
58 | { | ||
59 | unsigned long p = *ppos; | ||
60 | void *dst; | ||
61 | int err = 0; | ||
62 | unsigned long total_size; | ||
63 | |||
64 | if (info->state != FBINFO_STATE_RUNNING) | ||
65 | return -EPERM; | ||
66 | |||
67 | total_size = info->screen_size; | ||
68 | |||
69 | if (total_size == 0) | ||
70 | total_size = info->fix.smem_len; | ||
71 | |||
72 | if (p > total_size) | ||
73 | return -EFBIG; | ||
74 | |||
75 | if (count > total_size) { | ||
76 | err = -EFBIG; | ||
77 | count = total_size; | ||
78 | } | ||
79 | |||
80 | if (count + p > total_size) { | ||
81 | if (!err) | ||
82 | err = -ENOSPC; | ||
83 | |||
84 | count = total_size - p; | ||
85 | } | ||
86 | |||
87 | dst = (void __force *) (info->screen_base + p); | ||
88 | |||
89 | if (info->fbops->fb_sync) | ||
90 | info->fbops->fb_sync(info); | ||
91 | |||
92 | if (copy_from_user(dst, buf, count)) | ||
93 | err = -EFAULT; | ||
94 | |||
95 | if (!err) | ||
96 | *ppos += count; | ||
97 | |||
98 | return (err) ? err : count; | ||
99 | } | ||
100 | EXPORT_SYMBOL_GPL(fb_sys_write); | ||
101 | |||
102 | MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); | ||
103 | MODULE_DESCRIPTION("Generic file read (fb in system RAM)"); | ||
104 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 28225265159a..08d4e11d9121 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -354,59 +354,59 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst, | |||
354 | if (rotate == FB_ROTATE_UD) { | 354 | if (rotate == FB_ROTATE_UD) { |
355 | fb_rotate_logo_ud(image->data, dst, image->width, | 355 | fb_rotate_logo_ud(image->data, dst, image->width, |
356 | image->height); | 356 | image->height); |
357 | image->dx = info->var.xres - image->width; | 357 | image->dx = info->var.xres - image->width - image->dx; |
358 | image->dy = info->var.yres - image->height; | 358 | image->dy = info->var.yres - image->height - image->dy; |
359 | } else if (rotate == FB_ROTATE_CW) { | 359 | } else if (rotate == FB_ROTATE_CW) { |
360 | fb_rotate_logo_cw(image->data, dst, image->width, | 360 | fb_rotate_logo_cw(image->data, dst, image->width, |
361 | image->height); | 361 | image->height); |
362 | tmp = image->width; | 362 | tmp = image->width; |
363 | image->width = image->height; | 363 | image->width = image->height; |
364 | image->height = tmp; | 364 | image->height = tmp; |
365 | image->dx = info->var.xres - image->width; | 365 | tmp = image->dy; |
366 | image->dy = image->dx; | ||
367 | image->dx = info->var.xres - image->width - tmp; | ||
366 | } else if (rotate == FB_ROTATE_CCW) { | 368 | } else if (rotate == FB_ROTATE_CCW) { |
367 | fb_rotate_logo_ccw(image->data, dst, image->width, | 369 | fb_rotate_logo_ccw(image->data, dst, image->width, |
368 | image->height); | 370 | image->height); |
369 | tmp = image->width; | 371 | tmp = image->width; |
370 | image->width = image->height; | 372 | image->width = image->height; |
371 | image->height = tmp; | 373 | image->height = tmp; |
372 | image->dy = info->var.yres - image->height; | 374 | tmp = image->dx; |
375 | image->dx = image->dy; | ||
376 | image->dy = info->var.yres - image->height - tmp; | ||
373 | } | 377 | } |
374 | 378 | ||
375 | image->data = dst; | 379 | image->data = dst; |
376 | } | 380 | } |
377 | 381 | ||
378 | static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, | 382 | static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, |
379 | int rotate) | 383 | int rotate, unsigned int num) |
380 | { | 384 | { |
381 | int x; | 385 | unsigned int x; |
382 | 386 | ||
383 | if (rotate == FB_ROTATE_UR) { | 387 | if (rotate == FB_ROTATE_UR) { |
384 | for (x = 0; x < num_online_cpus() && | 388 | for (x = 0; |
385 | x * (fb_logo.logo->width + 8) <= | 389 | x < num && image->dx + image->width <= info->var.xres; |
386 | info->var.xres - fb_logo.logo->width; x++) { | 390 | x++) { |
387 | info->fbops->fb_imageblit(info, image); | 391 | info->fbops->fb_imageblit(info, image); |
388 | image->dx += fb_logo.logo->width + 8; | 392 | image->dx += image->width + 8; |
389 | } | 393 | } |
390 | } else if (rotate == FB_ROTATE_UD) { | 394 | } else if (rotate == FB_ROTATE_UD) { |
391 | for (x = 0; x < num_online_cpus() && | 395 | for (x = 0; x < num && image->dx >= 0; x++) { |
392 | x * (fb_logo.logo->width + 8) <= | ||
393 | info->var.xres - fb_logo.logo->width; x++) { | ||
394 | info->fbops->fb_imageblit(info, image); | 396 | info->fbops->fb_imageblit(info, image); |
395 | image->dx -= fb_logo.logo->width + 8; | 397 | image->dx -= image->width + 8; |
396 | } | 398 | } |
397 | } else if (rotate == FB_ROTATE_CW) { | 399 | } else if (rotate == FB_ROTATE_CW) { |
398 | for (x = 0; x < num_online_cpus() && | 400 | for (x = 0; |
399 | x * (fb_logo.logo->width + 8) <= | 401 | x < num && image->dy + image->height <= info->var.yres; |
400 | info->var.yres - fb_logo.logo->width; x++) { | 402 | x++) { |
401 | info->fbops->fb_imageblit(info, image); | 403 | info->fbops->fb_imageblit(info, image); |
402 | image->dy += fb_logo.logo->width + 8; | 404 | image->dy += image->height + 8; |
403 | } | 405 | } |
404 | } else if (rotate == FB_ROTATE_CCW) { | 406 | } else if (rotate == FB_ROTATE_CCW) { |
405 | for (x = 0; x < num_online_cpus() && | 407 | for (x = 0; x < num && image->dy >= 0; x++) { |
406 | x * (fb_logo.logo->width + 8) <= | ||
407 | info->var.yres - fb_logo.logo->width; x++) { | ||
408 | info->fbops->fb_imageblit(info, image); | 408 | info->fbops->fb_imageblit(info, image); |
409 | image->dy -= fb_logo.logo->width + 8; | 409 | image->dy -= image->height + 8; |
410 | } | 410 | } |
411 | } | 411 | } |
412 | } | 412 | } |
@@ -418,7 +418,8 @@ int fb_prepare_logo(struct fb_info *info, int rotate) | |||
418 | 418 | ||
419 | memset(&fb_logo, 0, sizeof(struct logo_data)); | 419 | memset(&fb_logo, 0, sizeof(struct logo_data)); |
420 | 420 | ||
421 | if (info->flags & FBINFO_MISC_TILEBLITTING) | 421 | if (info->flags & FBINFO_MISC_TILEBLITTING || |
422 | info->flags & FBINFO_MODULE) | ||
422 | return 0; | 423 | return 0; |
423 | 424 | ||
424 | if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | 425 | if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { |
@@ -483,7 +484,8 @@ int fb_show_logo(struct fb_info *info, int rotate) | |||
483 | struct fb_image image; | 484 | struct fb_image image; |
484 | 485 | ||
485 | /* Return if the frame buffer is not mapped or suspended */ | 486 | /* Return if the frame buffer is not mapped or suspended */ |
486 | if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) | 487 | if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING || |
488 | info->flags & FBINFO_MODULE) | ||
487 | return 0; | 489 | return 0; |
488 | 490 | ||
489 | image.depth = 8; | 491 | image.depth = 8; |
@@ -532,7 +534,7 @@ int fb_show_logo(struct fb_info *info, int rotate) | |||
532 | fb_rotate_logo(info, logo_rotate, &image, rotate); | 534 | fb_rotate_logo(info, logo_rotate, &image, rotate); |
533 | } | 535 | } |
534 | 536 | ||
535 | fb_do_show_logo(info, &image, rotate); | 537 | fb_do_show_logo(info, &image, rotate, num_online_cpus()); |
536 | 538 | ||
537 | kfree(palette); | 539 | kfree(palette); |
538 | if (saved_pseudo_palette != NULL) | 540 | if (saved_pseudo_palette != NULL) |
@@ -586,7 +588,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
586 | return -EPERM; | 588 | return -EPERM; |
587 | 589 | ||
588 | if (info->fbops->fb_read) | 590 | if (info->fbops->fb_read) |
589 | return info->fbops->fb_read(file, buf, count, ppos); | 591 | return info->fbops->fb_read(info, buf, count, ppos); |
590 | 592 | ||
591 | total_size = info->screen_size; | 593 | total_size = info->screen_size; |
592 | 594 | ||
@@ -661,7 +663,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
661 | return -EPERM; | 663 | return -EPERM; |
662 | 664 | ||
663 | if (info->fbops->fb_write) | 665 | if (info->fbops->fb_write) |
664 | return info->fbops->fb_write(file, buf, count, ppos); | 666 | return info->fbops->fb_write(info, buf, count, ppos); |
665 | 667 | ||
666 | total_size = info->screen_size; | 668 | total_size = info->screen_size; |
667 | 669 | ||
@@ -771,14 +773,37 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) | |||
771 | return 0; | 773 | return 0; |
772 | } | 774 | } |
773 | 775 | ||
776 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, | ||
777 | u32 activate) | ||
778 | { | ||
779 | struct fb_event event; | ||
780 | struct fb_blit_caps caps, fbcaps; | ||
781 | int err = 0; | ||
782 | |||
783 | memset(&caps, 0, sizeof(caps)); | ||
784 | memset(&fbcaps, 0, sizeof(fbcaps)); | ||
785 | caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0; | ||
786 | event.info = info; | ||
787 | event.data = ∩︀ | ||
788 | fb_notifier_call_chain(FB_EVENT_GET_REQ, &event); | ||
789 | info->fbops->fb_get_caps(info, &fbcaps, var); | ||
790 | |||
791 | if (((fbcaps.x ^ caps.x) & caps.x) || | ||
792 | ((fbcaps.y ^ caps.y) & caps.y) || | ||
793 | (fbcaps.len < caps.len)) | ||
794 | err = -EINVAL; | ||
795 | |||
796 | return err; | ||
797 | } | ||
798 | |||
774 | int | 799 | int |
775 | fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | 800 | fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) |
776 | { | 801 | { |
777 | int err, flags = info->flags; | 802 | int flags = info->flags; |
803 | int ret = 0; | ||
778 | 804 | ||
779 | if (var->activate & FB_ACTIVATE_INV_MODE) { | 805 | if (var->activate & FB_ACTIVATE_INV_MODE) { |
780 | struct fb_videomode mode1, mode2; | 806 | struct fb_videomode mode1, mode2; |
781 | int ret = 0; | ||
782 | 807 | ||
783 | fb_var_to_videomode(&mode1, var); | 808 | fb_var_to_videomode(&mode1, var); |
784 | fb_var_to_videomode(&mode2, &info->var); | 809 | fb_var_to_videomode(&mode2, &info->var); |
@@ -796,40 +821,51 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
796 | if (!ret) | 821 | if (!ret) |
797 | fb_delete_videomode(&mode1, &info->modelist); | 822 | fb_delete_videomode(&mode1, &info->modelist); |
798 | 823 | ||
799 | return ret; | 824 | |
825 | ret = (ret) ? -EINVAL : 0; | ||
826 | goto done; | ||
800 | } | 827 | } |
801 | 828 | ||
802 | if ((var->activate & FB_ACTIVATE_FORCE) || | 829 | if ((var->activate & FB_ACTIVATE_FORCE) || |
803 | memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { | 830 | memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { |
831 | u32 activate = var->activate; | ||
832 | |||
804 | if (!info->fbops->fb_check_var) { | 833 | if (!info->fbops->fb_check_var) { |
805 | *var = info->var; | 834 | *var = info->var; |
806 | return 0; | 835 | goto done; |
807 | } | 836 | } |
808 | 837 | ||
809 | if ((err = info->fbops->fb_check_var(var, info))) | 838 | ret = info->fbops->fb_check_var(var, info); |
810 | return err; | 839 | |
840 | if (ret) | ||
841 | goto done; | ||
811 | 842 | ||
812 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { | 843 | if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { |
813 | struct fb_videomode mode; | 844 | struct fb_videomode mode; |
814 | int err = 0; | 845 | |
846 | if (info->fbops->fb_get_caps) { | ||
847 | ret = fb_check_caps(info, var, activate); | ||
848 | |||
849 | if (ret) | ||
850 | goto done; | ||
851 | } | ||
815 | 852 | ||
816 | info->var = *var; | 853 | info->var = *var; |
854 | |||
817 | if (info->fbops->fb_set_par) | 855 | if (info->fbops->fb_set_par) |
818 | info->fbops->fb_set_par(info); | 856 | info->fbops->fb_set_par(info); |
819 | 857 | ||
820 | fb_pan_display(info, &info->var); | 858 | fb_pan_display(info, &info->var); |
821 | |||
822 | fb_set_cmap(&info->cmap, info); | 859 | fb_set_cmap(&info->cmap, info); |
823 | |||
824 | fb_var_to_videomode(&mode, &info->var); | 860 | fb_var_to_videomode(&mode, &info->var); |
825 | 861 | ||
826 | if (info->modelist.prev && info->modelist.next && | 862 | if (info->modelist.prev && info->modelist.next && |
827 | !list_empty(&info->modelist)) | 863 | !list_empty(&info->modelist)) |
828 | err = fb_add_videomode(&mode, &info->modelist); | 864 | ret = fb_add_videomode(&mode, &info->modelist); |
829 | 865 | ||
830 | if (!err && (flags & FBINFO_MISC_USEREVENT)) { | 866 | if (!ret && (flags & FBINFO_MISC_USEREVENT)) { |
831 | struct fb_event event; | 867 | struct fb_event event; |
832 | int evnt = (var->activate & FB_ACTIVATE_ALL) ? | 868 | int evnt = (activate & FB_ACTIVATE_ALL) ? |
833 | FB_EVENT_MODE_CHANGE_ALL : | 869 | FB_EVENT_MODE_CHANGE_ALL : |
834 | FB_EVENT_MODE_CHANGE; | 870 | FB_EVENT_MODE_CHANGE; |
835 | 871 | ||
@@ -839,7 +875,9 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
839 | } | 875 | } |
840 | } | 876 | } |
841 | } | 877 | } |
842 | return 0; | 878 | |
879 | done: | ||
880 | return ret; | ||
843 | } | 881 | } |
844 | 882 | ||
845 | int | 883 | int |
@@ -1266,6 +1304,9 @@ static const struct file_operations fb_fops = { | |||
1266 | #ifdef HAVE_ARCH_FB_UNMAPPED_AREA | 1304 | #ifdef HAVE_ARCH_FB_UNMAPPED_AREA |
1267 | .get_unmapped_area = get_fb_unmapped_area, | 1305 | .get_unmapped_area = get_fb_unmapped_area, |
1268 | #endif | 1306 | #endif |
1307 | #ifdef CONFIG_FB_DEFERRED_IO | ||
1308 | .fsync = fb_deferred_io_fsync, | ||
1309 | #endif | ||
1269 | }; | 1310 | }; |
1270 | 1311 | ||
1271 | struct class *fb_class; | 1312 | struct class *fb_class; |
@@ -1316,6 +1357,12 @@ register_framebuffer(struct fb_info *fb_info) | |||
1316 | } | 1357 | } |
1317 | fb_info->pixmap.offset = 0; | 1358 | fb_info->pixmap.offset = 0; |
1318 | 1359 | ||
1360 | if (!fb_info->pixmap.blit_x) | ||
1361 | fb_info->pixmap.blit_x = ~(u32)0; | ||
1362 | |||
1363 | if (!fb_info->pixmap.blit_y) | ||
1364 | fb_info->pixmap.blit_y = ~(u32)0; | ||
1365 | |||
1319 | if (!fb_info->modelist.prev || !fb_info->modelist.next) | 1366 | if (!fb_info->modelist.prev || !fb_info->modelist.next) |
1320 | INIT_LIST_HEAD(&fb_info->modelist); | 1367 | INIT_LIST_HEAD(&fb_info->modelist); |
1321 | 1368 | ||
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 6b385c39b8b5..438b9411905c 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -48,8 +48,9 @@ | |||
48 | #define DPRINTK(fmt, args...) | 48 | #define DPRINTK(fmt, args...) |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define FBMON_FIX_HEADER 1 | 51 | #define FBMON_FIX_HEADER 1 |
52 | #define FBMON_FIX_INPUT 2 | 52 | #define FBMON_FIX_INPUT 2 |
53 | #define FBMON_FIX_TIMINGS 3 | ||
53 | 54 | ||
54 | #ifdef CONFIG_FB_MODE_HELPERS | 55 | #ifdef CONFIG_FB_MODE_HELPERS |
55 | struct broken_edid { | 56 | struct broken_edid { |
@@ -71,6 +72,12 @@ static const struct broken_edid brokendb[] = { | |||
71 | .model = 0x5a44, | 72 | .model = 0x5a44, |
72 | .fix = FBMON_FIX_INPUT, | 73 | .fix = FBMON_FIX_INPUT, |
73 | }, | 74 | }, |
75 | /* Sharp UXGA? */ | ||
76 | { | ||
77 | .manufacturer = "SHP", | ||
78 | .model = 0x138e, | ||
79 | .fix = FBMON_FIX_TIMINGS, | ||
80 | }, | ||
74 | }; | 81 | }; |
75 | 82 | ||
76 | static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, | 83 | static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, |
@@ -87,6 +94,55 @@ static void copy_string(unsigned char *c, unsigned char *s) | |||
87 | while (i-- && (*--s == 0x20)) *s = 0; | 94 | while (i-- && (*--s == 0x20)) *s = 0; |
88 | } | 95 | } |
89 | 96 | ||
97 | static int edid_is_serial_block(unsigned char *block) | ||
98 | { | ||
99 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
100 | (block[2] == 0x00) && (block[3] == 0xff) && | ||
101 | (block[4] == 0x00)) | ||
102 | return 1; | ||
103 | else | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int edid_is_ascii_block(unsigned char *block) | ||
108 | { | ||
109 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
110 | (block[2] == 0x00) && (block[3] == 0xfe) && | ||
111 | (block[4] == 0x00)) | ||
112 | return 1; | ||
113 | else | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int edid_is_limits_block(unsigned char *block) | ||
118 | { | ||
119 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
120 | (block[2] == 0x00) && (block[3] == 0xfd) && | ||
121 | (block[4] == 0x00)) | ||
122 | return 1; | ||
123 | else | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int edid_is_monitor_block(unsigned char *block) | ||
128 | { | ||
129 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
130 | (block[2] == 0x00) && (block[3] == 0xfc) && | ||
131 | (block[4] == 0x00)) | ||
132 | return 1; | ||
133 | else | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int edid_is_timing_block(unsigned char *block) | ||
138 | { | ||
139 | if ((block[0] != 0x00) || (block[1] != 0x00) || | ||
140 | (block[2] != 0x00) || (block[4] != 0x00)) | ||
141 | return 1; | ||
142 | else | ||
143 | return 0; | ||
144 | } | ||
145 | |||
90 | static int check_edid(unsigned char *edid) | 146 | static int check_edid(unsigned char *edid) |
91 | { | 147 | { |
92 | unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4]; | 148 | unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4]; |
@@ -104,9 +160,6 @@ static int check_edid(unsigned char *edid) | |||
104 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { | 160 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { |
105 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && | 161 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && |
106 | brokendb[i].model == model) { | 162 | brokendb[i].model == model) { |
107 | printk("fbmon: The EDID Block of " | ||
108 | "Manufacturer: %s Model: 0x%x is known to " | ||
109 | "be broken,\n", manufacturer, model); | ||
110 | fix = brokendb[i].fix; | 163 | fix = brokendb[i].fix; |
111 | break; | 164 | break; |
112 | } | 165 | } |
@@ -115,8 +168,10 @@ static int check_edid(unsigned char *edid) | |||
115 | switch (fix) { | 168 | switch (fix) { |
116 | case FBMON_FIX_HEADER: | 169 | case FBMON_FIX_HEADER: |
117 | for (i = 0; i < 8; i++) { | 170 | for (i = 0; i < 8; i++) { |
118 | if (edid[i] != edid_v1_header[i]) | 171 | if (edid[i] != edid_v1_header[i]) { |
119 | ret = fix; | 172 | ret = fix; |
173 | break; | ||
174 | } | ||
120 | } | 175 | } |
121 | break; | 176 | break; |
122 | case FBMON_FIX_INPUT: | 177 | case FBMON_FIX_INPUT: |
@@ -126,14 +181,34 @@ static int check_edid(unsigned char *edid) | |||
126 | if (b[4] & 0x01 && b[0] & 0x80) | 181 | if (b[4] & 0x01 && b[0] & 0x80) |
127 | ret = fix; | 182 | ret = fix; |
128 | break; | 183 | break; |
184 | case FBMON_FIX_TIMINGS: | ||
185 | b = edid + DETAILED_TIMING_DESCRIPTIONS_START; | ||
186 | ret = fix; | ||
187 | |||
188 | for (i = 0; i < 4; i++) { | ||
189 | if (edid_is_limits_block(b)) { | ||
190 | ret = 0; | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | b += DETAILED_TIMING_DESCRIPTION_SIZE; | ||
195 | } | ||
196 | |||
197 | break; | ||
129 | } | 198 | } |
130 | 199 | ||
200 | if (ret) | ||
201 | printk("fbmon: The EDID Block of " | ||
202 | "Manufacturer: %s Model: 0x%x is known to " | ||
203 | "be broken,\n", manufacturer, model); | ||
204 | |||
131 | return ret; | 205 | return ret; |
132 | } | 206 | } |
133 | 207 | ||
134 | static void fix_edid(unsigned char *edid, int fix) | 208 | static void fix_edid(unsigned char *edid, int fix) |
135 | { | 209 | { |
136 | unsigned char *b; | 210 | int i; |
211 | unsigned char *b, csum = 0; | ||
137 | 212 | ||
138 | switch (fix) { | 213 | switch (fix) { |
139 | case FBMON_FIX_HEADER: | 214 | case FBMON_FIX_HEADER: |
@@ -145,6 +220,37 @@ static void fix_edid(unsigned char *edid, int fix) | |||
145 | b = edid + EDID_STRUCT_DISPLAY; | 220 | b = edid + EDID_STRUCT_DISPLAY; |
146 | b[0] &= ~0x80; | 221 | b[0] &= ~0x80; |
147 | edid[127] += 0x80; | 222 | edid[127] += 0x80; |
223 | break; | ||
224 | case FBMON_FIX_TIMINGS: | ||
225 | printk("fbmon: trying to fix monitor timings\n"); | ||
226 | b = edid + DETAILED_TIMING_DESCRIPTIONS_START; | ||
227 | for (i = 0; i < 4; i++) { | ||
228 | if (!(edid_is_serial_block(b) || | ||
229 | edid_is_ascii_block(b) || | ||
230 | edid_is_monitor_block(b) || | ||
231 | edid_is_timing_block(b))) { | ||
232 | b[0] = 0x00; | ||
233 | b[1] = 0x00; | ||
234 | b[2] = 0x00; | ||
235 | b[3] = 0xfd; | ||
236 | b[4] = 0x00; | ||
237 | b[5] = 60; /* vfmin */ | ||
238 | b[6] = 60; /* vfmax */ | ||
239 | b[7] = 30; /* hfmin */ | ||
240 | b[8] = 75; /* hfmax */ | ||
241 | b[9] = 17; /* pixclock - 170 MHz*/ | ||
242 | b[10] = 0; /* GTF */ | ||
243 | break; | ||
244 | } | ||
245 | |||
246 | b += DETAILED_TIMING_DESCRIPTION_SIZE; | ||
247 | } | ||
248 | |||
249 | for (i = 0; i < EDID_LENGTH - 1; i++) | ||
250 | csum += edid[i]; | ||
251 | |||
252 | edid[127] = 256 - csum; | ||
253 | break; | ||
148 | } | 254 | } |
149 | } | 255 | } |
150 | 256 | ||
@@ -273,46 +379,6 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs) | |||
273 | DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey); | 379 | DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey); |
274 | } | 380 | } |
275 | 381 | ||
276 | static int edid_is_serial_block(unsigned char *block) | ||
277 | { | ||
278 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
279 | (block[2] == 0x00) && (block[3] == 0xff) && | ||
280 | (block[4] == 0x00)) | ||
281 | return 1; | ||
282 | else | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int edid_is_ascii_block(unsigned char *block) | ||
287 | { | ||
288 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
289 | (block[2] == 0x00) && (block[3] == 0xfe) && | ||
290 | (block[4] == 0x00)) | ||
291 | return 1; | ||
292 | else | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int edid_is_limits_block(unsigned char *block) | ||
297 | { | ||
298 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
299 | (block[2] == 0x00) && (block[3] == 0xfd) && | ||
300 | (block[4] == 0x00)) | ||
301 | return 1; | ||
302 | else | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int edid_is_monitor_block(unsigned char *block) | ||
307 | { | ||
308 | if ((block[0] == 0x00) && (block[1] == 0x00) && | ||
309 | (block[2] == 0x00) && (block[3] == 0xfc) && | ||
310 | (block[4] == 0x00)) | ||
311 | return 1; | ||
312 | else | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static void calc_mode_timings(int xres, int yres, int refresh, | 382 | static void calc_mode_timings(int xres, int yres, int refresh, |
317 | struct fb_videomode *mode) | 383 | struct fb_videomode *mode) |
318 | { | 384 | { |
@@ -795,15 +861,6 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
795 | } | 861 | } |
796 | } | 862 | } |
797 | 863 | ||
798 | static int edid_is_timing_block(unsigned char *block) | ||
799 | { | ||
800 | if ((block[0] != 0x00) || (block[1] != 0x00) || | ||
801 | (block[2] != 0x00) || (block[4] != 0x00)) | ||
802 | return 1; | ||
803 | else | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) | 864 | int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) |
808 | { | 865 | { |
809 | int i; | 866 | int i; |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 40c80c8190e2..d4a2c11d9809 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -376,7 +376,7 @@ static ssize_t show_pan(struct device *device, | |||
376 | { | 376 | { |
377 | struct fb_info *fb_info = dev_get_drvdata(device); | 377 | struct fb_info *fb_info = dev_get_drvdata(device); |
378 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, | 378 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, |
379 | fb_info->var.xoffset); | 379 | fb_info->var.yoffset); |
380 | } | 380 | } |
381 | 381 | ||
382 | static ssize_t show_name(struct device *device, | 382 | static ssize_t show_name(struct device *device, |
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c new file mode 100644 index 000000000000..abfcb50364c8 --- /dev/null +++ b/drivers/video/hecubafb.c | |||
@@ -0,0 +1,471 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller | ||
3 | * | ||
4 | * Copyright (C) 2006, Jaya Kumar | ||
5 | * This work was sponsored by CIS(M) Sdn Bhd | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file COPYING in the main directory of this archive for | ||
9 | * more details. | ||
10 | * | ||
11 | * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. | ||
12 | * This work was possible because of apollo display code from E-Ink's website | ||
13 | * http://support.eink.com/community | ||
14 | * All information used to write this code is from public material made | ||
15 | * available by E-Ink on its support site. Some commands such as 0xA4 | ||
16 | * were found by looping through cmd=0x00 thru 0xFF and supplying random | ||
17 | * values. There are other commands that the display is capable of, | ||
18 | * beyond the 5 used here but they are more complex. | ||
19 | * | ||
20 | * This driver is written to be used with the Hecuba display controller | ||
21 | * board, and tested with the EInk 800x600 display in 1 bit mode. | ||
22 | * The interface between Hecuba and the host is TTL based GPIO. The | ||
23 | * GPIO requirements are 8 writable data lines and 6 lines for control. | ||
24 | * Only 4 of the controls are actually used here but 6 for future use. | ||
25 | * The driver requires the IO addresses for data and control GPIO at | ||
26 | * load time. It is also possible to use this display with a standard | ||
27 | * PC parallel port. | ||
28 | * | ||
29 | * General notes: | ||
30 | * - User must set hecubafb_enable=1 to enable it | ||
31 | * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | #include <linux/module.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <linux/string.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/vmalloc.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | #include <linux/fb.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/platform_device.h> | ||
47 | #include <linux/list.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | |||
50 | /* Apollo controller specific defines */ | ||
51 | #define APOLLO_START_NEW_IMG 0xA0 | ||
52 | #define APOLLO_STOP_IMG_DATA 0xA1 | ||
53 | #define APOLLO_DISPLAY_IMG 0xA2 | ||
54 | #define APOLLO_ERASE_DISPLAY 0xA3 | ||
55 | #define APOLLO_INIT_DISPLAY 0xA4 | ||
56 | |||
57 | /* Hecuba interface specific defines */ | ||
58 | /* WUP is inverted, CD is inverted, DS is inverted */ | ||
59 | #define HCB_NWUP_BIT 0x01 | ||
60 | #define HCB_NDS_BIT 0x02 | ||
61 | #define HCB_RW_BIT 0x04 | ||
62 | #define HCB_NCD_BIT 0x08 | ||
63 | #define HCB_ACK_BIT 0x80 | ||
64 | |||
65 | /* Display specific information */ | ||
66 | #define DPY_W 600 | ||
67 | #define DPY_H 800 | ||
68 | |||
69 | struct hecubafb_par { | ||
70 | unsigned long dio_addr; | ||
71 | unsigned long cio_addr; | ||
72 | unsigned long c2io_addr; | ||
73 | unsigned char ctl; | ||
74 | struct fb_info *info; | ||
75 | unsigned int irq; | ||
76 | }; | ||
77 | |||
78 | static struct fb_fix_screeninfo hecubafb_fix __devinitdata = { | ||
79 | .id = "hecubafb", | ||
80 | .type = FB_TYPE_PACKED_PIXELS, | ||
81 | .visual = FB_VISUAL_MONO01, | ||
82 | .xpanstep = 0, | ||
83 | .ypanstep = 0, | ||
84 | .ywrapstep = 0, | ||
85 | .accel = FB_ACCEL_NONE, | ||
86 | }; | ||
87 | |||
88 | static struct fb_var_screeninfo hecubafb_var __devinitdata = { | ||
89 | .xres = DPY_W, | ||
90 | .yres = DPY_H, | ||
91 | .xres_virtual = DPY_W, | ||
92 | .yres_virtual = DPY_H, | ||
93 | .bits_per_pixel = 1, | ||
94 | .nonstd = 1, | ||
95 | }; | ||
96 | |||
97 | static unsigned long dio_addr; | ||
98 | static unsigned long cio_addr; | ||
99 | static unsigned long c2io_addr; | ||
100 | static unsigned long splashval; | ||
101 | static unsigned int nosplash; | ||
102 | static unsigned int hecubafb_enable; | ||
103 | static unsigned int irq; | ||
104 | |||
105 | static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq); | ||
106 | |||
107 | static void hcb_set_ctl(struct hecubafb_par *par) | ||
108 | { | ||
109 | outb(par->ctl, par->cio_addr); | ||
110 | } | ||
111 | |||
112 | static unsigned char hcb_get_ctl(struct hecubafb_par *par) | ||
113 | { | ||
114 | return inb(par->c2io_addr); | ||
115 | } | ||
116 | |||
117 | static void hcb_set_data(struct hecubafb_par *par, unsigned char value) | ||
118 | { | ||
119 | outb(value, par->dio_addr); | ||
120 | } | ||
121 | |||
122 | static int __devinit apollo_init_control(struct hecubafb_par *par) | ||
123 | { | ||
124 | unsigned char ctl; | ||
125 | /* for init, we want the following setup to be set: | ||
126 | WUP = lo | ||
127 | ACK = hi | ||
128 | DS = hi | ||
129 | RW = hi | ||
130 | CD = lo | ||
131 | */ | ||
132 | |||
133 | /* write WUP to lo, DS to hi, RW to hi, CD to lo */ | ||
134 | par->ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ; | ||
135 | par->ctl &= ~HCB_NDS_BIT; | ||
136 | hcb_set_ctl(par); | ||
137 | |||
138 | /* check ACK is not lo */ | ||
139 | ctl = hcb_get_ctl(par); | ||
140 | if ((ctl & HCB_ACK_BIT)) { | ||
141 | printk(KERN_ERR "Fail because ACK is already low\n"); | ||
142 | return -ENXIO; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void hcb_wait_for_ack(struct hecubafb_par *par) | ||
149 | { | ||
150 | |||
151 | int timeout; | ||
152 | unsigned char ctl; | ||
153 | |||
154 | timeout=500; | ||
155 | do { | ||
156 | ctl = hcb_get_ctl(par); | ||
157 | if ((ctl & HCB_ACK_BIT)) | ||
158 | return; | ||
159 | udelay(1); | ||
160 | } while (timeout--); | ||
161 | printk(KERN_ERR "timed out waiting for ack\n"); | ||
162 | } | ||
163 | |||
164 | static void hcb_wait_for_ack_clear(struct hecubafb_par *par) | ||
165 | { | ||
166 | |||
167 | int timeout; | ||
168 | unsigned char ctl; | ||
169 | |||
170 | timeout=500; | ||
171 | do { | ||
172 | ctl = hcb_get_ctl(par); | ||
173 | if (!(ctl & HCB_ACK_BIT)) | ||
174 | return; | ||
175 | udelay(1); | ||
176 | } while (timeout--); | ||
177 | printk(KERN_ERR "timed out waiting for clear\n"); | ||
178 | } | ||
179 | |||
180 | static void apollo_send_data(struct hecubafb_par *par, unsigned char data) | ||
181 | { | ||
182 | /* set data */ | ||
183 | hcb_set_data(par, data); | ||
184 | |||
185 | /* set DS low */ | ||
186 | par->ctl |= HCB_NDS_BIT; | ||
187 | hcb_set_ctl(par); | ||
188 | |||
189 | hcb_wait_for_ack(par); | ||
190 | |||
191 | /* set DS hi */ | ||
192 | par->ctl &= ~(HCB_NDS_BIT); | ||
193 | hcb_set_ctl(par); | ||
194 | |||
195 | hcb_wait_for_ack_clear(par); | ||
196 | } | ||
197 | |||
198 | static void apollo_send_command(struct hecubafb_par *par, unsigned char data) | ||
199 | { | ||
200 | /* command so set CD to high */ | ||
201 | par->ctl &= ~(HCB_NCD_BIT); | ||
202 | hcb_set_ctl(par); | ||
203 | |||
204 | /* actually strobe with command */ | ||
205 | apollo_send_data(par, data); | ||
206 | |||
207 | /* clear CD back to low */ | ||
208 | par->ctl |= (HCB_NCD_BIT); | ||
209 | hcb_set_ctl(par); | ||
210 | } | ||
211 | |||
212 | /* main hecubafb functions */ | ||
213 | |||
214 | static void hecubafb_dpy_update(struct hecubafb_par *par) | ||
215 | { | ||
216 | int i; | ||
217 | unsigned char *buf = (unsigned char __force *)par->info->screen_base; | ||
218 | |||
219 | apollo_send_command(par, 0xA0); | ||
220 | |||
221 | for (i=0; i < (DPY_W*DPY_H/8); i++) { | ||
222 | apollo_send_data(par, *(buf++)); | ||
223 | } | ||
224 | |||
225 | apollo_send_command(par, 0xA1); | ||
226 | apollo_send_command(par, 0xA2); | ||
227 | } | ||
228 | |||
229 | /* this is called back from the deferred io workqueue */ | ||
230 | static void hecubafb_dpy_deferred_io(struct fb_info *info, | ||
231 | struct list_head *pagelist) | ||
232 | { | ||
233 | hecubafb_dpy_update(info->par); | ||
234 | } | ||
235 | |||
236 | static void hecubafb_fillrect(struct fb_info *info, | ||
237 | const struct fb_fillrect *rect) | ||
238 | { | ||
239 | struct hecubafb_par *par = info->par; | ||
240 | |||
241 | sys_fillrect(info, rect); | ||
242 | |||
243 | hecubafb_dpy_update(par); | ||
244 | } | ||
245 | |||
246 | static void hecubafb_copyarea(struct fb_info *info, | ||
247 | const struct fb_copyarea *area) | ||
248 | { | ||
249 | struct hecubafb_par *par = info->par; | ||
250 | |||
251 | sys_copyarea(info, area); | ||
252 | |||
253 | hecubafb_dpy_update(par); | ||
254 | } | ||
255 | |||
256 | static void hecubafb_imageblit(struct fb_info *info, | ||
257 | const struct fb_image *image) | ||
258 | { | ||
259 | struct hecubafb_par *par = info->par; | ||
260 | |||
261 | sys_imageblit(info, image); | ||
262 | |||
263 | hecubafb_dpy_update(par); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * this is the slow path from userspace. they can seek and write to | ||
268 | * the fb. it's inefficient to do anything less than a full screen draw | ||
269 | */ | ||
270 | static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf, | ||
271 | size_t count, loff_t *ppos) | ||
272 | { | ||
273 | unsigned long p; | ||
274 | int err=-EINVAL; | ||
275 | struct hecubafb_par *par; | ||
276 | unsigned int xres; | ||
277 | unsigned int fbmemlength; | ||
278 | |||
279 | p = *ppos; | ||
280 | par = info->par; | ||
281 | xres = info->var.xres; | ||
282 | fbmemlength = (xres * info->var.yres)/8; | ||
283 | |||
284 | if (p > fbmemlength) | ||
285 | return -ENOSPC; | ||
286 | |||
287 | err = 0; | ||
288 | if ((count + p) > fbmemlength) { | ||
289 | count = fbmemlength - p; | ||
290 | err = -ENOSPC; | ||
291 | } | ||
292 | |||
293 | if (count) { | ||
294 | char *base_addr; | ||
295 | |||
296 | base_addr = (char __force *)info->screen_base; | ||
297 | count -= copy_from_user(base_addr + p, buf, count); | ||
298 | *ppos += count; | ||
299 | err = -EFAULT; | ||
300 | } | ||
301 | |||
302 | hecubafb_dpy_update(par); | ||
303 | |||
304 | if (count) | ||
305 | return count; | ||
306 | |||
307 | return err; | ||
308 | } | ||
309 | |||
310 | static struct fb_ops hecubafb_ops = { | ||
311 | .owner = THIS_MODULE, | ||
312 | .fb_read = fb_sys_read, | ||
313 | .fb_write = hecubafb_write, | ||
314 | .fb_fillrect = hecubafb_fillrect, | ||
315 | .fb_copyarea = hecubafb_copyarea, | ||
316 | .fb_imageblit = hecubafb_imageblit, | ||
317 | }; | ||
318 | |||
319 | static struct fb_deferred_io hecubafb_defio = { | ||
320 | .delay = HZ, | ||
321 | .deferred_io = hecubafb_dpy_deferred_io, | ||
322 | }; | ||
323 | |||
324 | static int __devinit hecubafb_probe(struct platform_device *dev) | ||
325 | { | ||
326 | struct fb_info *info; | ||
327 | int retval = -ENOMEM; | ||
328 | int videomemorysize; | ||
329 | unsigned char *videomemory; | ||
330 | struct hecubafb_par *par; | ||
331 | |||
332 | videomemorysize = (DPY_W*DPY_H)/8; | ||
333 | |||
334 | if (!(videomemory = vmalloc(videomemorysize))) | ||
335 | return retval; | ||
336 | |||
337 | memset(videomemory, 0, videomemorysize); | ||
338 | |||
339 | info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev); | ||
340 | if (!info) | ||
341 | goto err; | ||
342 | |||
343 | info->screen_base = (char __iomem *) videomemory; | ||
344 | info->fbops = &hecubafb_ops; | ||
345 | |||
346 | info->var = hecubafb_var; | ||
347 | info->fix = hecubafb_fix; | ||
348 | info->fix.smem_len = videomemorysize; | ||
349 | par = info->par; | ||
350 | par->info = info; | ||
351 | |||
352 | if (!dio_addr || !cio_addr || !c2io_addr) { | ||
353 | printk(KERN_WARNING "no IO addresses supplied\n"); | ||
354 | goto err1; | ||
355 | } | ||
356 | par->dio_addr = dio_addr; | ||
357 | par->cio_addr = cio_addr; | ||
358 | par->c2io_addr = c2io_addr; | ||
359 | info->flags = FBINFO_FLAG_DEFAULT; | ||
360 | |||
361 | info->fbdefio = &hecubafb_defio; | ||
362 | fb_deferred_io_init(info); | ||
363 | |||
364 | retval = register_framebuffer(info); | ||
365 | if (retval < 0) | ||
366 | goto err1; | ||
367 | platform_set_drvdata(dev, info); | ||
368 | |||
369 | printk(KERN_INFO | ||
370 | "fb%d: Hecuba frame buffer device, using %dK of video memory\n", | ||
371 | info->node, videomemorysize >> 10); | ||
372 | |||
373 | /* this inits the dpy */ | ||
374 | apollo_init_control(par); | ||
375 | |||
376 | apollo_send_command(par, APOLLO_INIT_DISPLAY); | ||
377 | apollo_send_data(par, 0x81); | ||
378 | |||
379 | /* have to wait while display resets */ | ||
380 | udelay(1000); | ||
381 | |||
382 | /* if we were told to splash the screen, we just clear it */ | ||
383 | if (!nosplash) { | ||
384 | apollo_send_command(par, APOLLO_ERASE_DISPLAY); | ||
385 | apollo_send_data(par, splashval); | ||
386 | } | ||
387 | |||
388 | return 0; | ||
389 | err1: | ||
390 | framebuffer_release(info); | ||
391 | err: | ||
392 | vfree(videomemory); | ||
393 | return retval; | ||
394 | } | ||
395 | |||
396 | static int __devexit hecubafb_remove(struct platform_device *dev) | ||
397 | { | ||
398 | struct fb_info *info = platform_get_drvdata(dev); | ||
399 | |||
400 | if (info) { | ||
401 | fb_deferred_io_cleanup(info); | ||
402 | unregister_framebuffer(info); | ||
403 | vfree((void __force *)info->screen_base); | ||
404 | framebuffer_release(info); | ||
405 | } | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static struct platform_driver hecubafb_driver = { | ||
410 | .probe = hecubafb_probe, | ||
411 | .remove = hecubafb_remove, | ||
412 | .driver = { | ||
413 | .name = "hecubafb", | ||
414 | }, | ||
415 | }; | ||
416 | |||
417 | static struct platform_device *hecubafb_device; | ||
418 | |||
419 | static int __init hecubafb_init(void) | ||
420 | { | ||
421 | int ret; | ||
422 | |||
423 | if (!hecubafb_enable) { | ||
424 | printk(KERN_ERR "Use hecubafb_enable to enable the device\n"); | ||
425 | return -ENXIO; | ||
426 | } | ||
427 | |||
428 | ret = platform_driver_register(&hecubafb_driver); | ||
429 | if (!ret) { | ||
430 | hecubafb_device = platform_device_alloc("hecubafb", 0); | ||
431 | if (hecubafb_device) | ||
432 | ret = platform_device_add(hecubafb_device); | ||
433 | else | ||
434 | ret = -ENOMEM; | ||
435 | |||
436 | if (ret) { | ||
437 | platform_device_put(hecubafb_device); | ||
438 | platform_driver_unregister(&hecubafb_driver); | ||
439 | } | ||
440 | } | ||
441 | return ret; | ||
442 | |||
443 | } | ||
444 | |||
445 | static void __exit hecubafb_exit(void) | ||
446 | { | ||
447 | platform_device_unregister(hecubafb_device); | ||
448 | platform_driver_unregister(&hecubafb_driver); | ||
449 | } | ||
450 | |||
451 | module_param(nosplash, uint, 0); | ||
452 | MODULE_PARM_DESC(nosplash, "Disable doing the splash screen"); | ||
453 | module_param(hecubafb_enable, uint, 0); | ||
454 | MODULE_PARM_DESC(hecubafb_enable, "Enable communication with Hecuba board"); | ||
455 | module_param(dio_addr, ulong, 0); | ||
456 | MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480"); | ||
457 | module_param(cio_addr, ulong, 0); | ||
458 | MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400"); | ||
459 | module_param(c2io_addr, ulong, 0); | ||
460 | MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408"); | ||
461 | module_param(splashval, ulong, 0); | ||
462 | MODULE_PARM_DESC(splashval, "Splash pattern: 0x00 is black, 0x01 is white"); | ||
463 | module_param(irq, uint, 0); | ||
464 | MODULE_PARM_DESC(irq, "IRQ for the Hecuba board"); | ||
465 | |||
466 | module_init(hecubafb_init); | ||
467 | module_exit(hecubafb_exit); | ||
468 | |||
469 | MODULE_DESCRIPTION("fbdev driver for Hecuba board"); | ||
470 | MODULE_AUTHOR("Jaya Kumar"); | ||
471 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h index aa65ffce915b..889e4ea5edc1 100644 --- a/drivers/video/i810/i810.h +++ b/drivers/video/i810/i810.h | |||
@@ -133,7 +133,7 @@ | |||
133 | /* Masks (AND ops) and OR's */ | 133 | /* Masks (AND ops) and OR's */ |
134 | #define FB_START_MASK (0x3f << (32 - 6)) | 134 | #define FB_START_MASK (0x3f << (32 - 6)) |
135 | #define MMIO_ADDR_MASK (0x1FFF << (32 - 13)) | 135 | #define MMIO_ADDR_MASK (0x1FFF << (32 - 13)) |
136 | #define FREQ_MASK 0x1EF | 136 | #define FREQ_MASK (1 << 4) |
137 | #define SCR_OFF 0x20 | 137 | #define SCR_OFF 0x20 |
138 | #define DRAM_ON 0x08 | 138 | #define DRAM_ON 0x08 |
139 | #define DRAM_OFF 0xE7 | 139 | #define DRAM_OFF 0xE7 |
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index c1eb18bf0883..16bc8d75e36e 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo); | |||
1428 | static void reset_state(struct intelfb_info *dinfo); | 1428 | static void reset_state(struct intelfb_info *dinfo); |
1429 | static void do_flush(struct intelfb_info *dinfo); | 1429 | static void do_flush(struct intelfb_info *dinfo); |
1430 | 1430 | ||
1431 | static u32 get_ring_space(struct intelfb_info *dinfo) | ||
1432 | { | ||
1433 | u32 ring_space; | ||
1434 | |||
1435 | if (dinfo->ring_tail >= dinfo->ring_head) | ||
1436 | ring_space = dinfo->ring.size - | ||
1437 | (dinfo->ring_tail - dinfo->ring_head); | ||
1438 | else | ||
1439 | ring_space = dinfo->ring_head - dinfo->ring_tail; | ||
1440 | |||
1441 | if (ring_space > RING_MIN_FREE) | ||
1442 | ring_space -= RING_MIN_FREE; | ||
1443 | else | ||
1444 | ring_space = 0; | ||
1445 | |||
1446 | return ring_space; | ||
1447 | } | ||
1448 | |||
1431 | static int | 1449 | static int |
1432 | wait_ring(struct intelfb_info *dinfo, int n) | 1450 | wait_ring(struct intelfb_info *dinfo, int n) |
1433 | { | 1451 | { |
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n) | |||
1442 | end = jiffies + (HZ * 3); | 1460 | end = jiffies + (HZ * 3); |
1443 | while (dinfo->ring_space < n) { | 1461 | while (dinfo->ring_space < n) { |
1444 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; | 1462 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; |
1445 | if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) | 1463 | dinfo->ring_space = get_ring_space(dinfo); |
1446 | dinfo->ring_space = dinfo->ring_head | 1464 | |
1447 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1448 | else | ||
1449 | dinfo->ring_space = (dinfo->ring.size + | ||
1450 | dinfo->ring_head) | ||
1451 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1452 | if (dinfo->ring_head != last_head) { | 1465 | if (dinfo->ring_head != last_head) { |
1453 | end = jiffies + (HZ * 3); | 1466 | end = jiffies + (HZ * 3); |
1454 | last_head = dinfo->ring_head; | 1467 | last_head = dinfo->ring_head; |
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo) | |||
1513 | 1526 | ||
1514 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; | 1527 | dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; |
1515 | dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; | 1528 | dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; |
1516 | if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) | 1529 | dinfo->ring_space = get_ring_space(dinfo); |
1517 | dinfo->ring_space = dinfo->ring_head | ||
1518 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1519 | else | ||
1520 | dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head) | ||
1521 | - (dinfo->ring_tail + RING_MIN_FREE); | ||
1522 | } | 1530 | } |
1523 | 1531 | ||
1524 | static void | 1532 | static void |
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index f0e6512c87ff..9397bcef3018 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig | |||
@@ -2,73 +2,69 @@ | |||
2 | # Logo configuration | 2 | # Logo configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "Logo configuration" | 5 | menuconfig LOGO |
6 | |||
7 | config LOGO | ||
8 | bool "Bootup logo" | 6 | bool "Bootup logo" |
9 | depends on FB || SGI_NEWPORT_CONSOLE | 7 | depends on FB || SGI_NEWPORT_CONSOLE |
10 | help | 8 | help |
11 | Enable and select frame buffer bootup logos. | 9 | Enable and select frame buffer bootup logos. |
12 | 10 | ||
11 | if LOGO | ||
12 | |||
13 | config LOGO_LINUX_MONO | 13 | config LOGO_LINUX_MONO |
14 | bool "Standard black and white Linux logo" | 14 | bool "Standard black and white Linux logo" |
15 | depends on LOGO | ||
16 | default y | 15 | default y |
17 | 16 | ||
18 | config LOGO_LINUX_VGA16 | 17 | config LOGO_LINUX_VGA16 |
19 | bool "Standard 16-color Linux logo" | 18 | bool "Standard 16-color Linux logo" |
20 | depends on LOGO | ||
21 | default y | 19 | default y |
22 | 20 | ||
23 | config LOGO_LINUX_CLUT224 | 21 | config LOGO_LINUX_CLUT224 |
24 | bool "Standard 224-color Linux logo" | 22 | bool "Standard 224-color Linux logo" |
25 | depends on LOGO | ||
26 | default y | 23 | default y |
27 | 24 | ||
28 | config LOGO_DEC_CLUT224 | 25 | config LOGO_DEC_CLUT224 |
29 | bool "224-color Digital Equipment Corporation Linux logo" | 26 | bool "224-color Digital Equipment Corporation Linux logo" |
30 | depends on LOGO && (MACH_DECSTATION || ALPHA) | 27 | depends on MACH_DECSTATION || ALPHA |
31 | default y | 28 | default y |
32 | 29 | ||
33 | config LOGO_MAC_CLUT224 | 30 | config LOGO_MAC_CLUT224 |
34 | bool "224-color Macintosh Linux logo" | 31 | bool "224-color Macintosh Linux logo" |
35 | depends on LOGO && MAC | 32 | depends on MAC |
36 | default y | 33 | default y |
37 | 34 | ||
38 | config LOGO_PARISC_CLUT224 | 35 | config LOGO_PARISC_CLUT224 |
39 | bool "224-color PA-RISC Linux logo" | 36 | bool "224-color PA-RISC Linux logo" |
40 | depends on LOGO && PARISC | 37 | depends on PARISC |
41 | default y | 38 | default y |
42 | 39 | ||
43 | config LOGO_SGI_CLUT224 | 40 | config LOGO_SGI_CLUT224 |
44 | bool "224-color SGI Linux logo" | 41 | bool "224-color SGI Linux logo" |
45 | depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS) | 42 | depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS |
46 | default y | 43 | default y |
47 | 44 | ||
48 | config LOGO_SUN_CLUT224 | 45 | config LOGO_SUN_CLUT224 |
49 | bool "224-color Sun Linux logo" | 46 | bool "224-color Sun Linux logo" |
50 | depends on LOGO && SPARC | 47 | depends on SPARC |
51 | default y | 48 | default y |
52 | 49 | ||
53 | config LOGO_SUPERH_MONO | 50 | config LOGO_SUPERH_MONO |
54 | bool "Black and white SuperH Linux logo" | 51 | bool "Black and white SuperH Linux logo" |
55 | depends on LOGO && SUPERH | 52 | depends on SUPERH |
56 | default y | 53 | default y |
57 | 54 | ||
58 | config LOGO_SUPERH_VGA16 | 55 | config LOGO_SUPERH_VGA16 |
59 | bool "16-color SuperH Linux logo" | 56 | bool "16-color SuperH Linux logo" |
60 | depends on LOGO && SUPERH | 57 | depends on SUPERH |
61 | default y | 58 | default y |
62 | 59 | ||
63 | config LOGO_SUPERH_CLUT224 | 60 | config LOGO_SUPERH_CLUT224 |
64 | bool "224-color SuperH Linux logo" | 61 | bool "224-color SuperH Linux logo" |
65 | depends on LOGO && SUPERH | 62 | depends on SUPERH |
66 | default y | 63 | default y |
67 | 64 | ||
68 | config LOGO_M32R_CLUT224 | 65 | config LOGO_M32R_CLUT224 |
69 | bool "224-color M32R Linux logo" | 66 | bool "224-color M32R Linux logo" |
70 | depends on LOGO && M32R | 67 | depends on M32R |
71 | default y | 68 | default y |
72 | 69 | ||
73 | endmenu | 70 | endif # LOGO |
74 | |||
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 3e517940c5a5..3741ad729401 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -395,7 +395,7 @@ static int my_atoi(const char *name) | |||
395 | 395 | ||
396 | for (;; name++) { | 396 | for (;; name++) { |
397 | switch (*name) { | 397 | switch (*name) { |
398 | case '0'...'9': | 398 | case '0' ... '9': |
399 | val = 10*val+(*name-'0'); | 399 | val = 10*val+(*name-'0'); |
400 | break; | 400 | break; |
401 | default: | 401 | default: |
@@ -548,7 +548,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
548 | } else | 548 | } else |
549 | goto done; | 549 | goto done; |
550 | break; | 550 | break; |
551 | case '0'...'9': | 551 | case '0' ... '9': |
552 | break; | 552 | break; |
553 | case 'M': | 553 | case 'M': |
554 | if (!yres_specified) | 554 | if (!yres_specified) |
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 395ccedde9a6..bd30aba242d0 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -665,6 +665,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
665 | var->red.msb_right = 0; | 665 | var->red.msb_right = 0; |
666 | var->green.msb_right = 0; | 666 | var->green.msb_right = 0; |
667 | var->blue.msb_right = 0; | 667 | var->blue.msb_right = 0; |
668 | var->transp.msb_right = 0; | ||
668 | 669 | ||
669 | switch (var->bits_per_pixel) { | 670 | switch (var->bits_per_pixel) { |
670 | case 8: /* PSEUDOCOLOUR, 256 */ | 671 | case 8: /* PSEUDOCOLOUR, 256 */ |
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c index 9efb8a3854e2..fa4821c5572b 100644 --- a/drivers/video/nvidia/nv_accel.c +++ b/drivers/video/nvidia/nv_accel.c | |||
@@ -69,27 +69,38 @@ static const int NVCopyROP_PM[16] = { | |||
69 | 0x5A, /* invert */ | 69 | 0x5A, /* invert */ |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static inline void NVFlush(struct nvidia_par *par) | 72 | static inline void nvidiafb_safe_mode(struct fb_info *info) |
73 | { | 73 | { |
74 | struct nvidia_par *par = info->par; | ||
75 | |||
76 | touch_softlockup_watchdog(); | ||
77 | info->pixmap.scan_align = 1; | ||
78 | par->lockup = 1; | ||
79 | } | ||
80 | |||
81 | static inline void NVFlush(struct fb_info *info) | ||
82 | { | ||
83 | struct nvidia_par *par = info->par; | ||
74 | int count = 1000000000; | 84 | int count = 1000000000; |
75 | 85 | ||
76 | while (--count && READ_GET(par) != par->dmaPut) ; | 86 | while (--count && READ_GET(par) != par->dmaPut) ; |
77 | 87 | ||
78 | if (!count) { | 88 | if (!count) { |
79 | printk("nvidiafb: DMA Flush lockup\n"); | 89 | printk("nvidiafb: DMA Flush lockup\n"); |
80 | par->lockup = 1; | 90 | nvidiafb_safe_mode(info); |
81 | } | 91 | } |
82 | } | 92 | } |
83 | 93 | ||
84 | static inline void NVSync(struct nvidia_par *par) | 94 | static inline void NVSync(struct fb_info *info) |
85 | { | 95 | { |
96 | struct nvidia_par *par = info->par; | ||
86 | int count = 1000000000; | 97 | int count = 1000000000; |
87 | 98 | ||
88 | while (--count && NV_RD32(par->PGRAPH, 0x0700)) ; | 99 | while (--count && NV_RD32(par->PGRAPH, 0x0700)) ; |
89 | 100 | ||
90 | if (!count) { | 101 | if (!count) { |
91 | printk("nvidiafb: DMA Sync lockup\n"); | 102 | printk("nvidiafb: DMA Sync lockup\n"); |
92 | par->lockup = 1; | 103 | nvidiafb_safe_mode(info); |
93 | } | 104 | } |
94 | } | 105 | } |
95 | 106 | ||
@@ -101,8 +112,9 @@ static void NVDmaKickoff(struct nvidia_par *par) | |||
101 | } | 112 | } |
102 | } | 113 | } |
103 | 114 | ||
104 | static void NVDmaWait(struct nvidia_par *par, int size) | 115 | static void NVDmaWait(struct fb_info *info, int size) |
105 | { | 116 | { |
117 | struct nvidia_par *par = info->par; | ||
106 | int dmaGet; | 118 | int dmaGet; |
107 | int count = 1000000000, cnt; | 119 | int count = 1000000000, cnt; |
108 | size++; | 120 | size++; |
@@ -135,34 +147,38 @@ static void NVDmaWait(struct nvidia_par *par, int size) | |||
135 | } | 147 | } |
136 | 148 | ||
137 | if (!count) { | 149 | if (!count) { |
138 | printk("DMA Wait Lockup\n"); | 150 | printk("nvidiafb: DMA Wait Lockup\n"); |
139 | par->lockup = 1; | 151 | nvidiafb_safe_mode(info); |
140 | } | 152 | } |
141 | } | 153 | } |
142 | 154 | ||
143 | static void NVSetPattern(struct nvidia_par *par, u32 clr0, u32 clr1, | 155 | static void NVSetPattern(struct fb_info *info, u32 clr0, u32 clr1, |
144 | u32 pat0, u32 pat1) | 156 | u32 pat0, u32 pat1) |
145 | { | 157 | { |
146 | NVDmaStart(par, PATTERN_COLOR_0, 4); | 158 | struct nvidia_par *par = info->par; |
159 | |||
160 | NVDmaStart(info, par, PATTERN_COLOR_0, 4); | ||
147 | NVDmaNext(par, clr0); | 161 | NVDmaNext(par, clr0); |
148 | NVDmaNext(par, clr1); | 162 | NVDmaNext(par, clr1); |
149 | NVDmaNext(par, pat0); | 163 | NVDmaNext(par, pat0); |
150 | NVDmaNext(par, pat1); | 164 | NVDmaNext(par, pat1); |
151 | } | 165 | } |
152 | 166 | ||
153 | static void NVSetRopSolid(struct nvidia_par *par, u32 rop, u32 planemask) | 167 | static void NVSetRopSolid(struct fb_info *info, u32 rop, u32 planemask) |
154 | { | 168 | { |
169 | struct nvidia_par *par = info->par; | ||
170 | |||
155 | if (planemask != ~0) { | 171 | if (planemask != ~0) { |
156 | NVSetPattern(par, 0, planemask, ~0, ~0); | 172 | NVSetPattern(info, 0, planemask, ~0, ~0); |
157 | if (par->currentRop != (rop + 32)) { | 173 | if (par->currentRop != (rop + 32)) { |
158 | NVDmaStart(par, ROP_SET, 1); | 174 | NVDmaStart(info, par, ROP_SET, 1); |
159 | NVDmaNext(par, NVCopyROP_PM[rop]); | 175 | NVDmaNext(par, NVCopyROP_PM[rop]); |
160 | par->currentRop = rop + 32; | 176 | par->currentRop = rop + 32; |
161 | } | 177 | } |
162 | } else if (par->currentRop != rop) { | 178 | } else if (par->currentRop != rop) { |
163 | if (par->currentRop >= 16) | 179 | if (par->currentRop >= 16) |
164 | NVSetPattern(par, ~0, ~0, ~0, ~0); | 180 | NVSetPattern(info, ~0, ~0, ~0, ~0); |
165 | NVDmaStart(par, ROP_SET, 1); | 181 | NVDmaStart(info, par, ROP_SET, 1); |
166 | NVDmaNext(par, NVCopyROP[rop]); | 182 | NVDmaNext(par, NVCopyROP[rop]); |
167 | par->currentRop = rop; | 183 | par->currentRop = rop; |
168 | } | 184 | } |
@@ -175,7 +191,7 @@ static void NVSetClippingRectangle(struct fb_info *info, int x1, int y1, | |||
175 | int h = y2 - y1 + 1; | 191 | int h = y2 - y1 + 1; |
176 | int w = x2 - x1 + 1; | 192 | int w = x2 - x1 + 1; |
177 | 193 | ||
178 | NVDmaStart(par, CLIP_POINT, 2); | 194 | NVDmaStart(info, par, CLIP_POINT, 2); |
179 | NVDmaNext(par, (y1 << 16) | x1); | 195 | NVDmaNext(par, (y1 << 16) | x1); |
180 | NVDmaNext(par, (h << 16) | w); | 196 | NVDmaNext(par, (h << 16) | w); |
181 | } | 197 | } |
@@ -237,23 +253,23 @@ void NVResetGraphics(struct fb_info *info) | |||
237 | break; | 253 | break; |
238 | } | 254 | } |
239 | 255 | ||
240 | NVDmaStart(par, SURFACE_FORMAT, 4); | 256 | NVDmaStart(info, par, SURFACE_FORMAT, 4); |
241 | NVDmaNext(par, surfaceFormat); | 257 | NVDmaNext(par, surfaceFormat); |
242 | NVDmaNext(par, pitch | (pitch << 16)); | 258 | NVDmaNext(par, pitch | (pitch << 16)); |
243 | NVDmaNext(par, 0); | 259 | NVDmaNext(par, 0); |
244 | NVDmaNext(par, 0); | 260 | NVDmaNext(par, 0); |
245 | 261 | ||
246 | NVDmaStart(par, PATTERN_FORMAT, 1); | 262 | NVDmaStart(info, par, PATTERN_FORMAT, 1); |
247 | NVDmaNext(par, patternFormat); | 263 | NVDmaNext(par, patternFormat); |
248 | 264 | ||
249 | NVDmaStart(par, RECT_FORMAT, 1); | 265 | NVDmaStart(info, par, RECT_FORMAT, 1); |
250 | NVDmaNext(par, rectFormat); | 266 | NVDmaNext(par, rectFormat); |
251 | 267 | ||
252 | NVDmaStart(par, LINE_FORMAT, 1); | 268 | NVDmaStart(info, par, LINE_FORMAT, 1); |
253 | NVDmaNext(par, lineFormat); | 269 | NVDmaNext(par, lineFormat); |
254 | 270 | ||
255 | par->currentRop = ~0; /* set to something invalid */ | 271 | par->currentRop = ~0; /* set to something invalid */ |
256 | NVSetRopSolid(par, ROP_COPY, ~0); | 272 | NVSetRopSolid(info, ROP_COPY, ~0); |
257 | 273 | ||
258 | NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual, | 274 | NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual, |
259 | info->var.yres_virtual); | 275 | info->var.yres_virtual); |
@@ -269,10 +285,10 @@ int nvidiafb_sync(struct fb_info *info) | |||
269 | return 0; | 285 | return 0; |
270 | 286 | ||
271 | if (!par->lockup) | 287 | if (!par->lockup) |
272 | NVFlush(par); | 288 | NVFlush(info); |
273 | 289 | ||
274 | if (!par->lockup) | 290 | if (!par->lockup) |
275 | NVSync(par); | 291 | NVSync(info); |
276 | 292 | ||
277 | return 0; | 293 | return 0; |
278 | } | 294 | } |
@@ -287,7 +303,7 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
287 | if (par->lockup) | 303 | if (par->lockup) |
288 | return cfb_copyarea(info, region); | 304 | return cfb_copyarea(info, region); |
289 | 305 | ||
290 | NVDmaStart(par, BLIT_POINT_SRC, 3); | 306 | NVDmaStart(info, par, BLIT_POINT_SRC, 3); |
291 | NVDmaNext(par, (region->sy << 16) | region->sx); | 307 | NVDmaNext(par, (region->sy << 16) | region->sx); |
292 | NVDmaNext(par, (region->dy << 16) | region->dx); | 308 | NVDmaNext(par, (region->dy << 16) | region->dx); |
293 | NVDmaNext(par, (region->height << 16) | region->width); | 309 | NVDmaNext(par, (region->height << 16) | region->width); |
@@ -312,19 +328,19 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
312 | color = ((u32 *) info->pseudo_palette)[rect->color]; | 328 | color = ((u32 *) info->pseudo_palette)[rect->color]; |
313 | 329 | ||
314 | if (rect->rop != ROP_COPY) | 330 | if (rect->rop != ROP_COPY) |
315 | NVSetRopSolid(par, rect->rop, ~0); | 331 | NVSetRopSolid(info, rect->rop, ~0); |
316 | 332 | ||
317 | NVDmaStart(par, RECT_SOLID_COLOR, 1); | 333 | NVDmaStart(info, par, RECT_SOLID_COLOR, 1); |
318 | NVDmaNext(par, color); | 334 | NVDmaNext(par, color); |
319 | 335 | ||
320 | NVDmaStart(par, RECT_SOLID_RECTS(0), 2); | 336 | NVDmaStart(info, par, RECT_SOLID_RECTS(0), 2); |
321 | NVDmaNext(par, (rect->dx << 16) | rect->dy); | 337 | NVDmaNext(par, (rect->dx << 16) | rect->dy); |
322 | NVDmaNext(par, (rect->width << 16) | rect->height); | 338 | NVDmaNext(par, (rect->width << 16) | rect->height); |
323 | 339 | ||
324 | NVDmaKickoff(par); | 340 | NVDmaKickoff(par); |
325 | 341 | ||
326 | if (rect->rop != ROP_COPY) | 342 | if (rect->rop != ROP_COPY) |
327 | NVSetRopSolid(par, ROP_COPY, ~0); | 343 | NVSetRopSolid(info, ROP_COPY, ~0); |
328 | } | 344 | } |
329 | 345 | ||
330 | static void nvidiafb_mono_color_expand(struct fb_info *info, | 346 | static void nvidiafb_mono_color_expand(struct fb_info *info, |
@@ -346,7 +362,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info, | |||
346 | bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask; | 362 | bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask; |
347 | } | 363 | } |
348 | 364 | ||
349 | NVDmaStart(par, RECT_EXPAND_TWO_COLOR_CLIP, 7); | 365 | NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_CLIP, 7); |
350 | NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); | 366 | NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); |
351 | NVDmaNext(par, ((image->dy + image->height) << 16) | | 367 | NVDmaNext(par, ((image->dy + image->height) << 16) | |
352 | ((image->dx + image->width) & 0xffff)); | 368 | ((image->dx + image->width) & 0xffff)); |
@@ -357,7 +373,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info, | |||
357 | NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); | 373 | NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); |
358 | 374 | ||
359 | while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) { | 375 | while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) { |
360 | NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), | 376 | NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0), |
361 | RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS); | 377 | RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS); |
362 | 378 | ||
363 | for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) { | 379 | for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) { |
@@ -370,7 +386,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info, | |||
370 | } | 386 | } |
371 | 387 | ||
372 | if (dsize) { | 388 | if (dsize) { |
373 | NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize); | 389 | NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize); |
374 | 390 | ||
375 | for (j = dsize; j--;) { | 391 | for (j = dsize; j--;) { |
376 | tmp = data[k++]; | 392 | tmp = data[k++]; |
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index ea426115c6f9..f297c7b14a41 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c | |||
@@ -686,7 +686,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk, | |||
686 | 686 | ||
687 | if ((par->Chipset & 0x0FF0) == 0x01A0) { | 687 | if ((par->Chipset & 0x0FF0) == 0x01A0) { |
688 | unsigned int uMClkPostDiv; | 688 | unsigned int uMClkPostDiv; |
689 | dev = pci_find_slot(0, 3); | 689 | dev = pci_get_bus_and_slot(0, 3); |
690 | pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); | 690 | pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); |
691 | uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; | 691 | uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; |
692 | 692 | ||
@@ -694,11 +694,11 @@ static void nForceUpdateArbitrationSettings(unsigned VClk, | |||
694 | uMClkPostDiv = 4; | 694 | uMClkPostDiv = 4; |
695 | MClk = 400000 / uMClkPostDiv; | 695 | MClk = 400000 / uMClkPostDiv; |
696 | } else { | 696 | } else { |
697 | dev = pci_find_slot(0, 5); | 697 | dev = pci_get_bus_and_slot(0, 5); |
698 | pci_read_config_dword(dev, 0x4c, &MClk); | 698 | pci_read_config_dword(dev, 0x4c, &MClk); |
699 | MClk /= 1000; | 699 | MClk /= 1000; |
700 | } | 700 | } |
701 | 701 | pci_dev_put(dev); | |
702 | pll = NV_RD32(par->PRAMDAC0, 0x0500); | 702 | pll = NV_RD32(par->PRAMDAC0, 0x0500); |
703 | M = (pll >> 0) & 0xFF; | 703 | M = (pll >> 0) & 0xFF; |
704 | N = (pll >> 8) & 0xFF; | 704 | N = (pll >> 8) & 0xFF; |
@@ -707,19 +707,21 @@ static void nForceUpdateArbitrationSettings(unsigned VClk, | |||
707 | sim_data.pix_bpp = (char)pixelDepth; | 707 | sim_data.pix_bpp = (char)pixelDepth; |
708 | sim_data.enable_video = 0; | 708 | sim_data.enable_video = 0; |
709 | sim_data.enable_mp = 0; | 709 | sim_data.enable_mp = 0; |
710 | pci_find_slot(0, 1); | 710 | dev = pci_get_bus_and_slot(0, 1); |
711 | pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); | 711 | pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); |
712 | pci_dev_put(dev); | ||
712 | sim_data.memory_type = (sim_data.memory_type >> 12) & 1; | 713 | sim_data.memory_type = (sim_data.memory_type >> 12) & 1; |
713 | sim_data.memory_width = 64; | 714 | sim_data.memory_width = 64; |
714 | 715 | ||
715 | dev = pci_find_slot(0, 3); | 716 | dev = pci_get_bus_and_slot(0, 3); |
716 | pci_read_config_dword(dev, 0, &memctrl); | 717 | pci_read_config_dword(dev, 0, &memctrl); |
718 | pci_dev_put(dev); | ||
717 | memctrl >>= 16; | 719 | memctrl >>= 16; |
718 | 720 | ||
719 | if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) { | 721 | if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) { |
720 | int dimm[3]; | 722 | int dimm[3]; |
721 | 723 | ||
722 | pci_find_slot(0, 2); | 724 | dev = pci_get_bus_and_slot(0, 2); |
723 | pci_read_config_dword(dev, 0x40, &dimm[0]); | 725 | pci_read_config_dword(dev, 0x40, &dimm[0]); |
724 | dimm[0] = (dimm[0] >> 8) & 0x4f; | 726 | dimm[0] = (dimm[0] >> 8) & 0x4f; |
725 | pci_read_config_dword(dev, 0x44, &dimm[1]); | 727 | pci_read_config_dword(dev, 0x44, &dimm[1]); |
@@ -731,6 +733,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk, | |||
731 | printk("nvidiafb: your nForce DIMMs are not arranged " | 733 | printk("nvidiafb: your nForce DIMMs are not arranged " |
732 | "in optimal banks!\n"); | 734 | "in optimal banks!\n"); |
733 | } | 735 | } |
736 | pci_dev_put(dev); | ||
734 | } | 737 | } |
735 | 738 | ||
736 | sim_data.mem_latency = 3; | 739 | sim_data.mem_latency = 3; |
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index b8588973e400..afe4567e1ff4 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c | |||
@@ -30,16 +30,14 @@ static void nvidia_gpio_setscl(void *data, int state) | |||
30 | struct nvidia_par *par = chan->par; | 30 | struct nvidia_par *par = chan->par; |
31 | u32 val; | 31 | u32 val; |
32 | 32 | ||
33 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); | 33 | val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0; |
34 | val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0; | ||
35 | 34 | ||
36 | if (state) | 35 | if (state) |
37 | val |= 0x20; | 36 | val |= 0x20; |
38 | else | 37 | else |
39 | val &= ~0x20; | 38 | val &= ~0x20; |
40 | 39 | ||
41 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); | 40 | NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01); |
42 | VGA_WR08(par->PCIO, 0x3d5, val | 0x1); | ||
43 | } | 41 | } |
44 | 42 | ||
45 | static void nvidia_gpio_setsda(void *data, int state) | 43 | static void nvidia_gpio_setsda(void *data, int state) |
@@ -48,16 +46,14 @@ static void nvidia_gpio_setsda(void *data, int state) | |||
48 | struct nvidia_par *par = chan->par; | 46 | struct nvidia_par *par = chan->par; |
49 | u32 val; | 47 | u32 val; |
50 | 48 | ||
51 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); | 49 | val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0; |
52 | val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0; | ||
53 | 50 | ||
54 | if (state) | 51 | if (state) |
55 | val |= 0x10; | 52 | val |= 0x10; |
56 | else | 53 | else |
57 | val &= ~0x10; | 54 | val &= ~0x10; |
58 | 55 | ||
59 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); | 56 | NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01); |
60 | VGA_WR08(par->PCIO, 0x3d5, val | 0x1); | ||
61 | } | 57 | } |
62 | 58 | ||
63 | static int nvidia_gpio_getscl(void *data) | 59 | static int nvidia_gpio_getscl(void *data) |
@@ -66,12 +62,9 @@ static int nvidia_gpio_getscl(void *data) | |||
66 | struct nvidia_par *par = chan->par; | 62 | struct nvidia_par *par = chan->par; |
67 | u32 val = 0; | 63 | u32 val = 0; |
68 | 64 | ||
69 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); | 65 | if (NVReadCrtc(par, chan->ddc_base) & 0x04) |
70 | if (VGA_RD08(par->PCIO, 0x3d5) & 0x04) | ||
71 | val = 1; | 66 | val = 1; |
72 | 67 | ||
73 | val = VGA_RD08(par->PCIO, 0x3d5); | ||
74 | |||
75 | return val; | 68 | return val; |
76 | } | 69 | } |
77 | 70 | ||
@@ -81,20 +74,21 @@ static int nvidia_gpio_getsda(void *data) | |||
81 | struct nvidia_par *par = chan->par; | 74 | struct nvidia_par *par = chan->par; |
82 | u32 val = 0; | 75 | u32 val = 0; |
83 | 76 | ||
84 | VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); | 77 | if (NVReadCrtc(par, chan->ddc_base) & 0x08) |
85 | if (VGA_RD08(par->PCIO, 0x3d5) & 0x08) | ||
86 | val = 1; | 78 | val = 1; |
87 | 79 | ||
88 | return val; | 80 | return val; |
89 | } | 81 | } |
90 | 82 | ||
91 | static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name) | 83 | static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name, |
84 | unsigned int i2c_class) | ||
92 | { | 85 | { |
93 | int rc; | 86 | int rc; |
94 | 87 | ||
95 | strcpy(chan->adapter.name, name); | 88 | strcpy(chan->adapter.name, name); |
96 | chan->adapter.owner = THIS_MODULE; | 89 | chan->adapter.owner = THIS_MODULE; |
97 | chan->adapter.id = I2C_HW_B_NVIDIA; | 90 | chan->adapter.id = I2C_HW_B_NVIDIA; |
91 | chan->adapter.class = i2c_class; | ||
98 | chan->adapter.algo_data = &chan->algo; | 92 | chan->adapter.algo_data = &chan->algo; |
99 | chan->adapter.dev.parent = &chan->par->pci_dev->dev; | 93 | chan->adapter.dev.parent = &chan->par->pci_dev->dev; |
100 | chan->algo.setsda = nvidia_gpio_setsda; | 94 | chan->algo.setsda = nvidia_gpio_setsda; |
@@ -127,83 +121,39 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name) | |||
127 | 121 | ||
128 | void nvidia_create_i2c_busses(struct nvidia_par *par) | 122 | void nvidia_create_i2c_busses(struct nvidia_par *par) |
129 | { | 123 | { |
130 | par->bus = 3; | ||
131 | |||
132 | par->chan[0].par = par; | 124 | par->chan[0].par = par; |
133 | par->chan[1].par = par; | 125 | par->chan[1].par = par; |
134 | par->chan[2].par = par; | 126 | par->chan[2].par = par; |
135 | 127 | ||
136 | par->chan[0].ddc_base = 0x3e; | 128 | par->chan[0].ddc_base = 0x36; |
137 | nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0"); | 129 | nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON); |
138 | 130 | ||
139 | par->chan[1].ddc_base = 0x36; | 131 | par->chan[1].ddc_base = 0x3e; |
140 | nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1"); | 132 | nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0); |
141 | 133 | ||
142 | par->chan[2].ddc_base = 0x50; | 134 | par->chan[2].ddc_base = 0x50; |
143 | nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2"); | 135 | nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0); |
144 | } | 136 | } |
145 | 137 | ||
146 | void nvidia_delete_i2c_busses(struct nvidia_par *par) | 138 | void nvidia_delete_i2c_busses(struct nvidia_par *par) |
147 | { | 139 | { |
148 | if (par->chan[0].par) | 140 | int i; |
149 | i2c_del_adapter(&par->chan[0].adapter); | ||
150 | par->chan[0].par = NULL; | ||
151 | |||
152 | if (par->chan[1].par) | ||
153 | i2c_del_adapter(&par->chan[1].adapter); | ||
154 | par->chan[1].par = NULL; | ||
155 | |||
156 | if (par->chan[2].par) | ||
157 | i2c_del_adapter(&par->chan[2].adapter); | ||
158 | par->chan[2].par = NULL; | ||
159 | |||
160 | } | ||
161 | 141 | ||
162 | static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) | 142 | for (i = 0; i < 3; i++) { |
163 | { | 143 | if (!par->chan[i].par) |
164 | u8 start = 0x0; | 144 | continue; |
165 | struct i2c_msg msgs[] = { | 145 | i2c_del_adapter(&par->chan[i].adapter); |
166 | { | 146 | par->chan[i].par = NULL; |
167 | .addr = 0x50, | ||
168 | .len = 1, | ||
169 | .buf = &start, | ||
170 | }, { | ||
171 | .addr = 0x50, | ||
172 | .flags = I2C_M_RD, | ||
173 | .len = EDID_LENGTH, | ||
174 | }, | ||
175 | }; | ||
176 | u8 *buf; | ||
177 | |||
178 | if (!chan->par) | ||
179 | return NULL; | ||
180 | |||
181 | buf = kmalloc(EDID_LENGTH, GFP_KERNEL); | ||
182 | if (!buf) { | ||
183 | dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n"); | ||
184 | return NULL; | ||
185 | } | 147 | } |
186 | msgs[1].buf = buf; | ||
187 | |||
188 | if (i2c_transfer(&chan->adapter, msgs, 2) == 2) | ||
189 | return buf; | ||
190 | dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n"); | ||
191 | kfree(buf); | ||
192 | return NULL; | ||
193 | } | 148 | } |
194 | 149 | ||
195 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) | 150 | int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) |
196 | { | 151 | { |
197 | struct nvidia_par *par = info->par; | 152 | struct nvidia_par *par = info->par; |
198 | u8 *edid = NULL; | 153 | u8 *edid = NULL; |
199 | int i; | ||
200 | 154 | ||
201 | for (i = 0; i < 3; i++) { | 155 | if (par->chan[conn - 1].par) |
202 | /* Do the real work */ | 156 | edid = fb_ddc_read(&par->chan[conn - 1].adapter); |
203 | edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]); | ||
204 | if (edid) | ||
205 | break; | ||
206 | } | ||
207 | 157 | ||
208 | if (!edid && conn == 1) { | 158 | if (!edid && conn == 1) { |
209 | /* try to get from firmware */ | 159 | /* try to get from firmware */ |
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h index e009d242ea10..68e508daa417 100644 --- a/drivers/video/nvidia/nv_local.h +++ b/drivers/video/nvidia/nv_local.h | |||
@@ -73,9 +73,9 @@ | |||
73 | #define NVDmaNext(par, data) \ | 73 | #define NVDmaNext(par, data) \ |
74 | NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data)) | 74 | NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data)) |
75 | 75 | ||
76 | #define NVDmaStart(par, tag, size) { \ | 76 | #define NVDmaStart(info, par, tag, size) { \ |
77 | if((par)->dmaFree <= (size)) \ | 77 | if((par)->dmaFree <= (size)) \ |
78 | NVDmaWait(par, size); \ | 78 | NVDmaWait(info, size); \ |
79 | NVDmaNext(par, ((size) << 18) | (tag)); \ | 79 | NVDmaNext(par, ((size) << 18) | (tag)); \ |
80 | (par)->dmaFree -= ((size) + 1); \ | 80 | (par)->dmaFree -= ((size) + 1); \ |
81 | } | 81 | } |
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index eab3e282a4de..707e2c8a13ed 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c | |||
@@ -261,7 +261,7 @@ static void nv10GetConfig(struct nvidia_par *par) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | dev = pci_find_slot(0, 1); | 264 | dev = pci_get_bus_and_slot(0, 1); |
265 | if ((par->Chipset & 0xffff) == 0x01a0) { | 265 | if ((par->Chipset & 0xffff) == 0x01a0) { |
266 | int amt = 0; | 266 | int amt = 0; |
267 | 267 | ||
@@ -276,6 +276,7 @@ static void nv10GetConfig(struct nvidia_par *par) | |||
276 | par->RamAmountKBytes = | 276 | par->RamAmountKBytes = |
277 | (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10; | 277 | (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10; |
278 | } | 278 | } |
279 | pci_dev_put(dev); | ||
279 | 280 | ||
280 | par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ? | 281 | par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ? |
281 | 14318 : 13500; | 282 | 14318 : 13500; |
@@ -656,7 +657,7 @@ int NVCommonSetup(struct fb_info *info) | |||
656 | par->LVDS = 0; | 657 | par->LVDS = 0; |
657 | if (par->FlatPanel && par->twoHeads) { | 658 | if (par->FlatPanel && par->twoHeads) { |
658 | NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); | 659 | NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); |
659 | if (par->PRAMDAC0[0x08b4] & 1) | 660 | if (NV_RD32(par->PRAMDAC0, 0x08b4) & 1) |
660 | par->LVDS = 1; | 661 | par->LVDS = 1; |
661 | printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); | 662 | printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); |
662 | } | 663 | } |
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h index 86e65dea60d3..38f7cc0a2331 100644 --- a/drivers/video/nvidia/nv_type.h +++ b/drivers/video/nvidia/nv_type.h | |||
@@ -4,8 +4,9 @@ | |||
4 | #include <linux/fb.h> | 4 | #include <linux/fb.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/i2c.h> | 6 | #include <linux/i2c.h> |
7 | #include <linux/i2c-id.h> | ||
8 | #include <linux/i2c-algo-bit.h> | 7 | #include <linux/i2c-algo-bit.h> |
8 | #include <linux/mutex.h> | ||
9 | #include <video/vga.h> | ||
9 | 10 | ||
10 | #define NV_ARCH_04 0x04 | 11 | #define NV_ARCH_04 0x04 |
11 | #define NV_ARCH_10 0x10 | 12 | #define NV_ARCH_10 0x10 |
@@ -94,13 +95,15 @@ struct riva_regs { | |||
94 | struct nvidia_par { | 95 | struct nvidia_par { |
95 | RIVA_HW_STATE SavedReg; | 96 | RIVA_HW_STATE SavedReg; |
96 | RIVA_HW_STATE ModeReg; | 97 | RIVA_HW_STATE ModeReg; |
98 | RIVA_HW_STATE initial_state; | ||
97 | RIVA_HW_STATE *CurrentState; | 99 | RIVA_HW_STATE *CurrentState; |
100 | struct vgastate vgastate; | ||
101 | struct mutex open_lock; | ||
98 | u32 pseudo_palette[16]; | 102 | u32 pseudo_palette[16]; |
99 | struct pci_dev *pci_dev; | 103 | struct pci_dev *pci_dev; |
100 | u32 Architecture; | 104 | u32 Architecture; |
101 | u32 CursorStart; | 105 | u32 CursorStart; |
102 | int Chipset; | 106 | int Chipset; |
103 | int bus; | ||
104 | unsigned long FbAddress; | 107 | unsigned long FbAddress; |
105 | u8 __iomem *FbStart; | 108 | u8 __iomem *FbStart; |
106 | u32 FbMapSize; | 109 | u32 FbMapSize; |
@@ -143,6 +146,7 @@ struct nvidia_par { | |||
143 | int BlendingPossible; | 146 | int BlendingPossible; |
144 | u32 paletteEnabled; | 147 | u32 paletteEnabled; |
145 | u32 forceCRTC; | 148 | u32 forceCRTC; |
149 | u32 open_count; | ||
146 | u8 DDCBase; | 150 | u8 DDCBase; |
147 | #ifdef CONFIG_MTRR | 151 | #ifdef CONFIG_MTRR |
148 | struct { | 152 | struct { |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index b97ec6901263..7c36b5fe582e 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -200,7 +200,7 @@ static int nvidia_panel_tweak(struct nvidia_par *par, | |||
200 | return tweak; | 200 | return tweak; |
201 | } | 201 | } |
202 | 202 | ||
203 | static void nvidia_vga_protect(struct nvidia_par *par, int on) | 203 | static void nvidia_screen_off(struct nvidia_par *par, int on) |
204 | { | 204 | { |
205 | unsigned char tmp; | 205 | unsigned char tmp; |
206 | 206 | ||
@@ -649,7 +649,7 @@ static int nvidiafb_set_par(struct fb_info *info) | |||
649 | NVLockUnlock(par, 0); | 649 | NVLockUnlock(par, 0); |
650 | } | 650 | } |
651 | 651 | ||
652 | nvidia_vga_protect(par, 1); | 652 | nvidia_screen_off(par, 1); |
653 | 653 | ||
654 | nvidia_write_regs(par, &par->ModeReg); | 654 | nvidia_write_regs(par, &par->ModeReg); |
655 | NVSetStartAddress(par, 0); | 655 | NVSetStartAddress(par, 0); |
@@ -687,7 +687,7 @@ static int nvidiafb_set_par(struct fb_info *info) | |||
687 | 687 | ||
688 | par->cursor_reset = 1; | 688 | par->cursor_reset = 1; |
689 | 689 | ||
690 | nvidia_vga_protect(par, 0); | 690 | nvidia_screen_off(par, 0); |
691 | 691 | ||
692 | #ifdef CONFIG_BOOTX_TEXT | 692 | #ifdef CONFIG_BOOTX_TEXT |
693 | /* Update debug text engine */ | 693 | /* Update debug text engine */ |
@@ -696,6 +696,7 @@ static int nvidiafb_set_par(struct fb_info *info) | |||
696 | info->var.bits_per_pixel, info->fix.line_length); | 696 | info->var.bits_per_pixel, info->fix.line_length); |
697 | #endif | 697 | #endif |
698 | 698 | ||
699 | NVLockUnlock(par, 0); | ||
699 | NVTRACE_LEAVE(); | 700 | NVTRACE_LEAVE(); |
700 | return 0; | 701 | return 0; |
701 | } | 702 | } |
@@ -948,8 +949,80 @@ static int nvidiafb_blank(int blank, struct fb_info *info) | |||
948 | return 0; | 949 | return 0; |
949 | } | 950 | } |
950 | 951 | ||
952 | /* | ||
953 | * Because the VGA registers are not mapped linearly in its MMIO space, | ||
954 | * restrict VGA register saving and restore to x86 only, where legacy VGA IO | ||
955 | * access is legal. Consequently, we must also check if the device is the | ||
956 | * primary display. | ||
957 | */ | ||
958 | #ifdef CONFIG_X86 | ||
959 | static void save_vga_x86(struct nvidia_par *par) | ||
960 | { | ||
961 | struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE]; | ||
962 | |||
963 | if (res && res->flags & IORESOURCE_ROM_SHADOW) { | ||
964 | memset(&par->vgastate, 0, sizeof(par->vgastate)); | ||
965 | par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | | ||
966 | VGA_SAVE_CMAP; | ||
967 | save_vga(&par->vgastate); | ||
968 | } | ||
969 | } | ||
970 | |||
971 | static void restore_vga_x86(struct nvidia_par *par) | ||
972 | { | ||
973 | struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE]; | ||
974 | |||
975 | if (res && res->flags & IORESOURCE_ROM_SHADOW) | ||
976 | restore_vga(&par->vgastate); | ||
977 | } | ||
978 | #else | ||
979 | #define save_vga_x86(x) do {} while (0) | ||
980 | #define restore_vga_x86(x) do {} while (0) | ||
981 | #endif /* X86 */ | ||
982 | |||
983 | static int nvidiafb_open(struct fb_info *info, int user) | ||
984 | { | ||
985 | struct nvidia_par *par = info->par; | ||
986 | |||
987 | mutex_lock(&par->open_lock); | ||
988 | |||
989 | if (!par->open_count) { | ||
990 | save_vga_x86(par); | ||
991 | nvidia_save_vga(par, &par->initial_state); | ||
992 | } | ||
993 | |||
994 | par->open_count++; | ||
995 | mutex_unlock(&par->open_lock); | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static int nvidiafb_release(struct fb_info *info, int user) | ||
1000 | { | ||
1001 | struct nvidia_par *par = info->par; | ||
1002 | int err = 0; | ||
1003 | |||
1004 | mutex_lock(&par->open_lock); | ||
1005 | |||
1006 | if (!par->open_count) { | ||
1007 | err = -EINVAL; | ||
1008 | goto done; | ||
1009 | } | ||
1010 | |||
1011 | if (par->open_count == 1) { | ||
1012 | nvidia_write_regs(par, &par->initial_state); | ||
1013 | restore_vga_x86(par); | ||
1014 | } | ||
1015 | |||
1016 | par->open_count--; | ||
1017 | done: | ||
1018 | mutex_unlock(&par->open_lock); | ||
1019 | return err; | ||
1020 | } | ||
1021 | |||
951 | static struct fb_ops nvidia_fb_ops = { | 1022 | static struct fb_ops nvidia_fb_ops = { |
952 | .owner = THIS_MODULE, | 1023 | .owner = THIS_MODULE, |
1024 | .fb_open = nvidiafb_open, | ||
1025 | .fb_release = nvidiafb_release, | ||
953 | .fb_check_var = nvidiafb_check_var, | 1026 | .fb_check_var = nvidiafb_check_var, |
954 | .fb_set_par = nvidiafb_set_par, | 1027 | .fb_set_par = nvidiafb_set_par, |
955 | .fb_setcolreg = nvidiafb_setcolreg, | 1028 | .fb_setcolreg = nvidiafb_setcolreg, |
@@ -1207,7 +1280,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1207 | 1280 | ||
1208 | par = info->par; | 1281 | par = info->par; |
1209 | par->pci_dev = pd; | 1282 | par->pci_dev = pd; |
1210 | 1283 | mutex_init(&par->open_lock); | |
1211 | info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL); | 1284 | info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL); |
1212 | 1285 | ||
1213 | if (info->pixmap.addr == NULL) | 1286 | if (info->pixmap.addr == NULL) |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index a560a2223825..1ac5264bb2c1 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -81,8 +81,6 @@ static int lowvsync; | |||
81 | struct pm2fb_par | 81 | struct pm2fb_par |
82 | { | 82 | { |
83 | pm2type_t type; /* Board type */ | 83 | pm2type_t type; /* Board type */ |
84 | u32 fb_size; /* framebuffer memory size */ | ||
85 | unsigned char __iomem *v_fb; /* virtual address of frame buffer */ | ||
86 | unsigned char __iomem *v_regs;/* virtual address of p_regs */ | 84 | unsigned char __iomem *v_regs;/* virtual address of p_regs */ |
87 | u32 memclock; /* memclock */ | 85 | u32 memclock; /* memclock */ |
88 | u32 video; /* video flags before blanking */ | 86 | u32 video; /* video flags before blanking */ |
@@ -103,7 +101,7 @@ static struct fb_fix_screeninfo pm2fb_fix __devinitdata = { | |||
103 | .xpanstep = 1, | 101 | .xpanstep = 1, |
104 | .ypanstep = 1, | 102 | .ypanstep = 1, |
105 | .ywrapstep = 0, | 103 | .ywrapstep = 0, |
106 | .accel = FB_ACCEL_NONE, | 104 | .accel = FB_ACCEL_3DLABS_PERMEDIA2, |
107 | }; | 105 | }; |
108 | 106 | ||
109 | /* | 107 | /* |
@@ -206,6 +204,17 @@ static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) | |||
206 | } | 204 | } |
207 | #endif | 205 | #endif |
208 | 206 | ||
207 | static void wait_pm2(struct pm2fb_par* par) { | ||
208 | |||
209 | WAIT_FIFO(par, 1); | ||
210 | pm2_WR(par, PM2R_SYNC, 0); | ||
211 | mb(); | ||
212 | do { | ||
213 | while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0); | ||
214 | rmb(); | ||
215 | } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC)); | ||
216 | } | ||
217 | |||
209 | /* | 218 | /* |
210 | * partial products for the supported horizontal resolutions. | 219 | * partial products for the supported horizontal resolutions. |
211 | */ | 220 | */ |
@@ -302,10 +311,10 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn, | |||
302 | s32 delta = 1000; | 311 | s32 delta = 1000; |
303 | 312 | ||
304 | *mm = *nn = *pp = 0; | 313 | *mm = *nn = *pp = 0; |
305 | for (n = 1; n; n++) { | 314 | for ( m = 1; m < 128; m++) { |
306 | for ( m = 1; m; m++) { | 315 | for (n = 2 * m + 1; n; n++) { |
307 | for ( p = 0; p < 2; p++) { | 316 | for ( p = 0; p < 2; p++) { |
308 | f = PM2_REFERENCE_CLOCK * n / (m * (1 << (p + 1))); | 317 | f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m; |
309 | if ( clk > f - delta && clk < f + delta ) { | 318 | if ( clk > f - delta && clk < f + delta ) { |
310 | delta = ( clk > f ) ? clk - f : f - clk; | 319 | delta = ( clk > f ) ? clk - f : f - clk; |
311 | *mm=m; | 320 | *mm=m; |
@@ -462,21 +471,43 @@ static void set_memclock(struct pm2fb_par* par, u32 clk) | |||
462 | int i; | 471 | int i; |
463 | unsigned char m, n, p; | 472 | unsigned char m, n, p; |
464 | 473 | ||
465 | pm2_mnp(clk, &m, &n, &p); | 474 | switch (par->type) { |
466 | WAIT_FIFO(par, 10); | 475 | case PM2_TYPE_PERMEDIA2V: |
467 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6); | 476 | pm2v_mnp(clk/2, &m, &n, &p); |
468 | wmb(); | 477 | WAIT_FIFO(par, 8); |
469 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m); | 478 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); |
470 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n); | 479 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); |
471 | wmb(); | 480 | wmb(); |
472 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); | 481 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); |
473 | wmb(); | 482 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n); |
474 | pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); | 483 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); |
475 | rmb(); | 484 | wmb(); |
476 | for (i = 256; | 485 | pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); |
477 | i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); | 486 | rmb(); |
478 | i--) | 487 | for (i = 256; |
479 | ; | 488 | i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2); |
489 | i--) | ||
490 | ; | ||
491 | pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0); | ||
492 | break; | ||
493 | case PM2_TYPE_PERMEDIA2: | ||
494 | pm2_mnp(clk, &m, &n, &p); | ||
495 | WAIT_FIFO(par, 10); | ||
496 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6); | ||
497 | wmb(); | ||
498 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m); | ||
499 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n); | ||
500 | wmb(); | ||
501 | pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); | ||
502 | wmb(); | ||
503 | pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); | ||
504 | rmb(); | ||
505 | for (i = 256; | ||
506 | i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); | ||
507 | i--) | ||
508 | ; | ||
509 | break; | ||
510 | } | ||
480 | } | 511 | } |
481 | 512 | ||
482 | static void set_pixclock(struct pm2fb_par* par, u32 clk) | 513 | static void set_pixclock(struct pm2fb_par* par, u32 clk) |
@@ -623,6 +654,8 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
623 | return -EINVAL; | 654 | return -EINVAL; |
624 | } | 655 | } |
625 | 656 | ||
657 | var->transp.offset = 0; | ||
658 | var->transp.length = 0; | ||
626 | switch(var->bits_per_pixel) { | 659 | switch(var->bits_per_pixel) { |
627 | case 8: | 660 | case 8: |
628 | var->red.length = var->green.length = var->blue.length = 8; | 661 | var->red.length = var->green.length = var->blue.length = 8; |
@@ -1017,6 +1050,117 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info) | |||
1017 | return 0; | 1050 | return 0; |
1018 | } | 1051 | } |
1019 | 1052 | ||
1053 | /* | ||
1054 | * block operation. copy=0: rectangle fill, copy=1: rectangle copy. | ||
1055 | */ | ||
1056 | static void pm2fb_block_op(struct pm2fb_par* par, int copy, | ||
1057 | s32 xsrc, s32 ysrc, | ||
1058 | s32 x, s32 y, s32 w, s32 h, | ||
1059 | u32 color) { | ||
1060 | |||
1061 | if (!w || !h) | ||
1062 | return; | ||
1063 | WAIT_FIFO(par, 6); | ||
1064 | pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE | | ||
1065 | PM2F_CONFIG_FB_READ_SOURCE_ENABLE); | ||
1066 | pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0); | ||
1067 | if (copy) | ||
1068 | pm2_WR(par, PM2R_FB_SOURCE_DELTA, | ||
1069 | ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff)); | ||
1070 | else | ||
1071 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, color); | ||
1072 | pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x); | ||
1073 | pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w); | ||
1074 | wmb(); | ||
1075 | pm2_WR(par, PM2R_RENDER,PM2F_RENDER_RECTANGLE | | ||
1076 | (x<xsrc ? PM2F_INCREASE_X : 0) | | ||
1077 | (y<ysrc ? PM2F_INCREASE_Y : 0) | | ||
1078 | (copy ? 0 : PM2F_RENDER_FASTFILL)); | ||
1079 | wait_pm2(par); | ||
1080 | } | ||
1081 | |||
1082 | static void pm2fb_fillrect (struct fb_info *info, | ||
1083 | const struct fb_fillrect *region) | ||
1084 | { | ||
1085 | struct pm2fb_par *par = info->par; | ||
1086 | struct fb_fillrect modded; | ||
1087 | int vxres, vyres; | ||
1088 | u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? | ||
1089 | ((u32*)info->pseudo_palette)[region->color] : region->color; | ||
1090 | |||
1091 | if (info->state != FBINFO_STATE_RUNNING) | ||
1092 | return; | ||
1093 | if ((info->flags & FBINFO_HWACCEL_DISABLED) || | ||
1094 | region->rop != ROP_COPY ) { | ||
1095 | cfb_fillrect(info, region); | ||
1096 | return; | ||
1097 | } | ||
1098 | |||
1099 | vxres = info->var.xres_virtual; | ||
1100 | vyres = info->var.yres_virtual; | ||
1101 | |||
1102 | memcpy(&modded, region, sizeof(struct fb_fillrect)); | ||
1103 | |||
1104 | if(!modded.width || !modded.height || | ||
1105 | modded.dx >= vxres || modded.dy >= vyres) | ||
1106 | return; | ||
1107 | |||
1108 | if(modded.dx + modded.width > vxres) | ||
1109 | modded.width = vxres - modded.dx; | ||
1110 | if(modded.dy + modded.height > vyres) | ||
1111 | modded.height = vyres - modded.dy; | ||
1112 | |||
1113 | if(info->var.bits_per_pixel == 8) | ||
1114 | color |= color << 8; | ||
1115 | if(info->var.bits_per_pixel <= 16) | ||
1116 | color |= color << 16; | ||
1117 | |||
1118 | if(info->var.bits_per_pixel != 24) | ||
1119 | pm2fb_block_op(par, 0, 0, 0, | ||
1120 | modded.dx, modded.dy, | ||
1121 | modded.width, modded.height, color); | ||
1122 | else | ||
1123 | cfb_fillrect(info, region); | ||
1124 | } | ||
1125 | |||
1126 | static void pm2fb_copyarea(struct fb_info *info, | ||
1127 | const struct fb_copyarea *area) | ||
1128 | { | ||
1129 | struct pm2fb_par *par = info->par; | ||
1130 | struct fb_copyarea modded; | ||
1131 | u32 vxres, vyres; | ||
1132 | |||
1133 | if (info->state != FBINFO_STATE_RUNNING) | ||
1134 | return; | ||
1135 | if (info->flags & FBINFO_HWACCEL_DISABLED) { | ||
1136 | cfb_copyarea(info, area); | ||
1137 | return; | ||
1138 | } | ||
1139 | |||
1140 | memcpy(&modded, area, sizeof(struct fb_copyarea)); | ||
1141 | |||
1142 | vxres = info->var.xres_virtual; | ||
1143 | vyres = info->var.yres_virtual; | ||
1144 | |||
1145 | if(!modded.width || !modded.height || | ||
1146 | modded.sx >= vxres || modded.sy >= vyres || | ||
1147 | modded.dx >= vxres || modded.dy >= vyres) | ||
1148 | return; | ||
1149 | |||
1150 | if(modded.sx + modded.width > vxres) | ||
1151 | modded.width = vxres - modded.sx; | ||
1152 | if(modded.dx + modded.width > vxres) | ||
1153 | modded.width = vxres - modded.dx; | ||
1154 | if(modded.sy + modded.height > vyres) | ||
1155 | modded.height = vyres - modded.sy; | ||
1156 | if(modded.dy + modded.height > vyres) | ||
1157 | modded.height = vyres - modded.dy; | ||
1158 | |||
1159 | pm2fb_block_op(par, 1, modded.sx, modded.sy, | ||
1160 | modded.dx, modded.dy, | ||
1161 | modded.width, modded.height, 0); | ||
1162 | } | ||
1163 | |||
1020 | /* ------------ Hardware Independent Functions ------------ */ | 1164 | /* ------------ Hardware Independent Functions ------------ */ |
1021 | 1165 | ||
1022 | /* | 1166 | /* |
@@ -1030,8 +1174,8 @@ static struct fb_ops pm2fb_ops = { | |||
1030 | .fb_setcolreg = pm2fb_setcolreg, | 1174 | .fb_setcolreg = pm2fb_setcolreg, |
1031 | .fb_blank = pm2fb_blank, | 1175 | .fb_blank = pm2fb_blank, |
1032 | .fb_pan_display = pm2fb_pan_display, | 1176 | .fb_pan_display = pm2fb_pan_display, |
1033 | .fb_fillrect = cfb_fillrect, | 1177 | .fb_fillrect = pm2fb_fillrect, |
1034 | .fb_copyarea = cfb_copyarea, | 1178 | .fb_copyarea = pm2fb_copyarea, |
1035 | .fb_imageblit = cfb_imageblit, | 1179 | .fb_imageblit = cfb_imageblit, |
1036 | }; | 1180 | }; |
1037 | 1181 | ||
@@ -1119,38 +1263,47 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1119 | 1263 | ||
1120 | if(default_par->mem_control == 0 && | 1264 | if(default_par->mem_control == 0 && |
1121 | default_par->boot_address == 0x31 && | 1265 | default_par->boot_address == 0x31 && |
1122 | default_par->mem_config == 0x259fffff && | 1266 | default_par->mem_config == 0x259fffff) { |
1123 | pdev->subsystem_vendor == 0x1048 && | 1267 | default_par->memclock = CVPPC_MEMCLOCK; |
1124 | pdev->subsystem_device == 0x0a31) { | ||
1125 | DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", | ||
1126 | pdev->subsystem_vendor, pdev->subsystem_device); | ||
1127 | DPRINTK("We have not been initialized by VGA BIOS " | ||
1128 | "and are running on an Elsa Winner 2000 Office\n"); | ||
1129 | DPRINTK("Initializing card timings manually...\n"); | ||
1130 | default_par->mem_control=0; | 1268 | default_par->mem_control=0; |
1131 | default_par->boot_address=0x20; | 1269 | default_par->boot_address=0x20; |
1132 | default_par->mem_config=0xe6002021; | 1270 | default_par->mem_config=0xe6002021; |
1133 | default_par->memclock=100000; | 1271 | if (pdev->subsystem_vendor == 0x1048 && |
1272 | pdev->subsystem_device == 0x0a31) { | ||
1273 | DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", | ||
1274 | pdev->subsystem_vendor, pdev->subsystem_device); | ||
1275 | DPRINTK("We have not been initialized by VGA BIOS " | ||
1276 | "and are running on an Elsa Winner 2000 Office\n"); | ||
1277 | DPRINTK("Initializing card timings manually...\n"); | ||
1278 | default_par->memclock=70000; | ||
1279 | } | ||
1280 | if (pdev->subsystem_vendor == 0x3d3d && | ||
1281 | pdev->subsystem_device == 0x0100) { | ||
1282 | DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", | ||
1283 | pdev->subsystem_vendor, pdev->subsystem_device); | ||
1284 | DPRINTK("We have not been initialized by VGA BIOS " | ||
1285 | "and are running on an 3dlabs reference board\n"); | ||
1286 | DPRINTK("Initializing card timings manually...\n"); | ||
1287 | default_par->memclock=74894; | ||
1288 | } | ||
1134 | } | 1289 | } |
1135 | 1290 | ||
1136 | /* Now work out how big lfb is going to be. */ | 1291 | /* Now work out how big lfb is going to be. */ |
1137 | switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { | 1292 | switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { |
1138 | case PM2F_MEM_BANKS_1: | 1293 | case PM2F_MEM_BANKS_1: |
1139 | default_par->fb_size=0x200000; | 1294 | pm2fb_fix.smem_len=0x200000; |
1140 | break; | 1295 | break; |
1141 | case PM2F_MEM_BANKS_2: | 1296 | case PM2F_MEM_BANKS_2: |
1142 | default_par->fb_size=0x400000; | 1297 | pm2fb_fix.smem_len=0x400000; |
1143 | break; | 1298 | break; |
1144 | case PM2F_MEM_BANKS_3: | 1299 | case PM2F_MEM_BANKS_3: |
1145 | default_par->fb_size=0x600000; | 1300 | pm2fb_fix.smem_len=0x600000; |
1146 | break; | 1301 | break; |
1147 | case PM2F_MEM_BANKS_4: | 1302 | case PM2F_MEM_BANKS_4: |
1148 | default_par->fb_size=0x800000; | 1303 | pm2fb_fix.smem_len=0x800000; |
1149 | break; | 1304 | break; |
1150 | } | 1305 | } |
1151 | default_par->memclock = CVPPC_MEMCLOCK; | ||
1152 | pm2fb_fix.smem_start = pci_resource_start(pdev, 1); | 1306 | pm2fb_fix.smem_start = pci_resource_start(pdev, 1); |
1153 | pm2fb_fix.smem_len = default_par->fb_size; | ||
1154 | 1307 | ||
1155 | /* Linear frame buffer - request region and map it. */ | 1308 | /* Linear frame buffer - request region and map it. */ |
1156 | if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, | 1309 | if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, |
@@ -1158,9 +1311,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1158 | printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); | 1311 | printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); |
1159 | goto err_exit_mmio; | 1312 | goto err_exit_mmio; |
1160 | } | 1313 | } |
1161 | info->screen_base = default_par->v_fb = | 1314 | info->screen_base = |
1162 | ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); | 1315 | ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); |
1163 | if ( !default_par->v_fb ) { | 1316 | if ( !info->screen_base ) { |
1164 | printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); | 1317 | printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); |
1165 | release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); | 1318 | release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); |
1166 | goto err_exit_mmio; | 1319 | goto err_exit_mmio; |
@@ -1170,7 +1323,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1170 | info->fix = pm2fb_fix; | 1323 | info->fix = pm2fb_fix; |
1171 | info->pseudo_palette = default_par->palette; | 1324 | info->pseudo_palette = default_par->palette; |
1172 | info->flags = FBINFO_DEFAULT | | 1325 | info->flags = FBINFO_DEFAULT | |
1173 | FBINFO_HWACCEL_YPAN; | 1326 | FBINFO_HWACCEL_YPAN | |
1327 | FBINFO_HWACCEL_COPYAREA | | ||
1328 | FBINFO_HWACCEL_FILLRECT; | ||
1174 | 1329 | ||
1175 | if (!mode) | 1330 | if (!mode) |
1176 | mode = "640x480@60"; | 1331 | mode = "640x480@60"; |
@@ -1180,13 +1335,13 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, | |||
1180 | info->var = pm2fb_var; | 1335 | info->var = pm2fb_var; |
1181 | 1336 | ||
1182 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) | 1337 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) |
1183 | goto err_exit_all; | 1338 | goto err_exit_both; |
1184 | 1339 | ||
1185 | if (register_framebuffer(info) < 0) | 1340 | if (register_framebuffer(info) < 0) |
1186 | goto err_exit_both; | 1341 | goto err_exit_all; |
1187 | 1342 | ||
1188 | printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n", | 1343 | printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n", |
1189 | info->node, info->fix.id, default_par->fb_size / 1024); | 1344 | info->node, info->fix.id, pm2fb_fix.smem_len / 1024); |
1190 | 1345 | ||
1191 | /* | 1346 | /* |
1192 | * Our driver data | 1347 | * Our driver data |
@@ -1242,6 +1397,9 @@ static struct pci_device_id pm2fb_id_table[] = { | |||
1242 | { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, | 1397 | { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, |
1243 | PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, | 1398 | PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, |
1244 | 0xff0000, 0 }, | 1399 | 0xff0000, 0 }, |
1400 | { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, | ||
1401 | PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8, | ||
1402 | 0xff00, 0 }, | ||
1245 | { 0, } | 1403 | { 0, } |
1246 | }; | 1404 | }; |
1247 | 1405 | ||
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index a93618bc9d27..df2909ae704c 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c | |||
@@ -214,7 +214,7 @@ static int pvr2_init_cable(void); | |||
214 | static int pvr2_get_param(const struct pvr2_params *p, const char *s, | 214 | static int pvr2_get_param(const struct pvr2_params *p, const char *s, |
215 | int val, int size); | 215 | int val, int size); |
216 | #ifdef CONFIG_SH_DMA | 216 | #ifdef CONFIG_SH_DMA |
217 | static ssize_t pvr2fb_write(struct file *file, const char *buf, | 217 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, |
218 | size_t count, loff_t *ppos); | 218 | size_t count, loff_t *ppos); |
219 | #endif | 219 | #endif |
220 | 220 | ||
@@ -674,7 +674,7 @@ static int pvr2_init_cable(void) | |||
674 | } | 674 | } |
675 | 675 | ||
676 | #ifdef CONFIG_SH_DMA | 676 | #ifdef CONFIG_SH_DMA |
677 | static ssize_t pvr2fb_write(struct file *file, const char *buf, | 677 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, |
678 | size_t count, loff_t *ppos) | 678 | size_t count, loff_t *ppos) |
679 | { | 679 | { |
680 | unsigned long dst, start, end, len; | 680 | unsigned long dst, start, end, len; |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 0b195f33f84f..81e571d59b50 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1203,7 +1203,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options) | |||
1203 | } else | 1203 | } else |
1204 | goto done; | 1204 | goto done; |
1205 | break; | 1205 | break; |
1206 | case '0'...'9': | 1206 | case '0' ... '9': |
1207 | break; | 1207 | break; |
1208 | default: | 1208 | default: |
1209 | goto done; | 1209 | goto done; |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 9c6bd0991852..0fe547842c64 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -317,15 +317,15 @@ static int riva_bl_update_status(struct backlight_device *bd) | |||
317 | else | 317 | else |
318 | level = bd->props.brightness; | 318 | level = bd->props.brightness; |
319 | 319 | ||
320 | tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; | 320 | tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF; |
321 | tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC; | 321 | tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC; |
322 | if(level > 0) { | 322 | if(level > 0) { |
323 | tmp_pcrt |= 0x1; | 323 | tmp_pcrt |= 0x1; |
324 | tmp_pmc |= (1 << 31); /* backlight bit */ | 324 | tmp_pmc |= (1 << 31); /* backlight bit */ |
325 | tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ | 325 | tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ |
326 | } | 326 | } |
327 | par->riva.PCRTC0[0x081C/4] = tmp_pcrt; | 327 | NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt); |
328 | par->riva.PMC[0x10F0/4] = tmp_pmc; | 328 | NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc); |
329 | 329 | ||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
@@ -1788,8 +1788,10 @@ static int __devinit riva_get_EDID_i2c(struct fb_info *info) | |||
1788 | 1788 | ||
1789 | NVTRACE_ENTER(); | 1789 | NVTRACE_ENTER(); |
1790 | riva_create_i2c_busses(par); | 1790 | riva_create_i2c_busses(par); |
1791 | for (i = 0; i < par->bus; i++) { | 1791 | for (i = 0; i < 3; i++) { |
1792 | riva_probe_i2c_connector(par, i+1, &par->EDID); | 1792 | if (!par->chan[i].par) |
1793 | continue; | ||
1794 | riva_probe_i2c_connector(par, i, &par->EDID); | ||
1793 | if (par->EDID && !fb_parse_edid(par->EDID, &var)) { | 1795 | if (par->EDID && !fb_parse_edid(par->EDID, &var)) { |
1794 | printk(PFX "Found EDID Block from BUS %i\n", i); | 1796 | printk(PFX "Found EDID Block from BUS %i\n", i); |
1795 | break; | 1797 | break; |
@@ -2104,7 +2106,7 @@ err_ret: | |||
2104 | return ret; | 2106 | return ret; |
2105 | } | 2107 | } |
2106 | 2108 | ||
2107 | static void __exit rivafb_remove(struct pci_dev *pd) | 2109 | static void __devexit rivafb_remove(struct pci_dev *pd) |
2108 | { | 2110 | { |
2109 | struct fb_info *info = pci_get_drvdata(pd); | 2111 | struct fb_info *info = pci_get_drvdata(pd); |
2110 | struct riva_par *par = info->par; | 2112 | struct riva_par *par = info->par; |
@@ -2185,7 +2187,7 @@ static struct pci_driver rivafb_driver = { | |||
2185 | .name = "rivafb", | 2187 | .name = "rivafb", |
2186 | .id_table = rivafb_pci_tbl, | 2188 | .id_table = rivafb_pci_tbl, |
2187 | .probe = rivafb_probe, | 2189 | .probe = rivafb_probe, |
2188 | .remove = __exit_p(rivafb_remove), | 2190 | .remove = __devexit_p(rivafb_remove), |
2189 | }; | 2191 | }; |
2190 | 2192 | ||
2191 | 2193 | ||
diff --git a/drivers/video/riva/nv4ref.h b/drivers/video/riva/nv4ref.h deleted file mode 100644 index 3b5f9117c37d..000000000000 --- a/drivers/video/riva/nv4ref.h +++ /dev/null | |||
@@ -1,2445 +0,0 @@ | |||
1 | /***************************************************************************\ | ||
2 | |* *| | ||
3 | |* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *| | ||
4 | |* *| | ||
5 | |* NOTICE TO USER: The source code is copyrighted under U.S. and *| | ||
6 | |* international laws. Users and possessors of this source code are *| | ||
7 | |* hereby granted a nonexclusive, royalty-free copyright license to *| | ||
8 | |* use this code in individual and commercial software. *| | ||
9 | |* *| | ||
10 | |* Any use of this source code must include, in the user documenta- *| | ||
11 | |* tion and internal comments to the code, notices to the end user *| | ||
12 | |* as follows: *| | ||
13 | |* *| | ||
14 | |* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *| | ||
15 | |* *| | ||
16 | |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| | ||
17 | |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| | ||
18 | |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| | ||
19 | |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| | ||
20 | |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| | ||
21 | |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| | ||
22 | |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| | ||
23 | |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| | ||
24 | |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| | ||
25 | |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| | ||
26 | |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| | ||
27 | |* *| | ||
28 | |* U.S. Government End Users. This source code is a "commercial *| | ||
29 | |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| | ||
30 | |* consisting of "commercial computer software" and "commercial *| | ||
31 | |* computer software documentation," as such terms are used in *| | ||
32 | |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| | ||
33 | |* ment only as a commercial end item. Consistent with 48 C.F.R. *| | ||
34 | |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| | ||
35 | |* all U.S. Government End Users acquire the source code with only *| | ||
36 | |* those rights set forth herein. *| | ||
37 | |* *| | ||
38 | \***************************************************************************/ | ||
39 | |||
40 | /* | ||
41 | * GPL licensing note -- nVidia is allowing a liberal interpretation of | ||
42 | * the documentation restriction above, to merely say that this nVidia's | ||
43 | * copyright and disclaimer should be included with all code derived | ||
44 | * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 | ||
45 | */ | ||
46 | |||
47 | /***************************************************************************\ | ||
48 | |* Modified 1999 by Fredrik Reite (fredrik@reite.com) *| | ||
49 | \***************************************************************************/ | ||
50 | |||
51 | |||
52 | #ifndef __NV4REF_H__ | ||
53 | #define __NV4REF_H__ | ||
54 | |||
55 | /* Magic values to lock/unlock extended regs */ | ||
56 | #define NV_CIO_SR_LOCK_INDEX 0x0000001F /* */ | ||
57 | #define NV_CIO_SR_UNLOCK_RW_VALUE 0x00000057 /* */ | ||
58 | #define NV_CIO_SR_UNLOCK_RO_VALUE 0x00000075 /* */ | ||
59 | #define NV_CIO_SR_LOCK_VALUE 0x00000099 /* */ | ||
60 | |||
61 | #define UNLOCK_EXT_MAGIC 0x57 | ||
62 | #define LOCK_EXT_MAGIC 0x99 /* Any value other than 0x57 will do */ | ||
63 | |||
64 | #define LOCK_EXT_INDEX 0x6 | ||
65 | |||
66 | #define NV_PCRTC_HORIZ_TOTAL 0x00 | ||
67 | #define NV_PCRTC_HORIZ_DISPLAY_END 0x01 | ||
68 | #define NV_PCRTC_HORIZ_BLANK_START 0x02 | ||
69 | |||
70 | #define NV_PCRTC_HORIZ_BLANK_END 0x03 | ||
71 | #define NV_PCRTC_HORIZ_BLANK_END_EVRA 7:7 | ||
72 | #define NV_PCRTC_HORIZ_BLANK_END_DISPLAY_END_SKEW 6:5 | ||
73 | #define NV_PCRTC_HORIZ_BLANK_END_HORIZ_BLANK_END 4:0 | ||
74 | |||
75 | #define NV_PCRTC_HORIZ_RETRACE_START 0x04 | ||
76 | |||
77 | #define NV_PCRTC_HORIZ_RETRACE_END 0x05 | ||
78 | #define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_BLANK_END_5 7:7 | ||
79 | #define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_SKEW 6:5 | ||
80 | #define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_END 4:0 | ||
81 | |||
82 | #define NV_PCRTC_VERT_TOTAL 0x06 | ||
83 | |||
84 | #define NV_PCRTC_OVERFLOW 0x07 | ||
85 | #define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_9 7:7 | ||
86 | #define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_9 6:6 | ||
87 | #define NV_PCRTC_OVERFLOW_VERT_TOTAL_9 5:5 | ||
88 | #define NV_PCRTC_OVERFLOW_LINE_COMPARE_8 4:4 | ||
89 | #define NV_PCRTC_OVERFLOW_VERT_BLANK_START_8 3:3 | ||
90 | #define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_8 2:2 | ||
91 | #define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_8 1:1 | ||
92 | #define NV_PCRTC_OVERFLOW_VERT_TOTAL_8 0:0 | ||
93 | |||
94 | #define NV_PCRTC_PRESET_ROW_SCAN 0x08 | ||
95 | |||
96 | #define NV_PCRTC_MAX_SCAN_LINE 0x09 | ||
97 | #define NV_PCRTC_MAX_SCAN_LINE_DOUBLE_SCAN 7:7 | ||
98 | #define NV_PCRTC_MAX_SCAN_LINE_LINE_COMPARE_9 6:6 | ||
99 | #define NV_PCRTC_MAX_SCAN_LINE_VERT_BLANK_START_9 5:5 | ||
100 | #define NV_PCRTC_MAX_SCAN_LINE_MAX_SCAN_LINE 4:0 | ||
101 | |||
102 | #define NV_PCRTC_CURSOR_START 0x0A | ||
103 | #define NV_PCRTC_CURSOR_END 0x0B | ||
104 | #define NV_PCRTC_START_ADDR_HIGH 0x0C | ||
105 | #define NV_PCRTC_START_ADDR_LOW 0x0D | ||
106 | #define NV_PCRTC_CURSOR_LOCATION_HIGH 0x0E | ||
107 | #define NV_PCRTC_CURSOR_LOCATION_LOW 0x0F | ||
108 | |||
109 | #define NV_PCRTC_VERT_RETRACE_START 0x10 | ||
110 | #define NV_PCRTC_VERT_RETRACE_END 0x11 | ||
111 | #define NV_PCRTC_VERT_DISPLAY_END 0x12 | ||
112 | #define NV_PCRTC_OFFSET 0x13 | ||
113 | #define NV_PCRTC_UNDERLINE_LOCATION 0x14 | ||
114 | #define NV_PCRTC_VERT_BLANK_START 0x15 | ||
115 | #define NV_PCRTC_VERT_BLANK_END 0x16 | ||
116 | #define NV_PCRTC_MODE_CONTROL 0x17 | ||
117 | #define NV_PCRTC_LINE_COMPARE 0x18 | ||
118 | |||
119 | /* Extended offset and start address */ | ||
120 | #define NV_PCRTC_REPAINT0 0x19 | ||
121 | #define NV_PCRTC_REPAINT0_OFFSET_10_8 7:5 | ||
122 | #define NV_PCRTC_REPAINT0_START_ADDR_20_16 4:0 | ||
123 | |||
124 | /* Horizonal extended bits */ | ||
125 | #define NV_PCRTC_HORIZ_EXTRA 0x2d | ||
126 | #define NV_PCRTC_HORIZ_EXTRA_INTER_HALF_START_8 4:4 | ||
127 | #define NV_PCRTC_HORIZ_EXTRA_HORIZ_RETRACE_START_8 3:3 | ||
128 | #define NV_PCRTC_HORIZ_EXTRA_HORIZ_BLANK_START_8 2:2 | ||
129 | #define NV_PCRTC_HORIZ_EXTRA_DISPLAY_END_8 1:1 | ||
130 | #define NV_PCRTC_HORIZ_EXTRA_DISPLAY_TOTAL_8 0:0 | ||
131 | |||
132 | /* Assorted extra bits */ | ||
133 | #define NV_PCRTC_EXTRA 0x25 | ||
134 | #define NV_PCRTC_EXTRA_OFFSET_11 5:5 | ||
135 | #define NV_PCRTC_EXTRA_HORIZ_BLANK_END_6 4:4 | ||
136 | #define NV_PCRTC_EXTRA_VERT_BLANK_START_10 3:3 | ||
137 | #define NV_PCRTC_EXTRA_VERT_RETRACE_START_10 2:2 | ||
138 | #define NV_PCRTC_EXTRA_VERT_DISPLAY_END_10 1:1 | ||
139 | #define NV_PCRTC_EXTRA_VERT_TOTAL_10 0:0 | ||
140 | |||
141 | /* Controls how much data the refresh fifo requests */ | ||
142 | #define NV_PCRTC_FIFO_CONTROL 0x1b | ||
143 | #define NV_PCRTC_FIFO_CONTROL_UNDERFLOW_WARN 7:7 | ||
144 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH 2:0 | ||
145 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_8 0x0 | ||
146 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_32 0x1 | ||
147 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_64 0x2 | ||
148 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_128 0x3 | ||
149 | #define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_256 0x4 | ||
150 | |||
151 | /* When the fifo occupancy falls below *twice* the watermark, | ||
152 | * the refresh fifo will start to be refilled. If this value is | ||
153 | * too low, you will get junk on the screen. Too high, and performance | ||
154 | * will suffer. Watermark in units of 8 bytes | ||
155 | */ | ||
156 | #define NV_PCRTC_FIFO 0x20 | ||
157 | #define NV_PCRTC_FIFO_RESET 7:7 | ||
158 | #define NV_PCRTC_FIFO_WATERMARK 5:0 | ||
159 | |||
160 | /* Various flags */ | ||
161 | #define NV_PCRTC_REPAINT1 0x1a | ||
162 | #define NV_PCRTC_REPAINT1_HSYNC 7:7 | ||
163 | #define NV_PCRTC_REPAINT1_HYSNC_DISABLE 0x01 | ||
164 | #define NV_PCRTC_REPAINT1_HYSNC_ENABLE 0x00 | ||
165 | #define NV_PCRTC_REPAINT1_VSYNC 6:6 | ||
166 | #define NV_PCRTC_REPAINT1_VYSNC_DISABLE 0x01 | ||
167 | #define NV_PCRTC_REPAINT1_VYSNC_ENABLE 0x00 | ||
168 | #define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT 4:4 | ||
169 | #define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_ENABLE 0x01 | ||
170 | #define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_DISABLE 0x00 | ||
171 | #define NV_PCRTC_REPAINT1_LARGE_SCREEN 2:2 | ||
172 | #define NV_PCRTC_REPAINT1_LARGE_SCREEN_DISABLE 0x01 | ||
173 | #define NV_PCRTC_REPAINT1_LARGE_SCREEN_ENABLE 0x00 /* >=1280 */ | ||
174 | #define NV_PCRTC_REPAINT1_PALETTE_WIDTH 1:1 | ||
175 | #define NV_PCRTC_REPAINT1_PALETTE_WIDTH_8BITS 0x00 | ||
176 | #define NV_PCRTC_REPAINT1_PALETTE_WIDTH_6BITS 0x01 | ||
177 | |||
178 | #define NV_PCRTC_GRCURSOR0 0x30 | ||
179 | #define NV_PCRTC_GRCURSOR0_START_ADDR_21_16 5:0 | ||
180 | |||
181 | #define NV_PCRTC_GRCURSOR1 0x31 | ||
182 | #define NV_PCRTC_GRCURSOR1_START_ADDR_15_11 7:3 | ||
183 | #define NV_PCRTC_GRCURSOR1_SCAN_DBL 1:1 | ||
184 | #define NV_PCRTC_GRCURSOR1_SCAN_DBL_DISABLE 0 | ||
185 | #define NV_PCRTC_GRCURSOR1_SCAN_DBL_ENABLE 1 | ||
186 | #define NV_PCRTC_GRCURSOR1_CURSOR 0:0 | ||
187 | #define NV_PCRTC_GRCURSOR1_CURSOR_DISABLE 0 | ||
188 | #define NV_PCRTC_GRCURSOR1_CURSOR_ENABLE 1 | ||
189 | |||
190 | /* Controls what the format of the framebuffer is */ | ||
191 | #define NV_PCRTC_PIXEL 0x28 | ||
192 | #define NV_PCRTC_PIXEL_MODE 7:7 | ||
193 | #define NV_PCRTC_PIXEL_MODE_TV 0x01 | ||
194 | #define NV_PCRTC_PIXEL_MODE_VGA 0x00 | ||
195 | #define NV_PCRTC_PIXEL_TV_MODE 6:6 | ||
196 | #define NV_PCRTC_PIXEL_TV_MODE_NTSC 0x00 | ||
197 | #define NV_PCRTC_PIXEL_TV_MODE_PAL 0x01 | ||
198 | #define NV_PCRTC_PIXEL_TV_HORIZ_ADJUST 5:3 | ||
199 | #define NV_PCRTC_PIXEL_FORMAT 1:0 | ||
200 | #define NV_PCRTC_PIXEL_FORMAT_VGA 0x00 | ||
201 | #define NV_PCRTC_PIXEL_FORMAT_8BPP 0x01 | ||
202 | #define NV_PCRTC_PIXEL_FORMAT_16BPP 0x02 | ||
203 | #define NV_PCRTC_PIXEL_FORMAT_32BPP 0x03 | ||
204 | |||
205 | /* RAMDAC registers and fields */ | ||
206 | #define NV_PRAMDAC 0x00680FFF:0x00680000 /* RW--D */ | ||
207 | #define NV_PRAMDAC_GRCURSOR_START_POS 0x00680300 /* RW-4R */ | ||
208 | #define NV_PRAMDAC_GRCURSOR_START_POS_X 11:0 /* RWXSF */ | ||
209 | #define NV_PRAMDAC_GRCURSOR_START_POS_Y 27:16 /* RWXSF */ | ||
210 | #define NV_PRAMDAC_NVPLL_COEFF 0x00680500 /* RW-4R */ | ||
211 | #define NV_PRAMDAC_NVPLL_COEFF_MDIV 7:0 /* RWIUF */ | ||
212 | #define NV_PRAMDAC_NVPLL_COEFF_NDIV 15:8 /* RWIUF */ | ||
213 | #define NV_PRAMDAC_NVPLL_COEFF_PDIV 18:16 /* RWIVF */ | ||
214 | #define NV_PRAMDAC_MPLL_COEFF 0x00680504 /* RW-4R */ | ||
215 | #define NV_PRAMDAC_MPLL_COEFF_MDIV 7:0 /* RWIUF */ | ||
216 | #define NV_PRAMDAC_MPLL_COEFF_NDIV 15:8 /* RWIUF */ | ||
217 | #define NV_PRAMDAC_MPLL_COEFF_PDIV 18:16 /* RWIVF */ | ||
218 | #define NV_PRAMDAC_VPLL_COEFF 0x00680508 /* RW-4R */ | ||
219 | #define NV_PRAMDAC_VPLL_COEFF_MDIV 7:0 /* RWIUF */ | ||
220 | #define NV_PRAMDAC_VPLL_COEFF_NDIV 15:8 /* RWIUF */ | ||
221 | #define NV_PRAMDAC_VPLL_COEFF_PDIV 18:16 /* RWIVF */ | ||
222 | #define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050C /* RW-4R */ | ||
223 | #define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS 4:4 /* RWIVF */ | ||
224 | #define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_FALSE 0x00000000 /* RWI-V */ | ||
225 | #define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_TRUE 0x00000001 /* RW--V */ | ||
226 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE 8:8 /* RWIVF */ | ||
227 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */ | ||
228 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_PROG 0x00000001 /* RW--V */ | ||
229 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS 12:12 /* RWIVF */ | ||
230 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_FALSE 0x00000000 /* RWI-V */ | ||
231 | #define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_TRUE 0x00000001 /* RW--V */ | ||
232 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE 16:16 /* RWIVF */ | ||
233 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */ | ||
234 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_PROG 0x00000001 /* RW--V */ | ||
235 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS 20:20 /* RWIVF */ | ||
236 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_FALSE 0x00000000 /* RWI-V */ | ||
237 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_TRUE 0x00000001 /* RW--V */ | ||
238 | #define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE 25:24 /* RWIVF */ | ||
239 | #define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VPLL 0x00000000 /* RWI-V */ | ||
240 | #define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VIP 0x00000001 /* RW--V */ | ||
241 | #define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_XTALOSC 0x00000002 /* RW--V */ | ||
242 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO 28:28 /* RWIVF */ | ||
243 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1 0x00000000 /* RWI-V */ | ||
244 | #define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 0x00000001 /* RW--V */ | ||
245 | #define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 /* RW-4R */ | ||
246 | #define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF 1:0 /* RWIVF */ | ||
247 | #define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF_DEF 0x00000000 /* RWI-V */ | ||
248 | #define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE 4:4 /* RWIVF */ | ||
249 | #define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_GAMMA 0x00000000 /* RWI-V */ | ||
250 | #define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_INDEX 0x00000001 /* RW--V */ | ||
251 | #define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE 8:8 /* RWIVF */ | ||
252 | #define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSE 0x00000000 /* RWI-V */ | ||
253 | #define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL 0x00000001 /* RW--V */ | ||
254 | #define NV_PRAMDAC_GENERAL_CONTROL_565_MODE 12:12 /* RWIVF */ | ||
255 | #define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_NOTSEL 0x00000000 /* RWI-V */ | ||
256 | #define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_SEL 0x00000001 /* RW--V */ | ||
257 | #define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL 16:16 /* RWIVF */ | ||
258 | #define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF 0x00000000 /* RWI-V */ | ||
259 | #define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON 0x00000001 /* RW--V */ | ||
260 | #define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION 17:17 /* RWIVF */ | ||
261 | #define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM 0x00000000 /* RWI-V */ | ||
262 | #define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM 0x00000001 /* RW--V */ | ||
263 | #define NV_PRAMDAC_GENERAL_CONTROL_BPC 20:20 /* RWIVF */ | ||
264 | #define NV_PRAMDAC_GENERAL_CONTROL_BPC_6BITS 0x00000000 /* RWI-V */ | ||
265 | #define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS 0x00000001 /* RW--V */ | ||
266 | #define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP 24:24 /* RWIVF */ | ||
267 | #define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS 0x00000000 /* RWI-V */ | ||
268 | #define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN 0x00000001 /* RW--V */ | ||
269 | #define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK 28:28 /* RWIVF */ | ||
270 | #define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN 0x00000000 /* RWI-V */ | ||
271 | #define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS 0x00000001 /* RW--V */ | ||
272 | |||
273 | /* Master Control */ | ||
274 | #define NV_PMC 0x00000FFF:0x00000000 /* RW--D */ | ||
275 | #define NV_PMC_BOOT_0 0x00000000 /* R--4R */ | ||
276 | #define NV_PMC_BOOT_0_MINOR_REVISION 3:0 /* C--VF */ | ||
277 | #define NV_PMC_BOOT_0_MINOR_REVISION_0 0x00000000 /* C---V */ | ||
278 | #define NV_PMC_BOOT_0_MAJOR_REVISION 7:4 /* C--VF */ | ||
279 | #define NV_PMC_BOOT_0_MAJOR_REVISION_A 0x00000000 /* C---V */ | ||
280 | #define NV_PMC_BOOT_0_MAJOR_REVISION_B 0x00000001 /* ----V */ | ||
281 | #define NV_PMC_BOOT_0_IMPLEMENTATION 11:8 /* C--VF */ | ||
282 | #define NV_PMC_BOOT_0_IMPLEMENTATION_NV4_0 0x00000000 /* C---V */ | ||
283 | #define NV_PMC_BOOT_0_ARCHITECTURE 15:12 /* C--VF */ | ||
284 | #define NV_PMC_BOOT_0_ARCHITECTURE_NV0 0x00000000 /* ----V */ | ||
285 | #define NV_PMC_BOOT_0_ARCHITECTURE_NV1 0x00000001 /* ----V */ | ||
286 | #define NV_PMC_BOOT_0_ARCHITECTURE_NV2 0x00000002 /* ----V */ | ||
287 | #define NV_PMC_BOOT_0_ARCHITECTURE_NV3 0x00000003 /* ----V */ | ||
288 | #define NV_PMC_BOOT_0_ARCHITECTURE_NV4 0x00000004 /* C---V */ | ||
289 | #define NV_PMC_BOOT_0_FIB_REVISION 19:16 /* C--VF */ | ||
290 | #define NV_PMC_BOOT_0_FIB_REVISION_0 0x00000000 /* C---V */ | ||
291 | #define NV_PMC_BOOT_0_MASK_REVISION 23:20 /* C--VF */ | ||
292 | #define NV_PMC_BOOT_0_MASK_REVISION_A 0x00000000 /* C---V */ | ||
293 | #define NV_PMC_BOOT_0_MASK_REVISION_B 0x00000001 /* ----V */ | ||
294 | #define NV_PMC_BOOT_0_MANUFACTURER 27:24 /* C--UF */ | ||
295 | #define NV_PMC_BOOT_0_MANUFACTURER_NVIDIA 0x00000000 /* C---V */ | ||
296 | #define NV_PMC_BOOT_0_FOUNDRY 31:28 /* C--VF */ | ||
297 | #define NV_PMC_BOOT_0_FOUNDRY_SGS 0x00000000 /* ----V */ | ||
298 | #define NV_PMC_BOOT_0_FOUNDRY_HELIOS 0x00000001 /* ----V */ | ||
299 | #define NV_PMC_BOOT_0_FOUNDRY_TSMC 0x00000002 /* C---V */ | ||
300 | #define NV_PMC_INTR_0 0x00000100 /* RW-4R */ | ||
301 | #define NV_PMC_INTR_0_PMEDIA 4:4 /* R--VF */ | ||
302 | #define NV_PMC_INTR_0_PMEDIA_NOT_PENDING 0x00000000 /* R---V */ | ||
303 | #define NV_PMC_INTR_0_PMEDIA_PENDING 0x00000001 /* R---V */ | ||
304 | #define NV_PMC_INTR_0_PFIFO 8:8 /* R--VF */ | ||
305 | #define NV_PMC_INTR_0_PFIFO_NOT_PENDING 0x00000000 /* R---V */ | ||
306 | #define NV_PMC_INTR_0_PFIFO_PENDING 0x00000001 /* R---V */ | ||
307 | #define NV_PMC_INTR_0_PGRAPH 12:12 /* R--VF */ | ||
308 | #define NV_PMC_INTR_0_PGRAPH_NOT_PENDING 0x00000000 /* R---V */ | ||
309 | #define NV_PMC_INTR_0_PGRAPH_PENDING 0x00000001 /* R---V */ | ||
310 | #define NV_PMC_INTR_0_PVIDEO 16:16 /* R--VF */ | ||
311 | #define NV_PMC_INTR_0_PVIDEO_NOT_PENDING 0x00000000 /* R---V */ | ||
312 | #define NV_PMC_INTR_0_PVIDEO_PENDING 0x00000001 /* R---V */ | ||
313 | #define NV_PMC_INTR_0_PTIMER 20:20 /* R--VF */ | ||
314 | #define NV_PMC_INTR_0_PTIMER_NOT_PENDING 0x00000000 /* R---V */ | ||
315 | #define NV_PMC_INTR_0_PTIMER_PENDING 0x00000001 /* R---V */ | ||
316 | #define NV_PMC_INTR_0_PCRTC 24:24 /* R--VF */ | ||
317 | #define NV_PMC_INTR_0_PCRTC_NOT_PENDING 0x00000000 /* R---V */ | ||
318 | #define NV_PMC_INTR_0_PCRTC_PENDING 0x00000001 /* R---V */ | ||
319 | #define NV_PMC_INTR_0_PBUS 28:28 /* R--VF */ | ||
320 | #define NV_PMC_INTR_0_PBUS_NOT_PENDING 0x00000000 /* R---V */ | ||
321 | #define NV_PMC_INTR_0_PBUS_PENDING 0x00000001 /* R---V */ | ||
322 | #define NV_PMC_INTR_0_SOFTWARE 31:31 /* RWIVF */ | ||
323 | #define NV_PMC_INTR_0_SOFTWARE_NOT_PENDING 0x00000000 /* RWI-V */ | ||
324 | #define NV_PMC_INTR_0_SOFTWARE_PENDING 0x00000001 /* RW--V */ | ||
325 | #define NV_PMC_INTR_EN_0 0x00000140 /* RW-4R */ | ||
326 | #define NV_PMC_INTR_EN_0_INTA 1:0 /* RWIVF */ | ||
327 | #define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000 /* RWI-V */ | ||
328 | #define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001 /* RW--V */ | ||
329 | #define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002 /* RW--V */ | ||
330 | #define NV_PMC_INTR_READ_0 0x00000160 /* R--4R */ | ||
331 | #define NV_PMC_INTR_READ_0_INTA 0:0 /* R--VF */ | ||
332 | #define NV_PMC_INTR_READ_0_INTA_LOW 0x00000000 /* R---V */ | ||
333 | #define NV_PMC_INTR_READ_0_INTA_HIGH 0x00000001 /* R---V */ | ||
334 | #define NV_PMC_ENABLE 0x00000200 /* RW-4R */ | ||
335 | #define NV_PMC_ENABLE_PMEDIA 4:4 /* RWIVF */ | ||
336 | #define NV_PMC_ENABLE_PMEDIA_DISABLED 0x00000000 /* RWI-V */ | ||
337 | #define NV_PMC_ENABLE_PMEDIA_ENABLED 0x00000001 /* RW--V */ | ||
338 | #define NV_PMC_ENABLE_PFIFO 8:8 /* RWIVF */ | ||
339 | #define NV_PMC_ENABLE_PFIFO_DISABLED 0x00000000 /* RWI-V */ | ||
340 | #define NV_PMC_ENABLE_PFIFO_ENABLED 0x00000001 /* RW--V */ | ||
341 | #define NV_PMC_ENABLE_PGRAPH 12:12 /* RWIVF */ | ||
342 | #define NV_PMC_ENABLE_PGRAPH_DISABLED 0x00000000 /* RWI-V */ | ||
343 | #define NV_PMC_ENABLE_PGRAPH_ENABLED 0x00000001 /* RW--V */ | ||
344 | #define NV_PMC_ENABLE_PPMI 16:16 /* RWIVF */ | ||
345 | #define NV_PMC_ENABLE_PPMI_DISABLED 0x00000000 /* RWI-V */ | ||
346 | #define NV_PMC_ENABLE_PPMI_ENABLED 0x00000001 /* RW--V */ | ||
347 | #define NV_PMC_ENABLE_PFB 20:20 /* RWIVF */ | ||
348 | #define NV_PMC_ENABLE_PFB_DISABLED 0x00000000 /* RW--V */ | ||
349 | #define NV_PMC_ENABLE_PFB_ENABLED 0x00000001 /* RWI-V */ | ||
350 | #define NV_PMC_ENABLE_PCRTC 24:24 /* RWIVF */ | ||
351 | #define NV_PMC_ENABLE_PCRTC_DISABLED 0x00000000 /* RW--V */ | ||
352 | #define NV_PMC_ENABLE_PCRTC_ENABLED 0x00000001 /* RWI-V */ | ||
353 | #define NV_PMC_ENABLE_PVIDEO 28:28 /* RWIVF */ | ||
354 | #define NV_PMC_ENABLE_PVIDEO_DISABLED 0x00000000 /* RWI-V */ | ||
355 | #define NV_PMC_ENABLE_PVIDEO_ENABLED 0x00000001 /* RW--V */ | ||
356 | |||
357 | /* dev_timer.ref */ | ||
358 | #define NV_PTIMER 0x00009FFF:0x00009000 /* RW--D */ | ||
359 | #define NV_PTIMER_INTR_0 0x00009100 /* RW-4R */ | ||
360 | #define NV_PTIMER_INTR_0_ALARM 0:0 /* RWXVF */ | ||
361 | #define NV_PTIMER_INTR_0_ALARM_NOT_PENDING 0x00000000 /* R---V */ | ||
362 | #define NV_PTIMER_INTR_0_ALARM_PENDING 0x00000001 /* R---V */ | ||
363 | #define NV_PTIMER_INTR_0_ALARM_RESET 0x00000001 /* -W--V */ | ||
364 | #define NV_PTIMER_INTR_EN_0 0x00009140 /* RW-4R */ | ||
365 | #define NV_PTIMER_INTR_EN_0_ALARM 0:0 /* RWIVF */ | ||
366 | #define NV_PTIMER_INTR_EN_0_ALARM_DISABLED 0x00000000 /* RWI-V */ | ||
367 | #define NV_PTIMER_INTR_EN_0_ALARM_ENABLED 0x00000001 /* RW--V */ | ||
368 | #define NV_PTIMER_NUMERATOR 0x00009200 /* RW-4R */ | ||
369 | #define NV_PTIMER_NUMERATOR_VALUE 15:0 /* RWIUF */ | ||
370 | #define NV_PTIMER_NUMERATOR_VALUE_0 0x00000000 /* RWI-V */ | ||
371 | #define NV_PTIMER_DENOMINATOR 0x00009210 /* RW-4R */ | ||
372 | #define NV_PTIMER_DENOMINATOR_VALUE 15:0 /* RWIUF */ | ||
373 | #define NV_PTIMER_DENOMINATOR_VALUE_0 0x00000000 /* RWI-V */ | ||
374 | #define NV_PTIMER_TIME_0 0x00009400 /* RW-4R */ | ||
375 | #define NV_PTIMER_TIME_0_NSEC 31:5 /* RWXUF */ | ||
376 | #define NV_PTIMER_TIME_1 0x00009410 /* RW-4R */ | ||
377 | #define NV_PTIMER_TIME_1_NSEC 28:0 /* RWXUF */ | ||
378 | #define NV_PTIMER_ALARM_0 0x00009420 /* RW-4R */ | ||
379 | #define NV_PTIMER_ALARM_0_NSEC 31:5 /* RWXUF */ | ||
380 | |||
381 | /* dev_fifo.ref */ | ||
382 | #define NV_PFIFO 0x00003FFF:0x00002000 /* RW--D */ | ||
383 | #define NV_PFIFO_DELAY_0 0x00002040 /* RW-4R */ | ||
384 | #define NV_PFIFO_DELAY_0_WAIT_RETRY 9:0 /* RWIUF */ | ||
385 | #define NV_PFIFO_DELAY_0_WAIT_RETRY_0 0x00000000 /* RWI-V */ | ||
386 | #define NV_PFIFO_DMA_TIMESLICE 0x00002044 /* RW-4R */ | ||
387 | #define NV_PFIFO_DMA_TIMESLICE_SELECT 16:0 /* RWIUF */ | ||
388 | #define NV_PFIFO_DMA_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */ | ||
389 | #define NV_PFIFO_DMA_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */ | ||
390 | #define NV_PFIFO_DMA_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */ | ||
391 | #define NV_PFIFO_DMA_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */ | ||
392 | #define NV_PFIFO_DMA_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */ | ||
393 | #define NV_PFIFO_DMA_TIMESLICE_TIMEOUT 24:24 /* RWIUF */ | ||
394 | #define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */ | ||
395 | #define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */ | ||
396 | #define NV_PFIFO_PIO_TIMESLICE 0x00002048 /* RW-4R */ | ||
397 | #define NV_PFIFO_PIO_TIMESLICE_SELECT 16:0 /* RWIUF */ | ||
398 | #define NV_PFIFO_PIO_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */ | ||
399 | #define NV_PFIFO_PIO_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */ | ||
400 | #define NV_PFIFO_PIO_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */ | ||
401 | #define NV_PFIFO_PIO_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */ | ||
402 | #define NV_PFIFO_PIO_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */ | ||
403 | #define NV_PFIFO_PIO_TIMESLICE_TIMEOUT 24:24 /* RWIUF */ | ||
404 | #define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */ | ||
405 | #define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */ | ||
406 | #define NV_PFIFO_TIMESLICE 0x0000204C /* RW-4R */ | ||
407 | #define NV_PFIFO_TIMESLICE_TIMER 17:0 /* RWIUF */ | ||
408 | #define NV_PFIFO_TIMESLICE_TIMER_EXPIRED 0x0003FFFF /* RWI-V */ | ||
409 | #define NV_PFIFO_NEXT_CHANNEL 0x00002050 /* RW-4R */ | ||
410 | #define NV_PFIFO_NEXT_CHANNEL_CHID 3:0 /* RWXUF */ | ||
411 | #define NV_PFIFO_NEXT_CHANNEL_MODE 8:8 /* RWXVF */ | ||
412 | #define NV_PFIFO_NEXT_CHANNEL_MODE_PIO 0x00000000 /* RW--V */ | ||
413 | #define NV_PFIFO_NEXT_CHANNEL_MODE_DMA 0x00000001 /* RW--V */ | ||
414 | #define NV_PFIFO_NEXT_CHANNEL_SWITCH 12:12 /* RWIVF */ | ||
415 | #define NV_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING 0x00000000 /* RWI-V */ | ||
416 | #define NV_PFIFO_NEXT_CHANNEL_SWITCH_PENDING 0x00000001 /* RW--V */ | ||
417 | #define NV_PFIFO_DEBUG_0 0x00002080 /* R--4R */ | ||
418 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR0 0:0 /* R-XVF */ | ||
419 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING 0x00000000 /* R---V */ | ||
420 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING 0x00000001 /* R---V */ | ||
421 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR1 4:4 /* R-XVF */ | ||
422 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING 0x00000000 /* R---V */ | ||
423 | #define NV_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING 0x00000001 /* R---V */ | ||
424 | #define NV_PFIFO_INTR_0 0x00002100 /* RW-4R */ | ||
425 | #define NV_PFIFO_INTR_0_CACHE_ERROR 0:0 /* RWXVF */ | ||
426 | #define NV_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING 0x00000000 /* R---V */ | ||
427 | #define NV_PFIFO_INTR_0_CACHE_ERROR_PENDING 0x00000001 /* R---V */ | ||
428 | #define NV_PFIFO_INTR_0_CACHE_ERROR_RESET 0x00000001 /* -W--V */ | ||
429 | #define NV_PFIFO_INTR_0_RUNOUT 4:4 /* RWXVF */ | ||
430 | #define NV_PFIFO_INTR_0_RUNOUT_NOT_PENDING 0x00000000 /* R---V */ | ||
431 | #define NV_PFIFO_INTR_0_RUNOUT_PENDING 0x00000001 /* R---V */ | ||
432 | #define NV_PFIFO_INTR_0_RUNOUT_RESET 0x00000001 /* -W--V */ | ||
433 | #define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW 8:8 /* RWXVF */ | ||
434 | #define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING 0x00000000 /* R---V */ | ||
435 | #define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING 0x00000001 /* R---V */ | ||
436 | #define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET 0x00000001 /* -W--V */ | ||
437 | #define NV_PFIFO_INTR_0_DMA_PUSHER 12:12 /* RWXVF */ | ||
438 | #define NV_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING 0x00000000 /* R---V */ | ||
439 | #define NV_PFIFO_INTR_0_DMA_PUSHER_PENDING 0x00000001 /* R---V */ | ||
440 | #define NV_PFIFO_INTR_0_DMA_PUSHER_RESET 0x00000001 /* -W--V */ | ||
441 | #define NV_PFIFO_INTR_0_DMA_PT 16:16 /* RWXVF */ | ||
442 | #define NV_PFIFO_INTR_0_DMA_PT_NOT_PENDING 0x00000000 /* R---V */ | ||
443 | #define NV_PFIFO_INTR_0_DMA_PT_PENDING 0x00000001 /* R---V */ | ||
444 | #define NV_PFIFO_INTR_0_DMA_PT_RESET 0x00000001 /* -W--V */ | ||
445 | #define NV_PFIFO_INTR_EN_0 0x00002140 /* RW-4R */ | ||
446 | #define NV_PFIFO_INTR_EN_0_CACHE_ERROR 0:0 /* RWIVF */ | ||
447 | #define NV_PFIFO_INTR_EN_0_CACHE_ERROR_DISABLED 0x00000000 /* RWI-V */ | ||
448 | #define NV_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED 0x00000001 /* RW--V */ | ||
449 | #define NV_PFIFO_INTR_EN_0_RUNOUT 4:4 /* RWIVF */ | ||
450 | #define NV_PFIFO_INTR_EN_0_RUNOUT_DISABLED 0x00000000 /* RWI-V */ | ||
451 | #define NV_PFIFO_INTR_EN_0_RUNOUT_ENABLED 0x00000001 /* RW--V */ | ||
452 | #define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW 8:8 /* RWIVF */ | ||
453 | #define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_DISABLED 0x00000000 /* RWI-V */ | ||
454 | #define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED 0x00000001 /* RW--V */ | ||
455 | #define NV_PFIFO_INTR_EN_0_DMA_PUSHER 12:12 /* RWIVF */ | ||
456 | #define NV_PFIFO_INTR_EN_0_DMA_PUSHER_DISABLED 0x00000000 /* RWI-V */ | ||
457 | #define NV_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED 0x00000001 /* RW--V */ | ||
458 | #define NV_PFIFO_INTR_EN_0_DMA_PT 16:16 /* RWIVF */ | ||
459 | #define NV_PFIFO_INTR_EN_0_DMA_PT_DISABLED 0x00000000 /* RWI-V */ | ||
460 | #define NV_PFIFO_INTR_EN_0_DMA_PT_ENABLED 0x00000001 /* RW--V */ | ||
461 | #define NV_PFIFO_RAMHT 0x00002210 /* RW-4R */ | ||
462 | #define NV_PFIFO_RAMHT_BASE_ADDRESS 8:4 /* RWIUF */ | ||
463 | #define NV_PFIFO_RAMHT_BASE_ADDRESS_10000 0x00000010 /* RWI-V */ | ||
464 | #define NV_PFIFO_RAMHT_SIZE 17:16 /* RWIUF */ | ||
465 | #define NV_PFIFO_RAMHT_SIZE_4K 0x00000000 /* RWI-V */ | ||
466 | #define NV_PFIFO_RAMHT_SIZE_8K 0x00000001 /* RW--V */ | ||
467 | #define NV_PFIFO_RAMHT_SIZE_16K 0x00000002 /* RW--V */ | ||
468 | #define NV_PFIFO_RAMHT_SIZE_32K 0x00000003 /* RW--V */ | ||
469 | #define NV_PFIFO_RAMHT_SEARCH 25:24 /* RWIUF */ | ||
470 | #define NV_PFIFO_RAMHT_SEARCH_16 0x00000000 /* RWI-V */ | ||
471 | #define NV_PFIFO_RAMHT_SEARCH_32 0x00000001 /* RW--V */ | ||
472 | #define NV_PFIFO_RAMHT_SEARCH_64 0x00000002 /* RW--V */ | ||
473 | #define NV_PFIFO_RAMHT_SEARCH_128 0x00000003 /* RW--V */ | ||
474 | #define NV_PFIFO_RAMFC 0x00002214 /* RW-4R */ | ||
475 | #define NV_PFIFO_RAMFC_BASE_ADDRESS 8:1 /* RWIUF */ | ||
476 | #define NV_PFIFO_RAMFC_BASE_ADDRESS_11000 0x00000088 /* RWI-V */ | ||
477 | #define NV_PFIFO_RAMRO 0x00002218 /* RW-4R */ | ||
478 | #define NV_PFIFO_RAMRO_BASE_ADDRESS 8:1 /* RWIUF */ | ||
479 | #define NV_PFIFO_RAMRO_BASE_ADDRESS_11200 0x00000089 /* RWI-V */ | ||
480 | #define NV_PFIFO_RAMRO_BASE_ADDRESS_12000 0x00000090 /* RW--V */ | ||
481 | #define NV_PFIFO_RAMRO_SIZE 16:16 /* RWIVF */ | ||
482 | #define NV_PFIFO_RAMRO_SIZE_512 0x00000000 /* RWI-V */ | ||
483 | #define NV_PFIFO_RAMRO_SIZE_8K 0x00000001 /* RW--V */ | ||
484 | #define NV_PFIFO_CACHES 0x00002500 /* RW-4R */ | ||
485 | #define NV_PFIFO_CACHES_REASSIGN 0:0 /* RWIVF */ | ||
486 | #define NV_PFIFO_CACHES_REASSIGN_DISABLED 0x00000000 /* RWI-V */ | ||
487 | #define NV_PFIFO_CACHES_REASSIGN_ENABLED 0x00000001 /* RW--V */ | ||
488 | #define NV_PFIFO_CACHES_DMA_SUSPEND 4:4 /* R--VF */ | ||
489 | #define NV_PFIFO_CACHES_DMA_SUSPEND_IDLE 0x00000000 /* R---V */ | ||
490 | #define NV_PFIFO_CACHES_DMA_SUSPEND_BUSY 0x00000001 /* R---V */ | ||
491 | #define NV_PFIFO_MODE 0x00002504 /* RW-4R */ | ||
492 | #define NV_PFIFO_MODE_CHANNEL_0 0:0 /* RWIVF */ | ||
493 | #define NV_PFIFO_MODE_CHANNEL_0_PIO 0x00000000 /* RWI-V */ | ||
494 | #define NV_PFIFO_MODE_CHANNEL_0_DMA 0x00000001 /* RW--V */ | ||
495 | #define NV_PFIFO_MODE_CHANNEL_1 1:1 /* RWIVF */ | ||
496 | #define NV_PFIFO_MODE_CHANNEL_1_PIO 0x00000000 /* RWI-V */ | ||
497 | #define NV_PFIFO_MODE_CHANNEL_1_DMA 0x00000001 /* RW--V */ | ||
498 | #define NV_PFIFO_MODE_CHANNEL_2 2:2 /* RWIVF */ | ||
499 | #define NV_PFIFO_MODE_CHANNEL_2_PIO 0x00000000 /* RWI-V */ | ||
500 | #define NV_PFIFO_MODE_CHANNEL_2_DMA 0x00000001 /* RW--V */ | ||
501 | #define NV_PFIFO_MODE_CHANNEL_3 3:3 /* RWIVF */ | ||
502 | #define NV_PFIFO_MODE_CHANNEL_3_PIO 0x00000000 /* RWI-V */ | ||
503 | #define NV_PFIFO_MODE_CHANNEL_3_DMA 0x00000001 /* RW--V */ | ||
504 | #define NV_PFIFO_MODE_CHANNEL_4 4:4 /* RWIVF */ | ||
505 | #define NV_PFIFO_MODE_CHANNEL_4_PIO 0x00000000 /* RWI-V */ | ||
506 | #define NV_PFIFO_MODE_CHANNEL_4_DMA 0x00000001 /* RW--V */ | ||
507 | #define NV_PFIFO_MODE_CHANNEL_5 5:5 /* RWIVF */ | ||
508 | #define NV_PFIFO_MODE_CHANNEL_5_PIO 0x00000000 /* RWI-V */ | ||
509 | #define NV_PFIFO_MODE_CHANNEL_5_DMA 0x00000001 /* RW--V */ | ||
510 | #define NV_PFIFO_MODE_CHANNEL_6 6:6 /* RWIVF */ | ||
511 | #define NV_PFIFO_MODE_CHANNEL_6_PIO 0x00000000 /* RWI-V */ | ||
512 | #define NV_PFIFO_MODE_CHANNEL_6_DMA 0x00000001 /* RW--V */ | ||
513 | #define NV_PFIFO_MODE_CHANNEL_7 7:7 /* RWIVF */ | ||
514 | #define NV_PFIFO_MODE_CHANNEL_7_PIO 0x00000000 /* RWI-V */ | ||
515 | #define NV_PFIFO_MODE_CHANNEL_7_DMA 0x00000001 /* RW--V */ | ||
516 | #define NV_PFIFO_MODE_CHANNEL_8 8:8 /* RWIVF */ | ||
517 | #define NV_PFIFO_MODE_CHANNEL_8_PIO 0x00000000 /* RWI-V */ | ||
518 | #define NV_PFIFO_MODE_CHANNEL_8_DMA 0x00000001 /* RW--V */ | ||
519 | #define NV_PFIFO_MODE_CHANNEL_9 9:9 /* RWIVF */ | ||
520 | #define NV_PFIFO_MODE_CHANNEL_9_PIO 0x00000000 /* RWI-V */ | ||
521 | #define NV_PFIFO_MODE_CHANNEL_9_DMA 0x00000001 /* RW--V */ | ||
522 | #define NV_PFIFO_MODE_CHANNEL_10 10:10 /* RWIVF */ | ||
523 | #define NV_PFIFO_MODE_CHANNEL_10_PIO 0x00000000 /* RWI-V */ | ||
524 | #define NV_PFIFO_MODE_CHANNEL_10_DMA 0x00000001 /* RW--V */ | ||
525 | #define NV_PFIFO_MODE_CHANNEL_11 11:11 /* RWIVF */ | ||
526 | #define NV_PFIFO_MODE_CHANNEL_11_PIO 0x00000000 /* RWI-V */ | ||
527 | #define NV_PFIFO_MODE_CHANNEL_11_DMA 0x00000001 /* RW--V */ | ||
528 | #define NV_PFIFO_MODE_CHANNEL_12 12:12 /* RWIVF */ | ||
529 | #define NV_PFIFO_MODE_CHANNEL_12_PIO 0x00000000 /* RWI-V */ | ||
530 | #define NV_PFIFO_MODE_CHANNEL_12_DMA 0x00000001 /* RW--V */ | ||
531 | #define NV_PFIFO_MODE_CHANNEL_13 13:13 /* RWIVF */ | ||
532 | #define NV_PFIFO_MODE_CHANNEL_13_PIO 0x00000000 /* RWI-V */ | ||
533 | #define NV_PFIFO_MODE_CHANNEL_13_DMA 0x00000001 /* RW--V */ | ||
534 | #define NV_PFIFO_MODE_CHANNEL_14 14:14 /* RWIVF */ | ||
535 | #define NV_PFIFO_MODE_CHANNEL_14_PIO 0x00000000 /* RWI-V */ | ||
536 | #define NV_PFIFO_MODE_CHANNEL_14_DMA 0x00000001 /* RW--V */ | ||
537 | #define NV_PFIFO_MODE_CHANNEL_15 15:15 /* RWIVF */ | ||
538 | #define NV_PFIFO_MODE_CHANNEL_15_PIO 0x00000000 /* RWI-V */ | ||
539 | #define NV_PFIFO_MODE_CHANNEL_15_DMA 0x00000001 /* RW--V */ | ||
540 | #define NV_PFIFO_DMA 0x00002508 /* RW-4R */ | ||
541 | #define NV_PFIFO_DMA_CHANNEL_0 0:0 /* RWIVF */ | ||
542 | #define NV_PFIFO_DMA_CHANNEL_0_NOT_PENDING 0x00000000 /* RWI-V */ | ||
543 | #define NV_PFIFO_DMA_CHANNEL_0_PENDING 0x00000001 /* RW--V */ | ||
544 | #define NV_PFIFO_DMA_CHANNEL_1 1:1 /* RWIVF */ | ||
545 | #define NV_PFIFO_DMA_CHANNEL_1_NOT_PENDING 0x00000000 /* RWI-V */ | ||
546 | #define NV_PFIFO_DMA_CHANNEL_1_PENDING 0x00000001 /* RW--V */ | ||
547 | #define NV_PFIFO_DMA_CHANNEL_2 2:2 /* RWIVF */ | ||
548 | #define NV_PFIFO_DMA_CHANNEL_2_NOT_PENDING 0x00000000 /* RWI-V */ | ||
549 | #define NV_PFIFO_DMA_CHANNEL_2_PENDING 0x00000001 /* RW--V */ | ||
550 | #define NV_PFIFO_DMA_CHANNEL_3 3:3 /* RWIVF */ | ||
551 | #define NV_PFIFO_DMA_CHANNEL_3_NOT_PENDING 0x00000000 /* RWI-V */ | ||
552 | #define NV_PFIFO_DMA_CHANNEL_3_PENDING 0x00000001 /* RW--V */ | ||
553 | #define NV_PFIFO_DMA_CHANNEL_4 4:4 /* RWIVF */ | ||
554 | #define NV_PFIFO_DMA_CHANNEL_4_NOT_PENDING 0x00000000 /* RWI-V */ | ||
555 | #define NV_PFIFO_DMA_CHANNEL_4_PENDING 0x00000001 /* RW--V */ | ||
556 | #define NV_PFIFO_DMA_CHANNEL_5 5:5 /* RWIVF */ | ||
557 | #define NV_PFIFO_DMA_CHANNEL_5_NOT_PENDING 0x00000000 /* RWI-V */ | ||
558 | #define NV_PFIFO_DMA_CHANNEL_5_PENDING 0x00000001 /* RW--V */ | ||
559 | #define NV_PFIFO_DMA_CHANNEL_6 6:6 /* RWIVF */ | ||
560 | #define NV_PFIFO_DMA_CHANNEL_6_NOT_PENDING 0x00000000 /* RWI-V */ | ||
561 | #define NV_PFIFO_DMA_CHANNEL_6_PENDING 0x00000001 /* RW--V */ | ||
562 | #define NV_PFIFO_DMA_CHANNEL_7 7:7 /* RWIVF */ | ||
563 | #define NV_PFIFO_DMA_CHANNEL_7_NOT_PENDING 0x00000000 /* RWI-V */ | ||
564 | #define NV_PFIFO_DMA_CHANNEL_7_PENDING 0x00000001 /* RW--V */ | ||
565 | #define NV_PFIFO_DMA_CHANNEL_8 8:8 /* RWIVF */ | ||
566 | #define NV_PFIFO_DMA_CHANNEL_8_NOT_PENDING 0x00000000 /* RWI-V */ | ||
567 | #define NV_PFIFO_DMA_CHANNEL_8_PENDING 0x00000001 /* RW--V */ | ||
568 | #define NV_PFIFO_DMA_CHANNEL_9 9:9 /* RWIVF */ | ||
569 | #define NV_PFIFO_DMA_CHANNEL_9_NOT_PENDING 0x00000000 /* RWI-V */ | ||
570 | #define NV_PFIFO_DMA_CHANNEL_9_PENDING 0x00000001 /* RW--V */ | ||
571 | #define NV_PFIFO_DMA_CHANNEL_10 10:10 /* RWIVF */ | ||
572 | #define NV_PFIFO_DMA_CHANNEL_10_NOT_PENDING 0x00000000 /* RWI-V */ | ||
573 | #define NV_PFIFO_DMA_CHANNEL_10_PENDING 0x00000001 /* RW--V */ | ||
574 | #define NV_PFIFO_DMA_CHANNEL_11 11:11 /* RWIVF */ | ||
575 | #define NV_PFIFO_DMA_CHANNEL_11_NOT_PENDING 0x00000000 /* RWI-V */ | ||
576 | #define NV_PFIFO_DMA_CHANNEL_11_PENDING 0x00000001 /* RW--V */ | ||
577 | #define NV_PFIFO_DMA_CHANNEL_12 12:12 /* RWIVF */ | ||
578 | #define NV_PFIFO_DMA_CHANNEL_12_NOT_PENDING 0x00000000 /* RWI-V */ | ||
579 | #define NV_PFIFO_DMA_CHANNEL_12_PENDING 0x00000001 /* RW--V */ | ||
580 | #define NV_PFIFO_DMA_CHANNEL_13 13:13 /* RWIVF */ | ||
581 | #define NV_PFIFO_DMA_CHANNEL_13_NOT_PENDING 0x00000000 /* RWI-V */ | ||
582 | #define NV_PFIFO_DMA_CHANNEL_13_PENDING 0x00000001 /* RW--V */ | ||
583 | #define NV_PFIFO_DMA_CHANNEL_14 14:14 /* RWIVF */ | ||
584 | #define NV_PFIFO_DMA_CHANNEL_14_NOT_PENDING 0x00000000 /* RWI-V */ | ||
585 | #define NV_PFIFO_DMA_CHANNEL_14_PENDING 0x00000001 /* RW--V */ | ||
586 | #define NV_PFIFO_DMA_CHANNEL_15 15:15 /* RWIVF */ | ||
587 | #define NV_PFIFO_DMA_CHANNEL_15_NOT_PENDING 0x00000000 /* RWI-V */ | ||
588 | #define NV_PFIFO_DMA_CHANNEL_15_PENDING 0x00000001 /* RW--V */ | ||
589 | #define NV_PFIFO_SIZE 0x0000250C /* RW-4R */ | ||
590 | #define NV_PFIFO_SIZE_CHANNEL_0 0:0 /* RWIVF */ | ||
591 | #define NV_PFIFO_SIZE_CHANNEL_0_124_BYTES 0x00000000 /* RWI-V */ | ||
592 | #define NV_PFIFO_SIZE_CHANNEL_0_512_BYTES 0x00000001 /* RW--V */ | ||
593 | #define NV_PFIFO_SIZE_CHANNEL_1 1:1 /* RWIVF */ | ||
594 | #define NV_PFIFO_SIZE_CHANNEL_1_124_BYTES 0x00000000 /* RWI-V */ | ||
595 | #define NV_PFIFO_SIZE_CHANNEL_1_512_BYTES 0x00000001 /* RW--V */ | ||
596 | #define NV_PFIFO_SIZE_CHANNEL_2 2:2 /* RWIVF */ | ||
597 | #define NV_PFIFO_SIZE_CHANNEL_2_124_BYTES 0x00000000 /* RWI-V */ | ||
598 | #define NV_PFIFO_SIZE_CHANNEL_2_512_BYTES 0x00000001 /* RW--V */ | ||
599 | #define NV_PFIFO_SIZE_CHANNEL_3 3:3 /* RWIVF */ | ||
600 | #define NV_PFIFO_SIZE_CHANNEL_3_124_BYTES 0x00000000 /* RWI-V */ | ||
601 | #define NV_PFIFO_SIZE_CHANNEL_3_512_BYTES 0x00000001 /* RW--V */ | ||
602 | #define NV_PFIFO_SIZE_CHANNEL_4 4:4 /* RWIVF */ | ||
603 | #define NV_PFIFO_SIZE_CHANNEL_4_124_BYTES 0x00000000 /* RWI-V */ | ||
604 | #define NV_PFIFO_SIZE_CHANNEL_4_512_BYTES 0x00000001 /* RW--V */ | ||
605 | #define NV_PFIFO_SIZE_CHANNEL_5 5:5 /* RWIVF */ | ||
606 | #define NV_PFIFO_SIZE_CHANNEL_5_124_BYTES 0x00000000 /* RWI-V */ | ||
607 | #define NV_PFIFO_SIZE_CHANNEL_5_512_BYTES 0x00000001 /* RW--V */ | ||
608 | #define NV_PFIFO_SIZE_CHANNEL_6 6:6 /* RWIVF */ | ||
609 | #define NV_PFIFO_SIZE_CHANNEL_6_124_BYTES 0x00000000 /* RWI-V */ | ||
610 | #define NV_PFIFO_SIZE_CHANNEL_6_512_BYTES 0x00000001 /* RW--V */ | ||
611 | #define NV_PFIFO_SIZE_CHANNEL_7 7:7 /* RWIVF */ | ||
612 | #define NV_PFIFO_SIZE_CHANNEL_7_124_BYTES 0x00000000 /* RWI-V */ | ||
613 | #define NV_PFIFO_SIZE_CHANNEL_7_512_BYTES 0x00000001 /* RW--V */ | ||
614 | #define NV_PFIFO_SIZE_CHANNEL_8 8:8 /* RWIVF */ | ||
615 | #define NV_PFIFO_SIZE_CHANNEL_8_124_BYTES 0x00000000 /* RWI-V */ | ||
616 | #define NV_PFIFO_SIZE_CHANNEL_8_512_BYTES 0x00000001 /* RW--V */ | ||
617 | #define NV_PFIFO_SIZE_CHANNEL_9 9:9 /* RWIVF */ | ||
618 | #define NV_PFIFO_SIZE_CHANNEL_9_124_BYTES 0x00000000 /* RWI-V */ | ||
619 | #define NV_PFIFO_SIZE_CHANNEL_9_512_BYTES 0x00000001 /* RW--V */ | ||
620 | #define NV_PFIFO_SIZE_CHANNEL_10 10:10 /* RWIVF */ | ||
621 | #define NV_PFIFO_SIZE_CHANNEL_10_124_BYTES 0x00000000 /* RWI-V */ | ||
622 | #define NV_PFIFO_SIZE_CHANNEL_10_512_BYTES 0x00000001 /* RW--V */ | ||
623 | #define NV_PFIFO_SIZE_CHANNEL_11 11:11 /* RWIVF */ | ||
624 | #define NV_PFIFO_SIZE_CHANNEL_11_124_BYTES 0x00000000 /* RWI-V */ | ||
625 | #define NV_PFIFO_SIZE_CHANNEL_11_512_BYTES 0x00000001 /* RW--V */ | ||
626 | #define NV_PFIFO_SIZE_CHANNEL_12 12:12 /* RWIVF */ | ||
627 | #define NV_PFIFO_SIZE_CHANNEL_12_124_BYTES 0x00000000 /* RWI-V */ | ||
628 | #define NV_PFIFO_SIZE_CHANNEL_12_512_BYTES 0x00000001 /* RW--V */ | ||
629 | #define NV_PFIFO_SIZE_CHANNEL_13 13:13 /* RWIVF */ | ||
630 | #define NV_PFIFO_SIZE_CHANNEL_13_124_BYTES 0x00000000 /* RWI-V */ | ||
631 | #define NV_PFIFO_SIZE_CHANNEL_13_512_BYTES 0x00000001 /* RW--V */ | ||
632 | #define NV_PFIFO_SIZE_CHANNEL_14 14:14 /* RWIVF */ | ||
633 | #define NV_PFIFO_SIZE_CHANNEL_14_124_BYTES 0x00000000 /* RWI-V */ | ||
634 | #define NV_PFIFO_SIZE_CHANNEL_14_512_BYTES 0x00000001 /* RW--V */ | ||
635 | #define NV_PFIFO_SIZE_CHANNEL_15 15:15 /* RWIVF */ | ||
636 | #define NV_PFIFO_SIZE_CHANNEL_15_124_BYTES 0x00000000 /* RWI-V */ | ||
637 | #define NV_PFIFO_SIZE_CHANNEL_15_512_BYTES 0x00000001 /* RW--V */ | ||
638 | #define NV_PFIFO_CACHE0_PUSH0 0x00003000 /* RW-4R */ | ||
639 | #define NV_PFIFO_CACHE0_PUSH0_ACCESS 0:0 /* RWIVF */ | ||
640 | #define NV_PFIFO_CACHE0_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */ | ||
641 | #define NV_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */ | ||
642 | #define NV_PFIFO_CACHE1_PUSH0 0x00003200 /* RW-4R */ | ||
643 | #define NV_PFIFO_CACHE1_PUSH0_ACCESS 0:0 /* RWIVF */ | ||
644 | #define NV_PFIFO_CACHE1_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */ | ||
645 | #define NV_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */ | ||
646 | #define NV_PFIFO_CACHE0_PUSH1 0x00003004 /* RW-4R */ | ||
647 | #define NV_PFIFO_CACHE0_PUSH1_CHID 3:0 /* RWXUF */ | ||
648 | #define NV_PFIFO_CACHE1_PUSH1 0x00003204 /* RW-4R */ | ||
649 | #define NV_PFIFO_CACHE1_PUSH1_CHID 3:0 /* RWXUF */ | ||
650 | #define NV_PFIFO_CACHE1_PUSH1_MODE 8:8 /* RWIVF */ | ||
651 | #define NV_PFIFO_CACHE1_PUSH1_MODE_PIO 0x00000000 /* RWI-V */ | ||
652 | #define NV_PFIFO_CACHE1_PUSH1_MODE_DMA 0x00000001 /* RW--V */ | ||
653 | #define NV_PFIFO_CACHE1_DMA_PUSH 0x00003220 /* RW-4R */ | ||
654 | #define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS 0:0 /* RWIVF */ | ||
655 | #define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED 0x00000000 /* RWI-V */ | ||
656 | #define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED 0x00000001 /* RW--V */ | ||
657 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATE 4:4 /* R--VF */ | ||
658 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE 0x00000000 /* R---V */ | ||
659 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY 0x00000001 /* R---V */ | ||
660 | #define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER 8:8 /* R--VF */ | ||
661 | #define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY 0x00000000 /* R---V */ | ||
662 | #define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY 0x00000001 /* R---V */ | ||
663 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATUS 12:12 /* RWIVF */ | ||
664 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING 0x00000000 /* RWI-V */ | ||
665 | #define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED 0x00000001 /* RW--V */ | ||
666 | #define NV_PFIFO_CACHE1_DMA_FETCH 0x00003224 /* RW-4R */ | ||
667 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG 7:3 /* RWIUF */ | ||
668 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 /* RW--V */ | ||
669 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000001 /* RW--V */ | ||
670 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000002 /* RW--V */ | ||
671 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000003 /* RW--V */ | ||
672 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000004 /* RW--V */ | ||
673 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000005 /* RW--V */ | ||
674 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000006 /* RW--V */ | ||
675 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000007 /* RW--V */ | ||
676 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000008 /* RW--V */ | ||
677 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000009 /* RW--V */ | ||
678 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x0000000A /* RW--V */ | ||
679 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x0000000B /* RW--V */ | ||
680 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x0000000C /* RW--V */ | ||
681 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x0000000D /* RW--V */ | ||
682 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x0000000E /* RW--V */ | ||
683 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x0000000F /* RWI-V */ | ||
684 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000010 /* RW--V */ | ||
685 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000011 /* RW--V */ | ||
686 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000012 /* RW--V */ | ||
687 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000013 /* RW--V */ | ||
688 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x00000014 /* RW--V */ | ||
689 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x00000015 /* RW--V */ | ||
690 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x00000016 /* RW--V */ | ||
691 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x00000017 /* RW--V */ | ||
692 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x00000018 /* RW--V */ | ||
693 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x00000019 /* RW--V */ | ||
694 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x0000001A /* RW--V */ | ||
695 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x0000001B /* RW--V */ | ||
696 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x0000001C /* RW--V */ | ||
697 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x0000001D /* RW--V */ | ||
698 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x0000001E /* RW--V */ | ||
699 | #define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x0000001F /* RW--V */ | ||
700 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 15:13 /* RWIUF */ | ||
701 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 /* RW--V */ | ||
702 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00000001 /* RW--V */ | ||
703 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00000002 /* RW--V */ | ||
704 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00000003 /* RWI-V */ | ||
705 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00000004 /* RW--V */ | ||
706 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x00000005 /* RW--V */ | ||
707 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x00000006 /* RW--V */ | ||
708 | #define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x00000007 /* RW--V */ | ||
709 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 19:16 /* RWIUF */ | ||
710 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 /* RWI-V */ | ||
711 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00000001 /* RW--V */ | ||
712 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00000002 /* RW--V */ | ||
713 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00000003 /* RW--V */ | ||
714 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00000004 /* RW--V */ | ||
715 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00000005 /* RW--V */ | ||
716 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00000006 /* RW--V */ | ||
717 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00000007 /* RW--V */ | ||
718 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00000008 /* RW--V */ | ||
719 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00000009 /* RW--V */ | ||
720 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x0000000A /* RW--V */ | ||
721 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x0000000B /* RW--V */ | ||
722 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x0000000C /* RW--V */ | ||
723 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x0000000D /* RW--V */ | ||
724 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x0000000E /* RW--V */ | ||
725 | #define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x0000000F /* RW--V */ | ||
726 | #define NV_PFIFO_CACHE1_DMA_PUT 0x00003240 /* RW-4R */ | ||
727 | #define NV_PFIFO_CACHE1_DMA_PUT_OFFSET 28:2 /* RWXUF */ | ||
728 | #define NV_PFIFO_CACHE1_DMA_GET 0x00003244 /* RW-4R */ | ||
729 | #define NV_PFIFO_CACHE1_DMA_GET_OFFSET 28:2 /* RWXUF */ | ||
730 | #define NV_PFIFO_CACHE1_DMA_STATE 0x00003228 /* RW-4R */ | ||
731 | #define NV_PFIFO_CACHE1_DMA_STATE_METHOD 12:2 /* RWXUF */ | ||
732 | #define NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL 15:13 /* RWXUF */ | ||
733 | #define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT 28:18 /* RWIUF */ | ||
734 | #define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0 0x00000000 /* RWI-V */ | ||
735 | #define NV_PFIFO_CACHE1_DMA_STATE_ERROR 31:30 /* RWXUF */ | ||
736 | #define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE 0x00000000 /* RW--V */ | ||
737 | #define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE 0x00000001 /* RW--V */ | ||
738 | #define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 0x00000002 /* RW--V */ | ||
739 | #define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 0x00000003 /* RW--V */ | ||
740 | #define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000322C /* RW-4R */ | ||
741 | #define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 15:0 /* RWXUF */ | ||
742 | #define NV_PFIFO_CACHE1_DMA_CTL 0x00003230 /* RW-4R */ | ||
743 | #define NV_PFIFO_CACHE1_DMA_CTL_ADJUST 11:2 /* RWXUF */ | ||
744 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE 12:12 /* RWXUF */ | ||
745 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RW--V */ | ||
746 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */ | ||
747 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY 13:13 /* RWXUF */ | ||
748 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */ | ||
749 | #define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */ | ||
750 | #define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE 17:16 /* RWXUF */ | ||
751 | #define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI 0x00000002 /* RW--V */ | ||
752 | #define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP 0x00000003 /* RW--V */ | ||
753 | #define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO 31:31 /* RWIUF */ | ||
754 | #define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID 0x00000000 /* RW--V */ | ||
755 | #define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID 0x00000001 /* RWI-V */ | ||
756 | #define NV_PFIFO_CACHE1_DMA_LIMIT 0x00003234 /* RW-4R */ | ||
757 | #define NV_PFIFO_CACHE1_DMA_LIMIT_OFFSET 28:2 /* RWXUF */ | ||
758 | #define NV_PFIFO_CACHE1_DMA_TLB_TAG 0x00003238 /* RW-4R */ | ||
759 | #define NV_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS 28:12 /* RWXUF */ | ||
760 | #define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE 0:0 /* RWIUF */ | ||
761 | #define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID 0x00000000 /* RWI-V */ | ||
762 | #define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID 0x00000001 /* RW--V */ | ||
763 | #define NV_PFIFO_CACHE1_DMA_TLB_PTE 0x0000323C /* RW-4R */ | ||
764 | #define NV_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */ | ||
765 | #define NV_PFIFO_CACHE0_PULL0 0x00003050 /* RW-4R */ | ||
766 | #define NV_PFIFO_CACHE0_PULL0_ACCESS 0:0 /* RWIVF */ | ||
767 | #define NV_PFIFO_CACHE0_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */ | ||
768 | #define NV_PFIFO_CACHE0_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */ | ||
769 | #define NV_PFIFO_CACHE0_PULL0_HASH 4:4 /* R-XVF */ | ||
770 | #define NV_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */ | ||
771 | #define NV_PFIFO_CACHE0_PULL0_HASH_FAILED 0x00000001 /* R---V */ | ||
772 | #define NV_PFIFO_CACHE0_PULL0_DEVICE 8:8 /* R-XVF */ | ||
773 | #define NV_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */ | ||
774 | #define NV_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */ | ||
775 | #define NV_PFIFO_CACHE0_PULL0_HASH_STATE 12:12 /* R-XVF */ | ||
776 | #define NV_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */ | ||
777 | #define NV_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */ | ||
778 | #define NV_PFIFO_CACHE1_PULL0 0x00003250 /* RW-4R */ | ||
779 | #define NV_PFIFO_CACHE1_PULL0_ACCESS 0:0 /* RWIVF */ | ||
780 | #define NV_PFIFO_CACHE1_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */ | ||
781 | #define NV_PFIFO_CACHE1_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */ | ||
782 | #define NV_PFIFO_CACHE1_PULL0_HASH 4:4 /* R-XVF */ | ||
783 | #define NV_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */ | ||
784 | #define NV_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000001 /* R---V */ | ||
785 | #define NV_PFIFO_CACHE1_PULL0_DEVICE 8:8 /* R-XVF */ | ||
786 | #define NV_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */ | ||
787 | #define NV_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */ | ||
788 | #define NV_PFIFO_CACHE1_PULL0_HASH_STATE 12:12 /* R-XVF */ | ||
789 | #define NV_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */ | ||
790 | #define NV_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */ | ||
791 | #define NV_PFIFO_CACHE0_PULL1 0x00003054 /* RW-4R */ | ||
792 | #define NV_PFIFO_CACHE0_PULL1_ENGINE 1:0 /* RWXUF */ | ||
793 | #define NV_PFIFO_CACHE0_PULL1_ENGINE_SW 0x00000000 /* RW--V */ | ||
794 | #define NV_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */ | ||
795 | #define NV_PFIFO_CACHE0_PULL1_ENGINE_DVD 0x00000002 /* RW--V */ | ||
796 | #define NV_PFIFO_CACHE1_PULL1 0x00003254 /* RW-4R */ | ||
797 | #define NV_PFIFO_CACHE1_PULL1_ENGINE 1:0 /* RWXUF */ | ||
798 | #define NV_PFIFO_CACHE1_PULL1_ENGINE_SW 0x00000000 /* RW--V */ | ||
799 | #define NV_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */ | ||
800 | #define NV_PFIFO_CACHE1_PULL1_ENGINE_DVD 0x00000002 /* RW--V */ | ||
801 | #define NV_PFIFO_CACHE0_HASH 0x00003058 /* RW-4R */ | ||
802 | #define NV_PFIFO_CACHE0_HASH_INSTANCE 15:0 /* RWXUF */ | ||
803 | #define NV_PFIFO_CACHE0_HASH_VALID 16:16 /* RWXVF */ | ||
804 | #define NV_PFIFO_CACHE1_HASH 0x00003258 /* RW-4R */ | ||
805 | #define NV_PFIFO_CACHE1_HASH_INSTANCE 15:0 /* RWXUF */ | ||
806 | #define NV_PFIFO_CACHE1_HASH_VALID 16:16 /* RWXVF */ | ||
807 | #define NV_PFIFO_CACHE0_STATUS 0x00003014 /* R--4R */ | ||
808 | #define NV_PFIFO_CACHE0_STATUS_LOW_MARK 4:4 /* R--VF */ | ||
809 | #define NV_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */ | ||
810 | #define NV_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */ | ||
811 | #define NV_PFIFO_CACHE0_STATUS_HIGH_MARK 8:8 /* R--VF */ | ||
812 | #define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */ | ||
813 | #define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */ | ||
814 | #define NV_PFIFO_CACHE1_STATUS 0x00003214 /* R--4R */ | ||
815 | #define NV_PFIFO_CACHE1_STATUS_LOW_MARK 4:4 /* R--VF */ | ||
816 | #define NV_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */ | ||
817 | #define NV_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */ | ||
818 | #define NV_PFIFO_CACHE1_STATUS_HIGH_MARK 8:8 /* R--VF */ | ||
819 | #define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */ | ||
820 | #define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */ | ||
821 | #define NV_PFIFO_CACHE1_STATUS1 0x00003218 /* R--4R */ | ||
822 | #define NV_PFIFO_CACHE1_STATUS1_RANOUT 0:0 /* R-XVF */ | ||
823 | #define NV_PFIFO_CACHE1_STATUS1_RANOUT_FALSE 0x00000000 /* R---V */ | ||
824 | #define NV_PFIFO_CACHE1_STATUS1_RANOUT_TRUE 0x00000001 /* R---V */ | ||
825 | #define NV_PFIFO_CACHE0_PUT 0x00003010 /* RW-4R */ | ||
826 | #define NV_PFIFO_CACHE0_PUT_ADDRESS 2:2 /* RWXUF */ | ||
827 | #define NV_PFIFO_CACHE1_PUT 0x00003210 /* RW-4R */ | ||
828 | #define NV_PFIFO_CACHE1_PUT_ADDRESS 9:2 /* RWXUF */ | ||
829 | #define NV_PFIFO_CACHE0_GET 0x00003070 /* RW-4R */ | ||
830 | #define NV_PFIFO_CACHE0_GET_ADDRESS 2:2 /* RWXUF */ | ||
831 | #define NV_PFIFO_CACHE1_GET 0x00003270 /* RW-4R */ | ||
832 | #define NV_PFIFO_CACHE1_GET_ADDRESS 9:2 /* RWXUF */ | ||
833 | #define NV_PFIFO_CACHE0_ENGINE 0x00003080 /* RW-4R */ | ||
834 | #define NV_PFIFO_CACHE0_ENGINE_0 1:0 /* RWXUF */ | ||
835 | #define NV_PFIFO_CACHE0_ENGINE_0_SW 0x00000000 /* RW--V */ | ||
836 | #define NV_PFIFO_CACHE0_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */ | ||
837 | #define NV_PFIFO_CACHE0_ENGINE_0_DVD 0x00000002 /* RW--V */ | ||
838 | #define NV_PFIFO_CACHE0_ENGINE_1 5:4 /* RWXUF */ | ||
839 | #define NV_PFIFO_CACHE0_ENGINE_1_SW 0x00000000 /* RW--V */ | ||
840 | #define NV_PFIFO_CACHE0_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */ | ||
841 | #define NV_PFIFO_CACHE0_ENGINE_1_DVD 0x00000002 /* RW--V */ | ||
842 | #define NV_PFIFO_CACHE0_ENGINE_2 9:8 /* RWXUF */ | ||
843 | #define NV_PFIFO_CACHE0_ENGINE_2_SW 0x00000000 /* RW--V */ | ||
844 | #define NV_PFIFO_CACHE0_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */ | ||
845 | #define NV_PFIFO_CACHE0_ENGINE_2_DVD 0x00000002 /* RW--V */ | ||
846 | #define NV_PFIFO_CACHE0_ENGINE_3 13:12 /* RWXUF */ | ||
847 | #define NV_PFIFO_CACHE0_ENGINE_3_SW 0x00000000 /* RW--V */ | ||
848 | #define NV_PFIFO_CACHE0_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */ | ||
849 | #define NV_PFIFO_CACHE0_ENGINE_3_DVD 0x00000002 /* RW--V */ | ||
850 | #define NV_PFIFO_CACHE0_ENGINE_4 17:16 /* RWXUF */ | ||
851 | #define NV_PFIFO_CACHE0_ENGINE_4_SW 0x00000000 /* RW--V */ | ||
852 | #define NV_PFIFO_CACHE0_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */ | ||
853 | #define NV_PFIFO_CACHE0_ENGINE_4_DVD 0x00000002 /* RW--V */ | ||
854 | #define NV_PFIFO_CACHE0_ENGINE_5 21:20 /* RWXUF */ | ||
855 | #define NV_PFIFO_CACHE0_ENGINE_5_SW 0x00000000 /* RW--V */ | ||
856 | #define NV_PFIFO_CACHE0_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */ | ||
857 | #define NV_PFIFO_CACHE0_ENGINE_5_DVD 0x00000002 /* RW--V */ | ||
858 | #define NV_PFIFO_CACHE0_ENGINE_6 25:24 /* RWXUF */ | ||
859 | #define NV_PFIFO_CACHE0_ENGINE_6_SW 0x00000000 /* RW--V */ | ||
860 | #define NV_PFIFO_CACHE0_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */ | ||
861 | #define NV_PFIFO_CACHE0_ENGINE_6_DVD 0x00000002 /* RW--V */ | ||
862 | #define NV_PFIFO_CACHE0_ENGINE_7 29:28 /* RWXUF */ | ||
863 | #define NV_PFIFO_CACHE0_ENGINE_7_SW 0x00000000 /* RW--V */ | ||
864 | #define NV_PFIFO_CACHE0_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */ | ||
865 | #define NV_PFIFO_CACHE0_ENGINE_7_DVD 0x00000002 /* RW--V */ | ||
866 | #define NV_PFIFO_CACHE1_ENGINE 0x00003280 /* RW-4R */ | ||
867 | #define NV_PFIFO_CACHE1_ENGINE_0 1:0 /* RWXUF */ | ||
868 | #define NV_PFIFO_CACHE1_ENGINE_0_SW 0x00000000 /* RW--V */ | ||
869 | #define NV_PFIFO_CACHE1_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */ | ||
870 | #define NV_PFIFO_CACHE1_ENGINE_0_DVD 0x00000002 /* RW--V */ | ||
871 | #define NV_PFIFO_CACHE1_ENGINE_1 5:4 /* RWXUF */ | ||
872 | #define NV_PFIFO_CACHE1_ENGINE_1_SW 0x00000000 /* RW--V */ | ||
873 | #define NV_PFIFO_CACHE1_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */ | ||
874 | #define NV_PFIFO_CACHE1_ENGINE_1_DVD 0x00000002 /* RW--V */ | ||
875 | #define NV_PFIFO_CACHE1_ENGINE_2 9:8 /* RWXUF */ | ||
876 | #define NV_PFIFO_CACHE1_ENGINE_2_SW 0x00000000 /* RW--V */ | ||
877 | #define NV_PFIFO_CACHE1_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */ | ||
878 | #define NV_PFIFO_CACHE1_ENGINE_2_DVD 0x00000002 /* RW--V */ | ||
879 | #define NV_PFIFO_CACHE1_ENGINE_3 13:12 /* RWXUF */ | ||
880 | #define NV_PFIFO_CACHE1_ENGINE_3_SW 0x00000000 /* RW--V */ | ||
881 | #define NV_PFIFO_CACHE1_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */ | ||
882 | #define NV_PFIFO_CACHE1_ENGINE_3_DVD 0x00000002 /* RW--V */ | ||
883 | #define NV_PFIFO_CACHE1_ENGINE_4 17:16 /* RWXUF */ | ||
884 | #define NV_PFIFO_CACHE1_ENGINE_4_SW 0x00000000 /* RW--V */ | ||
885 | #define NV_PFIFO_CACHE1_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */ | ||
886 | #define NV_PFIFO_CACHE1_ENGINE_4_DVD 0x00000002 /* RW--V */ | ||
887 | #define NV_PFIFO_CACHE1_ENGINE_5 21:20 /* RWXUF */ | ||
888 | #define NV_PFIFO_CACHE1_ENGINE_5_SW 0x00000000 /* RW--V */ | ||
889 | #define NV_PFIFO_CACHE1_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */ | ||
890 | #define NV_PFIFO_CACHE1_ENGINE_5_DVD 0x00000002 /* RW--V */ | ||
891 | #define NV_PFIFO_CACHE1_ENGINE_6 25:24 /* RWXUF */ | ||
892 | #define NV_PFIFO_CACHE1_ENGINE_6_SW 0x00000000 /* RW--V */ | ||
893 | #define NV_PFIFO_CACHE1_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */ | ||
894 | #define NV_PFIFO_CACHE1_ENGINE_6_DVD 0x00000002 /* RW--V */ | ||
895 | #define NV_PFIFO_CACHE1_ENGINE_7 29:28 /* RWXUF */ | ||
896 | #define NV_PFIFO_CACHE1_ENGINE_7_SW 0x00000000 /* RW--V */ | ||
897 | #define NV_PFIFO_CACHE1_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */ | ||
898 | #define NV_PFIFO_CACHE1_ENGINE_7_DVD 0x00000002 /* RW--V */ | ||
899 | #define NV_PFIFO_CACHE0_METHOD(i) (0x00003100+(i)*8) /* RW-4A */ | ||
900 | #define NV_PFIFO_CACHE0_METHOD__SIZE_1 1 /* */ | ||
901 | #define NV_PFIFO_CACHE0_METHOD_ADDRESS 12:2 /* RWXUF */ | ||
902 | #define NV_PFIFO_CACHE0_METHOD_SUBCHANNEL 15:13 /* RWXUF */ | ||
903 | #define NV_PFIFO_CACHE1_METHOD(i) (0x00003800+(i)*8) /* RW-4A */ | ||
904 | #define NV_PFIFO_CACHE1_METHOD__SIZE_1 128 /* */ | ||
905 | #define NV_PFIFO_CACHE1_METHOD_ADDRESS 12:2 /* RWXUF */ | ||
906 | #define NV_PFIFO_CACHE1_METHOD_SUBCHANNEL 15:13 /* RWXUF */ | ||
907 | #define NV_PFIFO_CACHE1_METHOD_ALIAS(i) (0x00003C00+(i)*8) /* RW-4A */ | ||
908 | #define NV_PFIFO_CACHE1_METHOD_ALIAS__SIZE_1 128 /* */ | ||
909 | #define NV_PFIFO_CACHE0_DATA(i) (0x00003104+(i)*8) /* RW-4A */ | ||
910 | #define NV_PFIFO_CACHE0_DATA__SIZE_1 1 /* */ | ||
911 | #define NV_PFIFO_CACHE0_DATA_VALUE 31:0 /* RWXVF */ | ||
912 | #define NV_PFIFO_CACHE1_DATA(i) (0x00003804+(i)*8) /* RW-4A */ | ||
913 | #define NV_PFIFO_CACHE1_DATA__SIZE_1 128 /* */ | ||
914 | #define NV_PFIFO_CACHE1_DATA_VALUE 31:0 /* RWXVF */ | ||
915 | #define NV_PFIFO_CACHE1_DATA_ALIAS(i) (0x00003C04+(i)*8) /* RW-4A */ | ||
916 | #define NV_PFIFO_CACHE1_DATA_ALIAS__SIZE_1 128 /* */ | ||
917 | #define NV_PFIFO_DEVICE(i) (0x00002800+(i)*4) /* R--4A */ | ||
918 | #define NV_PFIFO_DEVICE__SIZE_1 128 /* */ | ||
919 | #define NV_PFIFO_DEVICE_CHID 3:0 /* R--UF */ | ||
920 | #define NV_PFIFO_DEVICE_SWITCH 24:24 /* R--VF */ | ||
921 | #define NV_PFIFO_DEVICE_SWITCH_UNAVAILABLE 0x00000000 /* R---V */ | ||
922 | #define NV_PFIFO_DEVICE_SWITCH_AVAILABLE 0x00000001 /* R---V */ | ||
923 | #define NV_PFIFO_RUNOUT_STATUS 0x00002400 /* R--4R */ | ||
924 | #define NV_PFIFO_RUNOUT_STATUS_RANOUT 0:0 /* R--VF */ | ||
925 | #define NV_PFIFO_RUNOUT_STATUS_RANOUT_FALSE 0x00000000 /* R---V */ | ||
926 | #define NV_PFIFO_RUNOUT_STATUS_RANOUT_TRUE 0x00000001 /* R---V */ | ||
927 | #define NV_PFIFO_RUNOUT_STATUS_LOW_MARK 4:4 /* R--VF */ | ||
928 | #define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */ | ||
929 | #define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */ | ||
930 | #define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK 8:8 /* R--VF */ | ||
931 | #define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */ | ||
932 | #define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */ | ||
933 | #define NV_PFIFO_RUNOUT_PUT 0x00002410 /* RW-4R */ | ||
934 | #define NV_PFIFO_RUNOUT_PUT_ADDRESS 12:3 /* RWXUF */ | ||
935 | #define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_0 8:3 /* RWXUF */ | ||
936 | #define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_1 12:3 /* RWXUF */ | ||
937 | #define NV_PFIFO_RUNOUT_GET 0x00002420 /* RW-4R */ | ||
938 | #define NV_PFIFO_RUNOUT_GET_ADDRESS 13:3 /* RWXUF */ | ||
939 | /* dev_graphics.ref */ | ||
940 | #define NV_PGRAPH 0x00401FFF:0x00400000 /* RW--D */ | ||
941 | #define NV_PGRAPH_DEBUG_0 0x00400080 /* RW-4R */ | ||
942 | #define NV_PGRAPH_DEBUG_1 0x00400084 /* RW-4R */ | ||
943 | #define NV_PGRAPH_DEBUG_2 0x00400088 /* RW-4R */ | ||
944 | #define NV_PGRAPH_DEBUG_3 0x0040008C /* RW-4R */ | ||
945 | #define NV_PGRAPH_INTR 0x00400100 /* RW-4R */ | ||
946 | #define NV_PGRAPH_INTR_NOTIFY 0:0 /* RWIVF */ | ||
947 | #define NV_PGRAPH_INTR_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */ | ||
948 | #define NV_PGRAPH_INTR_NOTIFY_PENDING 0x00000001 /* R---V */ | ||
949 | #define NV_PGRAPH_INTR_NOTIFY_RESET 0x00000001 /* -W--C */ | ||
950 | #define NV_PGRAPH_INTR_MISSING_HW 4:4 /* RWIVF */ | ||
951 | #define NV_PGRAPH_INTR_MISSING_HW_NOT_PENDING 0x00000000 /* R-I-V */ | ||
952 | #define NV_PGRAPH_INTR_MISSING_HW_PENDING 0x00000001 /* R---V */ | ||
953 | #define NV_PGRAPH_INTR_MISSING_HW_RESET 0x00000001 /* -W--C */ | ||
954 | #define NV_PGRAPH_INTR_TLB_PRESENT_A 8:8 /* RWIVF */ | ||
955 | #define NV_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING 0x00000000 /* R-I-V */ | ||
956 | #define NV_PGRAPH_INTR_TLB_PRESENT_A_PENDING 0x00000001 /* R---V */ | ||
957 | #define NV_PGRAPH_INTR_TLB_PRESENT_A_RESET 0x00000001 /* -W--C */ | ||
958 | #define NV_PGRAPH_INTR_TLB_PRESENT_B 9:9 /* RWIVF */ | ||
959 | #define NV_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING 0x00000000 /* R-I-V */ | ||
960 | #define NV_PGRAPH_INTR_TLB_PRESENT_B_PENDING 0x00000001 /* R---V */ | ||
961 | #define NV_PGRAPH_INTR_TLB_PRESENT_B_RESET 0x00000001 /* -W--C */ | ||
962 | #define NV_PGRAPH_INTR_CONTEXT_SWITCH 12:12 /* RWIVF */ | ||
963 | #define NV_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING 0x00000000 /* R-I-V */ | ||
964 | #define NV_PGRAPH_INTR_CONTEXT_SWITCH_PENDING 0x00000001 /* R---V */ | ||
965 | #define NV_PGRAPH_INTR_CONTEXT_SWITCH_RESET 0x00000001 /* -W--C */ | ||
966 | #define NV_PGRAPH_INTR_BUFFER_NOTIFY 16:16 /* RWIVF */ | ||
967 | #define NV_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */ | ||
968 | #define NV_PGRAPH_INTR_BUFFER_NOTIFY_PENDING 0x00000001 /* R---V */ | ||
969 | #define NV_PGRAPH_INTR_BUFFER_NOTIFY_RESET 0x00000001 /* -W--C */ | ||
970 | #define NV_PGRAPH_NSTATUS 0x00400104 /* RW-4R */ | ||
971 | #define NV_PGRAPH_NSTATUS_STATE_IN_USE 11:11 /* RWIVF */ | ||
972 | #define NV_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING 0x00000000 /* RWI-V */ | ||
973 | #define NV_PGRAPH_NSTATUS_STATE_IN_USE_PENDING 0x00000001 /* RW--V */ | ||
974 | #define NV_PGRAPH_NSTATUS_INVALID_STATE 12:12 /* RWIVF */ | ||
975 | #define NV_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING 0x00000000 /* RWI-V */ | ||
976 | #define NV_PGRAPH_NSTATUS_INVALID_STATE_PENDING 0x00000001 /* RW--V */ | ||
977 | #define NV_PGRAPH_NSTATUS_BAD_ARGUMENT 13:13 /* RWIVF */ | ||
978 | #define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING 0x00000000 /* RWI-V */ | ||
979 | #define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING 0x00000001 /* RW--V */ | ||
980 | #define NV_PGRAPH_NSTATUS_PROTECTION_FAULT 14:14 /* RWIVF */ | ||
981 | #define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING 0x00000000 /* RWI-V */ | ||
982 | #define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING 0x00000001 /* RW--V */ | ||
983 | #define NV_PGRAPH_NSOURCE 0x00400108 /* R--4R */ | ||
984 | #define NV_PGRAPH_NSOURCE_NOTIFICATION 0:0 /* R-IVF */ | ||
985 | #define NV_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
986 | #define NV_PGRAPH_NSOURCE_NOTIFICATION_PENDING 0x00000001 /* R---V */ | ||
987 | #define NV_PGRAPH_NSOURCE_DATA_ERROR 1:1 /* R-IVF */ | ||
988 | #define NV_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING 0x00000000 /* R-I-V */ | ||
989 | #define NV_PGRAPH_NSOURCE_DATA_ERROR_PENDING 0x00000001 /* R---V */ | ||
990 | #define NV_PGRAPH_NSOURCE_PROTECTION_ERROR 2:2 /* R-IVF */ | ||
991 | #define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING 0x00000000 /* R-I-V */ | ||
992 | #define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING 0x00000001 /* R---V */ | ||
993 | #define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION 3:3 /* R-IVF */ | ||
994 | #define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
995 | #define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING 0x00000001 /* R---V */ | ||
996 | #define NV_PGRAPH_NSOURCE_LIMIT_COLOR 4:4 /* R-IVF */ | ||
997 | #define NV_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING 0x00000000 /* R-I-V */ | ||
998 | #define NV_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING 0x00000001 /* R---V */ | ||
999 | #define NV_PGRAPH_NSOURCE_LIMIT_ZETA_ 5:5 /* R-IVF */ | ||
1000 | #define NV_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1001 | #define NV_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING 0x00000001 /* R---V */ | ||
1002 | #define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD 6:6 /* R-IVF */ | ||
1003 | #define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1004 | #define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING 0x00000001 /* R---V */ | ||
1005 | #define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION 7:7 /* R-IVF */ | ||
1006 | #define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1007 | #define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING 0x00000001 /* R---V */ | ||
1008 | #define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION 8:8 /* R-IVF */ | ||
1009 | #define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1010 | #define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING 0x00000001 /* R---V */ | ||
1011 | #define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION 9:9 /* R-IVF */ | ||
1012 | #define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1013 | #define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING 0x00000001 /* R---V */ | ||
1014 | #define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION 10:10 /* R-IVF */ | ||
1015 | #define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1016 | #define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING 0x00000001 /* R---V */ | ||
1017 | #define NV_PGRAPH_NSOURCE_STATE_INVALID 11:11 /* R-IVF */ | ||
1018 | #define NV_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1019 | #define NV_PGRAPH_NSOURCE_STATE_INVALID_PENDING 0x00000001 /* R---V */ | ||
1020 | #define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY 12:12 /* R-IVF */ | ||
1021 | #define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1022 | #define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING 0x00000001 /* R---V */ | ||
1023 | #define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE 13:13 /* R-IVF */ | ||
1024 | #define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1025 | #define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING 0x00000001 /* R---V */ | ||
1026 | #define NV_PGRAPH_NSOURCE_METHOD_CNT 14:14 /* R-IVF */ | ||
1027 | #define NV_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1028 | #define NV_PGRAPH_NSOURCE_METHOD_CNT_PENDING 0x00000001 /* R---V */ | ||
1029 | #define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION 15:15 /* R-IVF */ | ||
1030 | #define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */ | ||
1031 | #define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING 0x00000001 /* R---V */ | ||
1032 | #define NV_PGRAPH_INTR_EN 0x00400140 /* RW-4R */ | ||
1033 | #define NV_PGRAPH_INTR_EN_NOTIFY 0:0 /* RWIVF */ | ||
1034 | #define NV_PGRAPH_INTR_EN_NOTIFY_DISABLED 0x00000000 /* RWI-V */ | ||
1035 | #define NV_PGRAPH_INTR_EN_NOTIFY_ENABLED 0x00000001 /* RW--V */ | ||
1036 | #define NV_PGRAPH_INTR_EN_MISSING_HW 4:4 /* RWIVF */ | ||
1037 | #define NV_PGRAPH_INTR_EN_MISSING_HW_DISABLED 0x00000000 /* RWI-V */ | ||
1038 | #define NV_PGRAPH_INTR_EN_MISSING_HW_ENABLED 0x00000001 /* RW--V */ | ||
1039 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_A 8:8 /* RWIVF */ | ||
1040 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_DISABLED 0x00000000 /* RWI-V */ | ||
1041 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED 0x00000001 /* RW--V */ | ||
1042 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_B 9:9 /* RWIVF */ | ||
1043 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_DISABLED 0x00000000 /* RWI-V */ | ||
1044 | #define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED 0x00000001 /* RW--V */ | ||
1045 | #define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH 12:12 /* RWIVF */ | ||
1046 | #define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_DISABLED 0x00000000 /* RWI-V */ | ||
1047 | #define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED 0x00000001 /* RW--V */ | ||
1048 | #define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY 16:16 /* RWIVF */ | ||
1049 | #define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_DISABLED 0x00000000 /* RWI-V */ | ||
1050 | #define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED 0x00000001 /* RW--V */ | ||
1051 | #define NV_PGRAPH_CTX_SWITCH1 0x00400160 /* RW-4R */ | ||
1052 | #define NV_PGRAPH_CTX_SWITCH1_GRCLASS 7:0 /* RWXVF */ | ||
1053 | #define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY 12:12 /* RWXUF */ | ||
1054 | #define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE 0x00000000 /* RW--V */ | ||
1055 | #define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE 0x00000001 /* RW--V */ | ||
1056 | #define NV_PGRAPH_CTX_SWITCH1_USER_CLIP 13:13 /* RWXUF */ | ||
1057 | #define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE 0x00000000 /* RW--V */ | ||
1058 | #define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE 0x00000001 /* RW--V */ | ||
1059 | #define NV_PGRAPH_CTX_SWITCH1_SWIZZLE 14:14 /* RWXUF */ | ||
1060 | #define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE 0x00000000 /* RW--V */ | ||
1061 | #define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE 0x00000001 /* RW--V */ | ||
1062 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG 17:15 /* RWXUF */ | ||
1063 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND 0x00000000 /* RW--V */ | ||
1064 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND 0x00000001 /* RW--V */ | ||
1065 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND 0x00000002 /* RW--V */ | ||
1066 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY 0x00000003 /* RW--V */ | ||
1067 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE 0x00000004 /* RW--V */ | ||
1068 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE 0x00000005 /* RW--V */ | ||
1069 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS 24:24 /* RWXUF */ | ||
1070 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID 0x00000000 /* RW--V */ | ||
1071 | #define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID 0x00000001 /* RW--V */ | ||
1072 | #define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE 25:25 /* RWXUF */ | ||
1073 | #define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID 0x00000000 /* RW--V */ | ||
1074 | #define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID 0x00000001 /* RW--V */ | ||
1075 | #define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET 31:31 /* CWIVF */ | ||
1076 | #define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE 0x00000000 /* CWI-V */ | ||
1077 | #define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED 0x00000001 /* -W--T */ | ||
1078 | #define NV_PGRAPH_CTX_SWITCH2 0x00400164 /* RW-4R */ | ||
1079 | #define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT 1:0 /* RWXUF */ | ||
1080 | #define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID 0x00 /* RW--V */ | ||
1081 | #define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1 0x01 /* RW--V */ | ||
1082 | #define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1 0x02 /* RW--V */ | ||
1083 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT 13:8 /* RWXUF */ | ||
1084 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID 0x00 /* RW--V */ | ||
1085 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8 0x01 /* RW--V */ | ||
1086 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8 0x02 /* RW--V */ | ||
1087 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8 0x03 /* RW--V */ | ||
1088 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5 0x06 /* RW--V */ | ||
1089 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5 0x07 /* RW--V */ | ||
1090 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 /* RW--V */ | ||
1091 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5 0x09 /* RW--V */ | ||
1092 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5 0x0A /* RW--V */ | ||
1093 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5 0x0B /* RW--V */ | ||
1094 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5 0x0C /* RW--V */ | ||
1095 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8 0x0D /* RW--V */ | ||
1096 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8 0x0E /* RW--V */ | ||
1097 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16 0x0F /* RW--V */ | ||
1098 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16 0x10 /* RW--V */ | ||
1099 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16 0x11 /* RW--V */ | ||
1100 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */ | ||
1101 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */ | ||
1102 | #define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32 0x14 /* RW--V */ | ||
1103 | #define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE 31:16 /* RWXUF */ | ||
1104 | #define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID 0x0000 /* RW--V */ | ||
1105 | #define NV_PGRAPH_CTX_SWITCH3 0x00400168 /* RW-4R */ | ||
1106 | #define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0 15:0 /* RWXUF */ | ||
1107 | #define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID 0x0000 /* RW--V */ | ||
1108 | #define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1 31:16 /* RWXUF */ | ||
1109 | #define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID 0x0000 /* RW--V */ | ||
1110 | #define NV_PGRAPH_CTX_SWITCH4 0x0040016C /* RW-4R */ | ||
1111 | #define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE 15:0 /* RWXUF */ | ||
1112 | #define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID 0x0000 /* RW--V */ | ||
1113 | #define NV_PGRAPH_CTX_CACHE1(i) (0x00400180+(i)*4) /* RW-4A */ | ||
1114 | #define NV_PGRAPH_CTX_CACHE1__SIZE_1 8 /* */ | ||
1115 | #define NV_PGRAPH_CTX_CACHE1_GRCLASS 7:0 /* RWXVF */ | ||
1116 | #define NV_PGRAPH_CTX_CACHE1_CHROMA_KEY 12:12 /* RWXVF */ | ||
1117 | #define NV_PGRAPH_CTX_CACHE1_USER_CLIP 13:13 /* RWXVF */ | ||
1118 | #define NV_PGRAPH_CTX_CACHE1_SWIZZLE 14:14 /* RWXVF */ | ||
1119 | #define NV_PGRAPH_CTX_CACHE1_PATCH_CONFIG 19:15 /* RWXVF */ | ||
1120 | #define NV_PGRAPH_CTX_CACHE1_SPARE1 20:20 /* RWXVF */ | ||
1121 | #define NV_PGRAPH_CTX_CACHE1_PATCH_STATUS 24:24 /* RWXVF */ | ||
1122 | #define NV_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE 25:25 /* RWXVF */ | ||
1123 | #define NV_PGRAPH_CTX_CACHE2(i) (0x004001a0+(i)*4) /* RW-4A */ | ||
1124 | #define NV_PGRAPH_CTX_CACHE2__SIZE_1 8 /* */ | ||
1125 | #define NV_PGRAPH_CTX_CACHE2_MONO_FORMAT 1:0 /* RWXVF */ | ||
1126 | #define NV_PGRAPH_CTX_CACHE2_COLOR_FORMAT 13:8 /* RWXVF */ | ||
1127 | #define NV_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE 31:16 /* RWXVF */ | ||
1128 | #define NV_PGRAPH_CTX_CACHE3(i) (0x004001c0+(i)*4) /* RW-4A */ | ||
1129 | #define NV_PGRAPH_CTX_CACHE3__SIZE_1 8 /* */ | ||
1130 | #define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0 15:0 /* RWXVF */ | ||
1131 | #define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1 31:16 /* RWXVF */ | ||
1132 | #define NV_PGRAPH_CTX_CACHE4(i) (0x004001e0+(i)*4) /* RW-4A */ | ||
1133 | #define NV_PGRAPH_CTX_CACHE4__SIZE_1 8 /* */ | ||
1134 | #define NV_PGRAPH_CTX_CACHE4_USER_INSTANCE 15:0 /* RWXVF */ | ||
1135 | #define NV_PGRAPH_CTX_CONTROL 0x00400170 /* RW-4R */ | ||
1136 | #define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME 1:0 /* RWIVF */ | ||
1137 | #define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US 0x00000000 /* RWI-V */ | ||
1138 | #define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US 0x00000001 /* RW--V */ | ||
1139 | #define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS 0x00000002 /* RW--V */ | ||
1140 | #define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS 0x00000003 /* RW--V */ | ||
1141 | #define NV_PGRAPH_CTX_CONTROL_TIME 8:8 /* RWIVF */ | ||
1142 | #define NV_PGRAPH_CTX_CONTROL_TIME_EXPIRED 0x00000000 /* RWI-V */ | ||
1143 | #define NV_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED 0x00000001 /* RW--V */ | ||
1144 | #define NV_PGRAPH_CTX_CONTROL_CHID 16:16 /* RWIVF */ | ||
1145 | #define NV_PGRAPH_CTX_CONTROL_CHID_INVALID 0x00000000 /* RWI-V */ | ||
1146 | #define NV_PGRAPH_CTX_CONTROL_CHID_VALID 0x00000001 /* RW--V */ | ||
1147 | #define NV_PGRAPH_CTX_CONTROL_CHANGE 20:20 /* R--VF */ | ||
1148 | #define NV_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE 0x00000000 /* R---V */ | ||
1149 | #define NV_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE 0x00000001 /* R---V */ | ||
1150 | #define NV_PGRAPH_CTX_CONTROL_SWITCHING 24:24 /* RWIVF */ | ||
1151 | #define NV_PGRAPH_CTX_CONTROL_SWITCHING_IDLE 0x00000000 /* RWI-V */ | ||
1152 | #define NV_PGRAPH_CTX_CONTROL_SWITCHING_BUSY 0x00000001 /* RW--V */ | ||
1153 | #define NV_PGRAPH_CTX_CONTROL_DEVICE 28:28 /* RWIVF */ | ||
1154 | #define NV_PGRAPH_CTX_CONTROL_DEVICE_DISABLED 0x00000000 /* RWI-V */ | ||
1155 | #define NV_PGRAPH_CTX_CONTROL_DEVICE_ENABLED 0x00000001 /* RW--V */ | ||
1156 | #define NV_PGRAPH_CTX_USER 0x00400174 /* RW-4R */ | ||
1157 | #define NV_PGRAPH_CTX_USER_SUBCH 15:13 /* RWIVF */ | ||
1158 | #define NV_PGRAPH_CTX_USER_SUBCH_0 0x00000000 /* RWI-V */ | ||
1159 | #define NV_PGRAPH_CTX_USER_CHID 27:24 /* RWIVF */ | ||
1160 | #define NV_PGRAPH_CTX_USER_CHID_0 0x00000000 /* RWI-V */ | ||
1161 | #define NV_PGRAPH_FIFO 0x00400720 /* RW-4R */ | ||
1162 | #define NV_PGRAPH_FIFO_ACCESS 0:0 /* RWIVF */ | ||
1163 | #define NV_PGRAPH_FIFO_ACCESS_DISABLED 0x00000000 /* RW--V */ | ||
1164 | #define NV_PGRAPH_FIFO_ACCESS_ENABLED 0x00000001 /* RWI-V */ | ||
1165 | #define NV_PGRAPH_FFINTFC_FIFO_0(i) (0x00400730+(i)*4) /* RW-4A */ | ||
1166 | #define NV_PGRAPH_FFINTFC_FIFO_0__SIZE_1 4 /* */ | ||
1167 | #define NV_PGRAPH_FFINTFC_FIFO_0_TAG 0:0 /* RWXVF */ | ||
1168 | #define NV_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD 0x00000000 /* RW--V */ | ||
1169 | #define NV_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW 0x00000001 /* RW--V */ | ||
1170 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH 3:1 /* RWXVF */ | ||
1171 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_0 0x00000000 /* RW--V */ | ||
1172 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_1 0x00000001 /* RW--V */ | ||
1173 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_2 0x00000002 /* RW--V */ | ||
1174 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_3 0x00000003 /* RW--V */ | ||
1175 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_4 0x00000004 /* RW--V */ | ||
1176 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_5 0x00000005 /* RW--V */ | ||
1177 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_6 0x00000006 /* RW--V */ | ||
1178 | #define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_7 0x00000007 /* RW--V */ | ||
1179 | #define NV_PGRAPH_FFINTFC_FIFO_0_MTHD 14:4 /* RWXVF */ | ||
1180 | #define NV_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH 0x00000000 /* RW--V */ | ||
1181 | #define NV_PGRAPH_FFINTFC_FIFO_1(i) (0x00400740+(i)*4) /* RW-4A */ | ||
1182 | #define NV_PGRAPH_FFINTFC_FIFO_1__SIZE_1 4 /* */ | ||
1183 | #define NV_PGRAPH_FFINTFC_FIFO_1_ARGUMENT 31:0 /* RWXVF */ | ||
1184 | #define NV_PGRAPH_FFINTFC_FIFO_PTR 0x00400750 /* RW-4R */ | ||
1185 | #define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE 2:0 /* RWIVF */ | ||
1186 | #define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0 0x00000000 /* RWI-V */ | ||
1187 | #define NV_PGRAPH_FFINTFC_FIFO_PTR_READ 6:4 /* RWIVF */ | ||
1188 | #define NV_PGRAPH_FFINTFC_FIFO_PTR_READ_0 0x00000000 /* RWI-V */ | ||
1189 | #define NV_PGRAPH_FFINTFC_ST2 0x00400754 /* RW-4R */ | ||
1190 | #define NV_PGRAPH_FFINTFC_ST2_STATUS 0:0 /* RWIVF */ | ||
1191 | #define NV_PGRAPH_FFINTFC_ST2_STATUS_INVALID 0x00000000 /* RWI-V */ | ||
1192 | #define NV_PGRAPH_FFINTFC_ST2_STATUS_VALID 0x00000001 /* RW--V */ | ||
1193 | #define NV_PGRAPH_FFINTFC_ST2_MTHD 11:1 /* RWIVF */ | ||
1194 | #define NV_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH 0x00000000 /* RWI-V */ | ||
1195 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH 14:12 /* RWIVF */ | ||
1196 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_0 0x00000000 /* RWI-V */ | ||
1197 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_1 0x00000001 /* RW--V */ | ||
1198 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_2 0x00000002 /* RW--V */ | ||
1199 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_3 0x00000003 /* RW--V */ | ||
1200 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_4 0x00000004 /* RW--V */ | ||
1201 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_5 0x00000005 /* RW--V */ | ||
1202 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_6 0x00000006 /* RW--V */ | ||
1203 | #define NV_PGRAPH_FFINTFC_ST2_SUBCH_7 0x00000007 /* RW--V */ | ||
1204 | #define NV_PGRAPH_FFINTFC_ST2_CHID 18:15 /* RWIVF */ | ||
1205 | #define NV_PGRAPH_FFINTFC_ST2_CHID_0 0x00000000 /* RWI-V */ | ||
1206 | #define NV_PGRAPH_FFINTFC_ST2_CHID_1 0x00000001 /* RW--V */ | ||
1207 | #define NV_PGRAPH_FFINTFC_ST2_CHID_2 0x00000002 /* RW--V */ | ||
1208 | #define NV_PGRAPH_FFINTFC_ST2_CHID_3 0x00000003 /* RW--V */ | ||
1209 | #define NV_PGRAPH_FFINTFC_ST2_CHID_4 0x00000004 /* RW--V */ | ||
1210 | #define NV_PGRAPH_FFINTFC_ST2_CHID_5 0x00000005 /* RW--V */ | ||
1211 | #define NV_PGRAPH_FFINTFC_ST2_CHID_6 0x00000006 /* RW--V */ | ||
1212 | #define NV_PGRAPH_FFINTFC_ST2_CHID_7 0x00000007 /* RW--V */ | ||
1213 | #define NV_PGRAPH_FFINTFC_ST2_CHID_8 0x00000008 /* RW--V */ | ||
1214 | #define NV_PGRAPH_FFINTFC_ST2_CHID_9 0x00000009 /* RW--V */ | ||
1215 | #define NV_PGRAPH_FFINTFC_ST2_CHID_10 0x0000000A /* RW--V */ | ||
1216 | #define NV_PGRAPH_FFINTFC_ST2_CHID_11 0x0000000B /* RW--V */ | ||
1217 | #define NV_PGRAPH_FFINTFC_ST2_CHID_12 0x0000000C /* RW--V */ | ||
1218 | #define NV_PGRAPH_FFINTFC_ST2_CHID_13 0x0000000D /* RW--V */ | ||
1219 | #define NV_PGRAPH_FFINTFC_ST2_CHID_14 0x0000000E /* RW--V */ | ||
1220 | #define NV_PGRAPH_FFINTFC_ST2_CHID_15 0x0000000F /* RW--V */ | ||
1221 | #define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS 19:19 /* RWIVF */ | ||
1222 | #define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID 0x00000000 /* RWI-V */ | ||
1223 | #define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID 0x00000001 /* RW--V */ | ||
1224 | #define NV_PGRAPH_FFINTFC_ST2_D 0x00400758 /* RW-4R */ | ||
1225 | #define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT 31:0 /* RWIVF */ | ||
1226 | #define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0 0x00000000 /* RWI-V */ | ||
1227 | #define NV_PGRAPH_STATUS 0x00400700 /* R--4R */ | ||
1228 | #define NV_PGRAPH_STATUS_STATE 0:0 /* R-IVF */ | ||
1229 | #define NV_PGRAPH_STATUS_STATE_IDLE 0x00000000 /* R-I-V */ | ||
1230 | #define NV_PGRAPH_STATUS_STATE_BUSY 0x00000001 /* R---V */ | ||
1231 | #define NV_PGRAPH_STATUS_XY_LOGIC 4:4 /* R-IVF */ | ||
1232 | #define NV_PGRAPH_STATUS_XY_LOGIC_IDLE 0x00000000 /* R-I-V */ | ||
1233 | #define NV_PGRAPH_STATUS_XY_LOGIC_BUSY 0x00000001 /* R---V */ | ||
1234 | #define NV_PGRAPH_STATUS_FE 5:5 /* R-IVF */ | ||
1235 | #define NV_PGRAPH_STATUS_FE_IDLE 0x00000000 /* R-I-V */ | ||
1236 | #define NV_PGRAPH_STATUS_FE_BUSY 0x00000001 /* R---V */ | ||
1237 | #define NV_PGRAPH_STATUS_RASTERIZER 6:6 /* R-IVF */ | ||
1238 | #define NV_PGRAPH_STATUS_RASTERIZER_IDLE 0x00000000 /* R-I-V */ | ||
1239 | #define NV_PGRAPH_STATUS_RASTERIZER_BUSY 0x00000001 /* R---V */ | ||
1240 | #define NV_PGRAPH_STATUS_PORT_NOTIFY 8:8 /* R-IVF */ | ||
1241 | #define NV_PGRAPH_STATUS_PORT_NOTIFY_IDLE 0x00000000 /* R-I-V */ | ||
1242 | #define NV_PGRAPH_STATUS_PORT_NOTIFY_BUSY 0x00000001 /* R---V */ | ||
1243 | #define NV_PGRAPH_STATUS_PORT_REGISTER 12:12 /* R-IVF */ | ||
1244 | #define NV_PGRAPH_STATUS_PORT_REGISTER_IDLE 0x00000000 /* R-I-V */ | ||
1245 | #define NV_PGRAPH_STATUS_PORT_REGISTER_BUSY 0x00000001 /* R---V */ | ||
1246 | #define NV_PGRAPH_STATUS_PORT_DMA 16:16 /* R-IVF */ | ||
1247 | #define NV_PGRAPH_STATUS_PORT_DMA_IDLE 0x00000000 /* R-I-V */ | ||
1248 | #define NV_PGRAPH_STATUS_PORT_DMA_BUSY 0x00000001 /* R---V */ | ||
1249 | #define NV_PGRAPH_STATUS_DMA_ENGINE 17:17 /* R-IVF */ | ||
1250 | #define NV_PGRAPH_STATUS_DMA_ENGINE_IDLE 0x00000000 /* R-I-V */ | ||
1251 | #define NV_PGRAPH_STATUS_DMA_ENGINE_BUSY 0x00000001 /* R---V */ | ||
1252 | #define NV_PGRAPH_STATUS_DMA_NOTIFY 20:20 /* R-IVF */ | ||
1253 | #define NV_PGRAPH_STATUS_DMA_NOTIFY_IDLE 0x00000000 /* R-I-V */ | ||
1254 | #define NV_PGRAPH_STATUS_DMA_NOTIFY_BUSY 0x00000001 /* R---V */ | ||
1255 | #define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY 21:21 /* R-IVF */ | ||
1256 | #define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE 0x00000000 /* R-I-V */ | ||
1257 | #define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY 0x00000001 /* R---V */ | ||
1258 | #define NV_PGRAPH_STATUS_D3D 24:24 /* R-IVF */ | ||
1259 | #define NV_PGRAPH_STATUS_D3D_IDLE 0x00000000 /* R-I-V */ | ||
1260 | #define NV_PGRAPH_STATUS_D3D_BUSY 0x00000001 /* R---V */ | ||
1261 | #define NV_PGRAPH_STATUS_CACHE 25:25 /* R-IVF */ | ||
1262 | #define NV_PGRAPH_STATUS_CACHE_IDLE 0x00000000 /* R-I-V */ | ||
1263 | #define NV_PGRAPH_STATUS_CACHE_BUSY 0x00000001 /* R---V */ | ||
1264 | #define NV_PGRAPH_STATUS_LIGHTING 26:26 /* R-IVF */ | ||
1265 | #define NV_PGRAPH_STATUS_LIGHTING_IDLE 0x00000000 /* R-I-V */ | ||
1266 | #define NV_PGRAPH_STATUS_LIGHTING_BUSY 0x00000001 /* R---V */ | ||
1267 | #define NV_PGRAPH_STATUS_PREROP 27:27 /* R-IVF */ | ||
1268 | #define NV_PGRAPH_STATUS_PREROP_IDLE 0x00000000 /* R-I-V */ | ||
1269 | #define NV_PGRAPH_STATUS_PREROP_BUSY 0x00000001 /* R---V */ | ||
1270 | #define NV_PGRAPH_STATUS_ROP 28:28 /* R-IVF */ | ||
1271 | #define NV_PGRAPH_STATUS_ROP_IDLE 0x00000000 /* R-I-V */ | ||
1272 | #define NV_PGRAPH_STATUS_ROP_BUSY 0x00000001 /* R---V */ | ||
1273 | #define NV_PGRAPH_STATUS_PORT_USER 29:29 /* R-IVF */ | ||
1274 | #define NV_PGRAPH_STATUS_PORT_USER_IDLE 0x00000000 /* R-I-V */ | ||
1275 | #define NV_PGRAPH_STATUS_PORT_USER_BUSY 0x00000001 /* R---V */ | ||
1276 | #define NV_PGRAPH_TRAPPED_ADDR 0x00400704 /* R--4R */ | ||
1277 | #define NV_PGRAPH_TRAPPED_ADDR_MTHD 12:2 /* R-XUF */ | ||
1278 | #define NV_PGRAPH_TRAPPED_ADDR_SUBCH 15:13 /* R-XUF */ | ||
1279 | #define NV_PGRAPH_TRAPPED_ADDR_CHID 27:24 /* R-XUF */ | ||
1280 | #define NV_PGRAPH_TRAPPED_DATA 0x00400708 /* R--4R */ | ||
1281 | #define NV_PGRAPH_TRAPPED_DATA_VALUE 31:0 /* R-XVF */ | ||
1282 | #define NV_PGRAPH_SURFACE 0x0040070C /* RW-4R */ | ||
1283 | #define NV_PGRAPH_SURFACE_TYPE 1:0 /* RWIVF */ | ||
1284 | #define NV_PGRAPH_SURFACE_TYPE_INVALID 0x00000000 /* RWI-V */ | ||
1285 | #define NV_PGRAPH_SURFACE_TYPE_NON_SWIZZLE 0x00000001 /* RW--V */ | ||
1286 | #define NV_PGRAPH_SURFACE_TYPE_SWIZZLE 0x00000002 /* RW--V */ | ||
1287 | #define NV_PGRAPH_NOTIFY 0x00400714 /* RW-4R */ | ||
1288 | #define NV_PGRAPH_NOTIFY_BUFFER_REQ 0:0 /* RWIVF */ | ||
1289 | #define NV_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING 0x00000000 /* RWI-V */ | ||
1290 | #define NV_PGRAPH_NOTIFY_BUFFER_REQ_PENDING 0x00000001 /* RW--V */ | ||
1291 | #define NV_PGRAPH_NOTIFY_BUFFER_STYLE 8:8 /* RWIVF */ | ||
1292 | #define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */ | ||
1293 | #define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */ | ||
1294 | #define NV_PGRAPH_NOTIFY_REQ 16:16 /* RWIVF */ | ||
1295 | #define NV_PGRAPH_NOTIFY_REQ_NOT_PENDING 0x00000000 /* RWI-V */ | ||
1296 | #define NV_PGRAPH_NOTIFY_REQ_PENDING 0x00000001 /* RW--V */ | ||
1297 | #define NV_PGRAPH_NOTIFY_STYLE 20:20 /* RWIVF */ | ||
1298 | #define NV_PGRAPH_NOTIFY_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */ | ||
1299 | #define NV_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */ | ||
1300 | #define NV_PGRAPH_BOFFSET(i) (0x00400640+(i)*4) /* RW-4A */ | ||
1301 | #define NV_PGRAPH_BOFFSET__SIZE_1 6 /* */ | ||
1302 | #define NV_PGRAPH_BOFFSET_LINADRS 23:0 /* RWIUF */ | ||
1303 | #define NV_PGRAPH_BOFFSET_LINADRS_0 0x00000000 /* RWI-V */ | ||
1304 | #define NV_PGRAPH_BOFFSET0 0x00400640 /* RW-4R */ | ||
1305 | #define NV_PGRAPH_BOFFSET0__ALIAS_1 NV_PGRAPH_BOFFSET(0) /* */ | ||
1306 | #define NV_PGRAPH_BOFFSET0_LINADRS 23:0 /* RWIUF */ | ||
1307 | #define NV_PGRAPH_BOFFSET0_LINADRS_0 0x00000000 /* RWI-V */ | ||
1308 | #define NV_PGRAPH_BOFFSET1 0x00400644 /* RW-4R */ | ||
1309 | #define NV_PGRAPH_BOFFSET1__ALIAS_1 NV_PGRAPH_BOFFSET(1) /* */ | ||
1310 | #define NV_PGRAPH_BOFFSET1_LINADRS 23:0 /* RWIUF */ | ||
1311 | #define NV_PGRAPH_BOFFSET1_LINADRS_0 0x00000000 /* RWI-V */ | ||
1312 | #define NV_PGRAPH_BOFFSET2 0x00400648 /* RW-4R */ | ||
1313 | #define NV_PGRAPH_BOFFSET2__ALIAS_1 NV_PGRAPH_BOFFSET(2) /* */ | ||
1314 | #define NV_PGRAPH_BOFFSET2_LINADRS 23:0 /* RWIUF */ | ||
1315 | #define NV_PGRAPH_BOFFSET2_LINADRS_0 0x00000000 /* RWI-V */ | ||
1316 | #define NV_PGRAPH_BOFFSET3 0x0040064C /* RW-4R */ | ||
1317 | #define NV_PGRAPH_BOFFSET3__ALIAS_1 NV_PGRAPH_BOFFSET(3) /* */ | ||
1318 | #define NV_PGRAPH_BOFFSET3_LINADRS 23:0 /* RWIUF */ | ||
1319 | #define NV_PGRAPH_BOFFSET3_LINADRS_0 0x00000000 /* RWI-V */ | ||
1320 | #define NV_PGRAPH_BOFFSET4 0x00400650 /* RW-4R */ | ||
1321 | #define NV_PGRAPH_BOFFSET4__ALIAS_1 NV_PGRAPH_BOFFSET(4) /* */ | ||
1322 | #define NV_PGRAPH_BOFFSET4_LINADRS 23:0 /* RWIUF */ | ||
1323 | #define NV_PGRAPH_BOFFSET4_LINADRS_0 0x00000000 /* RWI-V */ | ||
1324 | #define NV_PGRAPH_BOFFSET5 0x00400654 /* RW-4R */ | ||
1325 | #define NV_PGRAPH_BOFFSET5__ALIAS_1 NV_PGRAPH_BOFFSET(5) /* */ | ||
1326 | #define NV_PGRAPH_BOFFSET5_LINADRS 23:0 /* RWIUF */ | ||
1327 | #define NV_PGRAPH_BOFFSET5_LINADRS_0 0x00000000 /* RWI-V */ | ||
1328 | #define NV_PGRAPH_BBASE(i) (0x00400658+(i)*4) /* RW-4A */ | ||
1329 | #define NV_PGRAPH_BBASE__SIZE_1 6 /* */ | ||
1330 | #define NV_PGRAPH_BBASE_LINADRS 23:0 /* RWIUF */ | ||
1331 | #define NV_PGRAPH_BBASE_LINADRS_0 0x00000000 /* RWI-V */ | ||
1332 | #define NV_PGRAPH_BBASE0 0x00400658 /* RW-4R */ | ||
1333 | #define NV_PGRAPH_BBASE0__ALIAS_1 NV_PGRAPH_BBASE(0) /* */ | ||
1334 | #define NV_PGRAPH_BBASE0_LINADRS 23:0 /* RWIUF */ | ||
1335 | #define NV_PGRAPH_BBASE0_LINADRS_0 0x00000000 /* RWI-V */ | ||
1336 | #define NV_PGRAPH_BBASE1 0x0040065c /* RW-4R */ | ||
1337 | #define NV_PGRAPH_BBASE1__ALIAS_1 NV_PGRAPH_BBASE(1) /* */ | ||
1338 | #define NV_PGRAPH_BBASE1_LINADRS 23:0 /* RWIUF */ | ||
1339 | #define NV_PGRAPH_BBASE1_LINADRS_0 0x00000000 /* RWI-V */ | ||
1340 | #define NV_PGRAPH_BBASE2 0x00400660 /* RW-4R */ | ||
1341 | #define NV_PGRAPH_BBASE2__ALIAS_1 NV_PGRAPH_BBASE(2) /* */ | ||
1342 | #define NV_PGRAPH_BBASE2_LINADRS 23:0 /* RWIUF */ | ||
1343 | #define NV_PGRAPH_BBASE2_LINADRS_0 0x00000000 /* RWI-V */ | ||
1344 | #define NV_PGRAPH_BBASE3 0x00400664 /* RW-4R */ | ||
1345 | #define NV_PGRAPH_BBASE3__ALIAS_1 NV_PGRAPH_BBASE(3) /* */ | ||
1346 | #define NV_PGRAPH_BBASE3_LINADRS 23:0 /* RWIUF */ | ||
1347 | #define NV_PGRAPH_BBASE3_LINADRS_0 0x00000000 /* RWI-V */ | ||
1348 | #define NV_PGRAPH_BBASE4 0x00400668 /* RW-4R */ | ||
1349 | #define NV_PGRAPH_BBASE4__ALIAS_1 NV_PGRAPH_BBASE(4) /* */ | ||
1350 | #define NV_PGRAPH_BBASE4_LINADRS 23:0 /* RWIUF */ | ||
1351 | #define NV_PGRAPH_BBASE4_LINADRS_0 0x00000000 /* RWI-V */ | ||
1352 | #define NV_PGRAPH_BBASE5 0x0040066C /* RW-4R */ | ||
1353 | #define NV_PGRAPH_BBASE5__ALIAS_1 NV_PGRAPH_BBASE(5) /* */ | ||
1354 | #define NV_PGRAPH_BBASE5_LINADRS 23:0 /* RWIUF */ | ||
1355 | #define NV_PGRAPH_BBASE5_LINADRS_0 0x00000000 /* RWI-V */ | ||
1356 | #define NV_PGRAPH_BPITCH(i) (0x00400670+(i)*4) /* RW-4A */ | ||
1357 | #define NV_PGRAPH_BPITCH__SIZE_1 5 /* */ | ||
1358 | #define NV_PGRAPH_BPITCH_VALUE 12:0 /* RWIUF */ | ||
1359 | #define NV_PGRAPH_BPITCH_VALUE_0 0x00000000 /* RWI-V */ | ||
1360 | #define NV_PGRAPH_BPITCH0 0x00400670 /* RW-4R */ | ||
1361 | #define NV_PGRAPH_BPITCH0__ALIAS_1 NV_PGRAPH_BPITCH(0) /* */ | ||
1362 | #define NV_PGRAPH_BPITCH0_VALUE 12:0 /* RWIUF */ | ||
1363 | #define NV_PGRAPH_BPITCH0_VALUE_0 0x00000000 /* RWI-V */ | ||
1364 | #define NV_PGRAPH_BPITCH1 0x00400674 /* RW-4R */ | ||
1365 | #define NV_PGRAPH_BPITCH1__ALIAS_1 NV_PGRAPH_BPITCH(1) /* */ | ||
1366 | #define NV_PGRAPH_BPITCH1_VALUE 12:0 /* RWIUF */ | ||
1367 | #define NV_PGRAPH_BPITCH1_VALUE_0 0x00000000 /* RWI-V */ | ||
1368 | #define NV_PGRAPH_BPITCH2 0x00400678 /* RW-4R */ | ||
1369 | #define NV_PGRAPH_BPITCH2__ALIAS_1 NV_PGRAPH_BPITCH(2) /* */ | ||
1370 | #define NV_PGRAPH_BPITCH2_VALUE 12:0 /* RWIUF */ | ||
1371 | #define NV_PGRAPH_BPITCH2_VALUE_0 0x00000000 /* RWI-V */ | ||
1372 | #define NV_PGRAPH_BPITCH3 0x0040067C /* RW-4R */ | ||
1373 | #define NV_PGRAPH_BPITCH3__ALIAS_1 NV_PGRAPH_BPITCH(3) /* */ | ||
1374 | #define NV_PGRAPH_BPITCH3_VALUE 12:0 /* RWIUF */ | ||
1375 | #define NV_PGRAPH_BPITCH3_VALUE_0 0x00000000 /* RWI-V */ | ||
1376 | #define NV_PGRAPH_BPITCH4 0x00400680 /* RW-4R */ | ||
1377 | #define NV_PGRAPH_BPITCH4__ALIAS_1 NV_PGRAPH_BPITCH(4) /* */ | ||
1378 | #define NV_PGRAPH_BPITCH4_VALUE 12:0 /* RWIUF */ | ||
1379 | #define NV_PGRAPH_BPITCH4_VALUE_0 0x00000000 /* RWI-V */ | ||
1380 | #define NV_PGRAPH_BLIMIT(i) (0x00400684+(i)*4) /* RW-4A */ | ||
1381 | #define NV_PGRAPH_BLIMIT__SIZE_1 6 /* */ | ||
1382 | #define NV_PGRAPH_BLIMIT_VALUE 23:0 /* RWXUF */ | ||
1383 | #define NV_PGRAPH_BLIMIT_TYPE 31:31 /* RWIVF */ | ||
1384 | #define NV_PGRAPH_BLIMIT_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1385 | #define NV_PGRAPH_BLIMIT_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1386 | #define NV_PGRAPH_BLIMIT0 0x00400684 /* RW-4R */ | ||
1387 | #define NV_PGRAPH_BLIMIT0__ALIAS_1 NV_PGRAPH_BLIMIT(0) /* */ | ||
1388 | #define NV_PGRAPH_BLIMIT0_VALUE 23:0 /* RWXUF */ | ||
1389 | #define NV_PGRAPH_BLIMIT0_TYPE 31:31 /* RWIVF */ | ||
1390 | #define NV_PGRAPH_BLIMIT0_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1391 | #define NV_PGRAPH_BLIMIT0_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1392 | #define NV_PGRAPH_BLIMIT1 0x00400688 /* RW-4R */ | ||
1393 | #define NV_PGRAPH_BLIMIT1__ALIAS_1 NV_PGRAPH_BLIMIT(1) /* */ | ||
1394 | #define NV_PGRAPH_BLIMIT1_VALUE 23:0 /* RWXUF */ | ||
1395 | #define NV_PGRAPH_BLIMIT1_TYPE 31:31 /* RWIVF */ | ||
1396 | #define NV_PGRAPH_BLIMIT1_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1397 | #define NV_PGRAPH_BLIMIT1_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1398 | #define NV_PGRAPH_BLIMIT2 0x0040068c /* RW-4R */ | ||
1399 | #define NV_PGRAPH_BLIMIT2__ALIAS_1 NV_PGRAPH_BLIMIT(2) /* */ | ||
1400 | #define NV_PGRAPH_BLIMIT2_VALUE 23:0 /* RWXUF */ | ||
1401 | #define NV_PGRAPH_BLIMIT2_TYPE 31:31 /* RWIVF */ | ||
1402 | #define NV_PGRAPH_BLIMIT2_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1403 | #define NV_PGRAPH_BLIMIT2_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1404 | #define NV_PGRAPH_BLIMIT3 0x00400690 /* RW-4R */ | ||
1405 | #define NV_PGRAPH_BLIMIT3__ALIAS_1 NV_PGRAPH_BLIMIT(3) /* */ | ||
1406 | #define NV_PGRAPH_BLIMIT3_VALUE 23:0 /* RWXUF */ | ||
1407 | #define NV_PGRAPH_BLIMIT3_TYPE 31:31 /* RWIVF */ | ||
1408 | #define NV_PGRAPH_BLIMIT3_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1409 | #define NV_PGRAPH_BLIMIT3_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1410 | #define NV_PGRAPH_BLIMIT4 0x00400694 /* RW-4R */ | ||
1411 | #define NV_PGRAPH_BLIMIT4__ALIAS_1 NV_PGRAPH_BLIMIT(4) /* */ | ||
1412 | #define NV_PGRAPH_BLIMIT4_VALUE 23:0 /* RWXUF */ | ||
1413 | #define NV_PGRAPH_BLIMIT4_TYPE 31:31 /* RWIVF */ | ||
1414 | #define NV_PGRAPH_BLIMIT4_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1415 | #define NV_PGRAPH_BLIMIT4_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1416 | #define NV_PGRAPH_BLIMIT5 0x00400698 /* RW-4R */ | ||
1417 | #define NV_PGRAPH_BLIMIT5__ALIAS_1 NV_PGRAPH_BLIMIT(5) /* */ | ||
1418 | #define NV_PGRAPH_BLIMIT5_VALUE 23:0 /* RWXUF */ | ||
1419 | #define NV_PGRAPH_BLIMIT5_TYPE 31:31 /* RWIVF */ | ||
1420 | #define NV_PGRAPH_BLIMIT5_TYPE_IN_MEMORY 0x00000000 /* RW--V */ | ||
1421 | #define NV_PGRAPH_BLIMIT5_TYPE_NULL 0x00000001 /* RWI-V */ | ||
1422 | #define NV_PGRAPH_BSWIZZLE2 0x0040069c /* RW-4R */ | ||
1423 | #define NV_PGRAPH_BSWIZZLE2_WIDTH 19:16 /* RWIUF */ | ||
1424 | #define NV_PGRAPH_BSWIZZLE2_WIDTH_0 0x00000000 /* RWI-V */ | ||
1425 | #define NV_PGRAPH_BSWIZZLE2_HEIGHT 27:24 /* RWIUF */ | ||
1426 | #define NV_PGRAPH_BSWIZZLE2_HEIGHT_0 0x00000000 /* RWI-V */ | ||
1427 | #define NV_PGRAPH_BSWIZZLE5 0x004006a0 /* RW-4R */ | ||
1428 | #define NV_PGRAPH_BSWIZZLE5_WIDTH 19:16 /* RWIUF */ | ||
1429 | #define NV_PGRAPH_BSWIZZLE5_WIDTH_0 0x00000000 /* RWI-V */ | ||
1430 | #define NV_PGRAPH_BSWIZZLE5_HEIGHT 27:24 /* RWIUF */ | ||
1431 | #define NV_PGRAPH_BSWIZZLE5_HEIGHT_0 0x00000000 /* RWI-V */ | ||
1432 | #define NV_PGRAPH_BPIXEL 0x00400724 /* RW-4R */ | ||
1433 | #define NV_PGRAPH_BPIXEL_DEPTH0 3:0 /* RWIVF */ | ||
1434 | #define NV_PGRAPH_BPIXEL_DEPTH0_INVALID 0x00000000 /* RWI-V */ | ||
1435 | #define NV_PGRAPH_BPIXEL_DEPTH0_Y8 0x00000001 /* RW--V */ | ||
1436 | #define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1437 | #define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1438 | #define NV_PGRAPH_BPIXEL_DEPTH0_A1R5G5B5 0x00000004 /* RW--V */ | ||
1439 | #define NV_PGRAPH_BPIXEL_DEPTH0_R5G6B5 0x00000005 /* RW--V */ | ||
1440 | #define NV_PGRAPH_BPIXEL_DEPTH0_Y16 0x00000006 /* RW--V */ | ||
1441 | #define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1442 | #define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1443 | #define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1444 | #define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1445 | #define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1446 | #define NV_PGRAPH_BPIXEL_DEPTH0_A8R8G8B8 0x0000000c /* RW--V */ | ||
1447 | #define NV_PGRAPH_BPIXEL_DEPTH0_Y32 0x0000000d /* RW--V */ | ||
1448 | #define NV_PGRAPH_BPIXEL_DEPTH0_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1449 | #define NV_PGRAPH_BPIXEL_DEPTH0_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1450 | #define NV_PGRAPH_BPIXEL_DEPTH1 7:4 /* RWIVF */ | ||
1451 | #define NV_PGRAPH_BPIXEL_DEPTH1_INVALID 0x00000000 /* RWI-V */ | ||
1452 | #define NV_PGRAPH_BPIXEL_DEPTH1_Y8 0x00000001 /* RW--V */ | ||
1453 | #define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1454 | #define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1455 | #define NV_PGRAPH_BPIXEL_DEPTH1_A1R5G5B5 0x00000004 /* RW--V */ | ||
1456 | #define NV_PGRAPH_BPIXEL_DEPTH1_R5G6B5 0x00000005 /* RW--V */ | ||
1457 | #define NV_PGRAPH_BPIXEL_DEPTH1_Y16 0x00000006 /* RW--V */ | ||
1458 | #define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1459 | #define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1460 | #define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1461 | #define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1462 | #define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1463 | #define NV_PGRAPH_BPIXEL_DEPTH1_A8R8G8B8 0x0000000c /* RW--V */ | ||
1464 | #define NV_PGRAPH_BPIXEL_DEPTH1_Y32 0x0000000d /* RW--V */ | ||
1465 | #define NV_PGRAPH_BPIXEL_DEPTH1_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1466 | #define NV_PGRAPH_BPIXEL_DEPTH1_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1467 | #define NV_PGRAPH_BPIXEL_DEPTH2 11:8 /* RWIVF */ | ||
1468 | #define NV_PGRAPH_BPIXEL_DEPTH2_INVALID 0x00000000 /* RWI-V */ | ||
1469 | #define NV_PGRAPH_BPIXEL_DEPTH2_Y8 0x00000001 /* RW--V */ | ||
1470 | #define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1471 | #define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1472 | #define NV_PGRAPH_BPIXEL_DEPTH2_A1R5G5B5 0x00000004 /* RW--V */ | ||
1473 | #define NV_PGRAPH_BPIXEL_DEPTH2_R5G6B5 0x00000005 /* RW--V */ | ||
1474 | #define NV_PGRAPH_BPIXEL_DEPTH2_Y16 0x00000006 /* RW--V */ | ||
1475 | #define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1476 | #define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1477 | #define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1478 | #define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1479 | #define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1480 | #define NV_PGRAPH_BPIXEL_DEPTH2_A8R8G8B8 0x0000000c /* RW--V */ | ||
1481 | #define NV_PGRAPH_BPIXEL_DEPTH2_Y32 0x0000000d /* RW--V */ | ||
1482 | #define NV_PGRAPH_BPIXEL_DEPTH2_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1483 | #define NV_PGRAPH_BPIXEL_DEPTH2_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1484 | #define NV_PGRAPH_BPIXEL_DEPTH3 15:12 /* RWIVF */ | ||
1485 | #define NV_PGRAPH_BPIXEL_DEPTH3_INVALID 0x00000000 /* RWI-V */ | ||
1486 | #define NV_PGRAPH_BPIXEL_DEPTH3_Y8 0x00000001 /* RW--V */ | ||
1487 | #define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1488 | #define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1489 | #define NV_PGRAPH_BPIXEL_DEPTH3_A1R5G5B5 0x00000004 /* RW--V */ | ||
1490 | #define NV_PGRAPH_BPIXEL_DEPTH3_R5G6B5 0x00000005 /* RW--V */ | ||
1491 | #define NV_PGRAPH_BPIXEL_DEPTH3_Y16 0x00000006 /* RW--V */ | ||
1492 | #define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1493 | #define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1494 | #define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1495 | #define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1496 | #define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1497 | #define NV_PGRAPH_BPIXEL_DEPTH3_A8R8G8B8 0x0000000c /* RW--V */ | ||
1498 | #define NV_PGRAPH_BPIXEL_DEPTH3_Y32 0x0000000d /* RW--V */ | ||
1499 | #define NV_PGRAPH_BPIXEL_DEPTH3_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1500 | #define NV_PGRAPH_BPIXEL_DEPTH3_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1501 | #define NV_PGRAPH_BPIXEL_DEPTH4 19:16 /* RWIVF */ | ||
1502 | #define NV_PGRAPH_BPIXEL_DEPTH4_INVALID 0x00000000 /* RWI-V */ | ||
1503 | #define NV_PGRAPH_BPIXEL_DEPTH4_Y8 0x00000001 /* RW--V */ | ||
1504 | #define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1505 | #define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1506 | #define NV_PGRAPH_BPIXEL_DEPTH4_A1R5G5B5 0x00000004 /* RW--V */ | ||
1507 | #define NV_PGRAPH_BPIXEL_DEPTH4_R5G6B5 0x00000005 /* RW--V */ | ||
1508 | #define NV_PGRAPH_BPIXEL_DEPTH4_Y16 0x00000006 /* RW--V */ | ||
1509 | #define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1510 | #define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1511 | #define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1512 | #define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1513 | #define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1514 | #define NV_PGRAPH_BPIXEL_DEPTH4_A8R8G8B8 0x0000000c /* RW--V */ | ||
1515 | #define NV_PGRAPH_BPIXEL_DEPTH4_Y32 0x0000000d /* RW--V */ | ||
1516 | #define NV_PGRAPH_BPIXEL_DEPTH4_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1517 | #define NV_PGRAPH_BPIXEL_DEPTH4_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1518 | #define NV_PGRAPH_BPIXEL_DEPTH5 23:20 /* RWIVF */ | ||
1519 | #define NV_PGRAPH_BPIXEL_DEPTH5_INVALID 0x00000000 /* RWI-V */ | ||
1520 | #define NV_PGRAPH_BPIXEL_DEPTH5_Y8 0x00000001 /* RW--V */ | ||
1521 | #define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1522 | #define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1523 | #define NV_PGRAPH_BPIXEL_DEPTH5_A1R5G5B5 0x00000004 /* RW--V */ | ||
1524 | #define NV_PGRAPH_BPIXEL_DEPTH5_R5G6B5 0x00000005 /* RW--V */ | ||
1525 | #define NV_PGRAPH_BPIXEL_DEPTH5_Y16 0x00000006 /* RW--V */ | ||
1526 | #define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1527 | #define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1528 | #define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1529 | #define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1530 | #define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1531 | #define NV_PGRAPH_BPIXEL_DEPTH5_A8R8G8B8 0x0000000c /* RW--V */ | ||
1532 | #define NV_PGRAPH_BPIXEL_DEPTH5_Y32 0x0000000d /* RW--V */ | ||
1533 | #define NV_PGRAPH_BPIXEL_DEPTH5_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1534 | #define NV_PGRAPH_BPIXEL_DEPTH5_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1535 | #define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 /* RW-4R */ | ||
1536 | #define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS 23:0 /* RWIVF */ | ||
1537 | #define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS_0 0x00000000 /* RWI-V */ | ||
1538 | #define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT 29:29 /* RWIVF */ | ||
1539 | #define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL 0x00000000 /* RWI-V */ | ||
1540 | #define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL 0x00000001 /* RW--V */ | ||
1541 | #define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT 30:30 /* RWIVF */ | ||
1542 | #define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL 0x00000000 /* RWI-V */ | ||
1543 | #define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL 0x00000001 /* RW--V */ | ||
1544 | #define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW 31:31 /* RWIVF */ | ||
1545 | #define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */ | ||
1546 | #define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL 0x00000001 /* RW--V */ | ||
1547 | #define NV_PGRAPH_LIMIT_VIOL_Z 0x00400614 /* RW-4R */ | ||
1548 | #define NV_PGRAPH_LIMIT_VIOL_Z_ADRS 23:0 /* RWIVF */ | ||
1549 | #define NV_PGRAPH_LIMIT_VIOL_Z_ADRS_0 0x00000000 /* RWI-V */ | ||
1550 | #define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT 30:30 /* RWIVF */ | ||
1551 | #define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL 0x00000000 /* RWI-V */ | ||
1552 | #define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL 0x00000001 /* RW--V */ | ||
1553 | #define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW 31:31 /* RWIVF */ | ||
1554 | #define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */ | ||
1555 | #define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL 0x00000001 /* RW--V */ | ||
1556 | #define NV_PGRAPH_STATE 0x00400710 /* RW-4R */ | ||
1557 | #define NV_PGRAPH_STATE_BUFFER_0 0:0 /* RWIVF */ | ||
1558 | #define NV_PGRAPH_STATE_BUFFER_0_INVALID 0x00000000 /* RWI-V */ | ||
1559 | #define NV_PGRAPH_STATE_BUFFER_0_VALID 0x00000001 /* RW--V */ | ||
1560 | #define NV_PGRAPH_STATE_BUFFER_1 1:1 /* RWIVF */ | ||
1561 | #define NV_PGRAPH_STATE_BUFFER_1_INVALID 0x00000000 /* RWI-V */ | ||
1562 | #define NV_PGRAPH_STATE_BUFFER_1_VALID 0x00000001 /* RW--V */ | ||
1563 | #define NV_PGRAPH_STATE_BUFFER_2 2:2 /* RWIVF */ | ||
1564 | #define NV_PGRAPH_STATE_BUFFER_2_INVALID 0x00000000 /* RWI-V */ | ||
1565 | #define NV_PGRAPH_STATE_BUFFER_2_VALID 0x00000001 /* RW--V */ | ||
1566 | #define NV_PGRAPH_STATE_BUFFER_3 3:3 /* RWIVF */ | ||
1567 | #define NV_PGRAPH_STATE_BUFFER_3_INVALID 0x00000000 /* RWI-V */ | ||
1568 | #define NV_PGRAPH_STATE_BUFFER_3_VALID 0x00000001 /* RW--V */ | ||
1569 | #define NV_PGRAPH_STATE_BUFFER_4 4:4 /* RWIVF */ | ||
1570 | #define NV_PGRAPH_STATE_BUFFER_4_INVALID 0x00000000 /* RWI-V */ | ||
1571 | #define NV_PGRAPH_STATE_BUFFER_4_VALID 0x00000001 /* RW--V */ | ||
1572 | #define NV_PGRAPH_STATE_BUFFER_5 5:5 /* RWIVF */ | ||
1573 | #define NV_PGRAPH_STATE_BUFFER_5_INVALID 0x00000000 /* RWI-V */ | ||
1574 | #define NV_PGRAPH_STATE_BUFFER_5_VALID 0x00000001 /* RW--V */ | ||
1575 | #define NV_PGRAPH_STATE_PITCH_0 8:8 /* RWIVF */ | ||
1576 | #define NV_PGRAPH_STATE_PITCH_0_INVALID 0x00000000 /* RWI-V */ | ||
1577 | #define NV_PGRAPH_STATE_PITCH_0_VALID 0x00000001 /* RW--V */ | ||
1578 | #define NV_PGRAPH_STATE_PITCH_1 9:9 /* RWIVF */ | ||
1579 | #define NV_PGRAPH_STATE_PITCH_1_INVALID 0x00000000 /* RWI-V */ | ||
1580 | #define NV_PGRAPH_STATE_PITCH_1_VALID 0x00000001 /* RW--V */ | ||
1581 | #define NV_PGRAPH_STATE_PITCH_2 10:10 /* RWIVF */ | ||
1582 | #define NV_PGRAPH_STATE_PITCH_2_INVALID 0x00000000 /* RWI-V */ | ||
1583 | #define NV_PGRAPH_STATE_PITCH_2_VALID 0x00000001 /* RW--V */ | ||
1584 | #define NV_PGRAPH_STATE_PITCH_3 11:11 /* RWIVF */ | ||
1585 | #define NV_PGRAPH_STATE_PITCH_3_INVALID 0x00000000 /* RWI-V */ | ||
1586 | #define NV_PGRAPH_STATE_PITCH_3_VALID 0x00000001 /* RW--V */ | ||
1587 | #define NV_PGRAPH_STATE_PITCH_4 12:12 /* RWIVF */ | ||
1588 | #define NV_PGRAPH_STATE_PITCH_4_INVALID 0x00000000 /* RWI-V */ | ||
1589 | #define NV_PGRAPH_STATE_PITCH_4_VALID 0x00000001 /* RW--V */ | ||
1590 | #define NV_PGRAPH_STATE_CHROMA_COLOR 16:16 /* RWIVF */ | ||
1591 | #define NV_PGRAPH_STATE_CHROMA_COLOR_INVALID 0x00000000 /* RWI-V */ | ||
1592 | #define NV_PGRAPH_STATE_CHROMA_COLOR_VALID 0x00000001 /* RW--V */ | ||
1593 | #define NV_PGRAPH_STATE_CHROMA_COLORFMT 17:17 /* RWIVF */ | ||
1594 | #define NV_PGRAPH_STATE_CHROMA_COLORFMT_INVALID 0x00000000 /* RWI-V */ | ||
1595 | #define NV_PGRAPH_STATE_CHROMA_COLORFMT_VALID 0x00000001 /* RW--V */ | ||
1596 | #define NV_PGRAPH_STATE_CPATTERN_COLORFMT 20:20 /* RWIVF */ | ||
1597 | #define NV_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID 0x00000000 /* RWI-V */ | ||
1598 | #define NV_PGRAPH_STATE_CPATTERN_COLORFMT_VALID 0x00000001 /* RW--V */ | ||
1599 | #define NV_PGRAPH_STATE_CPATTERN_MONOFMT 21:21 /* RWIVF */ | ||
1600 | #define NV_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID 0x00000000 /* RWI-V */ | ||
1601 | #define NV_PGRAPH_STATE_CPATTERN_MONOFMT_VALID 0x00000001 /* RW--V */ | ||
1602 | #define NV_PGRAPH_STATE_CPATTERN_SELECT 22:22 /* RWIVF */ | ||
1603 | #define NV_PGRAPH_STATE_CPATTERN_SELECT_INVALID 0x00000000 /* RWI-V */ | ||
1604 | #define NV_PGRAPH_STATE_CPATTERN_SELECT_VALID 0x00000001 /* RW--V */ | ||
1605 | #define NV_PGRAPH_STATE_PATTERN_COLOR0 24:24 /* RWIVF */ | ||
1606 | #define NV_PGRAPH_STATE_PATTERN_COLOR0_INVALID 0x00000000 /* RWI-V */ | ||
1607 | #define NV_PGRAPH_STATE_PATTERN_COLOR0_VALID 0x00000001 /* RW--V */ | ||
1608 | #define NV_PGRAPH_STATE_PATTERN_COLOR1 25:25 /* RWIVF */ | ||
1609 | #define NV_PGRAPH_STATE_PATTERN_COLOR1_INVALID 0x00000000 /* RWI-V */ | ||
1610 | #define NV_PGRAPH_STATE_PATTERN_COLOR1_VALID 0x00000001 /* RW--V */ | ||
1611 | #define NV_PGRAPH_STATE_PATTERN_PATT0 26:26 /* RWIVF */ | ||
1612 | #define NV_PGRAPH_STATE_PATTERN_PATT0_INVALID 0x00000000 /* RWI-V */ | ||
1613 | #define NV_PGRAPH_STATE_PATTERN_PATT0_VALID 0x00000001 /* RW--V */ | ||
1614 | #define NV_PGRAPH_STATE_PATTERN_PATT1 27:27 /* RWIVF */ | ||
1615 | #define NV_PGRAPH_STATE_PATTERN_PATT1_INVALID 0x00000000 /* RWI-V */ | ||
1616 | #define NV_PGRAPH_STATE_PATTERN_PATT1_VALID 0x00000001 /* RW--V */ | ||
1617 | #define NV_PGRAPH_CACHE_INDEX 0x00400728 /* RW-4R */ | ||
1618 | #define NV_PGRAPH_CACHE_INDEX_BANK 2:2 /* RWXVF */ | ||
1619 | #define NV_PGRAPH_CACHE_INDEX_BANK_10 0x00000000 /* RW--V */ | ||
1620 | #define NV_PGRAPH_CACHE_INDEX_BANK_32 0x00000001 /* RW--V */ | ||
1621 | #define NV_PGRAPH_CACHE_INDEX_ADRS 12:3 /* RWXVF */ | ||
1622 | #define NV_PGRAPH_CACHE_INDEX_ADRS_0 0x00000000 /* RW--V */ | ||
1623 | #define NV_PGRAPH_CACHE_INDEX_ADRS_1024 0x00000400 /* RW--V */ | ||
1624 | #define NV_PGRAPH_CACHE_INDEX_OP 14:13 /* RWXVF */ | ||
1625 | #define NV_PGRAPH_CACHE_INDEX_OP_WR_CACHE 0x00000000 /* RW--V */ | ||
1626 | #define NV_PGRAPH_CACHE_INDEX_OP_RD_CACHE 0x00000001 /* RW--V */ | ||
1627 | #define NV_PGRAPH_CACHE_INDEX_OP_RD_INDEX 0x00000002 /* RW--V */ | ||
1628 | #define NV_PGRAPH_CACHE_RAM 0x0040072c /* RW-4R */ | ||
1629 | #define NV_PGRAPH_CACHE_RAM_VALUE 31:0 /* RWXVF */ | ||
1630 | #define NV_PGRAPH_DMA_PITCH 0x00400760 /* RW-4R */ | ||
1631 | #define NV_PGRAPH_DMA_PITCH_S0 15:0 /* RWXSF */ | ||
1632 | #define NV_PGRAPH_DMA_PITCH_S1 31:16 /* RWXSF */ | ||
1633 | #define NV_PGRAPH_DVD_COLORFMT 0x00400764 /* RW-4R */ | ||
1634 | #define NV_PGRAPH_DVD_COLORFMT_IMAGE 5:0 /* RWNVF */ | ||
1635 | #define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID 0x00 /* RWN-V */ | ||
1636 | #define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */ | ||
1637 | #define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */ | ||
1638 | #define NV_PGRAPH_DVD_COLORFMT_OVLY 9:8 /* RWNVF */ | ||
1639 | #define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID 0x00 /* RWN-V */ | ||
1640 | #define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8 0x01 /* RW--V */ | ||
1641 | #define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6 0x02 /* RW--V */ | ||
1642 | #define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT 0x03 /* RW--V */ | ||
1643 | #define NV_PGRAPH_SCALED_FORMAT 0x00400768 /* RW-4R */ | ||
1644 | #define NV_PGRAPH_SCALED_FORMAT_ORIGIN 17:16 /* RWIVF */ | ||
1645 | #define NV_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID 0x00000000 /* RWI-V */ | ||
1646 | #define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER 0x00000001 /* RW--V */ | ||
1647 | #define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER 0x00000002 /* RW--V */ | ||
1648 | #define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR 24:24 /* RWIVF */ | ||
1649 | #define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH 0x00000000 /* RWI-V */ | ||
1650 | #define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH 0x00000001 /* RW--V */ | ||
1651 | #define NV_PGRAPH_PATT_COLOR0 0x00400800 /* RW-4R */ | ||
1652 | #define NV_PGRAPH_PATT_COLOR0_VALUE 31:0 /* RWXUF */ | ||
1653 | #define NV_PGRAPH_PATT_COLOR1 0x00400804 /* RW-4R */ | ||
1654 | #define NV_PGRAPH_PATT_COLOR1_VALUE 31:0 /* RWXUF */ | ||
1655 | #define NV_PGRAPH_PATT_COLORRAM(i) (0x00400900+(i)*4) /* R--4A */ | ||
1656 | #define NV_PGRAPH_PATT_COLORRAM__SIZE_1 64 /* */ | ||
1657 | #define NV_PGRAPH_PATT_COLORRAM_VALUE 23:0 /* R--UF */ | ||
1658 | #define NV_PGRAPH_PATTERN(i) (0x00400808+(i)*4) /* RW-4A */ | ||
1659 | #define NV_PGRAPH_PATTERN__SIZE_1 2 /* */ | ||
1660 | #define NV_PGRAPH_PATTERN_BITMAP 31:0 /* RWXVF */ | ||
1661 | #define NV_PGRAPH_PATTERN_SHAPE 0x00400810 /* RW-4R */ | ||
1662 | #define NV_PGRAPH_PATTERN_SHAPE_VALUE 1:0 /* RWXVF */ | ||
1663 | #define NV_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y 0x00000000 /* RW--V */ | ||
1664 | #define NV_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y 0x00000001 /* RW--V */ | ||
1665 | #define NV_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y 0x00000002 /* RW--V */ | ||
1666 | #define NV_PGRAPH_PATTERN_SHAPE_SELECT 4:4 /* RWXVF */ | ||
1667 | #define NV_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR 0x00000000 /* RW--V */ | ||
1668 | #define NV_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR 0x00000001 /* RW--V */ | ||
1669 | #define NV_PGRAPH_MONO_COLOR0 0x00400600 /* RW-4R */ | ||
1670 | #define NV_PGRAPH_MONO_COLOR0_VALUE 31:0 /* RWXUF */ | ||
1671 | #define NV_PGRAPH_ROP3 0x00400604 /* RW-4R */ | ||
1672 | #define NV_PGRAPH_ROP3_VALUE 7:0 /* RWXVF */ | ||
1673 | #define NV_PGRAPH_CHROMA 0x00400814 /* RW-4R */ | ||
1674 | #define NV_PGRAPH_CHROMA_VALUE 31:0 /* RWXUF */ | ||
1675 | #define NV_PGRAPH_BETA_AND 0x00400608 /* RW-4R */ | ||
1676 | #define NV_PGRAPH_BETA_AND_VALUE_FRACTION 30:23 /* RWXUF */ | ||
1677 | #define NV_PGRAPH_BETA_PREMULT 0x0040060c /* RW-4R */ | ||
1678 | #define NV_PGRAPH_BETA_PREMULT_VALUE 31:0 /* RWXUF */ | ||
1679 | #define NV_PGRAPH_CONTROL0 0x00400818 /* RW-4R */ | ||
1680 | #define NV_PGRAPH_CONTROL1 0x0040081c /* RW-4R */ | ||
1681 | #define NV_PGRAPH_CONTROL2 0x00400820 /* RW-4R */ | ||
1682 | #define NV_PGRAPH_BLEND 0x00400824 /* RW-4R */ | ||
1683 | #define NV_PGRAPH_DPRAM_INDEX 0x00400828 /* RW-4R */ | ||
1684 | #define NV_PGRAPH_DPRAM_INDEX_ADRS 6:0 /* RWIVF */ | ||
1685 | #define NV_PGRAPH_DPRAM_INDEX_ADRS_0 0x00000000 /* RWI-V */ | ||
1686 | #define NV_PGRAPH_DPRAM_INDEX_SELECT 10:8 /* RWIVF */ | ||
1687 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0 0x00000000 /* RWI-V */ | ||
1688 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1 0x00000001 /* RW--V */ | ||
1689 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_0 0x00000002 /* RW--V */ | ||
1690 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_1 0x00000003 /* RW--V */ | ||
1691 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_0 0x00000004 /* RW--V */ | ||
1692 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_1 0x00000005 /* RW--V */ | ||
1693 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0 0x00000006 /* RW--V */ | ||
1694 | #define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1 0x00000007 /* RW--V */ | ||
1695 | #define NV_PGRAPH_DPRAM_DATA 0x0040082c /* RW-4R */ | ||
1696 | #define NV_PGRAPH_DPRAM_DATA_VALUE 31:0 /* RWXVF */ | ||
1697 | #define NV_PGRAPH_DPRAM_ADRS_0 0x0040082c /* RW-4R */ | ||
1698 | #define NV_PGRAPH_DPRAM_ADRS_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1699 | #define NV_PGRAPH_DPRAM_ADRS_0_VALUE 19:0 /* RWXVF */ | ||
1700 | #define NV_PGRAPH_DPRAM_ADRS_1 0x0040082c /* RW-4R */ | ||
1701 | #define NV_PGRAPH_DPRAM_ADRS_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1702 | #define NV_PGRAPH_DPRAM_ADRS_1_VALUE 19:0 /* RWXVF */ | ||
1703 | #define NV_PGRAPH_DPRAM_DATA_0 0x0040082c /* RW-4R */ | ||
1704 | #define NV_PGRAPH_DPRAM_DATA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1705 | #define NV_PGRAPH_DPRAM_DATA_0_VALUE 31:0 /* RWXVF */ | ||
1706 | #define NV_PGRAPH_DPRAM_DATA_1 0x0040082c /* RW-4R */ | ||
1707 | #define NV_PGRAPH_DPRAM_DATA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1708 | #define NV_PGRAPH_DPRAM_DATA_1_VALUE 31:0 /* RWXVF */ | ||
1709 | #define NV_PGRAPH_DPRAM_WE_0 0x0040082c /* RW-4R */ | ||
1710 | #define NV_PGRAPH_DPRAM_WE_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1711 | #define NV_PGRAPH_DPRAM_WE_0_VALUE 23:0 /* RWXVF */ | ||
1712 | #define NV_PGRAPH_DPRAM_WE_1 0x0040082c /* RW-4R */ | ||
1713 | #define NV_PGRAPH_DPRAM_WE_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1714 | #define NV_PGRAPH_DPRAM_WE_1_VALUE 23:0 /* RWXVF */ | ||
1715 | #define NV_PGRAPH_DPRAM_ALPHA_0 0x0040082c /* RW-4R */ | ||
1716 | #define NV_PGRAPH_DPRAM_ALPHA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1717 | #define NV_PGRAPH_DPRAM_ALPHA_0_VALUE 31:0 /* RWXVF */ | ||
1718 | #define NV_PGRAPH_DPRAM_ALPHA_1 0x0040082c /* RW-4R */ | ||
1719 | #define NV_PGRAPH_DPRAM_ALPHA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */ | ||
1720 | #define NV_PGRAPH_DPRAM_ALPHA_1_VALUE 31:0 /* RWXVF */ | ||
1721 | #define NV_PGRAPH_STORED_FMT 0x00400830 /* RW-4R */ | ||
1722 | #define NV_PGRAPH_STORED_FMT_MONO0 5:0 /* RWXVF */ | ||
1723 | #define NV_PGRAPH_STORED_FMT_PATT0 13:8 /* RWXVF */ | ||
1724 | #define NV_PGRAPH_STORED_FMT_PATT1 21:16 /* RWXVF */ | ||
1725 | #define NV_PGRAPH_STORED_FMT_CHROMA 29:24 /* RWXVF */ | ||
1726 | #define NV_PGRAPH_FORMATS 0x00400618 /* RW-4R */ | ||
1727 | #define NV_PGRAPH_FORMATS_ROP 2:0 /* R-XVF */ | ||
1728 | #define NV_PGRAPH_FORMATS_ROP_Y8 0x00000000 /* -W--V */ | ||
1729 | #define NV_PGRAPH_FORMATS_ROP_RGB15 0x00000001 /* -W--V */ | ||
1730 | #define NV_PGRAPH_FORMATS_ROP_RGB16 0x00000002 /* -W--V */ | ||
1731 | #define NV_PGRAPH_FORMATS_ROP_Y16 0x00000003 /* -W--V */ | ||
1732 | #define NV_PGRAPH_FORMATS_ROP_INVALID 0x00000004 /* -W--V */ | ||
1733 | #define NV_PGRAPH_FORMATS_ROP_RGB24 0x00000005 /* -W--V */ | ||
1734 | #define NV_PGRAPH_FORMATS_ROP_RGB30 0x00000006 /* -W--V */ | ||
1735 | #define NV_PGRAPH_FORMATS_ROP_Y32 0x00000007 /* -W--V */ | ||
1736 | #define NV_PGRAPH_FORMATS_SRC 9:4 /* R-XVF */ | ||
1737 | #define NV_PGRAPH_FORMATS_SRC_INVALID 0x00000000 /* RW--V */ | ||
1738 | #define NV_PGRAPH_FORMATS_SRC_LE_Y8 0x00000001 /* RW--V */ | ||
1739 | #define NV_PGRAPH_FORMATS_SRC_LE_X16A8Y8 0x00000002 /* RW--V */ | ||
1740 | #define NV_PGRAPH_FORMATS_SRC_LE_X24Y8 0x00000003 /* RW--V */ | ||
1741 | #define NV_PGRAPH_FORMATS_SRC_LE_A1R5G5B5 0x00000006 /* RW--V */ | ||
1742 | #define NV_PGRAPH_FORMATS_SRC_LE_X1R5G5B5 0x00000007 /* RW--V */ | ||
1743 | #define NV_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5 0x00000008 /* RW--V */ | ||
1744 | #define NV_PGRAPH_FORMATS_SRC_LE_X17R5G5B5 0x00000009 /* RW--V */ | ||
1745 | #define NV_PGRAPH_FORMATS_SRC_LE_R5G6B5 0x0000000A /* RW--V */ | ||
1746 | #define NV_PGRAPH_FORMATS_SRC_LE_A16R5G6B5 0x0000000B /* RW--V */ | ||
1747 | #define NV_PGRAPH_FORMATS_SRC_LE_X16R5G6B5 0x0000000C /* RW--V */ | ||
1748 | #define NV_PGRAPH_FORMATS_SRC_LE_A8R8G8B8 0x0000000D /* RW--V */ | ||
1749 | #define NV_PGRAPH_FORMATS_SRC_LE_X8R8G8B8 0x0000000E /* RW--V */ | ||
1750 | #define NV_PGRAPH_FORMATS_SRC_LE_Y16 0x0000000F /* RW--V */ | ||
1751 | #define NV_PGRAPH_FORMATS_SRC_LE_A16Y16 0x00000010 /* RW--V */ | ||
1752 | #define NV_PGRAPH_FORMATS_SRC_LE_X16Y16 0x00000011 /* RW--V */ | ||
1753 | #define NV_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8 0x00000012 /* RW--V */ | ||
1754 | #define NV_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8 0x00000013 /* RW--V */ | ||
1755 | #define NV_PGRAPH_FORMATS_SRC_LE_Y32 0x00000014 /* RW--V */ | ||
1756 | #define NV_PGRAPH_FORMATS_FB 15:12 /* R-XVF */ | ||
1757 | #define NV_PGRAPH_FORMATS_FB_INVALID 0x00000000 /* RWI-V */ | ||
1758 | #define NV_PGRAPH_FORMATS_FB_Y8 0x00000001 /* RW--V */ | ||
1759 | #define NV_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */ | ||
1760 | #define NV_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */ | ||
1761 | #define NV_PGRAPH_FORMATS_FB_A1R5G5B5 0x00000004 /* RW--V */ | ||
1762 | #define NV_PGRAPH_FORMATS_FB_R5G6B5 0x00000005 /* RW--V */ | ||
1763 | #define NV_PGRAPH_FORMATS_FB_Y16 0x00000006 /* RW--V */ | ||
1764 | #define NV_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */ | ||
1765 | #define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */ | ||
1766 | #define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */ | ||
1767 | #define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */ | ||
1768 | #define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */ | ||
1769 | #define NV_PGRAPH_FORMATS_FB_A8R8G8B8 0x0000000c /* RW--V */ | ||
1770 | #define NV_PGRAPH_FORMATS_FB_Y32 0x0000000d /* RW--V */ | ||
1771 | #define NV_PGRAPH_FORMATS_FB_V8YB8U8YA8 0x0000000e /* RW--V */ | ||
1772 | #define NV_PGRAPH_FORMATS_FB_YB8V8YA8U8 0x0000000f /* RW--V */ | ||
1773 | #define NV_PGRAPH_ABS_X_RAM(i) (0x00400400+(i)*4) /* RW-4A */ | ||
1774 | #define NV_PGRAPH_ABS_X_RAM__SIZE_1 32 /* */ | ||
1775 | #define NV_PGRAPH_ABS_X_RAM_VALUE 31:0 /* RWXUF */ | ||
1776 | #define NV_PGRAPH_X_RAM_BPORT(i) (0x00400c00+(i)*4) /* R--4A */ | ||
1777 | #define NV_PGRAPH_X_RAM_BPORT__SIZE_1 32 /* */ | ||
1778 | #define NV_PGRAPH_X_RAM_BPORT_VALUE 31:0 /* R--UF */ | ||
1779 | #define NV_PGRAPH_ABS_Y_RAM(i) (0x00400480+(i)*4) /* RW-4A */ | ||
1780 | #define NV_PGRAPH_ABS_Y_RAM__SIZE_1 32 /* */ | ||
1781 | #define NV_PGRAPH_ABS_Y_RAM_VALUE 31:0 /* RWXUF */ | ||
1782 | #define NV_PGRAPH_Y_RAM_BPORT(i) (0x00400c80+(i)*4) /* R--4A */ | ||
1783 | #define NV_PGRAPH_Y_RAM_BPORT__SIZE_1 32 /* */ | ||
1784 | #define NV_PGRAPH_Y_RAM_BPORT_VALUE 31:0 /* R--UF */ | ||
1785 | #define NV_PGRAPH_XY_LOGIC_MISC0 0x00400514 /* RW-4R */ | ||
1786 | #define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER 17:0 /* RWBUF */ | ||
1787 | #define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER_0 0x00000000 /* RWB-V */ | ||
1788 | #define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION 20:20 /* RWVVF */ | ||
1789 | #define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO 0x00000000 /* RWV-V */ | ||
1790 | #define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO 0x00000001 /* RW--V */ | ||
1791 | #define NV_PGRAPH_XY_LOGIC_MISC0_INDEX 31:28 /* RWBUF */ | ||
1792 | #define NV_PGRAPH_XY_LOGIC_MISC0_INDEX_0 0x00000000 /* RWB-V */ | ||
1793 | #define NV_PGRAPH_XY_LOGIC_MISC1 0x00400518 /* RW-4R */ | ||
1794 | #define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL 0:0 /* RWNVF */ | ||
1795 | #define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED 0x00000000 /* RWN-V */ | ||
1796 | #define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE 0x00000001 /* RW--V */ | ||
1797 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX 4:4 /* RWIVF */ | ||
1798 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */ | ||
1799 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL 0x00000001 /* RW--V */ | ||
1800 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY 5:5 /* RWIVF */ | ||
1801 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */ | ||
1802 | #define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL 0x00000001 /* RW--V */ | ||
1803 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX 12:12 /* RWIVF */ | ||
1804 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX 0x00000000 /* RWI-V */ | ||
1805 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */ | ||
1806 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX 16:16 /* RWIVF */ | ||
1807 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX 0x00000000 /* RWI-V */ | ||
1808 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */ | ||
1809 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA 20:20 /* RWIVF */ | ||
1810 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */ | ||
1811 | #define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */ | ||
1812 | #define NV_PGRAPH_XY_LOGIC_MISC2 0x0040051C /* RW-4R */ | ||
1813 | #define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF 0:0 /* RWIVF */ | ||
1814 | #define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE 0x00000000 /* RWI-V */ | ||
1815 | #define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE 0x00000001 /* RW--V */ | ||
1816 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX 4:4 /* RWIVF */ | ||
1817 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */ | ||
1818 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL 0x00000001 /* RW--V */ | ||
1819 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY 5:5 /* RWIVF */ | ||
1820 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */ | ||
1821 | #define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL 0x00000001 /* RW--V */ | ||
1822 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX 12:12 /* RWIVF */ | ||
1823 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX 0x00000000 /* RWI-V */ | ||
1824 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */ | ||
1825 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX 16:16 /* RWIVF */ | ||
1826 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX 0x00000000 /* RWI-V */ | ||
1827 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */ | ||
1828 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA 20:20 /* RWIVF */ | ||
1829 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */ | ||
1830 | #define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */ | ||
1831 | #define NV_PGRAPH_XY_LOGIC_MISC3 0x00400520 /* RW-4R */ | ||
1832 | #define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0 0:0 /* RWXVF */ | ||
1833 | #define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL 0x00000000 /* RW--V */ | ||
1834 | #define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE 0x00000001 /* RW--V */ | ||
1835 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY 4:4 /* RWXVF */ | ||
1836 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL 0x00000000 /* RW--V */ | ||
1837 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE 0x00000001 /* RW--V */ | ||
1838 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX 8:8 /* RWIVF */ | ||
1839 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL 0x00000000 /* RWI-V */ | ||
1840 | #define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE 0x00000001 /* RW--V */ | ||
1841 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG 12:12 /* RWIVF */ | ||
1842 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL 0x00000000 /* RWI-V */ | ||
1843 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE 0x00000001 /* RW--V */ | ||
1844 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX 22:16 /* RWXUF */ | ||
1845 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0 0x00000000 /* RW--V */ | ||
1846 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX 30:24 /* RWXUF */ | ||
1847 | #define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0 0x00000000 /* RW--V */ | ||
1848 | #define NV_PGRAPH_X_MISC 0x00400500 /* RW-4R */ | ||
1849 | #define NV_PGRAPH_X_MISC_BIT33_0 0:0 /* RWNVF */ | ||
1850 | #define NV_PGRAPH_X_MISC_BIT33_0_0 0x00000000 /* RWN-V */ | ||
1851 | #define NV_PGRAPH_X_MISC_BIT33_1 1:1 /* RWNVF */ | ||
1852 | #define NV_PGRAPH_X_MISC_BIT33_1_0 0x00000000 /* RWN-V */ | ||
1853 | #define NV_PGRAPH_X_MISC_BIT33_2 2:2 /* RWNVF */ | ||
1854 | #define NV_PGRAPH_X_MISC_BIT33_2_0 0x00000000 /* RWN-V */ | ||
1855 | #define NV_PGRAPH_X_MISC_BIT33_3 3:3 /* RWNVF */ | ||
1856 | #define NV_PGRAPH_X_MISC_BIT33_3_0 0x00000000 /* RWN-V */ | ||
1857 | #define NV_PGRAPH_X_MISC_RANGE_0 4:4 /* RWNVF */ | ||
1858 | #define NV_PGRAPH_X_MISC_RANGE_0_0 0x00000000 /* RWN-V */ | ||
1859 | #define NV_PGRAPH_X_MISC_RANGE_1 5:5 /* RWNVF */ | ||
1860 | #define NV_PGRAPH_X_MISC_RANGE_1_0 0x00000000 /* RWN-V */ | ||
1861 | #define NV_PGRAPH_X_MISC_RANGE_2 6:6 /* RWNVF */ | ||
1862 | #define NV_PGRAPH_X_MISC_RANGE_2_0 0x00000000 /* RWN-V */ | ||
1863 | #define NV_PGRAPH_X_MISC_RANGE_3 7:7 /* RWNVF */ | ||
1864 | #define NV_PGRAPH_X_MISC_RANGE_3_0 0x00000000 /* RWN-V */ | ||
1865 | #define NV_PGRAPH_X_MISC_ADDER_OUTPUT 29:28 /* RWXVF */ | ||
1866 | #define NV_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */ | ||
1867 | #define NV_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */ | ||
1868 | #define NV_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */ | ||
1869 | #define NV_PGRAPH_Y_MISC 0x00400504 /* RW-4R */ | ||
1870 | #define NV_PGRAPH_Y_MISC_BIT33_0 0:0 /* RWNVF */ | ||
1871 | #define NV_PGRAPH_Y_MISC_BIT33_0_0 0x00000000 /* RWN-V */ | ||
1872 | #define NV_PGRAPH_Y_MISC_BIT33_1 1:1 /* RWNVF */ | ||
1873 | #define NV_PGRAPH_Y_MISC_BIT33_1_0 0x00000000 /* RWN-V */ | ||
1874 | #define NV_PGRAPH_Y_MISC_BIT33_2 2:2 /* RWNVF */ | ||
1875 | #define NV_PGRAPH_Y_MISC_BIT33_2_0 0x00000000 /* RWN-V */ | ||
1876 | #define NV_PGRAPH_Y_MISC_BIT33_3 3:3 /* RWNVF */ | ||
1877 | #define NV_PGRAPH_Y_MISC_BIT33_3_0 0x00000000 /* RWN-V */ | ||
1878 | #define NV_PGRAPH_Y_MISC_RANGE_0 4:4 /* RWNVF */ | ||
1879 | #define NV_PGRAPH_Y_MISC_RANGE_0_0 0x00000000 /* RWN-V */ | ||
1880 | #define NV_PGRAPH_Y_MISC_RANGE_1 5:5 /* RWNVF */ | ||
1881 | #define NV_PGRAPH_Y_MISC_RANGE_1_0 0x00000000 /* RWN-V */ | ||
1882 | #define NV_PGRAPH_Y_MISC_RANGE_2 6:6 /* RWNVF */ | ||
1883 | #define NV_PGRAPH_Y_MISC_RANGE_2_0 0x00000000 /* RWN-V */ | ||
1884 | #define NV_PGRAPH_Y_MISC_RANGE_3 7:7 /* RWNVF */ | ||
1885 | #define NV_PGRAPH_Y_MISC_RANGE_3_0 0x00000000 /* RWN-V */ | ||
1886 | #define NV_PGRAPH_Y_MISC_ADDER_OUTPUT 29:28 /* RWXVF */ | ||
1887 | #define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */ | ||
1888 | #define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */ | ||
1889 | #define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */ | ||
1890 | #define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C /* RW-4R */ | ||
1891 | #define NV_PGRAPH_ABS_UCLIP_XMIN_VALUE 15:0 /* RWXSF */ | ||
1892 | #define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 /* RW-4R */ | ||
1893 | #define NV_PGRAPH_ABS_UCLIP_XMAX_VALUE 17:0 /* RWXSF */ | ||
1894 | #define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 /* RW-4R */ | ||
1895 | #define NV_PGRAPH_ABS_UCLIP_YMIN_VALUE 15:0 /* RWXSF */ | ||
1896 | #define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 /* RW-4R */ | ||
1897 | #define NV_PGRAPH_ABS_UCLIP_YMAX_VALUE 17:0 /* RWXSF */ | ||
1898 | #define NV_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 /* RW-4R */ | ||
1899 | #define NV_PGRAPH_ABS_UCLIPA_XMIN_VALUE 15:0 /* RWXSF */ | ||
1900 | #define NV_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 /* RW-4R */ | ||
1901 | #define NV_PGRAPH_ABS_UCLIPA_XMAX_VALUE 17:0 /* RWXSF */ | ||
1902 | #define NV_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 /* RW-4R */ | ||
1903 | #define NV_PGRAPH_ABS_UCLIPA_YMIN_VALUE 15:0 /* RWXSF */ | ||
1904 | #define NV_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C /* RW-4R */ | ||
1905 | #define NV_PGRAPH_ABS_UCLIPA_YMAX_VALUE 17:0 /* RWXSF */ | ||
1906 | #define NV_PGRAPH_SOURCE_COLOR 0x0040050C /* RW-4R */ | ||
1907 | #define NV_PGRAPH_SOURCE_COLOR_VALUE 31:0 /* RWNVF */ | ||
1908 | #define NV_PGRAPH_SOURCE_COLOR_VALUE_0 0x00000000 /* RWN-V */ | ||
1909 | #define NV_PGRAPH_VALID1 0x00400508 /* RW-4R */ | ||
1910 | #define NV_PGRAPH_VALID1_VLD 22:0 /* RWNVF */ | ||
1911 | #define NV_PGRAPH_VALID1_VLD_0 0x00000000 /* RWN-V */ | ||
1912 | #define NV_PGRAPH_VALID1_CLIP_MIN 28:28 /* RWIVF */ | ||
1913 | #define NV_PGRAPH_VALID1_CLIP_MIN_NO_ERROR 0x00000000 /* RWI-V */ | ||
1914 | #define NV_PGRAPH_VALID1_CLIP_MIN_ONLY 0x00000001 /* RW--V */ | ||
1915 | #define NV_PGRAPH_VALID1_CLIPA_MIN 29:29 /* RWIVF */ | ||
1916 | #define NV_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR 0x00000000 /* RWI-V */ | ||
1917 | #define NV_PGRAPH_VALID1_CLIPA_MIN_ONLY 0x00000001 /* RW--V */ | ||
1918 | #define NV_PGRAPH_VALID1_CLIP_MAX 30:30 /* RWIVF */ | ||
1919 | #define NV_PGRAPH_VALID1_CLIP_MAX_NO_ERROR 0x00000000 /* RWI-V */ | ||
1920 | #define NV_PGRAPH_VALID1_CLIP_MAX_ONLY 0x00000001 /* RW--V */ | ||
1921 | #define NV_PGRAPH_VALID1_CLIPA_MAX 31:31 /* RWIVF */ | ||
1922 | #define NV_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR 0x00000000 /* RWI-V */ | ||
1923 | #define NV_PGRAPH_VALID1_CLIPA_MAX_ONLY 0x00000001 /* RW--V */ | ||
1924 | #define NV_PGRAPH_VALID2 0x00400578 /* RW-4R */ | ||
1925 | #define NV_PGRAPH_VALID2_VLD2 28:0 /* RWNVF */ | ||
1926 | #define NV_PGRAPH_VALID2_VLD2_0 0x00000000 /* RWN-V */ | ||
1927 | #define NV_PGRAPH_ABS_ICLIP_XMAX 0x00400534 /* RW-4R */ | ||
1928 | #define NV_PGRAPH_ABS_ICLIP_XMAX_VALUE 17:0 /* RWXSF */ | ||
1929 | #define NV_PGRAPH_ABS_ICLIP_YMAX 0x00400538 /* RW-4R */ | ||
1930 | #define NV_PGRAPH_ABS_ICLIP_YMAX_VALUE 17:0 /* RWXSF */ | ||
1931 | #define NV_PGRAPH_CLIPX_0 0x00400524 /* RW-4R */ | ||
1932 | #define NV_PGRAPH_CLIPX_0_CLIP0_MIN 1:0 /* RWNVF */ | ||
1933 | #define NV_PGRAPH_CLIPX_0_CLIP0_MIN_GT 0x00000000 /* RW--V */ | ||
1934 | #define NV_PGRAPH_CLIPX_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */ | ||
1935 | #define NV_PGRAPH_CLIPX_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */ | ||
1936 | #define NV_PGRAPH_CLIPX_0_CLIP0_MAX 3:2 /* RWNVF */ | ||
1937 | #define NV_PGRAPH_CLIPX_0_CLIP0_MAX_LT 0x00000000 /* RW--V */ | ||
1938 | #define NV_PGRAPH_CLIPX_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */ | ||
1939 | #define NV_PGRAPH_CLIPX_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */ | ||
1940 | #define NV_PGRAPH_CLIPX_0_CLIP1_MIN 5:4 /* RWNVF */ | ||
1941 | #define NV_PGRAPH_CLIPX_0_CLIP1_MIN_GT 0x00000000 /* RW--V */ | ||
1942 | #define NV_PGRAPH_CLIPX_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */ | ||
1943 | #define NV_PGRAPH_CLIPX_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */ | ||
1944 | #define NV_PGRAPH_CLIPX_0_CLIP1_MAX 7:6 /* RWNVF */ | ||
1945 | #define NV_PGRAPH_CLIPX_0_CLIP1_MAX_LT 0x00000000 /* RW--V */ | ||
1946 | #define NV_PGRAPH_CLIPX_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */ | ||
1947 | #define NV_PGRAPH_CLIPX_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */ | ||
1948 | #define NV_PGRAPH_CLIPX_0_CLIP2_MIN 9:8 /* RWNVF */ | ||
1949 | #define NV_PGRAPH_CLIPX_0_CLIP2_MIN_GT 0x00000000 /* RW--V */ | ||
1950 | #define NV_PGRAPH_CLIPX_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */ | ||
1951 | #define NV_PGRAPH_CLIPX_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */ | ||
1952 | #define NV_PGRAPH_CLIPX_0_CLIP2_MAX 11:10 /* RWNVF */ | ||
1953 | #define NV_PGRAPH_CLIPX_0_CLIP2_MAX_LT 0x00000000 /* RW--V */ | ||
1954 | #define NV_PGRAPH_CLIPX_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */ | ||
1955 | #define NV_PGRAPH_CLIPX_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */ | ||
1956 | #define NV_PGRAPH_CLIPX_0_CLIP3_MIN 13:12 /* RWNVF */ | ||
1957 | #define NV_PGRAPH_CLIPX_0_CLIP3_MIN_GT 0x00000000 /* RW--V */ | ||
1958 | #define NV_PGRAPH_CLIPX_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */ | ||
1959 | #define NV_PGRAPH_CLIPX_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */ | ||
1960 | #define NV_PGRAPH_CLIPX_0_CLIP3_MAX 15:14 /* RWNVF */ | ||
1961 | #define NV_PGRAPH_CLIPX_0_CLIP3_MAX_LT 0x00000000 /* RW--V */ | ||
1962 | #define NV_PGRAPH_CLIPX_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */ | ||
1963 | #define NV_PGRAPH_CLIPX_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */ | ||
1964 | #define NV_PGRAPH_CLIPX_0_CLIP4_MIN 17:16 /* RWNVF */ | ||
1965 | #define NV_PGRAPH_CLIPX_0_CLIP4_MIN_GT 0x00000000 /* RW--V */ | ||
1966 | #define NV_PGRAPH_CLIPX_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */ | ||
1967 | #define NV_PGRAPH_CLIPX_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */ | ||
1968 | #define NV_PGRAPH_CLIPX_0_CLIP4_MAX 19:18 /* RWNVF */ | ||
1969 | #define NV_PGRAPH_CLIPX_0_CLIP4_MAX_LT 0x00000000 /* RW--V */ | ||
1970 | #define NV_PGRAPH_CLIPX_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */ | ||
1971 | #define NV_PGRAPH_CLIPX_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */ | ||
1972 | #define NV_PGRAPH_CLIPX_0_CLIP5_MIN 21:20 /* RWNVF */ | ||
1973 | #define NV_PGRAPH_CLIPX_0_CLIP5_MIN_GT 0x00000000 /* RW--V */ | ||
1974 | #define NV_PGRAPH_CLIPX_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */ | ||
1975 | #define NV_PGRAPH_CLIPX_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */ | ||
1976 | #define NV_PGRAPH_CLIPX_0_CLIP5_MAX 23:22 /* RWNVF */ | ||
1977 | #define NV_PGRAPH_CLIPX_0_CLIP5_MAX_LT 0x00000000 /* RW--V */ | ||
1978 | #define NV_PGRAPH_CLIPX_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */ | ||
1979 | #define NV_PGRAPH_CLIPX_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */ | ||
1980 | #define NV_PGRAPH_CLIPX_0_CLIP6_MIN 25:24 /* RWNVF */ | ||
1981 | #define NV_PGRAPH_CLIPX_0_CLIP6_MIN_GT 0x00000000 /* RW--V */ | ||
1982 | #define NV_PGRAPH_CLIPX_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */ | ||
1983 | #define NV_PGRAPH_CLIPX_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */ | ||
1984 | #define NV_PGRAPH_CLIPX_0_CLIP6_MAX 27:26 /* RWNVF */ | ||
1985 | #define NV_PGRAPH_CLIPX_0_CLIP6_MAX_LT 0x00000000 /* RW--V */ | ||
1986 | #define NV_PGRAPH_CLIPX_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */ | ||
1987 | #define NV_PGRAPH_CLIPX_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */ | ||
1988 | #define NV_PGRAPH_CLIPX_0_CLIP7_MIN 29:28 /* RWNVF */ | ||
1989 | #define NV_PGRAPH_CLIPX_0_CLIP7_MIN_GT 0x00000000 /* RW--V */ | ||
1990 | #define NV_PGRAPH_CLIPX_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */ | ||
1991 | #define NV_PGRAPH_CLIPX_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */ | ||
1992 | #define NV_PGRAPH_CLIPX_0_CLIP7_MAX 31:30 /* RWNVF */ | ||
1993 | #define NV_PGRAPH_CLIPX_0_CLIP7_MAX_LT 0x00000000 /* RW--V */ | ||
1994 | #define NV_PGRAPH_CLIPX_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */ | ||
1995 | #define NV_PGRAPH_CLIPX_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */ | ||
1996 | #define NV_PGRAPH_CLIPX_1 0x00400528 /* RW-4R */ | ||
1997 | #define NV_PGRAPH_CLIPX_1_CLIP8_MIN 1:0 /* RWNVF */ | ||
1998 | #define NV_PGRAPH_CLIPX_1_CLIP8_MIN_GT 0x00000000 /* RW--V */ | ||
1999 | #define NV_PGRAPH_CLIPX_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */ | ||
2000 | #define NV_PGRAPH_CLIPX_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */ | ||
2001 | #define NV_PGRAPH_CLIPX_1_CLIP8_MAX 3:2 /* RWNVF */ | ||
2002 | #define NV_PGRAPH_CLIPX_1_CLIP8_MAX_LT 0x00000000 /* RW--V */ | ||
2003 | #define NV_PGRAPH_CLIPX_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */ | ||
2004 | #define NV_PGRAPH_CLIPX_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */ | ||
2005 | #define NV_PGRAPH_CLIPX_1_CLIP9_MIN 5:4 /* RWNVF */ | ||
2006 | #define NV_PGRAPH_CLIPX_1_CLIP9_MIN_GT 0x00000000 /* RW--V */ | ||
2007 | #define NV_PGRAPH_CLIPX_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */ | ||
2008 | #define NV_PGRAPH_CLIPX_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */ | ||
2009 | #define NV_PGRAPH_CLIPX_1_CLIP9_MAX 7:6 /* RWNVF */ | ||
2010 | #define NV_PGRAPH_CLIPX_1_CLIP9_MAX_LT 0x00000000 /* RW--V */ | ||
2011 | #define NV_PGRAPH_CLIPX_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */ | ||
2012 | #define NV_PGRAPH_CLIPX_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */ | ||
2013 | #define NV_PGRAPH_CLIPX_1_CLIP10_MIN 9:8 /* RWNVF */ | ||
2014 | #define NV_PGRAPH_CLIPX_1_CLIP10_MIN_GT 0x00000000 /* RW--V */ | ||
2015 | #define NV_PGRAPH_CLIPX_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */ | ||
2016 | #define NV_PGRAPH_CLIPX_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */ | ||
2017 | #define NV_PGRAPH_CLIPX_1_CLIP10_MAX 11:10 /* RWNVF */ | ||
2018 | #define NV_PGRAPH_CLIPX_1_CLIP10_MAX_LT 0x00000000 /* RW--V */ | ||
2019 | #define NV_PGRAPH_CLIPX_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */ | ||
2020 | #define NV_PGRAPH_CLIPX_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */ | ||
2021 | #define NV_PGRAPH_CLIPX_1_CLIP11_MIN 13:12 /* RWNVF */ | ||
2022 | #define NV_PGRAPH_CLIPX_1_CLIP11_MIN_GT 0x00000000 /* RW--V */ | ||
2023 | #define NV_PGRAPH_CLIPX_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */ | ||
2024 | #define NV_PGRAPH_CLIPX_1_CLIP11MIN_EQ 0x00000002 /* RW--V */ | ||
2025 | #define NV_PGRAPH_CLIPX_1_CLIP11_MAX 15:14 /* RWNVF */ | ||
2026 | #define NV_PGRAPH_CLIPX_1_CLIP11_MAX_LT 0x00000000 /* RW--V */ | ||
2027 | #define NV_PGRAPH_CLIPX_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */ | ||
2028 | #define NV_PGRAPH_CLIPX_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */ | ||
2029 | #define NV_PGRAPH_CLIPX_1_CLIP12_MIN 17:16 /* RWNVF */ | ||
2030 | #define NV_PGRAPH_CLIPX_1_CLIP12_MIN_GT 0x00000000 /* RW--V */ | ||
2031 | #define NV_PGRAPH_CLIPX_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */ | ||
2032 | #define NV_PGRAPH_CLIPX_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */ | ||
2033 | #define NV_PGRAPH_CLIPX_1_CLIP12_MAX 19:18 /* RWNVF */ | ||
2034 | #define NV_PGRAPH_CLIPX_1_CLIP12_MAX_LT 0x00000000 /* RW--V */ | ||
2035 | #define NV_PGRAPH_CLIPX_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */ | ||
2036 | #define NV_PGRAPH_CLIPX_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */ | ||
2037 | #define NV_PGRAPH_CLIPX_1_CLIP13_MIN 21:20 /* RWNVF */ | ||
2038 | #define NV_PGRAPH_CLIPX_1_CLIP13_MIN_GT 0x00000000 /* RW--V */ | ||
2039 | #define NV_PGRAPH_CLIPX_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */ | ||
2040 | #define NV_PGRAPH_CLIPX_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */ | ||
2041 | #define NV_PGRAPH_CLIPX_1_CLIP13_MAX 23:22 /* RWNVF */ | ||
2042 | #define NV_PGRAPH_CLIPX_1_CLIP13_MAX_LT 0x00000000 /* RW--V */ | ||
2043 | #define NV_PGRAPH_CLIPX_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */ | ||
2044 | #define NV_PGRAPH_CLIPX_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */ | ||
2045 | #define NV_PGRAPH_CLIPX_1_CLIP14_MIN 25:24 /* RWNVF */ | ||
2046 | #define NV_PGRAPH_CLIPX_1_CLIP14_MIN_GT 0x00000000 /* RW--V */ | ||
2047 | #define NV_PGRAPH_CLIPX_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */ | ||
2048 | #define NV_PGRAPH_CLIPX_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */ | ||
2049 | #define NV_PGRAPH_CLIPX_1_CLIP14_MAX 27:26 /* RWNVF */ | ||
2050 | #define NV_PGRAPH_CLIPX_1_CLIP14_MAX_LT 0x00000000 /* RW--V */ | ||
2051 | #define NV_PGRAPH_CLIPX_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */ | ||
2052 | #define NV_PGRAPH_CLIPX_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */ | ||
2053 | #define NV_PGRAPH_CLIPX_1_CLIP15_MIN 29:28 /* RWNVF */ | ||
2054 | #define NV_PGRAPH_CLIPX_1_CLIP15_MIN_GT 0x00000000 /* RW--V */ | ||
2055 | #define NV_PGRAPH_CLIPX_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */ | ||
2056 | #define NV_PGRAPH_CLIPX_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */ | ||
2057 | #define NV_PGRAPH_CLIPX_1_CLIP15_MAX 31:30 /* RWNVF */ | ||
2058 | #define NV_PGRAPH_CLIPX_1_CLIP15_MAX_LT 0x00000000 /* RW--V */ | ||
2059 | #define NV_PGRAPH_CLIPX_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */ | ||
2060 | #define NV_PGRAPH_CLIPX_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */ | ||
2061 | #define NV_PGRAPH_CLIPY_0 0x0040052c /* RW-4R */ | ||
2062 | #define NV_PGRAPH_CLIPY_0_CLIP0_MIN 1:0 /* RWNVF */ | ||
2063 | #define NV_PGRAPH_CLIPY_0_CLIP0_MIN_GT 0x00000000 /* RW--V */ | ||
2064 | #define NV_PGRAPH_CLIPY_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */ | ||
2065 | #define NV_PGRAPH_CLIPY_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */ | ||
2066 | #define NV_PGRAPH_CLIPY_0_CLIP0_MAX 3:2 /* RWNVF */ | ||
2067 | #define NV_PGRAPH_CLIPY_0_CLIP0_MAX_LT 0x00000000 /* RW--V */ | ||
2068 | #define NV_PGRAPH_CLIPY_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */ | ||
2069 | #define NV_PGRAPH_CLIPY_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */ | ||
2070 | #define NV_PGRAPH_CLIPY_0_CLIP1_MIN 5:4 /* RWNVF */ | ||
2071 | #define NV_PGRAPH_CLIPY_0_CLIP1_MIN_GT 0x00000000 /* RW--V */ | ||
2072 | #define NV_PGRAPH_CLIPY_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */ | ||
2073 | #define NV_PGRAPH_CLIPY_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */ | ||
2074 | #define NV_PGRAPH_CLIPY_0_CLIP1_MAX 7:6 /* RWNVF */ | ||
2075 | #define NV_PGRAPH_CLIPY_0_CLIP1_MAX_LT 0x00000000 /* RW--V */ | ||
2076 | #define NV_PGRAPH_CLIPY_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */ | ||
2077 | #define NV_PGRAPH_CLIPY_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */ | ||
2078 | #define NV_PGRAPH_CLIPY_0_CLIP2_MIN 9:8 /* RWNVF */ | ||
2079 | #define NV_PGRAPH_CLIPY_0_CLIP2_MIN_GT 0x00000000 /* RW--V */ | ||
2080 | #define NV_PGRAPH_CLIPY_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */ | ||
2081 | #define NV_PGRAPH_CLIPY_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */ | ||
2082 | #define NV_PGRAPH_CLIPY_0_CLIP2_MAX 11:10 /* RWNVF */ | ||
2083 | #define NV_PGRAPH_CLIPY_0_CLIP2_MAX_LT 0x00000000 /* RW--V */ | ||
2084 | #define NV_PGRAPH_CLIPY_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */ | ||
2085 | #define NV_PGRAPH_CLIPY_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */ | ||
2086 | #define NV_PGRAPH_CLIPY_0_CLIP3_MIN 13:12 /* RWNVF */ | ||
2087 | #define NV_PGRAPH_CLIPY_0_CLIP3_MIN_GT 0x00000000 /* RW--V */ | ||
2088 | #define NV_PGRAPH_CLIPY_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */ | ||
2089 | #define NV_PGRAPH_CLIPY_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */ | ||
2090 | #define NV_PGRAPH_CLIPY_0_CLIP3_MAX 15:14 /* RWNVF */ | ||
2091 | #define NV_PGRAPH_CLIPY_0_CLIP3_MAX_LT 0x00000000 /* RW--V */ | ||
2092 | #define NV_PGRAPH_CLIPY_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */ | ||
2093 | #define NV_PGRAPH_CLIPY_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */ | ||
2094 | #define NV_PGRAPH_CLIPY_0_CLIP4_MIN 17:16 /* RWNVF */ | ||
2095 | #define NV_PGRAPH_CLIPY_0_CLIP4_MIN_GT 0x00000000 /* RW--V */ | ||
2096 | #define NV_PGRAPH_CLIPY_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */ | ||
2097 | #define NV_PGRAPH_CLIPY_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */ | ||
2098 | #define NV_PGRAPH_CLIPY_0_CLIP4_MAX 19:18 /* RWNVF */ | ||
2099 | #define NV_PGRAPH_CLIPY_0_CLIP4_MAX_LT 0x00000000 /* RW--V */ | ||
2100 | #define NV_PGRAPH_CLIPY_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */ | ||
2101 | #define NV_PGRAPH_CLIPY_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */ | ||
2102 | #define NV_PGRAPH_CLIPY_0_CLIP5_MIN 21:20 /* RWNVF */ | ||
2103 | #define NV_PGRAPH_CLIPY_0_CLIP5_MIN_GT 0x00000000 /* RW--V */ | ||
2104 | #define NV_PGRAPH_CLIPY_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */ | ||
2105 | #define NV_PGRAPH_CLIPY_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */ | ||
2106 | #define NV_PGRAPH_CLIPY_0_CLIP5_MAX 23:22 /* RWNVF */ | ||
2107 | #define NV_PGRAPH_CLIPY_0_CLIP5_MAX_LT 0x00000000 /* RW--V */ | ||
2108 | #define NV_PGRAPH_CLIPY_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */ | ||
2109 | #define NV_PGRAPH_CLIPY_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */ | ||
2110 | #define NV_PGRAPH_CLIPY_0_CLIP6_MIN 25:24 /* RWNVF */ | ||
2111 | #define NV_PGRAPH_CLIPY_0_CLIP6_MIN_GT 0x00000000 /* RW--V */ | ||
2112 | #define NV_PGRAPH_CLIPY_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */ | ||
2113 | #define NV_PGRAPH_CLIPY_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */ | ||
2114 | #define NV_PGRAPH_CLIPY_0_CLIP6_MAX 27:26 /* RWNVF */ | ||
2115 | #define NV_PGRAPH_CLIPY_0_CLIP6_MAX_LT 0x00000000 /* RW--V */ | ||
2116 | #define NV_PGRAPH_CLIPY_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */ | ||
2117 | #define NV_PGRAPH_CLIPY_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */ | ||
2118 | #define NV_PGRAPH_CLIPY_0_CLIP7_MIN 29:28 /* RWNVF */ | ||
2119 | #define NV_PGRAPH_CLIPY_0_CLIP7_MIN_GT 0x00000000 /* RW--V */ | ||
2120 | #define NV_PGRAPH_CLIPY_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */ | ||
2121 | #define NV_PGRAPH_CLIPY_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */ | ||
2122 | #define NV_PGRAPH_CLIPY_0_CLIP7_MAX 31:30 /* RWNVF */ | ||
2123 | #define NV_PGRAPH_CLIPY_0_CLIP7_MAX_LT 0x00000000 /* RW--V */ | ||
2124 | #define NV_PGRAPH_CLIPY_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */ | ||
2125 | #define NV_PGRAPH_CLIPY_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */ | ||
2126 | #define NV_PGRAPH_CLIPY_1 0x00400530 /* RW-4R */ | ||
2127 | #define NV_PGRAPH_CLIPY_1_CLIP8_MIN 1:0 /* RWNVF */ | ||
2128 | #define NV_PGRAPH_CLIPY_1_CLIP8_MIN_GT 0x00000000 /* RW--V */ | ||
2129 | #define NV_PGRAPH_CLIPY_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */ | ||
2130 | #define NV_PGRAPH_CLIPY_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */ | ||
2131 | #define NV_PGRAPH_CLIPY_1_CLIP8_MAX 3:2 /* RWNVF */ | ||
2132 | #define NV_PGRAPH_CLIPY_1_CLIP8_MAX_LT 0x00000000 /* RW--V */ | ||
2133 | #define NV_PGRAPH_CLIPY_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */ | ||
2134 | #define NV_PGRAPH_CLIPY_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */ | ||
2135 | #define NV_PGRAPH_CLIPY_1_CLIP9_MIN 5:4 /* RWNVF */ | ||
2136 | #define NV_PGRAPH_CLIPY_1_CLIP9_MIN_GT 0x00000000 /* RW--V */ | ||
2137 | #define NV_PGRAPH_CLIPY_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */ | ||
2138 | #define NV_PGRAPH_CLIPY_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */ | ||
2139 | #define NV_PGRAPH_CLIPY_1_CLIP9_MAX 7:6 /* RWNVF */ | ||
2140 | #define NV_PGRAPH_CLIPY_1_CLIP9_MAX_LT 0x00000000 /* RW--V */ | ||
2141 | #define NV_PGRAPH_CLIPY_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */ | ||
2142 | #define NV_PGRAPH_CLIPY_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */ | ||
2143 | #define NV_PGRAPH_CLIPY_1_CLIP10_MIN 9:8 /* RWNVF */ | ||
2144 | #define NV_PGRAPH_CLIPY_1_CLIP10_MIN_GT 0x00000000 /* RW--V */ | ||
2145 | #define NV_PGRAPH_CLIPY_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */ | ||
2146 | #define NV_PGRAPH_CLIPY_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */ | ||
2147 | #define NV_PGRAPH_CLIPY_1_CLIP10_MAX 11:10 /* RWNVF */ | ||
2148 | #define NV_PGRAPH_CLIPY_1_CLIP10_MAX_LT 0x00000000 /* RW--V */ | ||
2149 | #define NV_PGRAPH_CLIPY_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */ | ||
2150 | #define NV_PGRAPH_CLIPY_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */ | ||
2151 | #define NV_PGRAPH_CLIPY_1_CLIP11_MIN 13:12 /* RWNVF */ | ||
2152 | #define NV_PGRAPH_CLIPY_1_CLIP11_MIN_GT 0x00000000 /* RW--V */ | ||
2153 | #define NV_PGRAPH_CLIPY_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */ | ||
2154 | #define NV_PGRAPH_CLIPY_1_CLIP11MIN_EQ 0x00000002 /* RW--V */ | ||
2155 | #define NV_PGRAPH_CLIPY_1_CLIP11_MAX 15:14 /* RWNVF */ | ||
2156 | #define NV_PGRAPH_CLIPY_1_CLIP11_MAX_LT 0x00000000 /* RW--V */ | ||
2157 | #define NV_PGRAPH_CLIPY_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */ | ||
2158 | #define NV_PGRAPH_CLIPY_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */ | ||
2159 | #define NV_PGRAPH_CLIPY_1_CLIP12_MIN 17:16 /* RWNVF */ | ||
2160 | #define NV_PGRAPH_CLIPY_1_CLIP12_MIN_GT 0x00000000 /* RW--V */ | ||
2161 | #define NV_PGRAPH_CLIPY_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */ | ||
2162 | #define NV_PGRAPH_CLIPY_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */ | ||
2163 | #define NV_PGRAPH_CLIPY_1_CLIP12_MAX 19:18 /* RWNVF */ | ||
2164 | #define NV_PGRAPH_CLIPY_1_CLIP12_MAX_LT 0x00000000 /* RW--V */ | ||
2165 | #define NV_PGRAPH_CLIPY_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */ | ||
2166 | #define NV_PGRAPH_CLIPY_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */ | ||
2167 | #define NV_PGRAPH_CLIPY_1_CLIP13_MIN 21:20 /* RWNVF */ | ||
2168 | #define NV_PGRAPH_CLIPY_1_CLIP13_MIN_GT 0x00000000 /* RW--V */ | ||
2169 | #define NV_PGRAPH_CLIPY_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */ | ||
2170 | #define NV_PGRAPH_CLIPY_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */ | ||
2171 | #define NV_PGRAPH_CLIPY_1_CLIP13_MAX 23:22 /* RWNVF */ | ||
2172 | #define NV_PGRAPH_CLIPY_1_CLIP13_MAX_LT 0x00000000 /* RW--V */ | ||
2173 | #define NV_PGRAPH_CLIPY_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */ | ||
2174 | #define NV_PGRAPH_CLIPY_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */ | ||
2175 | #define NV_PGRAPH_CLIPY_1_CLIP14_MIN 25:24 /* RWNVF */ | ||
2176 | #define NV_PGRAPH_CLIPY_1_CLIP14_MIN_GT 0x00000000 /* RW--V */ | ||
2177 | #define NV_PGRAPH_CLIPY_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */ | ||
2178 | #define NV_PGRAPH_CLIPY_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */ | ||
2179 | #define NV_PGRAPH_CLIPY_1_CLIP14_MAX 27:26 /* RWNVF */ | ||
2180 | #define NV_PGRAPH_CLIPY_1_CLIP14_MAX_LT 0x00000000 /* RW--V */ | ||
2181 | #define NV_PGRAPH_CLIPY_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */ | ||
2182 | #define NV_PGRAPH_CLIPY_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */ | ||
2183 | #define NV_PGRAPH_CLIPY_1_CLIP15_MIN 29:28 /* RWNVF */ | ||
2184 | #define NV_PGRAPH_CLIPY_1_CLIP15_MIN_GT 0x00000000 /* RW--V */ | ||
2185 | #define NV_PGRAPH_CLIPY_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */ | ||
2186 | #define NV_PGRAPH_CLIPY_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */ | ||
2187 | #define NV_PGRAPH_CLIPY_1_CLIP15_MAX 31:30 /* RWNVF */ | ||
2188 | #define NV_PGRAPH_CLIPY_1_CLIP15_MAX_LT 0x00000000 /* RW--V */ | ||
2189 | #define NV_PGRAPH_CLIPY_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */ | ||
2190 | #define NV_PGRAPH_CLIPY_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */ | ||
2191 | #define NV_PGRAPH_MISC24_0 0x00400510 /* RW-4R */ | ||
2192 | #define NV_PGRAPH_MISC24_0_VALUE 23:0 /* RWXUF */ | ||
2193 | #define NV_PGRAPH_MISC24_1 0x00400570 /* RW-4R */ | ||
2194 | #define NV_PGRAPH_MISC24_1_VALUE 23:0 /* RWXUF */ | ||
2195 | #define NV_PGRAPH_MISC24_2 0x00400574 /* RW-4R */ | ||
2196 | #define NV_PGRAPH_MISC24_2_VALUE 23:0 /* RWXUF */ | ||
2197 | #define NV_PGRAPH_PASSTHRU_0 0x0040057C /* RW-4R */ | ||
2198 | #define NV_PGRAPH_PASSTHRU_0_VALUE 31:0 /* RWXUF */ | ||
2199 | #define NV_PGRAPH_PASSTHRU_1 0x00400580 /* RW-4R */ | ||
2200 | #define NV_PGRAPH_PASSTHRU_1_VALUE 31:0 /* RWXUF */ | ||
2201 | #define NV_PGRAPH_PASSTHRU_2 0x00400584 /* RW-4R */ | ||
2202 | #define NV_PGRAPH_PASSTHRU_2_VALUE 31:0 /* RWXUF */ | ||
2203 | #define NV_PGRAPH_U_RAM(i) (0x00400d00+(i)*4) /* RW-4A */ | ||
2204 | #define NV_PGRAPH_U_RAM__SIZE_1 16 /* */ | ||
2205 | #define NV_PGRAPH_U_RAM_VALUE 31:6 /* RWXFF */ | ||
2206 | #define NV_PGRAPH_V_RAM(i) (0x00400d40+(i)*4) /* RW-4A */ | ||
2207 | #define NV_PGRAPH_V_RAM__SIZE_1 16 /* */ | ||
2208 | #define NV_PGRAPH_V_RAM_VALUE 31:6 /* RWXFF */ | ||
2209 | #define NV_PGRAPH_M_RAM(i) (0x00400d80+(i)*4) /* RW-4A */ | ||
2210 | #define NV_PGRAPH_M_RAM__SIZE_1 16 /* */ | ||
2211 | #define NV_PGRAPH_M_RAM_VALUE 31:6 /* RWXFF */ | ||
2212 | #define NV_PGRAPH_DMA_START_0 0x00401000 /* RW-4R */ | ||
2213 | #define NV_PGRAPH_DMA_START_0_VALUE 31:0 /* RWXUF */ | ||
2214 | #define NV_PGRAPH_DMA_START_1 0x00401004 /* RW-4R */ | ||
2215 | #define NV_PGRAPH_DMA_START_1_VALUE 31:0 /* RWXUF */ | ||
2216 | #define NV_PGRAPH_DMA_LENGTH 0x00401008 /* RW-4R */ | ||
2217 | #define NV_PGRAPH_DMA_LENGTH_VALUE 21:0 /* RWXUF */ | ||
2218 | #define NV_PGRAPH_DMA_MISC 0x0040100C /* RW-4R */ | ||
2219 | #define NV_PGRAPH_DMA_MISC_COUNT 15:0 /* RWXUF */ | ||
2220 | #define NV_PGRAPH_DMA_MISC_FMT_SRC 18:16 /* RWXVF */ | ||
2221 | #define NV_PGRAPH_DMA_MISC_FMT_DST 22:20 /* RWXVF */ | ||
2222 | #define NV_PGRAPH_DMA_DATA_0 0x00401020 /* RW-4R */ | ||
2223 | #define NV_PGRAPH_DMA_DATA_0_VALUE 31:0 /* RWXUF */ | ||
2224 | #define NV_PGRAPH_DMA_DATA_1 0x00401024 /* RW-4R */ | ||
2225 | #define NV_PGRAPH_DMA_DATA_1_VALUE 31:0 /* RWXUF */ | ||
2226 | #define NV_PGRAPH_DMA_RM 0x00401030 /* RW-4R */ | ||
2227 | #define NV_PGRAPH_DMA_RM_ASSIST_A 0:0 /* RWIVF */ | ||
2228 | #define NV_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING 0x00000000 /* R-I-V */ | ||
2229 | #define NV_PGRAPH_DMA_RM_ASSIST_A_PENDING 0x00000001 /* R---V */ | ||
2230 | #define NV_PGRAPH_DMA_RM_ASSIST_A_RESET 0x00000001 /* -W--C */ | ||
2231 | #define NV_PGRAPH_DMA_RM_ASSIST_B 1:1 /* RWIVF */ | ||
2232 | #define NV_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING 0x00000000 /* R-I-V */ | ||
2233 | #define NV_PGRAPH_DMA_RM_ASSIST_B_PENDING 0x00000001 /* R---V */ | ||
2234 | #define NV_PGRAPH_DMA_RM_ASSIST_B_RESET 0x00000001 /* -W--C */ | ||
2235 | #define NV_PGRAPH_DMA_RM_WRITE_REQ 4:4 /* CWIVF */ | ||
2236 | #define NV_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING 0x00000000 /* CWI-V */ | ||
2237 | #define NV_PGRAPH_DMA_RM_WRITE_REQ_PENDING 0x00000001 /* -W--T */ | ||
2238 | #define NV_PGRAPH_DMA_A_XLATE_INST 0x00401040 /* RW-4R */ | ||
2239 | #define NV_PGRAPH_DMA_A_XLATE_INST_VALUE 15:0 /* RWXUF */ | ||
2240 | #define NV_PGRAPH_DMA_A_CONTROL 0x00401044 /* RW-4R */ | ||
2241 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE 12:12 /* RWIVF */ | ||
2242 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */ | ||
2243 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */ | ||
2244 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */ | ||
2245 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */ | ||
2246 | #define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */ | ||
2247 | #define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE 17:16 /* RWXUF */ | ||
2248 | #define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */ | ||
2249 | #define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */ | ||
2250 | #define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */ | ||
2251 | #define NV_PGRAPH_DMA_A_CONTROL_ADJUST 31:20 /* RWXUF */ | ||
2252 | #define NV_PGRAPH_DMA_A_LIMIT 0x00401048 /* RW-4R */ | ||
2253 | #define NV_PGRAPH_DMA_A_LIMIT_OFFSET 31:0 /* RWXUF */ | ||
2254 | #define NV_PGRAPH_DMA_A_TLB_PTE 0x0040104C /* RW-4R */ | ||
2255 | #define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS 1:1 /* RWXVF */ | ||
2256 | #define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */ | ||
2257 | #define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */ | ||
2258 | #define NV_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */ | ||
2259 | #define NV_PGRAPH_DMA_A_TLB_TAG 0x00401050 /* RW-4R */ | ||
2260 | #define NV_PGRAPH_DMA_A_TLB_TAG_ADDRESS 31:12 /* RWXUF */ | ||
2261 | #define NV_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 /* RW-4R */ | ||
2262 | #define NV_PGRAPH_DMA_A_ADJ_OFFSET_VALUE 31:0 /* RWXUF */ | ||
2263 | #define NV_PGRAPH_DMA_A_OFFSET 0x00401058 /* RW-4R */ | ||
2264 | #define NV_PGRAPH_DMA_A_OFFSET_VALUE 31:0 /* RWXUF */ | ||
2265 | #define NV_PGRAPH_DMA_A_SIZE 0x0040105C /* RW-4R */ | ||
2266 | #define NV_PGRAPH_DMA_A_SIZE_VALUE 24:0 /* RWXUF */ | ||
2267 | #define NV_PGRAPH_DMA_A_Y_SIZE 0x00401060 /* RW-4R */ | ||
2268 | #define NV_PGRAPH_DMA_A_Y_SIZE_VALUE 10:0 /* RWXUF */ | ||
2269 | #define NV_PGRAPH_DMA_B_XLATE_INST 0x00401080 /* RW-4R */ | ||
2270 | #define NV_PGRAPH_DMA_B_XLATE_INST_VALUE 15:0 /* RWXUF */ | ||
2271 | #define NV_PGRAPH_DMA_B_CONTROL 0x00401084 /* RW-4R */ | ||
2272 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE 12:12 /* RWIVF */ | ||
2273 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */ | ||
2274 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */ | ||
2275 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */ | ||
2276 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */ | ||
2277 | #define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */ | ||
2278 | #define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE 17:16 /* RWXUF */ | ||
2279 | #define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */ | ||
2280 | #define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */ | ||
2281 | #define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */ | ||
2282 | #define NV_PGRAPH_DMA_B_CONTROL_ADJUST 31:20 /* RWXUF */ | ||
2283 | #define NV_PGRAPH_DMA_B_LIMIT 0x00401088 /* RW-4R */ | ||
2284 | #define NV_PGRAPH_DMA_B_LIMIT_OFFSET 31:0 /* RWXUF */ | ||
2285 | #define NV_PGRAPH_DMA_B_TLB_PTE 0x0040108C /* RW-4R */ | ||
2286 | #define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS 1:1 /* RWXVF */ | ||
2287 | #define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */ | ||
2288 | #define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */ | ||
2289 | #define NV_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */ | ||
2290 | #define NV_PGRAPH_DMA_B_TLB_TAG 0x00401090 /* RW-4R */ | ||
2291 | #define NV_PGRAPH_DMA_B_TLB_TAG_ADDRESS 31:12 /* RWXUF */ | ||
2292 | #define NV_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 /* RW-4R */ | ||
2293 | #define NV_PGRAPH_DMA_B_ADJ_OFFSET_VALUE 31:0 /* RWXUF */ | ||
2294 | #define NV_PGRAPH_DMA_B_OFFSET 0x00401098 /* RW-4R */ | ||
2295 | #define NV_PGRAPH_DMA_B_OFFSET_VALUE 31:0 /* RWXUF */ | ||
2296 | #define NV_PGRAPH_DMA_B_SIZE 0x0040109C /* RW-4R */ | ||
2297 | #define NV_PGRAPH_DMA_B_SIZE_VALUE 24:0 /* RWXUF */ | ||
2298 | #define NV_PGRAPH_DMA_B_Y_SIZE 0x004010A0 /* RW-4R */ | ||
2299 | #define NV_PGRAPH_DMA_B_Y_SIZE_VALUE 10:0 /* RWXUF */ | ||
2300 | |||
2301 | /* Framebuffer registers */ | ||
2302 | #define NV_PFB 0x00100FFF:0x00100000 /* RW--D */ | ||
2303 | #define NV_PFB_BOOT_0 0x00100000 /* RW-4R */ | ||
2304 | #define NV_PFB_BOOT_0_RAM_AMOUNT 1:0 /* RW-VF */ | ||
2305 | #define NV_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 /* RW--V */ | ||
2306 | #define NV_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 /* RW--V */ | ||
2307 | #define NV_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 /* RW--V */ | ||
2308 | #define NV_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 /* RW--V */ | ||
2309 | #define NV_PFB_BOOT_0_RAM_WIDTH_128 2:2 /* RW-VF */ | ||
2310 | #define NV_PFB_BOOT_0_RAM_WIDTH_128_OFF 0x00000000 /* RW--V */ | ||
2311 | #define NV_PFB_BOOT_0_RAM_WIDTH_128_ON 0x00000001 /* RW--V */ | ||
2312 | #define NV_PFB_BOOT_0_RAM_TYPE 4:3 /* RW-VF */ | ||
2313 | #define NV_PFB_BOOT_0_RAM_TYPE_256K 0x00000000 /* RW--V */ | ||
2314 | #define NV_PFB_BOOT_0_RAM_TYPE_512K_2BANK 0x00000001 /* RW--V */ | ||
2315 | #define NV_PFB_BOOT_0_RAM_TYPE_512K_4BANK 0x00000002 /* RW--V */ | ||
2316 | #define NV_PFB_BOOT_0_RAM_TYPE_1024K_2BANK 0x00000003 /* RW--V */ | ||
2317 | #define NV_PFB_CONFIG_0 0x00100200 /* RW-4R */ | ||
2318 | #define NV_PFB_CONFIG_0_TYPE 14:0 /* RWIVF */ | ||
2319 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP 0x00000120 /* RW--V */ | ||
2320 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP 0x00000220 /* RW--V */ | ||
2321 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP 0x00000320 /* RW--V */ | ||
2322 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP 0x00004120 /* RW--V */ | ||
2323 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP 0x00004220 /* RW--V */ | ||
2324 | #define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP 0x00004320 /* RW--V */ | ||
2325 | #define NV_PFB_CONFIG_0_TYPE_TETRIS 0x00002000 /* RW--V */ | ||
2326 | #define NV_PFB_CONFIG_0_TYPE_NOTILING 0x00001114 /* RWI-V */ | ||
2327 | #define NV_PFB_CONFIG_0_TETRIS_MODE 17:15 /* RWI-F */ | ||
2328 | #define NV_PFB_CONFIG_0_TETRIS_MODE_PASS 0x00000000 /* RWI-V */ | ||
2329 | #define NV_PFB_CONFIG_0_TETRIS_MODE_1 0x00000001 /* RW--V */ | ||
2330 | #define NV_PFB_CONFIG_0_TETRIS_MODE_2 0x00000002 /* RW--V */ | ||
2331 | #define NV_PFB_CONFIG_0_TETRIS_MODE_3 0x00000003 /* RW--V */ | ||
2332 | #define NV_PFB_CONFIG_0_TETRIS_MODE_4 0x00000004 /* RW--V */ | ||
2333 | #define NV_PFB_CONFIG_0_TETRIS_MODE_5 0x00000005 /* RW--V */ | ||
2334 | #define NV_PFB_CONFIG_0_TETRIS_MODE_6 0x00000006 /* RW--V */ | ||
2335 | #define NV_PFB_CONFIG_0_TETRIS_MODE_7 0x00000007 /* RW--V */ | ||
2336 | #define NV_PFB_CONFIG_0_TETRIS_SHIFT 19:18 /* RWI-F */ | ||
2337 | #define NV_PFB_CONFIG_0_TETRIS_SHIFT_0 0x00000000 /* RWI-V */ | ||
2338 | #define NV_PFB_CONFIG_0_TETRIS_SHIFT_1 0x00000001 /* RW--V */ | ||
2339 | #define NV_PFB_CONFIG_0_TETRIS_SHIFT_2 0x00000002 /* RW--V */ | ||
2340 | #define NV_PFB_CONFIG_0_BANK_SWAP 22:20 /* RWI-F */ | ||
2341 | #define NV_PFB_CONFIG_0_BANK_SWAP_OFF 0x00000000 /* RWI-V */ | ||
2342 | #define NV_PFB_CONFIG_0_BANK_SWAP_1M 0x00000001 /* RW--V */ | ||
2343 | #define NV_PFB_CONFIG_0_BANK_SWAP_2M 0x00000005 /* RW--V */ | ||
2344 | #define NV_PFB_CONFIG_0_BANK_SWAP_4M 0x00000007 /* RW--V */ | ||
2345 | #define NV_PFB_CONFIG_0_UNUSED 23:23 /* RW-VF */ | ||
2346 | #define NV_PFB_CONFIG_0_SCRAMBLE_EN 29:29 /* RWIVF */ | ||
2347 | #define NV_PFB_CONFIG_0_SCRAMBLE_EN_INIT 0x00000000 /* RW--V */ | ||
2348 | #define NV_PFB_CONFIG_0_SCRAMBLE_ACTIVE 0x00000001 /* RW--V */ | ||
2349 | #define NV_PFB_CONFIG_0_PRAMIN_WR 28:28 /* RWIVF */ | ||
2350 | #define NV_PFB_CONFIG_0_PRAMIN_WR_INIT 0x00000000 /* RW--V */ | ||
2351 | #define NV_PFB_CONFIG_0_PRAMIN_WR_DISABLED 0x00000001 /* RW--V */ | ||
2352 | #define NV_PFB_CONFIG_0_PRAMIN_WR_MASK 27:24 /* RWIVF */ | ||
2353 | #define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT 0x00000000 /* RWI-V */ | ||
2354 | #define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR 0x0000000f /* RWI-V */ | ||
2355 | #define NV_PFB_CONFIG_1 0x00100204 /* RW-4R */ | ||
2356 | #define NV_PFB_RTL 0x00100300 /* RW-4R */ | ||
2357 | #define NV_PFB_RTL_H 0:0 /* RWIUF */ | ||
2358 | #define NV_PFB_RTL_H_DEFAULT 0x00000000 /* RWI-V */ | ||
2359 | #define NV_PFB_RTL_MC 1:1 /* RWIUF */ | ||
2360 | #define NV_PFB_RTL_MC_DEFAULT 0x00000000 /* RWI-V */ | ||
2361 | #define NV_PFB_RTL_V 2:2 /* RWIUF */ | ||
2362 | #define NV_PFB_RTL_V_DEFAULT 0x00000000 /* RWI-V */ | ||
2363 | #define NV_PFB_RTL_G 3:3 /* RWIUF */ | ||
2364 | #define NV_PFB_RTL_G_DEFAULT 0x00000000 /* RWI-V */ | ||
2365 | #define NV_PFB_RTL_GB 4:4 /* RWIUF */ | ||
2366 | #define NV_PFB_RTL_GB_DEFAULT 0x00000000 /* RWI-V */ | ||
2367 | #define NV_PFB_CONFIG_0_RESOLUTION 5:0 /* RWIVF */ | ||
2368 | #define NV_PFB_CONFIG_0_RESOLUTION_320_PIXELS 0x0000000a /* RW--V */ | ||
2369 | #define NV_PFB_CONFIG_0_RESOLUTION_400_PIXELS 0x0000000d /* RW--V */ | ||
2370 | #define NV_PFB_CONFIG_0_RESOLUTION_480_PIXELS 0x0000000f /* RW--V */ | ||
2371 | #define NV_PFB_CONFIG_0_RESOLUTION_512_PIXELS 0x00000010 /* RW--V */ | ||
2372 | #define NV_PFB_CONFIG_0_RESOLUTION_640_PIXELS 0x00000014 /* RW--V */ | ||
2373 | #define NV_PFB_CONFIG_0_RESOLUTION_800_PIXELS 0x00000019 /* RW--V */ | ||
2374 | #define NV_PFB_CONFIG_0_RESOLUTION_960_PIXELS 0x0000001e /* RW--V */ | ||
2375 | #define NV_PFB_CONFIG_0_RESOLUTION_1024_PIXELS 0x00000020 /* RW--V */ | ||
2376 | #define NV_PFB_CONFIG_0_RESOLUTION_1152_PIXELS 0x00000024 /* RW--V */ | ||
2377 | #define NV_PFB_CONFIG_0_RESOLUTION_1280_PIXELS 0x00000028 /* RW--V */ | ||
2378 | #define NV_PFB_CONFIG_0_RESOLUTION_1600_PIXELS 0x00000032 /* RW--V */ | ||
2379 | #define NV_PFB_CONFIG_0_RESOLUTION_DEFAULT 0x00000014 /* RWI-V */ | ||
2380 | #define NV_PFB_CONFIG_0_PIXEL_DEPTH 9:8 /* RWIVF */ | ||
2381 | #define NV_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS 0x00000001 /* RW--V */ | ||
2382 | #define NV_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS 0x00000002 /* RW--V */ | ||
2383 | #define NV_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS 0x00000003 /* RW--V */ | ||
2384 | #define NV_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT 0x00000001 /* RWI-V */ | ||
2385 | #define NV_PFB_CONFIG_0_TILING 12:12 /* RWIVF */ | ||
2386 | #define NV_PFB_CONFIG_0_TILING_ENABLED 0x00000000 /* RW--V */ | ||
2387 | #define NV_PFB_CONFIG_0_TILING_DISABLED 0x00000001 /* RWI-V */ | ||
2388 | #define NV_PFB_CONFIG_1_SGRAM100 3:3 /* RWIVF */ | ||
2389 | #define NV_PFB_CONFIG_1_SGRAM100_ENABLED 0x00000000 /* RWI-V */ | ||
2390 | #define NV_PFB_CONFIG_1_SGRAM100_DISABLED 0x00000001 /* RW--V */ | ||
2391 | #define NV_PFB_DEBUG_0_CKE_ALWAYSON 29:29 /* RWIVF */ | ||
2392 | #define NV_PFB_DEBUG_0_CKE_ALWAYSON_OFF 0x00000000 /* RW--V */ | ||
2393 | #define NV_PFB_DEBUG_0_CKE_ALWAYSON_ON 0x00000001 /* RWI-V */ | ||
2394 | |||
2395 | #define NV_PEXTDEV 0x00101FFF:0x00101000 /* RW--D */ | ||
2396 | #define NV_PEXTDEV_BOOT_0 0x00101000 /* R--4R */ | ||
2397 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED 0:0 /* R-XVF */ | ||
2398 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_33MHZ 0x00000000 /* R---V */ | ||
2399 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_66MHZ 0x00000001 /* R---V */ | ||
2400 | #define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR 1:1 /* R-XVF */ | ||
2401 | #define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_NO_BIOS 0x00000000 /* R---V */ | ||
2402 | #define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_BIOS 0x00000001 /* R---V */ | ||
2403 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE 3:2 /* R-XVF */ | ||
2404 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_256K 0x00000000 /* R---V */ | ||
2405 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x00000001 /* R---V */ | ||
2406 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x00000002 /* R---V */ | ||
2407 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_1024K_2BANK 0x00000003 /* R---V */ | ||
2408 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH 4:4 /* R-XVF */ | ||
2409 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_64 0x00000000 /* R---V */ | ||
2410 | #define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_128 0x00000001 /* R---V */ | ||
2411 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE 5:5 /* R-XVF */ | ||
2412 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_PCI 0x00000000 /* R---V */ | ||
2413 | #define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_AGP 0x00000001 /* R---V */ | ||
2414 | #define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL 6:6 /* R-XVF */ | ||
2415 | #define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_13500K 0x00000000 /* R---V */ | ||
2416 | #define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_14318180 0x00000001 /* R---V */ | ||
2417 | #define NV_PEXTDEV_BOOT_0_STRAP_TVMODE 8:7 /* R-XVF */ | ||
2418 | #define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_SECAM 0x00000000 /* R---V */ | ||
2419 | #define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_NTSC 0x00000001 /* R---V */ | ||
2420 | #define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_PAL 0x00000002 /* R---V */ | ||
2421 | #define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_DISABLED 0x00000003 /* R---V */ | ||
2422 | #define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE 11:11 /* RWIVF */ | ||
2423 | #define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_DISABLED 0x00000000 /* RWI-V */ | ||
2424 | #define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_ENABLED 0x00000001 /* RW--V */ | ||
2425 | |||
2426 | /* Extras */ | ||
2427 | #define NV_PRAMIN 0x007FFFFF:0x00700000 /* RW--M */ | ||
2428 | /*#define NV_PRAMIN 0x00FFFFFF:0x00C00000*/ | ||
2429 | #define NV_PNVM 0x01FFFFFF:0x01000000 /* RW--M */ | ||
2430 | /*#define NV_PNVM 0x00BFFFFF:0x00800000*/ | ||
2431 | #define NV_CHAN0 0x0080ffff:0x00800000 | ||
2432 | |||
2433 | /* FIFO subchannels */ | ||
2434 | #define NV_UROP 0x43 | ||
2435 | #define NV_UCHROMA 0x57 | ||
2436 | #define NV_UCLIP 0x19 | ||
2437 | #define NV_UPATT 0x18 | ||
2438 | #define NV_ULIN 0x5C | ||
2439 | #define NV_UTRI 0x5D | ||
2440 | #define NV_URECT 0x5E | ||
2441 | #define NV_UBLIT 0x5F | ||
2442 | #define NV_UGLYPH 0x4B | ||
2443 | |||
2444 | #endif /*__NV4REF_H__*/ | ||
2445 | |||
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c index be630a0ccfd4..a11026812d1b 100644 --- a/drivers/video/riva/nv_driver.c +++ b/drivers/video/riva/nv_driver.c | |||
@@ -231,12 +231,14 @@ unsigned long riva_get_memlen(struct riva_par *par) | |||
231 | case NV_ARCH_30: | 231 | case NV_ARCH_30: |
232 | if(chipset == NV_CHIP_IGEFORCE2) { | 232 | if(chipset == NV_CHIP_IGEFORCE2) { |
233 | 233 | ||
234 | dev = pci_find_slot(0, 1); | 234 | dev = pci_get_bus_and_slot(0, 1); |
235 | pci_read_config_dword(dev, 0x7C, &amt); | 235 | pci_read_config_dword(dev, 0x7C, &amt); |
236 | pci_dev_put(dev); | ||
236 | memlen = (((amt >> 6) & 31) + 1) * 1024; | 237 | memlen = (((amt >> 6) & 31) + 1) * 1024; |
237 | } else if (chipset == NV_CHIP_0x01F0) { | 238 | } else if (chipset == NV_CHIP_0x01F0) { |
238 | dev = pci_find_slot(0, 1); | 239 | dev = pci_get_bus_and_slot(0, 1); |
239 | pci_read_config_dword(dev, 0x84, &amt); | 240 | pci_read_config_dword(dev, 0x84, &amt); |
241 | pci_dev_put(dev); | ||
240 | memlen = (((amt >> 4) & 127) + 1) * 1024; | 242 | memlen = (((amt >> 4) & 127) + 1) * 1024; |
241 | } else { | 243 | } else { |
242 | switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & | 244 | switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & |
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c index e0b8c521cc9c..70bfd78eca81 100644 --- a/drivers/video/riva/riva_hw.c +++ b/drivers/video/riva/riva_hw.c | |||
@@ -1118,8 +1118,9 @@ static void nForceUpdateArbitrationSettings | |||
1118 | unsigned int uMClkPostDiv; | 1118 | unsigned int uMClkPostDiv; |
1119 | struct pci_dev *dev; | 1119 | struct pci_dev *dev; |
1120 | 1120 | ||
1121 | dev = pci_find_slot(0, 3); | 1121 | dev = pci_get_bus_and_slot(0, 3); |
1122 | pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); | 1122 | pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); |
1123 | pci_dev_put(dev); | ||
1123 | uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; | 1124 | uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; |
1124 | 1125 | ||
1125 | if(!uMClkPostDiv) uMClkPostDiv = 4; | 1126 | if(!uMClkPostDiv) uMClkPostDiv = 4; |
@@ -1132,8 +1133,9 @@ static void nForceUpdateArbitrationSettings | |||
1132 | sim_data.enable_video = 0; | 1133 | sim_data.enable_video = 0; |
1133 | sim_data.enable_mp = 0; | 1134 | sim_data.enable_mp = 0; |
1134 | 1135 | ||
1135 | dev = pci_find_slot(0, 1); | 1136 | dev = pci_get_bus_and_slot(0, 1); |
1136 | pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); | 1137 | pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); |
1138 | pci_dev_put(dev); | ||
1137 | sim_data.memory_type = (sim_data.memory_type >> 12) & 1; | 1139 | sim_data.memory_type = (sim_data.memory_type >> 12) & 1; |
1138 | 1140 | ||
1139 | sim_data.memory_width = 64; | 1141 | sim_data.memory_width = 64; |
@@ -2112,12 +2114,14 @@ static void nv10GetConfig | |||
2112 | * Fill in chip configuration. | 2114 | * Fill in chip configuration. |
2113 | */ | 2115 | */ |
2114 | if(chipset == NV_CHIP_IGEFORCE2) { | 2116 | if(chipset == NV_CHIP_IGEFORCE2) { |
2115 | dev = pci_find_slot(0, 1); | 2117 | dev = pci_get_bus_and_slot(0, 1); |
2116 | pci_read_config_dword(dev, 0x7C, &amt); | 2118 | pci_read_config_dword(dev, 0x7C, &amt); |
2119 | pci_dev_put(dev); | ||
2117 | chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; | 2120 | chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; |
2118 | } else if(chipset == NV_CHIP_0x01F0) { | 2121 | } else if(chipset == NV_CHIP_0x01F0) { |
2119 | dev = pci_find_slot(0, 1); | 2122 | dev = pci_get_bus_and_slot(0, 1); |
2120 | pci_read_config_dword(dev, 0x84, &amt); | 2123 | pci_read_config_dword(dev, 0x84, &amt); |
2124 | pci_dev_put(dev); | ||
2121 | chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; | 2125 | chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; |
2122 | } else { | 2126 | } else { |
2123 | switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF) | 2127 | switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF) |
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 0405e839ff93..76e6ce353c8e 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c | |||
@@ -88,13 +88,16 @@ static int riva_gpio_getsda(void* data) | |||
88 | return val; | 88 | return val; |
89 | } | 89 | } |
90 | 90 | ||
91 | static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name) | 91 | static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan, |
92 | const char *name, | ||
93 | unsigned int i2c_class) | ||
92 | { | 94 | { |
93 | int rc; | 95 | int rc; |
94 | 96 | ||
95 | strcpy(chan->adapter.name, name); | 97 | strcpy(chan->adapter.name, name); |
96 | chan->adapter.owner = THIS_MODULE; | 98 | chan->adapter.owner = THIS_MODULE; |
97 | chan->adapter.id = I2C_HW_B_RIVA; | 99 | chan->adapter.id = I2C_HW_B_RIVA; |
100 | chan->adapter.class = i2c_class; | ||
98 | chan->adapter.algo_data = &chan->algo; | 101 | chan->adapter.algo_data = &chan->algo; |
99 | chan->adapter.dev.parent = &chan->par->pdev->dev; | 102 | chan->adapter.dev.parent = &chan->par->pdev->dev; |
100 | chan->algo.setsda = riva_gpio_setsda; | 103 | chan->algo.setsda = riva_gpio_setsda; |
@@ -124,42 +127,38 @@ static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name) | |||
124 | return rc; | 127 | return rc; |
125 | } | 128 | } |
126 | 129 | ||
127 | void riva_create_i2c_busses(struct riva_par *par) | 130 | void __devinit riva_create_i2c_busses(struct riva_par *par) |
128 | { | 131 | { |
129 | par->bus = 3; | ||
130 | |||
131 | par->chan[0].par = par; | 132 | par->chan[0].par = par; |
132 | par->chan[1].par = par; | 133 | par->chan[1].par = par; |
133 | par->chan[2].par = par; | 134 | par->chan[2].par = par; |
134 | 135 | ||
135 | par->chan[0].ddc_base = 0x3e; | 136 | par->chan[0].ddc_base = 0x36; |
136 | par->chan[1].ddc_base = 0x36; | 137 | par->chan[1].ddc_base = 0x3e; |
137 | par->chan[2].ddc_base = 0x50; | 138 | par->chan[2].ddc_base = 0x50; |
138 | riva_setup_i2c_bus(&par->chan[0], "BUS1"); | 139 | riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON); |
139 | riva_setup_i2c_bus(&par->chan[1], "BUS2"); | 140 | riva_setup_i2c_bus(&par->chan[1], "BUS2", 0); |
140 | riva_setup_i2c_bus(&par->chan[2], "BUS3"); | 141 | riva_setup_i2c_bus(&par->chan[2], "BUS3", 0); |
141 | } | 142 | } |
142 | 143 | ||
143 | void riva_delete_i2c_busses(struct riva_par *par) | 144 | void riva_delete_i2c_busses(struct riva_par *par) |
144 | { | 145 | { |
145 | if (par->chan[0].par) | 146 | int i; |
146 | i2c_del_adapter(&par->chan[0].adapter); | ||
147 | par->chan[0].par = NULL; | ||
148 | |||
149 | if (par->chan[1].par) | ||
150 | i2c_del_adapter(&par->chan[1].adapter); | ||
151 | par->chan[1].par = NULL; | ||
152 | 147 | ||
153 | if (par->chan[2].par) | 148 | for (i = 0; i < 3; i++) { |
154 | i2c_del_adapter(&par->chan[2].adapter); | 149 | if (!par->chan[i].par) |
155 | par->chan[2].par = NULL; | 150 | continue; |
151 | i2c_del_adapter(&par->chan[i].adapter); | ||
152 | par->chan[i].par = NULL; | ||
153 | } | ||
156 | } | 154 | } |
157 | 155 | ||
158 | int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) | 156 | int __devinit riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) |
159 | { | 157 | { |
160 | u8 *edid = NULL; | 158 | u8 *edid = NULL; |
161 | 159 | ||
162 | edid = fb_ddc_read(&par->chan[conn-1].adapter); | 160 | if (par->chan[conn].par) |
161 | edid = fb_ddc_read(&par->chan[conn].adapter); | ||
163 | 162 | ||
164 | if (out_edid) | 163 | if (out_edid) |
165 | *out_edid = edid; | 164 | *out_edid = edid; |
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h index 48ead6d72f24..d9f107b704c6 100644 --- a/drivers/video/riva/rivafb.h +++ b/drivers/video/riva/rivafb.h | |||
@@ -4,7 +4,6 @@ | |||
4 | #include <linux/fb.h> | 4 | #include <linux/fb.h> |
5 | #include <video/vga.h> | 5 | #include <video/vga.h> |
6 | #include <linux/i2c.h> | 6 | #include <linux/i2c.h> |
7 | #include <linux/i2c-id.h> | ||
8 | #include <linux/i2c-algo-bit.h> | 7 | #include <linux/i2c-algo-bit.h> |
9 | 8 | ||
10 | #include "riva_hw.h" | 9 | #include "riva_hw.h" |
@@ -61,7 +60,6 @@ struct riva_par { | |||
61 | Bool SecondCRTC; | 60 | Bool SecondCRTC; |
62 | int FlatPanel; | 61 | int FlatPanel; |
63 | struct pci_dev *pdev; | 62 | struct pci_dev *pdev; |
64 | int bus; | ||
65 | int cursor_reset; | 63 | int cursor_reset; |
66 | #ifdef CONFIG_MTRR | 64 | #ifdef CONFIG_MTRR |
67 | struct { int vram; int vram_valid; } mtrr; | 65 | struct { int vram; int vram_valid; } mtrr; |
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 3091b20124b4..756fafb41d78 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c | |||
@@ -65,7 +65,7 @@ static const struct svga_fb_format s3fb_formats[] = { | |||
65 | 65 | ||
66 | 66 | ||
67 | static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, | 67 | static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, |
68 | 60000, 240000, 14318}; | 68 | 35000, 240000, 14318}; |
69 | 69 | ||
70 | static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; | 70 | static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; |
71 | 71 | ||
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, defau | |||
164 | static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) | 164 | static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) |
165 | { | 165 | { |
166 | const u8 *font = map->data; | 166 | const u8 *font = map->data; |
167 | u8* fb = (u8 *) info->screen_base; | 167 | u8 __iomem *fb = (u8 __iomem *) info->screen_base; |
168 | int i, c; | 168 | int i, c; |
169 | 169 | ||
170 | if ((map->width != 8) || (map->height != 16) || | 170 | if ((map->width != 8) || (map->height != 16) || |
@@ -177,20 +177,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) | |||
177 | fb += 2; | 177 | fb += 2; |
178 | for (i = 0; i < map->height; i++) { | 178 | for (i = 0; i < map->height; i++) { |
179 | for (c = 0; c < map->length; c++) { | 179 | for (c = 0; c < map->length; c++) { |
180 | fb[c * 4] = font[c * map->height + i]; | 180 | fb_writeb(font[c * map->height + i], fb + c * 4); |
181 | } | 181 | } |
182 | fb += 1024; | 182 | fb += 1024; |
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | |||
187 | |||
188 | static struct fb_tile_ops s3fb_tile_ops = { | 186 | static struct fb_tile_ops s3fb_tile_ops = { |
189 | .fb_settile = svga_settile, | 187 | .fb_settile = svga_settile, |
190 | .fb_tilecopy = svga_tilecopy, | 188 | .fb_tilecopy = svga_tilecopy, |
191 | .fb_tilefill = svga_tilefill, | 189 | .fb_tilefill = svga_tilefill, |
192 | .fb_tileblit = svga_tileblit, | 190 | .fb_tileblit = svga_tileblit, |
193 | .fb_tilecursor = svga_tilecursor, | 191 | .fb_tilecursor = svga_tilecursor, |
192 | .fb_get_tilemax = svga_get_tilemax, | ||
194 | }; | 193 | }; |
195 | 194 | ||
196 | static struct fb_tile_ops s3fb_fast_tile_ops = { | 195 | static struct fb_tile_ops s3fb_fast_tile_ops = { |
@@ -199,6 +198,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = { | |||
199 | .fb_tilefill = svga_tilefill, | 198 | .fb_tilefill = svga_tilefill, |
200 | .fb_tileblit = svga_tileblit, | 199 | .fb_tileblit = svga_tileblit, |
201 | .fb_tilecursor = svga_tilecursor, | 200 | .fb_tilecursor = svga_tilecursor, |
201 | .fb_get_tilemax = svga_get_tilemax, | ||
202 | }; | 202 | }; |
203 | 203 | ||
204 | 204 | ||
@@ -326,8 +326,13 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock) | |||
326 | { | 326 | { |
327 | u16 m, n, r; | 327 | u16 m, n, r; |
328 | u8 regval; | 328 | u8 regval; |
329 | int rv; | ||
329 | 330 | ||
330 | svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); | 331 | rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); |
332 | if (rv < 0) { | ||
333 | printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); | ||
334 | return; | ||
335 | } | ||
331 | 336 | ||
332 | /* Set VGA misc register */ | 337 | /* Set VGA misc register */ |
333 | regval = vga_r(NULL, VGA_MIS_R); | 338 | regval = vga_r(NULL, VGA_MIS_R); |
@@ -449,6 +454,10 @@ static int s3fb_set_par(struct fb_info *info) | |||
449 | info->flags &= ~FBINFO_MISC_TILEBLITTING; | 454 | info->flags &= ~FBINFO_MISC_TILEBLITTING; |
450 | info->tileops = NULL; | 455 | info->tileops = NULL; |
451 | 456 | ||
457 | /* in 4bpp supports 8p wide tiles only, any tiles otherwise */ | ||
458 | info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0); | ||
459 | info->pixmap.blit_y = ~(u32)0; | ||
460 | |||
452 | offset_value = (info->var.xres_virtual * bpp) / 64; | 461 | offset_value = (info->var.xres_virtual * bpp) / 64; |
453 | screen_size = info->var.yres_virtual * info->fix.line_length; | 462 | screen_size = info->var.yres_virtual * info->fix.line_length; |
454 | } else { | 463 | } else { |
@@ -458,6 +467,10 @@ static int s3fb_set_par(struct fb_info *info) | |||
458 | info->flags |= FBINFO_MISC_TILEBLITTING; | 467 | info->flags |= FBINFO_MISC_TILEBLITTING; |
459 | info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; | 468 | info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; |
460 | 469 | ||
470 | /* supports 8x16 tiles only */ | ||
471 | info->pixmap.blit_x = 1 << (8 - 1); | ||
472 | info->pixmap.blit_y = 1 << (16 - 1); | ||
473 | |||
461 | offset_value = info->var.xres_virtual / 16; | 474 | offset_value = info->var.xres_virtual / 16; |
462 | screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64; | 475 | screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64; |
463 | } | 476 | } |
@@ -656,7 +669,7 @@ static int s3fb_set_par(struct fb_info *info) | |||
656 | value = ((value * hmul) / 8) - 5; | 669 | value = ((value * hmul) / 8) - 5; |
657 | vga_wcrt(NULL, 0x3C, (value + 1) / 2); | 670 | vga_wcrt(NULL, 0x3C, (value + 1) / 2); |
658 | 671 | ||
659 | memset((u8*)info->screen_base, 0x00, screen_size); | 672 | memset_io(info->screen_base, 0x00, screen_size); |
660 | /* Device and screen back on */ | 673 | /* Device and screen back on */ |
661 | svga_wcrt_mask(0x17, 0x80, 0x80); | 674 | svga_wcrt_mask(0x17, 0x80, 0x80); |
662 | svga_wseq_mask(0x01, 0x00, 0x20); | 675 | svga_wseq_mask(0x01, 0x00, 0x20); |
@@ -699,7 +712,7 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
699 | break; | 712 | break; |
700 | case 16: | 713 | case 16: |
701 | if (regno >= 16) | 714 | if (regno >= 16) |
702 | return -EINVAL; | 715 | return 0; |
703 | 716 | ||
704 | if (fb->var.green.length == 5) | 717 | if (fb->var.green.length == 5) |
705 | ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | | 718 | ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | |
@@ -712,9 +725,9 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
712 | case 24: | 725 | case 24: |
713 | case 32: | 726 | case 32: |
714 | if (regno >= 16) | 727 | if (regno >= 16) |
715 | return -EINVAL; | 728 | return 0; |
716 | 729 | ||
717 | ((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) | | 730 | ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) | |
718 | (green & 0xFF00) | ((blue & 0xFF00) >> 8); | 731 | (green & 0xFF00) | ((blue & 0xFF00) >> 8); |
719 | break; | 732 | break; |
720 | default: | 733 | default: |
@@ -767,12 +780,6 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
767 | 780 | ||
768 | unsigned int offset; | 781 | unsigned int offset; |
769 | 782 | ||
770 | /* Validate the offsets */ | ||
771 | if ((var->xoffset + var->xres) > var->xres_virtual) | ||
772 | return -EINVAL; | ||
773 | if ((var->yoffset + var->yres) > var->yres_virtual) | ||
774 | return -EINVAL; | ||
775 | |||
776 | /* Calculate the offset */ | 783 | /* Calculate the offset */ |
777 | if (var->bits_per_pixel == 0) { | 784 | if (var->bits_per_pixel == 0) { |
778 | offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2); | 785 | offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2); |
@@ -789,6 +796,23 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | |||
789 | return 0; | 796 | return 0; |
790 | } | 797 | } |
791 | 798 | ||
799 | /* Get capabilities of accelerator based on the mode */ | ||
800 | |||
801 | static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps, | ||
802 | struct fb_var_screeninfo *var) | ||
803 | { | ||
804 | if (var->bits_per_pixel == 0) { | ||
805 | /* can only support 256 8x16 bitmap */ | ||
806 | caps->x = 1 << (8 - 1); | ||
807 | caps->y = 1 << (16 - 1); | ||
808 | caps->len = 256; | ||
809 | } else { | ||
810 | caps->x = ~(u32)0; | ||
811 | caps->y = ~(u32)0; | ||
812 | caps->len = ~(u32)0; | ||
813 | } | ||
814 | } | ||
815 | |||
792 | /* ------------------------------------------------------------------------- */ | 816 | /* ------------------------------------------------------------------------- */ |
793 | 817 | ||
794 | /* Frame buffer operations */ | 818 | /* Frame buffer operations */ |
@@ -805,6 +829,7 @@ static struct fb_ops s3fb_ops = { | |||
805 | .fb_fillrect = s3fb_fillrect, | 829 | .fb_fillrect = s3fb_fillrect, |
806 | .fb_copyarea = cfb_copyarea, | 830 | .fb_copyarea = cfb_copyarea, |
807 | .fb_imageblit = s3fb_imageblit, | 831 | .fb_imageblit = s3fb_imageblit, |
832 | .fb_get_caps = s3fb_get_caps, | ||
808 | }; | 833 | }; |
809 | 834 | ||
810 | /* ------------------------------------------------------------------------- */ | 835 | /* ------------------------------------------------------------------------- */ |
@@ -1061,6 +1086,7 @@ static int s3_pci_resume(struct pci_dev* dev) | |||
1061 | { | 1086 | { |
1062 | struct fb_info *info = pci_get_drvdata(dev); | 1087 | struct fb_info *info = pci_get_drvdata(dev); |
1063 | struct s3fb_info *par = info->par; | 1088 | struct s3fb_info *par = info->par; |
1089 | int err; | ||
1064 | 1090 | ||
1065 | dev_info(&(dev->dev), "resume\n"); | 1091 | dev_info(&(dev->dev), "resume\n"); |
1066 | 1092 | ||
@@ -1075,7 +1101,13 @@ static int s3_pci_resume(struct pci_dev* dev) | |||
1075 | 1101 | ||
1076 | pci_set_power_state(dev, PCI_D0); | 1102 | pci_set_power_state(dev, PCI_D0); |
1077 | pci_restore_state(dev); | 1103 | pci_restore_state(dev); |
1078 | pci_enable_device(dev); | 1104 | err = pci_enable_device(dev); |
1105 | if (err) { | ||
1106 | mutex_unlock(&(par->open_lock)); | ||
1107 | release_console_sem(); | ||
1108 | dev_err(&(dev->dev), "error %d enabling device for resume\n", err); | ||
1109 | return err; | ||
1110 | } | ||
1079 | pci_set_master(dev); | 1111 | pci_set_master(dev); |
1080 | 1112 | ||
1081 | s3fb_set_par(info); | 1113 | s3fb_set_par(info); |
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 8db066ccca6b..35c1ce62b216 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c | |||
@@ -41,10 +41,6 @@ | |||
41 | #define SAVAGE4_I2C_SCL_IN 0x00000008 | 41 | #define SAVAGE4_I2C_SCL_IN 0x00000008 |
42 | #define SAVAGE4_I2C_SDA_IN 0x00000010 | 42 | #define SAVAGE4_I2C_SDA_IN 0x00000010 |
43 | 43 | ||
44 | #define SET_CR_IX(base, val) writeb((val), base + 0x8000 + VGA_CR_IX) | ||
45 | #define SET_CR_DATA(base, val) writeb((val), base + 0x8000 + VGA_CR_DATA) | ||
46 | #define GET_CR_DATA(base) readb(base + 0x8000 + VGA_CR_DATA) | ||
47 | |||
48 | static void savage4_gpio_setscl(void *data, int val) | 44 | static void savage4_gpio_setscl(void *data, int val) |
49 | { | 45 | { |
50 | struct savagefb_i2c_chan *chan = data; | 46 | struct savagefb_i2c_chan *chan = data; |
@@ -92,15 +88,15 @@ static void prosavage_gpio_setscl(void* data, int val) | |||
92 | struct savagefb_i2c_chan *chan = data; | 88 | struct savagefb_i2c_chan *chan = data; |
93 | u32 r; | 89 | u32 r; |
94 | 90 | ||
95 | SET_CR_IX(chan->ioaddr, chan->reg); | 91 | r = VGArCR(chan->reg, chan->par); |
96 | r = GET_CR_DATA(chan->ioaddr); | ||
97 | r |= PROSAVAGE_I2C_ENAB; | 92 | r |= PROSAVAGE_I2C_ENAB; |
98 | if (val) { | 93 | if (val) { |
99 | r |= PROSAVAGE_I2C_SCL_OUT; | 94 | r |= PROSAVAGE_I2C_SCL_OUT; |
100 | } else { | 95 | } else { |
101 | r &= ~PROSAVAGE_I2C_SCL_OUT; | 96 | r &= ~PROSAVAGE_I2C_SCL_OUT; |
102 | } | 97 | } |
103 | SET_CR_DATA(chan->ioaddr, r); | 98 | |
99 | VGAwCR(chan->reg, r, chan->par); | ||
104 | } | 100 | } |
105 | 101 | ||
106 | static void prosavage_gpio_setsda(void* data, int val) | 102 | static void prosavage_gpio_setsda(void* data, int val) |
@@ -108,31 +104,29 @@ static void prosavage_gpio_setsda(void* data, int val) | |||
108 | struct savagefb_i2c_chan *chan = data; | 104 | struct savagefb_i2c_chan *chan = data; |
109 | unsigned int r; | 105 | unsigned int r; |
110 | 106 | ||
111 | SET_CR_IX(chan->ioaddr, chan->reg); | 107 | r = VGArCR(chan->reg, chan->par); |
112 | r = GET_CR_DATA(chan->ioaddr); | ||
113 | r |= PROSAVAGE_I2C_ENAB; | 108 | r |= PROSAVAGE_I2C_ENAB; |
114 | if (val) { | 109 | if (val) { |
115 | r |= PROSAVAGE_I2C_SDA_OUT; | 110 | r |= PROSAVAGE_I2C_SDA_OUT; |
116 | } else { | 111 | } else { |
117 | r &= ~PROSAVAGE_I2C_SDA_OUT; | 112 | r &= ~PROSAVAGE_I2C_SDA_OUT; |
118 | } | 113 | } |
119 | SET_CR_DATA(chan->ioaddr, r); | 114 | |
115 | VGAwCR(chan->reg, r, chan->par); | ||
120 | } | 116 | } |
121 | 117 | ||
122 | static int prosavage_gpio_getscl(void* data) | 118 | static int prosavage_gpio_getscl(void* data) |
123 | { | 119 | { |
124 | struct savagefb_i2c_chan *chan = data; | 120 | struct savagefb_i2c_chan *chan = data; |
125 | 121 | ||
126 | SET_CR_IX(chan->ioaddr, chan->reg); | 122 | return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SCL_IN) ? 1 : 0; |
127 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN)); | ||
128 | } | 123 | } |
129 | 124 | ||
130 | static int prosavage_gpio_getsda(void* data) | 125 | static int prosavage_gpio_getsda(void* data) |
131 | { | 126 | { |
132 | struct savagefb_i2c_chan *chan = data; | 127 | struct savagefb_i2c_chan *chan = data; |
133 | 128 | ||
134 | SET_CR_IX(chan->ioaddr, chan->reg); | 129 | return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SDA_IN) ? 1 : 0; |
135 | return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN)); | ||
136 | } | 130 | } |
137 | 131 | ||
138 | static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, | 132 | static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, |
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index e648a6c0f6d9..8bfdfc3c5234 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/i2c-id.h> | 16 | #include <linux/i2c-id.h> |
17 | #include <linux/i2c-algo-bit.h> | 17 | #include <linux/i2c-algo-bit.h> |
18 | #include <linux/mutex.h> | ||
19 | #include <video/vga.h> | ||
18 | #include "../edid.h" | 20 | #include "../edid.h" |
19 | 21 | ||
20 | #ifdef SAVAGEFB_DEBUG | 22 | #ifdef SAVAGEFB_DEBUG |
@@ -189,8 +191,12 @@ struct savagefb_par { | |||
189 | struct savagefb_i2c_chan chan; | 191 | struct savagefb_i2c_chan chan; |
190 | struct savage_reg state; | 192 | struct savage_reg state; |
191 | struct savage_reg save; | 193 | struct savage_reg save; |
194 | struct savage_reg initial; | ||
195 | struct vgastate vgastate; | ||
196 | struct mutex open_lock; | ||
192 | unsigned char *edid; | 197 | unsigned char *edid; |
193 | u32 pseudo_palette[16]; | 198 | u32 pseudo_palette[16]; |
199 | u32 open_count; | ||
194 | int paletteEnabled; | 200 | int paletteEnabled; |
195 | int pm_state; | 201 | int pm_state; |
196 | int display_type; | 202 | int display_type; |
@@ -203,7 +209,7 @@ struct savagefb_par { | |||
203 | int clock[4]; | 209 | int clock[4]; |
204 | int MCLK, REFCLK, LCDclk; | 210 | int MCLK, REFCLK, LCDclk; |
205 | struct { | 211 | struct { |
206 | u8 __iomem *vbase; | 212 | void __iomem *vbase; |
207 | u32 pbase; | 213 | u32 pbase; |
208 | u32 len; | 214 | u32 len; |
209 | #ifdef CONFIG_MTRR | 215 | #ifdef CONFIG_MTRR |
@@ -212,7 +218,7 @@ struct savagefb_par { | |||
212 | } video; | 218 | } video; |
213 | 219 | ||
214 | struct { | 220 | struct { |
215 | volatile u8 __iomem *vbase; | 221 | void __iomem *vbase; |
216 | u32 pbase; | 222 | u32 pbase; |
217 | u32 len; | 223 | u32 len; |
218 | } mmio; | 224 | } mmio; |
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 0166ec2ccf32..3d7507ad55f6 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -1623,8 +1623,46 @@ static void savagefb_restore_state(struct fb_info *info) | |||
1623 | savagefb_blank(FB_BLANK_UNBLANK, info); | 1623 | savagefb_blank(FB_BLANK_UNBLANK, info); |
1624 | } | 1624 | } |
1625 | 1625 | ||
1626 | static int savagefb_open(struct fb_info *info, int user) | ||
1627 | { | ||
1628 | struct savagefb_par *par = info->par; | ||
1629 | |||
1630 | mutex_lock(&par->open_lock); | ||
1631 | |||
1632 | if (!par->open_count) { | ||
1633 | memset(&par->vgastate, 0, sizeof(par->vgastate)); | ||
1634 | par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS | | ||
1635 | VGA_SAVE_MODE; | ||
1636 | par->vgastate.vgabase = par->mmio.vbase + 0x8000; | ||
1637 | save_vga(&par->vgastate); | ||
1638 | savage_get_default_par(par, &par->initial); | ||
1639 | } | ||
1640 | |||
1641 | par->open_count++; | ||
1642 | mutex_unlock(&par->open_lock); | ||
1643 | return 0; | ||
1644 | } | ||
1645 | |||
1646 | static int savagefb_release(struct fb_info *info, int user) | ||
1647 | { | ||
1648 | struct savagefb_par *par = info->par; | ||
1649 | |||
1650 | mutex_lock(&par->open_lock); | ||
1651 | |||
1652 | if (par->open_count == 1) { | ||
1653 | savage_set_default_par(par, &par->initial); | ||
1654 | restore_vga(&par->vgastate); | ||
1655 | } | ||
1656 | |||
1657 | par->open_count--; | ||
1658 | mutex_unlock(&par->open_lock); | ||
1659 | return 0; | ||
1660 | } | ||
1661 | |||
1626 | static struct fb_ops savagefb_ops = { | 1662 | static struct fb_ops savagefb_ops = { |
1627 | .owner = THIS_MODULE, | 1663 | .owner = THIS_MODULE, |
1664 | .fb_open = savagefb_open, | ||
1665 | .fb_release = savagefb_release, | ||
1628 | .fb_check_var = savagefb_check_var, | 1666 | .fb_check_var = savagefb_check_var, |
1629 | .fb_set_par = savagefb_set_par, | 1667 | .fb_set_par = savagefb_set_par, |
1630 | .fb_setcolreg = savagefb_setcolreg, | 1668 | .fb_setcolreg = savagefb_setcolreg, |
@@ -2173,6 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev, | |||
2173 | if (!info) | 2211 | if (!info) |
2174 | return -ENOMEM; | 2212 | return -ENOMEM; |
2175 | par = info->par; | 2213 | par = info->par; |
2214 | mutex_init(&par->open_lock); | ||
2176 | err = pci_enable_device(dev); | 2215 | err = pci_enable_device(dev); |
2177 | if (err) | 2216 | if (err) |
2178 | goto failed_enable; | 2217 | goto failed_enable; |
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h index d048bd39961b..c1492782cb18 100644 --- a/drivers/video/sis/osdef.h +++ b/drivers/video/sis/osdef.h | |||
@@ -58,9 +58,6 @@ | |||
58 | #define SIS_LINUX_KERNEL /* Linux kernel framebuffer */ | 58 | #define SIS_LINUX_KERNEL /* Linux kernel framebuffer */ |
59 | #undef SIS_XORG_XF86 /* XFree86/X.org */ | 59 | #undef SIS_XORG_XF86 /* XFree86/X.org */ |
60 | 60 | ||
61 | #undef SIS_LINUX_KERNEL_24 | ||
62 | #undef SIS_LINUX_KERNEL_26 | ||
63 | |||
64 | #ifdef OutPortByte | 61 | #ifdef OutPortByte |
65 | #undef OutPortByte | 62 | #undef OutPortByte |
66 | #endif | 63 | #endif |
@@ -100,8 +97,6 @@ | |||
100 | #define SIS315H | 97 | #define SIS315H |
101 | #endif | 98 | #endif |
102 | 99 | ||
103 | #define SIS_LINUX_KERNEL_26 | ||
104 | |||
105 | #if !defined(SIS300) && !defined(SIS315H) | 100 | #if !defined(SIS300) && !defined(SIS315H) |
106 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set | 101 | #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set |
107 | #warning sisfb will not work! | 102 | #warning sisfb will not work! |
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h index 7d5ee2145e21..d5e2d9c27847 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/sis/sis.h | |||
@@ -27,11 +27,7 @@ | |||
27 | #include <linux/version.h> | 27 | #include <linux/version.h> |
28 | 28 | ||
29 | #include "osdef.h" | 29 | #include "osdef.h" |
30 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
31 | #include <video/sisfb.h> | 30 | #include <video/sisfb.h> |
32 | #else | ||
33 | #include <linux/sisfb.h> | ||
34 | #endif | ||
35 | 31 | ||
36 | #include "vgatypes.h" | 32 | #include "vgatypes.h" |
37 | #include "vstruct.h" | 33 | #include "vstruct.h" |
@@ -40,33 +36,17 @@ | |||
40 | #define VER_MINOR 8 | 36 | #define VER_MINOR 8 |
41 | #define VER_LEVEL 9 | 37 | #define VER_LEVEL 9 |
42 | 38 | ||
43 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
44 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
45 | #define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b) | 40 | |
46 | #define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c) | ||
47 | #define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b) | ||
48 | #define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a) | ||
49 | #ifdef CONFIG_COMPAT | 41 | #ifdef CONFIG_COMPAT |
50 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) | 42 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) |
51 | #include <linux/ioctl32.h> | 43 | #include <linux/ioctl32.h> |
52 | #define SIS_OLD_CONFIG_COMPAT | 44 | #define SIS_OLD_CONFIG_COMPAT |
53 | #else | 45 | #else |
54 | #include <linux/smp_lock.h> | ||
55 | #define SIS_NEW_CONFIG_COMPAT | 46 | #define SIS_NEW_CONFIG_COMPAT |
56 | #endif | 47 | #endif |
57 | #endif /* CONFIG_COMPAT */ | 48 | #endif /* CONFIG_COMPAT */ |
58 | #else /* 2.4 */ | 49 | |
59 | #define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b) | ||
60 | #define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c) | ||
61 | #define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b) | ||
62 | #define SIS_PCI_PUT_DEVICE(a) | ||
63 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19) | ||
64 | #ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */ | ||
65 | #include <asm/ioctl32.h> | ||
66 | #define SIS_OLD_CONFIG_COMPAT | ||
67 | #endif | ||
68 | #endif | ||
69 | #endif /* 2.4 */ | ||
70 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) | 50 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) |
71 | #define SIS_IOTYPE1 void __iomem | 51 | #define SIS_IOTYPE1 void __iomem |
72 | #define SIS_IOTYPE2 __iomem | 52 | #define SIS_IOTYPE2 __iomem |
@@ -498,26 +478,8 @@ struct sis_video_info { | |||
498 | 478 | ||
499 | struct fb_var_screeninfo default_var; | 479 | struct fb_var_screeninfo default_var; |
500 | 480 | ||
501 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
502 | struct fb_fix_screeninfo sisfb_fix; | 481 | struct fb_fix_screeninfo sisfb_fix; |
503 | u32 pseudo_palette[17]; | 482 | u32 pseudo_palette[17]; |
504 | #endif | ||
505 | |||
506 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
507 | struct display sis_disp; | ||
508 | struct display_switch sisfb_sw; | ||
509 | struct { | ||
510 | u16 red, green, blue, pad; | ||
511 | } sis_palette[256]; | ||
512 | union { | ||
513 | #ifdef FBCON_HAS_CFB16 | ||
514 | u16 cfb16[16]; | ||
515 | #endif | ||
516 | #ifdef FBCON_HAS_CFB32 | ||
517 | u32 cfb32[16]; | ||
518 | #endif | ||
519 | } sis_fbcon_cmap; | ||
520 | #endif | ||
521 | 483 | ||
522 | struct sisfb_monitor { | 484 | struct sisfb_monitor { |
523 | u16 hmin; | 485 | u16 hmin; |
@@ -538,10 +500,6 @@ struct sis_video_info { | |||
538 | 500 | ||
539 | int mni; /* Mode number index */ | 501 | int mni; /* Mode number index */ |
540 | 502 | ||
541 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
542 | int currcon; | ||
543 | #endif | ||
544 | |||
545 | unsigned long video_size; | 503 | unsigned long video_size; |
546 | unsigned long video_base; | 504 | unsigned long video_base; |
547 | unsigned long mmio_size; | 505 | unsigned long mmio_size; |
@@ -578,9 +536,6 @@ struct sis_video_info { | |||
578 | int sisfb_tvplug; | 536 | int sisfb_tvplug; |
579 | int sisfb_tvstd; | 537 | int sisfb_tvstd; |
580 | int sisfb_nocrt2rate; | 538 | int sisfb_nocrt2rate; |
581 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
582 | int sisfb_inverse; | ||
583 | #endif | ||
584 | 539 | ||
585 | u32 heapstart; /* offset */ | 540 | u32 heapstart; /* offset */ |
586 | SIS_IOTYPE1 *sisfb_heap_start; /* address */ | 541 | SIS_IOTYPE1 *sisfb_heap_start; /* address */ |
@@ -646,9 +601,7 @@ struct sis_video_info { | |||
646 | int modechanged; | 601 | int modechanged; |
647 | unsigned char modeprechange; | 602 | unsigned char modeprechange; |
648 | 603 | ||
649 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
650 | u8 sisfb_lastrates[128]; | 604 | u8 sisfb_lastrates[128]; |
651 | #endif | ||
652 | 605 | ||
653 | int newrom; | 606 | int newrom; |
654 | int haveXGIROM; | 607 | int haveXGIROM; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 01197d740217..a30e1e13d8be 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
42 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
43 | #include <linux/string.h> | 42 | #include <linux/string.h> |
@@ -1948,7 +1947,7 @@ sisfb_get_northbridge(int basechipid) | |||
1948 | default: return NULL; | 1947 | default: return NULL; |
1949 | } | 1948 | } |
1950 | for(i = 0; i < nbridgenum; i++) { | 1949 | for(i = 0; i < nbridgenum; i++) { |
1951 | if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, | 1950 | if((pdev = pci_get_device(PCI_VENDOR_ID_SI, |
1952 | nbridgeids[nbridgeidx+i], NULL))) | 1951 | nbridgeids[nbridgeidx+i], NULL))) |
1953 | break; | 1952 | break; |
1954 | } | 1953 | } |
@@ -4613,9 +4612,9 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev, | |||
4613 | unsigned short temp; | 4612 | unsigned short temp; |
4614 | int ret = 0; | 4613 | int ret = 0; |
4615 | 4614 | ||
4616 | while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) { | 4615 | while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { |
4617 | temp = pdev->vendor; | 4616 | temp = pdev->vendor; |
4618 | SIS_PCI_PUT_DEVICE(pdev); | 4617 | pci_dev_put(pdev); |
4619 | if(temp == pcivendor) { | 4618 | if(temp == pcivendor) { |
4620 | ret = 1; | 4619 | ret = 1; |
4621 | break; | 4620 | break; |
@@ -5154,24 +5153,24 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
5154 | if(reg & 0x80) v2 |= 0x80; | 5153 | if(reg & 0x80) v2 |= 0x80; |
5155 | v2 |= 0x01; | 5154 | v2 |= 0x01; |
5156 | 5155 | ||
5157 | if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) { | 5156 | if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) { |
5158 | SIS_PCI_PUT_DEVICE(mypdev); | 5157 | pci_dev_put(mypdev); |
5159 | if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4)) | 5158 | if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4)) |
5160 | v2 &= 0xf9; | 5159 | v2 &= 0xf9; |
5161 | v2 |= 0x08; | 5160 | v2 |= 0x08; |
5162 | v1 &= 0xfe; | 5161 | v1 &= 0xfe; |
5163 | } else { | 5162 | } else { |
5164 | mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL); | 5163 | mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL); |
5165 | if(!mypdev) | 5164 | if(!mypdev) |
5166 | mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL); | 5165 | mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL); |
5167 | if(!mypdev) | 5166 | if(!mypdev) |
5168 | mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL); | 5167 | mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL); |
5169 | if(mypdev) { | 5168 | if(mypdev) { |
5170 | pci_read_config_dword(mypdev, 0x94, ®d); | 5169 | pci_read_config_dword(mypdev, 0x94, ®d); |
5171 | regd &= 0xfffffeff; | 5170 | regd &= 0xfffffeff; |
5172 | pci_write_config_dword(mypdev, 0x94, regd); | 5171 | pci_write_config_dword(mypdev, 0x94, regd); |
5173 | v1 &= 0xfe; | 5172 | v1 &= 0xfe; |
5174 | SIS_PCI_PUT_DEVICE(mypdev); | 5173 | pci_dev_put(mypdev); |
5175 | } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) { | 5174 | } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) { |
5176 | v1 &= 0xfe; | 5175 | v1 &= 0xfe; |
5177 | } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) || | 5176 | } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) || |
@@ -5194,13 +5193,13 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
5194 | if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) | 5193 | if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) |
5195 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); | 5194 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); |
5196 | 5195 | ||
5197 | if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) { | 5196 | if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) { |
5198 | /* TODO: set CR5f &0xf1 | 0x01 for version 6570 | 5197 | /* TODO: set CR5f &0xf1 | 0x01 for version 6570 |
5199 | * of nforce 2 ROM | 5198 | * of nforce 2 ROM |
5200 | */ | 5199 | */ |
5201 | if(0) | 5200 | if(0) |
5202 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); | 5201 | setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); |
5203 | SIS_PCI_PUT_DEVICE(mypdev); | 5202 | pci_dev_put(mypdev); |
5204 | } | 5203 | } |
5205 | } | 5204 | } |
5206 | 5205 | ||
@@ -5236,9 +5235,9 @@ sisfb_post_xgi(struct pci_dev *pdev) | |||
5236 | setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); | 5235 | setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); |
5237 | setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); | 5236 | setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); |
5238 | v1 = bios[0x501]; | 5237 | v1 = bios[0x501]; |
5239 | if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) { | 5238 | if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) { |
5240 | v1 = 0xf0; | 5239 | v1 = 0xf0; |
5241 | SIS_PCI_PUT_DEVICE(mypdev); | 5240 | pci_dev_put(mypdev); |
5242 | } | 5241 | } |
5243 | outSISIDXREG(SISCR, 0x77, v1); | 5242 | outSISIDXREG(SISCR, 0x77, v1); |
5244 | } | 5243 | } |
@@ -5947,7 +5946,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5947 | 5946 | ||
5948 | if(!ivideo->sisvga_enabled) { | 5947 | if(!ivideo->sisvga_enabled) { |
5949 | if(pci_enable_device(pdev)) { | 5948 | if(pci_enable_device(pdev)) { |
5950 | if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge); | 5949 | if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); |
5951 | pci_set_drvdata(pdev, NULL); | 5950 | pci_set_drvdata(pdev, NULL); |
5952 | kfree(sis_fb_info); | 5951 | kfree(sis_fb_info); |
5953 | return -EIO; | 5952 | return -EIO; |
@@ -5974,7 +5973,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5974 | "requiring Chrontel/GPIO setup\n", | 5973 | "requiring Chrontel/GPIO setup\n", |
5975 | mychswtable[i].vendorName, | 5974 | mychswtable[i].vendorName, |
5976 | mychswtable[i].cardName); | 5975 | mychswtable[i].cardName); |
5977 | ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL); | 5976 | ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL); |
5978 | break; | 5977 | break; |
5979 | } | 5978 | } |
5980 | i++; | 5979 | i++; |
@@ -5984,7 +5983,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5984 | 5983 | ||
5985 | #ifdef CONFIG_FB_SIS_315 | 5984 | #ifdef CONFIG_FB_SIS_315 |
5986 | if((ivideo->chip == SIS_760) && (ivideo->nbridge)) { | 5985 | if((ivideo->chip == SIS_760) && (ivideo->nbridge)) { |
5987 | ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3)); | 5986 | ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3)); |
5988 | } | 5987 | } |
5989 | #endif | 5988 | #endif |
5990 | 5989 | ||
@@ -6149,9 +6148,9 @@ error_1: release_mem_region(ivideo->video_base, ivideo->video_size); | |||
6149 | error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); | 6148 | error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); |
6150 | error_3: vfree(ivideo->bios_abase); | 6149 | error_3: vfree(ivideo->bios_abase); |
6151 | if(ivideo->lpcdev) | 6150 | if(ivideo->lpcdev) |
6152 | SIS_PCI_PUT_DEVICE(ivideo->lpcdev); | 6151 | pci_dev_put(ivideo->lpcdev); |
6153 | if(ivideo->nbridge) | 6152 | if(ivideo->nbridge) |
6154 | SIS_PCI_PUT_DEVICE(ivideo->nbridge); | 6153 | pci_dev_put(ivideo->nbridge); |
6155 | pci_set_drvdata(pdev, NULL); | 6154 | pci_set_drvdata(pdev, NULL); |
6156 | if(!ivideo->sisvga_enabled) | 6155 | if(!ivideo->sisvga_enabled) |
6157 | pci_disable_device(pdev); | 6156 | pci_disable_device(pdev); |
@@ -6331,70 +6330,6 @@ error_3: vfree(ivideo->bios_abase); | |||
6331 | 6330 | ||
6332 | sisfb_set_vparms(ivideo); | 6331 | sisfb_set_vparms(ivideo); |
6333 | 6332 | ||
6334 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
6335 | |||
6336 | /* ---------------- For 2.4: Now switch the mode ------------------ */ | ||
6337 | |||
6338 | printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n", | ||
6339 | ivideo->video_width, ivideo->video_height, ivideo->video_bpp, | ||
6340 | ivideo->refresh_rate); | ||
6341 | |||
6342 | /* Determine whether or not acceleration is to be | ||
6343 | * used. Need to know before pre/post_set_mode() | ||
6344 | */ | ||
6345 | ivideo->accel = 0; | ||
6346 | ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT; | ||
6347 | if(ivideo->sisfb_accel) { | ||
6348 | ivideo->accel = -1; | ||
6349 | ivideo->default_var.accel_flags |= FB_ACCELF_TEXT; | ||
6350 | } | ||
6351 | |||
6352 | /* Now switch the mode */ | ||
6353 | sisfb_pre_setmode(ivideo); | ||
6354 | |||
6355 | if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) { | ||
6356 | printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n", | ||
6357 | ivideo->mode_no); | ||
6358 | ret = -EINVAL; | ||
6359 | iounmap(ivideo->mmio_vbase); | ||
6360 | goto error_0; | ||
6361 | } | ||
6362 | |||
6363 | outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); | ||
6364 | |||
6365 | sisfb_post_setmode(ivideo); | ||
6366 | |||
6367 | /* Maximize regardless of sisfb_max at startup */ | ||
6368 | ivideo->default_var.yres_virtual = 32767; | ||
6369 | |||
6370 | /* Force reset of x virtual in crtc_to_var */ | ||
6371 | ivideo->default_var.xres_virtual = 0; | ||
6372 | |||
6373 | /* Copy mode timing to var */ | ||
6374 | sisfb_crtc_to_var(ivideo, &ivideo->default_var); | ||
6375 | |||
6376 | /* Find out about screen pitch */ | ||
6377 | sisfb_calc_pitch(ivideo, &ivideo->default_var); | ||
6378 | sisfb_set_pitch(ivideo); | ||
6379 | |||
6380 | /* Init the accelerator (does nothing currently) */ | ||
6381 | sisfb_initaccel(ivideo); | ||
6382 | |||
6383 | /* Init some fbinfo entries */ | ||
6384 | sis_fb_info->node = -1; | ||
6385 | sis_fb_info->flags = FBINFO_FLAG_DEFAULT; | ||
6386 | sis_fb_info->fbops = &sisfb_ops; | ||
6387 | sis_fb_info->disp = &ivideo->sis_disp; | ||
6388 | sis_fb_info->blank = &sisfb_blank; | ||
6389 | sis_fb_info->switch_con = &sisfb_switch; | ||
6390 | sis_fb_info->updatevar = &sisfb_update_var; | ||
6391 | sis_fb_info->changevar = NULL; | ||
6392 | strcpy(sis_fb_info->fontname, sisfb_fontname); | ||
6393 | |||
6394 | sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info); | ||
6395 | |||
6396 | #else /* --------- For 2.6: Setup a somewhat sane default var ------------ */ | ||
6397 | |||
6398 | printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", | 6333 | printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", |
6399 | ivideo->video_width, ivideo->video_height, ivideo->video_bpp, | 6334 | ivideo->video_width, ivideo->video_height, ivideo->video_bpp, |
6400 | ivideo->refresh_rate); | 6335 | ivideo->refresh_rate); |
@@ -6454,7 +6389,6 @@ error_3: vfree(ivideo->bios_abase); | |||
6454 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; | 6389 | sis_fb_info->pseudo_palette = ivideo->pseudo_palette; |
6455 | 6390 | ||
6456 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); | 6391 | fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); |
6457 | #endif /* 2.6 */ | ||
6458 | 6392 | ||
6459 | printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); | 6393 | printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); |
6460 | 6394 | ||
@@ -6564,10 +6498,10 @@ static void __devexit sisfb_remove(struct pci_dev *pdev) | |||
6564 | vfree(ivideo->bios_abase); | 6498 | vfree(ivideo->bios_abase); |
6565 | 6499 | ||
6566 | if(ivideo->lpcdev) | 6500 | if(ivideo->lpcdev) |
6567 | SIS_PCI_PUT_DEVICE(ivideo->lpcdev); | 6501 | pci_dev_put(ivideo->lpcdev); |
6568 | 6502 | ||
6569 | if(ivideo->nbridge) | 6503 | if(ivideo->nbridge) |
6570 | SIS_PCI_PUT_DEVICE(ivideo->nbridge); | 6504 | pci_dev_put(ivideo->nbridge); |
6571 | 6505 | ||
6572 | #ifdef CONFIG_MTRR | 6506 | #ifdef CONFIG_MTRR |
6573 | /* Release MTRR region */ | 6507 | /* Release MTRR region */ |
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index bb96cb65fdaa..842b5cd054c6 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/delay.h> | 51 | #include <linux/delay.h> |
52 | #include <linux/fb.h> | 52 | #include <linux/fb.h> |
53 | #include <linux/init.h> | 53 | #include <linux/init.h> |
54 | #include <linux/pci.h> | ||
54 | 55 | ||
55 | /* | 56 | /* |
56 | * This is just simple sample code. | 57 | * This is just simple sample code. |
@@ -60,6 +61,11 @@ | |||
60 | */ | 61 | */ |
61 | 62 | ||
62 | /* | 63 | /* |
64 | * Driver data | ||
65 | */ | ||
66 | static char *mode_option __devinitdata; | ||
67 | |||
68 | /* | ||
63 | * If your driver supports multiple boards, you should make the | 69 | * If your driver supports multiple boards, you should make the |
64 | * below data types arrays, or allocate them dynamically (using kmalloc()). | 70 | * below data types arrays, or allocate them dynamically (using kmalloc()). |
65 | */ | 71 | */ |
@@ -78,7 +84,7 @@ struct xxx_par; | |||
78 | * if we don't use modedb. If we do use modedb see xxxfb_init how to use it | 84 | * if we don't use modedb. If we do use modedb see xxxfb_init how to use it |
79 | * to get a fb_var_screeninfo. Otherwise define a default var as well. | 85 | * to get a fb_var_screeninfo. Otherwise define a default var as well. |
80 | */ | 86 | */ |
81 | static struct fb_fix_screeninfo xxxfb_fix __initdata = { | 87 | static struct fb_fix_screeninfo xxxfb_fix __devinitdata = { |
82 | .id = "FB's name", | 88 | .id = "FB's name", |
83 | .type = FB_TYPE_PACKED_PIXELS, | 89 | .type = FB_TYPE_PACKED_PIXELS, |
84 | .visual = FB_VISUAL_PSEUDOCOLOR, | 90 | .visual = FB_VISUAL_PSEUDOCOLOR, |
@@ -142,7 +148,7 @@ int xxxfb_setup(char*); | |||
142 | * | 148 | * |
143 | * Returns negative errno on error, or zero on success. | 149 | * Returns negative errno on error, or zero on success. |
144 | */ | 150 | */ |
145 | static int xxxfb_open(const struct fb_info *info, int user) | 151 | static int xxxfb_open(struct fb_info *info, int user) |
146 | { | 152 | { |
147 | return 0; | 153 | return 0; |
148 | } | 154 | } |
@@ -161,7 +167,7 @@ static int xxxfb_open(const struct fb_info *info, int user) | |||
161 | * | 167 | * |
162 | * Returns negative errno on error, or zero on success. | 168 | * Returns negative errno on error, or zero on success. |
163 | */ | 169 | */ |
164 | static int xxxfb_release(const struct fb_info *info, int user) | 170 | static int xxxfb_release(struct fb_info *info, int user) |
165 | { | 171 | { |
166 | return 0; | 172 | return 0; |
167 | } | 173 | } |
@@ -278,7 +284,7 @@ static int xxxfb_set_par(struct fb_info *info) | |||
278 | */ | 284 | */ |
279 | static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | 285 | static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, |
280 | unsigned blue, unsigned transp, | 286 | unsigned blue, unsigned transp, |
281 | const struct fb_info *info) | 287 | struct fb_info *info) |
282 | { | 288 | { |
283 | if (regno >= 256) /* no. of hw registers */ | 289 | if (regno >= 256) /* no. of hw registers */ |
284 | return -EINVAL; | 290 | return -EINVAL; |
@@ -416,7 +422,7 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
416 | * Returns negative errno on error, or zero on success. | 422 | * Returns negative errno on error, or zero on success. |
417 | */ | 423 | */ |
418 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, | 424 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, |
419 | const struct fb_info *info) | 425 | struct fb_info *info) |
420 | { | 426 | { |
421 | /* | 427 | /* |
422 | * If your hardware does not support panning, _do_ _not_ implement this | 428 | * If your hardware does not support panning, _do_ _not_ implement this |
@@ -454,7 +460,7 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var, | |||
454 | * Return !0 for any modes that are unimplemented. | 460 | * Return !0 for any modes that are unimplemented. |
455 | * | 461 | * |
456 | */ | 462 | */ |
457 | static int xxxfb_blank(int blank_mode, const struct fb_info *info) | 463 | static int xxxfb_blank(int blank_mode, struct fb_info *info) |
458 | { | 464 | { |
459 | /* ... */ | 465 | /* ... */ |
460 | return 0; | 466 | return 0; |
@@ -483,7 +489,7 @@ static int xxxfb_blank(int blank_mode, const struct fb_info *info) | |||
483 | * depending on the rastering operation with the value of color which | 489 | * depending on the rastering operation with the value of color which |
484 | * is in the current color depth format. | 490 | * is in the current color depth format. |
485 | */ | 491 | */ |
486 | void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) | 492 | void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) |
487 | { | 493 | { |
488 | /* Meaning of struct fb_fillrect | 494 | /* Meaning of struct fb_fillrect |
489 | * | 495 | * |
@@ -623,19 +629,6 @@ void xxxfb_rotate(struct fb_info *info, int angle) | |||
623 | } | 629 | } |
624 | 630 | ||
625 | /** | 631 | /** |
626 | * xxxfb_poll - NOT a required function. The purpose of this | ||
627 | * function is to provide a way for some process | ||
628 | * to wait until a specific hardware event occurs | ||
629 | * for the framebuffer device. | ||
630 | * | ||
631 | * @info: frame buffer structure that represents a single frame buffer | ||
632 | * @wait: poll table where we store process that await a event. | ||
633 | */ | ||
634 | void xxxfb_poll(struct fb_info *info, poll_table *wait) | ||
635 | { | ||
636 | } | ||
637 | |||
638 | /** | ||
639 | * xxxfb_sync - NOT a required function. Normally the accel engine | 632 | * xxxfb_sync - NOT a required function. Normally the accel engine |
640 | * for a graphics card take a specific amount of time. | 633 | * for a graphics card take a specific amount of time. |
641 | * Often we have to wait for the accelerator to finish | 634 | * Often we have to wait for the accelerator to finish |
@@ -647,21 +640,49 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait) | |||
647 | * If the driver has implemented its own hardware-based drawing function, | 640 | * If the driver has implemented its own hardware-based drawing function, |
648 | * implementing this function is highly recommended. | 641 | * implementing this function is highly recommended. |
649 | */ | 642 | */ |
650 | void xxxfb_sync(struct fb_info *info) | 643 | int xxxfb_sync(struct fb_info *info) |
651 | { | 644 | { |
645 | return 0; | ||
652 | } | 646 | } |
653 | 647 | ||
654 | /* | 648 | /* |
649 | * Frame buffer operations | ||
650 | */ | ||
651 | |||
652 | static struct fb_ops xxxfb_ops = { | ||
653 | .owner = THIS_MODULE, | ||
654 | .fb_open = xxxfb_open, | ||
655 | .fb_read = xxxfb_read, | ||
656 | .fb_write = xxxfb_write, | ||
657 | .fb_release = xxxfb_release, | ||
658 | .fb_check_var = xxxfb_check_var, | ||
659 | .fb_set_par = xxxfb_set_par, | ||
660 | .fb_setcolreg = xxxfb_setcolreg, | ||
661 | .fb_blank = xxxfb_blank, | ||
662 | .fb_pan_display = xxxfb_pan_display, | ||
663 | .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ | ||
664 | .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ | ||
665 | .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ | ||
666 | .fb_cursor = xxxfb_cursor, /* Optional !!! */ | ||
667 | .fb_rotate = xxxfb_rotate, | ||
668 | .fb_sync = xxxfb_sync, | ||
669 | .fb_ioctl = xxxfb_ioctl, | ||
670 | .fb_mmap = xxxfb_mmap, | ||
671 | }; | ||
672 | |||
673 | /* ------------------------------------------------------------------------- */ | ||
674 | |||
675 | /* | ||
655 | * Initialization | 676 | * Initialization |
656 | */ | 677 | */ |
657 | 678 | ||
658 | /* static int __init xxfb_probe (struct device *device) -- for platform devs */ | 679 | /* static int __init xxfb_probe (struct device *device) -- for platform devs */ |
659 | static int __init xxxfb_probe(struct pci_dev *dev, | 680 | static int __devinit xxxfb_probe(struct pci_dev *dev, |
660 | const_struct pci_device_id *ent) | 681 | const struct pci_device_id *ent) |
661 | { | 682 | { |
662 | struct fb_info *info; | 683 | struct fb_info *info; |
663 | struct xxx_par *par; | 684 | struct xxx_par *par; |
664 | struct device = &dev->dev; /* for pci drivers */ | 685 | struct device* device = &dev->dev; /* for pci drivers */ |
665 | int cmap_len, retval; | 686 | int cmap_len, retval; |
666 | 687 | ||
667 | /* | 688 | /* |
@@ -684,7 +705,7 @@ static int __init xxxfb_probe(struct pci_dev *dev, | |||
684 | info->screen_base = framebuffer_virtual_memory; | 705 | info->screen_base = framebuffer_virtual_memory; |
685 | info->fbops = &xxxfb_ops; | 706 | info->fbops = &xxxfb_ops; |
686 | info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be | 707 | info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be |
687 | * used, so mark it as __initdata | 708 | * used, so mark it as __devinitdata |
688 | */ | 709 | */ |
689 | info->pseudo_palette = pseudo_palette; /* The pseudopalette is an | 710 | info->pseudo_palette = pseudo_palette; /* The pseudopalette is an |
690 | * 16-member array | 711 | * 16-member array |
@@ -760,7 +781,7 @@ static int __init xxxfb_probe(struct pci_dev *dev, | |||
760 | * | 781 | * |
761 | * NOTE: This field is currently unused. | 782 | * NOTE: This field is currently unused. |
762 | */ | 783 | */ |
763 | info->pixmap.scan_align = 32 | 784 | info->pixmap.scan_align = 32; |
764 | /***************************** End optional stage ***************************/ | 785 | /***************************** End optional stage ***************************/ |
765 | 786 | ||
766 | /* | 787 | /* |
@@ -770,13 +791,13 @@ static int __init xxxfb_probe(struct pci_dev *dev, | |||
770 | if (!mode_option) | 791 | if (!mode_option) |
771 | mode_option = "640x480@60"; | 792 | mode_option = "640x480@60"; |
772 | 793 | ||
773 | retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8); | 794 | retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); |
774 | 795 | ||
775 | if (!retval || retval == 4) | 796 | if (!retval || retval == 4) |
776 | return -EINVAL; | 797 | return -EINVAL; |
777 | 798 | ||
778 | /* This has to been done !!! */ | 799 | /* This has to been done !!! */ |
779 | fb_alloc_cmap(info->cmap, cmap_len, 0); | 800 | fb_alloc_cmap(&info->cmap, cmap_len, 0); |
780 | 801 | ||
781 | /* | 802 | /* |
782 | * The following is done in the case of having hardware with a static | 803 | * The following is done in the case of having hardware with a static |
@@ -811,34 +832,77 @@ static int __init xxxfb_probe(struct pci_dev *dev, | |||
811 | /* | 832 | /* |
812 | * Cleanup | 833 | * Cleanup |
813 | */ | 834 | */ |
814 | /* static void __exit xxxfb_remove(struct device *device) */ | 835 | /* static void __devexit xxxfb_remove(struct device *device) */ |
815 | static void __exit xxxfb_remove(struct pci_dev *dev) | 836 | static void __devexit xxxfb_remove(struct pci_dev *dev) |
816 | { | 837 | { |
817 | struct fb_info *info = pci_get_drv_data(dev); | 838 | struct fb_info *info = pci_get_drvdata(dev); |
818 | /* or dev_get_drv_data(device); */ | 839 | /* or dev_get_drvdata(device); */ |
819 | 840 | ||
820 | if (info) { | 841 | if (info) { |
821 | unregister_framebuffer(info); | 842 | unregister_framebuffer(info); |
822 | fb_dealloc_cmap(&info.cmap); | 843 | fb_dealloc_cmap(&info->cmap); |
823 | /* ... */ | 844 | /* ... */ |
824 | framebuffer_release(info); | 845 | framebuffer_release(info); |
825 | } | 846 | } |
847 | } | ||
848 | |||
849 | #ifdef CONFIG_PCI | ||
850 | #ifdef CONFIG_PM | ||
851 | /** | ||
852 | * xxxfb_suspend - Optional but recommended function. Suspend the device. | ||
853 | * @dev: PCI device | ||
854 | * @msg: the suspend event code. | ||
855 | * | ||
856 | * See Documentation/power/devices.txt for more information | ||
857 | */ | ||
858 | static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg) | ||
859 | { | ||
860 | struct fb_info *info = pci_get_drvdata(dev); | ||
861 | struct xxxfb_par *par = info->par; | ||
862 | |||
863 | /* suspend here */ | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | /** | ||
868 | * xxxfb_resume - Optional but recommended function. Resume the device. | ||
869 | * @dev: PCI device | ||
870 | * | ||
871 | * See Documentation/power/devices.txt for more information | ||
872 | */ | ||
873 | static int xxxfb_resume(struct pci_dev *dev) | ||
874 | { | ||
875 | struct fb_info *info = pci_get_drvdata(dev); | ||
876 | struct xxxfb_par *par = info->par; | ||
826 | 877 | ||
878 | /* resume here */ | ||
827 | return 0; | 879 | return 0; |
828 | } | 880 | } |
881 | #else | ||
882 | #define xxxfb_suspend NULL | ||
883 | #define xxxfb_resume NULL | ||
884 | #endif /* CONFIG_PM */ | ||
885 | |||
886 | static struct pci_device_id xxxfb_id_table[] = { | ||
887 | { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX, | ||
888 | PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, | ||
889 | PCI_CLASS_MASK, 0 }, | ||
890 | { 0, } | ||
891 | }; | ||
829 | 892 | ||
830 | #if CONFIG_PCI | ||
831 | /* For PCI drivers */ | 893 | /* For PCI drivers */ |
832 | static struct pci_driver xxxfb_driver = { | 894 | static struct pci_driver xxxfb_driver = { |
833 | .name = "xxxfb", | 895 | .name = "xxxfb", |
834 | .id_table = xxxfb_devices, | 896 | .id_table = xxxfb_id_table, |
835 | .probe = xxxfb_probe, | 897 | .probe = xxxfb_probe, |
836 | .remove = __devexit_p(xxxfb_remove), | 898 | .remove = __devexit_p(xxxfb_remove), |
837 | .suspend = xxxfb_suspend, /* optional */ | 899 | .suspend = xxxfb_suspend, /* optional but recommended */ |
838 | .resume = xxxfb_resume, /* optional */ | 900 | .resume = xxxfb_resume, /* optional but recommended */ |
839 | }; | 901 | }; |
840 | 902 | ||
841 | static int __init xxxfb_init(void) | 903 | MODULE_DEVICE_TABLE(pci, xxxfb_id_table); |
904 | |||
905 | int __init xxxfb_init(void) | ||
842 | { | 906 | { |
843 | /* | 907 | /* |
844 | * For kernel boot options (in 'video=xxxfb:<options>' format) | 908 | * For kernel boot options (in 'video=xxxfb:<options>' format) |
@@ -858,16 +922,53 @@ static void __exit xxxfb_exit(void) | |||
858 | { | 922 | { |
859 | pci_unregister_driver(&xxxfb_driver); | 923 | pci_unregister_driver(&xxxfb_driver); |
860 | } | 924 | } |
861 | #else | 925 | #else /* non PCI, platform drivers */ |
862 | #include <linux/platform_device.h> | 926 | #include <linux/platform_device.h> |
863 | /* for platform devices */ | 927 | /* for platform devices */ |
928 | |||
929 | #ifdef CONFIG_PM | ||
930 | /** | ||
931 | * xxxfb_suspend - Optional but recommended function. Suspend the device. | ||
932 | * @dev: platform device | ||
933 | * @msg: the suspend event code. | ||
934 | * | ||
935 | * See Documentation/power/devices.txt for more information | ||
936 | */ | ||
937 | static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg) | ||
938 | { | ||
939 | struct fb_info *info = platform_get_drvdata(dev); | ||
940 | struct xxxfb_par *par = info->par; | ||
941 | |||
942 | /* suspend here */ | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | /** | ||
947 | * xxxfb_resume - Optional but recommended function. Resume the device. | ||
948 | * @dev: platform device | ||
949 | * | ||
950 | * See Documentation/power/devices.txt for more information | ||
951 | */ | ||
952 | static int xxxfb_resume(struct platform_dev *dev) | ||
953 | { | ||
954 | struct fb_info *info = platform_get_drvdata(dev); | ||
955 | struct xxxfb_par *par = info->par; | ||
956 | |||
957 | /* resume here */ | ||
958 | return 0; | ||
959 | } | ||
960 | #else | ||
961 | #define xxxfb_suspend NULL | ||
962 | #define xxxfb_resume NULL | ||
963 | #endif /* CONFIG_PM */ | ||
964 | |||
864 | static struct device_driver xxxfb_driver = { | 965 | static struct device_driver xxxfb_driver = { |
865 | .name = "xxxfb", | 966 | .name = "xxxfb", |
866 | .bus = &platform_bus_type, | 967 | .bus = &platform_bus_type, |
867 | .probe = xxxfb_probe, | 968 | .probe = xxxfb_probe, |
868 | .remove = xxxfb_remove, | 969 | .remove = xxxfb_remove, |
869 | .suspend = xxxfb_suspend, /* optional */ | 970 | .suspend = xxxfb_suspend, /* optional but recommended */ |
870 | .resume = xxxfb_resume, /* optional */ | 971 | .resume = xxxfb_resume, /* optional but recommended */ |
871 | }; | 972 | }; |
872 | 973 | ||
873 | static struct platform_device xxxfb_device = { | 974 | static struct platform_device xxxfb_device = { |
@@ -903,8 +1004,9 @@ static void __exit xxxfb_exit(void) | |||
903 | platform_device_unregister(&xxxfb_device); | 1004 | platform_device_unregister(&xxxfb_device); |
904 | driver_unregister(&xxxfb_driver); | 1005 | driver_unregister(&xxxfb_driver); |
905 | } | 1006 | } |
906 | #endif | 1007 | #endif /* CONFIG_PCI */ |
907 | 1008 | ||
1009 | #ifdef MODULE | ||
908 | /* | 1010 | /* |
909 | * Setup | 1011 | * Setup |
910 | */ | 1012 | */ |
@@ -917,34 +1019,7 @@ int __init xxxfb_setup(char *options) | |||
917 | { | 1019 | { |
918 | /* Parse user speficied options (`video=xxxfb:') */ | 1020 | /* Parse user speficied options (`video=xxxfb:') */ |
919 | } | 1021 | } |
920 | 1022 | #endif /* MODULE */ | |
921 | /* ------------------------------------------------------------------------- */ | ||
922 | |||
923 | /* | ||
924 | * Frame buffer operations | ||
925 | */ | ||
926 | |||
927 | static struct fb_ops xxxfb_ops = { | ||
928 | .owner = THIS_MODULE, | ||
929 | .fb_open = xxxfb_open, | ||
930 | .fb_read = xxxfb_read, | ||
931 | .fb_write = xxxfb_write, | ||
932 | .fb_release = xxxfb_release, | ||
933 | .fb_check_var = xxxfb_check_var, | ||
934 | .fb_set_par = xxxfb_set_par, | ||
935 | .fb_setcolreg = xxxfb_setcolreg, | ||
936 | .fb_blank = xxxfb_blank, | ||
937 | .fb_pan_display = xxxfb_pan_display, | ||
938 | .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ | ||
939 | .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ | ||
940 | .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ | ||
941 | .fb_cursor = xxxfb_cursor, /* Optional !!! */ | ||
942 | .fb_rotate = xxxfb_rotate, | ||
943 | .fb_poll = xxxfb_poll, | ||
944 | .fb_sync = xxxfb_sync, | ||
945 | .fb_ioctl = xxxfb_ioctl, | ||
946 | .fb_mmap = xxxfb_mmap, | ||
947 | }; | ||
948 | 1023 | ||
949 | /* ------------------------------------------------------------------------- */ | 1024 | /* ------------------------------------------------------------------------- */ |
950 | 1025 | ||
@@ -954,6 +1029,6 @@ static struct fb_ops xxxfb_ops = { | |||
954 | */ | 1029 | */ |
955 | 1030 | ||
956 | module_init(xxxfb_init); | 1031 | module_init(xxxfb_init); |
957 | module_exit(xxxfb_cleanup); | 1032 | module_exit(xxxfb_remove); |
958 | 1033 | ||
959 | MODULE_LICENSE("GPL"); | 1034 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 0a44c44672c8..c86df126f93a 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -989,7 +989,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
989 | ((info->cmap.green[fg_col] & 0xFC) << 3) | | 989 | ((info->cmap.green[fg_col] & 0xFC) << 3) | |
990 | ((info->cmap.blue[fg_col] & 0xF8) >> 3); | 990 | ((info->cmap.blue[fg_col] & 0xF8) >> 3); |
991 | 991 | ||
992 | dev_dbg(fbi->dev, "fgcol %08x, bgcol %08x\n", fg, bg); | 992 | dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg); |
993 | 993 | ||
994 | writel(bg, base + SM501_OFF_HWC_COLOR_1_2); | 994 | writel(bg, base + SM501_OFF_HWC_COLOR_1_2); |
995 | writel(fg, base + SM501_OFF_HWC_COLOR_3); | 995 | writel(fg, base + SM501_OFF_HWC_COLOR_3); |
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c index 68b30d9eac58..079cdc911e48 100644 --- a/drivers/video/svgalib.c +++ b/drivers/video/svgalib.c | |||
@@ -194,7 +194,7 @@ void svga_dump_var(struct fb_var_screeninfo *var, int node) | |||
194 | void svga_settile(struct fb_info *info, struct fb_tilemap *map) | 194 | void svga_settile(struct fb_info *info, struct fb_tilemap *map) |
195 | { | 195 | { |
196 | const u8 *font = map->data; | 196 | const u8 *font = map->data; |
197 | u8* fb = (u8 *) info->screen_base; | 197 | u8 __iomem *fb = (u8 __iomem *)info->screen_base; |
198 | int i, c; | 198 | int i, c; |
199 | 199 | ||
200 | if ((map->width != 8) || (map->height != 16) || | 200 | if ((map->width != 8) || (map->height != 16) || |
@@ -207,7 +207,8 @@ void svga_settile(struct fb_info *info, struct fb_tilemap *map) | |||
207 | fb += 2; | 207 | fb += 2; |
208 | for (c = 0; c < map->length; c++) { | 208 | for (c = 0; c < map->length; c++) { |
209 | for (i = 0; i < map->height; i++) { | 209 | for (i = 0; i < map->height; i++) { |
210 | fb[i * 4] = font[i]; | 210 | fb_writeb(font[i], fb + i * 4); |
211 | // fb[i * 4] = font[i]; | ||
211 | } | 212 | } |
212 | fb += 128; | 213 | fb += 128; |
213 | font += map->height; | 214 | font += map->height; |
@@ -221,8 +222,8 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area) | |||
221 | /* colstride is halved in this function because u16 are used */ | 222 | /* colstride is halved in this function because u16 are used */ |
222 | int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); | 223 | int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); |
223 | int rowstride = colstride * (info->var.xres_virtual / 8); | 224 | int rowstride = colstride * (info->var.xres_virtual / 8); |
224 | u16 *fb = (u16 *) info->screen_base; | 225 | u16 __iomem *fb = (u16 __iomem *) info->screen_base; |
225 | u16 *src, *dst; | 226 | u16 __iomem *src, *dst; |
226 | 227 | ||
227 | if ((area->sy > area->dy) || | 228 | if ((area->sy > area->dy) || |
228 | ((area->sy == area->dy) && (area->sx > area->dx))) { | 229 | ((area->sy == area->dy) && (area->sx > area->dx))) { |
@@ -239,10 +240,11 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area) | |||
239 | } | 240 | } |
240 | 241 | ||
241 | for (dy = 0; dy < area->height; dy++) { | 242 | for (dy = 0; dy < area->height; dy++) { |
242 | u16* src2 = src; | 243 | u16 __iomem *src2 = src; |
243 | u16* dst2 = dst; | 244 | u16 __iomem *dst2 = dst; |
244 | for (dx = 0; dx < area->width; dx++) { | 245 | for (dx = 0; dx < area->width; dx++) { |
245 | *dst2 = *src2; | 246 | fb_writew(fb_readw(src2), dst2); |
247 | // *dst2 = *src2; | ||
246 | src2 += colstride; | 248 | src2 += colstride; |
247 | dst2 += colstride; | 249 | dst2 += colstride; |
248 | } | 250 | } |
@@ -258,14 +260,14 @@ void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect) | |||
258 | int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); | 260 | int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); |
259 | int rowstride = colstride * (info->var.xres_virtual / 8); | 261 | int rowstride = colstride * (info->var.xres_virtual / 8); |
260 | int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg); | 262 | int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg); |
261 | u8 *fb = (u8 *) info->screen_base; | 263 | u8 __iomem *fb = (u8 __iomem *)info->screen_base; |
262 | fb += rect->sx * colstride + rect->sy * rowstride; | 264 | fb += rect->sx * colstride + rect->sy * rowstride; |
263 | 265 | ||
264 | for (dy = 0; dy < rect->height; dy++) { | 266 | for (dy = 0; dy < rect->height; dy++) { |
265 | u8* fb2 = fb; | 267 | u8 __iomem *fb2 = fb; |
266 | for (dx = 0; dx < rect->width; dx++) { | 268 | for (dx = 0; dx < rect->width; dx++) { |
267 | fb2[0] = rect->index; | 269 | fb_writeb(rect->index, fb2); |
268 | fb2[1] = attr; | 270 | fb_writeb(attr, fb2 + 1); |
269 | fb2 += colstride; | 271 | fb2 += colstride; |
270 | } | 272 | } |
271 | fb += rowstride; | 273 | fb += rowstride; |
@@ -279,15 +281,15 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit) | |||
279 | int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); | 281 | int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); |
280 | int rowstride = colstride * (info->var.xres_virtual / 8); | 282 | int rowstride = colstride * (info->var.xres_virtual / 8); |
281 | int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg); | 283 | int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg); |
282 | u8* fb = (u8 *) info->screen_base; | 284 | u8 __iomem *fb = (u8 __iomem *)info->screen_base; |
283 | fb += blit->sx * colstride + blit->sy * rowstride; | 285 | fb += blit->sx * colstride + blit->sy * rowstride; |
284 | 286 | ||
285 | i=0; | 287 | i=0; |
286 | for (dy=0; dy < blit->height; dy ++) { | 288 | for (dy=0; dy < blit->height; dy ++) { |
287 | u8* fb2 = fb; | 289 | u8 __iomem *fb2 = fb; |
288 | for (dx = 0; dx < blit->width; dx ++) { | 290 | for (dx = 0; dx < blit->width; dx ++) { |
289 | fb2[0] = blit->indices[i]; | 291 | fb_writeb(blit->indices[i], fb2); |
290 | fb2[1] = attr; | 292 | fb_writeb(attr, fb2 + 1); |
291 | fb2 += colstride; | 293 | fb2 += colstride; |
292 | i ++; | 294 | i ++; |
293 | if (i == blit->length) return; | 295 | if (i == blit->length) return; |
@@ -340,6 +342,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor) | |||
340 | vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ | 342 | vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ |
341 | } | 343 | } |
342 | 344 | ||
345 | int svga_get_tilemax(struct fb_info *info) | ||
346 | { | ||
347 | return 256; | ||
348 | } | ||
349 | |||
343 | 350 | ||
344 | /* ------------------------------------------------------------------------- */ | 351 | /* ------------------------------------------------------------------------- */ |
345 | 352 | ||
@@ -621,6 +628,7 @@ EXPORT_SYMBOL(svga_tilecopy); | |||
621 | EXPORT_SYMBOL(svga_tilefill); | 628 | EXPORT_SYMBOL(svga_tilefill); |
622 | EXPORT_SYMBOL(svga_tileblit); | 629 | EXPORT_SYMBOL(svga_tileblit); |
623 | EXPORT_SYMBOL(svga_tilecursor); | 630 | EXPORT_SYMBOL(svga_tilecursor); |
631 | EXPORT_SYMBOL(svga_get_tilemax); | ||
624 | 632 | ||
625 | EXPORT_SYMBOL(svga_compute_pll); | 633 | EXPORT_SYMBOL(svga_compute_pll); |
626 | EXPORT_SYMBOL(svga_check_timings); | 634 | EXPORT_SYMBOL(svga_check_timings); |
diff --git a/drivers/video/syscopyarea.c b/drivers/video/syscopyarea.c new file mode 100644 index 000000000000..37af10ab8f52 --- /dev/null +++ b/drivers/video/syscopyarea.c | |||
@@ -0,0 +1,378 @@ | |||
1 | /* | ||
2 | * Generic Bit Block Transfer for frame buffers located in system RAM with | ||
3 | * packed pixels of any depth. | ||
4 | * | ||
5 | * Based almost entirely from cfbcopyarea.c (which is based almost entirely | ||
6 | * on Geert Uytterhoeven's copyarea routine) | ||
7 | * | ||
8 | * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net> | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/fb.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <asm/types.h> | ||
21 | #include <asm/io.h> | ||
22 | #include "fb_draw.h" | ||
23 | |||
24 | /* | ||
25 | * Generic bitwise copy algorithm | ||
26 | */ | ||
27 | |||
28 | static void | ||
29 | bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src, | ||
30 | int src_idx, int bits, unsigned n) | ||
31 | { | ||
32 | unsigned long first, last; | ||
33 | int const shift = dst_idx-src_idx; | ||
34 | int left, right; | ||
35 | |||
36 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | ||
37 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | ||
38 | |||
39 | if (!shift) { | ||
40 | /* Same alignment for source and dest */ | ||
41 | if (dst_idx+n <= bits) { | ||
42 | /* Single word */ | ||
43 | if (last) | ||
44 | first &= last; | ||
45 | *dst = comp(*src, *dst, first); | ||
46 | } else { | ||
47 | /* Multiple destination words */ | ||
48 | /* Leading bits */ | ||
49 | if (first != ~0UL) { | ||
50 | *dst = comp(*src, *dst, first); | ||
51 | dst++; | ||
52 | src++; | ||
53 | n -= bits - dst_idx; | ||
54 | } | ||
55 | |||
56 | /* Main chunk */ | ||
57 | n /= bits; | ||
58 | while (n >= 8) { | ||
59 | *dst++ = *src++; | ||
60 | *dst++ = *src++; | ||
61 | *dst++ = *src++; | ||
62 | *dst++ = *src++; | ||
63 | *dst++ = *src++; | ||
64 | *dst++ = *src++; | ||
65 | *dst++ = *src++; | ||
66 | *dst++ = *src++; | ||
67 | n -= 8; | ||
68 | } | ||
69 | while (n--) | ||
70 | *dst++ = *src++; | ||
71 | |||
72 | /* Trailing bits */ | ||
73 | if (last) | ||
74 | *dst = comp(*src, *dst, last); | ||
75 | } | ||
76 | } else { | ||
77 | unsigned long d0, d1; | ||
78 | int m; | ||
79 | |||
80 | /* Different alignment for source and dest */ | ||
81 | right = shift & (bits - 1); | ||
82 | left = -shift & (bits - 1); | ||
83 | |||
84 | if (dst_idx+n <= bits) { | ||
85 | /* Single destination word */ | ||
86 | if (last) | ||
87 | first &= last; | ||
88 | if (shift > 0) { | ||
89 | /* Single source word */ | ||
90 | *dst = comp(*src >> right, *dst, first); | ||
91 | } else if (src_idx+n <= bits) { | ||
92 | /* Single source word */ | ||
93 | *dst = comp(*src << left, *dst, first); | ||
94 | } else { | ||
95 | /* 2 source words */ | ||
96 | d0 = *src++; | ||
97 | d1 = *src; | ||
98 | *dst = comp(d0 << left | d1 >> right, *dst, | ||
99 | first); | ||
100 | } | ||
101 | } else { | ||
102 | /* Multiple destination words */ | ||
103 | /** We must always remember the last value read, | ||
104 | because in case SRC and DST overlap bitwise (e.g. | ||
105 | when moving just one pixel in 1bpp), we always | ||
106 | collect one full long for DST and that might | ||
107 | overlap with the current long from SRC. We store | ||
108 | this value in 'd0'. */ | ||
109 | d0 = *src++; | ||
110 | /* Leading bits */ | ||
111 | if (shift > 0) { | ||
112 | /* Single source word */ | ||
113 | *dst = comp(d0 >> right, *dst, first); | ||
114 | dst++; | ||
115 | n -= bits - dst_idx; | ||
116 | } else { | ||
117 | /* 2 source words */ | ||
118 | d1 = *src++; | ||
119 | *dst = comp(d0 << left | *dst >> right, *dst, first); | ||
120 | d0 = d1; | ||
121 | dst++; | ||
122 | n -= bits - dst_idx; | ||
123 | } | ||
124 | |||
125 | /* Main chunk */ | ||
126 | m = n % bits; | ||
127 | n /= bits; | ||
128 | while (n >= 4) { | ||
129 | d1 = *src++; | ||
130 | *dst++ = d0 << left | d1 >> right; | ||
131 | d0 = d1; | ||
132 | d1 = *src++; | ||
133 | *dst++ = d0 << left | d1 >> right; | ||
134 | d0 = d1; | ||
135 | d1 = *src++; | ||
136 | *dst++ = d0 << left | d1 >> right; | ||
137 | d0 = d1; | ||
138 | d1 = *src++; | ||
139 | *dst++ = d0 << left | d1 >> right; | ||
140 | d0 = d1; | ||
141 | n -= 4; | ||
142 | } | ||
143 | while (n--) { | ||
144 | d1 = *src++; | ||
145 | *dst++ = d0 << left | d1 >> right; | ||
146 | d0 = d1; | ||
147 | } | ||
148 | |||
149 | /* Trailing bits */ | ||
150 | if (last) { | ||
151 | if (m <= right) { | ||
152 | /* Single source word */ | ||
153 | *dst = comp(d0 << left, *dst, last); | ||
154 | } else { | ||
155 | /* 2 source words */ | ||
156 | d1 = *src; | ||
157 | *dst = comp(d0 << left | d1 >> right, | ||
158 | *dst, last); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Generic bitwise copy algorithm, operating backward | ||
167 | */ | ||
168 | |||
169 | static void | ||
170 | bitcpy_rev(unsigned long *dst, int dst_idx, const unsigned long *src, | ||
171 | int src_idx, int bits, unsigned n) | ||
172 | { | ||
173 | unsigned long first, last; | ||
174 | int shift; | ||
175 | |||
176 | dst += (n-1)/bits; | ||
177 | src += (n-1)/bits; | ||
178 | if ((n-1) % bits) { | ||
179 | dst_idx += (n-1) % bits; | ||
180 | dst += dst_idx >> (ffs(bits) - 1); | ||
181 | dst_idx &= bits - 1; | ||
182 | src_idx += (n-1) % bits; | ||
183 | src += src_idx >> (ffs(bits) - 1); | ||
184 | src_idx &= bits - 1; | ||
185 | } | ||
186 | |||
187 | shift = dst_idx-src_idx; | ||
188 | |||
189 | first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx); | ||
190 | last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits))); | ||
191 | |||
192 | if (!shift) { | ||
193 | /* Same alignment for source and dest */ | ||
194 | if ((unsigned long)dst_idx+1 >= n) { | ||
195 | /* Single word */ | ||
196 | if (last) | ||
197 | first &= last; | ||
198 | *dst = comp(*src, *dst, first); | ||
199 | } else { | ||
200 | /* Multiple destination words */ | ||
201 | |||
202 | /* Leading bits */ | ||
203 | if (first != ~0UL) { | ||
204 | *dst = comp(*src, *dst, first); | ||
205 | dst--; | ||
206 | src--; | ||
207 | n -= dst_idx+1; | ||
208 | } | ||
209 | |||
210 | /* Main chunk */ | ||
211 | n /= bits; | ||
212 | while (n >= 8) { | ||
213 | *dst-- = *src--; | ||
214 | *dst-- = *src--; | ||
215 | *dst-- = *src--; | ||
216 | *dst-- = *src--; | ||
217 | *dst-- = *src--; | ||
218 | *dst-- = *src--; | ||
219 | *dst-- = *src--; | ||
220 | *dst-- = *src--; | ||
221 | n -= 8; | ||
222 | } | ||
223 | while (n--) | ||
224 | *dst-- = *src--; | ||
225 | /* Trailing bits */ | ||
226 | if (last) | ||
227 | *dst = comp(*src, *dst, last); | ||
228 | } | ||
229 | } else { | ||
230 | /* Different alignment for source and dest */ | ||
231 | |||
232 | int const left = -shift & (bits-1); | ||
233 | int const right = shift & (bits-1); | ||
234 | |||
235 | if ((unsigned long)dst_idx+1 >= n) { | ||
236 | /* Single destination word */ | ||
237 | if (last) | ||
238 | first &= last; | ||
239 | if (shift < 0) { | ||
240 | /* Single source word */ | ||
241 | *dst = comp(*src << left, *dst, first); | ||
242 | } else if (1+(unsigned long)src_idx >= n) { | ||
243 | /* Single source word */ | ||
244 | *dst = comp(*src >> right, *dst, first); | ||
245 | } else { | ||
246 | /* 2 source words */ | ||
247 | *dst = comp(*src >> right | *(src-1) << left, | ||
248 | *dst, first); | ||
249 | } | ||
250 | } else { | ||
251 | /* Multiple destination words */ | ||
252 | /** We must always remember the last value read, | ||
253 | because in case SRC and DST overlap bitwise (e.g. | ||
254 | when moving just one pixel in 1bpp), we always | ||
255 | collect one full long for DST and that might | ||
256 | overlap with the current long from SRC. We store | ||
257 | this value in 'd0'. */ | ||
258 | unsigned long d0, d1; | ||
259 | int m; | ||
260 | |||
261 | d0 = *src--; | ||
262 | /* Leading bits */ | ||
263 | if (shift < 0) { | ||
264 | /* Single source word */ | ||
265 | *dst = comp(d0 << left, *dst, first); | ||
266 | } else { | ||
267 | /* 2 source words */ | ||
268 | d1 = *src--; | ||
269 | *dst = comp(d0 >> right | d1 << left, *dst, | ||
270 | first); | ||
271 | d0 = d1; | ||
272 | } | ||
273 | dst--; | ||
274 | n -= dst_idx+1; | ||
275 | |||
276 | /* Main chunk */ | ||
277 | m = n % bits; | ||
278 | n /= bits; | ||
279 | while (n >= 4) { | ||
280 | d1 = *src--; | ||
281 | *dst-- = d0 >> right | d1 << left; | ||
282 | d0 = d1; | ||
283 | d1 = *src--; | ||
284 | *dst-- = d0 >> right | d1 << left; | ||
285 | d0 = d1; | ||
286 | d1 = *src--; | ||
287 | *dst-- = d0 >> right | d1 << left; | ||
288 | d0 = d1; | ||
289 | d1 = *src--; | ||
290 | *dst-- = d0 >> right | d1 << left; | ||
291 | d0 = d1; | ||
292 | n -= 4; | ||
293 | } | ||
294 | while (n--) { | ||
295 | d1 = *src--; | ||
296 | *dst-- = d0 >> right | d1 << left; | ||
297 | d0 = d1; | ||
298 | } | ||
299 | |||
300 | /* Trailing bits */ | ||
301 | if (last) { | ||
302 | if (m <= left) { | ||
303 | /* Single source word */ | ||
304 | *dst = comp(d0 >> right, *dst, last); | ||
305 | } else { | ||
306 | /* 2 source words */ | ||
307 | d1 = *src; | ||
308 | *dst = comp(d0 >> right | d1 << left, | ||
309 | *dst, last); | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) | ||
317 | { | ||
318 | u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; | ||
319 | u32 height = area->height, width = area->width; | ||
320 | unsigned long const bits_per_line = p->fix.line_length*8u; | ||
321 | unsigned long *dst = NULL, *src = NULL; | ||
322 | int bits = BITS_PER_LONG, bytes = bits >> 3; | ||
323 | int dst_idx = 0, src_idx = 0, rev_copy = 0; | ||
324 | |||
325 | if (p->state != FBINFO_STATE_RUNNING) | ||
326 | return; | ||
327 | |||
328 | /* if the beginning of the target area might overlap with the end of | ||
329 | the source area, be have to copy the area reverse. */ | ||
330 | if ((dy == sy && dx > sx) || (dy > sy)) { | ||
331 | dy += height; | ||
332 | sy += height; | ||
333 | rev_copy = 1; | ||
334 | } | ||
335 | |||
336 | /* split the base of the framebuffer into a long-aligned address and | ||
337 | the index of the first bit */ | ||
338 | dst = src = (unsigned long *)((unsigned long)p->screen_base & | ||
339 | ~(bytes-1)); | ||
340 | dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1)); | ||
341 | /* add offset of source and target area */ | ||
342 | dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; | ||
343 | src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel; | ||
344 | |||
345 | if (p->fbops->fb_sync) | ||
346 | p->fbops->fb_sync(p); | ||
347 | |||
348 | if (rev_copy) { | ||
349 | while (height--) { | ||
350 | dst_idx -= bits_per_line; | ||
351 | src_idx -= bits_per_line; | ||
352 | dst += dst_idx >> (ffs(bits) - 1); | ||
353 | dst_idx &= (bytes - 1); | ||
354 | src += src_idx >> (ffs(bits) - 1); | ||
355 | src_idx &= (bytes - 1); | ||
356 | bitcpy_rev(dst, dst_idx, src, src_idx, bits, | ||
357 | width*p->var.bits_per_pixel); | ||
358 | } | ||
359 | } else { | ||
360 | while (height--) { | ||
361 | dst += dst_idx >> (ffs(bits) - 1); | ||
362 | dst_idx &= (bytes - 1); | ||
363 | src += src_idx >> (ffs(bits) - 1); | ||
364 | src_idx &= (bytes - 1); | ||
365 | bitcpy(dst, dst_idx, src, src_idx, bits, | ||
366 | width*p->var.bits_per_pixel); | ||
367 | dst_idx += bits_per_line; | ||
368 | src_idx += bits_per_line; | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | |||
373 | EXPORT_SYMBOL(sys_copyarea); | ||
374 | |||
375 | MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); | ||
376 | MODULE_DESCRIPTION("Generic copyarea (sys-to-sys)"); | ||
377 | MODULE_LICENSE("GPL"); | ||
378 | |||
diff --git a/drivers/video/sysfillrect.c b/drivers/video/sysfillrect.c new file mode 100644 index 000000000000..a261e9e6a675 --- /dev/null +++ b/drivers/video/sysfillrect.c | |||
@@ -0,0 +1,334 @@ | |||
1 | /* | ||
2 | * Generic fillrect for frame buffers in system RAM with packed pixels of | ||
3 | * any depth. | ||
4 | * | ||
5 | * Based almost entirely from cfbfillrect.c (which is based almost entirely | ||
6 | * on Geert Uytterhoeven's fillrect routine) | ||
7 | * | ||
8 | * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net> | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file COPYING in the main directory of this archive for | ||
12 | * more details. | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <asm/types.h> | ||
18 | #include "fb_draw.h" | ||
19 | |||
20 | /* | ||
21 | * Aligned pattern fill using 32/64-bit memory accesses | ||
22 | */ | ||
23 | |||
24 | static void | ||
25 | bitfill_aligned(unsigned long *dst, int dst_idx, unsigned long pat, | ||
26 | unsigned n, int bits) | ||
27 | { | ||
28 | unsigned long first, last; | ||
29 | |||
30 | if (!n) | ||
31 | return; | ||
32 | |||
33 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | ||
34 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | ||
35 | |||
36 | if (dst_idx+n <= bits) { | ||
37 | /* Single word */ | ||
38 | if (last) | ||
39 | first &= last; | ||
40 | *dst = comp(pat, *dst, first); | ||
41 | } else { | ||
42 | /* Multiple destination words */ | ||
43 | |||
44 | /* Leading bits */ | ||
45 | if (first!= ~0UL) { | ||
46 | *dst = comp(pat, *dst, first); | ||
47 | dst++; | ||
48 | n -= bits - dst_idx; | ||
49 | } | ||
50 | |||
51 | /* Main chunk */ | ||
52 | n /= bits; | ||
53 | while (n >= 8) { | ||
54 | *dst++ = pat; | ||
55 | *dst++ = pat; | ||
56 | *dst++ = pat; | ||
57 | *dst++ = pat; | ||
58 | *dst++ = pat; | ||
59 | *dst++ = pat; | ||
60 | *dst++ = pat; | ||
61 | *dst++ = pat; | ||
62 | n -= 8; | ||
63 | } | ||
64 | while (n--) | ||
65 | *dst++ = pat; | ||
66 | /* Trailing bits */ | ||
67 | if (last) | ||
68 | *dst = comp(pat, *dst, last); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | |||
73 | /* | ||
74 | * Unaligned generic pattern fill using 32/64-bit memory accesses | ||
75 | * The pattern must have been expanded to a full 32/64-bit value | ||
76 | * Left/right are the appropriate shifts to convert to the pattern to be | ||
77 | * used for the next 32/64-bit word | ||
78 | */ | ||
79 | |||
80 | static void | ||
81 | bitfill_unaligned(unsigned long *dst, int dst_idx, unsigned long pat, | ||
82 | int left, int right, unsigned n, int bits) | ||
83 | { | ||
84 | unsigned long first, last; | ||
85 | |||
86 | if (!n) | ||
87 | return; | ||
88 | |||
89 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | ||
90 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | ||
91 | |||
92 | if (dst_idx+n <= bits) { | ||
93 | /* Single word */ | ||
94 | if (last) | ||
95 | first &= last; | ||
96 | *dst = comp(pat, *dst, first); | ||
97 | } else { | ||
98 | /* Multiple destination words */ | ||
99 | /* Leading bits */ | ||
100 | if (first) { | ||
101 | *dst = comp(pat, *dst, first); | ||
102 | dst++; | ||
103 | pat = pat << left | pat >> right; | ||
104 | n -= bits - dst_idx; | ||
105 | } | ||
106 | |||
107 | /* Main chunk */ | ||
108 | n /= bits; | ||
109 | while (n >= 4) { | ||
110 | *dst++ = pat; | ||
111 | pat = pat << left | pat >> right; | ||
112 | *dst++ = pat; | ||
113 | pat = pat << left | pat >> right; | ||
114 | *dst++ = pat; | ||
115 | pat = pat << left | pat >> right; | ||
116 | *dst++ = pat; | ||
117 | pat = pat << left | pat >> right; | ||
118 | n -= 4; | ||
119 | } | ||
120 | while (n--) { | ||
121 | *dst++ = pat; | ||
122 | pat = pat << left | pat >> right; | ||
123 | } | ||
124 | |||
125 | /* Trailing bits */ | ||
126 | if (last) | ||
127 | *dst = comp(pat, *dst, first); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Aligned pattern invert using 32/64-bit memory accesses | ||
133 | */ | ||
134 | static void | ||
135 | bitfill_aligned_rev(unsigned long *dst, int dst_idx, unsigned long pat, | ||
136 | unsigned n, int bits) | ||
137 | { | ||
138 | unsigned long val = pat; | ||
139 | unsigned long first, last; | ||
140 | |||
141 | if (!n) | ||
142 | return; | ||
143 | |||
144 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | ||
145 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | ||
146 | |||
147 | if (dst_idx+n <= bits) { | ||
148 | /* Single word */ | ||
149 | if (last) | ||
150 | first &= last; | ||
151 | *dst = comp(*dst ^ val, *dst, first); | ||
152 | } else { | ||
153 | /* Multiple destination words */ | ||
154 | /* Leading bits */ | ||
155 | if (first!=0UL) { | ||
156 | *dst = comp(*dst ^ val, *dst, first); | ||
157 | dst++; | ||
158 | n -= bits - dst_idx; | ||
159 | } | ||
160 | |||
161 | /* Main chunk */ | ||
162 | n /= bits; | ||
163 | while (n >= 8) { | ||
164 | *dst++ ^= val; | ||
165 | *dst++ ^= val; | ||
166 | *dst++ ^= val; | ||
167 | *dst++ ^= val; | ||
168 | *dst++ ^= val; | ||
169 | *dst++ ^= val; | ||
170 | *dst++ ^= val; | ||
171 | *dst++ ^= val; | ||
172 | n -= 8; | ||
173 | } | ||
174 | while (n--) | ||
175 | *dst++ ^= val; | ||
176 | /* Trailing bits */ | ||
177 | if (last) | ||
178 | *dst = comp(*dst ^ val, *dst, last); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | |||
183 | /* | ||
184 | * Unaligned generic pattern invert using 32/64-bit memory accesses | ||
185 | * The pattern must have been expanded to a full 32/64-bit value | ||
186 | * Left/right are the appropriate shifts to convert to the pattern to be | ||
187 | * used for the next 32/64-bit word | ||
188 | */ | ||
189 | |||
190 | static void | ||
191 | bitfill_unaligned_rev(unsigned long *dst, int dst_idx, unsigned long pat, | ||
192 | int left, int right, unsigned n, int bits) | ||
193 | { | ||
194 | unsigned long first, last; | ||
195 | |||
196 | if (!n) | ||
197 | return; | ||
198 | |||
199 | first = FB_SHIFT_HIGH(~0UL, dst_idx); | ||
200 | last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); | ||
201 | |||
202 | if (dst_idx+n <= bits) { | ||
203 | /* Single word */ | ||
204 | if (last) | ||
205 | first &= last; | ||
206 | *dst = comp(*dst ^ pat, *dst, first); | ||
207 | } else { | ||
208 | /* Multiple destination words */ | ||
209 | |||
210 | /* Leading bits */ | ||
211 | if (first != 0UL) { | ||
212 | *dst = comp(*dst ^ pat, *dst, first); | ||
213 | dst++; | ||
214 | pat = pat << left | pat >> right; | ||
215 | n -= bits - dst_idx; | ||
216 | } | ||
217 | |||
218 | /* Main chunk */ | ||
219 | n /= bits; | ||
220 | while (n >= 4) { | ||
221 | *dst++ ^= pat; | ||
222 | pat = pat << left | pat >> right; | ||
223 | *dst++ ^= pat; | ||
224 | pat = pat << left | pat >> right; | ||
225 | *dst++ ^= pat; | ||
226 | pat = pat << left | pat >> right; | ||
227 | *dst++ ^= pat; | ||
228 | pat = pat << left | pat >> right; | ||
229 | n -= 4; | ||
230 | } | ||
231 | while (n--) { | ||
232 | *dst ^= pat; | ||
233 | pat = pat << left | pat >> right; | ||
234 | } | ||
235 | |||
236 | /* Trailing bits */ | ||
237 | if (last) | ||
238 | *dst = comp(*dst ^ pat, *dst, last); | ||
239 | } | ||
240 | } | ||
241 | |||
242 | void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect) | ||
243 | { | ||
244 | unsigned long pat, fg; | ||
245 | unsigned long width = rect->width, height = rect->height; | ||
246 | int bits = BITS_PER_LONG, bytes = bits >> 3; | ||
247 | u32 bpp = p->var.bits_per_pixel; | ||
248 | unsigned long *dst; | ||
249 | int dst_idx, left; | ||
250 | |||
251 | if (p->state != FBINFO_STATE_RUNNING) | ||
252 | return; | ||
253 | |||
254 | if (p->fix.visual == FB_VISUAL_TRUECOLOR || | ||
255 | p->fix.visual == FB_VISUAL_DIRECTCOLOR ) | ||
256 | fg = ((u32 *) (p->pseudo_palette))[rect->color]; | ||
257 | else | ||
258 | fg = rect->color; | ||
259 | |||
260 | pat = pixel_to_pat( bpp, fg); | ||
261 | |||
262 | dst = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1)); | ||
263 | dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8; | ||
264 | dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp; | ||
265 | /* FIXME For now we support 1-32 bpp only */ | ||
266 | left = bits % bpp; | ||
267 | if (p->fbops->fb_sync) | ||
268 | p->fbops->fb_sync(p); | ||
269 | if (!left) { | ||
270 | void (*fill_op32)(unsigned long *dst, int dst_idx, | ||
271 | unsigned long pat, unsigned n, int bits) = | ||
272 | NULL; | ||
273 | |||
274 | switch (rect->rop) { | ||
275 | case ROP_XOR: | ||
276 | fill_op32 = bitfill_aligned_rev; | ||
277 | break; | ||
278 | case ROP_COPY: | ||
279 | fill_op32 = bitfill_aligned; | ||
280 | break; | ||
281 | default: | ||
282 | printk( KERN_ERR "cfb_fillrect(): unknown rop, " | ||
283 | "defaulting to ROP_COPY\n"); | ||
284 | fill_op32 = bitfill_aligned; | ||
285 | break; | ||
286 | } | ||
287 | while (height--) { | ||
288 | dst += dst_idx >> (ffs(bits) - 1); | ||
289 | dst_idx &= (bits - 1); | ||
290 | fill_op32(dst, dst_idx, pat, width*bpp, bits); | ||
291 | dst_idx += p->fix.line_length*8; | ||
292 | } | ||
293 | } else { | ||
294 | int right; | ||
295 | int r; | ||
296 | int rot = (left-dst_idx) % bpp; | ||
297 | void (*fill_op)(unsigned long *dst, int dst_idx, | ||
298 | unsigned long pat, int left, int right, | ||
299 | unsigned n, int bits) = NULL; | ||
300 | |||
301 | /* rotate pattern to correct start position */ | ||
302 | pat = pat << rot | pat >> (bpp-rot); | ||
303 | |||
304 | right = bpp-left; | ||
305 | switch (rect->rop) { | ||
306 | case ROP_XOR: | ||
307 | fill_op = bitfill_unaligned_rev; | ||
308 | break; | ||
309 | case ROP_COPY: | ||
310 | fill_op = bitfill_unaligned; | ||
311 | break; | ||
312 | default: | ||
313 | printk(KERN_ERR "cfb_fillrect(): unknown rop, " | ||
314 | "defaulting to ROP_COPY\n"); | ||
315 | fill_op = bitfill_unaligned; | ||
316 | break; | ||
317 | } | ||
318 | while (height--) { | ||
319 | dst += dst_idx >> (ffs(bits) - 1); | ||
320 | dst_idx &= (bits - 1); | ||
321 | fill_op(dst, dst_idx, pat, left, right, | ||
322 | width*bpp, bits); | ||
323 | r = (p->fix.line_length*8) % bpp; | ||
324 | pat = pat << (bpp-r) | pat >> r; | ||
325 | dst_idx += p->fix.line_length*8; | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | |||
330 | EXPORT_SYMBOL(sys_fillrect); | ||
331 | |||
332 | MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); | ||
333 | MODULE_DESCRIPTION("Generic fill rectangle (sys-to-sys)"); | ||
334 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/sysimgblt.c b/drivers/video/sysimgblt.c new file mode 100644 index 000000000000..bd7e7e9d155f --- /dev/null +++ b/drivers/video/sysimgblt.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* | ||
2 | * Generic 1-bit or 8-bit source to 1-32 bit destination expansion | ||
3 | * for frame buffer located in system RAM with packed pixels of any depth. | ||
4 | * | ||
5 | * Based almost entirely on cfbimgblt.c | ||
6 | * | ||
7 | * Copyright (C) April 2007 Antonino Daplas <adaplas@pol.net> | ||
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 | #include <linux/module.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/fb.h> | ||
16 | #include <asm/types.h> | ||
17 | |||
18 | #define DEBUG | ||
19 | |||
20 | #ifdef DEBUG | ||
21 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args) | ||
22 | #else | ||
23 | #define DPRINTK(fmt, args...) | ||
24 | #endif | ||
25 | |||
26 | static const u32 cfb_tab8[] = { | ||
27 | #if defined(__BIG_ENDIAN) | ||
28 | 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, | ||
29 | 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, | ||
30 | 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, | ||
31 | 0xffff0000,0xffff00ff,0xffffff00,0xffffffff | ||
32 | #elif defined(__LITTLE_ENDIAN) | ||
33 | 0x00000000,0xff000000,0x00ff0000,0xffff0000, | ||
34 | 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, | ||
35 | 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, | ||
36 | 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff | ||
37 | #else | ||
38 | #error FIXME: No endianness?? | ||
39 | #endif | ||
40 | }; | ||
41 | |||
42 | static const u32 cfb_tab16[] = { | ||
43 | #if defined(__BIG_ENDIAN) | ||
44 | 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff | ||
45 | #elif defined(__LITTLE_ENDIAN) | ||
46 | 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff | ||
47 | #else | ||
48 | #error FIXME: No endianness?? | ||
49 | #endif | ||
50 | }; | ||
51 | |||
52 | static const u32 cfb_tab32[] = { | ||
53 | 0x00000000, 0xffffffff | ||
54 | }; | ||
55 | |||
56 | static void color_imageblit(const struct fb_image *image, struct fb_info *p, | ||
57 | void *dst1, u32 start_index, u32 pitch_index) | ||
58 | { | ||
59 | /* Draw the penguin */ | ||
60 | u32 *dst, *dst2; | ||
61 | u32 color = 0, val, shift; | ||
62 | int i, n, bpp = p->var.bits_per_pixel; | ||
63 | u32 null_bits = 32 - bpp; | ||
64 | u32 *palette = (u32 *) p->pseudo_palette; | ||
65 | const u8 *src = image->data; | ||
66 | |||
67 | dst2 = dst1; | ||
68 | for (i = image->height; i--; ) { | ||
69 | n = image->width; | ||
70 | dst = dst1; | ||
71 | shift = 0; | ||
72 | val = 0; | ||
73 | |||
74 | if (start_index) { | ||
75 | u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, | ||
76 | start_index)); | ||
77 | val = *dst & start_mask; | ||
78 | shift = start_index; | ||
79 | } | ||
80 | while (n--) { | ||
81 | if (p->fix.visual == FB_VISUAL_TRUECOLOR || | ||
82 | p->fix.visual == FB_VISUAL_DIRECTCOLOR ) | ||
83 | color = palette[*src]; | ||
84 | else | ||
85 | color = *src; | ||
86 | color <<= FB_LEFT_POS(bpp); | ||
87 | val |= FB_SHIFT_HIGH(color, shift); | ||
88 | if (shift >= null_bits) { | ||
89 | *dst++ = val; | ||
90 | |||
91 | val = (shift == null_bits) ? 0 : | ||
92 | FB_SHIFT_LOW(color, 32 - shift); | ||
93 | } | ||
94 | shift += bpp; | ||
95 | shift &= (32 - 1); | ||
96 | src++; | ||
97 | } | ||
98 | if (shift) { | ||
99 | u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); | ||
100 | |||
101 | *dst &= end_mask; | ||
102 | *dst |= val; | ||
103 | } | ||
104 | dst1 += p->fix.line_length; | ||
105 | if (pitch_index) { | ||
106 | dst2 += p->fix.line_length; | ||
107 | dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1)); | ||
108 | |||
109 | start_index += pitch_index; | ||
110 | start_index &= 32 - 1; | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | static void slow_imageblit(const struct fb_image *image, struct fb_info *p, | ||
116 | void *dst1, u32 fgcolor, u32 bgcolor, | ||
117 | u32 start_index, u32 pitch_index) | ||
118 | { | ||
119 | u32 shift, color = 0, bpp = p->var.bits_per_pixel; | ||
120 | u32 *dst, *dst2; | ||
121 | u32 val, pitch = p->fix.line_length; | ||
122 | u32 null_bits = 32 - bpp; | ||
123 | u32 spitch = (image->width+7)/8; | ||
124 | const u8 *src = image->data, *s; | ||
125 | u32 i, j, l; | ||
126 | |||
127 | dst2 = dst1; | ||
128 | fgcolor <<= FB_LEFT_POS(bpp); | ||
129 | bgcolor <<= FB_LEFT_POS(bpp); | ||
130 | |||
131 | for (i = image->height; i--; ) { | ||
132 | shift = val = 0; | ||
133 | l = 8; | ||
134 | j = image->width; | ||
135 | dst = dst1; | ||
136 | s = src; | ||
137 | |||
138 | /* write leading bits */ | ||
139 | if (start_index) { | ||
140 | u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index)); | ||
141 | val = *dst & start_mask; | ||
142 | shift = start_index; | ||
143 | } | ||
144 | |||
145 | while (j--) { | ||
146 | l--; | ||
147 | color = (*s & (1 << l)) ? fgcolor : bgcolor; | ||
148 | val |= FB_SHIFT_HIGH(color, shift); | ||
149 | |||
150 | /* Did the bitshift spill bits to the next long? */ | ||
151 | if (shift >= null_bits) { | ||
152 | *dst++ = val; | ||
153 | val = (shift == null_bits) ? 0 : | ||
154 | FB_SHIFT_LOW(color,32 - shift); | ||
155 | } | ||
156 | shift += bpp; | ||
157 | shift &= (32 - 1); | ||
158 | if (!l) { l = 8; s++; }; | ||
159 | } | ||
160 | |||
161 | /* write trailing bits */ | ||
162 | if (shift) { | ||
163 | u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); | ||
164 | |||
165 | *dst &= end_mask; | ||
166 | *dst |= val; | ||
167 | } | ||
168 | |||
169 | dst1 += pitch; | ||
170 | src += spitch; | ||
171 | if (pitch_index) { | ||
172 | dst2 += pitch; | ||
173 | dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1)); | ||
174 | start_index += pitch_index; | ||
175 | start_index &= 32 - 1; | ||
176 | } | ||
177 | |||
178 | } | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * fast_imageblit - optimized monochrome color expansion | ||
183 | * | ||
184 | * Only if: bits_per_pixel == 8, 16, or 32 | ||
185 | * image->width is divisible by pixel/dword (ppw); | ||
186 | * fix->line_legth is divisible by 4; | ||
187 | * beginning and end of a scanline is dword aligned | ||
188 | */ | ||
189 | static void fast_imageblit(const struct fb_image *image, struct fb_info *p, | ||
190 | void *dst1, u32 fgcolor, u32 bgcolor) | ||
191 | { | ||
192 | u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; | ||
193 | u32 ppw = 32/bpp, spitch = (image->width + 7)/8; | ||
194 | u32 bit_mask, end_mask, eorx, shift; | ||
195 | const char *s = image->data, *src; | ||
196 | u32 *dst; | ||
197 | const u32 *tab = NULL; | ||
198 | int i, j, k; | ||
199 | |||
200 | switch (bpp) { | ||
201 | case 8: | ||
202 | tab = cfb_tab8; | ||
203 | break; | ||
204 | case 16: | ||
205 | tab = cfb_tab16; | ||
206 | break; | ||
207 | case 32: | ||
208 | default: | ||
209 | tab = cfb_tab32; | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | for (i = ppw-1; i--; ) { | ||
214 | fgx <<= bpp; | ||
215 | bgx <<= bpp; | ||
216 | fgx |= fgcolor; | ||
217 | bgx |= bgcolor; | ||
218 | } | ||
219 | |||
220 | bit_mask = (1 << ppw) - 1; | ||
221 | eorx = fgx ^ bgx; | ||
222 | k = image->width/ppw; | ||
223 | |||
224 | for (i = image->height; i--; ) { | ||
225 | dst = dst1; | ||
226 | shift = 8; | ||
227 | src = s; | ||
228 | |||
229 | for (j = k; j--; ) { | ||
230 | shift -= ppw; | ||
231 | end_mask = tab[(*src >> shift) & bit_mask]; | ||
232 | *dst++ = (end_mask & eorx) ^ bgx; | ||
233 | if (!shift) { | ||
234 | shift = 8; | ||
235 | src++; | ||
236 | } | ||
237 | } | ||
238 | dst1 += p->fix.line_length; | ||
239 | s += spitch; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | void sys_imageblit(struct fb_info *p, const struct fb_image *image) | ||
244 | { | ||
245 | u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; | ||
246 | u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; | ||
247 | u32 width = image->width; | ||
248 | u32 dx = image->dx, dy = image->dy; | ||
249 | void *dst1; | ||
250 | |||
251 | if (p->state != FBINFO_STATE_RUNNING) | ||
252 | return; | ||
253 | |||
254 | bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); | ||
255 | start_index = bitstart & (32 - 1); | ||
256 | pitch_index = (p->fix.line_length & (bpl - 1)) * 8; | ||
257 | |||
258 | bitstart /= 8; | ||
259 | bitstart &= ~(bpl - 1); | ||
260 | dst1 = (void __force *)p->screen_base + bitstart; | ||
261 | |||
262 | if (p->fbops->fb_sync) | ||
263 | p->fbops->fb_sync(p); | ||
264 | |||
265 | if (image->depth == 1) { | ||
266 | if (p->fix.visual == FB_VISUAL_TRUECOLOR || | ||
267 | p->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
268 | fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; | ||
269 | bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; | ||
270 | } else { | ||
271 | fgcolor = image->fg_color; | ||
272 | bgcolor = image->bg_color; | ||
273 | } | ||
274 | |||
275 | if (32 % bpp == 0 && !start_index && !pitch_index && | ||
276 | ((width & (32/bpp-1)) == 0) && | ||
277 | bpp >= 8 && bpp <= 32) | ||
278 | fast_imageblit(image, p, dst1, fgcolor, bgcolor); | ||
279 | else | ||
280 | slow_imageblit(image, p, dst1, fgcolor, bgcolor, | ||
281 | start_index, pitch_index); | ||
282 | } else | ||
283 | color_imageblit(image, p, dst1, start_index, pitch_index); | ||
284 | } | ||
285 | |||
286 | EXPORT_SYMBOL(sys_imageblit); | ||
287 | |||
288 | MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>"); | ||
289 | MODULE_DESCRIPTION("1-bit/8-bit to 1-32 bit color expansion (sys-to-sys)"); | ||
290 | MODULE_LICENSE("GPL"); | ||
291 | |||
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index 7478d0e3e211..f0fde6ea7c36 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c | |||
@@ -5,27 +5,45 @@ | |||
5 | * Copyright (C) 1997 Geert Uytterhoeven | 5 | * Copyright (C) 1997 Geert Uytterhoeven |
6 | * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha | 6 | * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha |
7 | * Copyright (C) 2002 Richard Henderson | 7 | * Copyright (C) 2002 Richard Henderson |
8 | * Copyright (C) 2006 Maciej W. Rozycki | ||
8 | * | 9 | * |
9 | * This file is subject to the terms and conditions of the GNU General Public | 10 | * 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 | * License. See the file COPYING in the main directory of this archive for |
11 | * more details. | 12 | * more details. |
12 | */ | 13 | */ |
13 | 14 | ||
14 | #include <linux/module.h> | 15 | #include <linux/bitrev.h> |
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
21 | #include <linux/init.h> | 17 | #include <linux/device.h> |
18 | #include <linux/errno.h> | ||
22 | #include <linux/fb.h> | 19 | #include <linux/fb.h> |
20 | #include <linux/init.h> | ||
21 | #include <linux/ioport.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/module.h> | ||
23 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
24 | #include <linux/selection.h> | 26 | #include <linux/selection.h> |
25 | #include <linux/bitrev.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/string.h> | ||
29 | #include <linux/tc.h> | ||
30 | |||
26 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | |||
27 | #include <video/tgafb.h> | 33 | #include <video/tgafb.h> |
28 | 34 | ||
35 | #ifdef CONFIG_PCI | ||
36 | #define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type) | ||
37 | #else | ||
38 | #define TGA_BUS_PCI(dev) 0 | ||
39 | #endif | ||
40 | |||
41 | #ifdef CONFIG_TC | ||
42 | #define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type) | ||
43 | #else | ||
44 | #define TGA_BUS_TC(dev) 0 | ||
45 | #endif | ||
46 | |||
29 | /* | 47 | /* |
30 | * Local functions. | 48 | * Local functions. |
31 | */ | 49 | */ |
@@ -41,14 +59,19 @@ static void tgafb_init_fix(struct fb_info *); | |||
41 | static void tgafb_imageblit(struct fb_info *, const struct fb_image *); | 59 | static void tgafb_imageblit(struct fb_info *, const struct fb_image *); |
42 | static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); | 60 | static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); |
43 | static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); | 61 | static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); |
62 | static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); | ||
44 | 63 | ||
45 | static int __devinit tgafb_pci_register(struct pci_dev *, | 64 | static int __devinit tgafb_register(struct device *dev); |
46 | const struct pci_device_id *); | 65 | static void __devexit tgafb_unregister(struct device *dev); |
47 | static void __devexit tgafb_pci_unregister(struct pci_dev *); | ||
48 | 66 | ||
49 | static const char *mode_option = "640x480@60"; | 67 | static const char *mode_option; |
68 | static const char *mode_option_pci = "640x480@60"; | ||
69 | static const char *mode_option_tc = "1280x1024@72"; | ||
50 | 70 | ||
51 | 71 | ||
72 | static struct pci_driver tgafb_pci_driver; | ||
73 | static struct tc_driver tgafb_tc_driver; | ||
74 | |||
52 | /* | 75 | /* |
53 | * Frame buffer operations | 76 | * Frame buffer operations |
54 | */ | 77 | */ |
@@ -59,15 +82,20 @@ static struct fb_ops tgafb_ops = { | |||
59 | .fb_set_par = tgafb_set_par, | 82 | .fb_set_par = tgafb_set_par, |
60 | .fb_setcolreg = tgafb_setcolreg, | 83 | .fb_setcolreg = tgafb_setcolreg, |
61 | .fb_blank = tgafb_blank, | 84 | .fb_blank = tgafb_blank, |
85 | .fb_pan_display = tgafb_pan_display, | ||
62 | .fb_fillrect = tgafb_fillrect, | 86 | .fb_fillrect = tgafb_fillrect, |
63 | .fb_copyarea = tgafb_copyarea, | 87 | .fb_copyarea = tgafb_copyarea, |
64 | .fb_imageblit = tgafb_imageblit, | 88 | .fb_imageblit = tgafb_imageblit, |
65 | }; | 89 | }; |
66 | 90 | ||
67 | 91 | ||
92 | #ifdef CONFIG_PCI | ||
68 | /* | 93 | /* |
69 | * PCI registration operations | 94 | * PCI registration operations |
70 | */ | 95 | */ |
96 | static int __devinit tgafb_pci_register(struct pci_dev *, | ||
97 | const struct pci_device_id *); | ||
98 | static void __devexit tgafb_pci_unregister(struct pci_dev *); | ||
71 | 99 | ||
72 | static struct pci_device_id const tgafb_pci_table[] = { | 100 | static struct pci_device_id const tgafb_pci_table[] = { |
73 | { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) }, | 101 | { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) }, |
@@ -75,13 +103,68 @@ static struct pci_device_id const tgafb_pci_table[] = { | |||
75 | }; | 103 | }; |
76 | MODULE_DEVICE_TABLE(pci, tgafb_pci_table); | 104 | MODULE_DEVICE_TABLE(pci, tgafb_pci_table); |
77 | 105 | ||
78 | static struct pci_driver tgafb_driver = { | 106 | static struct pci_driver tgafb_pci_driver = { |
79 | .name = "tgafb", | 107 | .name = "tgafb", |
80 | .id_table = tgafb_pci_table, | 108 | .id_table = tgafb_pci_table, |
81 | .probe = tgafb_pci_register, | 109 | .probe = tgafb_pci_register, |
82 | .remove = __devexit_p(tgafb_pci_unregister), | 110 | .remove = __devexit_p(tgafb_pci_unregister), |
83 | }; | 111 | }; |
84 | 112 | ||
113 | static int __devinit | ||
114 | tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
115 | { | ||
116 | return tgafb_register(&pdev->dev); | ||
117 | } | ||
118 | |||
119 | static void __devexit | ||
120 | tgafb_pci_unregister(struct pci_dev *pdev) | ||
121 | { | ||
122 | tgafb_unregister(&pdev->dev); | ||
123 | } | ||
124 | #endif /* CONFIG_PCI */ | ||
125 | |||
126 | #ifdef CONFIG_TC | ||
127 | /* | ||
128 | * TC registration operations | ||
129 | */ | ||
130 | static int __devinit tgafb_tc_register(struct device *); | ||
131 | static int __devexit tgafb_tc_unregister(struct device *); | ||
132 | |||
133 | static struct tc_device_id const tgafb_tc_table[] = { | ||
134 | { "DEC ", "PMAGD-AA" }, | ||
135 | { "DEC ", "PMAGD " }, | ||
136 | { } | ||
137 | }; | ||
138 | MODULE_DEVICE_TABLE(tc, tgafb_tc_table); | ||
139 | |||
140 | static struct tc_driver tgafb_tc_driver = { | ||
141 | .id_table = tgafb_tc_table, | ||
142 | .driver = { | ||
143 | .name = "tgafb", | ||
144 | .bus = &tc_bus_type, | ||
145 | .probe = tgafb_tc_register, | ||
146 | .remove = __devexit_p(tgafb_tc_unregister), | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static int __devinit | ||
151 | tgafb_tc_register(struct device *dev) | ||
152 | { | ||
153 | int status = tgafb_register(dev); | ||
154 | if (!status) | ||
155 | get_device(dev); | ||
156 | return status; | ||
157 | } | ||
158 | |||
159 | static int __devexit | ||
160 | tgafb_tc_unregister(struct device *dev) | ||
161 | { | ||
162 | put_device(dev); | ||
163 | tgafb_unregister(dev); | ||
164 | return 0; | ||
165 | } | ||
166 | #endif /* CONFIG_TC */ | ||
167 | |||
85 | 168 | ||
86 | /** | 169 | /** |
87 | * tgafb_check_var - Optional function. Validates a var passed in. | 170 | * tgafb_check_var - Optional function. Validates a var passed in. |
@@ -132,10 +215,10 @@ static int | |||
132 | tgafb_set_par(struct fb_info *info) | 215 | tgafb_set_par(struct fb_info *info) |
133 | { | 216 | { |
134 | static unsigned int const deep_presets[4] = { | 217 | static unsigned int const deep_presets[4] = { |
135 | 0x00014000, | 218 | 0x00004000, |
136 | 0x0001440d, | 219 | 0x0000440d, |
137 | 0xffffffff, | 220 | 0xffffffff, |
138 | 0x0001441d | 221 | 0x0000441d |
139 | }; | 222 | }; |
140 | static unsigned int const rasterop_presets[4] = { | 223 | static unsigned int const rasterop_presets[4] = { |
141 | 0x00000003, | 224 | 0x00000003, |
@@ -157,6 +240,8 @@ tgafb_set_par(struct fb_info *info) | |||
157 | }; | 240 | }; |
158 | 241 | ||
159 | struct tga_par *par = (struct tga_par *) info->par; | 242 | struct tga_par *par = (struct tga_par *) info->par; |
243 | int tga_bus_pci = TGA_BUS_PCI(par->dev); | ||
244 | int tga_bus_tc = TGA_BUS_TC(par->dev); | ||
160 | u32 htimings, vtimings, pll_freq; | 245 | u32 htimings, vtimings, pll_freq; |
161 | u8 tga_type; | 246 | u8 tga_type; |
162 | int i; | 247 | int i; |
@@ -221,7 +306,7 @@ tgafb_set_par(struct fb_info *info) | |||
221 | TGA_WRITE_REG(par, vtimings, TGA_VERT_REG); | 306 | TGA_WRITE_REG(par, vtimings, TGA_VERT_REG); |
222 | 307 | ||
223 | /* Initalise RAMDAC. */ | 308 | /* Initalise RAMDAC. */ |
224 | if (tga_type == TGA_TYPE_8PLANE) { | 309 | if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) { |
225 | 310 | ||
226 | /* Init BT485 RAMDAC registers. */ | 311 | /* Init BT485 RAMDAC registers. */ |
227 | BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0), | 312 | BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0), |
@@ -236,21 +321,7 @@ tgafb_set_par(struct fb_info *info) | |||
236 | BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE); | 321 | BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE); |
237 | TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); | 322 | TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); |
238 | 323 | ||
239 | #ifdef CONFIG_HW_CONSOLE | ||
240 | for (i = 0; i < 16; i++) { | ||
241 | int j = color_table[i]; | ||
242 | |||
243 | TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8), | ||
244 | TGA_RAMDAC_REG); | ||
245 | TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8), | ||
246 | TGA_RAMDAC_REG); | ||
247 | TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8), | ||
248 | TGA_RAMDAC_REG); | ||
249 | } | ||
250 | for (i = 0; i < 240 * 3; i += 4) { | ||
251 | #else | ||
252 | for (i = 0; i < 256 * 3; i += 4) { | 324 | for (i = 0; i < 256 * 3; i += 4) { |
253 | #endif | ||
254 | TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8), | 325 | TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8), |
255 | TGA_RAMDAC_REG); | 326 | TGA_RAMDAC_REG); |
256 | TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8), | 327 | TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8), |
@@ -261,6 +332,27 @@ tgafb_set_par(struct fb_info *info) | |||
261 | TGA_RAMDAC_REG); | 332 | TGA_RAMDAC_REG); |
262 | } | 333 | } |
263 | 334 | ||
335 | } else if (tga_type == TGA_TYPE_8PLANE && tga_bus_tc) { | ||
336 | |||
337 | /* Init BT459 RAMDAC registers. */ | ||
338 | BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_0, 0x40); | ||
339 | BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_1, 0x00); | ||
340 | BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_2, | ||
341 | (par->sync_on_green ? 0xc0 : 0x40)); | ||
342 | |||
343 | BT459_WRITE(par, BT459_REG_ACC, BT459_CUR_CMD_REG, 0x00); | ||
344 | |||
345 | /* Fill the palette. */ | ||
346 | BT459_LOAD_ADDR(par, 0x0000); | ||
347 | TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG); | ||
348 | |||
349 | for (i = 0; i < 256 * 3; i += 4) { | ||
350 | TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG); | ||
351 | TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG); | ||
352 | TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG); | ||
353 | TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG); | ||
354 | } | ||
355 | |||
264 | } else { /* 24-plane or 24plusZ */ | 356 | } else { /* 24-plane or 24plusZ */ |
265 | 357 | ||
266 | /* Init BT463 RAMDAC registers. */ | 358 | /* Init BT463 RAMDAC registers. */ |
@@ -431,6 +523,8 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | |||
431 | unsigned transp, struct fb_info *info) | 523 | unsigned transp, struct fb_info *info) |
432 | { | 524 | { |
433 | struct tga_par *par = (struct tga_par *) info->par; | 525 | struct tga_par *par = (struct tga_par *) info->par; |
526 | int tga_bus_pci = TGA_BUS_PCI(par->dev); | ||
527 | int tga_bus_tc = TGA_BUS_TC(par->dev); | ||
434 | 528 | ||
435 | if (regno > 255) | 529 | if (regno > 255) |
436 | return 1; | 530 | return 1; |
@@ -438,12 +532,18 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | |||
438 | green >>= 8; | 532 | green >>= 8; |
439 | blue >>= 8; | 533 | blue >>= 8; |
440 | 534 | ||
441 | if (par->tga_type == TGA_TYPE_8PLANE) { | 535 | if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) { |
442 | BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE); | 536 | BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE); |
443 | TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); | 537 | TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); |
444 | TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); | 538 | TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); |
445 | TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); | 539 | TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); |
446 | TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); | 540 | TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); |
541 | } else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) { | ||
542 | BT459_LOAD_ADDR(par, regno); | ||
543 | TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG); | ||
544 | TGA_WRITE_REG(par, red, TGA_RAMDAC_REG); | ||
545 | TGA_WRITE_REG(par, green, TGA_RAMDAC_REG); | ||
546 | TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG); | ||
447 | } else { | 547 | } else { |
448 | if (regno < 16) { | 548 | if (regno < 16) { |
449 | u32 value = (regno << 16) | (regno << 8) | regno; | 549 | u32 value = (regno << 16) | (regno << 8) | regno; |
@@ -523,16 +623,8 @@ tgafb_blank(int blank, struct fb_info *info) | |||
523 | * Acceleration. | 623 | * Acceleration. |
524 | */ | 624 | */ |
525 | 625 | ||
526 | /** | ||
527 | * tgafb_imageblit - REQUIRED function. Can use generic routines if | ||
528 | * non acclerated hardware and packed pixel based. | ||
529 | * Copies a image from system memory to the screen. | ||
530 | * | ||
531 | * @info: frame buffer structure that represents a single frame buffer | ||
532 | * @image: structure defining the image. | ||
533 | */ | ||
534 | static void | 626 | static void |
535 | tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | 627 | tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image) |
536 | { | 628 | { |
537 | struct tga_par *par = (struct tga_par *) info->par; | 629 | struct tga_par *par = (struct tga_par *) info->par; |
538 | u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask; | 630 | u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask; |
@@ -542,6 +634,17 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
542 | void __iomem *regs_base; | 634 | void __iomem *regs_base; |
543 | void __iomem *fb_base; | 635 | void __iomem *fb_base; |
544 | 636 | ||
637 | is8bpp = info->var.bits_per_pixel == 8; | ||
638 | |||
639 | /* For copies that aren't pixel expansion, there's little we | ||
640 | can do better than the generic code. */ | ||
641 | /* ??? There is a DMA write mode; I wonder if that could be | ||
642 | made to pull the data from the image buffer... */ | ||
643 | if (image->depth > 1) { | ||
644 | cfb_imageblit(info, image); | ||
645 | return; | ||
646 | } | ||
647 | |||
545 | dx = image->dx; | 648 | dx = image->dx; |
546 | dy = image->dy; | 649 | dy = image->dy; |
547 | width = image->width; | 650 | width = image->width; |
@@ -559,18 +662,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
559 | if (dy + height > vyres) | 662 | if (dy + height > vyres) |
560 | height = vyres - dy; | 663 | height = vyres - dy; |
561 | 664 | ||
562 | /* For copies that aren't pixel expansion, there's little we | ||
563 | can do better than the generic code. */ | ||
564 | /* ??? There is a DMA write mode; I wonder if that could be | ||
565 | made to pull the data from the image buffer... */ | ||
566 | if (image->depth > 1) { | ||
567 | cfb_imageblit(info, image); | ||
568 | return; | ||
569 | } | ||
570 | |||
571 | regs_base = par->tga_regs_base; | 665 | regs_base = par->tga_regs_base; |
572 | fb_base = par->tga_fb_base; | 666 | fb_base = par->tga_fb_base; |
573 | is8bpp = info->var.bits_per_pixel == 8; | ||
574 | 667 | ||
575 | /* Expand the color values to fill 32-bits. */ | 668 | /* Expand the color values to fill 32-bits. */ |
576 | /* ??? Would be nice to notice colour changes elsewhere, so | 669 | /* ??? Would be nice to notice colour changes elsewhere, so |
@@ -748,6 +841,85 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
748 | regs_base + TGA_MODE_REG); | 841 | regs_base + TGA_MODE_REG); |
749 | } | 842 | } |
750 | 843 | ||
844 | static void | ||
845 | tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image) | ||
846 | { | ||
847 | struct tga_par *par = (struct tga_par *) info->par; | ||
848 | u32 color, dx, dy, width, height, vxres, vyres; | ||
849 | u32 *palette = ((u32 *)info->pseudo_palette); | ||
850 | unsigned long pos, line_length, i, j; | ||
851 | const unsigned char *data; | ||
852 | void *regs_base, *fb_base; | ||
853 | |||
854 | dx = image->dx; | ||
855 | dy = image->dy; | ||
856 | width = image->width; | ||
857 | height = image->height; | ||
858 | vxres = info->var.xres_virtual; | ||
859 | vyres = info->var.yres_virtual; | ||
860 | line_length = info->fix.line_length; | ||
861 | |||
862 | /* Crop the image to the screen. */ | ||
863 | if (dx > vxres || dy > vyres) | ||
864 | return; | ||
865 | if (dx + width > vxres) | ||
866 | width = vxres - dx; | ||
867 | if (dy + height > vyres) | ||
868 | height = vyres - dy; | ||
869 | |||
870 | regs_base = par->tga_regs_base; | ||
871 | fb_base = par->tga_fb_base; | ||
872 | |||
873 | pos = dy * line_length + (dx * 4); | ||
874 | data = image->data; | ||
875 | |||
876 | /* Now copy the image, color_expanding via the palette. */ | ||
877 | for (i = 0; i < height; i++) { | ||
878 | for (j = 0; j < width; j++) { | ||
879 | color = palette[*data++]; | ||
880 | __raw_writel(color, fb_base + pos + j*4); | ||
881 | } | ||
882 | pos += line_length; | ||
883 | } | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * tgafb_imageblit - REQUIRED function. Can use generic routines if | ||
888 | * non acclerated hardware and packed pixel based. | ||
889 | * Copies a image from system memory to the screen. | ||
890 | * | ||
891 | * @info: frame buffer structure that represents a single frame buffer | ||
892 | * @image: structure defining the image. | ||
893 | */ | ||
894 | static void | ||
895 | tgafb_imageblit(struct fb_info *info, const struct fb_image *image) | ||
896 | { | ||
897 | unsigned int is8bpp = info->var.bits_per_pixel == 8; | ||
898 | |||
899 | /* If a mono image, regardless of FB depth, go do it. */ | ||
900 | if (image->depth == 1) { | ||
901 | tgafb_mono_imageblit(info, image); | ||
902 | return; | ||
903 | } | ||
904 | |||
905 | /* For copies that aren't pixel expansion, there's little we | ||
906 | can do better than the generic code. */ | ||
907 | /* ??? There is a DMA write mode; I wonder if that could be | ||
908 | made to pull the data from the image buffer... */ | ||
909 | if (image->depth == info->var.bits_per_pixel) { | ||
910 | cfb_imageblit(info, image); | ||
911 | return; | ||
912 | } | ||
913 | |||
914 | /* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */ | ||
915 | if (!is8bpp && image->depth == 8) { | ||
916 | tgafb_clut_imageblit(info, image); | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | /* Silently return... */ | ||
921 | } | ||
922 | |||
751 | /** | 923 | /** |
752 | * tgafb_fillrect - REQUIRED function. Can use generic routines if | 924 | * tgafb_fillrect - REQUIRED function. Can use generic routines if |
753 | * non acclerated hardware and packed pixel based. | 925 | * non acclerated hardware and packed pixel based. |
@@ -1309,18 +1481,29 @@ static void | |||
1309 | tgafb_init_fix(struct fb_info *info) | 1481 | tgafb_init_fix(struct fb_info *info) |
1310 | { | 1482 | { |
1311 | struct tga_par *par = (struct tga_par *)info->par; | 1483 | struct tga_par *par = (struct tga_par *)info->par; |
1484 | int tga_bus_pci = TGA_BUS_PCI(par->dev); | ||
1485 | int tga_bus_tc = TGA_BUS_TC(par->dev); | ||
1312 | u8 tga_type = par->tga_type; | 1486 | u8 tga_type = par->tga_type; |
1313 | const char *tga_type_name; | 1487 | const char *tga_type_name = NULL; |
1314 | 1488 | ||
1315 | switch (tga_type) { | 1489 | switch (tga_type) { |
1316 | case TGA_TYPE_8PLANE: | 1490 | case TGA_TYPE_8PLANE: |
1317 | tga_type_name = "Digital ZLXp-E1"; | 1491 | if (tga_bus_pci) |
1492 | tga_type_name = "Digital ZLXp-E1"; | ||
1493 | if (tga_bus_tc) | ||
1494 | tga_type_name = "Digital ZLX-E1"; | ||
1318 | break; | 1495 | break; |
1319 | case TGA_TYPE_24PLANE: | 1496 | case TGA_TYPE_24PLANE: |
1320 | tga_type_name = "Digital ZLXp-E2"; | 1497 | if (tga_bus_pci) |
1498 | tga_type_name = "Digital ZLXp-E2"; | ||
1499 | if (tga_bus_tc) | ||
1500 | tga_type_name = "Digital ZLX-E2"; | ||
1321 | break; | 1501 | break; |
1322 | case TGA_TYPE_24PLUSZ: | 1502 | case TGA_TYPE_24PLUSZ: |
1323 | tga_type_name = "Digital ZLXp-E3"; | 1503 | if (tga_bus_pci) |
1504 | tga_type_name = "Digital ZLXp-E3"; | ||
1505 | if (tga_bus_tc) | ||
1506 | tga_type_name = "Digital ZLX-E3"; | ||
1324 | break; | 1507 | break; |
1325 | default: | 1508 | default: |
1326 | tga_type_name = "Unknown"; | 1509 | tga_type_name = "Unknown"; |
@@ -1346,11 +1529,37 @@ tgafb_init_fix(struct fb_info *info) | |||
1346 | info->fix.ywrapstep = 0; | 1529 | info->fix.ywrapstep = 0; |
1347 | 1530 | ||
1348 | info->fix.accel = FB_ACCEL_DEC_TGA; | 1531 | info->fix.accel = FB_ACCEL_DEC_TGA; |
1532 | |||
1533 | /* | ||
1534 | * These are needed by fb_set_logo_truepalette(), so we | ||
1535 | * set them here for 24-plane cards. | ||
1536 | */ | ||
1537 | if (tga_type != TGA_TYPE_8PLANE) { | ||
1538 | info->var.red.length = 8; | ||
1539 | info->var.green.length = 8; | ||
1540 | info->var.blue.length = 8; | ||
1541 | info->var.red.offset = 16; | ||
1542 | info->var.green.offset = 8; | ||
1543 | info->var.blue.offset = 0; | ||
1544 | } | ||
1349 | } | 1545 | } |
1350 | 1546 | ||
1351 | static __devinit int | 1547 | static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) |
1352 | tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | 1548 | { |
1549 | /* We just use this to catch switches out of graphics mode. */ | ||
1550 | tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */ | ||
1551 | return 0; | ||
1552 | } | ||
1553 | |||
1554 | static int __devinit | ||
1555 | tgafb_register(struct device *dev) | ||
1353 | { | 1556 | { |
1557 | static const struct fb_videomode modedb_tc = { | ||
1558 | /* 1280x1024 @ 72 Hz, 76.8 kHz hsync */ | ||
1559 | "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3, | ||
1560 | FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED | ||
1561 | }; | ||
1562 | |||
1354 | static unsigned int const fb_offset_presets[4] = { | 1563 | static unsigned int const fb_offset_presets[4] = { |
1355 | TGA_8PLANE_FB_OFFSET, | 1564 | TGA_8PLANE_FB_OFFSET, |
1356 | TGA_24PLANE_FB_OFFSET, | 1565 | TGA_24PLANE_FB_OFFSET, |
@@ -1358,40 +1567,51 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1358 | TGA_24PLUSZ_FB_OFFSET | 1567 | TGA_24PLUSZ_FB_OFFSET |
1359 | }; | 1568 | }; |
1360 | 1569 | ||
1570 | const struct fb_videomode *modedb_tga = NULL; | ||
1571 | resource_size_t bar0_start = 0, bar0_len = 0; | ||
1572 | const char *mode_option_tga = NULL; | ||
1573 | int tga_bus_pci = TGA_BUS_PCI(dev); | ||
1574 | int tga_bus_tc = TGA_BUS_TC(dev); | ||
1575 | unsigned int modedbsize_tga = 0; | ||
1361 | void __iomem *mem_base; | 1576 | void __iomem *mem_base; |
1362 | unsigned long bar0_start, bar0_len; | ||
1363 | struct fb_info *info; | 1577 | struct fb_info *info; |
1364 | struct tga_par *par; | 1578 | struct tga_par *par; |
1365 | u8 tga_type; | 1579 | u8 tga_type; |
1366 | int ret; | 1580 | int ret = 0; |
1367 | 1581 | ||
1368 | /* Enable device in PCI config. */ | 1582 | /* Enable device in PCI config. */ |
1369 | if (pci_enable_device(pdev)) { | 1583 | if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) { |
1370 | printk(KERN_ERR "tgafb: Cannot enable PCI device\n"); | 1584 | printk(KERN_ERR "tgafb: Cannot enable PCI device\n"); |
1371 | return -ENODEV; | 1585 | return -ENODEV; |
1372 | } | 1586 | } |
1373 | 1587 | ||
1374 | /* Allocate the fb and par structures. */ | 1588 | /* Allocate the fb and par structures. */ |
1375 | info = framebuffer_alloc(sizeof(struct tga_par), &pdev->dev); | 1589 | info = framebuffer_alloc(sizeof(struct tga_par), dev); |
1376 | if (!info) { | 1590 | if (!info) { |
1377 | printk(KERN_ERR "tgafb: Cannot allocate memory\n"); | 1591 | printk(KERN_ERR "tgafb: Cannot allocate memory\n"); |
1378 | return -ENOMEM; | 1592 | return -ENOMEM; |
1379 | } | 1593 | } |
1380 | 1594 | ||
1381 | par = info->par; | 1595 | par = info->par; |
1382 | pci_set_drvdata(pdev, info); | 1596 | dev_set_drvdata(dev, info); |
1383 | 1597 | ||
1384 | /* Request the mem regions. */ | 1598 | /* Request the mem regions. */ |
1385 | bar0_start = pci_resource_start(pdev, 0); | ||
1386 | bar0_len = pci_resource_len(pdev, 0); | ||
1387 | ret = -ENODEV; | 1599 | ret = -ENODEV; |
1600 | if (tga_bus_pci) { | ||
1601 | bar0_start = pci_resource_start(to_pci_dev(dev), 0); | ||
1602 | bar0_len = pci_resource_len(to_pci_dev(dev), 0); | ||
1603 | } | ||
1604 | if (tga_bus_tc) { | ||
1605 | bar0_start = to_tc_dev(dev)->resource.start; | ||
1606 | bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1; | ||
1607 | } | ||
1388 | if (!request_mem_region (bar0_start, bar0_len, "tgafb")) { | 1608 | if (!request_mem_region (bar0_start, bar0_len, "tgafb")) { |
1389 | printk(KERN_ERR "tgafb: cannot reserve FB region\n"); | 1609 | printk(KERN_ERR "tgafb: cannot reserve FB region\n"); |
1390 | goto err0; | 1610 | goto err0; |
1391 | } | 1611 | } |
1392 | 1612 | ||
1393 | /* Map the framebuffer. */ | 1613 | /* Map the framebuffer. */ |
1394 | mem_base = ioremap(bar0_start, bar0_len); | 1614 | mem_base = ioremap_nocache(bar0_start, bar0_len); |
1395 | if (!mem_base) { | 1615 | if (!mem_base) { |
1396 | printk(KERN_ERR "tgafb: Cannot map MMIO\n"); | 1616 | printk(KERN_ERR "tgafb: Cannot map MMIO\n"); |
1397 | goto err1; | 1617 | goto err1; |
@@ -1399,12 +1619,16 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1399 | 1619 | ||
1400 | /* Grab info about the card. */ | 1620 | /* Grab info about the card. */ |
1401 | tga_type = (readl(mem_base) >> 12) & 0x0f; | 1621 | tga_type = (readl(mem_base) >> 12) & 0x0f; |
1402 | par->pdev = pdev; | 1622 | par->dev = dev; |
1403 | par->tga_mem_base = mem_base; | 1623 | par->tga_mem_base = mem_base; |
1404 | par->tga_fb_base = mem_base + fb_offset_presets[tga_type]; | 1624 | par->tga_fb_base = mem_base + fb_offset_presets[tga_type]; |
1405 | par->tga_regs_base = mem_base + TGA_REGS_OFFSET; | 1625 | par->tga_regs_base = mem_base + TGA_REGS_OFFSET; |
1406 | par->tga_type = tga_type; | 1626 | par->tga_type = tga_type; |
1407 | pci_read_config_byte(pdev, PCI_REVISION_ID, &par->tga_chip_rev); | 1627 | if (tga_bus_pci) |
1628 | pci_read_config_byte(to_pci_dev(dev), PCI_REVISION_ID, | ||
1629 | &par->tga_chip_rev); | ||
1630 | if (tga_bus_tc) | ||
1631 | par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff; | ||
1408 | 1632 | ||
1409 | /* Setup framebuffer. */ | 1633 | /* Setup framebuffer. */ |
1410 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | | 1634 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | |
@@ -1414,8 +1638,17 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1414 | info->pseudo_palette = (void *)(par + 1); | 1638 | info->pseudo_palette = (void *)(par + 1); |
1415 | 1639 | ||
1416 | /* This should give a reasonable default video mode. */ | 1640 | /* This should give a reasonable default video mode. */ |
1417 | 1641 | if (tga_bus_pci) { | |
1418 | ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, | 1642 | mode_option_tga = mode_option_pci; |
1643 | } | ||
1644 | if (tga_bus_tc) { | ||
1645 | mode_option_tga = mode_option_tc; | ||
1646 | modedb_tga = &modedb_tc; | ||
1647 | modedbsize_tga = 1; | ||
1648 | } | ||
1649 | ret = fb_find_mode(&info->var, info, | ||
1650 | mode_option ? mode_option : mode_option_tga, | ||
1651 | modedb_tga, modedbsize_tga, NULL, | ||
1419 | tga_type == TGA_TYPE_8PLANE ? 8 : 32); | 1652 | tga_type == TGA_TYPE_8PLANE ? 8 : 32); |
1420 | if (ret == 0 || ret == 4) { | 1653 | if (ret == 0 || ret == 4) { |
1421 | printk(KERN_ERR "tgafb: Could not find valid video mode\n"); | 1654 | printk(KERN_ERR "tgafb: Could not find valid video mode\n"); |
@@ -1438,13 +1671,19 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1438 | goto err1; | 1671 | goto err1; |
1439 | } | 1672 | } |
1440 | 1673 | ||
1441 | printk(KERN_INFO "tgafb: DC21030 [TGA] detected, rev=0x%02x\n", | 1674 | if (tga_bus_pci) { |
1442 | par->tga_chip_rev); | 1675 | pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n", |
1443 | printk(KERN_INFO "tgafb: at PCI bus %d, device %d, function %d\n", | 1676 | par->tga_chip_rev); |
1444 | pdev->bus->number, PCI_SLOT(pdev->devfn), | 1677 | pr_info("tgafb: at PCI bus %d, device %d, function %d\n", |
1445 | PCI_FUNC(pdev->devfn)); | 1678 | to_pci_dev(dev)->bus->number, |
1446 | printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n", | 1679 | PCI_SLOT(to_pci_dev(dev)->devfn), |
1447 | info->node, info->fix.id, bar0_start); | 1680 | PCI_FUNC(to_pci_dev(dev)->devfn)); |
1681 | } | ||
1682 | if (tga_bus_tc) | ||
1683 | pr_info("tgafb: SFB+ detected, rev=0x%02x\n", | ||
1684 | par->tga_chip_rev); | ||
1685 | pr_info("fb%d: %s frame buffer device at 0x%lx\n", | ||
1686 | info->node, info->fix.id, (long)bar0_start); | ||
1448 | 1687 | ||
1449 | return 0; | 1688 | return 0; |
1450 | 1689 | ||
@@ -1458,25 +1697,39 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1458 | } | 1697 | } |
1459 | 1698 | ||
1460 | static void __devexit | 1699 | static void __devexit |
1461 | tgafb_pci_unregister(struct pci_dev *pdev) | 1700 | tgafb_unregister(struct device *dev) |
1462 | { | 1701 | { |
1463 | struct fb_info *info = pci_get_drvdata(pdev); | 1702 | resource_size_t bar0_start = 0, bar0_len = 0; |
1464 | struct tga_par *par = info->par; | 1703 | int tga_bus_pci = TGA_BUS_PCI(dev); |
1704 | int tga_bus_tc = TGA_BUS_TC(dev); | ||
1705 | struct fb_info *info = NULL; | ||
1706 | struct tga_par *par; | ||
1465 | 1707 | ||
1708 | info = dev_get_drvdata(dev); | ||
1466 | if (!info) | 1709 | if (!info) |
1467 | return; | 1710 | return; |
1711 | |||
1712 | par = info->par; | ||
1468 | unregister_framebuffer(info); | 1713 | unregister_framebuffer(info); |
1469 | fb_dealloc_cmap(&info->cmap); | 1714 | fb_dealloc_cmap(&info->cmap); |
1470 | iounmap(par->tga_mem_base); | 1715 | iounmap(par->tga_mem_base); |
1471 | release_mem_region(pci_resource_start(pdev, 0), | 1716 | if (tga_bus_pci) { |
1472 | pci_resource_len(pdev, 0)); | 1717 | bar0_start = pci_resource_start(to_pci_dev(dev), 0); |
1718 | bar0_len = pci_resource_len(to_pci_dev(dev), 0); | ||
1719 | } | ||
1720 | if (tga_bus_tc) { | ||
1721 | bar0_start = to_tc_dev(dev)->resource.start; | ||
1722 | bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1; | ||
1723 | } | ||
1724 | release_mem_region(bar0_start, bar0_len); | ||
1473 | framebuffer_release(info); | 1725 | framebuffer_release(info); |
1474 | } | 1726 | } |
1475 | 1727 | ||
1476 | static void __devexit | 1728 | static void __devexit |
1477 | tgafb_exit(void) | 1729 | tgafb_exit(void) |
1478 | { | 1730 | { |
1479 | pci_unregister_driver(&tgafb_driver); | 1731 | tc_unregister_driver(&tgafb_tc_driver); |
1732 | pci_unregister_driver(&tgafb_pci_driver); | ||
1480 | } | 1733 | } |
1481 | 1734 | ||
1482 | #ifndef MODULE | 1735 | #ifndef MODULE |
@@ -1505,6 +1758,7 @@ tgafb_setup(char *arg) | |||
1505 | static int __devinit | 1758 | static int __devinit |
1506 | tgafb_init(void) | 1759 | tgafb_init(void) |
1507 | { | 1760 | { |
1761 | int status; | ||
1508 | #ifndef MODULE | 1762 | #ifndef MODULE |
1509 | char *option = NULL; | 1763 | char *option = NULL; |
1510 | 1764 | ||
@@ -1512,7 +1766,10 @@ tgafb_init(void) | |||
1512 | return -ENODEV; | 1766 | return -ENODEV; |
1513 | tgafb_setup(option); | 1767 | tgafb_setup(option); |
1514 | #endif | 1768 | #endif |
1515 | return pci_register_driver(&tgafb_driver); | 1769 | status = pci_register_driver(&tgafb_pci_driver); |
1770 | if (!status) | ||
1771 | status = tc_register_driver(&tgafb_tc_driver); | ||
1772 | return status; | ||
1516 | } | 1773 | } |
1517 | 1774 | ||
1518 | /* | 1775 | /* |
@@ -1522,5 +1779,5 @@ tgafb_init(void) | |||
1522 | module_init(tgafb_init); | 1779 | module_init(tgafb_init); |
1523 | module_exit(tgafb_exit); | 1780 | module_exit(tgafb_exit); |
1524 | 1781 | ||
1525 | MODULE_DESCRIPTION("framebuffer driver for TGA chipset"); | 1782 | MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset"); |
1526 | MODULE_LICENSE("GPL"); | 1783 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/vermilion/Makefile new file mode 100644 index 000000000000..cc21a656153d --- /dev/null +++ b/drivers/video/vermilion/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_FB_LE80578) += vmlfb.o | ||
2 | obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o | ||
3 | |||
4 | vmlfb-objs := vermilion.o | ||
5 | crvml-objs := cr_pll.o | ||
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/vermilion/cr_pll.c new file mode 100644 index 000000000000..ebc6e6e0dd0f --- /dev/null +++ b/drivers/video/vermilion/cr_pll.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Copyright (c) Intel Corp. 2007. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||
6 | * develop this driver. | ||
7 | * | ||
8 | * This file is part of the Carillo Ranch video subsystem driver. | ||
9 | * The Carillo Ranch video subsystem driver is free software; | ||
10 | * you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * The Carillo Ranch video subsystem driver is distributed | ||
16 | * in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this driver; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | ||
27 | * Alan Hourihane <alanh-at-tungstengraphics-dot-com> | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/fb.h> | ||
35 | #include "vermilion.h" | ||
36 | |||
37 | /* The PLL Clock register sits on Host bridge */ | ||
38 | #define CRVML_DEVICE_MCH 0x5001 | ||
39 | #define CRVML_REG_MCHBAR 0x44 | ||
40 | #define CRVML_REG_MCHEN 0x54 | ||
41 | #define CRVML_MCHEN_BIT (1 << 28) | ||
42 | #define CRVML_MCHMAP_SIZE 4096 | ||
43 | #define CRVML_REG_CLOCK 0xc3c | ||
44 | #define CRVML_CLOCK_SHIFT 8 | ||
45 | #define CRVML_CLOCK_MASK 0x00000f00 | ||
46 | |||
47 | static struct pci_dev *mch_dev; | ||
48 | static u32 mch_bar; | ||
49 | static void __iomem *mch_regs_base; | ||
50 | static u32 saved_clock; | ||
51 | |||
52 | static const unsigned crvml_clocks[] = { | ||
53 | 6750, | ||
54 | 13500, | ||
55 | 27000, | ||
56 | 29700, | ||
57 | 37125, | ||
58 | 54000, | ||
59 | 59400, | ||
60 | 74250, | ||
61 | 120000 | ||
62 | /* | ||
63 | * There are more clocks, but they are disabled on the CR board. | ||
64 | */ | ||
65 | }; | ||
66 | |||
67 | static const u32 crvml_clock_bits[] = { | ||
68 | 0x0a, | ||
69 | 0x09, | ||
70 | 0x08, | ||
71 | 0x07, | ||
72 | 0x06, | ||
73 | 0x05, | ||
74 | 0x04, | ||
75 | 0x03, | ||
76 | 0x0b | ||
77 | }; | ||
78 | |||
79 | static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks); | ||
80 | |||
81 | static int crvml_sys_restore(struct vml_sys *sys) | ||
82 | { | ||
83 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
84 | |||
85 | iowrite32(saved_clock, clock_reg); | ||
86 | ioread32(clock_reg); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int crvml_sys_save(struct vml_sys *sys) | ||
92 | { | ||
93 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
94 | |||
95 | saved_clock = ioread32(clock_reg); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int crvml_nearest_index(const struct vml_sys *sys, int clock) | ||
101 | { | ||
102 | int i; | ||
103 | int cur_index = 0; | ||
104 | int cur_diff; | ||
105 | int diff; | ||
106 | |||
107 | cur_diff = clock - crvml_clocks[0]; | ||
108 | cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; | ||
109 | for (i = 1; i < crvml_num_clocks; ++i) { | ||
110 | diff = clock - crvml_clocks[i]; | ||
111 | diff = (diff < 0) ? -diff : diff; | ||
112 | if (diff < cur_diff) { | ||
113 | cur_index = i; | ||
114 | cur_diff = diff; | ||
115 | } | ||
116 | } | ||
117 | return cur_index; | ||
118 | } | ||
119 | |||
120 | static int crvml_nearest_clock(const struct vml_sys *sys, int clock) | ||
121 | { | ||
122 | return crvml_clocks[crvml_nearest_index(sys, clock)]; | ||
123 | } | ||
124 | |||
125 | static int crvml_set_clock(struct vml_sys *sys, int clock) | ||
126 | { | ||
127 | void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK; | ||
128 | int index; | ||
129 | u32 clock_val; | ||
130 | |||
131 | index = crvml_nearest_index(sys, clock); | ||
132 | |||
133 | if (crvml_clocks[index] != clock) | ||
134 | return -EINVAL; | ||
135 | |||
136 | clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK; | ||
137 | clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT; | ||
138 | iowrite32(clock_val, clock_reg); | ||
139 | ioread32(clock_reg); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static struct vml_sys cr_pll_ops = { | ||
145 | .name = "Carillo Ranch", | ||
146 | .save = crvml_sys_save, | ||
147 | .restore = crvml_sys_restore, | ||
148 | .set_clock = crvml_set_clock, | ||
149 | .nearest_clock = crvml_nearest_clock, | ||
150 | }; | ||
151 | |||
152 | static int __init cr_pll_init(void) | ||
153 | { | ||
154 | int err; | ||
155 | u32 dev_en; | ||
156 | |||
157 | mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
158 | CRVML_DEVICE_MCH, NULL); | ||
159 | if (!mch_dev) { | ||
160 | printk(KERN_ERR | ||
161 | "Could not find Carillo Ranch MCH device.\n"); | ||
162 | return -ENODEV; | ||
163 | } | ||
164 | |||
165 | pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en); | ||
166 | if (!(dev_en & CRVML_MCHEN_BIT)) { | ||
167 | printk(KERN_ERR | ||
168 | "Carillo Ranch MCH device was not enabled.\n"); | ||
169 | pci_dev_put(mch_dev); | ||
170 | return -ENODEV; | ||
171 | } | ||
172 | |||
173 | pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR, | ||
174 | &mch_bar); | ||
175 | mch_regs_base = | ||
176 | ioremap_nocache(mch_bar, CRVML_MCHMAP_SIZE); | ||
177 | if (!mch_regs_base) { | ||
178 | printk(KERN_ERR | ||
179 | "Carillo Ranch MCH device was not enabled.\n"); | ||
180 | pci_dev_put(mch_dev); | ||
181 | return -ENODEV; | ||
182 | } | ||
183 | |||
184 | err = vmlfb_register_subsys(&cr_pll_ops); | ||
185 | if (err) { | ||
186 | printk(KERN_ERR | ||
187 | "Carillo Ranch failed to initialize vml_sys.\n"); | ||
188 | pci_dev_put(mch_dev); | ||
189 | return err; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void __exit cr_pll_exit(void) | ||
196 | { | ||
197 | vmlfb_unregister_subsys(&cr_pll_ops); | ||
198 | |||
199 | iounmap(mch_regs_base); | ||
200 | pci_dev_put(mch_dev); | ||
201 | } | ||
202 | |||
203 | module_init(cr_pll_init); | ||
204 | module_exit(cr_pll_exit); | ||
205 | |||
206 | MODULE_AUTHOR("Tungsten Graphics Inc."); | ||
207 | MODULE_DESCRIPTION("Carillo Ranch PLL Driver"); | ||
208 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c new file mode 100644 index 000000000000..de531c907718 --- /dev/null +++ b/drivers/video/vermilion/vermilion.c | |||
@@ -0,0 +1,1195 @@ | |||
1 | /* | ||
2 | * Copyright (c) Intel Corp. 2007. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||
6 | * develop this driver. | ||
7 | * | ||
8 | * This file is part of the Vermilion Range fb driver. | ||
9 | * The Vermilion Range fb driver is free software; | ||
10 | * you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * The Vermilion Range fb driver is distributed | ||
16 | * in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this driver; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellström <thomas-at-tungstengraphics-dot-com> | ||
27 | * Michel Dänzer <michel-at-tungstengraphics-dot-com> | ||
28 | * Alan Hourihane <alanh-at-tungstengraphics-dot-com> | ||
29 | */ | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/mm.h> | ||
37 | #include <linux/fb.h> | ||
38 | #include <linux/pci.h> | ||
39 | #include <asm/cacheflush.h> | ||
40 | #include <asm/tlbflush.h> | ||
41 | #include <linux/mmzone.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | /* #define VERMILION_DEBUG */ | ||
45 | |||
46 | #include "vermilion.h" | ||
47 | |||
48 | #define MODULE_NAME "vmlfb" | ||
49 | |||
50 | #define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) | ||
51 | |||
52 | static struct mutex vml_mutex; | ||
53 | static struct list_head global_no_mode; | ||
54 | static struct list_head global_has_mode; | ||
55 | static struct fb_ops vmlfb_ops; | ||
56 | static struct vml_sys *subsys = NULL; | ||
57 | static char *vml_default_mode = "1024x768@60"; | ||
58 | static struct fb_videomode defaultmode = { | ||
59 | NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6, | ||
60 | 0, FB_VMODE_NONINTERLACED | ||
61 | }; | ||
62 | |||
63 | static u32 vml_mem_requested = (10 * 1024 * 1024); | ||
64 | static u32 vml_mem_contig = (4 * 1024 * 1024); | ||
65 | static u32 vml_mem_min = (4 * 1024 * 1024); | ||
66 | |||
67 | static u32 vml_clocks[] = { | ||
68 | 6750, | ||
69 | 13500, | ||
70 | 27000, | ||
71 | 29700, | ||
72 | 37125, | ||
73 | 54000, | ||
74 | 59400, | ||
75 | 74250, | ||
76 | 120000, | ||
77 | 148500 | ||
78 | }; | ||
79 | |||
80 | static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks); | ||
81 | |||
82 | /* | ||
83 | * Allocate a contiguous vram area and make its linear kernel map | ||
84 | * uncached. | ||
85 | */ | ||
86 | |||
87 | static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order, | ||
88 | unsigned min_order) | ||
89 | { | ||
90 | gfp_t flags; | ||
91 | unsigned long i; | ||
92 | pgprot_t wc_pageprot; | ||
93 | |||
94 | wc_pageprot = PAGE_KERNEL_NOCACHE; | ||
95 | max_order++; | ||
96 | do { | ||
97 | /* | ||
98 | * Really try hard to get the needed memory. | ||
99 | * We need memory below the first 32MB, so we | ||
100 | * add the __GFP_DMA flag that guarantees that we are | ||
101 | * below the first 16MB. | ||
102 | */ | ||
103 | |||
104 | flags = __GFP_DMA | __GFP_HIGH; | ||
105 | va->logical = | ||
106 | __get_free_pages(flags, --max_order); | ||
107 | } while (va->logical == 0 && max_order > min_order); | ||
108 | |||
109 | if (!va->logical) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | va->phys = virt_to_phys((void *)va->logical); | ||
113 | va->size = PAGE_SIZE << max_order; | ||
114 | va->order = max_order; | ||
115 | |||
116 | /* | ||
117 | * It seems like __get_free_pages only ups the usage count | ||
118 | * of the first page. This doesn't work with nopage mapping, so | ||
119 | * up the usage count once more. | ||
120 | */ | ||
121 | |||
122 | memset((void *)va->logical, 0x00, va->size); | ||
123 | for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) { | ||
124 | get_page(virt_to_page(i)); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Change caching policy of the linear kernel map to avoid | ||
129 | * mapping type conflicts with user-space mappings. | ||
130 | * The first global_flush_tlb() is really only there to do a global | ||
131 | * wbinvd(). | ||
132 | */ | ||
133 | |||
134 | global_flush_tlb(); | ||
135 | change_page_attr(virt_to_page(va->logical), va->size >> PAGE_SHIFT, | ||
136 | wc_pageprot); | ||
137 | global_flush_tlb(); | ||
138 | |||
139 | printk(KERN_DEBUG MODULE_NAME | ||
140 | ": Allocated %ld bytes vram area at 0x%08lx\n", | ||
141 | va->size, va->phys); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Free a contiguous vram area and reset its linear kernel map | ||
148 | * mapping type. | ||
149 | */ | ||
150 | |||
151 | static void vmlfb_free_vram_area(struct vram_area *va) | ||
152 | { | ||
153 | unsigned long j; | ||
154 | |||
155 | if (va->logical) { | ||
156 | |||
157 | /* | ||
158 | * Reset the linear kernel map caching policy. | ||
159 | */ | ||
160 | |||
161 | change_page_attr(virt_to_page(va->logical), | ||
162 | va->size >> PAGE_SHIFT, PAGE_KERNEL); | ||
163 | global_flush_tlb(); | ||
164 | |||
165 | /* | ||
166 | * Decrease the usage count on the pages we've used | ||
167 | * to compensate for upping when allocating. | ||
168 | */ | ||
169 | |||
170 | for (j = va->logical; j < va->logical + va->size; | ||
171 | j += PAGE_SIZE) { | ||
172 | (void)put_page_testzero(virt_to_page(j)); | ||
173 | } | ||
174 | |||
175 | printk(KERN_DEBUG MODULE_NAME | ||
176 | ": Freeing %ld bytes vram area at 0x%08lx\n", | ||
177 | va->size, va->phys); | ||
178 | free_pages(va->logical, va->order); | ||
179 | |||
180 | va->logical = 0; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Free allocated vram. | ||
186 | */ | ||
187 | |||
188 | static void vmlfb_free_vram(struct vml_info *vinfo) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | for (i = 0; i < vinfo->num_areas; ++i) { | ||
193 | vmlfb_free_vram_area(&vinfo->vram[i]); | ||
194 | } | ||
195 | vinfo->num_areas = 0; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Allocate vram. Currently we try to allocate contiguous areas from the | ||
200 | * __GFP_DMA zone and puzzle them together. A better approach would be to | ||
201 | * allocate one contiguous area for scanout and use one-page allocations for | ||
202 | * offscreen areas. This requires user-space and GPU virtual mappings. | ||
203 | */ | ||
204 | |||
205 | static int vmlfb_alloc_vram(struct vml_info *vinfo, | ||
206 | size_t requested, | ||
207 | size_t min_total, size_t min_contig) | ||
208 | { | ||
209 | int i, j; | ||
210 | int order; | ||
211 | int contiguous; | ||
212 | int err; | ||
213 | struct vram_area *va; | ||
214 | struct vram_area *va2; | ||
215 | |||
216 | vinfo->num_areas = 0; | ||
217 | for (i = 0; i < VML_VRAM_AREAS; ++i) { | ||
218 | va = &vinfo->vram[i]; | ||
219 | order = 0; | ||
220 | |||
221 | while (requested > (PAGE_SIZE << order) && order < MAX_ORDER) | ||
222 | order++; | ||
223 | |||
224 | err = vmlfb_alloc_vram_area(va, order, 0); | ||
225 | |||
226 | if (err) | ||
227 | break; | ||
228 | |||
229 | if (i == 0) { | ||
230 | vinfo->vram_start = va->phys; | ||
231 | vinfo->vram_logical = (void __iomem *) va->logical; | ||
232 | vinfo->vram_contig_size = va->size; | ||
233 | vinfo->num_areas = 1; | ||
234 | } else { | ||
235 | contiguous = 0; | ||
236 | |||
237 | for (j = 0; j < i; ++j) { | ||
238 | va2 = &vinfo->vram[j]; | ||
239 | if (va->phys + va->size == va2->phys || | ||
240 | va2->phys + va2->size == va->phys) { | ||
241 | contiguous = 1; | ||
242 | break; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | if (contiguous) { | ||
247 | vinfo->num_areas++; | ||
248 | if (va->phys < vinfo->vram_start) { | ||
249 | vinfo->vram_start = va->phys; | ||
250 | vinfo->vram_logical = | ||
251 | (void __iomem *)va->logical; | ||
252 | } | ||
253 | vinfo->vram_contig_size += va->size; | ||
254 | } else { | ||
255 | vmlfb_free_vram_area(va); | ||
256 | break; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | if (requested < va->size) | ||
261 | break; | ||
262 | else | ||
263 | requested -= va->size; | ||
264 | } | ||
265 | |||
266 | if (vinfo->vram_contig_size > min_total && | ||
267 | vinfo->vram_contig_size > min_contig) { | ||
268 | |||
269 | printk(KERN_DEBUG MODULE_NAME | ||
270 | ": Contiguous vram: %ld bytes at physical 0x%08lx.\n", | ||
271 | (unsigned long)vinfo->vram_contig_size, | ||
272 | (unsigned long)vinfo->vram_start); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | printk(KERN_ERR MODULE_NAME | ||
278 | ": Could not allocate requested minimal amount of vram.\n"); | ||
279 | |||
280 | vmlfb_free_vram(vinfo); | ||
281 | |||
282 | return -ENOMEM; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Find the GPU to use with our display controller. | ||
287 | */ | ||
288 | |||
289 | static int vmlfb_get_gpu(struct vml_par *par) | ||
290 | { | ||
291 | mutex_lock(&vml_mutex); | ||
292 | |||
293 | par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL); | ||
294 | |||
295 | if (!par->gpu) { | ||
296 | mutex_unlock(&vml_mutex); | ||
297 | return -ENODEV; | ||
298 | } | ||
299 | |||
300 | mutex_unlock(&vml_mutex); | ||
301 | |||
302 | if (pci_enable_device(par->gpu) < 0) | ||
303 | return -ENODEV; | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * Find a contiguous vram area that contains a given offset from vram start. | ||
310 | */ | ||
311 | static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset) | ||
312 | { | ||
313 | unsigned long aoffset; | ||
314 | unsigned i; | ||
315 | |||
316 | for (i = 0; i < vinfo->num_areas; ++i) { | ||
317 | aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start); | ||
318 | |||
319 | if (aoffset < vinfo->vram[i].size) { | ||
320 | return 0; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | return -EINVAL; | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * Remap the MMIO register spaces of the VDC and the GPU. | ||
329 | */ | ||
330 | |||
331 | static int vmlfb_enable_mmio(struct vml_par *par) | ||
332 | { | ||
333 | int err; | ||
334 | |||
335 | par->vdc_mem_base = pci_resource_start(par->vdc, 0); | ||
336 | par->vdc_mem_size = pci_resource_len(par->vdc, 0); | ||
337 | if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) { | ||
338 | printk(KERN_ERR MODULE_NAME | ||
339 | ": Could not claim display controller MMIO.\n"); | ||
340 | return -EBUSY; | ||
341 | } | ||
342 | par->vdc_mem = ioremap_nocache(par->vdc_mem_base, par->vdc_mem_size); | ||
343 | if (par->vdc_mem == NULL) { | ||
344 | printk(KERN_ERR MODULE_NAME | ||
345 | ": Could not map display controller MMIO.\n"); | ||
346 | err = -ENOMEM; | ||
347 | goto out_err_0; | ||
348 | } | ||
349 | |||
350 | par->gpu_mem_base = pci_resource_start(par->gpu, 0); | ||
351 | par->gpu_mem_size = pci_resource_len(par->gpu, 0); | ||
352 | if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) { | ||
353 | printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n"); | ||
354 | err = -EBUSY; | ||
355 | goto out_err_1; | ||
356 | } | ||
357 | par->gpu_mem = ioremap_nocache(par->gpu_mem_base, par->gpu_mem_size); | ||
358 | if (par->gpu_mem == NULL) { | ||
359 | printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n"); | ||
360 | err = -ENOMEM; | ||
361 | goto out_err_2; | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | |||
366 | out_err_2: | ||
367 | release_mem_region(par->gpu_mem_base, par->gpu_mem_size); | ||
368 | out_err_1: | ||
369 | iounmap(par->vdc_mem); | ||
370 | out_err_0: | ||
371 | release_mem_region(par->vdc_mem_base, par->vdc_mem_size); | ||
372 | return err; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Unmap the VDC and GPU register spaces. | ||
377 | */ | ||
378 | |||
379 | static void vmlfb_disable_mmio(struct vml_par *par) | ||
380 | { | ||
381 | iounmap(par->gpu_mem); | ||
382 | release_mem_region(par->gpu_mem_base, par->gpu_mem_size); | ||
383 | iounmap(par->vdc_mem); | ||
384 | release_mem_region(par->vdc_mem_base, par->vdc_mem_size); | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * Release and uninit the VDC and GPU. | ||
389 | */ | ||
390 | |||
391 | static void vmlfb_release_devices(struct vml_par *par) | ||
392 | { | ||
393 | if (atomic_dec_and_test(&par->refcount)) { | ||
394 | pci_set_drvdata(par->vdc, NULL); | ||
395 | pci_disable_device(par->gpu); | ||
396 | pci_disable_device(par->vdc); | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * Free up allocated resources for a device. | ||
402 | */ | ||
403 | |||
404 | static void __devexit vml_pci_remove(struct pci_dev *dev) | ||
405 | { | ||
406 | struct fb_info *info; | ||
407 | struct vml_info *vinfo; | ||
408 | struct vml_par *par; | ||
409 | |||
410 | info = pci_get_drvdata(dev); | ||
411 | if (info) { | ||
412 | vinfo = container_of(info, struct vml_info, info); | ||
413 | par = vinfo->par; | ||
414 | mutex_lock(&vml_mutex); | ||
415 | unregister_framebuffer(info); | ||
416 | fb_dealloc_cmap(&info->cmap); | ||
417 | vmlfb_free_vram(vinfo); | ||
418 | vmlfb_disable_mmio(par); | ||
419 | vmlfb_release_devices(par); | ||
420 | kfree(vinfo); | ||
421 | kfree(par); | ||
422 | mutex_unlock(&vml_mutex); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var) | ||
427 | { | ||
428 | switch (var->bits_per_pixel) { | ||
429 | case 16: | ||
430 | var->blue.offset = 0; | ||
431 | var->blue.length = 5; | ||
432 | var->green.offset = 5; | ||
433 | var->green.length = 5; | ||
434 | var->red.offset = 10; | ||
435 | var->red.length = 5; | ||
436 | var->transp.offset = 15; | ||
437 | var->transp.length = 1; | ||
438 | break; | ||
439 | case 32: | ||
440 | var->blue.offset = 0; | ||
441 | var->blue.length = 8; | ||
442 | var->green.offset = 8; | ||
443 | var->green.length = 8; | ||
444 | var->red.offset = 16; | ||
445 | var->red.length = 8; | ||
446 | var->transp.offset = 24; | ||
447 | var->transp.length = 0; | ||
448 | break; | ||
449 | default: | ||
450 | break; | ||
451 | } | ||
452 | |||
453 | var->blue.msb_right = var->green.msb_right = | ||
454 | var->red.msb_right = var->transp.msb_right = 0; | ||
455 | } | ||
456 | |||
457 | /* | ||
458 | * Device initialization. | ||
459 | * We initialize one vml_par struct per device and one vml_info | ||
460 | * struct per pipe. Currently we have only one pipe. | ||
461 | */ | ||
462 | |||
463 | static int __devinit vml_pci_probe(struct pci_dev *dev, | ||
464 | const struct pci_device_id *id) | ||
465 | { | ||
466 | struct vml_info *vinfo; | ||
467 | struct fb_info *info; | ||
468 | struct vml_par *par; | ||
469 | int err = 0; | ||
470 | |||
471 | par = kzalloc(sizeof(*par), GFP_KERNEL); | ||
472 | if (par == NULL) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL); | ||
476 | if (vinfo == NULL) { | ||
477 | err = -ENOMEM; | ||
478 | goto out_err_0; | ||
479 | } | ||
480 | |||
481 | vinfo->par = par; | ||
482 | par->vdc = dev; | ||
483 | atomic_set(&par->refcount, 1); | ||
484 | |||
485 | switch (id->device) { | ||
486 | case VML_DEVICE_VDC: | ||
487 | if ((err = vmlfb_get_gpu(par))) | ||
488 | goto out_err_1; | ||
489 | pci_set_drvdata(dev, &vinfo->info); | ||
490 | break; | ||
491 | default: | ||
492 | err = -ENODEV; | ||
493 | goto out_err_1; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | info = &vinfo->info; | ||
498 | info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK; | ||
499 | |||
500 | err = vmlfb_enable_mmio(par); | ||
501 | if (err) | ||
502 | goto out_err_2; | ||
503 | |||
504 | err = vmlfb_alloc_vram(vinfo, vml_mem_requested, | ||
505 | vml_mem_contig, vml_mem_min); | ||
506 | if (err) | ||
507 | goto out_err_3; | ||
508 | |||
509 | strcpy(info->fix.id, "Vermilion Range"); | ||
510 | info->fix.mmio_start = 0; | ||
511 | info->fix.mmio_len = 0; | ||
512 | info->fix.smem_start = vinfo->vram_start; | ||
513 | info->fix.smem_len = vinfo->vram_contig_size; | ||
514 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
515 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
516 | info->fix.ypanstep = 1; | ||
517 | info->fix.xpanstep = 1; | ||
518 | info->fix.ywrapstep = 0; | ||
519 | info->fix.accel = FB_ACCEL_NONE; | ||
520 | info->screen_base = vinfo->vram_logical; | ||
521 | info->pseudo_palette = vinfo->pseudo_palette; | ||
522 | info->par = par; | ||
523 | info->fbops = &vmlfb_ops; | ||
524 | info->device = &dev->dev; | ||
525 | |||
526 | INIT_LIST_HEAD(&vinfo->head); | ||
527 | vinfo->pipe_disabled = 1; | ||
528 | vinfo->cur_blank_mode = FB_BLANK_UNBLANK; | ||
529 | |||
530 | info->var.grayscale = 0; | ||
531 | info->var.bits_per_pixel = 16; | ||
532 | vmlfb_set_pref_pixel_format(&info->var); | ||
533 | |||
534 | if (!fb_find_mode | ||
535 | (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) { | ||
536 | printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n"); | ||
537 | } | ||
538 | |||
539 | if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) { | ||
540 | err = -ENOMEM; | ||
541 | goto out_err_4; | ||
542 | } | ||
543 | |||
544 | err = register_framebuffer(info); | ||
545 | if (err) { | ||
546 | printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n"); | ||
547 | goto out_err_5; | ||
548 | } | ||
549 | |||
550 | printk("Initialized vmlfb\n"); | ||
551 | |||
552 | return 0; | ||
553 | |||
554 | out_err_5: | ||
555 | fb_dealloc_cmap(&info->cmap); | ||
556 | out_err_4: | ||
557 | vmlfb_free_vram(vinfo); | ||
558 | out_err_3: | ||
559 | vmlfb_disable_mmio(par); | ||
560 | out_err_2: | ||
561 | vmlfb_release_devices(par); | ||
562 | out_err_1: | ||
563 | kfree(vinfo); | ||
564 | out_err_0: | ||
565 | kfree(par); | ||
566 | return err; | ||
567 | } | ||
568 | |||
569 | static int vmlfb_open(struct fb_info *info, int user) | ||
570 | { | ||
571 | /* | ||
572 | * Save registers here? | ||
573 | */ | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int vmlfb_release(struct fb_info *info, int user) | ||
578 | { | ||
579 | /* | ||
580 | * Restore registers here. | ||
581 | */ | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int vml_nearest_clock(int clock) | ||
587 | { | ||
588 | |||
589 | int i; | ||
590 | int cur_index; | ||
591 | int cur_diff; | ||
592 | int diff; | ||
593 | |||
594 | cur_index = 0; | ||
595 | cur_diff = clock - vml_clocks[0]; | ||
596 | cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff; | ||
597 | for (i = 1; i < vml_num_clocks; ++i) { | ||
598 | diff = clock - vml_clocks[i]; | ||
599 | diff = (diff < 0) ? -diff : diff; | ||
600 | if (diff < cur_diff) { | ||
601 | cur_index = i; | ||
602 | cur_diff = diff; | ||
603 | } | ||
604 | } | ||
605 | return vml_clocks[cur_index]; | ||
606 | } | ||
607 | |||
608 | static int vmlfb_check_var_locked(struct fb_var_screeninfo *var, | ||
609 | struct vml_info *vinfo) | ||
610 | { | ||
611 | u32 pitch; | ||
612 | u64 mem; | ||
613 | int nearest_clock; | ||
614 | int clock; | ||
615 | int clock_diff; | ||
616 | struct fb_var_screeninfo v; | ||
617 | |||
618 | v = *var; | ||
619 | clock = PICOS2KHZ(var->pixclock); | ||
620 | |||
621 | if (subsys && subsys->nearest_clock) { | ||
622 | nearest_clock = subsys->nearest_clock(subsys, clock); | ||
623 | } else { | ||
624 | nearest_clock = vml_nearest_clock(clock); | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Accept a 20% diff. | ||
629 | */ | ||
630 | |||
631 | clock_diff = nearest_clock - clock; | ||
632 | clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff; | ||
633 | if (clock_diff > clock / 5) { | ||
634 | #if 0 | ||
635 | printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock); | ||
636 | #endif | ||
637 | return -EINVAL; | ||
638 | } | ||
639 | |||
640 | v.pixclock = KHZ2PICOS(nearest_clock); | ||
641 | |||
642 | if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) { | ||
643 | printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n"); | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) { | ||
647 | printk(KERN_DEBUG MODULE_NAME | ||
648 | ": Virtual resolution failure.\n"); | ||
649 | return -EINVAL; | ||
650 | } | ||
651 | switch (v.bits_per_pixel) { | ||
652 | case 0 ... 16: | ||
653 | v.bits_per_pixel = 16; | ||
654 | break; | ||
655 | case 17 ... 32: | ||
656 | v.bits_per_pixel = 32; | ||
657 | break; | ||
658 | default: | ||
659 | printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n", | ||
660 | var->bits_per_pixel); | ||
661 | return -EINVAL; | ||
662 | } | ||
663 | |||
664 | pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F); | ||
665 | mem = pitch * var->yres_virtual; | ||
666 | if (mem > vinfo->vram_contig_size) { | ||
667 | return -ENOMEM; | ||
668 | } | ||
669 | |||
670 | switch (v.bits_per_pixel) { | ||
671 | case 16: | ||
672 | if (var->blue.offset != 0 || | ||
673 | var->blue.length != 5 || | ||
674 | var->green.offset != 5 || | ||
675 | var->green.length != 5 || | ||
676 | var->red.offset != 10 || | ||
677 | var->red.length != 5 || | ||
678 | var->transp.offset != 15 || var->transp.length != 1) { | ||
679 | vmlfb_set_pref_pixel_format(&v); | ||
680 | } | ||
681 | break; | ||
682 | case 32: | ||
683 | if (var->blue.offset != 0 || | ||
684 | var->blue.length != 8 || | ||
685 | var->green.offset != 8 || | ||
686 | var->green.length != 8 || | ||
687 | var->red.offset != 16 || | ||
688 | var->red.length != 8 || | ||
689 | (var->transp.length != 0 && var->transp.length != 8) || | ||
690 | (var->transp.length == 8 && var->transp.offset != 24)) { | ||
691 | vmlfb_set_pref_pixel_format(&v); | ||
692 | } | ||
693 | break; | ||
694 | default: | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | |||
698 | *var = v; | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
704 | { | ||
705 | struct vml_info *vinfo = container_of(info, struct vml_info, info); | ||
706 | int ret; | ||
707 | |||
708 | mutex_lock(&vml_mutex); | ||
709 | ret = vmlfb_check_var_locked(var, vinfo); | ||
710 | mutex_unlock(&vml_mutex); | ||
711 | |||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | static void vml_wait_vblank(struct vml_info *vinfo) | ||
716 | { | ||
717 | /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ | ||
718 | mdelay(20); | ||
719 | } | ||
720 | |||
721 | static void vmlfb_disable_pipe(struct vml_info *vinfo) | ||
722 | { | ||
723 | struct vml_par *par = vinfo->par; | ||
724 | |||
725 | /* Disable the MDVO pad */ | ||
726 | VML_WRITE32(par, VML_RCOMPSTAT, 0); | ||
727 | while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ; | ||
728 | |||
729 | /* Disable display planes */ | ||
730 | VML_WRITE32(par, VML_DSPCCNTR, | ||
731 | VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE); | ||
732 | (void)VML_READ32(par, VML_DSPCCNTR); | ||
733 | /* Wait for vblank for the disable to take effect */ | ||
734 | vml_wait_vblank(vinfo); | ||
735 | |||
736 | /* Next, disable display pipes */ | ||
737 | VML_WRITE32(par, VML_PIPEACONF, 0); | ||
738 | (void)VML_READ32(par, VML_PIPEACONF); | ||
739 | |||
740 | vinfo->pipe_disabled = 1; | ||
741 | } | ||
742 | |||
743 | #ifdef VERMILION_DEBUG | ||
744 | static void vml_dump_regs(struct vml_info *vinfo) | ||
745 | { | ||
746 | struct vml_par *par = vinfo->par; | ||
747 | |||
748 | printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n"); | ||
749 | printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n", | ||
750 | (unsigned)VML_READ32(par, VML_HTOTAL_A)); | ||
751 | printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n", | ||
752 | (unsigned)VML_READ32(par, VML_HBLANK_A)); | ||
753 | printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n", | ||
754 | (unsigned)VML_READ32(par, VML_HSYNC_A)); | ||
755 | printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n", | ||
756 | (unsigned)VML_READ32(par, VML_VTOTAL_A)); | ||
757 | printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n", | ||
758 | (unsigned)VML_READ32(par, VML_VBLANK_A)); | ||
759 | printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n", | ||
760 | (unsigned)VML_READ32(par, VML_VSYNC_A)); | ||
761 | printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n", | ||
762 | (unsigned)VML_READ32(par, VML_DSPCSTRIDE)); | ||
763 | printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n", | ||
764 | (unsigned)VML_READ32(par, VML_DSPCSIZE)); | ||
765 | printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n", | ||
766 | (unsigned)VML_READ32(par, VML_DSPCPOS)); | ||
767 | printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n", | ||
768 | (unsigned)VML_READ32(par, VML_DSPARB)); | ||
769 | printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n", | ||
770 | (unsigned)VML_READ32(par, VML_DSPCADDR)); | ||
771 | printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n", | ||
772 | (unsigned)VML_READ32(par, VML_BCLRPAT_A)); | ||
773 | printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n", | ||
774 | (unsigned)VML_READ32(par, VML_CANVSCLR_A)); | ||
775 | printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n", | ||
776 | (unsigned)VML_READ32(par, VML_PIPEASRC)); | ||
777 | printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n", | ||
778 | (unsigned)VML_READ32(par, VML_PIPEACONF)); | ||
779 | printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n", | ||
780 | (unsigned)VML_READ32(par, VML_DSPCCNTR)); | ||
781 | printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n", | ||
782 | (unsigned)VML_READ32(par, VML_RCOMPSTAT)); | ||
783 | printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n"); | ||
784 | } | ||
785 | #endif | ||
786 | |||
787 | static int vmlfb_set_par_locked(struct vml_info *vinfo) | ||
788 | { | ||
789 | struct vml_par *par = vinfo->par; | ||
790 | struct fb_info *info = &vinfo->info; | ||
791 | struct fb_var_screeninfo *var = &info->var; | ||
792 | u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end; | ||
793 | u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end; | ||
794 | u32 dspcntr; | ||
795 | int clock; | ||
796 | |||
797 | vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; | ||
798 | vinfo->stride = | ||
799 | __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F); | ||
800 | info->fix.line_length = vinfo->stride; | ||
801 | |||
802 | if (!subsys) | ||
803 | return 0; | ||
804 | |||
805 | htotal = | ||
806 | var->xres + var->right_margin + var->hsync_len + var->left_margin; | ||
807 | hactive = var->xres; | ||
808 | hblank_start = var->xres; | ||
809 | hblank_end = htotal; | ||
810 | hsync_start = hactive + var->right_margin; | ||
811 | hsync_end = hsync_start + var->hsync_len; | ||
812 | |||
813 | vtotal = | ||
814 | var->yres + var->lower_margin + var->vsync_len + var->upper_margin; | ||
815 | vactive = var->yres; | ||
816 | vblank_start = var->yres; | ||
817 | vblank_end = vtotal; | ||
818 | vsync_start = vactive + var->lower_margin; | ||
819 | vsync_end = vsync_start + var->vsync_len; | ||
820 | |||
821 | dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS; | ||
822 | clock = PICOS2KHZ(var->pixclock); | ||
823 | |||
824 | if (subsys->nearest_clock) { | ||
825 | clock = subsys->nearest_clock(subsys, clock); | ||
826 | } else { | ||
827 | clock = vml_nearest_clock(clock); | ||
828 | } | ||
829 | printk(KERN_DEBUG MODULE_NAME | ||
830 | ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal, | ||
831 | ((clock / htotal) * 1000) / vtotal); | ||
832 | |||
833 | switch (var->bits_per_pixel) { | ||
834 | case 16: | ||
835 | dspcntr |= VML_GFX_ARGB1555; | ||
836 | break; | ||
837 | case 32: | ||
838 | if (var->transp.length == 8) | ||
839 | dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT; | ||
840 | else | ||
841 | dspcntr |= VML_GFX_RGB0888; | ||
842 | break; | ||
843 | default: | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | |||
847 | vmlfb_disable_pipe(vinfo); | ||
848 | mb(); | ||
849 | |||
850 | if (subsys->set_clock) | ||
851 | subsys->set_clock(subsys, clock); | ||
852 | else | ||
853 | return -EINVAL; | ||
854 | |||
855 | VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1)); | ||
856 | VML_WRITE32(par, VML_HBLANK_A, | ||
857 | ((hblank_end - 1) << 16) | (hblank_start - 1)); | ||
858 | VML_WRITE32(par, VML_HSYNC_A, | ||
859 | ((hsync_end - 1) << 16) | (hsync_start - 1)); | ||
860 | VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1)); | ||
861 | VML_WRITE32(par, VML_VBLANK_A, | ||
862 | ((vblank_end - 1) << 16) | (vblank_start - 1)); | ||
863 | VML_WRITE32(par, VML_VSYNC_A, | ||
864 | ((vsync_end - 1) << 16) | (vsync_start - 1)); | ||
865 | VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride); | ||
866 | VML_WRITE32(par, VML_DSPCSIZE, | ||
867 | ((var->yres - 1) << 16) | (var->xres - 1)); | ||
868 | VML_WRITE32(par, VML_DSPCPOS, 0x00000000); | ||
869 | VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT); | ||
870 | VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000); | ||
871 | VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000); | ||
872 | VML_WRITE32(par, VML_PIPEASRC, | ||
873 | ((var->xres - 1) << 16) | (var->yres - 1)); | ||
874 | |||
875 | wmb(); | ||
876 | VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE); | ||
877 | wmb(); | ||
878 | VML_WRITE32(par, VML_DSPCCNTR, dspcntr); | ||
879 | wmb(); | ||
880 | VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + | ||
881 | var->yoffset * vinfo->stride + | ||
882 | var->xoffset * vinfo->bytes_per_pixel); | ||
883 | |||
884 | VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE); | ||
885 | |||
886 | while (!(VML_READ32(par, VML_RCOMPSTAT) & | ||
887 | (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ; | ||
888 | |||
889 | vinfo->pipe_disabled = 0; | ||
890 | #ifdef VERMILION_DEBUG | ||
891 | vml_dump_regs(vinfo); | ||
892 | #endif | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static int vmlfb_set_par(struct fb_info *info) | ||
898 | { | ||
899 | struct vml_info *vinfo = container_of(info, struct vml_info, info); | ||
900 | int ret; | ||
901 | |||
902 | mutex_lock(&vml_mutex); | ||
903 | list_del(&vinfo->head); | ||
904 | list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode); | ||
905 | ret = vmlfb_set_par_locked(vinfo); | ||
906 | |||
907 | mutex_unlock(&vml_mutex); | ||
908 | return ret; | ||
909 | } | ||
910 | |||
911 | static int vmlfb_blank_locked(struct vml_info *vinfo) | ||
912 | { | ||
913 | struct vml_par *par = vinfo->par; | ||
914 | u32 cur = VML_READ32(par, VML_PIPEACONF); | ||
915 | |||
916 | switch (vinfo->cur_blank_mode) { | ||
917 | case FB_BLANK_UNBLANK: | ||
918 | if (vinfo->pipe_disabled) { | ||
919 | vmlfb_set_par_locked(vinfo); | ||
920 | } | ||
921 | VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER); | ||
922 | (void)VML_READ32(par, VML_PIPEACONF); | ||
923 | break; | ||
924 | case FB_BLANK_NORMAL: | ||
925 | if (vinfo->pipe_disabled) { | ||
926 | vmlfb_set_par_locked(vinfo); | ||
927 | } | ||
928 | VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER); | ||
929 | (void)VML_READ32(par, VML_PIPEACONF); | ||
930 | break; | ||
931 | case FB_BLANK_VSYNC_SUSPEND: | ||
932 | case FB_BLANK_HSYNC_SUSPEND: | ||
933 | if (!vinfo->pipe_disabled) { | ||
934 | vmlfb_disable_pipe(vinfo); | ||
935 | } | ||
936 | break; | ||
937 | case FB_BLANK_POWERDOWN: | ||
938 | if (!vinfo->pipe_disabled) { | ||
939 | vmlfb_disable_pipe(vinfo); | ||
940 | } | ||
941 | break; | ||
942 | default: | ||
943 | return -EINVAL; | ||
944 | } | ||
945 | |||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static int vmlfb_blank(int blank_mode, struct fb_info *info) | ||
950 | { | ||
951 | struct vml_info *vinfo = container_of(info, struct vml_info, info); | ||
952 | int ret; | ||
953 | |||
954 | mutex_lock(&vml_mutex); | ||
955 | vinfo->cur_blank_mode = blank_mode; | ||
956 | ret = vmlfb_blank_locked(vinfo); | ||
957 | mutex_unlock(&vml_mutex); | ||
958 | return ret; | ||
959 | } | ||
960 | |||
961 | static int vmlfb_pan_display(struct fb_var_screeninfo *var, | ||
962 | struct fb_info *info) | ||
963 | { | ||
964 | struct vml_info *vinfo = container_of(info, struct vml_info, info); | ||
965 | struct vml_par *par = vinfo->par; | ||
966 | |||
967 | mutex_lock(&vml_mutex); | ||
968 | VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start + | ||
969 | var->yoffset * vinfo->stride + | ||
970 | var->xoffset * vinfo->bytes_per_pixel); | ||
971 | (void)VML_READ32(par, VML_DSPCADDR); | ||
972 | mutex_unlock(&vml_mutex); | ||
973 | |||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | ||
978 | u_int transp, struct fb_info *info) | ||
979 | { | ||
980 | u32 v; | ||
981 | |||
982 | if (regno >= 16) | ||
983 | return -EINVAL; | ||
984 | |||
985 | if (info->var.grayscale) { | ||
986 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
987 | } | ||
988 | |||
989 | if (info->fix.visual != FB_VISUAL_TRUECOLOR) | ||
990 | return -EINVAL; | ||
991 | |||
992 | red = VML_TOHW(red, info->var.red.length); | ||
993 | blue = VML_TOHW(blue, info->var.blue.length); | ||
994 | green = VML_TOHW(green, info->var.green.length); | ||
995 | transp = VML_TOHW(transp, info->var.transp.length); | ||
996 | |||
997 | v = (red << info->var.red.offset) | | ||
998 | (green << info->var.green.offset) | | ||
999 | (blue << info->var.blue.offset) | | ||
1000 | (transp << info->var.transp.offset); | ||
1001 | |||
1002 | switch (info->var.bits_per_pixel) { | ||
1003 | case 16: | ||
1004 | ((u32 *) info->pseudo_palette)[regno] = v; | ||
1005 | break; | ||
1006 | case 24: | ||
1007 | case 32: | ||
1008 | ((u32 *) info->pseudo_palette)[regno] = v; | ||
1009 | break; | ||
1010 | } | ||
1011 | return 0; | ||
1012 | } | ||
1013 | |||
1014 | static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
1015 | { | ||
1016 | struct vml_info *vinfo = container_of(info, struct vml_info, info); | ||
1017 | unsigned long size = vma->vm_end - vma->vm_start; | ||
1018 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
1019 | int ret; | ||
1020 | |||
1021 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) | ||
1022 | return -EINVAL; | ||
1023 | if (offset + size > vinfo->vram_contig_size) | ||
1024 | return -EINVAL; | ||
1025 | ret = vmlfb_vram_offset(vinfo, offset); | ||
1026 | if (ret) | ||
1027 | return -EINVAL; | ||
1028 | offset += vinfo->vram_start; | ||
1029 | pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; | ||
1030 | pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; | ||
1031 | vma->vm_flags |= VM_RESERVED | VM_IO; | ||
1032 | if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, | ||
1033 | size, vma->vm_page_prot)) | ||
1034 | return -EAGAIN; | ||
1035 | return 0; | ||
1036 | } | ||
1037 | |||
1038 | static int vmlfb_sync(struct fb_info *info) | ||
1039 | { | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
1044 | { | ||
1045 | return -EINVAL; /* just to force soft_cursor() call */ | ||
1046 | } | ||
1047 | |||
1048 | static struct fb_ops vmlfb_ops = { | ||
1049 | .owner = THIS_MODULE, | ||
1050 | .fb_open = vmlfb_open, | ||
1051 | .fb_release = vmlfb_release, | ||
1052 | .fb_check_var = vmlfb_check_var, | ||
1053 | .fb_set_par = vmlfb_set_par, | ||
1054 | .fb_blank = vmlfb_blank, | ||
1055 | .fb_pan_display = vmlfb_pan_display, | ||
1056 | .fb_fillrect = cfb_fillrect, | ||
1057 | .fb_copyarea = cfb_copyarea, | ||
1058 | .fb_imageblit = cfb_imageblit, | ||
1059 | .fb_cursor = vmlfb_cursor, | ||
1060 | .fb_sync = vmlfb_sync, | ||
1061 | .fb_mmap = vmlfb_mmap, | ||
1062 | .fb_setcolreg = vmlfb_setcolreg | ||
1063 | }; | ||
1064 | |||
1065 | static struct pci_device_id vml_ids[] = { | ||
1066 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)}, | ||
1067 | {0} | ||
1068 | }; | ||
1069 | |||
1070 | static struct pci_driver vmlfb_pci_driver = { | ||
1071 | .name = "vmlfb", | ||
1072 | .id_table = vml_ids, | ||
1073 | .probe = vml_pci_probe, | ||
1074 | .remove = __devexit_p(vml_pci_remove) | ||
1075 | }; | ||
1076 | |||
1077 | static void __exit vmlfb_cleanup(void) | ||
1078 | { | ||
1079 | pci_unregister_driver(&vmlfb_pci_driver); | ||
1080 | } | ||
1081 | |||
1082 | static int __init vmlfb_init(void) | ||
1083 | { | ||
1084 | |||
1085 | #ifndef MODULE | ||
1086 | char *option = NULL; | ||
1087 | |||
1088 | if (fb_get_options(MODULE_NAME, &option)) | ||
1089 | return -ENODEV; | ||
1090 | #endif | ||
1091 | |||
1092 | printk(KERN_DEBUG MODULE_NAME ": initializing\n"); | ||
1093 | mutex_init(&vml_mutex); | ||
1094 | INIT_LIST_HEAD(&global_no_mode); | ||
1095 | INIT_LIST_HEAD(&global_has_mode); | ||
1096 | |||
1097 | return pci_register_driver(&vmlfb_pci_driver); | ||
1098 | } | ||
1099 | |||
1100 | int vmlfb_register_subsys(struct vml_sys *sys) | ||
1101 | { | ||
1102 | struct vml_info *entry; | ||
1103 | struct list_head *list; | ||
1104 | u32 save_activate; | ||
1105 | |||
1106 | mutex_lock(&vml_mutex); | ||
1107 | if (subsys != NULL) { | ||
1108 | subsys->restore(subsys); | ||
1109 | } | ||
1110 | subsys = sys; | ||
1111 | subsys->save(subsys); | ||
1112 | |||
1113 | /* | ||
1114 | * We need to restart list traversal for each item, since we | ||
1115 | * release the list mutex in the loop. | ||
1116 | */ | ||
1117 | |||
1118 | list = global_no_mode.next; | ||
1119 | while (list != &global_no_mode) { | ||
1120 | list_del_init(list); | ||
1121 | entry = list_entry(list, struct vml_info, head); | ||
1122 | |||
1123 | /* | ||
1124 | * First, try the current mode which might not be | ||
1125 | * completely validated with respect to the pixel clock. | ||
1126 | */ | ||
1127 | |||
1128 | if (!vmlfb_check_var_locked(&entry->info.var, entry)) { | ||
1129 | vmlfb_set_par_locked(entry); | ||
1130 | list_add_tail(list, &global_has_mode); | ||
1131 | } else { | ||
1132 | |||
1133 | /* | ||
1134 | * Didn't work. Try to find another mode, | ||
1135 | * that matches this subsys. | ||
1136 | */ | ||
1137 | |||
1138 | mutex_unlock(&vml_mutex); | ||
1139 | save_activate = entry->info.var.activate; | ||
1140 | entry->info.var.bits_per_pixel = 16; | ||
1141 | vmlfb_set_pref_pixel_format(&entry->info.var); | ||
1142 | if (fb_find_mode(&entry->info.var, | ||
1143 | &entry->info, | ||
1144 | vml_default_mode, NULL, 0, NULL, 16)) { | ||
1145 | entry->info.var.activate |= | ||
1146 | FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; | ||
1147 | fb_set_var(&entry->info, &entry->info.var); | ||
1148 | } else { | ||
1149 | printk(KERN_ERR MODULE_NAME | ||
1150 | ": Sorry. no mode found for this subsys.\n"); | ||
1151 | } | ||
1152 | entry->info.var.activate = save_activate; | ||
1153 | mutex_lock(&vml_mutex); | ||
1154 | } | ||
1155 | vmlfb_blank_locked(entry); | ||
1156 | list = global_no_mode.next; | ||
1157 | } | ||
1158 | mutex_unlock(&vml_mutex); | ||
1159 | |||
1160 | printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n", | ||
1161 | subsys->name ? subsys->name : "unknown"); | ||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | EXPORT_SYMBOL_GPL(vmlfb_register_subsys); | ||
1166 | |||
1167 | void vmlfb_unregister_subsys(struct vml_sys *sys) | ||
1168 | { | ||
1169 | struct vml_info *entry, *next; | ||
1170 | |||
1171 | mutex_lock(&vml_mutex); | ||
1172 | if (subsys != sys) { | ||
1173 | mutex_unlock(&vml_mutex); | ||
1174 | return; | ||
1175 | } | ||
1176 | subsys->restore(subsys); | ||
1177 | subsys = NULL; | ||
1178 | list_for_each_entry_safe(entry, next, &global_has_mode, head) { | ||
1179 | printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n"); | ||
1180 | vmlfb_disable_pipe(entry); | ||
1181 | list_del(&entry->head); | ||
1182 | list_add_tail(&entry->head, &global_no_mode); | ||
1183 | } | ||
1184 | mutex_unlock(&vml_mutex); | ||
1185 | } | ||
1186 | |||
1187 | EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys); | ||
1188 | |||
1189 | module_init(vmlfb_init); | ||
1190 | module_exit(vmlfb_cleanup); | ||
1191 | |||
1192 | MODULE_AUTHOR("Tungsten Graphics"); | ||
1193 | MODULE_DESCRIPTION("Initialization of the Vermilion display devices"); | ||
1194 | MODULE_VERSION("1.0.0"); | ||
1195 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h new file mode 100644 index 000000000000..1fc6695a49d2 --- /dev/null +++ b/drivers/video/vermilion/vermilion.h | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * Copyright (c) Intel Corp. 2007. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to | ||
6 | * develop this driver. | ||
7 | * | ||
8 | * This file is part of the Vermilion Range fb driver. | ||
9 | * The Vermilion Range fb driver is free software; | ||
10 | * you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * The Vermilion Range fb driver is distributed | ||
16 | * in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this driver; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Authors: | ||
26 | * Thomas Hellström <thomas-at-tungstengraphics-dot-com> | ||
27 | */ | ||
28 | |||
29 | #ifndef _VERMILION_H_ | ||
30 | #define _VERMILION_H_ | ||
31 | |||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/version.h> | ||
34 | #include <linux/pci.h> | ||
35 | #include <asm/atomic.h> | ||
36 | #include <linux/mutex.h> | ||
37 | |||
38 | #define VML_DEVICE_GPU 0x5002 | ||
39 | #define VML_DEVICE_VDC 0x5009 | ||
40 | |||
41 | #define VML_VRAM_AREAS 3 | ||
42 | #define VML_MAX_XRES 1024 | ||
43 | #define VML_MAX_YRES 768 | ||
44 | #define VML_MAX_XRES_VIRTUAL 1040 | ||
45 | |||
46 | /* | ||
47 | * Display controller registers: | ||
48 | */ | ||
49 | |||
50 | /* Display controller 10-bit color representation */ | ||
51 | |||
52 | #define VML_R_MASK 0x3FF00000 | ||
53 | #define VML_R_SHIFT 20 | ||
54 | #define VML_G_MASK 0x000FFC00 | ||
55 | #define VML_G_SHIFT 10 | ||
56 | #define VML_B_MASK 0x000003FF | ||
57 | #define VML_B_SHIFT 0 | ||
58 | |||
59 | /* Graphics plane control */ | ||
60 | #define VML_DSPCCNTR 0x00072180 | ||
61 | #define VML_GFX_ENABLE 0x80000000 | ||
62 | #define VML_GFX_GAMMABYPASS 0x40000000 | ||
63 | #define VML_GFX_ARGB1555 0x0C000000 | ||
64 | #define VML_GFX_RGB0888 0x18000000 | ||
65 | #define VML_GFX_ARGB8888 0x1C000000 | ||
66 | #define VML_GFX_ALPHACONST 0x02000000 | ||
67 | #define VML_GFX_ALPHAMULT 0x01000000 | ||
68 | #define VML_GFX_CONST_ALPHA 0x000000FF | ||
69 | |||
70 | /* Graphics plane start address. Pixel aligned. */ | ||
71 | #define VML_DSPCADDR 0x00072184 | ||
72 | |||
73 | /* Graphics plane stride register. */ | ||
74 | #define VML_DSPCSTRIDE 0x00072188 | ||
75 | |||
76 | /* Graphics plane position register. */ | ||
77 | #define VML_DSPCPOS 0x0007218C | ||
78 | #define VML_POS_YMASK 0x0FFF0000 | ||
79 | #define VML_POS_YSHIFT 16 | ||
80 | #define VML_POS_XMASK 0x00000FFF | ||
81 | #define VML_POS_XSHIFT 0 | ||
82 | |||
83 | /* Graphics plane height and width */ | ||
84 | #define VML_DSPCSIZE 0x00072190 | ||
85 | #define VML_SIZE_HMASK 0x0FFF0000 | ||
86 | #define VML_SIZE_HSHIFT 16 | ||
87 | #define VML_SISE_WMASK 0x00000FFF | ||
88 | #define VML_SIZE_WSHIFT 0 | ||
89 | |||
90 | /* Graphics plane gamma correction lookup table registers (129 * 32 bits) */ | ||
91 | #define VML_DSPCGAMLUT 0x00072200 | ||
92 | |||
93 | /* Pixel video output configuration register */ | ||
94 | #define VML_PVOCONFIG 0x00061140 | ||
95 | #define VML_CONFIG_BASE 0x80000000 | ||
96 | #define VML_CONFIG_PIXEL_SWAP 0x04000000 | ||
97 | #define VML_CONFIG_DE_INV 0x01000000 | ||
98 | #define VML_CONFIG_HREF_INV 0x00400000 | ||
99 | #define VML_CONFIG_VREF_INV 0x00100000 | ||
100 | #define VML_CONFIG_CLK_INV 0x00040000 | ||
101 | #define VML_CONFIG_CLK_DIV2 0x00010000 | ||
102 | #define VML_CONFIG_ESTRB_INV 0x00008000 | ||
103 | |||
104 | /* Pipe A Horizontal total register */ | ||
105 | #define VML_HTOTAL_A 0x00060000 | ||
106 | #define VML_HTOTAL_MASK 0x1FFF0000 | ||
107 | #define VML_HTOTAL_SHIFT 16 | ||
108 | #define VML_HTOTAL_VAL 8192 | ||
109 | #define VML_HACTIVE_MASK 0x000007FF | ||
110 | #define VML_HACTIVE_SHIFT 0 | ||
111 | #define VML_HACTIVE_VAL 4096 | ||
112 | |||
113 | /* Pipe A Horizontal Blank register */ | ||
114 | #define VML_HBLANK_A 0x00060004 | ||
115 | #define VML_HBLANK_END_MASK 0x1FFF0000 | ||
116 | #define VML_HBLANK_END_SHIFT 16 | ||
117 | #define VML_HBLANK_END_VAL 8192 | ||
118 | #define VML_HBLANK_START_MASK 0x00001FFF | ||
119 | #define VML_HBLANK_START_SHIFT 0 | ||
120 | #define VML_HBLANK_START_VAL 8192 | ||
121 | |||
122 | /* Pipe A Horizontal Sync register */ | ||
123 | #define VML_HSYNC_A 0x00060008 | ||
124 | #define VML_HSYNC_END_MASK 0x1FFF0000 | ||
125 | #define VML_HSYNC_END_SHIFT 16 | ||
126 | #define VML_HSYNC_END_VAL 8192 | ||
127 | #define VML_HSYNC_START_MASK 0x00001FFF | ||
128 | #define VML_HSYNC_START_SHIFT 0 | ||
129 | #define VML_HSYNC_START_VAL 8192 | ||
130 | |||
131 | /* Pipe A Vertical total register */ | ||
132 | #define VML_VTOTAL_A 0x0006000C | ||
133 | #define VML_VTOTAL_MASK 0x1FFF0000 | ||
134 | #define VML_VTOTAL_SHIFT 16 | ||
135 | #define VML_VTOTAL_VAL 8192 | ||
136 | #define VML_VACTIVE_MASK 0x000007FF | ||
137 | #define VML_VACTIVE_SHIFT 0 | ||
138 | #define VML_VACTIVE_VAL 4096 | ||
139 | |||
140 | /* Pipe A Vertical Blank register */ | ||
141 | #define VML_VBLANK_A 0x00060010 | ||
142 | #define VML_VBLANK_END_MASK 0x1FFF0000 | ||
143 | #define VML_VBLANK_END_SHIFT 16 | ||
144 | #define VML_VBLANK_END_VAL 8192 | ||
145 | #define VML_VBLANK_START_MASK 0x00001FFF | ||
146 | #define VML_VBLANK_START_SHIFT 0 | ||
147 | #define VML_VBLANK_START_VAL 8192 | ||
148 | |||
149 | /* Pipe A Vertical Sync register */ | ||
150 | #define VML_VSYNC_A 0x00060014 | ||
151 | #define VML_VSYNC_END_MASK 0x1FFF0000 | ||
152 | #define VML_VSYNC_END_SHIFT 16 | ||
153 | #define VML_VSYNC_END_VAL 8192 | ||
154 | #define VML_VSYNC_START_MASK 0x00001FFF | ||
155 | #define VML_VSYNC_START_SHIFT 0 | ||
156 | #define VML_VSYNC_START_VAL 8192 | ||
157 | |||
158 | /* Pipe A Source Image size (minus one - equal to active size) | ||
159 | * Programmable while pipe is enabled. | ||
160 | */ | ||
161 | #define VML_PIPEASRC 0x0006001C | ||
162 | #define VML_PIPEASRC_HMASK 0x0FFF0000 | ||
163 | #define VML_PIPEASRC_HSHIFT 16 | ||
164 | #define VML_PIPEASRC_VMASK 0x00000FFF | ||
165 | #define VML_PIPEASRC_VSHIFT 0 | ||
166 | |||
167 | /* Pipe A Border Color Pattern register (10 bit color) */ | ||
168 | #define VML_BCLRPAT_A 0x00060020 | ||
169 | |||
170 | /* Pipe A Canvas Color register (10 bit color) */ | ||
171 | #define VML_CANVSCLR_A 0x00060024 | ||
172 | |||
173 | /* Pipe A Configuration register */ | ||
174 | #define VML_PIPEACONF 0x00070008 | ||
175 | #define VML_PIPE_BASE 0x00000000 | ||
176 | #define VML_PIPE_ENABLE 0x80000000 | ||
177 | #define VML_PIPE_FORCE_BORDER 0x02000000 | ||
178 | #define VML_PIPE_PLANES_OFF 0x00080000 | ||
179 | #define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000 | ||
180 | |||
181 | /* Pipe A FIFO setting */ | ||
182 | #define VML_DSPARB 0x00070030 | ||
183 | #define VML_FIFO_DEFAULT 0x00001D9C | ||
184 | |||
185 | /* MDVO rcomp status & pads control register */ | ||
186 | #define VML_RCOMPSTAT 0x00070048 | ||
187 | #define VML_MDVO_VDC_I_RCOMP 0x80000000 | ||
188 | #define VML_MDVO_POWERSAVE_OFF 0x00000008 | ||
189 | #define VML_MDVO_PAD_ENABLE 0x00000004 | ||
190 | #define VML_MDVO_PULLDOWN_ENABLE 0x00000001 | ||
191 | |||
192 | struct vml_par { | ||
193 | struct pci_dev *vdc; | ||
194 | u64 vdc_mem_base; | ||
195 | u64 vdc_mem_size; | ||
196 | char __iomem *vdc_mem; | ||
197 | |||
198 | struct pci_dev *gpu; | ||
199 | u64 gpu_mem_base; | ||
200 | u64 gpu_mem_size; | ||
201 | char __iomem *gpu_mem; | ||
202 | |||
203 | atomic_t refcount; | ||
204 | }; | ||
205 | |||
206 | struct vram_area { | ||
207 | unsigned long logical; | ||
208 | unsigned long phys; | ||
209 | unsigned long size; | ||
210 | unsigned order; | ||
211 | }; | ||
212 | |||
213 | struct vml_info { | ||
214 | struct fb_info info; | ||
215 | struct vml_par *par; | ||
216 | struct list_head head; | ||
217 | struct vram_area vram[VML_VRAM_AREAS]; | ||
218 | u64 vram_start; | ||
219 | u64 vram_contig_size; | ||
220 | u32 num_areas; | ||
221 | void __iomem *vram_logical; | ||
222 | u32 pseudo_palette[16]; | ||
223 | u32 stride; | ||
224 | u32 bytes_per_pixel; | ||
225 | atomic_t vmas; | ||
226 | int cur_blank_mode; | ||
227 | int pipe_disabled; | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * Subsystem | ||
232 | */ | ||
233 | |||
234 | struct vml_sys { | ||
235 | char *name; | ||
236 | |||
237 | /* | ||
238 | * Save / Restore; | ||
239 | */ | ||
240 | |||
241 | int (*save) (struct vml_sys * sys); | ||
242 | int (*restore) (struct vml_sys * sys); | ||
243 | |||
244 | /* | ||
245 | * PLL programming; | ||
246 | */ | ||
247 | |||
248 | int (*set_clock) (struct vml_sys * sys, int clock); | ||
249 | int (*nearest_clock) (const struct vml_sys * sys, int clock); | ||
250 | }; | ||
251 | |||
252 | extern int vmlfb_register_subsys(struct vml_sys *sys); | ||
253 | extern void vmlfb_unregister_subsys(struct vml_sys *sys); | ||
254 | |||
255 | #define VML_READ32(_par, _offset) \ | ||
256 | (ioread32((_par)->vdc_mem + (_offset))) | ||
257 | #define VML_WRITE32(_par, _offset, _value) \ | ||
258 | iowrite32(_value, (_par)->vdc_mem + (_offset)) | ||
259 | |||
260 | #endif | ||
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index a9b99b01bd8e..64ee78c3c12b 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c | |||
@@ -84,13 +84,15 @@ static int vfb_mmap(struct fb_info *info, | |||
84 | struct vm_area_struct *vma); | 84 | struct vm_area_struct *vma); |
85 | 85 | ||
86 | static struct fb_ops vfb_ops = { | 86 | static struct fb_ops vfb_ops = { |
87 | .fb_read = fb_sys_read, | ||
88 | .fb_write = fb_sys_write, | ||
87 | .fb_check_var = vfb_check_var, | 89 | .fb_check_var = vfb_check_var, |
88 | .fb_set_par = vfb_set_par, | 90 | .fb_set_par = vfb_set_par, |
89 | .fb_setcolreg = vfb_setcolreg, | 91 | .fb_setcolreg = vfb_setcolreg, |
90 | .fb_pan_display = vfb_pan_display, | 92 | .fb_pan_display = vfb_pan_display, |
91 | .fb_fillrect = cfb_fillrect, | 93 | .fb_fillrect = sys_fillrect, |
92 | .fb_copyarea = cfb_copyarea, | 94 | .fb_copyarea = sys_copyarea, |
93 | .fb_imageblit = cfb_imageblit, | 95 | .fb_imageblit = sys_imageblit, |
94 | .fb_mmap = vfb_mmap, | 96 | .fb_mmap = vfb_mmap, |
95 | }; | 97 | }; |
96 | 98 | ||
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index ec4c7dc54a66..2a14d28c4163 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c | |||
@@ -1378,6 +1378,8 @@ static int __init vga16fb_probe(struct platform_device *dev) | |||
1378 | info->fbops = &vga16fb_ops; | 1378 | info->fbops = &vga16fb_ops; |
1379 | info->var = vga16fb_defined; | 1379 | info->var = vga16fb_defined; |
1380 | info->fix = vga16fb_fix; | 1380 | info->fix = vga16fb_fix; |
1381 | /* supports rectangles with widths of multiples of 8 */ | ||
1382 | info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31; | ||
1381 | info->flags = FBINFO_FLAG_DEFAULT | | 1383 | info->flags = FBINFO_FLAG_DEFAULT | |
1382 | FBINFO_HWACCEL_YPAN; | 1384 | FBINFO_HWACCEL_YPAN; |
1383 | 1385 | ||
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index d94efafc77b5..b91c466225b9 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c | |||
@@ -50,23 +50,28 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase) | |||
50 | struct regstate *saved = (struct regstate *) state->vidstate; | 50 | struct regstate *saved = (struct regstate *) state->vidstate; |
51 | int i; | 51 | int i; |
52 | u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4; | 52 | u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4; |
53 | unsigned short iobase; | ||
53 | 54 | ||
54 | /* if in graphics mode, no need to save */ | 55 | /* if in graphics mode, no need to save */ |
56 | misc = vga_r(state->vgabase, VGA_MIS_R); | ||
57 | iobase = (misc & 1) ? 0x3d0 : 0x3b0; | ||
58 | |||
59 | vga_r(state->vgabase, iobase + 0xa); | ||
60 | vga_w(state->vgabase, VGA_ATT_W, 0x00); | ||
55 | attr10 = vga_rattr(state->vgabase, 0x10); | 61 | attr10 = vga_rattr(state->vgabase, 0x10); |
62 | vga_r(state->vgabase, iobase + 0xa); | ||
63 | vga_w(state->vgabase, VGA_ATT_W, 0x20); | ||
64 | |||
56 | if (attr10 & 1) | 65 | if (attr10 & 1) |
57 | return; | 66 | return; |
58 | 67 | ||
59 | /* save regs */ | 68 | /* save regs */ |
60 | misc = vga_r(state->vgabase, VGA_MIS_R); | ||
61 | gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); | 69 | gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); |
62 | gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE); | 70 | gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE); |
63 | gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); | 71 | gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); |
64 | seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); | 72 | seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); |
65 | seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); | 73 | seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); |
66 | 74 | ||
67 | /* force graphics mode */ | ||
68 | vga_w(state->vgabase, VGA_MIS_W, misc | 1); | ||
69 | |||
70 | /* blank screen */ | 75 | /* blank screen */ |
71 | seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); | 76 | seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); |
72 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); | 77 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); |
@@ -115,15 +120,12 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase) | |||
115 | } | 120 | } |
116 | 121 | ||
117 | /* restore regs */ | 122 | /* restore regs */ |
118 | vga_wattr(state->vgabase, 0x10, attr10); | ||
119 | |||
120 | vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); | 123 | vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); |
121 | vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); | 124 | vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); |
122 | 125 | ||
123 | vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); | 126 | vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); |
124 | vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5); | 127 | vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5); |
125 | vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6); | 128 | vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6); |
126 | vga_w(state->vgabase, VGA_MIS_W, misc); | ||
127 | 129 | ||
128 | /* unblank screen */ | 130 | /* unblank screen */ |
129 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); | 131 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); |
@@ -137,11 +139,10 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase) | |||
137 | { | 139 | { |
138 | struct regstate *saved = (struct regstate *) state->vidstate; | 140 | struct regstate *saved = (struct regstate *) state->vidstate; |
139 | int i; | 141 | int i; |
140 | u8 misc, gr1, gr3, gr4, gr5, gr6, gr8; | 142 | u8 gr1, gr3, gr4, gr5, gr6, gr8; |
141 | u8 seq1, seq2, seq4; | 143 | u8 seq1, seq2, seq4; |
142 | 144 | ||
143 | /* save regs */ | 145 | /* save regs */ |
144 | misc = vga_r(state->vgabase, VGA_MIS_R); | ||
145 | gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE); | 146 | gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE); |
146 | gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE); | 147 | gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE); |
147 | gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); | 148 | gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); |
@@ -151,9 +152,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase) | |||
151 | seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); | 152 | seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); |
152 | seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); | 153 | seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); |
153 | 154 | ||
154 | /* force graphics mode */ | ||
155 | vga_w(state->vgabase, VGA_MIS_W, misc | 1); | ||
156 | |||
157 | /* blank screen */ | 155 | /* blank screen */ |
158 | seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); | 156 | seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); |
159 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); | 157 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); |
@@ -213,8 +211,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase) | |||
213 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); | 211 | vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); |
214 | 212 | ||
215 | /* restore regs */ | 213 | /* restore regs */ |
216 | vga_w(state->vgabase, VGA_MIS_W, misc); | ||
217 | |||
218 | vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1); | 214 | vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1); |
219 | vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3); | 215 | vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3); |
220 | vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); | 216 | vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); |
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c new file mode 100644 index 000000000000..1d29a89a86b4 --- /dev/null +++ b/drivers/video/xilinxfb.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * xilinxfb.c | ||
3 | * | ||
4 | * Xilinx TFT LCD frame buffer driver | ||
5 | * | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * source@mvista.com | ||
8 | * | ||
9 | * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the | ||
10 | * terms of the GNU General Public License version 2. This program is licensed | ||
11 | * "as is" without any warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | /* | ||
15 | * This driver was based on au1100fb.c by MontaVista rewritten for 2.6 | ||
16 | * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn | ||
17 | * was based on skeletonfb.c, Skeleton for a frame buffer device by | ||
18 | * Geert Uytterhoeven. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/version.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/mm.h> | ||
27 | #include <linux/fb.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/dma-mapping.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | |||
32 | #include <asm/io.h> | ||
33 | #include <syslib/virtex_devices.h> | ||
34 | |||
35 | #define DRIVER_NAME "xilinxfb" | ||
36 | #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver" | ||
37 | |||
38 | /* | ||
39 | * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for | ||
40 | * the VGA port on the Xilinx ML40x board. This is a hardware display controller | ||
41 | * for a 640x480 resolution TFT or VGA screen. | ||
42 | * | ||
43 | * The interface to the framebuffer is nice and simple. There are two | ||
44 | * control registers. The first tells the LCD interface where in memory | ||
45 | * the frame buffer is (only the 11 most significant bits are used, so | ||
46 | * don't start thinking about scrolling). The second allows the LCD to | ||
47 | * be turned on or off as well as rotated 180 degrees. | ||
48 | */ | ||
49 | #define NUM_REGS 2 | ||
50 | #define REG_FB_ADDR 0 | ||
51 | #define REG_CTRL 1 | ||
52 | #define REG_CTRL_ENABLE 0x0001 | ||
53 | #define REG_CTRL_ROTATE 0x0002 | ||
54 | |||
55 | /* | ||
56 | * The hardware only handles a single mode: 640x480 24 bit true | ||
57 | * color. Each pixel gets a word (32 bits) of memory. Within each word, | ||
58 | * the 8 most significant bits are ignored, the next 8 bits are the red | ||
59 | * level, the next 8 bits are the green level and the 8 least | ||
60 | * significant bits are the blue level. Each row of the LCD uses 1024 | ||
61 | * words, but only the first 640 pixels are displayed with the other 384 | ||
62 | * words being ignored. There are 480 rows. | ||
63 | */ | ||
64 | #define BYTES_PER_PIXEL 4 | ||
65 | #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) | ||
66 | #define XRES 640 | ||
67 | #define YRES 480 | ||
68 | #define XRES_VIRTUAL 1024 | ||
69 | #define YRES_VIRTUAL YRES | ||
70 | #define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL) | ||
71 | #define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH) | ||
72 | |||
73 | #define RED_SHIFT 16 | ||
74 | #define GREEN_SHIFT 8 | ||
75 | #define BLUE_SHIFT 0 | ||
76 | |||
77 | #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ | ||
78 | |||
79 | /* | ||
80 | * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures | ||
81 | */ | ||
82 | static struct fb_fix_screeninfo xilinx_fb_fix __initdata = { | ||
83 | .id = "Xilinx", | ||
84 | .type = FB_TYPE_PACKED_PIXELS, | ||
85 | .visual = FB_VISUAL_TRUECOLOR, | ||
86 | .smem_len = FB_SIZE, | ||
87 | .line_length = LINE_LENGTH, | ||
88 | .accel = FB_ACCEL_NONE | ||
89 | }; | ||
90 | |||
91 | static struct fb_var_screeninfo xilinx_fb_var __initdata = { | ||
92 | .xres = XRES, | ||
93 | .yres = YRES, | ||
94 | .xres_virtual = XRES_VIRTUAL, | ||
95 | .yres_virtual = YRES_VIRTUAL, | ||
96 | |||
97 | .bits_per_pixel = BITS_PER_PIXEL, | ||
98 | |||
99 | .red = { RED_SHIFT, 8, 0 }, | ||
100 | .green = { GREEN_SHIFT, 8, 0 }, | ||
101 | .blue = { BLUE_SHIFT, 8, 0 }, | ||
102 | .transp = { 0, 0, 0 }, | ||
103 | |||
104 | .activate = FB_ACTIVATE_NOW | ||
105 | }; | ||
106 | |||
107 | struct xilinxfb_drvdata { | ||
108 | |||
109 | struct fb_info info; /* FB driver info record */ | ||
110 | |||
111 | u32 regs_phys; /* phys. address of the control registers */ | ||
112 | u32 __iomem *regs; /* virt. address of the control registers */ | ||
113 | |||
114 | unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */ | ||
115 | dma_addr_t fb_phys; /* phys. address of the frame buffer */ | ||
116 | |||
117 | u32 reg_ctrl_default; | ||
118 | |||
119 | u32 pseudo_palette[PALETTE_ENTRIES_NO]; | ||
120 | /* Fake palette of 16 colors */ | ||
121 | }; | ||
122 | |||
123 | #define to_xilinxfb_drvdata(_info) \ | ||
124 | container_of(_info, struct xilinxfb_drvdata, info) | ||
125 | |||
126 | /* | ||
127 | * The LCD controller has DCR interface to its registers, but all | ||
128 | * the boards and configurations the driver has been tested with | ||
129 | * use opb2dcr bridge. So the registers are seen as memory mapped. | ||
130 | * This macro is to make it simple to add the direct DCR access | ||
131 | * when it's needed. | ||
132 | */ | ||
133 | #define xilinx_fb_out_be32(driverdata, offset, val) \ | ||
134 | out_be32(driverdata->regs + offset, val) | ||
135 | |||
136 | static int | ||
137 | xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, | ||
138 | unsigned transp, struct fb_info *fbi) | ||
139 | { | ||
140 | u32 *palette = fbi->pseudo_palette; | ||
141 | |||
142 | if (regno >= PALETTE_ENTRIES_NO) | ||
143 | return -EINVAL; | ||
144 | |||
145 | if (fbi->var.grayscale) { | ||
146 | /* Convert color to grayscale. | ||
147 | * grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
148 | red = green = blue = | ||
149 | (red * 77 + green * 151 + blue * 28 + 127) >> 8; | ||
150 | } | ||
151 | |||
152 | /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */ | ||
153 | |||
154 | /* We only handle 8 bits of each color. */ | ||
155 | red >>= 8; | ||
156 | green >>= 8; | ||
157 | blue >>= 8; | ||
158 | palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) | | ||
159 | (blue << BLUE_SHIFT); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int | ||
165 | xilinx_fb_blank(int blank_mode, struct fb_info *fbi) | ||
166 | { | ||
167 | struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi); | ||
168 | |||
169 | switch (blank_mode) { | ||
170 | case FB_BLANK_UNBLANK: | ||
171 | /* turn on panel */ | ||
172 | xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); | ||
173 | break; | ||
174 | |||
175 | case FB_BLANK_NORMAL: | ||
176 | case FB_BLANK_VSYNC_SUSPEND: | ||
177 | case FB_BLANK_HSYNC_SUSPEND: | ||
178 | case FB_BLANK_POWERDOWN: | ||
179 | /* turn off panel */ | ||
180 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | ||
181 | default: | ||
182 | break; | ||
183 | |||
184 | } | ||
185 | return 0; /* success */ | ||
186 | } | ||
187 | |||
188 | static struct fb_ops xilinxfb_ops = | ||
189 | { | ||
190 | .owner = THIS_MODULE, | ||
191 | .fb_setcolreg = xilinx_fb_setcolreg, | ||
192 | .fb_blank = xilinx_fb_blank, | ||
193 | .fb_fillrect = cfb_fillrect, | ||
194 | .fb_copyarea = cfb_copyarea, | ||
195 | .fb_imageblit = cfb_imageblit, | ||
196 | }; | ||
197 | |||
198 | /* === The device driver === */ | ||
199 | |||
200 | static int | ||
201 | xilinxfb_drv_probe(struct device *dev) | ||
202 | { | ||
203 | struct platform_device *pdev; | ||
204 | struct xilinxfb_platform_data *pdata; | ||
205 | struct xilinxfb_drvdata *drvdata; | ||
206 | struct resource *regs_res; | ||
207 | int retval; | ||
208 | |||
209 | if (!dev) | ||
210 | return -EINVAL; | ||
211 | |||
212 | pdev = to_platform_device(dev); | ||
213 | pdata = pdev->dev.platform_data; | ||
214 | |||
215 | if (pdata == NULL) { | ||
216 | printk(KERN_ERR "Couldn't find platform data.\n"); | ||
217 | return -EFAULT; | ||
218 | } | ||
219 | |||
220 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | ||
221 | if (!drvdata) { | ||
222 | printk(KERN_ERR "Couldn't allocate device private record\n"); | ||
223 | return -ENOMEM; | ||
224 | } | ||
225 | dev_set_drvdata(dev, drvdata); | ||
226 | |||
227 | /* Map the control registers in */ | ||
228 | regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
229 | if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { | ||
230 | printk(KERN_ERR "Couldn't get registers resource\n"); | ||
231 | retval = -EFAULT; | ||
232 | goto failed1; | ||
233 | } | ||
234 | |||
235 | if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { | ||
236 | printk(KERN_ERR | ||
237 | "Couldn't lock memory region at 0x%08X\n", | ||
238 | regs_res->start); | ||
239 | retval = -EBUSY; | ||
240 | goto failed1; | ||
241 | } | ||
242 | drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8); | ||
243 | drvdata->regs_phys = regs_res->start; | ||
244 | |||
245 | /* Allocate the framebuffer memory */ | ||
246 | drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), | ||
247 | &drvdata->fb_phys, GFP_KERNEL); | ||
248 | if (!drvdata->fb_virt) { | ||
249 | printk(KERN_ERR "Could not allocate frame buffer memory\n"); | ||
250 | retval = -ENOMEM; | ||
251 | goto failed2; | ||
252 | } | ||
253 | |||
254 | /* Clear (turn to black) the framebuffer */ | ||
255 | memset_io((void *) drvdata->fb_virt, 0, FB_SIZE); | ||
256 | |||
257 | /* Tell the hardware where the frame buffer is */ | ||
258 | xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); | ||
259 | |||
260 | /* Turn on the display */ | ||
261 | if (pdata->rotate_screen) { | ||
262 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE | REG_CTRL_ROTATE; | ||
263 | } else { | ||
264 | drvdata->reg_ctrl_default = REG_CTRL_ENABLE; | ||
265 | } | ||
266 | xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); | ||
267 | |||
268 | /* Fill struct fb_info */ | ||
269 | drvdata->info.device = dev; | ||
270 | drvdata->info.screen_base = drvdata->fb_virt; | ||
271 | drvdata->info.fbops = &xilinxfb_ops; | ||
272 | drvdata->info.fix = xilinx_fb_fix; | ||
273 | drvdata->info.fix.smem_start = drvdata->fb_phys; | ||
274 | drvdata->info.pseudo_palette = drvdata->pseudo_palette; | ||
275 | |||
276 | if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) { | ||
277 | printk(KERN_ERR "Fail to allocate colormap (%d entries)\n", | ||
278 | PALETTE_ENTRIES_NO); | ||
279 | retval = -EFAULT; | ||
280 | goto failed3; | ||
281 | } | ||
282 | |||
283 | drvdata->info.flags = FBINFO_DEFAULT; | ||
284 | xilinx_fb_var.height = pdata->screen_height_mm; | ||
285 | xilinx_fb_var.width = pdata->screen_width_mm; | ||
286 | drvdata->info.var = xilinx_fb_var; | ||
287 | |||
288 | /* Register new frame buffer */ | ||
289 | if (register_framebuffer(&drvdata->info) < 0) { | ||
290 | printk(KERN_ERR "Could not register frame buffer\n"); | ||
291 | retval = -EINVAL; | ||
292 | goto failed4; | ||
293 | } | ||
294 | |||
295 | return 0; /* success */ | ||
296 | |||
297 | failed4: | ||
298 | fb_dealloc_cmap(&drvdata->info.cmap); | ||
299 | |||
300 | failed3: | ||
301 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | ||
302 | drvdata->fb_phys); | ||
303 | |||
304 | /* Turn off the display */ | ||
305 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | ||
306 | iounmap(drvdata->regs); | ||
307 | |||
308 | failed2: | ||
309 | release_mem_region(regs_res->start, 8); | ||
310 | |||
311 | failed1: | ||
312 | kfree(drvdata); | ||
313 | dev_set_drvdata(dev, NULL); | ||
314 | |||
315 | return retval; | ||
316 | } | ||
317 | |||
318 | static int | ||
319 | xilinxfb_drv_remove(struct device *dev) | ||
320 | { | ||
321 | struct xilinxfb_drvdata *drvdata; | ||
322 | |||
323 | if (!dev) | ||
324 | return -ENODEV; | ||
325 | |||
326 | drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev); | ||
327 | |||
328 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) | ||
329 | xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); | ||
330 | #endif | ||
331 | |||
332 | unregister_framebuffer(&drvdata->info); | ||
333 | |||
334 | fb_dealloc_cmap(&drvdata->info.cmap); | ||
335 | |||
336 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | ||
337 | drvdata->fb_phys); | ||
338 | |||
339 | /* Turn off the display */ | ||
340 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | ||
341 | iounmap(drvdata->regs); | ||
342 | |||
343 | release_mem_region(drvdata->regs_phys, 8); | ||
344 | |||
345 | kfree(drvdata); | ||
346 | dev_set_drvdata(dev, NULL); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | |||
352 | static struct device_driver xilinxfb_driver = { | ||
353 | .name = DRIVER_NAME, | ||
354 | .bus = &platform_bus_type, | ||
355 | |||
356 | .probe = xilinxfb_drv_probe, | ||
357 | .remove = xilinxfb_drv_remove | ||
358 | }; | ||
359 | |||
360 | static int __init | ||
361 | xilinxfb_init(void) | ||
362 | { | ||
363 | /* | ||
364 | * No kernel boot options used, | ||
365 | * so we just need to register the driver | ||
366 | */ | ||
367 | return driver_register(&xilinxfb_driver); | ||
368 | } | ||
369 | |||
370 | static void __exit | ||
371 | xilinxfb_cleanup(void) | ||
372 | { | ||
373 | driver_unregister(&xilinxfb_driver); | ||
374 | } | ||
375 | |||
376 | module_init(xilinxfb_init); | ||
377 | module_exit(xilinxfb_cleanup); | ||
378 | |||
379 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); | ||
380 | MODULE_DESCRIPTION(DRIVER_DESCRIPTION); | ||
381 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index 2fb425536eae..8f779338f744 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig | |||
@@ -35,5 +35,13 @@ config W1_MASTER_DS2482 | |||
35 | This driver can also be built as a module. If so, the module | 35 | This driver can also be built as a module. If so, the module |
36 | will be called ds2482. | 36 | will be called ds2482. |
37 | 37 | ||
38 | config W1_MASTER_DS1WM | ||
39 | tristate "Maxim DS1WM 1-wire busmaster" | ||
40 | depends on W1 && ARM | ||
41 | help | ||
42 | Say Y here to enable the DS1WM 1-wire driver, such as that | ||
43 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like | ||
44 | hx4700. | ||
45 | |||
38 | endmenu | 46 | endmenu |
39 | 47 | ||
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile index 4cee256a8134..11551b328186 100644 --- a/drivers/w1/masters/Makefile +++ b/drivers/w1/masters/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o | 5 | obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o |
6 | obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o | 6 | obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o |
7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o | 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o |
8 | 8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o | |
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c new file mode 100644 index 000000000000..763bc73e5070 --- /dev/null +++ b/drivers/w1/masters/ds1wm.c | |||
@@ -0,0 +1,468 @@ | |||
1 | /* | ||
2 | * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs | ||
3 | * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3 | ||
4 | * like hx4700). | ||
5 | * | ||
6 | * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> | ||
7 | * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net> | ||
8 | * | ||
9 | * Use consistent with the GNU GPL is permitted, | ||
10 | * provided that this copyright notice is | ||
11 | * preserved in its entirety in all copies and derived works. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/ds1wm.h> | ||
22 | |||
23 | #include <asm/io.h> | ||
24 | |||
25 | #include "../w1.h" | ||
26 | #include "../w1_int.h" | ||
27 | |||
28 | |||
29 | #define DS1WM_CMD 0x00 /* R/W 4 bits command */ | ||
30 | #define DS1WM_DATA 0x01 /* R/W 8 bits, transmit/receive buffer */ | ||
31 | #define DS1WM_INT 0x02 /* R/W interrupt status */ | ||
32 | #define DS1WM_INT_EN 0x03 /* R/W interrupt enable */ | ||
33 | #define DS1WM_CLKDIV 0x04 /* R/W 5 bits of divisor and pre-scale */ | ||
34 | |||
35 | #define DS1WM_CMD_1W_RESET (1 << 0) /* force reset on 1-wire bus */ | ||
36 | #define DS1WM_CMD_SRA (1 << 1) /* enable Search ROM accelerator mode */ | ||
37 | #define DS1WM_CMD_DQ_OUTPUT (1 << 2) /* write only - forces bus low */ | ||
38 | #define DS1WM_CMD_DQ_INPUT (1 << 3) /* read only - reflects state of bus */ | ||
39 | #define DS1WM_CMD_RST (1 << 5) /* software reset */ | ||
40 | #define DS1WM_CMD_OD (1 << 7) /* overdrive */ | ||
41 | |||
42 | #define DS1WM_INT_PD (1 << 0) /* presence detect */ | ||
43 | #define DS1WM_INT_PDR (1 << 1) /* presence detect result */ | ||
44 | #define DS1WM_INT_TBE (1 << 2) /* tx buffer empty */ | ||
45 | #define DS1WM_INT_TSRE (1 << 3) /* tx shift register empty */ | ||
46 | #define DS1WM_INT_RBF (1 << 4) /* rx buffer full */ | ||
47 | #define DS1WM_INT_RSRF (1 << 5) /* rx shift register full */ | ||
48 | |||
49 | #define DS1WM_INTEN_EPD (1 << 0) /* enable presence detect int */ | ||
50 | #define DS1WM_INTEN_IAS (1 << 1) /* INTR active state */ | ||
51 | #define DS1WM_INTEN_ETBE (1 << 2) /* enable tx buffer empty int */ | ||
52 | #define DS1WM_INTEN_ETMT (1 << 3) /* enable tx shift register empty int */ | ||
53 | #define DS1WM_INTEN_ERBF (1 << 4) /* enable rx buffer full int */ | ||
54 | #define DS1WM_INTEN_ERSRF (1 << 5) /* enable rx shift register full int */ | ||
55 | #define DS1WM_INTEN_DQO (1 << 6) /* enable direct bus driving ops */ | ||
56 | |||
57 | |||
58 | #define DS1WM_TIMEOUT (HZ * 5) | ||
59 | |||
60 | static struct { | ||
61 | unsigned long freq; | ||
62 | unsigned long divisor; | ||
63 | } freq[] = { | ||
64 | { 4000000, 0x8 }, | ||
65 | { 5000000, 0x2 }, | ||
66 | { 6000000, 0x5 }, | ||
67 | { 7000000, 0x3 }, | ||
68 | { 8000000, 0xc }, | ||
69 | { 10000000, 0x6 }, | ||
70 | { 12000000, 0x9 }, | ||
71 | { 14000000, 0x7 }, | ||
72 | { 16000000, 0x10 }, | ||
73 | { 20000000, 0xa }, | ||
74 | { 24000000, 0xd }, | ||
75 | { 28000000, 0xb }, | ||
76 | { 32000000, 0x14 }, | ||
77 | { 40000000, 0xe }, | ||
78 | { 48000000, 0x11 }, | ||
79 | { 56000000, 0xf }, | ||
80 | { 64000000, 0x18 }, | ||
81 | { 80000000, 0x12 }, | ||
82 | { 96000000, 0x15 }, | ||
83 | { 112000000, 0x13 }, | ||
84 | { 128000000, 0x1c }, | ||
85 | }; | ||
86 | |||
87 | struct ds1wm_data { | ||
88 | void *map; | ||
89 | int bus_shift; /* # of shifts to calc register offsets */ | ||
90 | struct platform_device *pdev; | ||
91 | struct ds1wm_platform_data *pdata; | ||
92 | int irq; | ||
93 | int active_high; | ||
94 | struct clk *clk; | ||
95 | int slave_present; | ||
96 | void *reset_complete; | ||
97 | void *read_complete; | ||
98 | void *write_complete; | ||
99 | u8 read_byte; /* last byte received */ | ||
100 | }; | ||
101 | |||
102 | static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, | ||
103 | u8 val) | ||
104 | { | ||
105 | __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); | ||
106 | } | ||
107 | |||
108 | static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg) | ||
109 | { | ||
110 | return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); | ||
111 | } | ||
112 | |||
113 | |||
114 | static irqreturn_t ds1wm_isr(int isr, void *data) | ||
115 | { | ||
116 | struct ds1wm_data *ds1wm_data = data; | ||
117 | u8 intr = ds1wm_read_register(ds1wm_data, DS1WM_INT); | ||
118 | |||
119 | ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1; | ||
120 | |||
121 | if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete) | ||
122 | complete(ds1wm_data->reset_complete); | ||
123 | |||
124 | if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete) | ||
125 | complete(ds1wm_data->write_complete); | ||
126 | |||
127 | if (intr & DS1WM_INT_RBF) { | ||
128 | ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data, | ||
129 | DS1WM_DATA); | ||
130 | if (ds1wm_data->read_complete) | ||
131 | complete(ds1wm_data->read_complete); | ||
132 | } | ||
133 | |||
134 | return IRQ_HANDLED; | ||
135 | } | ||
136 | |||
137 | static int ds1wm_reset(struct ds1wm_data *ds1wm_data) | ||
138 | { | ||
139 | unsigned long timeleft; | ||
140 | DECLARE_COMPLETION_ONSTACK(reset_done); | ||
141 | |||
142 | ds1wm_data->reset_complete = &reset_done; | ||
143 | |||
144 | ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD | | ||
145 | (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0)); | ||
146 | |||
147 | ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET); | ||
148 | |||
149 | timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT); | ||
150 | ds1wm_data->reset_complete = NULL; | ||
151 | if (!timeleft) { | ||
152 | dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n"); | ||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | /* Wait for the end of the reset. According to the specs, the time | ||
157 | * from when the interrupt is asserted to the end of the reset is: | ||
158 | * tRSTH - tPDH - tPDL - tPDI | ||
159 | * 625 us - 60 us - 240 us - 100 ns = 324.9 us | ||
160 | * | ||
161 | * We'll wait a bit longer just to be sure. | ||
162 | */ | ||
163 | udelay(500); | ||
164 | |||
165 | ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, | ||
166 | DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD | | ||
167 | (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0)); | ||
168 | |||
169 | if (!ds1wm_data->slave_present) { | ||
170 | dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); | ||
171 | return 1; | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data) | ||
178 | { | ||
179 | DECLARE_COMPLETION_ONSTACK(write_done); | ||
180 | ds1wm_data->write_complete = &write_done; | ||
181 | |||
182 | ds1wm_write_register(ds1wm_data, DS1WM_DATA, data); | ||
183 | |||
184 | wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT); | ||
185 | ds1wm_data->write_complete = NULL; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static int ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data) | ||
191 | { | ||
192 | DECLARE_COMPLETION_ONSTACK(read_done); | ||
193 | ds1wm_data->read_complete = &read_done; | ||
194 | |||
195 | ds1wm_write(ds1wm_data, write_data); | ||
196 | wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT); | ||
197 | ds1wm_data->read_complete = NULL; | ||
198 | |||
199 | return ds1wm_data->read_byte; | ||
200 | } | ||
201 | |||
202 | static int ds1wm_find_divisor(int gclk) | ||
203 | { | ||
204 | int i; | ||
205 | |||
206 | for (i = 0; i < ARRAY_SIZE(freq); i++) | ||
207 | if (gclk <= freq[i].freq) | ||
208 | return freq[i].divisor; | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static void ds1wm_up(struct ds1wm_data *ds1wm_data) | ||
214 | { | ||
215 | int gclk, divisor; | ||
216 | |||
217 | if (ds1wm_data->pdata->enable) | ||
218 | ds1wm_data->pdata->enable(ds1wm_data->pdev); | ||
219 | |||
220 | gclk = clk_get_rate(ds1wm_data->clk); | ||
221 | clk_enable(ds1wm_data->clk); | ||
222 | divisor = ds1wm_find_divisor(gclk); | ||
223 | if (divisor == 0) { | ||
224 | dev_err(&ds1wm_data->pdev->dev, | ||
225 | "no suitable divisor for %dHz clock\n", gclk); | ||
226 | return; | ||
227 | } | ||
228 | ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor); | ||
229 | |||
230 | /* Let the w1 clock stabilize. */ | ||
231 | msleep(1); | ||
232 | |||
233 | ds1wm_reset(ds1wm_data); | ||
234 | } | ||
235 | |||
236 | static void ds1wm_down(struct ds1wm_data *ds1wm_data) | ||
237 | { | ||
238 | ds1wm_reset(ds1wm_data); | ||
239 | |||
240 | /* Disable interrupts. */ | ||
241 | ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, | ||
242 | ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0); | ||
243 | |||
244 | if (ds1wm_data->pdata->disable) | ||
245 | ds1wm_data->pdata->disable(ds1wm_data->pdev); | ||
246 | |||
247 | clk_disable(ds1wm_data->clk); | ||
248 | } | ||
249 | |||
250 | /* --------------------------------------------------------------------- */ | ||
251 | /* w1 methods */ | ||
252 | |||
253 | static u8 ds1wm_read_byte(void *data) | ||
254 | { | ||
255 | struct ds1wm_data *ds1wm_data = data; | ||
256 | |||
257 | return ds1wm_read(ds1wm_data, 0xff); | ||
258 | } | ||
259 | |||
260 | static void ds1wm_write_byte(void *data, u8 byte) | ||
261 | { | ||
262 | struct ds1wm_data *ds1wm_data = data; | ||
263 | |||
264 | ds1wm_write(ds1wm_data, byte); | ||
265 | } | ||
266 | |||
267 | static u8 ds1wm_reset_bus(void *data) | ||
268 | { | ||
269 | struct ds1wm_data *ds1wm_data = data; | ||
270 | |||
271 | ds1wm_reset(ds1wm_data); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static void ds1wm_search(void *data, u8 search_type, | ||
277 | w1_slave_found_callback slave_found) | ||
278 | { | ||
279 | struct ds1wm_data *ds1wm_data = data; | ||
280 | int i; | ||
281 | unsigned long long rom_id; | ||
282 | |||
283 | /* XXX We need to iterate for multiple devices per the DS1WM docs. | ||
284 | * See http://www.maxim-ic.com/appnotes.cfm/appnote_number/120. */ | ||
285 | if (ds1wm_reset(ds1wm_data)) | ||
286 | return; | ||
287 | |||
288 | ds1wm_write(ds1wm_data, search_type); | ||
289 | ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA); | ||
290 | |||
291 | for (rom_id = 0, i = 0; i < 16; i++) { | ||
292 | |||
293 | unsigned char resp, r, d; | ||
294 | |||
295 | resp = ds1wm_read(ds1wm_data, 0x00); | ||
296 | |||
297 | r = ((resp & 0x02) >> 1) | | ||
298 | ((resp & 0x08) >> 2) | | ||
299 | ((resp & 0x20) >> 3) | | ||
300 | ((resp & 0x80) >> 4); | ||
301 | |||
302 | d = ((resp & 0x01) >> 0) | | ||
303 | ((resp & 0x04) >> 1) | | ||
304 | ((resp & 0x10) >> 2) | | ||
305 | ((resp & 0x40) >> 3); | ||
306 | |||
307 | rom_id |= (unsigned long long) r << (i * 4); | ||
308 | |||
309 | } | ||
310 | dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id); | ||
311 | |||
312 | ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA); | ||
313 | ds1wm_reset(ds1wm_data); | ||
314 | |||
315 | slave_found(ds1wm_data, rom_id); | ||
316 | } | ||
317 | |||
318 | /* --------------------------------------------------------------------- */ | ||
319 | |||
320 | static struct w1_bus_master ds1wm_master = { | ||
321 | .read_byte = ds1wm_read_byte, | ||
322 | .write_byte = ds1wm_write_byte, | ||
323 | .reset_bus = ds1wm_reset_bus, | ||
324 | .search = ds1wm_search, | ||
325 | }; | ||
326 | |||
327 | static int ds1wm_probe(struct platform_device *pdev) | ||
328 | { | ||
329 | struct ds1wm_data *ds1wm_data; | ||
330 | struct ds1wm_platform_data *plat; | ||
331 | struct resource *res; | ||
332 | int ret; | ||
333 | |||
334 | if (!pdev) | ||
335 | return -ENODEV; | ||
336 | |||
337 | ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL); | ||
338 | if (!ds1wm_data) | ||
339 | return -ENOMEM; | ||
340 | |||
341 | platform_set_drvdata(pdev, ds1wm_data); | ||
342 | |||
343 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
344 | if (!res) { | ||
345 | ret = -ENXIO; | ||
346 | goto err0; | ||
347 | } | ||
348 | ds1wm_data->map = ioremap(res->start, res->end - res->start + 1); | ||
349 | if (!ds1wm_data->map) { | ||
350 | ret = -ENOMEM; | ||
351 | goto err0; | ||
352 | } | ||
353 | plat = pdev->dev.platform_data; | ||
354 | ds1wm_data->bus_shift = plat->bus_shift; | ||
355 | ds1wm_data->pdev = pdev; | ||
356 | ds1wm_data->pdata = plat; | ||
357 | |||
358 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
359 | if (!res) { | ||
360 | ret = -ENXIO; | ||
361 | goto err1; | ||
362 | } | ||
363 | ds1wm_data->irq = res->start; | ||
364 | ds1wm_data->active_high = (res->flags & IORESOURCE_IRQ_HIGHEDGE) ? | ||
365 | 1 : 0; | ||
366 | |||
367 | set_irq_type(ds1wm_data->irq, ds1wm_data->active_high ? | ||
368 | IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING); | ||
369 | |||
370 | ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED, | ||
371 | "ds1wm", ds1wm_data); | ||
372 | if (ret) | ||
373 | goto err1; | ||
374 | |||
375 | ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm"); | ||
376 | if (!ds1wm_data->clk) { | ||
377 | ret = -ENOENT; | ||
378 | goto err2; | ||
379 | } | ||
380 | |||
381 | ds1wm_up(ds1wm_data); | ||
382 | |||
383 | ds1wm_master.data = (void *)ds1wm_data; | ||
384 | |||
385 | ret = w1_add_master_device(&ds1wm_master); | ||
386 | if (ret) | ||
387 | goto err3; | ||
388 | |||
389 | return 0; | ||
390 | |||
391 | err3: | ||
392 | ds1wm_down(ds1wm_data); | ||
393 | clk_put(ds1wm_data->clk); | ||
394 | err2: | ||
395 | free_irq(ds1wm_data->irq, ds1wm_data); | ||
396 | err1: | ||
397 | iounmap(ds1wm_data->map); | ||
398 | err0: | ||
399 | kfree(ds1wm_data); | ||
400 | |||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | #ifdef CONFIG_PM | ||
405 | static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state) | ||
406 | { | ||
407 | struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev); | ||
408 | |||
409 | ds1wm_down(ds1wm_data); | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int ds1wm_resume(struct platform_device *pdev) | ||
415 | { | ||
416 | struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev); | ||
417 | |||
418 | ds1wm_up(ds1wm_data); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | #else | ||
423 | #define ds1wm_suspend NULL | ||
424 | #define ds1wm_resume NULL | ||
425 | #endif | ||
426 | |||
427 | static int ds1wm_remove(struct platform_device *pdev) | ||
428 | { | ||
429 | struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev); | ||
430 | |||
431 | w1_remove_master_device(&ds1wm_master); | ||
432 | ds1wm_down(ds1wm_data); | ||
433 | clk_put(ds1wm_data->clk); | ||
434 | free_irq(ds1wm_data->irq, ds1wm_data); | ||
435 | iounmap(ds1wm_data->map); | ||
436 | kfree(ds1wm_data); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static struct platform_driver ds1wm_driver = { | ||
442 | .driver = { | ||
443 | .name = "ds1wm", | ||
444 | }, | ||
445 | .probe = ds1wm_probe, | ||
446 | .remove = ds1wm_remove, | ||
447 | .suspend = ds1wm_suspend, | ||
448 | .resume = ds1wm_resume | ||
449 | }; | ||
450 | |||
451 | static int __init ds1wm_init(void) | ||
452 | { | ||
453 | printk("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n"); | ||
454 | return platform_driver_register(&ds1wm_driver); | ||
455 | } | ||
456 | |||
457 | static void __exit ds1wm_exit(void) | ||
458 | { | ||
459 | platform_driver_unregister(&ds1wm_driver); | ||
460 | } | ||
461 | |||
462 | module_init(ds1wm_init); | ||
463 | module_exit(ds1wm_exit); | ||
464 | |||
465 | MODULE_LICENSE("GPL"); | ||
466 | MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, " | ||
467 | "Matt Reimer <mreimer@vpop.net>"); | ||
468 | MODULE_DESCRIPTION("DS1WM w1 busmaster driver"); | ||
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 63c07243993c..7d6876dbcc96 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -459,7 +459,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
459 | (unsigned long long) sl->reg_num.id); | 459 | (unsigned long long) sl->reg_num.id); |
460 | 460 | ||
461 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, | 461 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, |
462 | &sl->dev.bus_id[0]); | 462 | &sl->dev.bus_id[0], sl); |
463 | 463 | ||
464 | err = device_register(&sl->dev); | 464 | err = device_register(&sl->dev); |
465 | if (err < 0) { | 465 | if (err < 0) { |
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 357a2e0f637a..258defdb2efd 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
@@ -100,7 +100,8 @@ int w1_add_master_device(struct w1_bus_master *master) | |||
100 | 100 | ||
101 | /* validate minimum functionality */ | 101 | /* validate minimum functionality */ |
102 | if (!(master->touch_bit && master->reset_bus) && | 102 | if (!(master->touch_bit && master->reset_bus) && |
103 | !(master->write_bit && master->read_bit)) { | 103 | !(master->write_bit && master->read_bit) && |
104 | !(master->write_byte && master->read_byte && master->reset_bus)) { | ||
104 | printk(KERN_ERR "w1_add_master_device: invalid function set\n"); | 105 | printk(KERN_ERR "w1_add_master_device: invalid function set\n"); |
105 | return(-EINVAL); | 106 | return(-EINVAL); |
106 | } | 107 | } |