diff options
Diffstat (limited to 'drivers')
28 files changed, 1588 insertions, 312 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 614da5b8613a..e3749d0ba68b 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -3557,67 +3557,65 @@ static ctl_table cdrom_table[] = { | |||
3557 | .data = &cdrom_sysctl_settings.info, | 3557 | .data = &cdrom_sysctl_settings.info, |
3558 | .maxlen = CDROM_STR_SIZE, | 3558 | .maxlen = CDROM_STR_SIZE, |
3559 | .mode = 0444, | 3559 | .mode = 0444, |
3560 | .proc_handler = &cdrom_sysctl_info, | 3560 | .proc_handler = cdrom_sysctl_info, |
3561 | }, | 3561 | }, |
3562 | { | 3562 | { |
3563 | .procname = "autoclose", | 3563 | .procname = "autoclose", |
3564 | .data = &cdrom_sysctl_settings.autoclose, | 3564 | .data = &cdrom_sysctl_settings.autoclose, |
3565 | .maxlen = sizeof(int), | 3565 | .maxlen = sizeof(int), |
3566 | .mode = 0644, | 3566 | .mode = 0644, |
3567 | .proc_handler = &cdrom_sysctl_handler, | 3567 | .proc_handler = cdrom_sysctl_handler, |
3568 | }, | 3568 | }, |
3569 | { | 3569 | { |
3570 | .procname = "autoeject", | 3570 | .procname = "autoeject", |
3571 | .data = &cdrom_sysctl_settings.autoeject, | 3571 | .data = &cdrom_sysctl_settings.autoeject, |
3572 | .maxlen = sizeof(int), | 3572 | .maxlen = sizeof(int), |
3573 | .mode = 0644, | 3573 | .mode = 0644, |
3574 | .proc_handler = &cdrom_sysctl_handler, | 3574 | .proc_handler = cdrom_sysctl_handler, |
3575 | }, | 3575 | }, |
3576 | { | 3576 | { |
3577 | .procname = "debug", | 3577 | .procname = "debug", |
3578 | .data = &cdrom_sysctl_settings.debug, | 3578 | .data = &cdrom_sysctl_settings.debug, |
3579 | .maxlen = sizeof(int), | 3579 | .maxlen = sizeof(int), |
3580 | .mode = 0644, | 3580 | .mode = 0644, |
3581 | .proc_handler = &cdrom_sysctl_handler, | 3581 | .proc_handler = cdrom_sysctl_handler, |
3582 | }, | 3582 | }, |
3583 | { | 3583 | { |
3584 | .procname = "lock", | 3584 | .procname = "lock", |
3585 | .data = &cdrom_sysctl_settings.lock, | 3585 | .data = &cdrom_sysctl_settings.lock, |
3586 | .maxlen = sizeof(int), | 3586 | .maxlen = sizeof(int), |
3587 | .mode = 0644, | 3587 | .mode = 0644, |
3588 | .proc_handler = &cdrom_sysctl_handler, | 3588 | .proc_handler = cdrom_sysctl_handler, |
3589 | }, | 3589 | }, |
3590 | { | 3590 | { |
3591 | .procname = "check_media", | 3591 | .procname = "check_media", |
3592 | .data = &cdrom_sysctl_settings.check, | 3592 | .data = &cdrom_sysctl_settings.check, |
3593 | .maxlen = sizeof(int), | 3593 | .maxlen = sizeof(int), |
3594 | .mode = 0644, | 3594 | .mode = 0644, |
3595 | .proc_handler = &cdrom_sysctl_handler | 3595 | .proc_handler = cdrom_sysctl_handler |
3596 | }, | 3596 | }, |
3597 | { .ctl_name = 0 } | 3597 | { } |
3598 | }; | 3598 | }; |
3599 | 3599 | ||
3600 | static ctl_table cdrom_cdrom_table[] = { | 3600 | static ctl_table cdrom_cdrom_table[] = { |
3601 | { | 3601 | { |
3602 | .ctl_name = DEV_CDROM, | ||
3603 | .procname = "cdrom", | 3602 | .procname = "cdrom", |
3604 | .maxlen = 0, | 3603 | .maxlen = 0, |
3605 | .mode = 0555, | 3604 | .mode = 0555, |
3606 | .child = cdrom_table, | 3605 | .child = cdrom_table, |
3607 | }, | 3606 | }, |
3608 | { .ctl_name = 0 } | 3607 | { } |
3609 | }; | 3608 | }; |
3610 | 3609 | ||
3611 | /* Make sure that /proc/sys/dev is there */ | 3610 | /* Make sure that /proc/sys/dev is there */ |
3612 | static ctl_table cdrom_root_table[] = { | 3611 | static ctl_table cdrom_root_table[] = { |
3613 | { | 3612 | { |
3614 | .ctl_name = CTL_DEV, | ||
3615 | .procname = "dev", | 3613 | .procname = "dev", |
3616 | .maxlen = 0, | 3614 | .maxlen = 0, |
3617 | .mode = 0555, | 3615 | .mode = 0555, |
3618 | .child = cdrom_cdrom_table, | 3616 | .child = cdrom_cdrom_table, |
3619 | }, | 3617 | }, |
3620 | { .ctl_name = 0 } | 3618 | { } |
3621 | }; | 3619 | }; |
3622 | static struct ctl_table_header *cdrom_sysctl_header; | 3620 | static struct ctl_table_header *cdrom_sysctl_header; |
3623 | 3621 | ||
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 70a770ac0138..e481c5938bad 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -675,36 +675,33 @@ static int hpet_is_known(struct hpet_data *hdp) | |||
675 | 675 | ||
676 | static ctl_table hpet_table[] = { | 676 | static ctl_table hpet_table[] = { |
677 | { | 677 | { |
678 | .ctl_name = CTL_UNNUMBERED, | ||
679 | .procname = "max-user-freq", | 678 | .procname = "max-user-freq", |
680 | .data = &hpet_max_freq, | 679 | .data = &hpet_max_freq, |
681 | .maxlen = sizeof(int), | 680 | .maxlen = sizeof(int), |
682 | .mode = 0644, | 681 | .mode = 0644, |
683 | .proc_handler = &proc_dointvec, | 682 | .proc_handler = proc_dointvec, |
684 | }, | 683 | }, |
685 | {.ctl_name = 0} | 684 | {} |
686 | }; | 685 | }; |
687 | 686 | ||
688 | static ctl_table hpet_root[] = { | 687 | static ctl_table hpet_root[] = { |
689 | { | 688 | { |
690 | .ctl_name = CTL_UNNUMBERED, | ||
691 | .procname = "hpet", | 689 | .procname = "hpet", |
692 | .maxlen = 0, | 690 | .maxlen = 0, |
693 | .mode = 0555, | 691 | .mode = 0555, |
694 | .child = hpet_table, | 692 | .child = hpet_table, |
695 | }, | 693 | }, |
696 | {.ctl_name = 0} | 694 | {} |
697 | }; | 695 | }; |
698 | 696 | ||
699 | static ctl_table dev_root[] = { | 697 | static ctl_table dev_root[] = { |
700 | { | 698 | { |
701 | .ctl_name = CTL_DEV, | ||
702 | .procname = "dev", | 699 | .procname = "dev", |
703 | .maxlen = 0, | 700 | .maxlen = 0, |
704 | .mode = 0555, | 701 | .mode = 0555, |
705 | .child = hpet_root, | 702 | .child = hpet_root, |
706 | }, | 703 | }, |
707 | {.ctl_name = 0} | 704 | {} |
708 | }; | 705 | }; |
709 | 706 | ||
710 | static struct ctl_table_header *sysctl_header; | 707 | static struct ctl_table_header *sysctl_header; |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 2e66b5f773dd..0dec5da000ef 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -660,26 +660,23 @@ static struct ipmi_smi_watcher smi_watcher = { | |||
660 | #include <linux/sysctl.h> | 660 | #include <linux/sysctl.h> |
661 | 661 | ||
662 | static ctl_table ipmi_table[] = { | 662 | static ctl_table ipmi_table[] = { |
663 | { .ctl_name = DEV_IPMI_POWEROFF_POWERCYCLE, | 663 | { .procname = "poweroff_powercycle", |
664 | .procname = "poweroff_powercycle", | ||
665 | .data = &poweroff_powercycle, | 664 | .data = &poweroff_powercycle, |
666 | .maxlen = sizeof(poweroff_powercycle), | 665 | .maxlen = sizeof(poweroff_powercycle), |
667 | .mode = 0644, | 666 | .mode = 0644, |
668 | .proc_handler = &proc_dointvec }, | 667 | .proc_handler = proc_dointvec }, |
669 | { } | 668 | { } |
670 | }; | 669 | }; |
671 | 670 | ||
672 | static ctl_table ipmi_dir_table[] = { | 671 | static ctl_table ipmi_dir_table[] = { |
673 | { .ctl_name = DEV_IPMI, | 672 | { .procname = "ipmi", |
674 | .procname = "ipmi", | ||
675 | .mode = 0555, | 673 | .mode = 0555, |
676 | .child = ipmi_table }, | 674 | .child = ipmi_table }, |
677 | { } | 675 | { } |
678 | }; | 676 | }; |
679 | 677 | ||
680 | static ctl_table ipmi_root_table[] = { | 678 | static ctl_table ipmi_root_table[] = { |
681 | { .ctl_name = CTL_DEV, | 679 | { .procname = "dev", |
682 | .procname = "dev", | ||
683 | .mode = 0555, | 680 | .mode = 0555, |
684 | .child = ipmi_dir_table }, | 681 | .child = ipmi_dir_table }, |
685 | { } | 682 | { } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 62f282e67638..d86c0bc05c1c 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -431,30 +431,25 @@ static struct cdev ptmx_cdev; | |||
431 | 431 | ||
432 | static struct ctl_table pty_table[] = { | 432 | static struct ctl_table pty_table[] = { |
433 | { | 433 | { |
434 | .ctl_name = PTY_MAX, | ||
435 | .procname = "max", | 434 | .procname = "max", |
436 | .maxlen = sizeof(int), | 435 | .maxlen = sizeof(int), |
437 | .mode = 0644, | 436 | .mode = 0644, |
438 | .data = &pty_limit, | 437 | .data = &pty_limit, |
439 | .proc_handler = &proc_dointvec_minmax, | 438 | .proc_handler = proc_dointvec_minmax, |
440 | .strategy = &sysctl_intvec, | ||
441 | .extra1 = &pty_limit_min, | 439 | .extra1 = &pty_limit_min, |
442 | .extra2 = &pty_limit_max, | 440 | .extra2 = &pty_limit_max, |
443 | }, { | 441 | }, { |
444 | .ctl_name = PTY_NR, | ||
445 | .procname = "nr", | 442 | .procname = "nr", |
446 | .maxlen = sizeof(int), | 443 | .maxlen = sizeof(int), |
447 | .mode = 0444, | 444 | .mode = 0444, |
448 | .data = &pty_count, | 445 | .data = &pty_count, |
449 | .proc_handler = &proc_dointvec, | 446 | .proc_handler = proc_dointvec, |
450 | }, { | 447 | }, |
451 | .ctl_name = 0 | 448 | {} |
452 | } | ||
453 | }; | 449 | }; |
454 | 450 | ||
455 | static struct ctl_table pty_kern_table[] = { | 451 | static struct ctl_table pty_kern_table[] = { |
456 | { | 452 | { |
457 | .ctl_name = KERN_PTY, | ||
458 | .procname = "pty", | 453 | .procname = "pty", |
459 | .mode = 0555, | 454 | .mode = 0555, |
460 | .child = pty_table, | 455 | .child = pty_table, |
@@ -464,7 +459,6 @@ static struct ctl_table pty_kern_table[] = { | |||
464 | 459 | ||
465 | static struct ctl_table pty_root_table[] = { | 460 | static struct ctl_table pty_root_table[] = { |
466 | { | 461 | { |
467 | .ctl_name = CTL_KERN, | ||
468 | .procname = "kernel", | 462 | .procname = "kernel", |
469 | .mode = 0555, | 463 | .mode = 0555, |
470 | .child = pty_kern_table, | 464 | .child = pty_kern_table, |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 04b505e5a5e2..dcd08635cf1b 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1257,94 +1257,54 @@ static int proc_do_uuid(ctl_table *table, int write, | |||
1257 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); | 1257 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); |
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | static int uuid_strategy(ctl_table *table, | ||
1261 | void __user *oldval, size_t __user *oldlenp, | ||
1262 | void __user *newval, size_t newlen) | ||
1263 | { | ||
1264 | unsigned char tmp_uuid[16], *uuid; | ||
1265 | unsigned int len; | ||
1266 | |||
1267 | if (!oldval || !oldlenp) | ||
1268 | return 1; | ||
1269 | |||
1270 | uuid = table->data; | ||
1271 | if (!uuid) { | ||
1272 | uuid = tmp_uuid; | ||
1273 | uuid[8] = 0; | ||
1274 | } | ||
1275 | if (uuid[8] == 0) | ||
1276 | generate_random_uuid(uuid); | ||
1277 | |||
1278 | if (get_user(len, oldlenp)) | ||
1279 | return -EFAULT; | ||
1280 | if (len) { | ||
1281 | if (len > 16) | ||
1282 | len = 16; | ||
1283 | if (copy_to_user(oldval, uuid, len) || | ||
1284 | put_user(len, oldlenp)) | ||
1285 | return -EFAULT; | ||
1286 | } | ||
1287 | return 1; | ||
1288 | } | ||
1289 | |||
1290 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; | 1260 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; |
1291 | ctl_table random_table[] = { | 1261 | ctl_table random_table[] = { |
1292 | { | 1262 | { |
1293 | .ctl_name = RANDOM_POOLSIZE, | ||
1294 | .procname = "poolsize", | 1263 | .procname = "poolsize", |
1295 | .data = &sysctl_poolsize, | 1264 | .data = &sysctl_poolsize, |
1296 | .maxlen = sizeof(int), | 1265 | .maxlen = sizeof(int), |
1297 | .mode = 0444, | 1266 | .mode = 0444, |
1298 | .proc_handler = &proc_dointvec, | 1267 | .proc_handler = proc_dointvec, |
1299 | }, | 1268 | }, |
1300 | { | 1269 | { |
1301 | .ctl_name = RANDOM_ENTROPY_COUNT, | ||
1302 | .procname = "entropy_avail", | 1270 | .procname = "entropy_avail", |
1303 | .maxlen = sizeof(int), | 1271 | .maxlen = sizeof(int), |
1304 | .mode = 0444, | 1272 | .mode = 0444, |
1305 | .proc_handler = &proc_dointvec, | 1273 | .proc_handler = proc_dointvec, |
1306 | .data = &input_pool.entropy_count, | 1274 | .data = &input_pool.entropy_count, |
1307 | }, | 1275 | }, |
1308 | { | 1276 | { |
1309 | .ctl_name = RANDOM_READ_THRESH, | ||
1310 | .procname = "read_wakeup_threshold", | 1277 | .procname = "read_wakeup_threshold", |
1311 | .data = &random_read_wakeup_thresh, | 1278 | .data = &random_read_wakeup_thresh, |
1312 | .maxlen = sizeof(int), | 1279 | .maxlen = sizeof(int), |
1313 | .mode = 0644, | 1280 | .mode = 0644, |
1314 | .proc_handler = &proc_dointvec_minmax, | 1281 | .proc_handler = proc_dointvec_minmax, |
1315 | .strategy = &sysctl_intvec, | ||
1316 | .extra1 = &min_read_thresh, | 1282 | .extra1 = &min_read_thresh, |
1317 | .extra2 = &max_read_thresh, | 1283 | .extra2 = &max_read_thresh, |
1318 | }, | 1284 | }, |
1319 | { | 1285 | { |
1320 | .ctl_name = RANDOM_WRITE_THRESH, | ||
1321 | .procname = "write_wakeup_threshold", | 1286 | .procname = "write_wakeup_threshold", |
1322 | .data = &random_write_wakeup_thresh, | 1287 | .data = &random_write_wakeup_thresh, |
1323 | .maxlen = sizeof(int), | 1288 | .maxlen = sizeof(int), |
1324 | .mode = 0644, | 1289 | .mode = 0644, |
1325 | .proc_handler = &proc_dointvec_minmax, | 1290 | .proc_handler = proc_dointvec_minmax, |
1326 | .strategy = &sysctl_intvec, | ||
1327 | .extra1 = &min_write_thresh, | 1291 | .extra1 = &min_write_thresh, |
1328 | .extra2 = &max_write_thresh, | 1292 | .extra2 = &max_write_thresh, |
1329 | }, | 1293 | }, |
1330 | { | 1294 | { |
1331 | .ctl_name = RANDOM_BOOT_ID, | ||
1332 | .procname = "boot_id", | 1295 | .procname = "boot_id", |
1333 | .data = &sysctl_bootid, | 1296 | .data = &sysctl_bootid, |
1334 | .maxlen = 16, | 1297 | .maxlen = 16, |
1335 | .mode = 0444, | 1298 | .mode = 0444, |
1336 | .proc_handler = &proc_do_uuid, | 1299 | .proc_handler = proc_do_uuid, |
1337 | .strategy = &uuid_strategy, | ||
1338 | }, | 1300 | }, |
1339 | { | 1301 | { |
1340 | .ctl_name = RANDOM_UUID, | ||
1341 | .procname = "uuid", | 1302 | .procname = "uuid", |
1342 | .maxlen = 16, | 1303 | .maxlen = 16, |
1343 | .mode = 0444, | 1304 | .mode = 0444, |
1344 | .proc_handler = &proc_do_uuid, | 1305 | .proc_handler = proc_do_uuid, |
1345 | .strategy = &uuid_strategy, | ||
1346 | }, | 1306 | }, |
1347 | { .ctl_name = 0 } | 1307 | { } |
1348 | }; | 1308 | }; |
1349 | #endif /* CONFIG_SYSCTL */ | 1309 | #endif /* CONFIG_SYSCTL */ |
1350 | 1310 | ||
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index bc4ab3e54550..95acb8c880f4 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -282,34 +282,31 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
282 | */ | 282 | */ |
283 | static ctl_table rtc_table[] = { | 283 | static ctl_table rtc_table[] = { |
284 | { | 284 | { |
285 | .ctl_name = CTL_UNNUMBERED, | ||
286 | .procname = "max-user-freq", | 285 | .procname = "max-user-freq", |
287 | .data = &rtc_max_user_freq, | 286 | .data = &rtc_max_user_freq, |
288 | .maxlen = sizeof(int), | 287 | .maxlen = sizeof(int), |
289 | .mode = 0644, | 288 | .mode = 0644, |
290 | .proc_handler = &proc_dointvec, | 289 | .proc_handler = proc_dointvec, |
291 | }, | 290 | }, |
292 | { .ctl_name = 0 } | 291 | { } |
293 | }; | 292 | }; |
294 | 293 | ||
295 | static ctl_table rtc_root[] = { | 294 | static ctl_table rtc_root[] = { |
296 | { | 295 | { |
297 | .ctl_name = CTL_UNNUMBERED, | ||
298 | .procname = "rtc", | 296 | .procname = "rtc", |
299 | .mode = 0555, | 297 | .mode = 0555, |
300 | .child = rtc_table, | 298 | .child = rtc_table, |
301 | }, | 299 | }, |
302 | { .ctl_name = 0 } | 300 | { } |
303 | }; | 301 | }; |
304 | 302 | ||
305 | static ctl_table dev_root[] = { | 303 | static ctl_table dev_root[] = { |
306 | { | 304 | { |
307 | .ctl_name = CTL_DEV, | ||
308 | .procname = "dev", | 305 | .procname = "dev", |
309 | .mode = 0555, | 306 | .mode = 0555, |
310 | .child = rtc_root, | 307 | .child = rtc_root, |
311 | }, | 308 | }, |
312 | { .ctl_name = 0 } | 309 | { } |
313 | }; | 310 | }; |
314 | 311 | ||
315 | static struct ctl_table_header *sysctl_header; | 312 | static struct ctl_table_header *sysctl_header; |
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index 713ed7d37247..689cc6a6214d 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | static bool report_gart_errors; | 4 | static bool report_gart_errors; |
5 | static void (*nb_bus_decoder)(int node_id, struct err_regs *regs); | 5 | static void (*nb_bus_decoder)(int node_id, struct err_regs *regs); |
6 | static void (*orig_mce_callback)(struct mce *m); | ||
7 | 6 | ||
8 | void amd_report_gart_errors(bool v) | 7 | void amd_report_gart_errors(bool v) |
9 | { | 8 | { |
@@ -363,8 +362,10 @@ static inline void amd_decode_err_code(unsigned int ec) | |||
363 | pr_warning("Huh? Unknown MCE error 0x%x\n", ec); | 362 | pr_warning("Huh? Unknown MCE error 0x%x\n", ec); |
364 | } | 363 | } |
365 | 364 | ||
366 | static void amd_decode_mce(struct mce *m) | 365 | static int amd_decode_mce(struct notifier_block *nb, unsigned long val, |
366 | void *data) | ||
367 | { | 367 | { |
368 | struct mce *m = (struct mce *)data; | ||
368 | struct err_regs regs; | 369 | struct err_regs regs; |
369 | int node, ecc; | 370 | int node, ecc; |
370 | 371 | ||
@@ -420,20 +421,22 @@ static void amd_decode_mce(struct mce *m) | |||
420 | } | 421 | } |
421 | 422 | ||
422 | amd_decode_err_code(m->status & 0xffff); | 423 | amd_decode_err_code(m->status & 0xffff); |
424 | |||
425 | return NOTIFY_STOP; | ||
423 | } | 426 | } |
424 | 427 | ||
428 | static struct notifier_block amd_mce_dec_nb = { | ||
429 | .notifier_call = amd_decode_mce, | ||
430 | }; | ||
431 | |||
425 | static int __init mce_amd_init(void) | 432 | static int __init mce_amd_init(void) |
426 | { | 433 | { |
427 | /* | 434 | /* |
428 | * We can decode MCEs for Opteron and later CPUs: | 435 | * We can decode MCEs for Opteron and later CPUs: |
429 | */ | 436 | */ |
430 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && | 437 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && |
431 | (boot_cpu_data.x86 >= 0xf)) { | 438 | (boot_cpu_data.x86 >= 0xf)) |
432 | /* safe the default decode mce callback */ | 439 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); |
433 | orig_mce_callback = x86_mce_decode_callback; | ||
434 | |||
435 | x86_mce_decode_callback = amd_decode_mce; | ||
436 | } | ||
437 | 440 | ||
438 | return 0; | 441 | return 0; |
439 | } | 442 | } |
@@ -442,7 +445,7 @@ early_initcall(mce_amd_init); | |||
442 | #ifdef MODULE | 445 | #ifdef MODULE |
443 | static void __exit mce_amd_exit(void) | 446 | static void __exit mce_amd_exit(void) |
444 | { | 447 | { |
445 | x86_mce_decode_callback = orig_mce_callback; | 448 | atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb); |
446 | } | 449 | } |
447 | 450 | ||
448 | MODULE_DESCRIPTION("AMD MCE decoder"); | 451 | MODULE_DESCRIPTION("AMD MCE decoder"); |
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index cc9f27514aef..7b4ef5bb556b 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c | |||
@@ -27,54 +27,49 @@ static int mouse_last_keycode; | |||
27 | /* file(s) in /proc/sys/dev/mac_hid */ | 27 | /* file(s) in /proc/sys/dev/mac_hid */ |
28 | static ctl_table mac_hid_files[] = { | 28 | static ctl_table mac_hid_files[] = { |
29 | { | 29 | { |
30 | .ctl_name = DEV_MAC_HID_MOUSE_BUTTON_EMULATION, | ||
31 | .procname = "mouse_button_emulation", | 30 | .procname = "mouse_button_emulation", |
32 | .data = &mouse_emulate_buttons, | 31 | .data = &mouse_emulate_buttons, |
33 | .maxlen = sizeof(int), | 32 | .maxlen = sizeof(int), |
34 | .mode = 0644, | 33 | .mode = 0644, |
35 | .proc_handler = &proc_dointvec, | 34 | .proc_handler = proc_dointvec, |
36 | }, | 35 | }, |
37 | { | 36 | { |
38 | .ctl_name = DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE, | ||
39 | .procname = "mouse_button2_keycode", | 37 | .procname = "mouse_button2_keycode", |
40 | .data = &mouse_button2_keycode, | 38 | .data = &mouse_button2_keycode, |
41 | .maxlen = sizeof(int), | 39 | .maxlen = sizeof(int), |
42 | .mode = 0644, | 40 | .mode = 0644, |
43 | .proc_handler = &proc_dointvec, | 41 | .proc_handler = proc_dointvec, |
44 | }, | 42 | }, |
45 | { | 43 | { |
46 | .ctl_name = DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE, | ||
47 | .procname = "mouse_button3_keycode", | 44 | .procname = "mouse_button3_keycode", |
48 | .data = &mouse_button3_keycode, | 45 | .data = &mouse_button3_keycode, |
49 | .maxlen = sizeof(int), | 46 | .maxlen = sizeof(int), |
50 | .mode = 0644, | 47 | .mode = 0644, |
51 | .proc_handler = &proc_dointvec, | 48 | .proc_handler = proc_dointvec, |
52 | }, | 49 | }, |
53 | { .ctl_name = 0 } | 50 | { } |
54 | }; | 51 | }; |
55 | 52 | ||
56 | /* dir in /proc/sys/dev */ | 53 | /* dir in /proc/sys/dev */ |
57 | static ctl_table mac_hid_dir[] = { | 54 | static ctl_table mac_hid_dir[] = { |
58 | { | 55 | { |
59 | .ctl_name = DEV_MAC_HID, | ||
60 | .procname = "mac_hid", | 56 | .procname = "mac_hid", |
61 | .maxlen = 0, | 57 | .maxlen = 0, |
62 | .mode = 0555, | 58 | .mode = 0555, |
63 | .child = mac_hid_files, | 59 | .child = mac_hid_files, |
64 | }, | 60 | }, |
65 | { .ctl_name = 0 } | 61 | { } |
66 | }; | 62 | }; |
67 | 63 | ||
68 | /* /proc/sys/dev itself, in case that is not there yet */ | 64 | /* /proc/sys/dev itself, in case that is not there yet */ |
69 | static ctl_table mac_hid_root_dir[] = { | 65 | static ctl_table mac_hid_root_dir[] = { |
70 | { | 66 | { |
71 | .ctl_name = CTL_DEV, | ||
72 | .procname = "dev", | 67 | .procname = "dev", |
73 | .maxlen = 0, | 68 | .maxlen = 0, |
74 | .mode = 0555, | 69 | .mode = 0555, |
75 | .child = mac_hid_dir, | 70 | .child = mac_hid_dir, |
76 | }, | 71 | }, |
77 | { .ctl_name = 0 } | 72 | { } |
78 | }; | 73 | }; |
79 | 74 | ||
80 | static struct ctl_table_header *mac_hid_sysctl_header; | 75 | static struct ctl_table_header *mac_hid_sysctl_header; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index b182f86a19dd..5f154ef1e4be 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -98,44 +98,40 @@ static struct ctl_table_header *raid_table_header; | |||
98 | 98 | ||
99 | static ctl_table raid_table[] = { | 99 | static ctl_table raid_table[] = { |
100 | { | 100 | { |
101 | .ctl_name = DEV_RAID_SPEED_LIMIT_MIN, | ||
102 | .procname = "speed_limit_min", | 101 | .procname = "speed_limit_min", |
103 | .data = &sysctl_speed_limit_min, | 102 | .data = &sysctl_speed_limit_min, |
104 | .maxlen = sizeof(int), | 103 | .maxlen = sizeof(int), |
105 | .mode = S_IRUGO|S_IWUSR, | 104 | .mode = S_IRUGO|S_IWUSR, |
106 | .proc_handler = &proc_dointvec, | 105 | .proc_handler = proc_dointvec, |
107 | }, | 106 | }, |
108 | { | 107 | { |
109 | .ctl_name = DEV_RAID_SPEED_LIMIT_MAX, | ||
110 | .procname = "speed_limit_max", | 108 | .procname = "speed_limit_max", |
111 | .data = &sysctl_speed_limit_max, | 109 | .data = &sysctl_speed_limit_max, |
112 | .maxlen = sizeof(int), | 110 | .maxlen = sizeof(int), |
113 | .mode = S_IRUGO|S_IWUSR, | 111 | .mode = S_IRUGO|S_IWUSR, |
114 | .proc_handler = &proc_dointvec, | 112 | .proc_handler = proc_dointvec, |
115 | }, | 113 | }, |
116 | { .ctl_name = 0 } | 114 | { } |
117 | }; | 115 | }; |
118 | 116 | ||
119 | static ctl_table raid_dir_table[] = { | 117 | static ctl_table raid_dir_table[] = { |
120 | { | 118 | { |
121 | .ctl_name = DEV_RAID, | ||
122 | .procname = "raid", | 119 | .procname = "raid", |
123 | .maxlen = 0, | 120 | .maxlen = 0, |
124 | .mode = S_IRUGO|S_IXUGO, | 121 | .mode = S_IRUGO|S_IXUGO, |
125 | .child = raid_table, | 122 | .child = raid_table, |
126 | }, | 123 | }, |
127 | { .ctl_name = 0 } | 124 | { } |
128 | }; | 125 | }; |
129 | 126 | ||
130 | static ctl_table raid_root_table[] = { | 127 | static ctl_table raid_root_table[] = { |
131 | { | 128 | { |
132 | .ctl_name = CTL_DEV, | ||
133 | .procname = "dev", | 129 | .procname = "dev", |
134 | .maxlen = 0, | 130 | .maxlen = 0, |
135 | .mode = 0555, | 131 | .mode = 0555, |
136 | .child = raid_dir_table, | 132 | .child = raid_dir_table, |
137 | }, | 133 | }, |
138 | { .ctl_name = 0 } | 134 | { } |
139 | }; | 135 | }; |
140 | 136 | ||
141 | static const struct block_device_operations md_fops; | 137 | static const struct block_device_operations md_fops; |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index a87a477c87f2..b134553eb3b5 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -195,6 +195,24 @@ config RADIO_MAESTRO | |||
195 | To compile this driver as a module, choose M here: the | 195 | To compile this driver as a module, choose M here: the |
196 | module will be called radio-maestro. | 196 | module will be called radio-maestro. |
197 | 197 | ||
198 | config RADIO_MIROPCM20 | ||
199 | tristate "miroSOUND PCM20 radio" | ||
200 | depends on ISA && VIDEO_V4L2 | ||
201 | select SND_MIRO | ||
202 | ---help--- | ||
203 | Choose Y here if you have this FM radio card. You also need to enable | ||
204 | the ALSA sound system. This choice automatically selects the ALSA | ||
205 | sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this | ||
206 | is required for the radio-miropcm20. | ||
207 | |||
208 | In order to control your radio card, you will need to use programs | ||
209 | that are compatible with the Video For Linux API. Information on | ||
210 | this API and pointers to "v4l" programs may be found at | ||
211 | <file:Documentation/video4linux/API.html>. | ||
212 | |||
213 | To compile this driver as a module, choose M here: the | ||
214 | module will be called radio-miropcm20. | ||
215 | |||
198 | config RADIO_SF16FMI | 216 | config RADIO_SF16FMI |
199 | tristate "SF16FMI Radio" | 217 | tristate "SF16FMI Radio" |
200 | depends on ISA && VIDEO_V4L2 | 218 | depends on ISA && VIDEO_V4L2 |
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 2a1be3bf4f7c..8a63d543ae41 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o | |||
18 | obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o | 18 | obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o |
19 | obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o | 19 | obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o |
20 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o | 20 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o |
21 | obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o | ||
21 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 22 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
22 | obj-$(CONFIG_RADIO_SI470X) += si470x/ | 23 | obj-$(CONFIG_RADIO_SI470X) += si470x/ |
23 | obj-$(CONFIG_USB_MR800) += radio-mr800.o | 24 | obj-$(CONFIG_USB_MR800) += radio-mr800.o |
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c new file mode 100644 index 000000000000..4ff885445fd4 --- /dev/null +++ b/drivers/media/radio/radio-miropcm20.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* Miro PCM20 radio driver for Linux radio support | ||
2 | * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl> | ||
3 | * Thanks to Norberto Pellici for the ACI device interface specification | ||
4 | * The API part is based on the radiotrack driver by M. Kirkwood | ||
5 | * This driver relies on the aci mixer provided by the snd-miro | ||
6 | * ALSA driver. | ||
7 | * Look there for further info... | ||
8 | */ | ||
9 | |||
10 | /* What ever you think about the ACI, version 0x07 is not very well! | ||
11 | * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono | ||
12 | * conditions... Robert | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/videodev2.h> | ||
18 | #include <media/v4l2-device.h> | ||
19 | #include <media/v4l2-ioctl.h> | ||
20 | #include <sound/aci.h> | ||
21 | |||
22 | static int radio_nr = -1; | ||
23 | module_param(radio_nr, int, 0); | ||
24 | MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)"); | ||
25 | |||
26 | static int mono; | ||
27 | module_param(mono, bool, 0); | ||
28 | MODULE_PARM_DESC(mono, "Force tuner into mono mode."); | ||
29 | |||
30 | struct pcm20 { | ||
31 | struct v4l2_device v4l2_dev; | ||
32 | struct video_device vdev; | ||
33 | unsigned long freq; | ||
34 | int muted; | ||
35 | struct snd_miro_aci *aci; | ||
36 | }; | ||
37 | |||
38 | static struct pcm20 pcm20_card = { | ||
39 | .freq = 87*16000, | ||
40 | .muted = 1, | ||
41 | }; | ||
42 | |||
43 | static int pcm20_mute(struct pcm20 *dev, unsigned char mute) | ||
44 | { | ||
45 | dev->muted = mute; | ||
46 | return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1); | ||
47 | } | ||
48 | |||
49 | static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo) | ||
50 | { | ||
51 | return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1); | ||
52 | } | ||
53 | |||
54 | static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) | ||
55 | { | ||
56 | unsigned char freql; | ||
57 | unsigned char freqh; | ||
58 | struct snd_miro_aci *aci = dev->aci; | ||
59 | |||
60 | dev->freq = freq; | ||
61 | |||
62 | freq /= 160; | ||
63 | if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0)) | ||
64 | freq /= 10; /* I don't know exactly which version | ||
65 | * needs this hack */ | ||
66 | freql = freq & 0xff; | ||
67 | freqh = freq >> 8; | ||
68 | |||
69 | pcm20_stereo(dev, !mono); | ||
70 | return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh); | ||
71 | } | ||
72 | |||
73 | static const struct v4l2_file_operations pcm20_fops = { | ||
74 | .owner = THIS_MODULE, | ||
75 | .ioctl = video_ioctl2, | ||
76 | }; | ||
77 | |||
78 | static int vidioc_querycap(struct file *file, void *priv, | ||
79 | struct v4l2_capability *v) | ||
80 | { | ||
81 | strlcpy(v->driver, "Miro PCM20", sizeof(v->driver)); | ||
82 | strlcpy(v->card, "Miro PCM20", sizeof(v->card)); | ||
83 | strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); | ||
84 | v->version = 0x1; | ||
85 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
90 | struct v4l2_tuner *v) | ||
91 | { | ||
92 | if (v->index) /* Only 1 tuner */ | ||
93 | return -EINVAL; | ||
94 | strlcpy(v->name, "FM", sizeof(v->name)); | ||
95 | v->type = V4L2_TUNER_RADIO; | ||
96 | v->rangelow = 87*16000; | ||
97 | v->rangehigh = 108*16000; | ||
98 | v->signal = 0xffff; | ||
99 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | ||
100 | v->capability = V4L2_TUNER_CAP_LOW; | ||
101 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
106 | struct v4l2_tuner *v) | ||
107 | { | ||
108 | return v->index ? -EINVAL : 0; | ||
109 | } | ||
110 | |||
111 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
112 | struct v4l2_frequency *f) | ||
113 | { | ||
114 | struct pcm20 *dev = video_drvdata(file); | ||
115 | |||
116 | if (f->tuner != 0) | ||
117 | return -EINVAL; | ||
118 | |||
119 | f->type = V4L2_TUNER_RADIO; | ||
120 | f->frequency = dev->freq; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | |||
125 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
126 | struct v4l2_frequency *f) | ||
127 | { | ||
128 | struct pcm20 *dev = video_drvdata(file); | ||
129 | |||
130 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
131 | return -EINVAL; | ||
132 | |||
133 | dev->freq = f->frequency; | ||
134 | pcm20_setfreq(dev, f->frequency); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
139 | struct v4l2_queryctrl *qc) | ||
140 | { | ||
141 | switch (qc->id) { | ||
142 | case V4L2_CID_AUDIO_MUTE: | ||
143 | return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); | ||
144 | } | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
149 | struct v4l2_control *ctrl) | ||
150 | { | ||
151 | struct pcm20 *dev = video_drvdata(file); | ||
152 | |||
153 | switch (ctrl->id) { | ||
154 | case V4L2_CID_AUDIO_MUTE: | ||
155 | ctrl->value = dev->muted; | ||
156 | break; | ||
157 | default: | ||
158 | return -EINVAL; | ||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
164 | struct v4l2_control *ctrl) | ||
165 | { | ||
166 | struct pcm20 *dev = video_drvdata(file); | ||
167 | |||
168 | switch (ctrl->id) { | ||
169 | case V4L2_CID_AUDIO_MUTE: | ||
170 | pcm20_mute(dev, ctrl->value); | ||
171 | break; | ||
172 | default: | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
179 | { | ||
180 | *i = 0; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
185 | { | ||
186 | return i ? -EINVAL : 0; | ||
187 | } | ||
188 | |||
189 | static int vidioc_g_audio(struct file *file, void *priv, | ||
190 | struct v4l2_audio *a) | ||
191 | { | ||
192 | a->index = 0; | ||
193 | strlcpy(a->name, "Radio", sizeof(a->name)); | ||
194 | a->capability = V4L2_AUDCAP_STEREO; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int vidioc_s_audio(struct file *file, void *priv, | ||
199 | struct v4l2_audio *a) | ||
200 | { | ||
201 | return a->index ? -EINVAL : 0; | ||
202 | } | ||
203 | |||
204 | static const struct v4l2_ioctl_ops pcm20_ioctl_ops = { | ||
205 | .vidioc_querycap = vidioc_querycap, | ||
206 | .vidioc_g_tuner = vidioc_g_tuner, | ||
207 | .vidioc_s_tuner = vidioc_s_tuner, | ||
208 | .vidioc_g_frequency = vidioc_g_frequency, | ||
209 | .vidioc_s_frequency = vidioc_s_frequency, | ||
210 | .vidioc_queryctrl = vidioc_queryctrl, | ||
211 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
212 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
213 | .vidioc_g_audio = vidioc_g_audio, | ||
214 | .vidioc_s_audio = vidioc_s_audio, | ||
215 | .vidioc_g_input = vidioc_g_input, | ||
216 | .vidioc_s_input = vidioc_s_input, | ||
217 | }; | ||
218 | |||
219 | static int __init pcm20_init(void) | ||
220 | { | ||
221 | struct pcm20 *dev = &pcm20_card; | ||
222 | struct v4l2_device *v4l2_dev = &dev->v4l2_dev; | ||
223 | int res; | ||
224 | |||
225 | dev->aci = snd_aci_get_aci(); | ||
226 | if (dev->aci == NULL) { | ||
227 | v4l2_err(v4l2_dev, | ||
228 | "you must load the snd-miro driver first!\n"); | ||
229 | return -ENODEV; | ||
230 | } | ||
231 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); | ||
232 | |||
233 | |||
234 | res = v4l2_device_register(NULL, v4l2_dev); | ||
235 | if (res < 0) { | ||
236 | v4l2_err(v4l2_dev, "could not register v4l2_device\n"); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); | ||
241 | dev->vdev.v4l2_dev = v4l2_dev; | ||
242 | dev->vdev.fops = &pcm20_fops; | ||
243 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; | ||
244 | dev->vdev.release = video_device_release_empty; | ||
245 | video_set_drvdata(&dev->vdev, dev); | ||
246 | |||
247 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) | ||
248 | goto fail; | ||
249 | |||
250 | v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n"); | ||
251 | return 0; | ||
252 | fail: | ||
253 | v4l2_device_unregister(v4l2_dev); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | |||
257 | MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt"); | ||
258 | MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card."); | ||
259 | MODULE_LICENSE("GPL"); | ||
260 | |||
261 | static void __exit pcm20_cleanup(void) | ||
262 | { | ||
263 | struct pcm20 *dev = &pcm20_card; | ||
264 | |||
265 | video_unregister_device(&dev->vdev); | ||
266 | v4l2_device_unregister(&dev->v4l2_dev); | ||
267 | } | ||
268 | |||
269 | module_init(pcm20_init); | ||
270 | module_exit(pcm20_cleanup); | ||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 570be139f9df..08f2d07bf56a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -121,6 +121,12 @@ config TWL4030_POWER | |||
121 | and load scripts controling which resources are switched off/on | 121 | and load scripts controling which resources are switched off/on |
122 | or reset when a sleep, wakeup or warm reset event occurs. | 122 | or reset when a sleep, wakeup or warm reset event occurs. |
123 | 123 | ||
124 | config TWL4030_CODEC | ||
125 | bool | ||
126 | depends on TWL4030_CORE | ||
127 | select MFD_CORE | ||
128 | default n | ||
129 | |||
124 | config MFD_TMIO | 130 | config MFD_TMIO |
125 | bool | 131 | bool |
126 | default n | 132 | default n |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f3b277b90d40..af0fc903cec8 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_MENELAUS) += menelaus.o | |||
26 | 26 | ||
27 | obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o twl4030-irq.o | 27 | obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o twl4030-irq.o |
28 | obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o | 28 | obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o |
29 | obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o | ||
29 | 30 | ||
30 | obj-$(CONFIG_MFD_MC13783) += mc13783-core.o | 31 | obj-$(CONFIG_MFD_MC13783) += mc13783-core.o |
31 | 32 | ||
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c new file mode 100644 index 000000000000..77b914907d7c --- /dev/null +++ b/drivers/mfd/twl4030-codec.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * MFD driver for twl4030 codec submodule | ||
3 | * | ||
4 | * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> | ||
5 | * | ||
6 | * Copyright: (C) 2009 Nokia Corporation | ||
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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/i2c/twl4030.h> | ||
30 | #include <linux/mfd/core.h> | ||
31 | #include <linux/mfd/twl4030-codec.h> | ||
32 | |||
33 | #define TWL4030_CODEC_CELLS 2 | ||
34 | |||
35 | static struct platform_device *twl4030_codec_dev; | ||
36 | |||
37 | struct twl4030_codec_resource { | ||
38 | int request_count; | ||
39 | u8 reg; | ||
40 | u8 mask; | ||
41 | }; | ||
42 | |||
43 | struct twl4030_codec { | ||
44 | unsigned int audio_mclk; | ||
45 | struct mutex mutex; | ||
46 | struct twl4030_codec_resource resource[TWL4030_CODEC_RES_MAX]; | ||
47 | struct mfd_cell cells[TWL4030_CODEC_CELLS]; | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * Modify the resource, the function returns the content of the register | ||
52 | * after the modification. | ||
53 | */ | ||
54 | static int twl4030_codec_set_resource(enum twl4030_codec_res id, int enable) | ||
55 | { | ||
56 | struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); | ||
57 | u8 val; | ||
58 | |||
59 | twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, | ||
60 | codec->resource[id].reg); | ||
61 | |||
62 | if (enable) | ||
63 | val |= codec->resource[id].mask; | ||
64 | else | ||
65 | val &= ~codec->resource[id].mask; | ||
66 | |||
67 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
68 | val, codec->resource[id].reg); | ||
69 | |||
70 | return val; | ||
71 | } | ||
72 | |||
73 | static inline int twl4030_codec_get_resource(enum twl4030_codec_res id) | ||
74 | { | ||
75 | struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); | ||
76 | u8 val; | ||
77 | |||
78 | twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, | ||
79 | codec->resource[id].reg); | ||
80 | |||
81 | return val; | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * Enable the resource. | ||
86 | * The function returns with error or the content of the register | ||
87 | */ | ||
88 | int twl4030_codec_enable_resource(enum twl4030_codec_res id) | ||
89 | { | ||
90 | struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); | ||
91 | int val; | ||
92 | |||
93 | if (id >= TWL4030_CODEC_RES_MAX) { | ||
94 | dev_err(&twl4030_codec_dev->dev, | ||
95 | "Invalid resource ID (%u)\n", id); | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | mutex_lock(&codec->mutex); | ||
100 | if (!codec->resource[id].request_count) | ||
101 | /* Resource was disabled, enable it */ | ||
102 | val = twl4030_codec_set_resource(id, 1); | ||
103 | else | ||
104 | val = twl4030_codec_get_resource(id); | ||
105 | |||
106 | codec->resource[id].request_count++; | ||
107 | mutex_unlock(&codec->mutex); | ||
108 | |||
109 | return val; | ||
110 | } | ||
111 | EXPORT_SYMBOL_GPL(twl4030_codec_enable_resource); | ||
112 | |||
113 | /* | ||
114 | * Disable the resource. | ||
115 | * The function returns with error or the content of the register | ||
116 | */ | ||
117 | int twl4030_codec_disable_resource(unsigned id) | ||
118 | { | ||
119 | struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); | ||
120 | int val; | ||
121 | |||
122 | if (id >= TWL4030_CODEC_RES_MAX) { | ||
123 | dev_err(&twl4030_codec_dev->dev, | ||
124 | "Invalid resource ID (%u)\n", id); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | mutex_lock(&codec->mutex); | ||
129 | if (!codec->resource[id].request_count) { | ||
130 | dev_err(&twl4030_codec_dev->dev, | ||
131 | "Resource has been disabled already (%u)\n", id); | ||
132 | mutex_unlock(&codec->mutex); | ||
133 | return -EPERM; | ||
134 | } | ||
135 | codec->resource[id].request_count--; | ||
136 | |||
137 | if (!codec->resource[id].request_count) | ||
138 | /* Resource can be disabled now */ | ||
139 | val = twl4030_codec_set_resource(id, 0); | ||
140 | else | ||
141 | val = twl4030_codec_get_resource(id); | ||
142 | |||
143 | mutex_unlock(&codec->mutex); | ||
144 | |||
145 | return val; | ||
146 | } | ||
147 | EXPORT_SYMBOL_GPL(twl4030_codec_disable_resource); | ||
148 | |||
149 | unsigned int twl4030_codec_get_mclk(void) | ||
150 | { | ||
151 | struct twl4030_codec *codec = platform_get_drvdata(twl4030_codec_dev); | ||
152 | |||
153 | return codec->audio_mclk; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(twl4030_codec_get_mclk); | ||
156 | |||
157 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) | ||
158 | { | ||
159 | struct twl4030_codec *codec; | ||
160 | struct twl4030_codec_data *pdata = pdev->dev.platform_data; | ||
161 | struct mfd_cell *cell = NULL; | ||
162 | int ret, childs = 0; | ||
163 | u8 val; | ||
164 | |||
165 | if (!pdata) { | ||
166 | dev_err(&pdev->dev, "Platform data is missing\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | /* Configure APLL_INFREQ and disable APLL if enabled */ | ||
171 | val = 0; | ||
172 | switch (pdata->audio_mclk) { | ||
173 | case 19200000: | ||
174 | val |= TWL4030_APLL_INFREQ_19200KHZ; | ||
175 | break; | ||
176 | case 26000000: | ||
177 | val |= TWL4030_APLL_INFREQ_26000KHZ; | ||
178 | break; | ||
179 | case 38400000: | ||
180 | val |= TWL4030_APLL_INFREQ_38400KHZ; | ||
181 | break; | ||
182 | default: | ||
183 | dev_err(&pdev->dev, "Invalid audio_mclk\n"); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, | ||
187 | val, TWL4030_REG_APLL_CTL); | ||
188 | |||
189 | codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL); | ||
190 | if (!codec) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | platform_set_drvdata(pdev, codec); | ||
194 | |||
195 | twl4030_codec_dev = pdev; | ||
196 | mutex_init(&codec->mutex); | ||
197 | codec->audio_mclk = pdata->audio_mclk; | ||
198 | |||
199 | /* Codec power */ | ||
200 | codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE; | ||
201 | codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ; | ||
202 | |||
203 | /* PLL */ | ||
204 | codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL; | ||
205 | codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN; | ||
206 | |||
207 | if (pdata->audio) { | ||
208 | cell = &codec->cells[childs]; | ||
209 | cell->name = "twl4030_codec_audio"; | ||
210 | cell->platform_data = pdata->audio; | ||
211 | cell->data_size = sizeof(*pdata->audio); | ||
212 | childs++; | ||
213 | } | ||
214 | if (pdata->vibra) { | ||
215 | cell = &codec->cells[childs]; | ||
216 | cell->name = "twl4030_codec_vibra"; | ||
217 | cell->platform_data = pdata->vibra; | ||
218 | cell->data_size = sizeof(*pdata->vibra); | ||
219 | childs++; | ||
220 | } | ||
221 | |||
222 | if (childs) | ||
223 | ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells, | ||
224 | childs, NULL, 0); | ||
225 | else { | ||
226 | dev_err(&pdev->dev, "No platform data found for childs\n"); | ||
227 | ret = -ENODEV; | ||
228 | } | ||
229 | |||
230 | if (!ret) | ||
231 | return 0; | ||
232 | |||
233 | platform_set_drvdata(pdev, NULL); | ||
234 | kfree(codec); | ||
235 | twl4030_codec_dev = NULL; | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | static int __devexit twl4030_codec_remove(struct platform_device *pdev) | ||
240 | { | ||
241 | struct twl4030_codec *codec = platform_get_drvdata(pdev); | ||
242 | |||
243 | mfd_remove_devices(&pdev->dev); | ||
244 | platform_set_drvdata(pdev, NULL); | ||
245 | kfree(codec); | ||
246 | twl4030_codec_dev = NULL; | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | MODULE_ALIAS("platform:twl4030_codec"); | ||
252 | |||
253 | static struct platform_driver twl4030_codec_driver = { | ||
254 | .probe = twl4030_codec_probe, | ||
255 | .remove = __devexit_p(twl4030_codec_remove), | ||
256 | .driver = { | ||
257 | .owner = THIS_MODULE, | ||
258 | .name = "twl4030_codec", | ||
259 | }, | ||
260 | }; | ||
261 | |||
262 | static int __devinit twl4030_codec_init(void) | ||
263 | { | ||
264 | return platform_driver_register(&twl4030_codec_driver); | ||
265 | } | ||
266 | module_init(twl4030_codec_init); | ||
267 | |||
268 | static void __devexit twl4030_codec_exit(void) | ||
269 | { | ||
270 | platform_driver_unregister(&twl4030_codec_driver); | ||
271 | } | ||
272 | module_exit(twl4030_codec_exit); | ||
273 | |||
274 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>"); | ||
275 | MODULE_LICENSE("GPL"); | ||
276 | |||
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c index a1c47ee95c0e..98b984e191d5 100644 --- a/drivers/mfd/twl4030-core.c +++ b/drivers/mfd/twl4030-core.c | |||
@@ -114,6 +114,12 @@ | |||
114 | #define twl_has_watchdog() false | 114 | #define twl_has_watchdog() false |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | #if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) | ||
118 | #define twl_has_codec() true | ||
119 | #else | ||
120 | #define twl_has_codec() false | ||
121 | #endif | ||
122 | |||
117 | /* Triton Core internal information (BEGIN) */ | 123 | /* Triton Core internal information (BEGIN) */ |
118 | 124 | ||
119 | /* Last - for index max*/ | 125 | /* Last - for index max*/ |
@@ -601,6 +607,14 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
601 | return PTR_ERR(child); | 607 | return PTR_ERR(child); |
602 | } | 608 | } |
603 | 609 | ||
610 | if (twl_has_codec() && pdata->codec) { | ||
611 | child = add_child(1, "twl4030_codec", | ||
612 | pdata->codec, sizeof(*pdata->codec), | ||
613 | false, 0, 0); | ||
614 | if (IS_ERR(child)) | ||
615 | return PTR_ERR(child); | ||
616 | } | ||
617 | |||
604 | if (twl_has_regulator()) { | 618 | if (twl_has_regulator()) { |
605 | /* | 619 | /* |
606 | child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); | 620 | child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); |
@@ -763,7 +777,7 @@ static int twl4030_remove(struct i2c_client *client) | |||
763 | } | 777 | } |
764 | 778 | ||
765 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ | 779 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ |
766 | static int | 780 | static int __init |
767 | twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) | 781 | twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) |
768 | { | 782 | { |
769 | int status; | 783 | int status; |
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index fd3688a3e23f..832ed4c88cf7 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
@@ -89,48 +89,40 @@ static int xpc_disengage_max_timelimit = 120; | |||
89 | 89 | ||
90 | static ctl_table xpc_sys_xpc_hb_dir[] = { | 90 | static ctl_table xpc_sys_xpc_hb_dir[] = { |
91 | { | 91 | { |
92 | .ctl_name = CTL_UNNUMBERED, | ||
93 | .procname = "hb_interval", | 92 | .procname = "hb_interval", |
94 | .data = &xpc_hb_interval, | 93 | .data = &xpc_hb_interval, |
95 | .maxlen = sizeof(int), | 94 | .maxlen = sizeof(int), |
96 | .mode = 0644, | 95 | .mode = 0644, |
97 | .proc_handler = &proc_dointvec_minmax, | 96 | .proc_handler = proc_dointvec_minmax, |
98 | .strategy = &sysctl_intvec, | ||
99 | .extra1 = &xpc_hb_min_interval, | 97 | .extra1 = &xpc_hb_min_interval, |
100 | .extra2 = &xpc_hb_max_interval}, | 98 | .extra2 = &xpc_hb_max_interval}, |
101 | { | 99 | { |
102 | .ctl_name = CTL_UNNUMBERED, | ||
103 | .procname = "hb_check_interval", | 100 | .procname = "hb_check_interval", |
104 | .data = &xpc_hb_check_interval, | 101 | .data = &xpc_hb_check_interval, |
105 | .maxlen = sizeof(int), | 102 | .maxlen = sizeof(int), |
106 | .mode = 0644, | 103 | .mode = 0644, |
107 | .proc_handler = &proc_dointvec_minmax, | 104 | .proc_handler = proc_dointvec_minmax, |
108 | .strategy = &sysctl_intvec, | ||
109 | .extra1 = &xpc_hb_check_min_interval, | 105 | .extra1 = &xpc_hb_check_min_interval, |
110 | .extra2 = &xpc_hb_check_max_interval}, | 106 | .extra2 = &xpc_hb_check_max_interval}, |
111 | {} | 107 | {} |
112 | }; | 108 | }; |
113 | static ctl_table xpc_sys_xpc_dir[] = { | 109 | static ctl_table xpc_sys_xpc_dir[] = { |
114 | { | 110 | { |
115 | .ctl_name = CTL_UNNUMBERED, | ||
116 | .procname = "hb", | 111 | .procname = "hb", |
117 | .mode = 0555, | 112 | .mode = 0555, |
118 | .child = xpc_sys_xpc_hb_dir}, | 113 | .child = xpc_sys_xpc_hb_dir}, |
119 | { | 114 | { |
120 | .ctl_name = CTL_UNNUMBERED, | ||
121 | .procname = "disengage_timelimit", | 115 | .procname = "disengage_timelimit", |
122 | .data = &xpc_disengage_timelimit, | 116 | .data = &xpc_disengage_timelimit, |
123 | .maxlen = sizeof(int), | 117 | .maxlen = sizeof(int), |
124 | .mode = 0644, | 118 | .mode = 0644, |
125 | .proc_handler = &proc_dointvec_minmax, | 119 | .proc_handler = proc_dointvec_minmax, |
126 | .strategy = &sysctl_intvec, | ||
127 | .extra1 = &xpc_disengage_min_timelimit, | 120 | .extra1 = &xpc_disengage_min_timelimit, |
128 | .extra2 = &xpc_disengage_max_timelimit}, | 121 | .extra2 = &xpc_disengage_max_timelimit}, |
129 | {} | 122 | {} |
130 | }; | 123 | }; |
131 | static ctl_table xpc_sys_dir[] = { | 124 | static ctl_table xpc_sys_dir[] = { |
132 | { | 125 | { |
133 | .ctl_name = CTL_UNNUMBERED, | ||
134 | .procname = "xpc", | 126 | .procname = "xpc", |
135 | .mode = 0555, | 127 | .mode = 0555, |
136 | .child = xpc_sys_xpc_dir}, | 128 | .child = xpc_sys_xpc_dir}, |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index c76677afda1b..b5bbe59f9c57 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -106,7 +106,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) | |||
106 | int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); | 106 | int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade); |
107 | 107 | ||
108 | #if defined CONFIG_X86_64 | 108 | #if defined CONFIG_X86_64 |
109 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset); | 109 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, |
110 | UV_AFFINITY_CPU); | ||
110 | if (mq->irq < 0) { | 111 | if (mq->irq < 0) { |
111 | dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", | 112 | dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", |
112 | -mq->irq); | 113 | -mq->irq); |
@@ -136,7 +137,7 @@ static void | |||
136 | xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq) | 137 | xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq) |
137 | { | 138 | { |
138 | #if defined CONFIG_X86_64 | 139 | #if defined CONFIG_X86_64 |
139 | uv_teardown_irq(mq->irq, mq->mmr_blade, mq->mmr_offset); | 140 | uv_teardown_irq(mq->irq); |
140 | 141 | ||
141 | #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV | 142 | #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV |
142 | int mmr_pnode; | 143 | int mmr_pnode; |
diff --git a/drivers/of/base.c b/drivers/of/base.c index ddf224d456b2..e6627b2320f1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -9,7 +9,8 @@ | |||
9 | * | 9 | * |
10 | * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net | 10 | * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net |
11 | * | 11 | * |
12 | * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell. | 12 | * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and |
13 | * Grant Likely. | ||
13 | * | 14 | * |
14 | * This program is free software; you can redistribute it and/or | 15 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License | 16 | * modify it under the terms of the GNU General Public License |
@@ -82,6 +83,29 @@ struct property *of_find_property(const struct device_node *np, | |||
82 | } | 83 | } |
83 | EXPORT_SYMBOL(of_find_property); | 84 | EXPORT_SYMBOL(of_find_property); |
84 | 85 | ||
86 | /** | ||
87 | * of_find_all_nodes - Get next node in global list | ||
88 | * @prev: Previous node or NULL to start iteration | ||
89 | * of_node_put() will be called on it | ||
90 | * | ||
91 | * Returns a node pointer with refcount incremented, use | ||
92 | * of_node_put() on it when done. | ||
93 | */ | ||
94 | struct device_node *of_find_all_nodes(struct device_node *prev) | ||
95 | { | ||
96 | struct device_node *np; | ||
97 | |||
98 | read_lock(&devtree_lock); | ||
99 | np = prev ? prev->allnext : allnodes; | ||
100 | for (; np != NULL; np = np->allnext) | ||
101 | if (of_node_get(np)) | ||
102 | break; | ||
103 | of_node_put(prev); | ||
104 | read_unlock(&devtree_lock); | ||
105 | return np; | ||
106 | } | ||
107 | EXPORT_SYMBOL(of_find_all_nodes); | ||
108 | |||
85 | /* | 109 | /* |
86 | * Find a property with a given name for a given node | 110 | * Find a property with a given name for a given node |
87 | * and return the value. | 111 | * and return the value. |
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c index 8eefe56f1cbe..3f56bc086cb5 100644 --- a/drivers/parport/procfs.c +++ b/drivers/parport/procfs.c | |||
@@ -233,10 +233,10 @@ static int do_hardware_modes (ctl_table *table, int write, | |||
233 | return copy_to_user(result, buffer, len) ? -EFAULT : 0; | 233 | return copy_to_user(result, buffer, len) ? -EFAULT : 0; |
234 | } | 234 | } |
235 | 235 | ||
236 | #define PARPORT_PORT_DIR(CHILD) { .ctl_name = 0, .procname = NULL, .mode = 0555, .child = CHILD } | 236 | #define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD } |
237 | #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \ | 237 | #define PARPORT_PARPORT_DIR(CHILD) { .procname = "parport", \ |
238 | .mode = 0555, .child = CHILD } | 238 | .mode = 0555, .child = CHILD } |
239 | #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD } | 239 | #define PARPORT_DEV_DIR(CHILD) { .procname = "dev", .mode = 0555, .child = CHILD } |
240 | #define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \ | 240 | #define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \ |
241 | .mode = 0555, .child = NULL } | 241 | .mode = 0555, .child = NULL } |
242 | 242 | ||
@@ -270,7 +270,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
270 | .data = NULL, | 270 | .data = NULL, |
271 | .maxlen = sizeof(int), | 271 | .maxlen = sizeof(int), |
272 | .mode = 0644, | 272 | .mode = 0644, |
273 | .proc_handler = &proc_dointvec_minmax, | 273 | .proc_handler = proc_dointvec_minmax, |
274 | .extra1 = (void*) &parport_min_spintime_value, | 274 | .extra1 = (void*) &parport_min_spintime_value, |
275 | .extra2 = (void*) &parport_max_spintime_value | 275 | .extra2 = (void*) &parport_max_spintime_value |
276 | }, | 276 | }, |
@@ -279,28 +279,28 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
279 | .data = NULL, | 279 | .data = NULL, |
280 | .maxlen = 0, | 280 | .maxlen = 0, |
281 | .mode = 0444, | 281 | .mode = 0444, |
282 | .proc_handler = &do_hardware_base_addr | 282 | .proc_handler = do_hardware_base_addr |
283 | }, | 283 | }, |
284 | { | 284 | { |
285 | .procname = "irq", | 285 | .procname = "irq", |
286 | .data = NULL, | 286 | .data = NULL, |
287 | .maxlen = 0, | 287 | .maxlen = 0, |
288 | .mode = 0444, | 288 | .mode = 0444, |
289 | .proc_handler = &do_hardware_irq | 289 | .proc_handler = do_hardware_irq |
290 | }, | 290 | }, |
291 | { | 291 | { |
292 | .procname = "dma", | 292 | .procname = "dma", |
293 | .data = NULL, | 293 | .data = NULL, |
294 | .maxlen = 0, | 294 | .maxlen = 0, |
295 | .mode = 0444, | 295 | .mode = 0444, |
296 | .proc_handler = &do_hardware_dma | 296 | .proc_handler = do_hardware_dma |
297 | }, | 297 | }, |
298 | { | 298 | { |
299 | .procname = "modes", | 299 | .procname = "modes", |
300 | .data = NULL, | 300 | .data = NULL, |
301 | .maxlen = 0, | 301 | .maxlen = 0, |
302 | .mode = 0444, | 302 | .mode = 0444, |
303 | .proc_handler = &do_hardware_modes | 303 | .proc_handler = do_hardware_modes |
304 | }, | 304 | }, |
305 | PARPORT_DEVICES_ROOT_DIR, | 305 | PARPORT_DEVICES_ROOT_DIR, |
306 | #ifdef CONFIG_PARPORT_1284 | 306 | #ifdef CONFIG_PARPORT_1284 |
@@ -309,35 +309,35 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
309 | .data = NULL, | 309 | .data = NULL, |
310 | .maxlen = 0, | 310 | .maxlen = 0, |
311 | .mode = 0444, | 311 | .mode = 0444, |
312 | .proc_handler = &do_autoprobe | 312 | .proc_handler = do_autoprobe |
313 | }, | 313 | }, |
314 | { | 314 | { |
315 | .procname = "autoprobe0", | 315 | .procname = "autoprobe0", |
316 | .data = NULL, | 316 | .data = NULL, |
317 | .maxlen = 0, | 317 | .maxlen = 0, |
318 | .mode = 0444, | 318 | .mode = 0444, |
319 | .proc_handler = &do_autoprobe | 319 | .proc_handler = do_autoprobe |
320 | }, | 320 | }, |
321 | { | 321 | { |
322 | .procname = "autoprobe1", | 322 | .procname = "autoprobe1", |
323 | .data = NULL, | 323 | .data = NULL, |
324 | .maxlen = 0, | 324 | .maxlen = 0, |
325 | .mode = 0444, | 325 | .mode = 0444, |
326 | .proc_handler = &do_autoprobe | 326 | .proc_handler = do_autoprobe |
327 | }, | 327 | }, |
328 | { | 328 | { |
329 | .procname = "autoprobe2", | 329 | .procname = "autoprobe2", |
330 | .data = NULL, | 330 | .data = NULL, |
331 | .maxlen = 0, | 331 | .maxlen = 0, |
332 | .mode = 0444, | 332 | .mode = 0444, |
333 | .proc_handler = &do_autoprobe | 333 | .proc_handler = do_autoprobe |
334 | }, | 334 | }, |
335 | { | 335 | { |
336 | .procname = "autoprobe3", | 336 | .procname = "autoprobe3", |
337 | .data = NULL, | 337 | .data = NULL, |
338 | .maxlen = 0, | 338 | .maxlen = 0, |
339 | .mode = 0444, | 339 | .mode = 0444, |
340 | .proc_handler = &do_autoprobe | 340 | .proc_handler = do_autoprobe |
341 | }, | 341 | }, |
342 | #endif /* IEEE 1284 support */ | 342 | #endif /* IEEE 1284 support */ |
343 | {} | 343 | {} |
@@ -348,7 +348,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
348 | .data = NULL, | 348 | .data = NULL, |
349 | .maxlen = 0, | 349 | .maxlen = 0, |
350 | .mode = 0444, | 350 | .mode = 0444, |
351 | .proc_handler = &do_active_device | 351 | .proc_handler = do_active_device |
352 | }, | 352 | }, |
353 | {} | 353 | {} |
354 | }, | 354 | }, |
@@ -386,14 +386,13 @@ parport_device_sysctl_template = { | |||
386 | .data = NULL, | 386 | .data = NULL, |
387 | .maxlen = sizeof(unsigned long), | 387 | .maxlen = sizeof(unsigned long), |
388 | .mode = 0644, | 388 | .mode = 0644, |
389 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 389 | .proc_handler = proc_doulongvec_ms_jiffies_minmax, |
390 | .extra1 = (void*) &parport_min_timeslice_value, | 390 | .extra1 = (void*) &parport_min_timeslice_value, |
391 | .extra2 = (void*) &parport_max_timeslice_value | 391 | .extra2 = (void*) &parport_max_timeslice_value |
392 | }, | 392 | }, |
393 | }, | 393 | }, |
394 | { | 394 | { |
395 | { | 395 | { |
396 | .ctl_name = 0, | ||
397 | .procname = NULL, | 396 | .procname = NULL, |
398 | .data = NULL, | 397 | .data = NULL, |
399 | .maxlen = 0, | 398 | .maxlen = 0, |
@@ -438,7 +437,7 @@ parport_default_sysctl_table = { | |||
438 | .data = &parport_default_timeslice, | 437 | .data = &parport_default_timeslice, |
439 | .maxlen = sizeof(parport_default_timeslice), | 438 | .maxlen = sizeof(parport_default_timeslice), |
440 | .mode = 0644, | 439 | .mode = 0644, |
441 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | 440 | .proc_handler = proc_doulongvec_ms_jiffies_minmax, |
442 | .extra1 = (void*) &parport_min_timeslice_value, | 441 | .extra1 = (void*) &parport_min_timeslice_value, |
443 | .extra2 = (void*) &parport_max_timeslice_value | 442 | .extra2 = (void*) &parport_max_timeslice_value |
444 | }, | 443 | }, |
@@ -447,7 +446,7 @@ parport_default_sysctl_table = { | |||
447 | .data = &parport_default_spintime, | 446 | .data = &parport_default_spintime, |
448 | .maxlen = sizeof(parport_default_spintime), | 447 | .maxlen = sizeof(parport_default_spintime), |
449 | .mode = 0644, | 448 | .mode = 0644, |
450 | .proc_handler = &proc_dointvec_minmax, | 449 | .proc_handler = proc_dointvec_minmax, |
451 | .extra1 = (void*) &parport_min_spintime_value, | 450 | .extra1 = (void*) &parport_min_spintime_value, |
452 | .extra2 = (void*) &parport_max_spintime_value | 451 | .extra2 = (void*) &parport_max_spintime_value |
453 | }, | 452 | }, |
@@ -455,7 +454,6 @@ parport_default_sysctl_table = { | |||
455 | }, | 454 | }, |
456 | { | 455 | { |
457 | { | 456 | { |
458 | .ctl_name = DEV_PARPORT_DEFAULT, | ||
459 | .procname = "default", | 457 | .procname = "default", |
460 | .mode = 0555, | 458 | .mode = 0555, |
461 | .child = parport_default_sysctl_table.vars | 459 | .child = parport_default_sysctl_table.vars |
@@ -495,7 +493,6 @@ int parport_proc_register(struct parport *port) | |||
495 | t->vars[6 + i].extra2 = &port->probe_info[i]; | 493 | t->vars[6 + i].extra2 = &port->probe_info[i]; |
496 | 494 | ||
497 | t->port_dir[0].procname = port->name; | 495 | t->port_dir[0].procname = port->name; |
498 | t->port_dir[0].ctl_name = 0; | ||
499 | 496 | ||
500 | t->port_dir[0].child = t->vars; | 497 | t->port_dir[0].child = t->vars; |
501 | t->parport_dir[0].child = t->port_dir; | 498 | t->parport_dir[0].child = t->port_dir; |
@@ -534,11 +531,9 @@ int parport_device_proc_register(struct pardevice *device) | |||
534 | t->dev_dir[0].child = t->parport_dir; | 531 | t->dev_dir[0].child = t->parport_dir; |
535 | t->parport_dir[0].child = t->port_dir; | 532 | t->parport_dir[0].child = t->port_dir; |
536 | t->port_dir[0].procname = port->name; | 533 | t->port_dir[0].procname = port->name; |
537 | t->port_dir[0].ctl_name = 0; | ||
538 | t->port_dir[0].child = t->devices_root_dir; | 534 | t->port_dir[0].child = t->devices_root_dir; |
539 | t->devices_root_dir[0].child = t->device_dir; | 535 | t->devices_root_dir[0].child = t->device_dir; |
540 | 536 | ||
541 | t->device_dir[0].ctl_name = 0; | ||
542 | t->device_dir[0].procname = device->name; | 537 | t->device_dir[0].procname = device->name; |
543 | t->device_dir[0].child = t->vars; | 538 | t->device_dir[0].child = t->vars; |
544 | t->vars[0].data = &device->timeslice; | 539 | t->vars[0].data = &device->timeslice; |
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index b44462a6c6d3..740fe405c395 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c | |||
@@ -101,18 +101,17 @@ static struct ctl_table callhome_table[] = { | |||
101 | .mode = 0644, | 101 | .mode = 0644, |
102 | .proc_handler = proc_handler_callhome, | 102 | .proc_handler = proc_handler_callhome, |
103 | }, | 103 | }, |
104 | { .ctl_name = 0 } | 104 | {} |
105 | }; | 105 | }; |
106 | 106 | ||
107 | static struct ctl_table kern_dir_table[] = { | 107 | static struct ctl_table kern_dir_table[] = { |
108 | { | 108 | { |
109 | .ctl_name = CTL_KERN, | ||
110 | .procname = "kernel", | 109 | .procname = "kernel", |
111 | .maxlen = 0, | 110 | .maxlen = 0, |
112 | .mode = 0555, | 111 | .mode = 0555, |
113 | .child = callhome_table, | 112 | .child = callhome_table, |
114 | }, | 113 | }, |
115 | { .ctl_name = 0 } | 114 | {} |
116 | }; | 115 | }; |
117 | 116 | ||
118 | /* | 117 | /* |
diff --git a/drivers/scsi/scsi_sysctl.c b/drivers/scsi/scsi_sysctl.c index 63a30f566f3a..2b6b93f7d8ef 100644 --- a/drivers/scsi/scsi_sysctl.c +++ b/drivers/scsi/scsi_sysctl.c | |||
@@ -13,26 +13,23 @@ | |||
13 | 13 | ||
14 | 14 | ||
15 | static ctl_table scsi_table[] = { | 15 | static ctl_table scsi_table[] = { |
16 | { .ctl_name = DEV_SCSI_LOGGING_LEVEL, | 16 | { .procname = "logging_level", |
17 | .procname = "logging_level", | ||
18 | .data = &scsi_logging_level, | 17 | .data = &scsi_logging_level, |
19 | .maxlen = sizeof(scsi_logging_level), | 18 | .maxlen = sizeof(scsi_logging_level), |
20 | .mode = 0644, | 19 | .mode = 0644, |
21 | .proc_handler = &proc_dointvec }, | 20 | .proc_handler = proc_dointvec }, |
22 | { } | 21 | { } |
23 | }; | 22 | }; |
24 | 23 | ||
25 | static ctl_table scsi_dir_table[] = { | 24 | static ctl_table scsi_dir_table[] = { |
26 | { .ctl_name = DEV_SCSI, | 25 | { .procname = "scsi", |
27 | .procname = "scsi", | ||
28 | .mode = 0555, | 26 | .mode = 0555, |
29 | .child = scsi_table }, | 27 | .child = scsi_table }, |
30 | { } | 28 | { } |
31 | }; | 29 | }; |
32 | 30 | ||
33 | static ctl_table scsi_root_table[] = { | 31 | static ctl_table scsi_root_table[] = { |
34 | { .ctl_name = CTL_DEV, | 32 | { .procname = "dev", |
35 | .procname = "dev", | ||
36 | .mode = 0555, | 33 | .mode = 0555, |
37 | .child = scsi_dir_table }, | 34 | .child = scsi_dir_table }, |
38 | { } | 35 | { } |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e52257257279..50943ff78f4b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -1477,4 +1477,17 @@ config SERIAL_BCM63XX_CONSOLE | |||
1477 | If you have enabled the serial port on the bcm63xx CPU | 1477 | If you have enabled the serial port on the bcm63xx CPU |
1478 | you can make it the console by answering Y to this option. | 1478 | you can make it the console by answering Y to this option. |
1479 | 1479 | ||
1480 | config SERIAL_GRLIB_GAISLER_APBUART | ||
1481 | tristate "GRLIB APBUART serial support" | ||
1482 | depends on OF | ||
1483 | ---help--- | ||
1484 | Add support for the GRLIB APBUART serial port. | ||
1485 | |||
1486 | config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | ||
1487 | bool "Console on GRLIB APBUART serial port" | ||
1488 | depends on SERIAL_GRLIB_GAISLER_APBUART=y | ||
1489 | select SERIAL_CORE_CONSOLE | ||
1490 | help | ||
1491 | Support for running a console on the GRLIB APBUART | ||
1492 | |||
1480 | endmenu | 1493 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index d21d5dd5d048..5548fe7df61d 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -81,3 +81,4 @@ obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o | |||
81 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o | 81 | obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o |
82 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o | 82 | obj-$(CONFIG_SERIAL_QE) += ucc_uart.o |
83 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o | 83 | obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o |
84 | obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o | ||
diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c new file mode 100644 index 000000000000..fe91319b5f65 --- /dev/null +++ b/drivers/serial/apbuart.c | |||
@@ -0,0 +1,710 @@ | |||
1 | /* | ||
2 | * Driver for GRLIB serial ports (APBUART) | ||
3 | * | ||
4 | * Based on linux/drivers/serial/amba.c | ||
5 | * | ||
6 | * Copyright (C) 2000 Deep Blue Solutions Ltd. | ||
7 | * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de> | ||
8 | * Copyright (C) 2006 Daniel Hellstrom <daniel@gaisler.com>, Aeroflex Gaisler AB | ||
9 | * Copyright (C) 2008 Gilead Kutnick <kutnickg@zin-tech.com> | ||
10 | * Copyright (C) 2009 Kristoffer Glembo <kristoffer@gaisler.com>, Aeroflex Gaisler AB | ||
11 | */ | ||
12 | |||
13 | #if defined(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
14 | #define SUPPORT_SYSRQ | ||
15 | #endif | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/tty.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/serial.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/sysrq.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/serial_core.h> | ||
32 | #include <asm/irq.h> | ||
33 | |||
34 | #include "apbuart.h" | ||
35 | |||
36 | #define SERIAL_APBUART_MAJOR TTY_MAJOR | ||
37 | #define SERIAL_APBUART_MINOR 64 | ||
38 | #define UART_DUMMY_RSR_RX 0x8000 /* for ignore all read */ | ||
39 | |||
40 | static void apbuart_tx_chars(struct uart_port *port); | ||
41 | |||
42 | static void apbuart_stop_tx(struct uart_port *port) | ||
43 | { | ||
44 | unsigned int cr; | ||
45 | |||
46 | cr = UART_GET_CTRL(port); | ||
47 | cr &= ~UART_CTRL_TI; | ||
48 | UART_PUT_CTRL(port, cr); | ||
49 | } | ||
50 | |||
51 | static void apbuart_start_tx(struct uart_port *port) | ||
52 | { | ||
53 | unsigned int cr; | ||
54 | |||
55 | cr = UART_GET_CTRL(port); | ||
56 | cr |= UART_CTRL_TI; | ||
57 | UART_PUT_CTRL(port, cr); | ||
58 | |||
59 | if (UART_GET_STATUS(port) & UART_STATUS_THE) | ||
60 | apbuart_tx_chars(port); | ||
61 | } | ||
62 | |||
63 | static void apbuart_stop_rx(struct uart_port *port) | ||
64 | { | ||
65 | unsigned int cr; | ||
66 | |||
67 | cr = UART_GET_CTRL(port); | ||
68 | cr &= ~(UART_CTRL_RI); | ||
69 | UART_PUT_CTRL(port, cr); | ||
70 | } | ||
71 | |||
72 | static void apbuart_enable_ms(struct uart_port *port) | ||
73 | { | ||
74 | /* No modem status change interrupts for APBUART */ | ||
75 | } | ||
76 | |||
77 | static void apbuart_rx_chars(struct uart_port *port) | ||
78 | { | ||
79 | struct tty_struct *tty = port->state->port.tty; | ||
80 | unsigned int status, ch, rsr, flag; | ||
81 | unsigned int max_chars = port->fifosize; | ||
82 | |||
83 | status = UART_GET_STATUS(port); | ||
84 | |||
85 | while (UART_RX_DATA(status) && (max_chars--)) { | ||
86 | |||
87 | ch = UART_GET_CHAR(port); | ||
88 | flag = TTY_NORMAL; | ||
89 | |||
90 | port->icount.rx++; | ||
91 | |||
92 | rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX; | ||
93 | UART_PUT_STATUS(port, 0); | ||
94 | if (rsr & UART_STATUS_ERR) { | ||
95 | |||
96 | if (rsr & UART_STATUS_BR) { | ||
97 | rsr &= ~(UART_STATUS_FE | UART_STATUS_PE); | ||
98 | port->icount.brk++; | ||
99 | if (uart_handle_break(port)) | ||
100 | goto ignore_char; | ||
101 | } else if (rsr & UART_STATUS_PE) { | ||
102 | port->icount.parity++; | ||
103 | } else if (rsr & UART_STATUS_FE) { | ||
104 | port->icount.frame++; | ||
105 | } | ||
106 | if (rsr & UART_STATUS_OE) | ||
107 | port->icount.overrun++; | ||
108 | |||
109 | rsr &= port->read_status_mask; | ||
110 | |||
111 | if (rsr & UART_STATUS_PE) | ||
112 | flag = TTY_PARITY; | ||
113 | else if (rsr & UART_STATUS_FE) | ||
114 | flag = TTY_FRAME; | ||
115 | } | ||
116 | |||
117 | if (uart_handle_sysrq_char(port, ch)) | ||
118 | goto ignore_char; | ||
119 | |||
120 | uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag); | ||
121 | |||
122 | |||
123 | ignore_char: | ||
124 | status = UART_GET_STATUS(port); | ||
125 | } | ||
126 | |||
127 | tty_flip_buffer_push(tty); | ||
128 | } | ||
129 | |||
130 | static void apbuart_tx_chars(struct uart_port *port) | ||
131 | { | ||
132 | struct circ_buf *xmit = &port->state->xmit; | ||
133 | int count; | ||
134 | |||
135 | if (port->x_char) { | ||
136 | UART_PUT_CHAR(port, port->x_char); | ||
137 | port->icount.tx++; | ||
138 | port->x_char = 0; | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
143 | apbuart_stop_tx(port); | ||
144 | return; | ||
145 | } | ||
146 | |||
147 | /* amba: fill FIFO */ | ||
148 | count = port->fifosize >> 1; | ||
149 | do { | ||
150 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | ||
151 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
152 | port->icount.tx++; | ||
153 | if (uart_circ_empty(xmit)) | ||
154 | break; | ||
155 | } while (--count > 0); | ||
156 | |||
157 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
158 | uart_write_wakeup(port); | ||
159 | |||
160 | if (uart_circ_empty(xmit)) | ||
161 | apbuart_stop_tx(port); | ||
162 | } | ||
163 | |||
164 | static irqreturn_t apbuart_int(int irq, void *dev_id) | ||
165 | { | ||
166 | struct uart_port *port = dev_id; | ||
167 | unsigned int status; | ||
168 | |||
169 | spin_lock(&port->lock); | ||
170 | |||
171 | status = UART_GET_STATUS(port); | ||
172 | if (status & UART_STATUS_DR) | ||
173 | apbuart_rx_chars(port); | ||
174 | if (status & UART_STATUS_THE) | ||
175 | apbuart_tx_chars(port); | ||
176 | |||
177 | spin_unlock(&port->lock); | ||
178 | |||
179 | return IRQ_HANDLED; | ||
180 | } | ||
181 | |||
182 | static unsigned int apbuart_tx_empty(struct uart_port *port) | ||
183 | { | ||
184 | unsigned int status = UART_GET_STATUS(port); | ||
185 | return status & UART_STATUS_THE ? TIOCSER_TEMT : 0; | ||
186 | } | ||
187 | |||
188 | static unsigned int apbuart_get_mctrl(struct uart_port *port) | ||
189 | { | ||
190 | /* The GRLIB APBUART handles flow control in hardware */ | ||
191 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
192 | } | ||
193 | |||
194 | static void apbuart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
195 | { | ||
196 | /* The GRLIB APBUART handles flow control in hardware */ | ||
197 | } | ||
198 | |||
199 | static void apbuart_break_ctl(struct uart_port *port, int break_state) | ||
200 | { | ||
201 | /* We don't support sending break */ | ||
202 | } | ||
203 | |||
204 | static int apbuart_startup(struct uart_port *port) | ||
205 | { | ||
206 | int retval; | ||
207 | unsigned int cr; | ||
208 | |||
209 | /* Allocate the IRQ */ | ||
210 | retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port); | ||
211 | if (retval) | ||
212 | return retval; | ||
213 | |||
214 | /* Finally, enable interrupts */ | ||
215 | cr = UART_GET_CTRL(port); | ||
216 | UART_PUT_CTRL(port, | ||
217 | cr | UART_CTRL_RE | UART_CTRL_TE | | ||
218 | UART_CTRL_RI | UART_CTRL_TI); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static void apbuart_shutdown(struct uart_port *port) | ||
224 | { | ||
225 | unsigned int cr; | ||
226 | |||
227 | /* disable all interrupts, disable the port */ | ||
228 | cr = UART_GET_CTRL(port); | ||
229 | UART_PUT_CTRL(port, | ||
230 | cr & ~(UART_CTRL_RE | UART_CTRL_TE | | ||
231 | UART_CTRL_RI | UART_CTRL_TI)); | ||
232 | |||
233 | /* Free the interrupt */ | ||
234 | free_irq(port->irq, port); | ||
235 | } | ||
236 | |||
237 | static void apbuart_set_termios(struct uart_port *port, | ||
238 | struct ktermios *termios, struct ktermios *old) | ||
239 | { | ||
240 | unsigned int cr; | ||
241 | unsigned long flags; | ||
242 | unsigned int baud, quot; | ||
243 | |||
244 | /* Ask the core to calculate the divisor for us. */ | ||
245 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | ||
246 | if (baud == 0) | ||
247 | panic("invalid baudrate %i\n", port->uartclk / 16); | ||
248 | |||
249 | /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */ | ||
250 | quot = (uart_get_divisor(port, baud)) * 2; | ||
251 | cr = UART_GET_CTRL(port); | ||
252 | cr &= ~(UART_CTRL_PE | UART_CTRL_PS); | ||
253 | |||
254 | if (termios->c_cflag & PARENB) { | ||
255 | cr |= UART_CTRL_PE; | ||
256 | if ((termios->c_cflag & PARODD)) | ||
257 | cr |= UART_CTRL_PS; | ||
258 | } | ||
259 | |||
260 | /* Enable flow control. */ | ||
261 | if (termios->c_cflag & CRTSCTS) | ||
262 | cr |= UART_CTRL_FL; | ||
263 | |||
264 | spin_lock_irqsave(&port->lock, flags); | ||
265 | |||
266 | /* Update the per-port timeout. */ | ||
267 | uart_update_timeout(port, termios->c_cflag, baud); | ||
268 | |||
269 | port->read_status_mask = UART_STATUS_OE; | ||
270 | if (termios->c_iflag & INPCK) | ||
271 | port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE; | ||
272 | |||
273 | /* Characters to ignore */ | ||
274 | port->ignore_status_mask = 0; | ||
275 | if (termios->c_iflag & IGNPAR) | ||
276 | port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE; | ||
277 | |||
278 | /* Ignore all characters if CREAD is not set. */ | ||
279 | if ((termios->c_cflag & CREAD) == 0) | ||
280 | port->ignore_status_mask |= UART_DUMMY_RSR_RX; | ||
281 | |||
282 | /* Set baud rate */ | ||
283 | quot -= 1; | ||
284 | UART_PUT_SCAL(port, quot); | ||
285 | UART_PUT_CTRL(port, cr); | ||
286 | |||
287 | spin_unlock_irqrestore(&port->lock, flags); | ||
288 | } | ||
289 | |||
290 | static const char *apbuart_type(struct uart_port *port) | ||
291 | { | ||
292 | return port->type == PORT_APBUART ? "GRLIB/APBUART" : NULL; | ||
293 | } | ||
294 | |||
295 | static void apbuart_release_port(struct uart_port *port) | ||
296 | { | ||
297 | release_mem_region(port->mapbase, 0x100); | ||
298 | } | ||
299 | |||
300 | static int apbuart_request_port(struct uart_port *port) | ||
301 | { | ||
302 | return request_mem_region(port->mapbase, 0x100, "grlib-apbuart") | ||
303 | != NULL ? 0 : -EBUSY; | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* Configure/autoconfigure the port */ | ||
308 | static void apbuart_config_port(struct uart_port *port, int flags) | ||
309 | { | ||
310 | if (flags & UART_CONFIG_TYPE) { | ||
311 | port->type = PORT_APBUART; | ||
312 | apbuart_request_port(port); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* Verify the new serial_struct (for TIOCSSERIAL) */ | ||
317 | static int apbuart_verify_port(struct uart_port *port, | ||
318 | struct serial_struct *ser) | ||
319 | { | ||
320 | int ret = 0; | ||
321 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_APBUART) | ||
322 | ret = -EINVAL; | ||
323 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | ||
324 | ret = -EINVAL; | ||
325 | if (ser->baud_base < 9600) | ||
326 | ret = -EINVAL; | ||
327 | return ret; | ||
328 | } | ||
329 | |||
330 | static struct uart_ops grlib_apbuart_ops = { | ||
331 | .tx_empty = apbuart_tx_empty, | ||
332 | .set_mctrl = apbuart_set_mctrl, | ||
333 | .get_mctrl = apbuart_get_mctrl, | ||
334 | .stop_tx = apbuart_stop_tx, | ||
335 | .start_tx = apbuart_start_tx, | ||
336 | .stop_rx = apbuart_stop_rx, | ||
337 | .enable_ms = apbuart_enable_ms, | ||
338 | .break_ctl = apbuart_break_ctl, | ||
339 | .startup = apbuart_startup, | ||
340 | .shutdown = apbuart_shutdown, | ||
341 | .set_termios = apbuart_set_termios, | ||
342 | .type = apbuart_type, | ||
343 | .release_port = apbuart_release_port, | ||
344 | .request_port = apbuart_request_port, | ||
345 | .config_port = apbuart_config_port, | ||
346 | .verify_port = apbuart_verify_port, | ||
347 | }; | ||
348 | |||
349 | static struct uart_port grlib_apbuart_ports[UART_NR]; | ||
350 | static struct device_node *grlib_apbuart_nodes[UART_NR]; | ||
351 | |||
352 | static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber) | ||
353 | { | ||
354 | int ctrl, loop = 0; | ||
355 | int status; | ||
356 | int fifosize; | ||
357 | unsigned long flags; | ||
358 | |||
359 | ctrl = UART_GET_CTRL(port); | ||
360 | |||
361 | /* | ||
362 | * Enable the transceiver and wait for it to be ready to send data. | ||
363 | * Clear interrupts so that this process will not be externally | ||
364 | * interrupted in the middle (which can cause the transceiver to | ||
365 | * drain prematurely). | ||
366 | */ | ||
367 | |||
368 | local_irq_save(flags); | ||
369 | |||
370 | UART_PUT_CTRL(port, ctrl | UART_CTRL_TE); | ||
371 | |||
372 | while (!UART_TX_READY(UART_GET_STATUS(port))) | ||
373 | loop++; | ||
374 | |||
375 | /* | ||
376 | * Disable the transceiver so data isn't actually sent during the | ||
377 | * actual test. | ||
378 | */ | ||
379 | |||
380 | UART_PUT_CTRL(port, ctrl & ~(UART_CTRL_TE)); | ||
381 | |||
382 | fifosize = 1; | ||
383 | UART_PUT_CHAR(port, 0); | ||
384 | |||
385 | /* | ||
386 | * So long as transmitting a character increments the tranceivier FIFO | ||
387 | * length the FIFO must be at least that big. These bytes will | ||
388 | * automatically drain off of the FIFO. | ||
389 | */ | ||
390 | |||
391 | status = UART_GET_STATUS(port); | ||
392 | while (((status >> 20) & 0x3F) == fifosize) { | ||
393 | fifosize++; | ||
394 | UART_PUT_CHAR(port, 0); | ||
395 | status = UART_GET_STATUS(port); | ||
396 | } | ||
397 | |||
398 | fifosize--; | ||
399 | |||
400 | UART_PUT_CTRL(port, ctrl); | ||
401 | local_irq_restore(flags); | ||
402 | |||
403 | if (fifosize == 0) | ||
404 | fifosize = 1; | ||
405 | |||
406 | return fifosize; | ||
407 | } | ||
408 | |||
409 | static void apbuart_flush_fifo(struct uart_port *port) | ||
410 | { | ||
411 | int i; | ||
412 | |||
413 | for (i = 0; i < port->fifosize; i++) | ||
414 | UART_GET_CHAR(port); | ||
415 | } | ||
416 | |||
417 | |||
418 | /* ======================================================================== */ | ||
419 | /* Console driver, if enabled */ | ||
420 | /* ======================================================================== */ | ||
421 | |||
422 | #ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE | ||
423 | |||
424 | static void apbuart_console_putchar(struct uart_port *port, int ch) | ||
425 | { | ||
426 | unsigned int status; | ||
427 | do { | ||
428 | status = UART_GET_STATUS(port); | ||
429 | } while (!UART_TX_READY(status)); | ||
430 | UART_PUT_CHAR(port, ch); | ||
431 | } | ||
432 | |||
433 | static void | ||
434 | apbuart_console_write(struct console *co, const char *s, unsigned int count) | ||
435 | { | ||
436 | struct uart_port *port = &grlib_apbuart_ports[co->index]; | ||
437 | unsigned int status, old_cr, new_cr; | ||
438 | |||
439 | /* First save the CR then disable the interrupts */ | ||
440 | old_cr = UART_GET_CTRL(port); | ||
441 | new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI); | ||
442 | UART_PUT_CTRL(port, new_cr); | ||
443 | |||
444 | uart_console_write(port, s, count, apbuart_console_putchar); | ||
445 | |||
446 | /* | ||
447 | * Finally, wait for transmitter to become empty | ||
448 | * and restore the TCR | ||
449 | */ | ||
450 | do { | ||
451 | status = UART_GET_STATUS(port); | ||
452 | } while (!UART_TX_READY(status)); | ||
453 | UART_PUT_CTRL(port, old_cr); | ||
454 | } | ||
455 | |||
456 | static void __init | ||
457 | apbuart_console_get_options(struct uart_port *port, int *baud, | ||
458 | int *parity, int *bits) | ||
459 | { | ||
460 | if (UART_GET_CTRL(port) & (UART_CTRL_RE | UART_CTRL_TE)) { | ||
461 | |||
462 | unsigned int quot, status; | ||
463 | status = UART_GET_STATUS(port); | ||
464 | |||
465 | *parity = 'n'; | ||
466 | if (status & UART_CTRL_PE) { | ||
467 | if ((status & UART_CTRL_PS) == 0) | ||
468 | *parity = 'e'; | ||
469 | else | ||
470 | *parity = 'o'; | ||
471 | } | ||
472 | |||
473 | *bits = 8; | ||
474 | quot = UART_GET_SCAL(port) / 8; | ||
475 | *baud = port->uartclk / (16 * (quot + 1)); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | static int __init apbuart_console_setup(struct console *co, char *options) | ||
480 | { | ||
481 | struct uart_port *port; | ||
482 | int baud = 38400; | ||
483 | int bits = 8; | ||
484 | int parity = 'n'; | ||
485 | int flow = 'n'; | ||
486 | |||
487 | pr_debug("apbuart_console_setup co=%p, co->index=%i, options=%s\n", | ||
488 | co, co->index, options); | ||
489 | |||
490 | /* | ||
491 | * Check whether an invalid uart number has been specified, and | ||
492 | * if so, search for the first available port that does have | ||
493 | * console support. | ||
494 | */ | ||
495 | if (co->index >= grlib_apbuart_port_nr) | ||
496 | co->index = 0; | ||
497 | |||
498 | port = &grlib_apbuart_ports[co->index]; | ||
499 | |||
500 | spin_lock_init(&port->lock); | ||
501 | |||
502 | if (options) | ||
503 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
504 | else | ||
505 | apbuart_console_get_options(port, &baud, &parity, &bits); | ||
506 | |||
507 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
508 | } | ||
509 | |||
510 | static struct uart_driver grlib_apbuart_driver; | ||
511 | |||
512 | static struct console grlib_apbuart_console = { | ||
513 | .name = "ttyS", | ||
514 | .write = apbuart_console_write, | ||
515 | .device = uart_console_device, | ||
516 | .setup = apbuart_console_setup, | ||
517 | .flags = CON_PRINTBUFFER, | ||
518 | .index = -1, | ||
519 | .data = &grlib_apbuart_driver, | ||
520 | }; | ||
521 | |||
522 | |||
523 | static void grlib_apbuart_configure(void); | ||
524 | |||
525 | static int __init apbuart_console_init(void) | ||
526 | { | ||
527 | grlib_apbuart_configure(); | ||
528 | register_console(&grlib_apbuart_console); | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | console_initcall(apbuart_console_init); | ||
533 | |||
534 | #define APBUART_CONSOLE (&grlib_apbuart_console) | ||
535 | #else | ||
536 | #define APBUART_CONSOLE NULL | ||
537 | #endif | ||
538 | |||
539 | static struct uart_driver grlib_apbuart_driver = { | ||
540 | .owner = THIS_MODULE, | ||
541 | .driver_name = "serial", | ||
542 | .dev_name = "ttyS", | ||
543 | .major = SERIAL_APBUART_MAJOR, | ||
544 | .minor = SERIAL_APBUART_MINOR, | ||
545 | .nr = UART_NR, | ||
546 | .cons = APBUART_CONSOLE, | ||
547 | }; | ||
548 | |||
549 | |||
550 | /* ======================================================================== */ | ||
551 | /* OF Platform Driver */ | ||
552 | /* ======================================================================== */ | ||
553 | |||
554 | static int __devinit apbuart_probe(struct of_device *op, | ||
555 | const struct of_device_id *match) | ||
556 | { | ||
557 | int i = -1; | ||
558 | struct uart_port *port = NULL; | ||
559 | |||
560 | i = 0; | ||
561 | for (i = 0; i < grlib_apbuart_port_nr; i++) { | ||
562 | if (op->node == grlib_apbuart_nodes[i]) | ||
563 | break; | ||
564 | } | ||
565 | |||
566 | port = &grlib_apbuart_ports[i]; | ||
567 | port->dev = &op->dev; | ||
568 | |||
569 | uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port); | ||
570 | |||
571 | apbuart_flush_fifo((struct uart_port *) port); | ||
572 | |||
573 | printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n", | ||
574 | (unsigned long long) port->mapbase, port->irq); | ||
575 | return 0; | ||
576 | |||
577 | } | ||
578 | |||
579 | static struct of_device_id __initdata apbuart_match[] = { | ||
580 | { | ||
581 | .name = "GAISLER_APBUART", | ||
582 | }, | ||
583 | {}, | ||
584 | }; | ||
585 | |||
586 | static struct of_platform_driver grlib_apbuart_of_driver = { | ||
587 | .match_table = apbuart_match, | ||
588 | .probe = apbuart_probe, | ||
589 | .driver = { | ||
590 | .owner = THIS_MODULE, | ||
591 | .name = "grlib-apbuart", | ||
592 | }, | ||
593 | }; | ||
594 | |||
595 | |||
596 | static void grlib_apbuart_configure(void) | ||
597 | { | ||
598 | static int enum_done; | ||
599 | struct device_node *np, *rp; | ||
600 | struct uart_port *port = NULL; | ||
601 | const u32 *prop; | ||
602 | int freq_khz; | ||
603 | int v = 0, d = 0; | ||
604 | unsigned int addr; | ||
605 | int irq, line; | ||
606 | struct amba_prom_registers *regs; | ||
607 | |||
608 | if (enum_done) | ||
609 | return; | ||
610 | |||
611 | /* Get bus frequency */ | ||
612 | rp = of_find_node_by_path("/"); | ||
613 | rp = of_get_next_child(rp, NULL); | ||
614 | prop = of_get_property(rp, "clock-frequency", NULL); | ||
615 | freq_khz = *prop; | ||
616 | |||
617 | line = 0; | ||
618 | for_each_matching_node(np, apbuart_match) { | ||
619 | |||
620 | int *vendor = (int *) of_get_property(np, "vendor", NULL); | ||
621 | int *device = (int *) of_get_property(np, "device", NULL); | ||
622 | int *irqs = (int *) of_get_property(np, "interrupts", NULL); | ||
623 | regs = (struct amba_prom_registers *) | ||
624 | of_get_property(np, "reg", NULL); | ||
625 | |||
626 | if (vendor) | ||
627 | v = *vendor; | ||
628 | if (device) | ||
629 | d = *device; | ||
630 | |||
631 | if (!irqs || !regs) | ||
632 | return; | ||
633 | |||
634 | grlib_apbuart_nodes[line] = np; | ||
635 | |||
636 | addr = regs->phys_addr; | ||
637 | irq = *irqs; | ||
638 | |||
639 | port = &grlib_apbuart_ports[line]; | ||
640 | |||
641 | port->mapbase = addr; | ||
642 | port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map)); | ||
643 | port->irq = irq; | ||
644 | port->iotype = UPIO_MEM; | ||
645 | port->ops = &grlib_apbuart_ops; | ||
646 | port->flags = UPF_BOOT_AUTOCONF; | ||
647 | port->line = line; | ||
648 | port->uartclk = freq_khz * 1000; | ||
649 | port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line); | ||
650 | line++; | ||
651 | |||
652 | /* We support maximum UART_NR uarts ... */ | ||
653 | if (line == UART_NR) | ||
654 | break; | ||
655 | |||
656 | } | ||
657 | |||
658 | enum_done = 1; | ||
659 | |||
660 | grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line; | ||
661 | } | ||
662 | |||
663 | static int __init grlib_apbuart_init(void) | ||
664 | { | ||
665 | int ret; | ||
666 | |||
667 | /* Find all APBUARTS in device the tree and initialize their ports */ | ||
668 | grlib_apbuart_configure(); | ||
669 | |||
670 | printk(KERN_INFO "Serial: GRLIB APBUART driver\n"); | ||
671 | |||
672 | ret = uart_register_driver(&grlib_apbuart_driver); | ||
673 | |||
674 | if (ret) { | ||
675 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", | ||
676 | __FILE__, ret); | ||
677 | return ret; | ||
678 | } | ||
679 | |||
680 | ret = of_register_platform_driver(&grlib_apbuart_of_driver); | ||
681 | if (ret) { | ||
682 | printk(KERN_ERR | ||
683 | "%s: of_register_platform_driver failed (%i)\n", | ||
684 | __FILE__, ret); | ||
685 | uart_unregister_driver(&grlib_apbuart_driver); | ||
686 | return ret; | ||
687 | } | ||
688 | |||
689 | return ret; | ||
690 | } | ||
691 | |||
692 | static void __exit grlib_apbuart_exit(void) | ||
693 | { | ||
694 | int i; | ||
695 | |||
696 | for (i = 0; i < grlib_apbuart_port_nr; i++) | ||
697 | uart_remove_one_port(&grlib_apbuart_driver, | ||
698 | &grlib_apbuart_ports[i]); | ||
699 | |||
700 | uart_unregister_driver(&grlib_apbuart_driver); | ||
701 | of_unregister_platform_driver(&grlib_apbuart_of_driver); | ||
702 | } | ||
703 | |||
704 | module_init(grlib_apbuart_init); | ||
705 | module_exit(grlib_apbuart_exit); | ||
706 | |||
707 | MODULE_AUTHOR("Aeroflex Gaisler AB"); | ||
708 | MODULE_DESCRIPTION("GRLIB APBUART serial driver"); | ||
709 | MODULE_VERSION("2.1"); | ||
710 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/apbuart.h b/drivers/serial/apbuart.h new file mode 100644 index 000000000000..5faf87c8d2bc --- /dev/null +++ b/drivers/serial/apbuart.h | |||
@@ -0,0 +1,64 @@ | |||
1 | #ifndef __GRLIB_APBUART_H__ | ||
2 | #define __GRLIB_APBUART_H__ | ||
3 | |||
4 | #include <asm/io.h> | ||
5 | |||
6 | #define UART_NR 8 | ||
7 | static int grlib_apbuart_port_nr; | ||
8 | |||
9 | struct grlib_apbuart_regs_map { | ||
10 | u32 data; | ||
11 | u32 status; | ||
12 | u32 ctrl; | ||
13 | u32 scaler; | ||
14 | }; | ||
15 | |||
16 | struct amba_prom_registers { | ||
17 | unsigned int phys_addr; | ||
18 | unsigned int reg_size; | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * The following defines the bits in the APBUART Status Registers. | ||
23 | */ | ||
24 | #define UART_STATUS_DR 0x00000001 /* Data Ready */ | ||
25 | #define UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ | ||
26 | #define UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ | ||
27 | #define UART_STATUS_BR 0x00000008 /* Break Error */ | ||
28 | #define UART_STATUS_OE 0x00000010 /* RX Overrun Error */ | ||
29 | #define UART_STATUS_PE 0x00000020 /* RX Parity Error */ | ||
30 | #define UART_STATUS_FE 0x00000040 /* RX Framing Error */ | ||
31 | #define UART_STATUS_ERR 0x00000078 /* Error Mask */ | ||
32 | |||
33 | /* | ||
34 | * The following defines the bits in the APBUART Ctrl Registers. | ||
35 | */ | ||
36 | #define UART_CTRL_RE 0x00000001 /* Receiver enable */ | ||
37 | #define UART_CTRL_TE 0x00000002 /* Transmitter enable */ | ||
38 | #define UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ | ||
39 | #define UART_CTRL_TI 0x00000008 /* Transmitter irq */ | ||
40 | #define UART_CTRL_PS 0x00000010 /* Parity select */ | ||
41 | #define UART_CTRL_PE 0x00000020 /* Parity enable */ | ||
42 | #define UART_CTRL_FL 0x00000040 /* Flow control enable */ | ||
43 | #define UART_CTRL_LB 0x00000080 /* Loopback enable */ | ||
44 | |||
45 | #define APBBASE(port) ((struct grlib_apbuart_regs_map *)((port)->membase)) | ||
46 | |||
47 | #define APBBASE_DATA_P(port) (&(APBBASE(port)->data)) | ||
48 | #define APBBASE_STATUS_P(port) (&(APBBASE(port)->status)) | ||
49 | #define APBBASE_CTRL_P(port) (&(APBBASE(port)->ctrl)) | ||
50 | #define APBBASE_SCALAR_P(port) (&(APBBASE(port)->scaler)) | ||
51 | |||
52 | #define UART_GET_CHAR(port) (__raw_readl(APBBASE_DATA_P(port))) | ||
53 | #define UART_PUT_CHAR(port, v) (__raw_writel(v, APBBASE_DATA_P(port))) | ||
54 | #define UART_GET_STATUS(port) (__raw_readl(APBBASE_STATUS_P(port))) | ||
55 | #define UART_PUT_STATUS(port, v)(__raw_writel(v, APBBASE_STATUS_P(port))) | ||
56 | #define UART_GET_CTRL(port) (__raw_readl(APBBASE_CTRL_P(port))) | ||
57 | #define UART_PUT_CTRL(port, v) (__raw_writel(v, APBBASE_CTRL_P(port))) | ||
58 | #define UART_GET_SCAL(port) (__raw_readl(APBBASE_SCALAR_P(port))) | ||
59 | #define UART_PUT_SCAL(port, v) (__raw_writel(v, APBBASE_SCALAR_P(port))) | ||
60 | |||
61 | #define UART_RX_DATA(s) (((s) & UART_STATUS_DR) != 0) | ||
62 | #define UART_TX_READY(s) (((s) & UART_STATUS_THE) != 0) | ||
63 | |||
64 | #endif /* __GRLIB_APBUART_H__ */ | ||
diff --git a/drivers/staging/arlan/arlan-proc.c b/drivers/staging/arlan/arlan-proc.c index a8b689635a3b..b22983e6c0cf 100644 --- a/drivers/staging/arlan/arlan-proc.c +++ b/drivers/staging/arlan/arlan-proc.c | |||
@@ -816,84 +816,83 @@ static int arlan_sysctl_reset(ctl_table * ctl, int write, | |||
816 | 816 | ||
817 | 817 | ||
818 | /* Place files in /proc/sys/dev/arlan */ | 818 | /* Place files in /proc/sys/dev/arlan */ |
819 | #define CTBLN(num,card,nam) \ | 819 | #define CTBLN(card,nam) \ |
820 | { .ctl_name = num,\ | 820 | { .procname = #nam,\ |
821 | .procname = #nam,\ | ||
822 | .data = &(arlan_conf[card].nam),\ | 821 | .data = &(arlan_conf[card].nam),\ |
823 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec} | 822 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec} |
824 | #ifdef ARLAN_DEBUGGING | 823 | #ifdef ARLAN_DEBUGGING |
825 | 824 | ||
826 | #define ARLAN_PROC_DEBUG_ENTRIES \ | 825 | #define ARLAN_PROC_DEBUG_ENTRIES \ |
827 | { .ctl_name = 48, .procname = "entry_exit_debug",\ | 826 | { .procname = "entry_exit_debug",\ |
828 | .data = &arlan_entry_and_exit_debug,\ | 827 | .data = &arlan_entry_and_exit_debug,\ |
829 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec},\ | 828 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec},\ |
830 | { .ctl_name = 49, .procname = "debug", .data = &arlan_debug,\ | 829 | { .procname = "debug", .data = &arlan_debug,\ |
831 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec}, | 830 | .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec}, |
832 | #else | 831 | #else |
833 | #define ARLAN_PROC_DEBUG_ENTRIES | 832 | #define ARLAN_PROC_DEBUG_ENTRIES |
834 | #endif | 833 | #endif |
835 | 834 | ||
836 | #define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\ | 835 | #define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\ |
837 | CTBLN(1,cardNo,spreadingCode),\ | 836 | CTBLN(cardNo,spreadingCode),\ |
838 | CTBLN(2,cardNo, channelNumber),\ | 837 | CTBLN(cardNo, channelNumber),\ |
839 | CTBLN(3,cardNo, scramblingDisable),\ | 838 | CTBLN(cardNo, scramblingDisable),\ |
840 | CTBLN(4,cardNo, txAttenuation),\ | 839 | CTBLN(cardNo, txAttenuation),\ |
841 | CTBLN(5,cardNo, systemId), \ | 840 | CTBLN(cardNo, systemId), \ |
842 | CTBLN(6,cardNo, maxDatagramSize),\ | 841 | CTBLN(cardNo, maxDatagramSize),\ |
843 | CTBLN(7,cardNo, maxFrameSize),\ | 842 | CTBLN(cardNo, maxFrameSize),\ |
844 | CTBLN(8,cardNo, maxRetries),\ | 843 | CTBLN(cardNo, maxRetries),\ |
845 | CTBLN(9,cardNo, receiveMode),\ | 844 | CTBLN(cardNo, receiveMode),\ |
846 | CTBLN(10,cardNo, priority),\ | 845 | CTBLN(cardNo, priority),\ |
847 | CTBLN(11,cardNo, rootOrRepeater),\ | 846 | CTBLN(cardNo, rootOrRepeater),\ |
848 | CTBLN(12,cardNo, SID),\ | 847 | CTBLN(cardNo, SID),\ |
849 | CTBLN(13,cardNo, registrationMode),\ | 848 | CTBLN(cardNo, registrationMode),\ |
850 | CTBLN(14,cardNo, registrationFill),\ | 849 | CTBLN(cardNo, registrationFill),\ |
851 | CTBLN(15,cardNo, localTalkAddress),\ | 850 | CTBLN(cardNo, localTalkAddress),\ |
852 | CTBLN(16,cardNo, codeFormat),\ | 851 | CTBLN(cardNo, codeFormat),\ |
853 | CTBLN(17,cardNo, numChannels),\ | 852 | CTBLN(cardNo, numChannels),\ |
854 | CTBLN(18,cardNo, channel1),\ | 853 | CTBLN(cardNo, channel1),\ |
855 | CTBLN(19,cardNo, channel2),\ | 854 | CTBLN(cardNo, channel2),\ |
856 | CTBLN(20,cardNo, channel3),\ | 855 | CTBLN(cardNo, channel3),\ |
857 | CTBLN(21,cardNo, channel4),\ | 856 | CTBLN(cardNo, channel4),\ |
858 | CTBLN(22,cardNo, txClear),\ | 857 | CTBLN(cardNo, txClear),\ |
859 | CTBLN(23,cardNo, txRetries),\ | 858 | CTBLN(cardNo, txRetries),\ |
860 | CTBLN(24,cardNo, txRouting),\ | 859 | CTBLN(cardNo, txRouting),\ |
861 | CTBLN(25,cardNo, txScrambled),\ | 860 | CTBLN(cardNo, txScrambled),\ |
862 | CTBLN(26,cardNo, rxParameter),\ | 861 | CTBLN(cardNo, rxParameter),\ |
863 | CTBLN(27,cardNo, txTimeoutMs),\ | 862 | CTBLN(cardNo, txTimeoutMs),\ |
864 | CTBLN(28,cardNo, waitCardTimeout),\ | 863 | CTBLN(cardNo, waitCardTimeout),\ |
865 | CTBLN(29,cardNo, channelSet), \ | 864 | CTBLN(cardNo, channelSet), \ |
866 | {.ctl_name = 30, .procname = "name",\ | 865 | { .procname = "name",\ |
867 | .data = arlan_conf[cardNo].siteName,\ | 866 | .data = arlan_conf[cardNo].siteName,\ |
868 | .maxlen = 16, .mode = 0600, .proc_handler = &proc_dostring},\ | 867 | .maxlen = 16, .mode = 0600, .proc_handler = proc_dostring},\ |
869 | CTBLN(31,cardNo,waitTime),\ | 868 | CTBLN(cardNo,waitTime),\ |
870 | CTBLN(32,cardNo,lParameter),\ | 869 | CTBLN(cardNo,lParameter),\ |
871 | CTBLN(33,cardNo,_15),\ | 870 | CTBLN(cardNo,_15),\ |
872 | CTBLN(34,cardNo,headerSize),\ | 871 | CTBLN(cardNo,headerSize),\ |
873 | CTBLN(36,cardNo,tx_delay_ms),\ | 872 | CTBLN(cardNo,tx_delay_ms),\ |
874 | CTBLN(37,cardNo,retries),\ | 873 | CTBLN(cardNo,retries),\ |
875 | CTBLN(38,cardNo,ReTransmitPacketMaxSize),\ | 874 | CTBLN(cardNo,ReTransmitPacketMaxSize),\ |
876 | CTBLN(39,cardNo,waitReTransmitPacketMaxSize),\ | 875 | CTBLN(cardNo,waitReTransmitPacketMaxSize),\ |
877 | CTBLN(40,cardNo,fastReTransCount),\ | 876 | CTBLN(cardNo,fastReTransCount),\ |
878 | CTBLN(41,cardNo,driverRetransmissions),\ | 877 | CTBLN(cardNo,driverRetransmissions),\ |
879 | CTBLN(42,cardNo,txAckTimeoutMs),\ | 878 | CTBLN(cardNo,txAckTimeoutMs),\ |
880 | CTBLN(43,cardNo,registrationInterrupts),\ | 879 | CTBLN(cardNo,registrationInterrupts),\ |
881 | CTBLN(44,cardNo,hardwareType),\ | 880 | CTBLN(cardNo,hardwareType),\ |
882 | CTBLN(45,cardNo,radioType),\ | 881 | CTBLN(cardNo,radioType),\ |
883 | CTBLN(46,cardNo,writeEEPROM),\ | 882 | CTBLN(cardNo,writeEEPROM),\ |
884 | CTBLN(47,cardNo,writeRadioType),\ | 883 | CTBLN(cardNo,writeRadioType),\ |
885 | ARLAN_PROC_DEBUG_ENTRIES\ | 884 | ARLAN_PROC_DEBUG_ENTRIES\ |
886 | CTBLN(50,cardNo,in_speed),\ | 885 | CTBLN(cardNo,in_speed),\ |
887 | CTBLN(51,cardNo,out_speed),\ | 886 | CTBLN(cardNo,out_speed),\ |
888 | CTBLN(52,cardNo,in_speed10),\ | 887 | CTBLN(cardNo,in_speed10),\ |
889 | CTBLN(53,cardNo,out_speed10),\ | 888 | CTBLN(cardNo,out_speed10),\ |
890 | CTBLN(54,cardNo,in_speed_max),\ | 889 | CTBLN(cardNo,in_speed_max),\ |
891 | CTBLN(55,cardNo,out_speed_max),\ | 890 | CTBLN(cardNo,out_speed_max),\ |
892 | CTBLN(56,cardNo,measure_rate),\ | 891 | CTBLN(cardNo,measure_rate),\ |
893 | CTBLN(57,cardNo,pre_Command_Wait),\ | 892 | CTBLN(cardNo,pre_Command_Wait),\ |
894 | CTBLN(58,cardNo,rx_tweak1),\ | 893 | CTBLN(cardNo,rx_tweak1),\ |
895 | CTBLN(59,cardNo,rx_tweak2),\ | 894 | CTBLN(cardNo,rx_tweak2),\ |
896 | CTBLN(60,cardNo,tx_queue_len),\ | 895 | CTBLN(cardNo,tx_queue_len),\ |
897 | 896 | ||
898 | 897 | ||
899 | 898 | ||
@@ -903,63 +902,56 @@ static ctl_table arlan_conf_table0[] = | |||
903 | 902 | ||
904 | #ifdef ARLAN_PROC_SHM_DUMP | 903 | #ifdef ARLAN_PROC_SHM_DUMP |
905 | { | 904 | { |
906 | .ctl_name = 150, | ||
907 | .procname = "arlan0-txRing", | 905 | .procname = "arlan0-txRing", |
908 | .data = &arlan_drive_info, | 906 | .data = &arlan_drive_info, |
909 | .maxlen = ARLAN_STR_SIZE, | 907 | .maxlen = ARLAN_STR_SIZE, |
910 | .mode = 0400, | 908 | .mode = 0400, |
911 | .proc_handler = &arlan_sysctl_infotxRing, | 909 | .proc_handler = arlan_sysctl_infotxRing, |
912 | }, | 910 | }, |
913 | { | 911 | { |
914 | .ctl_name = 151, | ||
915 | .procname = "arlan0-rxRing", | 912 | .procname = "arlan0-rxRing", |
916 | .data = &arlan_drive_info, | 913 | .data = &arlan_drive_info, |
917 | .maxlen = ARLAN_STR_SIZE, | 914 | .maxlen = ARLAN_STR_SIZE, |
918 | .mode = 0400, | 915 | .mode = 0400, |
919 | .proc_handler = &arlan_sysctl_inforxRing, | 916 | .proc_handler = arlan_sysctl_inforxRing, |
920 | }, | 917 | }, |
921 | { | 918 | { |
922 | .ctl_name = 152, | ||
923 | .procname = "arlan0-18", | 919 | .procname = "arlan0-18", |
924 | .data = &arlan_drive_info, | 920 | .data = &arlan_drive_info, |
925 | .maxlen = ARLAN_STR_SIZE, | 921 | .maxlen = ARLAN_STR_SIZE, |
926 | .mode = 0400, | 922 | .mode = 0400, |
927 | .proc_handler = &arlan_sysctl_info18, | 923 | .proc_handler = arlan_sysctl_info18, |
928 | }, | 924 | }, |
929 | { | 925 | { |
930 | .ctl_name = 153, | ||
931 | .procname = "arlan0-ring", | 926 | .procname = "arlan0-ring", |
932 | .data = &arlan_drive_info, | 927 | .data = &arlan_drive_info, |
933 | .maxlen = ARLAN_STR_SIZE, | 928 | .maxlen = ARLAN_STR_SIZE, |
934 | .mode = 0400, | 929 | .mode = 0400, |
935 | .proc_handler = &arlan_sysctl_info161719, | 930 | .proc_handler = arlan_sysctl_info161719, |
936 | }, | 931 | }, |
937 | { | 932 | { |
938 | .ctl_name = 154, | ||
939 | .procname = "arlan0-shm-cpy", | 933 | .procname = "arlan0-shm-cpy", |
940 | .data = &arlan_drive_info, | 934 | .data = &arlan_drive_info, |
941 | .maxlen = ARLAN_STR_SIZE, | 935 | .maxlen = ARLAN_STR_SIZE, |
942 | .mode = 0400, | 936 | .mode = 0400, |
943 | .proc_handler = &arlan_sysctl_info, | 937 | .proc_handler = arlan_sysctl_info, |
944 | }, | 938 | }, |
945 | #endif | 939 | #endif |
946 | { | 940 | { |
947 | .ctl_name = 155, | ||
948 | .procname = "config0", | 941 | .procname = "config0", |
949 | .data = &conf_reset_result, | 942 | .data = &conf_reset_result, |
950 | .maxlen = 100, | 943 | .maxlen = 100, |
951 | .mode = 0400, | 944 | .mode = 0400, |
952 | .proc_handler = &arlan_configure | 945 | .proc_handler = arlan_configure |
953 | }, | 946 | }, |
954 | { | 947 | { |
955 | .ctl_name = 156, | ||
956 | .procname = "reset0", | 948 | .procname = "reset0", |
957 | .data = &conf_reset_result, | 949 | .data = &conf_reset_result, |
958 | .maxlen = 100, | 950 | .maxlen = 100, |
959 | .mode = 0400, | 951 | .mode = 0400, |
960 | .proc_handler = &arlan_sysctl_reset, | 952 | .proc_handler = arlan_sysctl_reset, |
961 | }, | 953 | }, |
962 | { .ctl_name = 0 } | 954 | { } |
963 | }; | 955 | }; |
964 | 956 | ||
965 | static ctl_table arlan_conf_table1[] = | 957 | static ctl_table arlan_conf_table1[] = |
@@ -969,63 +961,56 @@ static ctl_table arlan_conf_table1[] = | |||
969 | 961 | ||
970 | #ifdef ARLAN_PROC_SHM_DUMP | 962 | #ifdef ARLAN_PROC_SHM_DUMP |
971 | { | 963 | { |
972 | .ctl_name = 150, | ||
973 | .procname = "arlan1-txRing", | 964 | .procname = "arlan1-txRing", |
974 | .data = &arlan_drive_info, | 965 | .data = &arlan_drive_info, |
975 | .maxlen = ARLAN_STR_SIZE, | 966 | .maxlen = ARLAN_STR_SIZE, |
976 | .mode = 0400, | 967 | .mode = 0400, |
977 | .proc_handler = &arlan_sysctl_infotxRing, | 968 | .proc_handler = arlan_sysctl_infotxRing, |
978 | }, | 969 | }, |
979 | { | 970 | { |
980 | .ctl_name = 151, | ||
981 | .procname = "arlan1-rxRing", | 971 | .procname = "arlan1-rxRing", |
982 | .data = &arlan_drive_info, | 972 | .data = &arlan_drive_info, |
983 | .maxlen = ARLAN_STR_SIZE, | 973 | .maxlen = ARLAN_STR_SIZE, |
984 | .mode = 0400, | 974 | .mode = 0400, |
985 | .proc_handler = &arlan_sysctl_inforxRing, | 975 | .proc_handler = arlan_sysctl_inforxRing, |
986 | }, | 976 | }, |
987 | { | 977 | { |
988 | .ctl_name = 152, | ||
989 | .procname = "arlan1-18", | 978 | .procname = "arlan1-18", |
990 | .data = &arlan_drive_info, | 979 | .data = &arlan_drive_info, |
991 | .maxlen = ARLAN_STR_SIZE, | 980 | .maxlen = ARLAN_STR_SIZE, |
992 | .mode = 0400, | 981 | .mode = 0400, |
993 | .proc_handler = &arlan_sysctl_info18, | 982 | .proc_handler = arlan_sysctl_info18, |
994 | }, | 983 | }, |
995 | { | 984 | { |
996 | .ctl_name = 153, | ||
997 | .procname = "arlan1-ring", | 985 | .procname = "arlan1-ring", |
998 | .data = &arlan_drive_info, | 986 | .data = &arlan_drive_info, |
999 | .maxlen = ARLAN_STR_SIZE, | 987 | .maxlen = ARLAN_STR_SIZE, |
1000 | .mode = 0400, | 988 | .mode = 0400, |
1001 | .proc_handler = &arlan_sysctl_info161719, | 989 | .proc_handler = arlan_sysctl_info161719, |
1002 | }, | 990 | }, |
1003 | { | 991 | { |
1004 | .ctl_name = 154, | ||
1005 | .procname = "arlan1-shm-cpy", | 992 | .procname = "arlan1-shm-cpy", |
1006 | .data = &arlan_drive_info, | 993 | .data = &arlan_drive_info, |
1007 | .maxlen = ARLAN_STR_SIZE, | 994 | .maxlen = ARLAN_STR_SIZE, |
1008 | .mode = 0400, | 995 | .mode = 0400, |
1009 | .proc_handler = &arlan_sysctl_info, | 996 | .proc_handler = arlan_sysctl_info, |
1010 | }, | 997 | }, |
1011 | #endif | 998 | #endif |
1012 | { | 999 | { |
1013 | .ctl_name = 155, | ||
1014 | .procname = "config1", | 1000 | .procname = "config1", |
1015 | .data = &conf_reset_result, | 1001 | .data = &conf_reset_result, |
1016 | .maxlen = 100, | 1002 | .maxlen = 100, |
1017 | .mode = 0400, | 1003 | .mode = 0400, |
1018 | .proc_handler = &arlan_configure, | 1004 | .proc_handler = arlan_configure, |
1019 | }, | 1005 | }, |
1020 | { | 1006 | { |
1021 | .ctl_name = 156, | ||
1022 | .procname = "reset1", | 1007 | .procname = "reset1", |
1023 | .data = &conf_reset_result, | 1008 | .data = &conf_reset_result, |
1024 | .maxlen = 100, | 1009 | .maxlen = 100, |
1025 | .mode = 0400, | 1010 | .mode = 0400, |
1026 | .proc_handler = &arlan_sysctl_reset, | 1011 | .proc_handler = arlan_sysctl_reset, |
1027 | }, | 1012 | }, |
1028 | { .ctl_name = 0 } | 1013 | { } |
1029 | }; | 1014 | }; |
1030 | 1015 | ||
1031 | static ctl_table arlan_conf_table2[] = | 1016 | static ctl_table arlan_conf_table2[] = |
@@ -1035,63 +1020,56 @@ static ctl_table arlan_conf_table2[] = | |||
1035 | 1020 | ||
1036 | #ifdef ARLAN_PROC_SHM_DUMP | 1021 | #ifdef ARLAN_PROC_SHM_DUMP |
1037 | { | 1022 | { |
1038 | .ctl_name = 150, | ||
1039 | .procname = "arlan2-txRing", | 1023 | .procname = "arlan2-txRing", |
1040 | .data = &arlan_drive_info, | 1024 | .data = &arlan_drive_info, |
1041 | .maxlen = ARLAN_STR_SIZE, | 1025 | .maxlen = ARLAN_STR_SIZE, |
1042 | .mode = 0400, | 1026 | .mode = 0400, |
1043 | .proc_handler = &arlan_sysctl_infotxRing, | 1027 | .proc_handler = arlan_sysctl_infotxRing, |
1044 | }, | 1028 | }, |
1045 | { | 1029 | { |
1046 | .ctl_name = 151, | ||
1047 | .procname = "arlan2-rxRing", | 1030 | .procname = "arlan2-rxRing", |
1048 | .data = &arlan_drive_info, | 1031 | .data = &arlan_drive_info, |
1049 | .maxlen = ARLAN_STR_SIZE, | 1032 | .maxlen = ARLAN_STR_SIZE, |
1050 | .mode = 0400, | 1033 | .mode = 0400, |
1051 | .proc_handler = &arlan_sysctl_inforxRing, | 1034 | .proc_handler = arlan_sysctl_inforxRing, |
1052 | }, | 1035 | }, |
1053 | { | 1036 | { |
1054 | .ctl_name = 152, | ||
1055 | .procname = "arlan2-18", | 1037 | .procname = "arlan2-18", |
1056 | .data = &arlan_drive_info, | 1038 | .data = &arlan_drive_info, |
1057 | .maxlen = ARLAN_STR_SIZE, | 1039 | .maxlen = ARLAN_STR_SIZE, |
1058 | .mode = 0400, | 1040 | .mode = 0400, |
1059 | .proc_handler = &arlan_sysctl_info18, | 1041 | .proc_handler = arlan_sysctl_info18, |
1060 | }, | 1042 | }, |
1061 | { | 1043 | { |
1062 | .ctl_name = 153, | ||
1063 | .procname = "arlan2-ring", | 1044 | .procname = "arlan2-ring", |
1064 | .data = &arlan_drive_info, | 1045 | .data = &arlan_drive_info, |
1065 | .maxlen = ARLAN_STR_SIZE, | 1046 | .maxlen = ARLAN_STR_SIZE, |
1066 | .mode = 0400, | 1047 | .mode = 0400, |
1067 | .proc_handler = &arlan_sysctl_info161719, | 1048 | .proc_handler = arlan_sysctl_info161719, |
1068 | }, | 1049 | }, |
1069 | { | 1050 | { |
1070 | .ctl_name = 154, | ||
1071 | .procname = "arlan2-shm-cpy", | 1051 | .procname = "arlan2-shm-cpy", |
1072 | .data = &arlan_drive_info, | 1052 | .data = &arlan_drive_info, |
1073 | .maxlen = ARLAN_STR_SIZE, | 1053 | .maxlen = ARLAN_STR_SIZE, |
1074 | .mode = 0400, | 1054 | .mode = 0400, |
1075 | .proc_handler = &arlan_sysctl_info, | 1055 | .proc_handler = arlan_sysctl_info, |
1076 | }, | 1056 | }, |
1077 | #endif | 1057 | #endif |
1078 | { | 1058 | { |
1079 | .ctl_name = 155, | ||
1080 | .procname = "config2", | 1059 | .procname = "config2", |
1081 | .data = &conf_reset_result, | 1060 | .data = &conf_reset_result, |
1082 | .maxlen = 100, | 1061 | .maxlen = 100, |
1083 | .mode = 0400, | 1062 | .mode = 0400, |
1084 | .proc_handler = &arlan_configure, | 1063 | .proc_handler = arlan_configure, |
1085 | }, | 1064 | }, |
1086 | { | 1065 | { |
1087 | .ctl_name = 156, | ||
1088 | .procname = "reset2", | 1066 | .procname = "reset2", |
1089 | .data = &conf_reset_result, | 1067 | .data = &conf_reset_result, |
1090 | .maxlen = 100, | 1068 | .maxlen = 100, |
1091 | .mode = 0400, | 1069 | .mode = 0400, |
1092 | .proc_handler = &arlan_sysctl_reset, | 1070 | .proc_handler = arlan_sysctl_reset, |
1093 | }, | 1071 | }, |
1094 | { .ctl_name = 0 } | 1072 | { } |
1095 | }; | 1073 | }; |
1096 | 1074 | ||
1097 | static ctl_table arlan_conf_table3[] = | 1075 | static ctl_table arlan_conf_table3[] = |
@@ -1101,63 +1079,56 @@ static ctl_table arlan_conf_table3[] = | |||
1101 | 1079 | ||
1102 | #ifdef ARLAN_PROC_SHM_DUMP | 1080 | #ifdef ARLAN_PROC_SHM_DUMP |
1103 | { | 1081 | { |
1104 | .ctl_name = 150, | ||
1105 | .procname = "arlan3-txRing", | 1082 | .procname = "arlan3-txRing", |
1106 | .data = &arlan_drive_info, | 1083 | .data = &arlan_drive_info, |
1107 | .maxlen = ARLAN_STR_SIZE, | 1084 | .maxlen = ARLAN_STR_SIZE, |
1108 | .mode = 0400, | 1085 | .mode = 0400, |
1109 | .proc_handler = &arlan_sysctl_infotxRing, | 1086 | .proc_handler = arlan_sysctl_infotxRing, |
1110 | }, | 1087 | }, |
1111 | { | 1088 | { |
1112 | .ctl_name = 151, | ||
1113 | .procname = "arlan3-rxRing", | 1089 | .procname = "arlan3-rxRing", |
1114 | .data = &arlan_drive_info, | 1090 | .data = &arlan_drive_info, |
1115 | .maxlen = ARLAN_STR_SIZE, | 1091 | .maxlen = ARLAN_STR_SIZE, |
1116 | .mode = 0400, | 1092 | .mode = 0400, |
1117 | .proc_handler = &arlan_sysctl_inforxRing, | 1093 | .proc_handler = arlan_sysctl_inforxRing, |
1118 | }, | 1094 | }, |
1119 | { | 1095 | { |
1120 | .ctl_name = 152, | ||
1121 | .procname = "arlan3-18", | 1096 | .procname = "arlan3-18", |
1122 | .data = &arlan_drive_info, | 1097 | .data = &arlan_drive_info, |
1123 | .maxlen = ARLAN_STR_SIZE, | 1098 | .maxlen = ARLAN_STR_SIZE, |
1124 | .mode = 0400, | 1099 | .mode = 0400, |
1125 | .proc_handler = &arlan_sysctl_info18, | 1100 | .proc_handler = arlan_sysctl_info18, |
1126 | }, | 1101 | }, |
1127 | { | 1102 | { |
1128 | .ctl_name = 153, | ||
1129 | .procname = "arlan3-ring", | 1103 | .procname = "arlan3-ring", |
1130 | .data = &arlan_drive_info, | 1104 | .data = &arlan_drive_info, |
1131 | .maxlen = ARLAN_STR_SIZE, | 1105 | .maxlen = ARLAN_STR_SIZE, |
1132 | .mode = 0400, | 1106 | .mode = 0400, |
1133 | .proc_handler = &arlan_sysctl_info161719, | 1107 | .proc_handler = arlan_sysctl_info161719, |
1134 | }, | 1108 | }, |
1135 | { | 1109 | { |
1136 | .ctl_name = 154, | ||
1137 | .procname = "arlan3-shm-cpy", | 1110 | .procname = "arlan3-shm-cpy", |
1138 | .data = &arlan_drive_info, | 1111 | .data = &arlan_drive_info, |
1139 | .maxlen = ARLAN_STR_SIZE, | 1112 | .maxlen = ARLAN_STR_SIZE, |
1140 | .mode = 0400, | 1113 | .mode = 0400, |
1141 | .proc_handler = &arlan_sysctl_info, | 1114 | .proc_handler = arlan_sysctl_info, |
1142 | }, | 1115 | }, |
1143 | #endif | 1116 | #endif |
1144 | { | 1117 | { |
1145 | .ctl_name = 155, | ||
1146 | .procname = "config3", | 1118 | .procname = "config3", |
1147 | .data = &conf_reset_result, | 1119 | .data = &conf_reset_result, |
1148 | .maxlen = 100, | 1120 | .maxlen = 100, |
1149 | .mode = 0400, | 1121 | .mode = 0400, |
1150 | .proc_handler = &arlan_configure, | 1122 | .proc_handler = arlan_configure, |
1151 | }, | 1123 | }, |
1152 | { | 1124 | { |
1153 | .ctl_name = 156, | ||
1154 | .procname = "reset3", | 1125 | .procname = "reset3", |
1155 | .data = &conf_reset_result, | 1126 | .data = &conf_reset_result, |
1156 | .maxlen = 100, | 1127 | .maxlen = 100, |
1157 | .mode = 0400, | 1128 | .mode = 0400, |
1158 | .proc_handler = &arlan_sysctl_reset, | 1129 | .proc_handler = arlan_sysctl_reset, |
1159 | }, | 1130 | }, |
1160 | { .ctl_name = 0 } | 1131 | { } |
1161 | }; | 1132 | }; |
1162 | 1133 | ||
1163 | 1134 | ||
@@ -1165,41 +1136,37 @@ static ctl_table arlan_conf_table3[] = | |||
1165 | static ctl_table arlan_table[] = | 1136 | static ctl_table arlan_table[] = |
1166 | { | 1137 | { |
1167 | { | 1138 | { |
1168 | .ctl_name = 0, | ||
1169 | .procname = "arlan0", | 1139 | .procname = "arlan0", |
1170 | .maxlen = 0, | 1140 | .maxlen = 0, |
1171 | .mode = 0600, | 1141 | .mode = 0600, |
1172 | .child = arlan_conf_table0, | 1142 | .child = arlan_conf_table0, |
1173 | }, | 1143 | }, |
1174 | { | 1144 | { |
1175 | .ctl_name = 0, | ||
1176 | .procname = "arlan1", | 1145 | .procname = "arlan1", |
1177 | .maxlen = 0, | 1146 | .maxlen = 0, |
1178 | .mode = 0600, | 1147 | .mode = 0600, |
1179 | .child = arlan_conf_table1, | 1148 | .child = arlan_conf_table1, |
1180 | }, | 1149 | }, |
1181 | { | 1150 | { |
1182 | .ctl_name = 0, | ||
1183 | .procname = "arlan2", | 1151 | .procname = "arlan2", |
1184 | .maxlen = 0, | 1152 | .maxlen = 0, |
1185 | .mode = 0600, | 1153 | .mode = 0600, |
1186 | .child = arlan_conf_table2, | 1154 | .child = arlan_conf_table2, |
1187 | }, | 1155 | }, |
1188 | { | 1156 | { |
1189 | .ctl_name = 0, | ||
1190 | .procname = "arlan3", | 1157 | .procname = "arlan3", |
1191 | .maxlen = 0, | 1158 | .maxlen = 0, |
1192 | .mode = 0600, | 1159 | .mode = 0600, |
1193 | .child = arlan_conf_table3, | 1160 | .child = arlan_conf_table3, |
1194 | }, | 1161 | }, |
1195 | { .ctl_name = 0 } | 1162 | { } |
1196 | }; | 1163 | }; |
1197 | 1164 | ||
1198 | #else | 1165 | #else |
1199 | 1166 | ||
1200 | static ctl_table arlan_table[MAX_ARLANS + 1] = | 1167 | static ctl_table arlan_table[] = |
1201 | { | 1168 | { |
1202 | { .ctl_name = 0 } | 1169 | { } |
1203 | }; | 1170 | }; |
1204 | #endif | 1171 | #endif |
1205 | 1172 | ||
@@ -1209,22 +1176,14 @@ static ctl_table arlan_table[MAX_ARLANS + 1] = | |||
1209 | static ctl_table arlan_root_table[] = | 1176 | static ctl_table arlan_root_table[] = |
1210 | { | 1177 | { |
1211 | { | 1178 | { |
1212 | .ctl_name = CTL_ARLAN, | ||
1213 | .procname = "arlan", | 1179 | .procname = "arlan", |
1214 | .maxlen = 0, | 1180 | .maxlen = 0, |
1215 | .mode = 0555, | 1181 | .mode = 0555, |
1216 | .child = arlan_table, | 1182 | .child = arlan_table, |
1217 | }, | 1183 | }, |
1218 | { .ctl_name = 0 } | 1184 | { } |
1219 | }; | 1185 | }; |
1220 | 1186 | ||
1221 | /* Make sure that /proc/sys/dev is there */ | ||
1222 | //static ctl_table arlan_device_root_table[] = | ||
1223 | //{ | ||
1224 | // {CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table}, | ||
1225 | // {0} | ||
1226 | //}; | ||
1227 | |||
1228 | 1187 | ||
1229 | static struct ctl_table_header *arlan_device_sysctl_header; | 1188 | static struct ctl_table_header *arlan_device_sysctl_header; |
1230 | 1189 | ||
@@ -1234,8 +1193,6 @@ int __init init_arlan_proc(void) | |||
1234 | int i = 0; | 1193 | int i = 0; |
1235 | if (arlan_device_sysctl_header) | 1194 | if (arlan_device_sysctl_header) |
1236 | return 0; | 1195 | return 0; |
1237 | for (i = 0; i < MAX_ARLANS && arlan_device[i]; i++) | ||
1238 | arlan_table[i].ctl_name = i + 1; | ||
1239 | arlan_device_sysctl_header = register_sysctl_table(arlan_root_table); | 1196 | arlan_device_sysctl_header = register_sysctl_table(arlan_root_table); |
1240 | if (!arlan_device_sysctl_header) | 1197 | if (!arlan_device_sysctl_header) |
1241 | return -1; | 1198 | return -1; |
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index d3c824dc2358..c14ae8676903 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/miscdevice.h> | 12 | #include <linux/miscdevice.h> |
13 | #include <linux/smp_lock.h> | ||
14 | #include <linux/watchdog.h> | 13 | #include <linux/watchdog.h> |
15 | #include <linux/of.h> | 14 | #include <linux/of.h> |
16 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
@@ -75,7 +74,6 @@ static void riowd_writereg(struct riowd *p, u8 val, int index) | |||
75 | 74 | ||
76 | static int riowd_open(struct inode *inode, struct file *filp) | 75 | static int riowd_open(struct inode *inode, struct file *filp) |
77 | { | 76 | { |
78 | cycle_kernel_lock(); | ||
79 | nonseekable_open(inode, filp); | 77 | nonseekable_open(inode, filp); |
80 | return 0; | 78 | return 0; |
81 | } | 79 | } |
@@ -194,6 +192,8 @@ static int __devinit riowd_probe(struct of_device *op, | |||
194 | printk(KERN_ERR PFX "Cannot map registers.\n"); | 192 | printk(KERN_ERR PFX "Cannot map registers.\n"); |
195 | goto out_free; | 193 | goto out_free; |
196 | } | 194 | } |
195 | /* Make miscdev useable right away */ | ||
196 | riowd_device = p; | ||
197 | 197 | ||
198 | err = misc_register(&riowd_miscdev); | 198 | err = misc_register(&riowd_miscdev); |
199 | if (err) { | 199 | if (err) { |
@@ -205,10 +205,10 @@ static int __devinit riowd_probe(struct of_device *op, | |||
205 | "regs at %p\n", riowd_timeout, p->regs); | 205 | "regs at %p\n", riowd_timeout, p->regs); |
206 | 206 | ||
207 | dev_set_drvdata(&op->dev, p); | 207 | dev_set_drvdata(&op->dev, p); |
208 | riowd_device = p; | ||
209 | return 0; | 208 | return 0; |
210 | 209 | ||
211 | out_iounmap: | 210 | out_iounmap: |
211 | riowd_device = NULL; | ||
212 | of_iounmap(&op->resource[0], p->regs, 2); | 212 | of_iounmap(&op->resource[0], p->regs, 2); |
213 | 213 | ||
214 | out_free: | 214 | out_free: |