1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2d670bd4fSSam Ravnborg /* smp.c: Sparc SMP support.
3d670bd4fSSam Ravnborg *
4d670bd4fSSam Ravnborg * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5d670bd4fSSam Ravnborg * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6d670bd4fSSam Ravnborg * Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
7d670bd4fSSam Ravnborg */
8d670bd4fSSam Ravnborg
9d670bd4fSSam Ravnborg #include <asm/head.h>
10d670bd4fSSam Ravnborg
11d670bd4fSSam Ravnborg #include <linux/kernel.h>
12d670bd4fSSam Ravnborg #include <linux/sched.h>
13d670bd4fSSam Ravnborg #include <linux/threads.h>
14d670bd4fSSam Ravnborg #include <linux/smp.h>
15d670bd4fSSam Ravnborg #include <linux/interrupt.h>
16d670bd4fSSam Ravnborg #include <linux/kernel_stat.h>
17d670bd4fSSam Ravnborg #include <linux/init.h>
18d670bd4fSSam Ravnborg #include <linux/spinlock.h>
19d670bd4fSSam Ravnborg #include <linux/mm.h>
20d670bd4fSSam Ravnborg #include <linux/fs.h>
21d670bd4fSSam Ravnborg #include <linux/seq_file.h>
22d670bd4fSSam Ravnborg #include <linux/cache.h>
23d670bd4fSSam Ravnborg #include <linux/delay.h>
24d3091298SSam Ravnborg #include <linux/profile.h>
25f9fd3488SSam Ravnborg #include <linux/cpu.h>
26d670bd4fSSam Ravnborg
27d670bd4fSSam Ravnborg #include <asm/ptrace.h>
2860063497SArun Sharma #include <linux/atomic.h>
29d670bd4fSSam Ravnborg
30d670bd4fSSam Ravnborg #include <asm/irq.h>
31d670bd4fSSam Ravnborg #include <asm/page.h>
32d670bd4fSSam Ravnborg #include <asm/oplib.h>
33d670bd4fSSam Ravnborg #include <asm/cacheflush.h>
34d670bd4fSSam Ravnborg #include <asm/tlbflush.h>
35d670bd4fSSam Ravnborg #include <asm/cpudata.h>
36f9fd3488SSam Ravnborg #include <asm/timer.h>
378401707fSKonrad Eisele #include <asm/leon.h>
38d670bd4fSSam Ravnborg
39f9fd3488SSam Ravnborg #include "kernel.h"
40d670bd4fSSam Ravnborg #include "irq.h"
41d670bd4fSSam Ravnborg
422066aaddSPaul Gortmaker volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
43d670bd4fSSam Ravnborg
44d670bd4fSSam Ravnborg cpumask_t smp_commenced_mask = CPU_MASK_NONE;
45d670bd4fSSam Ravnborg
464ba22b16SSam Ravnborg const struct sparc32_ipi_ops *sparc32_ipi_ops;
474ba22b16SSam Ravnborg
48d670bd4fSSam Ravnborg /* The only guaranteed locking primitive available on all Sparc
49d670bd4fSSam Ravnborg * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically
50d670bd4fSSam Ravnborg * places the current byte at the effective address into dest_reg and
51d670bd4fSSam Ravnborg * places 0xff there afterwards. Pretty lame locking primitive
52d670bd4fSSam Ravnborg * compared to the Alpha and the Intel no? Most Sparcs have 'swap'
53d670bd4fSSam Ravnborg * instruction which is much better...
54d670bd4fSSam Ravnborg */
55d670bd4fSSam Ravnborg
smp_store_cpu_info(int id)562066aaddSPaul Gortmaker void smp_store_cpu_info(int id)
57d670bd4fSSam Ravnborg {
58d670bd4fSSam Ravnborg int cpu_node;
59f486b3dcSSam Ravnborg int mid;
60d670bd4fSSam Ravnborg
61d670bd4fSSam Ravnborg cpu_data(id).udelay_val = loops_per_jiffy;
62d670bd4fSSam Ravnborg
63d670bd4fSSam Ravnborg cpu_find_by_mid(id, &cpu_node);
64d670bd4fSSam Ravnborg cpu_data(id).clock_tick = prom_getintdefault(cpu_node,
65d670bd4fSSam Ravnborg "clock-frequency", 0);
66d670bd4fSSam Ravnborg cpu_data(id).prom_node = cpu_node;
67f486b3dcSSam Ravnborg mid = cpu_get_hwmid(cpu_node);
68d670bd4fSSam Ravnborg
69f486b3dcSSam Ravnborg if (mid < 0) {
70551d57ffSHans Wennborg printk(KERN_NOTICE "No MID found for CPU%d at node 0x%08x", id, cpu_node);
71f486b3dcSSam Ravnborg mid = 0;
72f486b3dcSSam Ravnborg }
73f486b3dcSSam Ravnborg cpu_data(id).mid = mid;
74d670bd4fSSam Ravnborg }
75d670bd4fSSam Ravnborg
smp_cpus_done(unsigned int max_cpus)76d670bd4fSSam Ravnborg void __init smp_cpus_done(unsigned int max_cpus)
77d670bd4fSSam Ravnborg {
78d670bd4fSSam Ravnborg unsigned long bogosum = 0;
79ec7c14bdSRusty Russell int cpu, num = 0;
80d670bd4fSSam Ravnborg
81ec7c14bdSRusty Russell for_each_online_cpu(cpu) {
82d670bd4fSSam Ravnborg num++;
83d670bd4fSSam Ravnborg bogosum += cpu_data(cpu).udelay_val;
84d670bd4fSSam Ravnborg }
85d670bd4fSSam Ravnborg
86d670bd4fSSam Ravnborg printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
87d670bd4fSSam Ravnborg num, bogosum/(500000/HZ),
88d670bd4fSSam Ravnborg (bogosum/(5000/HZ))%100);
89d670bd4fSSam Ravnborg
90d670bd4fSSam Ravnborg switch(sparc_cpu_model) {
91d670bd4fSSam Ravnborg case sun4m:
92d670bd4fSSam Ravnborg smp4m_smp_done();
93d670bd4fSSam Ravnborg break;
94d670bd4fSSam Ravnborg case sun4d:
95d670bd4fSSam Ravnborg smp4d_smp_done();
96d670bd4fSSam Ravnborg break;
978401707fSKonrad Eisele case sparc_leon:
988401707fSKonrad Eisele leon_smp_done();
998401707fSKonrad Eisele break;
100d670bd4fSSam Ravnborg case sun4e:
101d670bd4fSSam Ravnborg printk("SUN4E\n");
102d670bd4fSSam Ravnborg BUG();
103d670bd4fSSam Ravnborg break;
104d670bd4fSSam Ravnborg case sun4u:
105d670bd4fSSam Ravnborg printk("SUN4U\n");
106d670bd4fSSam Ravnborg BUG();
107d670bd4fSSam Ravnborg break;
108d670bd4fSSam Ravnborg default:
109d670bd4fSSam Ravnborg printk("UNKNOWN!\n");
110d670bd4fSSam Ravnborg BUG();
111d670bd4fSSam Ravnborg break;
1126cb79b3fSJoe Perches }
113d670bd4fSSam Ravnborg }
114d670bd4fSSam Ravnborg
cpu_panic(void)115d670bd4fSSam Ravnborg void cpu_panic(void)
116d670bd4fSSam Ravnborg {
117d670bd4fSSam Ravnborg printk("CPU[%d]: Returns from cpu_idle!\n", smp_processor_id());
118d670bd4fSSam Ravnborg panic("SMP bolixed\n");
119d670bd4fSSam Ravnborg }
120d670bd4fSSam Ravnborg
1212066aaddSPaul Gortmaker struct linux_prom_registers smp_penguin_ctable = { 0 };
122d670bd4fSSam Ravnborg
arch_smp_send_reschedule(int cpu)123*4c8c3c7fSValentin Schneider void arch_smp_send_reschedule(int cpu)
124d670bd4fSSam Ravnborg {
125d6d04819SDaniel Hellstrom /*
126d6d04819SDaniel Hellstrom * CPU model dependent way of implementing IPI generation targeting
127d6d04819SDaniel Hellstrom * a single CPU. The trap handler needs only to do trap entry/return
128d6d04819SDaniel Hellstrom * to call schedule.
129d6d04819SDaniel Hellstrom */
1304ba22b16SSam Ravnborg sparc32_ipi_ops->resched(cpu);
131d670bd4fSSam Ravnborg }
132d670bd4fSSam Ravnborg
smp_send_stop(void)133d670bd4fSSam Ravnborg void smp_send_stop(void)
134d670bd4fSSam Ravnborg {
135d670bd4fSSam Ravnborg }
136d670bd4fSSam Ravnborg
arch_send_call_function_single_ipi(int cpu)137d6d04819SDaniel Hellstrom void arch_send_call_function_single_ipi(int cpu)
138d6d04819SDaniel Hellstrom {
139d6d04819SDaniel Hellstrom /* trigger one IPI single call on one CPU */
1404ba22b16SSam Ravnborg sparc32_ipi_ops->single(cpu);
141d6d04819SDaniel Hellstrom }
142d6d04819SDaniel Hellstrom
arch_send_call_function_ipi_mask(const struct cpumask * mask)143d6d04819SDaniel Hellstrom void arch_send_call_function_ipi_mask(const struct cpumask *mask)
144d6d04819SDaniel Hellstrom {
145d6d04819SDaniel Hellstrom int cpu;
146d6d04819SDaniel Hellstrom
147d6d04819SDaniel Hellstrom /* trigger IPI mask call on each CPU */
148d6d04819SDaniel Hellstrom for_each_cpu(cpu, mask)
1494ba22b16SSam Ravnborg sparc32_ipi_ops->mask_one(cpu);
150d6d04819SDaniel Hellstrom }
151d6d04819SDaniel Hellstrom
smp_resched_interrupt(void)152d6d04819SDaniel Hellstrom void smp_resched_interrupt(void)
153d6d04819SDaniel Hellstrom {
15490d3ac15SDavid S. Miller irq_enter();
15590d3ac15SDavid S. Miller scheduler_ipi();
156d6d04819SDaniel Hellstrom local_cpu_data().irq_resched_count++;
15790d3ac15SDavid S. Miller irq_exit();
15890d3ac15SDavid S. Miller /* re-schedule routine called by interrupt return code. */
159d6d04819SDaniel Hellstrom }
160d6d04819SDaniel Hellstrom
smp_call_function_single_interrupt(void)161d6d04819SDaniel Hellstrom void smp_call_function_single_interrupt(void)
162d6d04819SDaniel Hellstrom {
163d6d04819SDaniel Hellstrom irq_enter();
164d6d04819SDaniel Hellstrom generic_smp_call_function_single_interrupt();
165d6d04819SDaniel Hellstrom local_cpu_data().irq_call_count++;
166d6d04819SDaniel Hellstrom irq_exit();
167d6d04819SDaniel Hellstrom }
168d6d04819SDaniel Hellstrom
smp_call_function_interrupt(void)169d6d04819SDaniel Hellstrom void smp_call_function_interrupt(void)
170d6d04819SDaniel Hellstrom {
171d6d04819SDaniel Hellstrom irq_enter();
172d6d04819SDaniel Hellstrom generic_smp_call_function_interrupt();
173d6d04819SDaniel Hellstrom local_cpu_data().irq_call_count++;
174d6d04819SDaniel Hellstrom irq_exit();
175d6d04819SDaniel Hellstrom }
176d6d04819SDaniel Hellstrom
smp_prepare_cpus(unsigned int max_cpus)177d670bd4fSSam Ravnborg void __init smp_prepare_cpus(unsigned int max_cpus)
178d670bd4fSSam Ravnborg {
179d670bd4fSSam Ravnborg int i, cpuid, extra;
180d670bd4fSSam Ravnborg
181d670bd4fSSam Ravnborg printk("Entering SMP Mode...\n");
182d670bd4fSSam Ravnborg
183d670bd4fSSam Ravnborg extra = 0;
184d670bd4fSSam Ravnborg for (i = 0; !cpu_find_by_instance(i, NULL, &cpuid); i++) {
185d670bd4fSSam Ravnborg if (cpuid >= NR_CPUS)
186d670bd4fSSam Ravnborg extra++;
187d670bd4fSSam Ravnborg }
188d670bd4fSSam Ravnborg /* i = number of cpus */
189d670bd4fSSam Ravnborg if (extra && max_cpus > i - extra)
190d670bd4fSSam Ravnborg printk("Warning: NR_CPUS is too low to start all cpus\n");
191d670bd4fSSam Ravnborg
192d670bd4fSSam Ravnborg smp_store_cpu_info(boot_cpu_id);
193d670bd4fSSam Ravnborg
194d670bd4fSSam Ravnborg switch(sparc_cpu_model) {
195d670bd4fSSam Ravnborg case sun4m:
196d670bd4fSSam Ravnborg smp4m_boot_cpus();
197d670bd4fSSam Ravnborg break;
198d670bd4fSSam Ravnborg case sun4d:
199d670bd4fSSam Ravnborg smp4d_boot_cpus();
200d670bd4fSSam Ravnborg break;
2018401707fSKonrad Eisele case sparc_leon:
2028401707fSKonrad Eisele leon_boot_cpus();
2038401707fSKonrad Eisele break;
204d670bd4fSSam Ravnborg case sun4e:
205d670bd4fSSam Ravnborg printk("SUN4E\n");
206d670bd4fSSam Ravnborg BUG();
207d670bd4fSSam Ravnborg break;
208d670bd4fSSam Ravnborg case sun4u:
209d670bd4fSSam Ravnborg printk("SUN4U\n");
210d670bd4fSSam Ravnborg BUG();
211d670bd4fSSam Ravnborg break;
212d670bd4fSSam Ravnborg default:
213d670bd4fSSam Ravnborg printk("UNKNOWN!\n");
214d670bd4fSSam Ravnborg BUG();
215d670bd4fSSam Ravnborg break;
2166cb79b3fSJoe Perches }
217d670bd4fSSam Ravnborg }
218d670bd4fSSam Ravnborg
219d670bd4fSSam Ravnborg /* Set this up early so that things like the scheduler can init
220d670bd4fSSam Ravnborg * properly. We use the same cpu mask for both the present and
221d670bd4fSSam Ravnborg * possible cpu map.
222d670bd4fSSam Ravnborg */
smp_setup_cpu_possible_map(void)223d670bd4fSSam Ravnborg void __init smp_setup_cpu_possible_map(void)
224d670bd4fSSam Ravnborg {
225d670bd4fSSam Ravnborg int instance, mid;
226d670bd4fSSam Ravnborg
227d670bd4fSSam Ravnborg instance = 0;
228d670bd4fSSam Ravnborg while (!cpu_find_by_instance(instance, NULL, &mid)) {
229d670bd4fSSam Ravnborg if (mid < NR_CPUS) {
230fe73971cSRusty Russell set_cpu_possible(mid, true);
231fe73971cSRusty Russell set_cpu_present(mid, true);
232d670bd4fSSam Ravnborg }
233d670bd4fSSam Ravnborg instance++;
234d670bd4fSSam Ravnborg }
235d670bd4fSSam Ravnborg }
236d670bd4fSSam Ravnborg
smp_prepare_boot_cpu(void)237d670bd4fSSam Ravnborg void __init smp_prepare_boot_cpu(void)
238d670bd4fSSam Ravnborg {
239d670bd4fSSam Ravnborg int cpuid = hard_smp_processor_id();
240d670bd4fSSam Ravnborg
241d670bd4fSSam Ravnborg if (cpuid >= NR_CPUS) {
242d670bd4fSSam Ravnborg prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
243d670bd4fSSam Ravnborg prom_halt();
244d670bd4fSSam Ravnborg }
245d670bd4fSSam Ravnborg if (cpuid != 0)
246d670bd4fSSam Ravnborg printk("boot cpu id != 0, this could work but is untested\n");
247d670bd4fSSam Ravnborg
248d670bd4fSSam Ravnborg current_thread_info()->cpu = cpuid;
249fe73971cSRusty Russell set_cpu_online(cpuid, true);
250fe73971cSRusty Russell set_cpu_possible(cpuid, true);
251d670bd4fSSam Ravnborg }
252d670bd4fSSam Ravnborg
__cpu_up(unsigned int cpu,struct task_struct * tidle)2532066aaddSPaul Gortmaker int __cpu_up(unsigned int cpu, struct task_struct *tidle)
254d670bd4fSSam Ravnborg {
255d670bd4fSSam Ravnborg int ret=0;
256d670bd4fSSam Ravnborg
257d670bd4fSSam Ravnborg switch(sparc_cpu_model) {
258d670bd4fSSam Ravnborg case sun4m:
259f0a2bc7eSThomas Gleixner ret = smp4m_boot_one_cpu(cpu, tidle);
260d670bd4fSSam Ravnborg break;
261d670bd4fSSam Ravnborg case sun4d:
262f0a2bc7eSThomas Gleixner ret = smp4d_boot_one_cpu(cpu, tidle);
263d670bd4fSSam Ravnborg break;
2648401707fSKonrad Eisele case sparc_leon:
265f0a2bc7eSThomas Gleixner ret = leon_boot_one_cpu(cpu, tidle);
2668401707fSKonrad Eisele break;
267d670bd4fSSam Ravnborg case sun4e:
268d670bd4fSSam Ravnborg printk("SUN4E\n");
269d670bd4fSSam Ravnborg BUG();
270d670bd4fSSam Ravnborg break;
271d670bd4fSSam Ravnborg case sun4u:
272d670bd4fSSam Ravnborg printk("SUN4U\n");
273d670bd4fSSam Ravnborg BUG();
274d670bd4fSSam Ravnborg break;
275d670bd4fSSam Ravnborg default:
276d670bd4fSSam Ravnborg printk("UNKNOWN!\n");
277d670bd4fSSam Ravnborg BUG();
278d670bd4fSSam Ravnborg break;
2796cb79b3fSJoe Perches }
280d670bd4fSSam Ravnborg
281d670bd4fSSam Ravnborg if (!ret) {
282fb1fece5SKOSAKI Motohiro cpumask_set_cpu(cpu, &smp_commenced_mask);
283d670bd4fSSam Ravnborg while (!cpu_online(cpu))
284d670bd4fSSam Ravnborg mb();
285d670bd4fSSam Ravnborg }
286d670bd4fSSam Ravnborg return ret;
287d670bd4fSSam Ravnborg }
288d670bd4fSSam Ravnborg
arch_cpu_pre_starting(void * arg)289c0b0ba84SSam Ravnborg static void arch_cpu_pre_starting(void *arg)
290f9fd3488SSam Ravnborg {
291f9fd3488SSam Ravnborg local_ops->cache_all();
292f9fd3488SSam Ravnborg local_ops->tlb_all();
293f9fd3488SSam Ravnborg
294f9fd3488SSam Ravnborg switch(sparc_cpu_model) {
295f9fd3488SSam Ravnborg case sun4m:
296f9fd3488SSam Ravnborg sun4m_cpu_pre_starting(arg);
297f9fd3488SSam Ravnborg break;
298f9fd3488SSam Ravnborg case sun4d:
299f9fd3488SSam Ravnborg sun4d_cpu_pre_starting(arg);
300f9fd3488SSam Ravnborg break;
301f9fd3488SSam Ravnborg case sparc_leon:
302f9fd3488SSam Ravnborg leon_cpu_pre_starting(arg);
303f9fd3488SSam Ravnborg break;
304f9fd3488SSam Ravnborg default:
305f9fd3488SSam Ravnborg BUG();
306f9fd3488SSam Ravnborg }
307f9fd3488SSam Ravnborg }
308f9fd3488SSam Ravnborg
arch_cpu_pre_online(void * arg)309c0b0ba84SSam Ravnborg static void arch_cpu_pre_online(void *arg)
310f9fd3488SSam Ravnborg {
311f9fd3488SSam Ravnborg unsigned int cpuid = hard_smp_processor_id();
312f9fd3488SSam Ravnborg
313f9fd3488SSam Ravnborg register_percpu_ce(cpuid);
314f9fd3488SSam Ravnborg
315f9fd3488SSam Ravnborg calibrate_delay();
316f9fd3488SSam Ravnborg smp_store_cpu_info(cpuid);
317f9fd3488SSam Ravnborg
318f9fd3488SSam Ravnborg local_ops->cache_all();
319f9fd3488SSam Ravnborg local_ops->tlb_all();
320f9fd3488SSam Ravnborg
321f9fd3488SSam Ravnborg switch(sparc_cpu_model) {
322f9fd3488SSam Ravnborg case sun4m:
323f9fd3488SSam Ravnborg sun4m_cpu_pre_online(arg);
324f9fd3488SSam Ravnborg break;
325f9fd3488SSam Ravnborg case sun4d:
326f9fd3488SSam Ravnborg sun4d_cpu_pre_online(arg);
327f9fd3488SSam Ravnborg break;
328f9fd3488SSam Ravnborg case sparc_leon:
329f9fd3488SSam Ravnborg leon_cpu_pre_online(arg);
330f9fd3488SSam Ravnborg break;
331f9fd3488SSam Ravnborg default:
332f9fd3488SSam Ravnborg BUG();
333f9fd3488SSam Ravnborg }
334f9fd3488SSam Ravnborg }
335f9fd3488SSam Ravnborg
sparc_start_secondary(void * arg)336c0b0ba84SSam Ravnborg static void sparc_start_secondary(void *arg)
337f9fd3488SSam Ravnborg {
338f9fd3488SSam Ravnborg unsigned int cpu;
339f9fd3488SSam Ravnborg
340f9fd3488SSam Ravnborg /*
341f9fd3488SSam Ravnborg * SMP booting is extremely fragile in some architectures. So run
342f9fd3488SSam Ravnborg * the cpu initialization code first before anything else.
343f9fd3488SSam Ravnborg */
344f9fd3488SSam Ravnborg arch_cpu_pre_starting(arg);
345f9fd3488SSam Ravnborg
346f9fd3488SSam Ravnborg cpu = smp_processor_id();
347f9fd3488SSam Ravnborg
348f9fd3488SSam Ravnborg notify_cpu_starting(cpu);
349f9fd3488SSam Ravnborg arch_cpu_pre_online(arg);
350f9fd3488SSam Ravnborg
351f9fd3488SSam Ravnborg /* Set the CPU in the cpu_online_mask */
352f9fd3488SSam Ravnborg set_cpu_online(cpu, true);
353f9fd3488SSam Ravnborg
354f9fd3488SSam Ravnborg /* Enable local interrupts now */
355f9fd3488SSam Ravnborg local_irq_enable();
356f9fd3488SSam Ravnborg
357f9fd3488SSam Ravnborg wmb();
358fc6d73d6SThomas Gleixner cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
359f9fd3488SSam Ravnborg
360f9fd3488SSam Ravnborg /* We should never reach here! */
361f9fd3488SSam Ravnborg BUG();
362f9fd3488SSam Ravnborg }
363f9fd3488SSam Ravnborg
smp_callin(void)3642066aaddSPaul Gortmaker void smp_callin(void)
365f9fd3488SSam Ravnborg {
366f9fd3488SSam Ravnborg sparc_start_secondary(NULL);
367f9fd3488SSam Ravnborg }
368f9fd3488SSam Ravnborg
smp_bogo(struct seq_file * m)369d670bd4fSSam Ravnborg void smp_bogo(struct seq_file *m)
370d670bd4fSSam Ravnborg {
371d670bd4fSSam Ravnborg int i;
372d670bd4fSSam Ravnborg
373d670bd4fSSam Ravnborg for_each_online_cpu(i) {
374d670bd4fSSam Ravnborg seq_printf(m,
375d670bd4fSSam Ravnborg "Cpu%dBogo\t: %lu.%02lu\n",
376d670bd4fSSam Ravnborg i,
377d670bd4fSSam Ravnborg cpu_data(i).udelay_val/(500000/HZ),
378d670bd4fSSam Ravnborg (cpu_data(i).udelay_val/(5000/HZ))%100);
379d670bd4fSSam Ravnborg }
380d670bd4fSSam Ravnborg }
381d670bd4fSSam Ravnborg
smp_info(struct seq_file * m)382d670bd4fSSam Ravnborg void smp_info(struct seq_file *m)
383d670bd4fSSam Ravnborg {
384d670bd4fSSam Ravnborg int i;
385d670bd4fSSam Ravnborg
386d670bd4fSSam Ravnborg seq_printf(m, "State:\n");
387d670bd4fSSam Ravnborg for_each_online_cpu(i)
388d670bd4fSSam Ravnborg seq_printf(m, "CPU%d\t\t: online\n", i);
389d670bd4fSSam Ravnborg }
390