diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/fpu.S | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 84 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_parse.c | 17 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp-tbsync.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 25 |
8 files changed, 109 insertions, 52 deletions
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 7e2c9fe44ac1..821e152e093c 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
@@ -2,6 +2,11 @@ | |||
2 | * FPU support code, moved here from head.S so that it can be used | 2 | * FPU support code, moved here from head.S so that it can be used |
3 | * by chips which use other head-whatever.S files. | 3 | * by chips which use other head-whatever.S files. |
4 | * | 4 | * |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
6 | * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> | ||
7 | * Copyright (C) 1996 Paul Mackerras. | ||
8 | * Copyright (C) 1997 Dan Malek (dmalek@jlc.net). | ||
9 | * | ||
5 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
7 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 7ee685433319..12c5971d6565 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -322,7 +322,8 @@ EXPORT_SYMBOL(do_softirq); | |||
322 | 322 | ||
323 | static LIST_HEAD(irq_hosts); | 323 | static LIST_HEAD(irq_hosts); |
324 | static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; | 324 | static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; |
325 | 325 | static DEFINE_PER_CPU(unsigned int, irq_radix_reader); | |
326 | static unsigned int irq_radix_writer; | ||
326 | struct irq_map_entry irq_map[NR_IRQS]; | 327 | struct irq_map_entry irq_map[NR_IRQS]; |
327 | static unsigned int irq_virq_count = NR_IRQS; | 328 | static unsigned int irq_virq_count = NR_IRQS; |
328 | static struct irq_host *irq_default_host; | 329 | static struct irq_host *irq_default_host; |
@@ -455,6 +456,58 @@ void irq_set_virq_count(unsigned int count) | |||
455 | irq_virq_count = count; | 456 | irq_virq_count = count; |
456 | } | 457 | } |
457 | 458 | ||
459 | /* radix tree not lockless safe ! we use a brlock-type mecanism | ||
460 | * for now, until we can use a lockless radix tree | ||
461 | */ | ||
462 | static void irq_radix_wrlock(unsigned long *flags) | ||
463 | { | ||
464 | unsigned int cpu, ok; | ||
465 | |||
466 | spin_lock_irqsave(&irq_big_lock, *flags); | ||
467 | irq_radix_writer = 1; | ||
468 | smp_mb(); | ||
469 | do { | ||
470 | barrier(); | ||
471 | ok = 1; | ||
472 | for_each_possible_cpu(cpu) { | ||
473 | if (per_cpu(irq_radix_reader, cpu)) { | ||
474 | ok = 0; | ||
475 | break; | ||
476 | } | ||
477 | } | ||
478 | if (!ok) | ||
479 | cpu_relax(); | ||
480 | } while(!ok); | ||
481 | } | ||
482 | |||
483 | static void irq_radix_wrunlock(unsigned long flags) | ||
484 | { | ||
485 | smp_wmb(); | ||
486 | irq_radix_writer = 0; | ||
487 | spin_unlock_irqrestore(&irq_big_lock, flags); | ||
488 | } | ||
489 | |||
490 | static void irq_radix_rdlock(unsigned long *flags) | ||
491 | { | ||
492 | local_irq_save(*flags); | ||
493 | __get_cpu_var(irq_radix_reader) = 1; | ||
494 | smp_mb(); | ||
495 | if (likely(irq_radix_writer == 0)) | ||
496 | return; | ||
497 | __get_cpu_var(irq_radix_reader) = 0; | ||
498 | smp_wmb(); | ||
499 | spin_lock(&irq_big_lock); | ||
500 | __get_cpu_var(irq_radix_reader) = 1; | ||
501 | spin_unlock(&irq_big_lock); | ||
502 | } | ||
503 | |||
504 | static void irq_radix_rdunlock(unsigned long flags) | ||
505 | { | ||
506 | __get_cpu_var(irq_radix_reader) = 0; | ||
507 | local_irq_restore(flags); | ||
508 | } | ||
509 | |||
510 | |||
458 | unsigned int irq_create_mapping(struct irq_host *host, | 511 | unsigned int irq_create_mapping(struct irq_host *host, |
459 | irq_hw_number_t hwirq) | 512 | irq_hw_number_t hwirq) |
460 | { | 513 | { |
@@ -604,13 +657,9 @@ void irq_dispose_mapping(unsigned int virq) | |||
604 | /* Check if radix tree allocated yet */ | 657 | /* Check if radix tree allocated yet */ |
605 | if (host->revmap_data.tree.gfp_mask == 0) | 658 | if (host->revmap_data.tree.gfp_mask == 0) |
606 | break; | 659 | break; |
607 | /* XXX radix tree not safe ! remove lock whem it becomes safe | 660 | irq_radix_wrlock(&flags); |
608 | * and use some RCU sync to make sure everything is ok before we | ||
609 | * can re-use that map entry | ||
610 | */ | ||
611 | spin_lock_irqsave(&irq_big_lock, flags); | ||
612 | radix_tree_delete(&host->revmap_data.tree, hwirq); | 661 | radix_tree_delete(&host->revmap_data.tree, hwirq); |
613 | spin_unlock_irqrestore(&irq_big_lock, flags); | 662 | irq_radix_wrunlock(flags); |
614 | break; | 663 | break; |
615 | } | 664 | } |
616 | 665 | ||
@@ -677,25 +726,24 @@ unsigned int irq_radix_revmap(struct irq_host *host, | |||
677 | if (tree->gfp_mask == 0) | 726 | if (tree->gfp_mask == 0) |
678 | return irq_find_mapping(host, hwirq); | 727 | return irq_find_mapping(host, hwirq); |
679 | 728 | ||
680 | /* XXX Current radix trees are NOT SMP safe !!! Remove that lock | ||
681 | * when that is fixed (when Nick's patch gets in | ||
682 | */ | ||
683 | spin_lock_irqsave(&irq_big_lock, flags); | ||
684 | |||
685 | /* Now try to resolve */ | 729 | /* Now try to resolve */ |
730 | irq_radix_rdlock(&flags); | ||
686 | ptr = radix_tree_lookup(tree, hwirq); | 731 | ptr = radix_tree_lookup(tree, hwirq); |
732 | irq_radix_rdunlock(flags); | ||
733 | |||
687 | /* Found it, return */ | 734 | /* Found it, return */ |
688 | if (ptr) { | 735 | if (ptr) { |
689 | virq = ptr - irq_map; | 736 | virq = ptr - irq_map; |
690 | goto bail; | 737 | return virq; |
691 | } | 738 | } |
692 | 739 | ||
693 | /* If not there, try to insert it */ | 740 | /* If not there, try to insert it */ |
694 | virq = irq_find_mapping(host, hwirq); | 741 | virq = irq_find_mapping(host, hwirq); |
695 | if (virq != NO_IRQ) | 742 | if (virq != NO_IRQ) { |
743 | irq_radix_wrlock(&flags); | ||
696 | radix_tree_insert(tree, hwirq, &irq_map[virq]); | 744 | radix_tree_insert(tree, hwirq, &irq_map[virq]); |
697 | bail: | 745 | irq_radix_wrunlock(flags); |
698 | spin_unlock_irqrestore(&irq_big_lock, flags); | 746 | } |
699 | return virq; | 747 | return virq; |
700 | } | 748 | } |
701 | 749 | ||
@@ -806,12 +854,12 @@ static int irq_late_init(void) | |||
806 | struct irq_host *h; | 854 | struct irq_host *h; |
807 | unsigned long flags; | 855 | unsigned long flags; |
808 | 856 | ||
809 | spin_lock_irqsave(&irq_big_lock, flags); | 857 | irq_radix_wrlock(&flags); |
810 | list_for_each_entry(h, &irq_hosts, link) { | 858 | list_for_each_entry(h, &irq_hosts, link) { |
811 | if (h->revmap_type == IRQ_HOST_MAP_TREE) | 859 | if (h->revmap_type == IRQ_HOST_MAP_TREE) |
812 | INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); | 860 | INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); |
813 | } | 861 | } |
814 | spin_unlock_irqrestore(&irq_big_lock, flags); | 862 | irq_radix_wrunlock(flags); |
815 | 863 | ||
816 | return 0; | 864 | return 0; |
817 | } | 865 | } |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2fce7738e9e2..138134c8c17d 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -1289,6 +1289,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1289 | 1289 | ||
1290 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 1290 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); |
1291 | 1291 | ||
1292 | #ifdef DEBUG | ||
1293 | memset(&oirq, 0xff, sizeof(oirq)); | ||
1294 | #endif | ||
1292 | /* Try to get a mapping from the device-tree */ | 1295 | /* Try to get a mapping from the device-tree */ |
1293 | if (of_irq_map_pci(pci_dev, &oirq)) { | 1296 | if (of_irq_map_pci(pci_dev, &oirq)) { |
1294 | u8 line, pin; | 1297 | u8 line, pin; |
@@ -1314,8 +1317,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1314 | if (virq != NO_IRQ) | 1317 | if (virq != NO_IRQ) |
1315 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | 1318 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); |
1316 | } else { | 1319 | } else { |
1317 | DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", | 1320 | DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", |
1318 | oirq.size, oirq.specifier[0], oirq.controller->full_name); | 1321 | oirq.size, oirq.specifier[0], oirq.specifier[1], |
1322 | oirq.controller->full_name); | ||
1319 | 1323 | ||
1320 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 1324 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
1321 | oirq.size); | 1325 | oirq.size); |
@@ -1324,6 +1328,9 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
1324 | DBG(" -> failed to map !\n"); | 1328 | DBG(" -> failed to map !\n"); |
1325 | return -1; | 1329 | return -1; |
1326 | } | 1330 | } |
1331 | |||
1332 | DBG(" -> mapped to linux irq %d\n", virq); | ||
1333 | |||
1327 | pci_dev->irq = virq; | 1334 | pci_dev->irq = virq; |
1328 | pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); | 1335 | pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); |
1329 | 1336 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index f6a05f090b25..39d3bfcabcd2 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -126,10 +126,6 @@ EXPORT_SYMBOL(pci_bus_mem_base_phys); | |||
126 | EXPORT_SYMBOL(pci_bus_to_hose); | 126 | EXPORT_SYMBOL(pci_bus_to_hose); |
127 | #endif /* CONFIG_PCI */ | 127 | #endif /* CONFIG_PCI */ |
128 | 128 | ||
129 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
130 | EXPORT_SYMBOL(flush_dcache_all); | ||
131 | #endif | ||
132 | |||
133 | EXPORT_SYMBOL(start_thread); | 129 | EXPORT_SYMBOL(start_thread); |
134 | EXPORT_SYMBOL(kernel_thread); | 130 | EXPORT_SYMBOL(kernel_thread); |
135 | 131 | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 462bced40c12..4394e545f9f7 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -646,13 +646,13 @@ static unsigned char ibm_architecture_vec[] = { | |||
646 | 5 - 1, /* 5 option vectors */ | 646 | 5 - 1, /* 5 option vectors */ |
647 | 647 | ||
648 | /* option vector 1: processor architectures supported */ | 648 | /* option vector 1: processor architectures supported */ |
649 | 3 - 1, /* length */ | 649 | 3 - 2, /* length */ |
650 | 0, /* don't ignore, don't halt */ | 650 | 0, /* don't ignore, don't halt */ |
651 | OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | | 651 | OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | |
652 | OV1_PPC_2_04 | OV1_PPC_2_05, | 652 | OV1_PPC_2_04 | OV1_PPC_2_05, |
653 | 653 | ||
654 | /* option vector 2: Open Firmware options supported */ | 654 | /* option vector 2: Open Firmware options supported */ |
655 | 34 - 1, /* length */ | 655 | 34 - 2, /* length */ |
656 | OV2_REAL_MODE, | 656 | OV2_REAL_MODE, |
657 | 0, 0, | 657 | 0, 0, |
658 | W(0xffffffff), /* real_base */ | 658 | W(0xffffffff), /* real_base */ |
@@ -666,16 +666,16 @@ static unsigned char ibm_architecture_vec[] = { | |||
666 | 48, /* max log_2(hash table size) */ | 666 | 48, /* max log_2(hash table size) */ |
667 | 667 | ||
668 | /* option vector 3: processor options supported */ | 668 | /* option vector 3: processor options supported */ |
669 | 3 - 1, /* length */ | 669 | 3 - 2, /* length */ |
670 | 0, /* don't ignore, don't halt */ | 670 | 0, /* don't ignore, don't halt */ |
671 | OV3_FP | OV3_VMX, | 671 | OV3_FP | OV3_VMX, |
672 | 672 | ||
673 | /* option vector 4: IBM PAPR implementation */ | 673 | /* option vector 4: IBM PAPR implementation */ |
674 | 2 - 1, /* length */ | 674 | 2 - 2, /* length */ |
675 | 0, /* don't halt */ | 675 | 0, /* don't halt */ |
676 | 676 | ||
677 | /* option vector 5: PAPR/OF options */ | 677 | /* option vector 5: PAPR/OF options */ |
678 | 3 - 1, /* length */ | 678 | 3 - 2, /* length */ |
679 | 0, /* don't ignore, don't halt */ | 679 | 0, /* don't ignore, don't halt */ |
680 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, | 680 | OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, |
681 | }; | 681 | }; |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 11052c212ad5..a10825a5dfe6 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
@@ -639,14 +639,17 @@ void of_irq_map_init(unsigned int flags) | |||
639 | 639 | ||
640 | } | 640 | } |
641 | 641 | ||
642 | int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, | 642 | int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, |
643 | struct of_irq *out_irq) | 643 | u32 *addr, struct of_irq *out_irq) |
644 | { | 644 | { |
645 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | 645 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; |
646 | u32 *tmp, *imap, *imask; | 646 | u32 *tmp, *imap, *imask; |
647 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | 647 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; |
648 | int imaplen, match, i; | 648 | int imaplen, match, i; |
649 | 649 | ||
650 | DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", | ||
651 | parent->full_name, intspec[0], intspec[1], ointsize); | ||
652 | |||
650 | ipar = of_node_get(parent); | 653 | ipar = of_node_get(parent); |
651 | 654 | ||
652 | /* First get the #interrupt-cells property of the current cursor | 655 | /* First get the #interrupt-cells property of the current cursor |
@@ -670,6 +673,9 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, | |||
670 | 673 | ||
671 | DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); | 674 | DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); |
672 | 675 | ||
676 | if (ointsize != intsize) | ||
677 | return -EINVAL; | ||
678 | |||
673 | /* Look for this #address-cells. We have to implement the old linux | 679 | /* Look for this #address-cells. We have to implement the old linux |
674 | * trick of looking for the parent here as some device-trees rely on it | 680 | * trick of looking for the parent here as some device-trees rely on it |
675 | */ | 681 | */ |
@@ -875,12 +881,15 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq | |||
875 | } | 881 | } |
876 | intsize = *tmp; | 882 | intsize = *tmp; |
877 | 883 | ||
884 | DBG(" intsize=%d intlen=%d\n", intsize, intlen); | ||
885 | |||
878 | /* Check index */ | 886 | /* Check index */ |
879 | if ((index + 1) * intsize > intlen) | 887 | if ((index + 1) * intsize > intlen) |
880 | return -EINVAL; | 888 | return -EINVAL; |
881 | 889 | ||
882 | /* Get new specifier and map it */ | 890 | /* Get new specifier and map it */ |
883 | res = of_irq_map_raw(p, intspec + index * intsize, addr, out_irq); | 891 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, |
892 | addr, out_irq); | ||
884 | of_node_put(p); | 893 | of_node_put(p); |
885 | return res; | 894 | return res; |
886 | } | 895 | } |
@@ -965,7 +974,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | |||
965 | laddr[0] = (pdev->bus->number << 16) | 974 | laddr[0] = (pdev->bus->number << 16) |
966 | | (pdev->devfn << 8); | 975 | | (pdev->devfn << 8); |
967 | laddr[1] = laddr[2] = 0; | 976 | laddr[1] = laddr[2] = 0; |
968 | return of_irq_map_raw(ppnode, &lspec, laddr, out_irq); | 977 | return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); |
969 | } | 978 | } |
970 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 979 | EXPORT_SYMBOL_GPL(of_irq_map_pci); |
971 | #endif /* CONFIG_PCI */ | 980 | #endif /* CONFIG_PCI */ |
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index f19e2e0e61e7..de59c6c31a5b 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c | |||
@@ -45,8 +45,9 @@ void __devinit smp_generic_take_timebase(void) | |||
45 | { | 45 | { |
46 | int cmd; | 46 | int cmd; |
47 | u64 tb; | 47 | u64 tb; |
48 | unsigned long flags; | ||
48 | 49 | ||
49 | local_irq_disable(); | 50 | local_irq_save(flags); |
50 | while (!running) | 51 | while (!running) |
51 | barrier(); | 52 | barrier(); |
52 | rmb(); | 53 | rmb(); |
@@ -70,7 +71,7 @@ void __devinit smp_generic_take_timebase(void) | |||
70 | set_tb(tb >> 32, tb & 0xfffffffful); | 71 | set_tb(tb >> 32, tb & 0xfffffffful); |
71 | enter_contest(tbsync->mark, -1); | 72 | enter_contest(tbsync->mark, -1); |
72 | } | 73 | } |
73 | local_irq_enable(); | 74 | local_irq_restore(flags); |
74 | } | 75 | } |
75 | 76 | ||
76 | static int __devinit start_contest(int cmd, long offset, int num) | 77 | static int __devinit start_contest(int cmd, long offset, int num) |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 18e59e43d2b3..a124499e65d9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -125,15 +125,8 @@ static long timezone_offset; | |||
125 | unsigned long ppc_proc_freq; | 125 | unsigned long ppc_proc_freq; |
126 | unsigned long ppc_tb_freq; | 126 | unsigned long ppc_tb_freq; |
127 | 127 | ||
128 | u64 tb_last_jiffy __cacheline_aligned_in_smp; | 128 | static u64 tb_last_jiffy __cacheline_aligned_in_smp; |
129 | unsigned long tb_last_stamp; | 129 | static DEFINE_PER_CPU(u64, last_jiffy); |
130 | |||
131 | /* | ||
132 | * Note that on ppc32 this only stores the bottom 32 bits of | ||
133 | * the timebase value, but that's enough to tell when a jiffy | ||
134 | * has passed. | ||
135 | */ | ||
136 | DEFINE_PER_CPU(unsigned long, last_jiffy); | ||
137 | 130 | ||
138 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 131 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
139 | /* | 132 | /* |
@@ -458,7 +451,7 @@ void do_gettimeofday(struct timeval *tv) | |||
458 | do { | 451 | do { |
459 | seq = read_seqbegin_irqsave(&xtime_lock, flags); | 452 | seq = read_seqbegin_irqsave(&xtime_lock, flags); |
460 | sec = xtime.tv_sec; | 453 | sec = xtime.tv_sec; |
461 | nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp); | 454 | nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy); |
462 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | 455 | } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); |
463 | usec = nsec / 1000; | 456 | usec = nsec / 1000; |
464 | while (usec >= 1000000) { | 457 | while (usec >= 1000000) { |
@@ -700,7 +693,6 @@ void timer_interrupt(struct pt_regs * regs) | |||
700 | tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; | 693 | tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; |
701 | if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { | 694 | if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { |
702 | tb_last_jiffy = tb_next_jiffy; | 695 | tb_last_jiffy = tb_next_jiffy; |
703 | tb_last_stamp = per_cpu(last_jiffy, cpu); | ||
704 | do_timer(regs); | 696 | do_timer(regs); |
705 | timer_recalc_offset(tb_last_jiffy); | 697 | timer_recalc_offset(tb_last_jiffy); |
706 | timer_check_rtc(); | 698 | timer_check_rtc(); |
@@ -749,7 +741,7 @@ void __init smp_space_timers(unsigned int max_cpus) | |||
749 | int i; | 741 | int i; |
750 | unsigned long half = tb_ticks_per_jiffy / 2; | 742 | unsigned long half = tb_ticks_per_jiffy / 2; |
751 | unsigned long offset = tb_ticks_per_jiffy / max_cpus; | 743 | unsigned long offset = tb_ticks_per_jiffy / max_cpus; |
752 | unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); | 744 | u64 previous_tb = per_cpu(last_jiffy, boot_cpuid); |
753 | 745 | ||
754 | /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ | 746 | /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ |
755 | previous_tb -= tb_ticks_per_jiffy; | 747 | previous_tb -= tb_ticks_per_jiffy; |
@@ -830,7 +822,7 @@ int do_settimeofday(struct timespec *tv) | |||
830 | * and therefore the (jiffies - wall_jiffies) computation | 822 | * and therefore the (jiffies - wall_jiffies) computation |
831 | * has been removed. | 823 | * has been removed. |
832 | */ | 824 | */ |
833 | tb_delta = tb_ticks_since(tb_last_stamp); | 825 | tb_delta = tb_ticks_since(tb_last_jiffy); |
834 | tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ | 826 | tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ |
835 | new_nsec -= SCALE_XSEC(tb_delta, 1000000000); | 827 | new_nsec -= SCALE_XSEC(tb_delta, 1000000000); |
836 | 828 | ||
@@ -950,8 +942,7 @@ void __init time_init(void) | |||
950 | if (__USE_RTC()) { | 942 | if (__USE_RTC()) { |
951 | /* 601 processor: dec counts down by 128 every 128ns */ | 943 | /* 601 processor: dec counts down by 128 every 128ns */ |
952 | ppc_tb_freq = 1000000000; | 944 | ppc_tb_freq = 1000000000; |
953 | tb_last_stamp = get_rtcl(); | 945 | tb_last_jiffy = get_rtcl(); |
954 | tb_last_jiffy = tb_last_stamp; | ||
955 | } else { | 946 | } else { |
956 | /* Normal PowerPC with timebase register */ | 947 | /* Normal PowerPC with timebase register */ |
957 | ppc_md.calibrate_decr(); | 948 | ppc_md.calibrate_decr(); |
@@ -959,7 +950,7 @@ void __init time_init(void) | |||
959 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); | 950 | ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); |
960 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", | 951 | printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", |
961 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); | 952 | ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); |
962 | tb_last_stamp = tb_last_jiffy = get_tb(); | 953 | tb_last_jiffy = get_tb(); |
963 | } | 954 | } |
964 | 955 | ||
965 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; | 956 | tb_ticks_per_jiffy = ppc_tb_freq / HZ; |
@@ -1036,7 +1027,7 @@ void __init time_init(void) | |||
1036 | do_gtod.varp = &do_gtod.vars[0]; | 1027 | do_gtod.varp = &do_gtod.vars[0]; |
1037 | do_gtod.var_idx = 0; | 1028 | do_gtod.var_idx = 0; |
1038 | do_gtod.varp->tb_orig_stamp = tb_last_jiffy; | 1029 | do_gtod.varp->tb_orig_stamp = tb_last_jiffy; |
1039 | __get_cpu_var(last_jiffy) = tb_last_stamp; | 1030 | __get_cpu_var(last_jiffy) = tb_last_jiffy; |
1040 | do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | 1031 | do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; |
1041 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | 1032 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; |
1042 | do_gtod.varp->tb_to_xs = tb_to_xs; | 1033 | do_gtod.varp->tb_to_xs = tb_to_xs; |