diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/time.c | 212 |
1 files changed, 131 insertions, 81 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index b73bbf31f432..6e09bc285ba0 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/cpu.h> | ||
24 | #include <linux/stop_machine.h> | ||
23 | #include <linux/time.h> | 25 | #include <linux/time.h> |
24 | #include <linux/sysdev.h> | 26 | #include <linux/sysdev.h> |
25 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
@@ -391,6 +393,15 @@ static void enable_sync_clock(void) | |||
391 | atomic_set_mask(0x80000000, sw_ptr); | 393 | atomic_set_mask(0x80000000, sw_ptr); |
392 | } | 394 | } |
393 | 395 | ||
396 | /* Single threaded workqueue used for etr and stp sync events */ | ||
397 | static struct workqueue_struct *time_sync_wq; | ||
398 | |||
399 | static void __init time_init_wq(void) | ||
400 | { | ||
401 | if (!time_sync_wq) | ||
402 | time_sync_wq = create_singlethread_workqueue("timesync"); | ||
403 | } | ||
404 | |||
394 | /* | 405 | /* |
395 | * External Time Reference (ETR) code. | 406 | * External Time Reference (ETR) code. |
396 | */ | 407 | */ |
@@ -483,17 +494,18 @@ static int __init etr_init(void) | |||
483 | 494 | ||
484 | if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags)) | 495 | if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags)) |
485 | return 0; | 496 | return 0; |
497 | time_init_wq(); | ||
486 | /* Check if this machine has the steai instruction. */ | 498 | /* Check if this machine has the steai instruction. */ |
487 | if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0) | 499 | if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0) |
488 | etr_steai_available = 1; | 500 | etr_steai_available = 1; |
489 | setup_timer(&etr_timer, etr_timeout, 0UL); | 501 | setup_timer(&etr_timer, etr_timeout, 0UL); |
490 | if (etr_port0_online) { | 502 | if (etr_port0_online) { |
491 | set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); | 503 | set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); |
492 | schedule_work(&etr_work); | 504 | queue_work(time_sync_wq, &etr_work); |
493 | } | 505 | } |
494 | if (etr_port1_online) { | 506 | if (etr_port1_online) { |
495 | set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); | 507 | set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); |
496 | schedule_work(&etr_work); | 508 | queue_work(time_sync_wq, &etr_work); |
497 | } | 509 | } |
498 | return 0; | 510 | return 0; |
499 | } | 511 | } |
@@ -520,7 +532,7 @@ void etr_switch_to_local(void) | |||
520 | if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) | 532 | if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) |
521 | disable_sync_clock(NULL); | 533 | disable_sync_clock(NULL); |
522 | set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events); | 534 | set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events); |
523 | schedule_work(&etr_work); | 535 | queue_work(time_sync_wq, &etr_work); |
524 | } | 536 | } |
525 | 537 | ||
526 | /* | 538 | /* |
@@ -536,7 +548,7 @@ void etr_sync_check(void) | |||
536 | if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) | 548 | if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) |
537 | disable_sync_clock(NULL); | 549 | disable_sync_clock(NULL); |
538 | set_bit(ETR_EVENT_SYNC_CHECK, &etr_events); | 550 | set_bit(ETR_EVENT_SYNC_CHECK, &etr_events); |
539 | schedule_work(&etr_work); | 551 | queue_work(time_sync_wq, &etr_work); |
540 | } | 552 | } |
541 | 553 | ||
542 | /* | 554 | /* |
@@ -560,13 +572,13 @@ static void etr_timing_alert(struct etr_irq_parm *intparm) | |||
560 | * Both ports are not up-to-date now. | 572 | * Both ports are not up-to-date now. |
561 | */ | 573 | */ |
562 | set_bit(ETR_EVENT_PORT_ALERT, &etr_events); | 574 | set_bit(ETR_EVENT_PORT_ALERT, &etr_events); |
563 | schedule_work(&etr_work); | 575 | queue_work(time_sync_wq, &etr_work); |
564 | } | 576 | } |
565 | 577 | ||
566 | static void etr_timeout(unsigned long dummy) | 578 | static void etr_timeout(unsigned long dummy) |
567 | { | 579 | { |
568 | set_bit(ETR_EVENT_UPDATE, &etr_events); | 580 | set_bit(ETR_EVENT_UPDATE, &etr_events); |
569 | schedule_work(&etr_work); | 581 | queue_work(time_sync_wq, &etr_work); |
570 | } | 582 | } |
571 | 583 | ||
572 | /* | 584 | /* |
@@ -673,14 +685,16 @@ static int etr_aib_follows(struct etr_aib *a1, struct etr_aib *a2, int p) | |||
673 | } | 685 | } |
674 | 686 | ||
675 | struct clock_sync_data { | 687 | struct clock_sync_data { |
688 | atomic_t cpus; | ||
676 | int in_sync; | 689 | int in_sync; |
677 | unsigned long long fixup_cc; | 690 | unsigned long long fixup_cc; |
691 | int etr_port; | ||
692 | struct etr_aib *etr_aib; | ||
678 | }; | 693 | }; |
679 | 694 | ||
680 | static void clock_sync_cpu_start(void *dummy) | 695 | static void clock_sync_cpu(struct clock_sync_data *sync) |
681 | { | 696 | { |
682 | struct clock_sync_data *sync = dummy; | 697 | atomic_dec(&sync->cpus); |
683 | |||
684 | enable_sync_clock(); | 698 | enable_sync_clock(); |
685 | /* | 699 | /* |
686 | * This looks like a busy wait loop but it isn't. etr_sync_cpus | 700 | * This looks like a busy wait loop but it isn't. etr_sync_cpus |
@@ -706,39 +720,35 @@ static void clock_sync_cpu_start(void *dummy) | |||
706 | fixup_clock_comparator(sync->fixup_cc); | 720 | fixup_clock_comparator(sync->fixup_cc); |
707 | } | 721 | } |
708 | 722 | ||
709 | static void clock_sync_cpu_end(void *dummy) | ||
710 | { | ||
711 | } | ||
712 | |||
713 | /* | 723 | /* |
714 | * Sync the TOD clock using the port refered to by aibp. This port | 724 | * Sync the TOD clock using the port refered to by aibp. This port |
715 | * has to be enabled and the other port has to be disabled. The | 725 | * has to be enabled and the other port has to be disabled. The |
716 | * last eacr update has to be more than 1.6 seconds in the past. | 726 | * last eacr update has to be more than 1.6 seconds in the past. |
717 | */ | 727 | */ |
718 | static int etr_sync_clock(struct etr_aib *aib, int port) | 728 | static int etr_sync_clock(void *data) |
719 | { | 729 | { |
720 | struct etr_aib *sync_port; | 730 | static int first; |
721 | struct clock_sync_data etr_sync; | ||
722 | unsigned long long clock, old_clock, delay, delta; | 731 | unsigned long long clock, old_clock, delay, delta; |
723 | int follows; | 732 | struct clock_sync_data *etr_sync; |
733 | struct etr_aib *sync_port, *aib; | ||
734 | int port; | ||
724 | int rc; | 735 | int rc; |
725 | 736 | ||
726 | /* Check if the current aib is adjacent to the sync port aib. */ | 737 | etr_sync = data; |
727 | sync_port = (port == 0) ? &etr_port0 : &etr_port1; | ||
728 | follows = etr_aib_follows(sync_port, aib, port); | ||
729 | memcpy(sync_port, aib, sizeof(*aib)); | ||
730 | if (!follows) | ||
731 | return -EAGAIN; | ||
732 | 738 | ||
733 | /* | 739 | if (xchg(&first, 1) == 1) { |
734 | * Catch all other cpus and make them wait until we have | 740 | /* Slave */ |
735 | * successfully synced the clock. smp_call_function will | 741 | clock_sync_cpu(etr_sync); |
736 | * return after all other cpus are in etr_sync_cpu_start. | 742 | return 0; |
737 | */ | 743 | } |
738 | memset(&etr_sync, 0, sizeof(etr_sync)); | 744 | |
739 | preempt_disable(); | 745 | /* Wait until all other cpus entered the sync function. */ |
740 | smp_call_function(clock_sync_cpu_start, &etr_sync, 0); | 746 | while (atomic_read(&etr_sync->cpus) != 0) |
741 | local_irq_disable(); | 747 | cpu_relax(); |
748 | |||
749 | port = etr_sync->etr_port; | ||
750 | aib = etr_sync->etr_aib; | ||
751 | sync_port = (port == 0) ? &etr_port0 : &etr_port1; | ||
742 | enable_sync_clock(); | 752 | enable_sync_clock(); |
743 | 753 | ||
744 | /* Set clock to next OTE. */ | 754 | /* Set clock to next OTE. */ |
@@ -755,16 +765,16 @@ static int etr_sync_clock(struct etr_aib *aib, int port) | |||
755 | delay = (unsigned long long) | 765 | delay = (unsigned long long) |
756 | (aib->edf2.etv - sync_port->edf2.etv) << 32; | 766 | (aib->edf2.etv - sync_port->edf2.etv) << 32; |
757 | delta = adjust_time(old_clock, clock, delay); | 767 | delta = adjust_time(old_clock, clock, delay); |
758 | etr_sync.fixup_cc = delta; | 768 | etr_sync->fixup_cc = delta; |
759 | fixup_clock_comparator(delta); | 769 | fixup_clock_comparator(delta); |
760 | /* Verify that the clock is properly set. */ | 770 | /* Verify that the clock is properly set. */ |
761 | if (!etr_aib_follows(sync_port, aib, port)) { | 771 | if (!etr_aib_follows(sync_port, aib, port)) { |
762 | /* Didn't work. */ | 772 | /* Didn't work. */ |
763 | disable_sync_clock(NULL); | 773 | disable_sync_clock(NULL); |
764 | etr_sync.in_sync = -EAGAIN; | 774 | etr_sync->in_sync = -EAGAIN; |
765 | rc = -EAGAIN; | 775 | rc = -EAGAIN; |
766 | } else { | 776 | } else { |
767 | etr_sync.in_sync = 1; | 777 | etr_sync->in_sync = 1; |
768 | rc = 0; | 778 | rc = 0; |
769 | } | 779 | } |
770 | } else { | 780 | } else { |
@@ -772,12 +782,33 @@ static int etr_sync_clock(struct etr_aib *aib, int port) | |||
772 | __ctl_clear_bit(0, 29); | 782 | __ctl_clear_bit(0, 29); |
773 | __ctl_clear_bit(14, 21); | 783 | __ctl_clear_bit(14, 21); |
774 | disable_sync_clock(NULL); | 784 | disable_sync_clock(NULL); |
775 | etr_sync.in_sync = -EAGAIN; | 785 | etr_sync->in_sync = -EAGAIN; |
776 | rc = -EAGAIN; | 786 | rc = -EAGAIN; |
777 | } | 787 | } |
778 | local_irq_enable(); | 788 | xchg(&first, 0); |
779 | smp_call_function(clock_sync_cpu_end, NULL, 0); | 789 | return rc; |
780 | preempt_enable(); | 790 | } |
791 | |||
792 | static int etr_sync_clock_stop(struct etr_aib *aib, int port) | ||
793 | { | ||
794 | struct clock_sync_data etr_sync; | ||
795 | struct etr_aib *sync_port; | ||
796 | int follows; | ||
797 | int rc; | ||
798 | |||
799 | /* Check if the current aib is adjacent to the sync port aib. */ | ||
800 | sync_port = (port == 0) ? &etr_port0 : &etr_port1; | ||
801 | follows = etr_aib_follows(sync_port, aib, port); | ||
802 | memcpy(sync_port, aib, sizeof(*aib)); | ||
803 | if (!follows) | ||
804 | return -EAGAIN; | ||
805 | memset(&etr_sync, 0, sizeof(etr_sync)); | ||
806 | etr_sync.etr_aib = aib; | ||
807 | etr_sync.etr_port = port; | ||
808 | get_online_cpus(); | ||
809 | atomic_set(&etr_sync.cpus, num_online_cpus() - 1); | ||
810 | rc = stop_machine(etr_sync_clock, &etr_sync, &cpu_online_map); | ||
811 | put_online_cpus(); | ||
781 | return rc; | 812 | return rc; |
782 | } | 813 | } |
783 | 814 | ||
@@ -934,7 +965,7 @@ static void etr_update_eacr(struct etr_eacr eacr) | |||
934 | } | 965 | } |
935 | 966 | ||
936 | /* | 967 | /* |
937 | * ETR tasklet. In this function you'll find the main logic. In | 968 | * ETR work. In this function you'll find the main logic. In |
938 | * particular this is the only function that calls etr_update_eacr(), | 969 | * particular this is the only function that calls etr_update_eacr(), |
939 | * it "controls" the etr control register. | 970 | * it "controls" the etr control register. |
940 | */ | 971 | */ |
@@ -1067,7 +1098,7 @@ static void etr_work_fn(struct work_struct *work) | |||
1067 | etr_update_eacr(eacr); | 1098 | etr_update_eacr(eacr); |
1068 | set_bit(CLOCK_SYNC_ETR, &clock_sync_flags); | 1099 | set_bit(CLOCK_SYNC_ETR, &clock_sync_flags); |
1069 | if (now < etr_tolec + (1600000 << 12) || | 1100 | if (now < etr_tolec + (1600000 << 12) || |
1070 | etr_sync_clock(&aib, sync_port) != 0) { | 1101 | etr_sync_clock_stop(&aib, sync_port) != 0) { |
1071 | /* Sync failed. Try again in 1/2 second. */ | 1102 | /* Sync failed. Try again in 1/2 second. */ |
1072 | eacr.es = 0; | 1103 | eacr.es = 0; |
1073 | etr_update_eacr(eacr); | 1104 | etr_update_eacr(eacr); |
@@ -1156,13 +1187,13 @@ static ssize_t etr_online_store(struct sys_device *dev, | |||
1156 | return count; /* Nothing to do. */ | 1187 | return count; /* Nothing to do. */ |
1157 | etr_port0_online = value; | 1188 | etr_port0_online = value; |
1158 | set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); | 1189 | set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events); |
1159 | schedule_work(&etr_work); | 1190 | queue_work(time_sync_wq, &etr_work); |
1160 | } else { | 1191 | } else { |
1161 | if (etr_port1_online == value) | 1192 | if (etr_port1_online == value) |
1162 | return count; /* Nothing to do. */ | 1193 | return count; /* Nothing to do. */ |
1163 | etr_port1_online = value; | 1194 | etr_port1_online = value; |
1164 | set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); | 1195 | set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events); |
1165 | schedule_work(&etr_work); | 1196 | queue_work(time_sync_wq, &etr_work); |
1166 | } | 1197 | } |
1167 | return count; | 1198 | return count; |
1168 | } | 1199 | } |
@@ -1396,8 +1427,12 @@ static void __init stp_reset(void) | |||
1396 | 1427 | ||
1397 | static int __init stp_init(void) | 1428 | static int __init stp_init(void) |
1398 | { | 1429 | { |
1399 | if (test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags) && stp_online) | 1430 | if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) |
1400 | schedule_work(&stp_work); | 1431 | return 0; |
1432 | time_init_wq(); | ||
1433 | if (!stp_online) | ||
1434 | return 0; | ||
1435 | queue_work(time_sync_wq, &stp_work); | ||
1401 | return 0; | 1436 | return 0; |
1402 | } | 1437 | } |
1403 | 1438 | ||
@@ -1414,7 +1449,7 @@ arch_initcall(stp_init); | |||
1414 | static void stp_timing_alert(struct stp_irq_parm *intparm) | 1449 | static void stp_timing_alert(struct stp_irq_parm *intparm) |
1415 | { | 1450 | { |
1416 | if (intparm->tsc || intparm->lac || intparm->tcpc) | 1451 | if (intparm->tsc || intparm->lac || intparm->tcpc) |
1417 | schedule_work(&stp_work); | 1452 | queue_work(time_sync_wq, &stp_work); |
1418 | } | 1453 | } |
1419 | 1454 | ||
1420 | /* | 1455 | /* |
@@ -1428,7 +1463,7 @@ void stp_sync_check(void) | |||
1428 | if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) | 1463 | if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) |
1429 | return; | 1464 | return; |
1430 | disable_sync_clock(NULL); | 1465 | disable_sync_clock(NULL); |
1431 | schedule_work(&stp_work); | 1466 | queue_work(time_sync_wq, &stp_work); |
1432 | } | 1467 | } |
1433 | 1468 | ||
1434 | /* | 1469 | /* |
@@ -1442,46 +1477,34 @@ void stp_island_check(void) | |||
1442 | if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) | 1477 | if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags)) |
1443 | return; | 1478 | return; |
1444 | disable_sync_clock(NULL); | 1479 | disable_sync_clock(NULL); |
1445 | schedule_work(&stp_work); | 1480 | queue_work(time_sync_wq, &stp_work); |
1446 | } | 1481 | } |
1447 | 1482 | ||
1448 | /* | 1483 | |
1449 | * STP tasklet. Check for the STP state and take over the clock | 1484 | static int stp_sync_clock(void *data) |
1450 | * synchronization if the STP clock source is usable. | ||
1451 | */ | ||
1452 | static void stp_work_fn(struct work_struct *work) | ||
1453 | { | 1485 | { |
1454 | struct clock_sync_data stp_sync; | 1486 | static int first; |
1455 | unsigned long long old_clock, delta; | 1487 | unsigned long long old_clock, delta; |
1488 | struct clock_sync_data *stp_sync; | ||
1456 | int rc; | 1489 | int rc; |
1457 | 1490 | ||
1458 | if (!stp_online) { | 1491 | stp_sync = data; |
1459 | chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); | ||
1460 | return; | ||
1461 | } | ||
1462 | 1492 | ||
1463 | rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0); | 1493 | if (xchg(&first, 1) == 1) { |
1464 | if (rc) | 1494 | /* Slave */ |
1465 | return; | 1495 | clock_sync_cpu(stp_sync); |
1496 | return 0; | ||
1497 | } | ||
1466 | 1498 | ||
1467 | rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); | 1499 | /* Wait until all other cpus entered the sync function. */ |
1468 | if (rc || stp_info.c == 0) | 1500 | while (atomic_read(&stp_sync->cpus) != 0) |
1469 | return; | 1501 | cpu_relax(); |
1470 | 1502 | ||
1471 | /* | ||
1472 | * Catch all other cpus and make them wait until we have | ||
1473 | * successfully synced the clock. smp_call_function will | ||
1474 | * return after all other cpus are in clock_sync_cpu_start. | ||
1475 | */ | ||
1476 | memset(&stp_sync, 0, sizeof(stp_sync)); | ||
1477 | preempt_disable(); | ||
1478 | smp_call_function(clock_sync_cpu_start, &stp_sync, 0); | ||
1479 | local_irq_disable(); | ||
1480 | enable_sync_clock(); | 1503 | enable_sync_clock(); |
1481 | 1504 | ||
1482 | set_bit(CLOCK_SYNC_STP, &clock_sync_flags); | 1505 | set_bit(CLOCK_SYNC_STP, &clock_sync_flags); |
1483 | if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) | 1506 | if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags)) |
1484 | schedule_work(&etr_work); | 1507 | queue_work(time_sync_wq, &etr_work); |
1485 | 1508 | ||
1486 | rc = 0; | 1509 | rc = 0; |
1487 | if (stp_info.todoff[0] || stp_info.todoff[1] || | 1510 | if (stp_info.todoff[0] || stp_info.todoff[1] || |
@@ -1500,16 +1523,43 @@ static void stp_work_fn(struct work_struct *work) | |||
1500 | } | 1523 | } |
1501 | if (rc) { | 1524 | if (rc) { |
1502 | disable_sync_clock(NULL); | 1525 | disable_sync_clock(NULL); |
1503 | stp_sync.in_sync = -EAGAIN; | 1526 | stp_sync->in_sync = -EAGAIN; |
1504 | clear_bit(CLOCK_SYNC_STP, &clock_sync_flags); | 1527 | clear_bit(CLOCK_SYNC_STP, &clock_sync_flags); |
1505 | if (etr_port0_online || etr_port1_online) | 1528 | if (etr_port0_online || etr_port1_online) |
1506 | schedule_work(&etr_work); | 1529 | queue_work(time_sync_wq, &etr_work); |
1507 | } else | 1530 | } else |
1508 | stp_sync.in_sync = 1; | 1531 | stp_sync->in_sync = 1; |
1532 | xchg(&first, 0); | ||
1533 | return 0; | ||
1534 | } | ||
1509 | 1535 | ||
1510 | local_irq_enable(); | 1536 | /* |
1511 | smp_call_function(clock_sync_cpu_end, NULL, 0); | 1537 | * STP work. Check for the STP state and take over the clock |
1512 | preempt_enable(); | 1538 | * synchronization if the STP clock source is usable. |
1539 | */ | ||
1540 | static void stp_work_fn(struct work_struct *work) | ||
1541 | { | ||
1542 | struct clock_sync_data stp_sync; | ||
1543 | int rc; | ||
1544 | |||
1545 | if (!stp_online) { | ||
1546 | chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000); | ||
1547 | return; | ||
1548 | } | ||
1549 | |||
1550 | rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0); | ||
1551 | if (rc) | ||
1552 | return; | ||
1553 | |||
1554 | rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); | ||
1555 | if (rc || stp_info.c == 0) | ||
1556 | return; | ||
1557 | |||
1558 | memset(&stp_sync, 0, sizeof(stp_sync)); | ||
1559 | get_online_cpus(); | ||
1560 | atomic_set(&stp_sync.cpus, num_online_cpus() - 1); | ||
1561 | stop_machine(stp_sync_clock, &stp_sync, &cpu_online_map); | ||
1562 | put_online_cpus(); | ||
1513 | } | 1563 | } |
1514 | 1564 | ||
1515 | /* | 1565 | /* |
@@ -1618,7 +1668,7 @@ static ssize_t stp_online_store(struct sysdev_class *class, | |||
1618 | if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) | 1668 | if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags)) |
1619 | return -EOPNOTSUPP; | 1669 | return -EOPNOTSUPP; |
1620 | stp_online = value; | 1670 | stp_online = value; |
1621 | schedule_work(&stp_work); | 1671 | queue_work(time_sync_wq, &stp_work); |
1622 | return count; | 1672 | return count; |
1623 | } | 1673 | } |
1624 | 1674 | ||