diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2012-03-15 14:18:00 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-03-20 20:16:11 -0400 |
commit | f5339277eb8d3aed37f12a27988366f68ab68930 (patch) | |
tree | 4b8f14bb6144b128a2d3741aad21bfe24ba15b0d /arch/powerpc/kernel | |
parent | ec86b45af464d2d3c00d1125b220d6c3b6ca93d8 (diff) |
powerpc: Remove FW_FEATURE ISERIES from arch code
This is no longer selectable, so just remove all the dependent code.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 14 | ||||
-rw-r--r-- | arch/powerpc/kernel/isa-bridge.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 108 | ||||
-rw-r--r-- | arch/powerpc/kernel/paca.c | 12 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 108 |
7 files changed, 15 insertions, 252 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index eb804e15b29b..45b367c8d8b8 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -211,11 +211,6 @@ notrace void arch_local_irq_restore(unsigned long en) | |||
211 | * External interrupt events on non-iseries will have caused | 211 | * External interrupt events on non-iseries will have caused |
212 | * interrupts to be hard-disabled, so there is no problem, we | 212 | * interrupts to be hard-disabled, so there is no problem, we |
213 | * cannot have preempted. | 213 | * cannot have preempted. |
214 | * | ||
215 | * That leaves us with EEs on iSeries or decrementer interrupts, | ||
216 | * which I decided to safely ignore. The preemption would have | ||
217 | * itself been the result of an interrupt, upon which return we | ||
218 | * will have checked for pending events on the old CPU. | ||
219 | */ | 214 | */ |
220 | irq_happened = get_irq_happened(); | 215 | irq_happened = get_irq_happened(); |
221 | if (!irq_happened) | 216 | if (!irq_happened) |
@@ -458,15 +453,6 @@ void do_IRQ(struct pt_regs *regs) | |||
458 | irq_exit(); | 453 | irq_exit(); |
459 | set_irq_regs(old_regs); | 454 | set_irq_regs(old_regs); |
460 | 455 | ||
461 | #ifdef CONFIG_PPC_ISERIES | ||
462 | if (firmware_has_feature(FW_FEATURE_ISERIES) && | ||
463 | get_lppaca()->int_dword.fields.decr_int) { | ||
464 | get_lppaca()->int_dword.fields.decr_int = 0; | ||
465 | /* Signal a fake decrementer interrupt */ | ||
466 | timer_interrupt(regs); | ||
467 | } | ||
468 | #endif | ||
469 | |||
470 | trace_irq_exit(regs); | 456 | trace_irq_exit(regs); |
471 | } | 457 | } |
472 | 458 | ||
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c index 479752901ec6..d45ec58703ce 100644 --- a/arch/powerpc/kernel/isa-bridge.c +++ b/arch/powerpc/kernel/isa-bridge.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <asm/pci-bridge.h> | 29 | #include <asm/pci-bridge.h> |
30 | #include <asm/machdep.h> | 30 | #include <asm/machdep.h> |
31 | #include <asm/ppc-pci.h> | 31 | #include <asm/ppc-pci.h> |
32 | #include <asm/firmware.h> | ||
33 | 32 | ||
34 | unsigned long isa_io_base; /* NULL if no ISA bus */ | 33 | unsigned long isa_io_base; /* NULL if no ISA bus */ |
35 | EXPORT_SYMBOL(isa_io_base); | 34 | EXPORT_SYMBOL(isa_io_base); |
@@ -261,8 +260,6 @@ static struct notifier_block isa_bridge_notifier = { | |||
261 | */ | 260 | */ |
262 | static int __init isa_bridge_init(void) | 261 | static int __init isa_bridge_init(void) |
263 | { | 262 | { |
264 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
265 | return 0; | ||
266 | bus_register_notifier(&pci_bus_type, &isa_bridge_notifier); | 263 | bus_register_notifier(&pci_bus_type, &isa_bridge_notifier); |
267 | return 0; | 264 | return 0; |
268 | } | 265 | } |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 578f35f18723..ac12bd80ad95 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/iseries/hv_lp_config.h> | ||
30 | #include <asm/lppaca.h> | 29 | #include <asm/lppaca.h> |
31 | #include <asm/hvcall.h> | 30 | #include <asm/hvcall.h> |
32 | #include <asm/firmware.h> | 31 | #include <asm/firmware.h> |
@@ -55,80 +54,14 @@ static unsigned long get_purr(void) | |||
55 | int cpu; | 54 | int cpu; |
56 | 55 | ||
57 | for_each_possible_cpu(cpu) { | 56 | for_each_possible_cpu(cpu) { |
58 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 57 | struct cpu_usage *cu; |
59 | sum_purr += lppaca_of(cpu).emulated_time_base; | ||
60 | else { | ||
61 | struct cpu_usage *cu; | ||
62 | 58 | ||
63 | cu = &per_cpu(cpu_usage_array, cpu); | 59 | cu = &per_cpu(cpu_usage_array, cpu); |
64 | sum_purr += cu->current_tb; | 60 | sum_purr += cu->current_tb; |
65 | } | ||
66 | } | 61 | } |
67 | return sum_purr; | 62 | return sum_purr; |
68 | } | 63 | } |
69 | 64 | ||
70 | #ifdef CONFIG_PPC_ISERIES | ||
71 | |||
72 | /* | ||
73 | * Methods used to fetch LPAR data when running on an iSeries platform. | ||
74 | */ | ||
75 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
76 | { | ||
77 | unsigned long pool_id; | ||
78 | int shared, entitled_capacity, max_entitled_capacity; | ||
79 | int processors, max_processors; | ||
80 | unsigned long purr = get_purr(); | ||
81 | |||
82 | shared = (int)(local_paca->lppaca_ptr->shared_proc); | ||
83 | |||
84 | seq_printf(m, "system_active_processors=%d\n", | ||
85 | (int)HvLpConfig_getSystemPhysicalProcessors()); | ||
86 | |||
87 | seq_printf(m, "system_potential_processors=%d\n", | ||
88 | (int)HvLpConfig_getSystemPhysicalProcessors()); | ||
89 | |||
90 | processors = (int)HvLpConfig_getPhysicalProcessors(); | ||
91 | seq_printf(m, "partition_active_processors=%d\n", processors); | ||
92 | |||
93 | max_processors = (int)HvLpConfig_getMaxPhysicalProcessors(); | ||
94 | seq_printf(m, "partition_potential_processors=%d\n", max_processors); | ||
95 | |||
96 | if (shared) { | ||
97 | entitled_capacity = HvLpConfig_getSharedProcUnits(); | ||
98 | max_entitled_capacity = HvLpConfig_getMaxSharedProcUnits(); | ||
99 | } else { | ||
100 | entitled_capacity = processors * 100; | ||
101 | max_entitled_capacity = max_processors * 100; | ||
102 | } | ||
103 | seq_printf(m, "partition_entitled_capacity=%d\n", entitled_capacity); | ||
104 | |||
105 | seq_printf(m, "partition_max_entitled_capacity=%d\n", | ||
106 | max_entitled_capacity); | ||
107 | |||
108 | if (shared) { | ||
109 | pool_id = HvLpConfig_getSharedPoolIndex(); | ||
110 | seq_printf(m, "pool=%d\n", (int)pool_id); | ||
111 | seq_printf(m, "pool_capacity=%d\n", | ||
112 | (int)(HvLpConfig_getNumProcsInSharedPool(pool_id) * | ||
113 | 100)); | ||
114 | seq_printf(m, "purr=%ld\n", purr); | ||
115 | } | ||
116 | |||
117 | seq_printf(m, "shared_processor_mode=%d\n", shared); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | #else /* CONFIG_PPC_ISERIES */ | ||
123 | |||
124 | static int iseries_lparcfg_data(struct seq_file *m, void *v) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | #endif /* CONFIG_PPC_ISERIES */ | ||
130 | |||
131 | #ifdef CONFIG_PPC_PSERIES | ||
132 | /* | 65 | /* |
133 | * Methods used to fetch LPAR data when running on a pSeries platform. | 66 | * Methods used to fetch LPAR data when running on a pSeries platform. |
134 | */ | 67 | */ |
@@ -648,8 +581,7 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, | |||
648 | u8 new_weight, *new_weight_ptr = &new_weight; | 581 | u8 new_weight, *new_weight_ptr = &new_weight; |
649 | ssize_t retval; | 582 | ssize_t retval; |
650 | 583 | ||
651 | if (!firmware_has_feature(FW_FEATURE_SPLPAR) || | 584 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) |
652 | firmware_has_feature(FW_FEATURE_ISERIES)) | ||
653 | return -EINVAL; | 585 | return -EINVAL; |
654 | 586 | ||
655 | if (count > kbuf_sz) | 587 | if (count > kbuf_sz) |
@@ -709,21 +641,6 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, | |||
709 | return retval; | 641 | return retval; |
710 | } | 642 | } |
711 | 643 | ||
712 | #else /* CONFIG_PPC_PSERIES */ | ||
713 | |||
714 | static int pseries_lparcfg_data(struct seq_file *m, void *v) | ||
715 | { | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static ssize_t lparcfg_write(struct file *file, const char __user * buf, | ||
720 | size_t count, loff_t * off) | ||
721 | { | ||
722 | return -EINVAL; | ||
723 | } | ||
724 | |||
725 | #endif /* CONFIG_PPC_PSERIES */ | ||
726 | |||
727 | static int lparcfg_data(struct seq_file *m, void *v) | 644 | static int lparcfg_data(struct seq_file *m, void *v) |
728 | { | 645 | { |
729 | struct device_node *rootdn; | 646 | struct device_node *rootdn; |
@@ -738,19 +655,11 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
738 | rootdn = of_find_node_by_path("/"); | 655 | rootdn = of_find_node_by_path("/"); |
739 | if (rootdn) { | 656 | if (rootdn) { |
740 | tmp = of_get_property(rootdn, "model", NULL); | 657 | tmp = of_get_property(rootdn, "model", NULL); |
741 | if (tmp) { | 658 | if (tmp) |
742 | model = tmp; | 659 | model = tmp; |
743 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
744 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
745 | model += 4; | ||
746 | } | ||
747 | tmp = of_get_property(rootdn, "system-id", NULL); | 660 | tmp = of_get_property(rootdn, "system-id", NULL); |
748 | if (tmp) { | 661 | if (tmp) |
749 | system_id = tmp; | 662 | system_id = tmp; |
750 | /* Skip "IBM," - see platforms/iseries/dt.c */ | ||
751 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
752 | system_id += 4; | ||
753 | } | ||
754 | lp_index_ptr = of_get_property(rootdn, "ibm,partition-no", | 663 | lp_index_ptr = of_get_property(rootdn, "ibm,partition-no", |
755 | NULL); | 664 | NULL); |
756 | if (lp_index_ptr) | 665 | if (lp_index_ptr) |
@@ -761,8 +670,6 @@ static int lparcfg_data(struct seq_file *m, void *v) | |||
761 | seq_printf(m, "system_type=%s\n", model); | 670 | seq_printf(m, "system_type=%s\n", model); |
762 | seq_printf(m, "partition_id=%d\n", (int)lp_index); | 671 | seq_printf(m, "partition_id=%d\n", (int)lp_index); |
763 | 672 | ||
764 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
765 | return iseries_lparcfg_data(m, v); | ||
766 | return pseries_lparcfg_data(m, v); | 673 | return pseries_lparcfg_data(m, v); |
767 | } | 674 | } |
768 | 675 | ||
@@ -786,8 +693,7 @@ static int __init lparcfg_init(void) | |||
786 | umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; | 693 | umode_t mode = S_IRUSR | S_IRGRP | S_IROTH; |
787 | 694 | ||
788 | /* Allow writing if we have FW_FEATURE_SPLPAR */ | 695 | /* Allow writing if we have FW_FEATURE_SPLPAR */ |
789 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && | 696 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) |
790 | !firmware_has_feature(FW_FEATURE_ISERIES)) | ||
791 | mode |= S_IWUSR; | 697 | mode |= S_IWUSR; |
792 | 698 | ||
793 | ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops); | 699 | ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops); |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 41456ff55e14..0bb1f98613ba 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -11,13 +11,10 @@ | |||
11 | #include <linux/export.h> | 11 | #include <linux/export.h> |
12 | #include <linux/memblock.h> | 12 | #include <linux/memblock.h> |
13 | 13 | ||
14 | #include <asm/firmware.h> | ||
15 | #include <asm/lppaca.h> | 14 | #include <asm/lppaca.h> |
16 | #include <asm/paca.h> | 15 | #include <asm/paca.h> |
17 | #include <asm/sections.h> | 16 | #include <asm/sections.h> |
18 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
19 | #include <asm/iseries/lpar_map.h> | ||
20 | #include <asm/iseries/hv_types.h> | ||
21 | #include <asm/kexec.h> | 18 | #include <asm/kexec.h> |
22 | 19 | ||
23 | /* This symbol is provided by the linker - let it fill in the paca | 20 | /* This symbol is provided by the linker - let it fill in the paca |
@@ -30,8 +27,8 @@ extern unsigned long __toc_start; | |||
30 | * The structure which the hypervisor knows about - this structure | 27 | * The structure which the hypervisor knows about - this structure |
31 | * should not cross a page boundary. The vpa_init/register_vpa call | 28 | * should not cross a page boundary. The vpa_init/register_vpa call |
32 | * is now known to fail if the lppaca structure crosses a page | 29 | * is now known to fail if the lppaca structure crosses a page |
33 | * boundary. The lppaca is also used on legacy iSeries and POWER5 | 30 | * boundary. The lppaca is also used on POWER5 pSeries boxes. |
34 | * pSeries boxes. The lppaca is 640 bytes long, and cannot readily | 31 | * The lppaca is 640 bytes long, and cannot readily |
35 | * change since the hypervisor knows its layout, so a 1kB alignment | 32 | * change since the hypervisor knows its layout, so a 1kB alignment |
36 | * will suffice to ensure that it doesn't cross a page boundary. | 33 | * will suffice to ensure that it doesn't cross a page boundary. |
37 | */ | 34 | */ |
@@ -183,12 +180,9 @@ void __init allocate_pacas(void) | |||
183 | /* | 180 | /* |
184 | * We can't take SLB misses on the paca, and we want to access them | 181 | * We can't take SLB misses on the paca, and we want to access them |
185 | * in real mode, so allocate them within the RMA and also within | 182 | * in real mode, so allocate them within the RMA and also within |
186 | * the first segment. On iSeries they must be within the area mapped | 183 | * the first segment. |
187 | * by the HV, which is HvPagesToMap * HVPAGESIZE bytes. | ||
188 | */ | 184 | */ |
189 | limit = min(0x10000000ULL, ppc64_rma_size); | 185 | limit = min(0x10000000ULL, ppc64_rma_size); |
190 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
191 | limit = min(limit, HvPagesToMap * HVPAGESIZE); | ||
192 | 186 | ||
193 | paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids); | 187 | paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids); |
194 | 188 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index cce98d76e905..d0373bcb7c9d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <asm/byteorder.h> | 38 | #include <asm/byteorder.h> |
39 | #include <asm/machdep.h> | 39 | #include <asm/machdep.h> |
40 | #include <asm/ppc-pci.h> | 40 | #include <asm/ppc-pci.h> |
41 | #include <asm/firmware.h> | ||
42 | #include <asm/eeh.h> | 41 | #include <asm/eeh.h> |
43 | 42 | ||
44 | static DEFINE_SPINLOCK(hose_spinlock); | 43 | static DEFINE_SPINLOCK(hose_spinlock); |
@@ -219,20 +218,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) | |||
219 | struct of_irq oirq; | 218 | struct of_irq oirq; |
220 | unsigned int virq; | 219 | unsigned int virq; |
221 | 220 | ||
222 | /* The current device-tree that iSeries generates from the HV | ||
223 | * PCI informations doesn't contain proper interrupt routing, | ||
224 | * and all the fallback would do is print out crap, so we | ||
225 | * don't attempt to resolve the interrupts here at all, some | ||
226 | * iSeries specific fixup does it. | ||
227 | * | ||
228 | * In the long run, we will hopefully fix the generated device-tree | ||
229 | * instead. | ||
230 | */ | ||
231 | #ifdef CONFIG_PPC_ISERIES | ||
232 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
233 | return -1; | ||
234 | #endif | ||
235 | |||
236 | pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); | 221 | pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); |
237 | 222 | ||
238 | #ifdef DEBUG | 223 | #ifdef DEBUG |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 883e74c0d1b3..0c683d376b1c 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <asm/current.h> | 12 | #include <asm/current.h> |
13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
14 | #include <asm/cputable.h> | 14 | #include <asm/cputable.h> |
15 | #include <asm/firmware.h> | ||
16 | #include <asm/hvcall.h> | 15 | #include <asm/hvcall.h> |
17 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
18 | #include <asm/machdep.h> | 17 | #include <asm/machdep.h> |
@@ -341,8 +340,7 @@ static void __cpuinit register_cpu_online(unsigned int cpu) | |||
341 | int i, nattrs; | 340 | int i, nattrs; |
342 | 341 | ||
343 | #ifdef CONFIG_PPC64 | 342 | #ifdef CONFIG_PPC64 |
344 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && | 343 | if (cpu_has_feature(CPU_FTR_SMT)) |
345 | cpu_has_feature(CPU_FTR_SMT)) | ||
346 | device_create_file(s, &dev_attr_smt_snooze_delay); | 344 | device_create_file(s, &dev_attr_smt_snooze_delay); |
347 | #endif | 345 | #endif |
348 | 346 | ||
@@ -414,8 +412,7 @@ static void unregister_cpu_online(unsigned int cpu) | |||
414 | BUG_ON(!c->hotpluggable); | 412 | BUG_ON(!c->hotpluggable); |
415 | 413 | ||
416 | #ifdef CONFIG_PPC64 | 414 | #ifdef CONFIG_PPC64 |
417 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && | 415 | if (cpu_has_feature(CPU_FTR_SMT)) |
418 | cpu_has_feature(CPU_FTR_SMT)) | ||
419 | device_remove_file(s, &dev_attr_smt_snooze_delay); | 416 | device_remove_file(s, &dev_attr_smt_snooze_delay); |
420 | #endif | 417 | #endif |
421 | 418 | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index f81c81b92f0e..2c42cd72d0f5 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -17,8 +17,7 @@ | |||
17 | * | 17 | * |
18 | * TODO (not necessarily in this file): | 18 | * TODO (not necessarily in this file): |
19 | * - improve precision and reproducibility of timebase frequency | 19 | * - improve precision and reproducibility of timebase frequency |
20 | * measurement at boot time. (for iSeries, we calibrate the timebase | 20 | * measurement at boot time. |
21 | * against the Titan chip's clock.) | ||
22 | * - for astronomical applications: add a new function to get | 21 | * - for astronomical applications: add a new function to get |
23 | * non ambiguous timestamps even around leap seconds. This needs | 22 | * non ambiguous timestamps even around leap seconds. This needs |
24 | * a new timestamp format and a good name. | 23 | * a new timestamp format and a good name. |
@@ -70,10 +69,6 @@ | |||
70 | #include <asm/vdso_datapage.h> | 69 | #include <asm/vdso_datapage.h> |
71 | #include <asm/firmware.h> | 70 | #include <asm/firmware.h> |
72 | #include <asm/cputime.h> | 71 | #include <asm/cputime.h> |
73 | #ifdef CONFIG_PPC_ISERIES | ||
74 | #include <asm/iseries/it_lp_queue.h> | ||
75 | #include <asm/iseries/hv_call_xm.h> | ||
76 | #endif | ||
77 | 72 | ||
78 | /* powerpc clocksource/clockevent code */ | 73 | /* powerpc clocksource/clockevent code */ |
79 | 74 | ||
@@ -117,14 +112,6 @@ static struct clock_event_device decrementer_clockevent = { | |||
117 | DEFINE_PER_CPU(u64, decrementers_next_tb); | 112 | DEFINE_PER_CPU(u64, decrementers_next_tb); |
118 | static DEFINE_PER_CPU(struct clock_event_device, decrementers); | 113 | static DEFINE_PER_CPU(struct clock_event_device, decrementers); |
119 | 114 | ||
120 | #ifdef CONFIG_PPC_ISERIES | ||
121 | static unsigned long __initdata iSeries_recal_titan; | ||
122 | static signed long __initdata iSeries_recal_tb; | ||
123 | |||
124 | /* Forward declaration is only needed for iSereis compiles */ | ||
125 | static void __init clocksource_init(void); | ||
126 | #endif | ||
127 | |||
128 | #define XSEC_PER_SEC (1024*1024) | 115 | #define XSEC_PER_SEC (1024*1024) |
129 | 116 | ||
130 | #ifdef CONFIG_PPC64 | 117 | #ifdef CONFIG_PPC64 |
@@ -423,74 +410,6 @@ unsigned long profile_pc(struct pt_regs *regs) | |||
423 | EXPORT_SYMBOL(profile_pc); | 410 | EXPORT_SYMBOL(profile_pc); |
424 | #endif | 411 | #endif |
425 | 412 | ||
426 | #ifdef CONFIG_PPC_ISERIES | ||
427 | |||
428 | /* | ||
429 | * This function recalibrates the timebase based on the 49-bit time-of-day | ||
430 | * value in the Titan chip. The Titan is much more accurate than the value | ||
431 | * returned by the service processor for the timebase frequency. | ||
432 | */ | ||
433 | |||
434 | static int __init iSeries_tb_recal(void) | ||
435 | { | ||
436 | unsigned long titan, tb; | ||
437 | |||
438 | /* Make sure we only run on iSeries */ | ||
439 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
440 | return -ENODEV; | ||
441 | |||
442 | tb = get_tb(); | ||
443 | titan = HvCallXm_loadTod(); | ||
444 | if ( iSeries_recal_titan ) { | ||
445 | unsigned long tb_ticks = tb - iSeries_recal_tb; | ||
446 | unsigned long titan_usec = (titan - iSeries_recal_titan) >> 12; | ||
447 | unsigned long new_tb_ticks_per_sec = (tb_ticks * USEC_PER_SEC)/titan_usec; | ||
448 | unsigned long new_tb_ticks_per_jiffy = | ||
449 | DIV_ROUND_CLOSEST(new_tb_ticks_per_sec, HZ); | ||
450 | long tick_diff = new_tb_ticks_per_jiffy - tb_ticks_per_jiffy; | ||
451 | char sign = '+'; | ||
452 | /* make sure tb_ticks_per_sec and tb_ticks_per_jiffy are consistent */ | ||
453 | new_tb_ticks_per_sec = new_tb_ticks_per_jiffy * HZ; | ||
454 | |||
455 | if ( tick_diff < 0 ) { | ||
456 | tick_diff = -tick_diff; | ||
457 | sign = '-'; | ||
458 | } | ||
459 | if ( tick_diff ) { | ||
460 | if ( tick_diff < tb_ticks_per_jiffy/25 ) { | ||
461 | printk( "Titan recalibrate: new tb_ticks_per_jiffy = %lu (%c%ld)\n", | ||
462 | new_tb_ticks_per_jiffy, sign, tick_diff ); | ||
463 | tb_ticks_per_jiffy = new_tb_ticks_per_jiffy; | ||
464 | tb_ticks_per_sec = new_tb_ticks_per_sec; | ||
465 | calc_cputime_factors(); | ||
466 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | ||
467 | setup_cputime_one_jiffy(); | ||
468 | } | ||
469 | else { | ||
470 | printk( "Titan recalibrate: FAILED (difference > 4 percent)\n" | ||
471 | " new tb_ticks_per_jiffy = %lu\n" | ||
472 | " old tb_ticks_per_jiffy = %lu\n", | ||
473 | new_tb_ticks_per_jiffy, tb_ticks_per_jiffy ); | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | iSeries_recal_titan = titan; | ||
478 | iSeries_recal_tb = tb; | ||
479 | |||
480 | /* Called here as now we know accurate values for the timebase */ | ||
481 | clocksource_init(); | ||
482 | return 0; | ||
483 | } | ||
484 | late_initcall(iSeries_tb_recal); | ||
485 | |||
486 | /* Called from platform early init */ | ||
487 | void __init iSeries_time_init_early(void) | ||
488 | { | ||
489 | iSeries_recal_tb = get_tb(); | ||
490 | iSeries_recal_titan = HvCallXm_loadTod(); | ||
491 | } | ||
492 | #endif /* CONFIG_PPC_ISERIES */ | ||
493 | |||
494 | #ifdef CONFIG_IRQ_WORK | 413 | #ifdef CONFIG_IRQ_WORK |
495 | 414 | ||
496 | /* | 415 | /* |
@@ -547,16 +466,6 @@ void arch_irq_work_raise(void) | |||
547 | #endif /* CONFIG_IRQ_WORK */ | 466 | #endif /* CONFIG_IRQ_WORK */ |
548 | 467 | ||
549 | /* | 468 | /* |
550 | * For iSeries shared processors, we have to let the hypervisor | ||
551 | * set the hardware decrementer. We set a virtual decrementer | ||
552 | * in the lppaca and call the hypervisor if the virtual | ||
553 | * decrementer is less than the current value in the hardware | ||
554 | * decrementer. (almost always the new decrementer value will | ||
555 | * be greater than the current hardware decementer so the hypervisor | ||
556 | * call will not be needed) | ||
557 | */ | ||
558 | |||
559 | /* | ||
560 | * timer_interrupt - gets called when the decrementer overflows, | 469 | * timer_interrupt - gets called when the decrementer overflows, |
561 | * with interrupts disabled. | 470 | * with interrupts disabled. |
562 | */ | 471 | */ |
@@ -599,20 +508,10 @@ void timer_interrupt(struct pt_regs * regs) | |||
599 | irq_work_run(); | 508 | irq_work_run(); |
600 | } | 509 | } |
601 | 510 | ||
602 | #ifdef CONFIG_PPC_ISERIES | ||
603 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
604 | get_lppaca()->int_dword.fields.decr_int = 0; | ||
605 | #endif | ||
606 | |||
607 | *next_tb = ~(u64)0; | 511 | *next_tb = ~(u64)0; |
608 | if (evt->event_handler) | 512 | if (evt->event_handler) |
609 | evt->event_handler(evt); | 513 | evt->event_handler(evt); |
610 | 514 | ||
611 | #ifdef CONFIG_PPC_ISERIES | ||
612 | if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) | ||
613 | process_hvlpevents(); | ||
614 | #endif | ||
615 | |||
616 | #ifdef CONFIG_PPC64 | 515 | #ifdef CONFIG_PPC64 |
617 | /* collect purr register values often, for accurate calculations */ | 516 | /* collect purr register values often, for accurate calculations */ |
618 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 517 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
@@ -984,9 +883,8 @@ void __init time_init(void) | |||
984 | */ | 883 | */ |
985 | start_cpu_decrementer(); | 884 | start_cpu_decrementer(); |
986 | 885 | ||
987 | /* Register the clocksource, if we're not running on iSeries */ | 886 | /* Register the clocksource */ |
988 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | 887 | clocksource_init(); |
989 | clocksource_init(); | ||
990 | 888 | ||
991 | init_decrementer_clockevent(); | 889 | init_decrementer_clockevent(); |
992 | } | 890 | } |