From: Anton Blanchard Cleanup ppc64 procfs code: - Use initcalls everywhere. This allowed us to remove the iseries proc callback interface. - Kill proc_pmc.c. Most of it wasnt used (and we are planning to export the PMCs via sysfs). The few things left were iseries specific so they got moved into iSeries_proc.c. - Kill pmc.c. We dont use those statistics and the ones that are left can be gained via PMCs. - Create /proc/iSeries and /proc/ppc64 very early. This means we no longer have to call proc_ppc64_init in all the drivers, we can assume its there. - Fix some error return cases in rtas-proc.c and rtas-flash - Dont even try some pseries specific drivers on pmac. --- 25-akpm/arch/ppc/platforms/proc_rtas.c | 10 25-akpm/arch/ppc64/kernel/Makefile | 4 25-akpm/arch/ppc64/kernel/iSeries_proc.c | 263 ++++--- 25-akpm/arch/ppc64/kernel/iSeries_setup.c | 4 25-akpm/arch/ppc64/kernel/mf.c | 3 25-akpm/arch/ppc64/kernel/mf_proc.c | 24 25-akpm/arch/ppc64/kernel/pmc.c | 167 ---- 25-akpm/arch/ppc64/kernel/ppc_ksyms.c | 2 25-akpm/arch/ppc64/kernel/proc_pmc.c | 810 ----------------------- 25-akpm/arch/ppc64/kernel/proc_ppc64.c | 151 +--- 25-akpm/arch/ppc64/kernel/ras.c | 1 25-akpm/arch/ppc64/kernel/rtas-proc.c | 76 +- 25-akpm/arch/ppc64/kernel/rtas.c | 1 25-akpm/arch/ppc64/kernel/rtas_flash.c | 94 +- 25-akpm/arch/ppc64/kernel/rtasd.c | 18 25-akpm/arch/ppc64/kernel/scanlog.c | 12 25-akpm/arch/ppc64/kernel/viopath.c | 101 +- 25-akpm/arch/ppc64/mm/hash_utils.c | 1 25-akpm/arch/ppc64/mm/init.c | 1 25-akpm/fs/proc/root.c | 3 25-akpm/include/asm-ppc64/iSeries/iSeries_proc.h | 6 25-akpm/include/asm-ppc64/iSeries/mf.h | 2 25-akpm/include/asm-ppc64/pmc.h | 113 --- 25-akpm/include/asm-ppc64/proc_fs.h | 39 - 25-akpm/include/asm-ppc64/proc_pmc.h | 33 25 files changed, 394 insertions(+), 1545 deletions(-) diff -puN arch/ppc/platforms/proc_rtas.c~ppc64-procfs-cleanup arch/ppc/platforms/proc_rtas.c --- 25/arch/ppc/platforms/proc_rtas.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.153634880 -0800 +++ 25-akpm/arch/ppc/platforms/proc_rtas.c 2004-03-14 15:35:15.189629408 -0800 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -194,18 +195,18 @@ int check_location (char *c, int idx, ch /* ****************************************************************** */ /* MAIN */ /* ****************************************************************** */ -void proc_rtas_init(void) +static int __init proc_rtas_init(void) { struct proc_dir_entry *entry; rtas = find_devices("rtas"); if ((rtas == 0) || (_machine != _MACH_chrp)) { - return; + return 1; } proc_rtas = proc_mkdir("rtas", 0); if (proc_rtas == 0) - return; + return 1; /* /proc/rtas entries */ @@ -226,7 +227,10 @@ void proc_rtas_init(void) entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + + return 0; } +__initcall(proc_rtas_init); /* ****************************************************************** */ /* POWER-ON-TIME */ diff -puN arch/ppc64/kernel/Makefile~ppc64-procfs-cleanup arch/ppc64/kernel/Makefile --- 25/arch/ppc64/kernel/Makefile~ppc64-procfs-cleanup 2004-03-14 15:35:15.154634728 -0800 +++ 25-akpm/arch/ppc64/kernel/Makefile 2004-03-14 15:35:15.189629408 -0800 @@ -9,7 +9,7 @@ obj-y := setup.o entry.o t time.o process.o signal.o syscalls.o misc.o ptrace.o \ align.o semaphore.o bitops.o stab.o pacaData.o \ udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ - ptrace32.o signal32.o pmc.o rtc.o init_task.o \ + ptrace32.o signal32.o rtc.o init_task.o \ lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ iommu.o @@ -29,7 +29,7 @@ obj-$(CONFIG_PPC_ISERIES) += iSeries_irq HvCall.o HvLpConfig.o LparData.o mf_proc.o \ iSeries_setup.o ItLpQueue.o hvCall.o \ mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ - proc_pmc.o iSeries_iommu.o + iSeries_iommu.o obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ eeh.o nvram.o pSeries_nvram.o rtasd.o ras.o \ diff -puN arch/ppc64/kernel/iSeries_proc.c~ppc64-procfs-cleanup arch/ppc64/kernel/iSeries_proc.c --- 25/arch/ppc64/kernel/iSeries_proc.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.156634424 -0800 +++ 25-akpm/arch/ppc64/kernel/iSeries_proc.c 2004-03-14 15:35:15.191629104 -0800 @@ -1,133 +1,162 @@ /* - * iSeries_proc.c - * Copyright (C) 2001 Kyle A. Lucke IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include + * iSeries_proc.c + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -static struct proc_dir_entry *iSeries_proc_root; -static int iSeries_proc_initializationDone; -static spinlock_t iSeries_proc_lock; - -struct iSeries_proc_registration { - struct iSeries_proc_registration *next; - iSeriesProcFunction functionMember; +static int __init iseries_proc_create(void) +{ + struct proc_dir_entry *e = proc_mkdir("iSeries", 0); + if (!e) + return 1; + + return 0; +} +core_initcall(iseries_proc_create); + +static char *event_types[9] = { + "Hypervisor\t\t", + "Machine Facilities\t", + "Session Manager\t", + "SPD I/O\t\t", + "Virtual Bus\t\t", + "PCI I/O\t\t", + "RIO I/O\t\t", + "Virtual Lan\t\t", + "Virtual I/O\t\t" }; -struct iSeries_proc_registration preallocated[16]; +static int proc_lpevents_show(struct seq_file *m, void *v) +{ + unsigned int i; + + seq_printf(m, "LpEventQueue 0\n"); + seq_printf(m, " events processed:\t%lu\n", + (unsigned long)xItLpQueue.xLpIntCount); -#define MYQUEUETYPE(T) struct MYQueue##T -#define MYQUEUE(T) \ -MYQUEUETYPE(T) \ -{ \ - struct T *head; \ - struct T *tail; \ -} -#define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0) -#define MYQUEUEENQ(q, p) \ -do { \ - (p)->next = NULL; \ - if ((q)->head != NULL) { \ - (q)->head->next = (p); \ - (q)->head = (p); \ - } else { \ - (q)->tail = (q)->head = (p); \ - } \ -} while(0) - -#define MYQUEUEDEQ(q,p) \ -do { \ - (p) = (q)->tail; \ - if ((p) != NULL) { \ - (q)->tail = (p)->next; \ - (p)->next = NULL; \ - } \ - if ((q)->tail == NULL) \ - (q)->head = NULL; \ -} while(0) - -MYQUEUE(iSeries_proc_registration); -typedef MYQUEUETYPE(iSeries_proc_registration) aQueue; - -static aQueue iSeries_free; -static aQueue iSeries_queued; - -void iSeries_proc_early_init(void) -{ - int i = 0; - unsigned long flags; - - iSeries_proc_initializationDone = 0; - spin_lock_init(&iSeries_proc_lock); - MYQUEUECTOR(&iSeries_free); - MYQUEUECTOR(&iSeries_queued); - - spin_lock_irqsave(&iSeries_proc_lock, flags); - for (i = 0; i < 16; ++i) - MYQUEUEENQ(&iSeries_free, preallocated + i); - spin_unlock_irqrestore(&iSeries_proc_lock, flags); -} - -static int iSeries_proc_create(void) -{ - unsigned long flags; - struct iSeries_proc_registration *reg; - - printk("iSeries_proc: Creating /proc/iSeries\n"); - - spin_lock_irqsave(&iSeries_proc_lock, flags); - iSeries_proc_root = proc_mkdir("iSeries", 0); - if (!iSeries_proc_root) - goto out; - - MYQUEUEDEQ(&iSeries_queued, reg); - while (reg != NULL) { - (*(reg->functionMember))(iSeries_proc_root); - MYQUEUEDEQ(&iSeries_queued, reg); - } + for (i = 0; i < 9; ++i) + seq_printf(m, " %s %10lu\n", event_types[i], + (unsigned long)xItLpQueue.xLpIntCountByType[i]); + + seq_printf(m, "\n events processed by processor:\n"); + + for_each_online_cpu(i) + seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpEvent_count); - iSeries_proc_initializationDone = 1; -out: - spin_unlock_irqrestore(&iSeries_proc_lock, flags); return 0; } -arch_initcall(iSeries_proc_create); +static int proc_lpevents_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lpevents_show, NULL); +} + +static struct file_operations proc_lpevents_operations = { + .open = proc_lpevents_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; -void iSeries_proc_callback(iSeriesProcFunction initFunction) +static unsigned long startTitan = 0; +static unsigned long startTb = 0; + +static int proc_titantod_show(struct seq_file *m, void *v) { - unsigned long flags; + unsigned long tb0, titan_tod; + + tb0 = get_tb(); + titan_tod = HvCallXm_loadTod(); - spin_lock_irqsave(&iSeries_proc_lock, flags); - if (iSeries_proc_initializationDone) - (*initFunction)(iSeries_proc_root); - else { - struct iSeries_proc_registration *reg = NULL; - - MYQUEUEDEQ(&iSeries_free, reg); - if (reg != NULL) { - reg->functionMember = initFunction; - MYQUEUEENQ(&iSeries_queued, reg); - } else - printk("Couldn't get a queue entry\n"); + seq_printf(m, "Titan\n" ); + seq_printf(m, " time base = %016lx\n", tb0); + seq_printf(m, " titan tod = %016lx\n", titan_tod); + seq_printf(m, " xProcFreq = %016x\n", + xIoHriProcessorVpd[0].xProcFreq); + seq_printf(m, " xTimeBaseFreq = %016x\n", + xIoHriProcessorVpd[0].xTimeBaseFreq); + seq_printf(m, " tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy); + seq_printf(m, " tb_ticks_per_usec = %lu\n", tb_ticks_per_usec); + + if (!startTitan) { + startTitan = titan_tod; + startTb = tb0; + } else { + unsigned long titan_usec = (titan_tod - startTitan) >> 12; + unsigned long tb_ticks = (tb0 - startTb); + unsigned long titan_jiffies = titan_usec / (1000000/HZ); + unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ); + unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec; + unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy; + unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy; + unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks; + unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec; + unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec; + + seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec); + seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks); + seq_printf(m, " titan jiffies = %lu.%04lu \n", titan_jiffies, + titan_jiff_rem_usec); + seq_printf(m, " tb jiffies = %lu.%04lu\n", tb_jiffies, + tb_jiff_rem_usec); + seq_printf(m, " new tb_ticks_per_jiffy = %lu\n", + new_tb_ticks_per_jiffy); } - spin_unlock_irqrestore(&iSeries_proc_lock, flags); + + return 0; +} + +static int proc_titantod_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_titantod_show, NULL); +} + +static struct file_operations proc_titantod_operations = { + .open = proc_titantod_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init iseries_proc_init(void) +{ + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_lpevents_operations; + + e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_titantod_operations; + + return 0; } -EXPORT_SYMBOL(iSeries_proc_callback); +__initcall(iseries_proc_init); diff -puN arch/ppc64/kernel/iSeries_setup.c~ppc64-procfs-cleanup arch/ppc64/kernel/iSeries_setup.c --- 25/arch/ppc64/kernel/iSeries_setup.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.158634120 -0800 +++ 25-akpm/arch/ppc64/kernel/iSeries_setup.c 2004-03-14 15:35:15.192628952 -0800 @@ -51,7 +51,6 @@ #include #include #include -#include #include /* Function Prototypes */ @@ -393,12 +392,9 @@ void __init iSeries_init(unsigned long r iSeries_setup_dprofile(); - iSeries_proc_early_init(); mf_init(); mf_initialized = 1; mb(); - - iSeries_proc_callback(&pmc_proc_init); } /* diff -puN arch/ppc64/kernel/mf.c~ppc64-procfs-cleanup arch/ppc64/kernel/mf.c --- 25/arch/ppc64/kernel/mf.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.159633968 -0800 +++ 25-akpm/arch/ppc64/kernel/mf.c 2004-03-14 15:35:15.192628952 -0800 @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -683,8 +682,6 @@ void mf_init(void) /* initialization complete */ printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n"); - - iSeries_proc_callback(&mf_proc_init); } void mf_setSide(char side) diff -puN arch/ppc64/kernel/mf_proc.c~ppc64-procfs-cleanup arch/ppc64/kernel/mf_proc.c --- 25/arch/ppc64/kernel/mf_proc.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.161633664 -0800 +++ 25-akpm/arch/ppc64/kernel/mf_proc.c 2004-03-14 15:35:15.193628800 -0800 @@ -16,11 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include -static struct proc_dir_entry *mf_proc_root = NULL; - static int proc_mf_dump_cmdline(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -187,27 +186,28 @@ static int proc_mf_change_vmlinux(struct return count; } -void mf_proc_init(struct proc_dir_entry *iSeries_proc) +static int __init mf_proc_init(void) { + struct proc_dir_entry *mf_proc_root; struct proc_dir_entry *ent; struct proc_dir_entry *mf; char name[2]; int i; - mf_proc_root = proc_mkdir("mf", iSeries_proc); + mf_proc_root = proc_mkdir("iSeries/mf", NULL); if (!mf_proc_root) - return; + return 1; name[1] = '\0'; for (i = 0; i < 4; i++) { name[0] = 'A' + i; mf = proc_mkdir(name, mf_proc_root); if (!mf) - return; + return 1; ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf); if (!ent) - return; + return 1; ent->nlink = 1; ent->data = (void *)(long)i; ent->read_proc = proc_mf_dump_cmdline; @@ -218,7 +218,7 @@ void mf_proc_init(struct proc_dir_entry ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf); if (!ent) - return; + return 1; ent->nlink = 1; ent->data = (void *)(long)i; #if 0 @@ -239,7 +239,7 @@ void mf_proc_init(struct proc_dir_entry ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); if (!ent) - return; + return 1; ent->nlink = 1; ent->data = (void *)0; ent->read_proc = proc_mf_dump_side; @@ -247,9 +247,13 @@ void mf_proc_init(struct proc_dir_entry ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); if (!ent) - return; + return 1; ent->nlink = 1; ent->data = (void *)0; ent->read_proc = proc_mf_dump_src; ent->write_proc = proc_mf_change_src; + + return 0; } + +__initcall(mf_proc_init); diff -puN arch/ppc64/kernel/pmc.c~ppc64-procfs-cleanup arch/ppc64/kernel/pmc.c --- 25/arch/ppc64/kernel/pmc.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.162633512 -0800 +++ 25-akpm/arch/ppc64/kernel/pmc.c 2004-03-14 15:35:15.194628648 -0800 @@ -1,167 +0,0 @@ -/* - * pmc.c - * Copyright (C) 2001 Dave Engebretsen & Mike Corrigan IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Change Activity: - * 2001/06/05 : engebret : Created. - * End Change Activity - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -struct _pmc_sw pmc_sw_system = { - 0 -}; - -struct _pmc_sw pmc_sw_cpu[NR_CPUS] = { - {0 }, -}; - -/* - * Provide enough storage for either system level counters or - * one cpu's counters. - */ -struct _pmc_sw_text pmc_sw_text; -struct _pmc_hw_text pmc_hw_text; - -char * -ppc64_pmc_stab(int file) -{ - int n; - unsigned long stab_faults, stab_capacity_castouts, stab_invalidations; - unsigned long i; - - stab_faults = stab_capacity_castouts = stab_invalidations = n = 0; - - if (file == -1) { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; - stab_faults += pmc_sw_cpu[i].stab_faults; - stab_capacity_castouts += pmc_sw_cpu[i].stab_capacity_castouts; - stab_invalidations += pmc_sw_cpu[i].stab_invalidations; - } - n += sprintf(pmc_sw_text.buffer + n, - "Faults 0x%lx\n", stab_faults); - n += sprintf(pmc_sw_text.buffer + n, - "Castouts 0x%lx\n", stab_capacity_castouts); - n += sprintf(pmc_sw_text.buffer + n, - "Invalidations 0x%lx\n", stab_invalidations); - } else { - n += sprintf(pmc_sw_text.buffer + n, - "Faults 0x%lx\n", - pmc_sw_cpu[file].stab_faults); - - n += sprintf(pmc_sw_text.buffer + n, - "Castouts 0x%lx\n", - pmc_sw_cpu[file].stab_capacity_castouts); - - n += sprintf(pmc_sw_text.buffer + n, - "Invalidations 0x%lx\n", - pmc_sw_cpu[file].stab_invalidations); - - for (i = 0; i < STAB_ENTRY_MAX; i++) { - if (pmc_sw_cpu[file].stab_entry_use[i]) { - n += sprintf(pmc_sw_text.buffer + n, - "Entry %02ld 0x%lx\n", i, - pmc_sw_cpu[file].stab_entry_use[i]); - } - } - - } - - return(pmc_sw_text.buffer); -} - -char * -ppc64_pmc_htab(int file) -{ - int n; - unsigned long htab_primary_overflows, htab_capacity_castouts; - unsigned long htab_read_to_write_faults; - - htab_primary_overflows = htab_capacity_castouts = 0; - htab_read_to_write_faults = n = 0; - - if (file == -1) { - n += sprintf(pmc_sw_text.buffer + n, - "Primary Overflows 0x%lx\n", - pmc_sw_system.htab_primary_overflows); - n += sprintf(pmc_sw_text.buffer + n, - "Castouts 0x%lx\n", - pmc_sw_system.htab_capacity_castouts); - } else { - n += sprintf(pmc_sw_text.buffer + n, - "Primary Overflows N/A\n"); - - n += sprintf(pmc_sw_text.buffer + n, - "Castouts N/A\n\n"); - - } - - return(pmc_sw_text.buffer); -} - -char * -ppc64_pmc_hw(int file) -{ - int n; - - n = 0; - if (file == -1) { - n += sprintf(pmc_hw_text.buffer + n, "Not Implemented\n"); - } else { - n += sprintf(pmc_hw_text.buffer + n, - "MMCR0 0x%lx\n", mfspr(MMCR0)); - n += sprintf(pmc_hw_text.buffer + n, - "MMCR1 0x%lx\n", mfspr(MMCR1)); -#if 0 - n += sprintf(pmc_hw_text.buffer + n, - "MMCRA 0x%lx\n", mfspr(MMCRA)); -#endif - - n += sprintf(pmc_hw_text.buffer + n, - "PMC1 0x%lx\n", mfspr(PMC1)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC2 0x%lx\n", mfspr(PMC2)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC3 0x%lx\n", mfspr(PMC3)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC4 0x%lx\n", mfspr(PMC4)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC5 0x%lx\n", mfspr(PMC5)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC6 0x%lx\n", mfspr(PMC6)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC7 0x%lx\n", mfspr(PMC7)); - n += sprintf(pmc_hw_text.buffer + n, - "PMC8 0x%lx\n", mfspr(PMC8)); - } - - return(pmc_hw_text.buffer); -} diff -puN arch/ppc64/kernel/ppc_ksyms.c~ppc64-procfs-cleanup arch/ppc64/kernel/ppc_ksyms.c --- 25/arch/ppc64/kernel/ppc_ksyms.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.163633360 -0800 +++ 25-akpm/arch/ppc64/kernel/ppc_ksyms.c 2004-03-14 15:35:15.194628648 -0800 @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_PPC_ISERIES #include #endif @@ -164,6 +163,5 @@ EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(tb_ticks_per_usec); EXPORT_SYMBOL(paca); -EXPORT_SYMBOL(proc_ppc64); EXPORT_SYMBOL(cur_cpu_spec); EXPORT_SYMBOL(systemcfg); diff -puN arch/ppc64/kernel/proc_pmc.c~ppc64-procfs-cleanup arch/ppc64/kernel/proc_pmc.c --- 25/arch/ppc64/kernel/proc_pmc.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.165633056 -0800 +++ 25-akpm/arch/ppc64/kernel/proc_pmc.c 2004-03-14 15:35:15.198628040 -0800 @@ -1,810 +0,0 @@ -/* - * proc_pmc.c - * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -/* Change Activity: - * 2001 : mikec : Created - * 2001/06/05 : engebret : Software event count support. - * End Change Activity - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int proc_pmc_control_mode = 0; - -static struct proc_dir_entry *proc_ppc64_pmc_system_root = NULL; -static struct proc_dir_entry *proc_ppc64_pmc_cpu_root[NR_CPUS] = {NULL, }; - -static spinlock_t proc_ppc64_lock; -int proc_ppc64_pmc_find_file(void *data); -int proc_ppc64_pmc_read(char *page, char **start, off_t off, - int count, int *eof, char *buffer); -int proc_ppc64_pmc_stab_read(char *page, char **start, off_t off, - int count, int *eof, void *data); -int proc_ppc64_pmc_htab_read(char *page, char **start, off_t off, - int count, int *eof, void *data); -int proc_ppc64_pmc_hw_read(char *page, char **start, off_t off, - int count, int *eof, void *data); - -static struct proc_dir_entry *pmc_proc_root = NULL; - -int proc_get_lpevents( char *page, char **start, off_t off, int count, int *eof, void *data); -int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data); - -int proc_get_titanTod( char *page, char **start, off_t off, int count, int *eof, void *data); - -int proc_pmc_get_control( char *page, char **start, off_t off, int count, int *eof, void *data); - -int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data); -int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data); - -#if 0 -int proc_ppc64_init(void) -{ - unsigned long i; - struct proc_dir_entry *ent = NULL; - char buf[256]; - - printk("proc_ppc64: Creating /proc/ppc64/pmc\n"); - - /* - * Create the root, system, and cpu directories as follows: - * /proc/ppc64/pmc/system - * /proc/ppc64/pmc/cpu0 - */ - spin_lock(&proc_ppc64_lock); - if (proc_ppc64.root == NULL) { - proc_ppc64_init(); - if (!proc_ppc64.root) { - spin_unlock(&proc_ppc64_lock); - return; - } - } - spin_unlock(&proc_ppc64_lock); - - /* Placeholder for rtas interfaces. */ - if (proc_ppc64.rtas == NULL) { - return; - } - - proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64.root); - - proc_ppc64_pmc_system_root = proc_mkdir("system", proc_ppc64_pmc_root); - for (i = 0; i < NR_CPUS; i++) { - if (cpu_online(i)) { - sprintf(buf, "cpu%ld", i); - proc_ppc64_pmc_cpu_root[i] = - proc_mkdir(buf, proc_ppc64_pmc_root); - } - } - - /* Create directories for the software counters. */ - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; - ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_cpu_root[i]); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; - ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = NULL; - } - - ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_cpu_root[i]); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; - ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = NULL; - } - } - - ent = create_proc_entry("stab", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_system_root); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_system_root; - ent->read_proc = (void *)proc_ppc64_pmc_stab_read; - ent->write_proc = NULL; - } - - ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_system_root); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_system_root; - ent->read_proc = (void *)proc_ppc64_pmc_htab_read; - ent->write_proc = NULL; - } - - /* Create directories for the hardware counters. */ - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; - ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_cpu_root[i]); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_cpu_root[i]; - ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = NULL; - } - } - - ent = create_proc_entry("hardware", S_IRUGO | S_IWUSR, - proc_ppc64_pmc_system_root); - if (ent) { - ent->nlink = 1; - ent->data = (void *)proc_ppc64_pmc_system_root; - ent->read_proc = (void *)proc_ppc64_pmc_hw_read; - ent->write_proc = NULL; - } -} -#endif - -/* - * Find the requested 'file' given a proc token. - * - * Inputs: void * data: proc token - * Output: int : (0, ..., +N) = CPU number. - * -1 = System. - */ -int proc_ppc64_pmc_find_file(void *data) -{ - int i; - - if ((unsigned long)data == - (unsigned long) proc_ppc64_pmc_system_root) { - return(-1); - } else { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; - if ((unsigned long)data == - (unsigned long)proc_ppc64_pmc_cpu_root[i]) { - return(i); - } - } - } - - /* On error, just default to a type of system. */ - printk("proc_ppc64_pmc_find_file: failed to find file token.\n"); - return(-1); -} - -int -proc_ppc64_pmc_read(char *page, char **start, off_t off, - int count, int *eof, char *buffer) -{ - int buffer_size, n; - - if (count < 0) return 0; - - if (buffer == NULL) { - *eof = 1; - return 0; - } - - /* Check for read beyond EOF */ - buffer_size = n = strlen(buffer); - if (off >= buffer_size) { - *eof = 1; - return 0; - } - if (n > (buffer_size - off)) n = buffer_size - off; - - /* Never return more than was requested */ - if (n > count) { - n = count; - } else { - *eof = 1; - } - - memcpy(page, buffer + off, n); - - *start = page; - - return n; -} - -int -proc_ppc64_pmc_stab_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int n, file; - char *buffer = NULL; - - if (count < 0) return 0; - spin_lock(&proc_ppc64_lock); - - /* Figure out which file is being request. */ - file = proc_ppc64_pmc_find_file(data); - - /* Update the counters and the text buffer representation. */ - buffer = ppc64_pmc_stab(file); - - /* Put the data into the requestor's buffer. */ - n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer); - - spin_unlock(&proc_ppc64_lock); - return n; -} - -int -proc_ppc64_pmc_htab_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int n, file; - char *buffer = NULL; - - if (count < 0) return 0; - spin_lock(&proc_ppc64_lock); - - /* Figure out which file is being request. */ - file = proc_ppc64_pmc_find_file(data); - - /* Update the counters and the text buffer representation. */ - buffer = ppc64_pmc_htab(file); - - /* Put the data into the requestor's buffer. */ - n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer); - - spin_unlock(&proc_ppc64_lock); - return n; -} - -int -proc_ppc64_pmc_hw_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int n, file; - char *buffer = NULL; - - if (count < 0) return 0; - spin_lock(&proc_ppc64_lock); - - /* Figure out which file is being request. */ - file = proc_ppc64_pmc_find_file(data); - - /* Update the counters and the text buffer representation. */ - buffer = ppc64_pmc_hw(file); - - /* Put the data into the requestor's buffer. */ - n = proc_ppc64_pmc_read(page, start, off, count, eof, buffer); - - spin_unlock(&proc_ppc64_lock); - return n; -} - -/* - * DRENG the remainder of these functions still need work ... - */ -void pmc_proc_init(struct proc_dir_entry *iSeries_proc) -{ - struct proc_dir_entry *ent = NULL; - - ent = create_proc_entry("lpevents", S_IFREG|S_IRUGO, iSeries_proc); - if (!ent) return; - ent->nlink = 1; - ent->data = (void *)0; - ent->read_proc = proc_get_lpevents; - ent->write_proc = proc_reset_lpevents; - - ent = create_proc_entry("titanTod", S_IFREG|S_IRUGO, iSeries_proc); - if (!ent) return; - ent->nlink = 1; - ent->data = (void *)0; - ent->size = 0; - ent->read_proc = proc_get_titanTod; - ent->write_proc = NULL; - - pmc_proc_root = proc_mkdir("pmc", iSeries_proc); - if (!pmc_proc_root) return; - - ent = create_proc_entry("control", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); - if (!ent) return; - ent->nlink = 1; - ent->data = (void *)0; - ent->read_proc = proc_pmc_get_control; - ent->write_proc = proc_pmc_set_control; - -} - -static int pmc_calc_metrics( char *page, char **start, off_t off, int count, int *eof, int len) -{ - if ( len <= off+count) - *eof = 1; - *start = page+off; - len -= off; - if ( len > count ) - len = count; - if ( len < 0 ) - len = 0; - return len; -} - -static char * lpEventTypes[9] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" - }; - - -int proc_get_lpevents -(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - unsigned i; - int len = 0; - - len += sprintf( page+len, "LpEventQueue 0\n" ); - len += sprintf( page+len, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount ); - for (i=0; i<9; ++i) { - len += sprintf( page+len, " %s %10lu\n", - lpEventTypes[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i] ); - } - len += sprintf( page+len, "\n events processed by processor:\n" ); - for (i = 0; i < NR_CPUS; ++i) { - if (cpu_online(i)) - len += sprintf( page+len, " CPU%02d %10u\n", - i, paca[i].lpEvent_count ); - } - - return pmc_calc_metrics( page, start, off, count, eof, len ); - -} - -int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - return count; -} - -static unsigned long startTitan = 0; -static unsigned long startTb = 0; - - -int proc_get_titanTod -(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - int len = 0; - unsigned long tb0, titan_tod; - - tb0 = get_tb(); - titan_tod = HvCallXm_loadTod(); - - len += sprintf( page+len, "Titan\n" ); - len += sprintf( page+len, " time base = %016lx\n", tb0 ); - len += sprintf( page+len, " titan tod = %016lx\n", titan_tod ); - len += sprintf( page+len, " xProcFreq = %016x\n", xIoHriProcessorVpd[0].xProcFreq ); - len += sprintf( page+len, " xTimeBaseFreq = %016x\n", xIoHriProcessorVpd[0].xTimeBaseFreq ); - len += sprintf( page+len, " tb_ticks_per_jiffy = %lu\n", tb_ticks_per_jiffy ); - len += sprintf( page+len, " tb_ticks_per_usec = %lu\n", tb_ticks_per_usec ); - - if ( !startTitan ) { - startTitan = titan_tod; - startTb = tb0; - } - else { - unsigned long titan_usec = (titan_tod - startTitan) >> 12; - unsigned long tb_ticks = (tb0 - startTb); - unsigned long titan_jiffies = titan_usec / (1000000/HZ); - unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ); - unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec; - unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy; - unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy; - unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks; - unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec; - unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec; - - len += sprintf( page+len, " titan elapsed = %lu uSec\n", titan_usec); - len += sprintf( page+len, " tb elapsed = %lu ticks\n", tb_ticks); - len += sprintf( page+len, " titan jiffies = %lu.%04lu \n", titan_jiffies, titan_jiff_rem_usec ); - len += sprintf( page+len, " tb jiffies = %lu.%04lu\n", tb_jiffies, tb_jiff_rem_usec ); - len += sprintf( page+len, " new tb_ticks_per_jiffy = %lu\n", new_tb_ticks_per_jiffy ); - - } - - return pmc_calc_metrics( page, start, off, count, eof, len ); -} - -int proc_pmc_get_control -(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - int len = 0; - - if ( proc_pmc_control_mode == PMC_CONTROL_CPI ) { - unsigned long mach_cycles = mfspr( PMC5 ); - unsigned long inst_complete = mfspr( PMC4 ); - unsigned long inst_dispatch = mfspr( PMC3 ); - unsigned long thread_active_run = mfspr( PMC1 ); - unsigned long thread_active = mfspr( PMC2 ); - unsigned long cpi = 0; - unsigned long cpithou = 0; - unsigned long remain; - - if ( inst_complete ) { - cpi = thread_active_run / inst_complete; - remain = thread_active_run % inst_complete; - if ( inst_complete > 1000000 ) - cpithou = remain / ( inst_complete / 1000 ); - else - cpithou = ( remain * 1000 ) / inst_complete; - } - len += sprintf( page+len, "PMC CPI Mode\nRaw Counts\n" ); - len += sprintf( page+len, "machine cycles : %12lu\n", mach_cycles ); - len += sprintf( page+len, "thread active cycles : %12lu\n\n", thread_active ); - - len += sprintf( page+len, "instructions completed : %12lu\n", inst_complete ); - len += sprintf( page+len, "instructions dispatched : %12lu\n", inst_dispatch ); - len += sprintf( page+len, "thread active run cycles : %12lu\n", thread_active_run ); - - len += sprintf( page+len, "thread active run cycles/instructions completed\n" ); - len += sprintf( page+len, "CPI = %lu.%03lu\n", cpi, cpithou ); - - } - else if ( proc_pmc_control_mode == PMC_CONTROL_TLB ) { - len += sprintf( page+len, "PMC TLB Mode\n" ); - len += sprintf( page+len, "I-miss count : %12lu\n", mfspr( PMC1 ) ); - len += sprintf( page+len, "I-miss latency : %12lu\n", mfspr( PMC2 ) ); - len += sprintf( page+len, "D-miss count : %12lu\n", mfspr( PMC3 ) ); - len += sprintf( page+len, "D-miss latency : %12lu\n", mfspr( PMC4 ) ); - len += sprintf( page+len, "IERAT miss count : %12lu\n", mfspr( PMC5 ) ); - len += sprintf( page+len, "D-reference count : %12lu\n", mfspr( PMC6 ) ); - len += sprintf( page+len, "miss PTEs searched : %12lu\n", mfspr( PMC7 ) ); - len += sprintf( page+len, "miss >8 PTEs searched : %12lu\n", mfspr( PMC8 ) ); - } - /* IMPLEMENT ME */ - return pmc_calc_metrics( page, start, off, count, eof, len ); -} - -unsigned long proc_pmc_conv_int( const char *buf, unsigned count ) -{ - const char * p; - char b0, b1; - unsigned v, multiplier, mult, i; - unsigned long val; - multiplier = 10; - p = buf; - if ( count >= 3 ) { - b0 = buf[0]; - b1 = buf[1]; - if ( ( b0 == '0' ) && - ( ( b1 == 'x' ) || ( b1 == 'X' ) ) ) { - p = buf + 2; - count -= 2; - multiplier = 16; - } - - } - val = 0; - for ( i=0; i= '0' ) && ( b0 <= '9' ) ) - v = b0 - '0'; - else if ( multiplier == 16 ) { - if ( ( b0 >= 'a' ) && ( b0 <= 'f' ) ) - v = b0 - 'a' + 10; - else if ( ( b0 >= 'A' ) && ( b0 <= 'F' ) ) - v = b0 - 'A' + 10; - else - mult = 1; - } - else - mult = 1; - val *= mult; - val += v; - } - - return val; - -} - -static inline void proc_pmc_stop(void) -{ - /* Freeze all counters, leave everything else alone */ - mtspr( MMCR0, mfspr( MMCR0 ) | 0x80000000 ); -} - -static inline void proc_pmc_start(void) -{ - /* Unfreeze all counters, leave everything else alone */ - mtspr( MMCR0, mfspr( MMCR0 ) & ~0x80000000 ); - -} - -static inline void proc_pmc_reset(void) -{ - /* Clear all the PMCs to zeros - * Assume a "stop" has already frozen the counters - * Clear all the PMCs - */ - mtspr( PMC1, 0 ); - mtspr( PMC2, 0 ); - mtspr( PMC3, 0 ); - mtspr( PMC4, 0 ); - mtspr( PMC5, 0 ); - mtspr( PMC6, 0 ); - mtspr( PMC7, 0 ); - mtspr( PMC8, 0 ); - -} - -static inline void proc_pmc_cpi(void) -{ - /* Configure the PMC registers to count cycles and instructions */ - /* so we can compute cpi */ - /* - * MMCRA[30] = 1 Don't count in wait state (CTRL[31]=0) - * MMCR0[6] = 1 Freeze counters when any overflow - * MMCR0[19:25] = 0x01 PMC1 counts Thread Active Run Cycles - * MMCR0[26:31] = 0x05 PMC2 counts Thread Active Cycles - * MMCR1[0:4] = 0x07 PMC3 counts Instructions Dispatched - * MMCR1[5:9] = 0x03 PMC4 counts Instructions Completed - * MMCR1[10:14] = 0x06 PMC5 counts Machine Cycles - * - */ - - proc_pmc_control_mode = PMC_CONTROL_CPI; - - /* Indicate to hypervisor that we are using the PMCs */ - get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; - - /* Freeze all counters */ - mtspr( MMCR0, 0x80000000 ); - mtspr( MMCR1, 0x00000000 ); - - /* Clear all the PMCs */ - mtspr( PMC1, 0 ); - mtspr( PMC2, 0 ); - mtspr( PMC3, 0 ); - mtspr( PMC4, 0 ); - mtspr( PMC5, 0 ); - mtspr( PMC6, 0 ); - mtspr( PMC7, 0 ); - mtspr( PMC8, 0 ); - - /* Freeze counters in Wait State (CTRL[31]=0) */ - mtspr( MMCRA, 0x00000002 ); - - /* PMC3<-0x07, PMC4<-0x03, PMC5<-0x06 */ - mtspr( MMCR1, 0x38cc0000 ); - - mb(); - - /* PMC1<-0x01, PMC2<-0x05 - * Start all counters - */ - mtspr( MMCR0, 0x02000045 ); - -} - -static inline void proc_pmc_tlb(void) -{ - /* Configure the PMC registers to count tlb misses */ - /* - * MMCR0[6] = 1 Freeze counters when any overflow - * MMCR0[19:25] = 0x55 Group count - * PMC1 counts I misses - * PMC2 counts I miss duration (latency) - * PMC3 counts D misses - * PMC4 counts D miss duration (latency) - * PMC5 counts IERAT misses - * PMC6 counts D references (including PMC7) - * PMC7 counts miss PTEs searched - * PMC8 counts miss >8 PTEs searched - * - */ - - proc_pmc_control_mode = PMC_CONTROL_TLB; - - /* Indicate to hypervisor that we are using the PMCs */ - get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; - - /* Freeze all counters */ - mtspr( MMCR0, 0x80000000 ); - mtspr( MMCR1, 0x00000000 ); - - /* Clear all the PMCs */ - mtspr( PMC1, 0 ); - mtspr( PMC2, 0 ); - mtspr( PMC3, 0 ); - mtspr( PMC4, 0 ); - mtspr( PMC5, 0 ); - mtspr( PMC6, 0 ); - mtspr( PMC7, 0 ); - mtspr( PMC8, 0 ); - - mtspr( MMCRA, 0x00000000 ); - - mb(); - - /* PMC1<-0x55 - * Start all counters - */ - mtspr( MMCR0, 0x02001540 ); - -} - -int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - char stkbuf[10]; - if (count > 9) count = 9; - if (copy_from_user (stkbuf, buffer, count)) { - return -EFAULT; - } - stkbuf[count] = 0; - - if ( ! strncmp( stkbuf, "stop", 4 ) ) - proc_pmc_stop(); - else if ( ! strncmp( stkbuf, "start", 5 ) ) - proc_pmc_start(); - else if ( ! strncmp( stkbuf, "reset", 5 ) ) - proc_pmc_reset(); - else if ( ! strncmp( stkbuf, "cpi", 3 ) ) - proc_pmc_cpi(); - else if ( ! strncmp( stkbuf, "tlb", 3 ) ) - proc_pmc_tlb(); - - /* IMPLEMENT ME */ - return count; -} - -int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - v = v & ~0x04000000; /* Don't allow interrupts for now */ - if ( v & ~0x80000000 ) /* Inform hypervisor we are using PMCs */ - get_paca()->xLpPacaPtr->xPMCRegsInUse = 1; - else - get_paca()->xLpPacaPtr->xPMCRegsInUse = 0; - mtspr( MMCR0, v ); - - return count; -} - -int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( MMCR1, v ); - - return count; -} - -int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - v = v & ~0x00008000; /* Don't allow interrupts for now */ - mtspr( MMCRA, v ); - - return count; -} - - -int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC1, v ); - - return count; -} - -int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC2, v ); - - return count; -} - -int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC3, v ); - - return count; -} - -int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC4, v ); - - return count; -} - -int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC5, v ); - - return count; -} - -int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC6, v ); - - return count; -} - -int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC7, v ); - - return count; -} - -int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data ) -{ - unsigned long v; - v = proc_pmc_conv_int( buffer, count ); - mtspr( PMC8, v ); - - return count; -} - diff -puN arch/ppc64/kernel/proc_ppc64.c~ppc64-procfs-cleanup arch/ppc64/kernel/proc_ppc64.c --- 25/arch/ppc64/kernel/proc_ppc64.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.166632904 -0800 +++ 25-akpm/arch/ppc64/kernel/proc_ppc64.c 2004-03-14 15:35:15.199627888 -0800 @@ -18,15 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - * Change Activity: - * 2001 : mikec : Created - * 2001/06/05 : engebret : Software event count support. - * 2003/02/13 : bergner : Move PMC code to pmc.c - * End Change Activity - */ - #include #include #include @@ -34,7 +25,6 @@ #include #include -#include #include #include #include @@ -42,10 +32,6 @@ #include #include -struct proc_ppc64_t proc_ppc64; - -void proc_ppc64_create_paca(int num); - static loff_t page_map_seek( struct file *file, loff_t off, int whence); static ssize_t page_map_read( struct file *file, char *buf, size_t nbytes, loff_t *ppos); static int page_map_mmap( struct file *file, struct vm_area_struct *vma ); @@ -59,7 +45,7 @@ static struct file_operations page_map_f #ifdef CONFIG_PPC_PSERIES /* routines for /proc/ppc64/ofdt */ static ssize_t ofdt_write(struct file *, const char __user *, size_t, loff_t *); -static void proc_ppc64_create_ofdt(struct proc_dir_entry *); +static void proc_ppc64_create_ofdt(void); static int do_remove_node(char *); static int do_add_node(char *, size_t); static void release_prop_list(const struct property *); @@ -70,77 +56,19 @@ static struct file_operations ofdt_fops }; #endif -int __init proc_ppc64_init(void) -{ - - - if (proc_ppc64.root == NULL) { - printk(KERN_INFO "proc_ppc64: Creating /proc/ppc64/\n"); - proc_ppc64.root = proc_mkdir("ppc64", 0); - if (!proc_ppc64.root) - return 0; - } else { - return 0; - } - - proc_ppc64.naca = create_proc_entry("naca", S_IRUSR, proc_ppc64.root); - if ( proc_ppc64.naca ) { - proc_ppc64.naca->nlink = 1; - proc_ppc64.naca->data = naca; - proc_ppc64.naca->size = 4096; - proc_ppc64.naca->proc_fops = &page_map_fops; - } - - proc_ppc64.systemcfg = create_proc_entry("systemcfg", S_IFREG|S_IRUGO, proc_ppc64.root); - if ( proc_ppc64.systemcfg ) { - proc_ppc64.systemcfg->nlink = 1; - proc_ppc64.systemcfg->data = systemcfg; - proc_ppc64.systemcfg->size = 4096; - proc_ppc64.systemcfg->proc_fops = &page_map_fops; - } - - /* /proc/ppc64/paca/XX -- raw paca contents. Only readable to root */ - proc_ppc64.paca = proc_mkdir("paca", proc_ppc64.root); - if (proc_ppc64.paca) { - unsigned long i; - - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; - proc_ppc64_create_paca(i); - } - } - -#ifdef CONFIG_PPC_PSERIES - /* Placeholder for rtas interfaces. */ - if (proc_ppc64.rtas == NULL) - proc_ppc64.rtas = proc_mkdir("rtas", proc_ppc64.root); - - if (proc_ppc64.rtas) - proc_symlink("rtas", 0, "ppc64/rtas"); - - proc_ppc64_create_ofdt(proc_ppc64.root); -#endif - - return 0; -} - - /* - * NOTE: since paca data is always in flux the values will never be a consistant set. - * In theory it could be made consistent if we made the corresponding cpu - * copy the page for us (via an IPI). Probably not worth it. - * + * NOTE: since paca data is always in flux the values will never be a + * consistant set. */ -void proc_ppc64_create_paca(int num) +static void __init proc_create_paca(struct proc_dir_entry *dir, int num) { struct proc_dir_entry *ent; struct paca_struct *lpaca = paca + num; char buf[16]; sprintf(buf, "%02x", num); - ent = create_proc_entry(buf, S_IRUSR, proc_ppc64.paca); - if ( ent ) { + ent = create_proc_entry(buf, S_IRUSR, dir); + if (ent) { ent->nlink = 1; ent->data = lpaca; ent->size = 4096; @@ -148,6 +76,67 @@ void proc_ppc64_create_paca(int num) } } +/* + * Create the ppc64 and ppc64/rtas directories early. This allows us to + * assume that they have been previously created in drivers. + */ +static int __init proc_ppc64_create(void) +{ + struct proc_dir_entry *root; + + root = proc_mkdir("ppc64", 0); + if (!root) + return 1; + + if (!(systemcfg->platform & PLATFORM_PSERIES)) + return 0; + + if (!proc_mkdir("rtas", root)) + return 1; + + if (!proc_symlink("rtas", 0, "ppc64/rtas")) + return 1; + + return 0; +} +core_initcall(proc_ppc64_create); + +static int __init proc_ppc64_init(void) +{ + unsigned long i; + struct proc_dir_entry *pde; + + pde = create_proc_entry("ppc64/naca", S_IRUSR, NULL); + if (!pde) + return 1; + pde->nlink = 1; + pde->data = naca; + pde->size = 4096; + pde->proc_fops = &page_map_fops; + + pde = create_proc_entry("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL); + if (!pde) + return 1; + pde->nlink = 1; + pde->data = systemcfg; + pde->size = 4096; + pde->proc_fops = &page_map_fops; + + /* /proc/ppc64/paca/XX -- raw paca contents. Only readable to root */ + pde = proc_mkdir("ppc64/paca", NULL); + if (!pde) + return 1; + for_each_cpu(i) + proc_create_paca(pde, i); + +#ifdef CONFIG_PPC_PSERIES + if ((systemcfg->platform & PLATFORM_PSERIES)) + proc_ppc64_create_ofdt(); +#endif + + return 0; +} +__initcall(proc_ppc64_init); static loff_t page_map_seek( struct file *file, loff_t off, int whence) { @@ -204,11 +193,11 @@ static int page_map_mmap( struct file *f #ifdef CONFIG_PPC_PSERIES /* create /proc/ppc64/ofdt write-only by root */ -static void proc_ppc64_create_ofdt(struct proc_dir_entry *parent) +static void proc_ppc64_create_ofdt(void) { struct proc_dir_entry *ent; - ent = create_proc_entry("ofdt", S_IWUSR, parent); + ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); if (ent) { ent->nlink = 1; ent->data = NULL; @@ -423,5 +412,3 @@ static void release_prop_list(const stru } #endif /* defined(CONFIG_PPC_PSERIES) */ - -fs_initcall(proc_ppc64_init); diff -puN arch/ppc64/kernel/ras.c~ppc64-procfs-cleanup arch/ppc64/kernel/ras.c --- 25/arch/ppc64/kernel/ras.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.167632752 -0800 +++ 25-akpm/arch/ppc64/kernel/ras.c 2004-03-14 15:35:15.200627736 -0800 @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff -puN arch/ppc64/kernel/rtas-proc.c~ppc64-procfs-cleanup arch/ppc64/kernel/rtas-proc.c --- 25/arch/ppc64/kernel/rtas-proc.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.168632600 -0800 +++ 25-akpm/arch/ppc64/kernel/rtas-proc.c 2004-03-14 15:35:15.201627584 -0800 @@ -28,7 +28,6 @@ #include #include #include -#include #include /* for ppc_md */ #include @@ -117,8 +116,6 @@ /* Globals */ -extern struct proc_dir_entry *proc_rtas; - static struct rtas_sensors sensors; static struct device_node *rtas_node = NULL; static unsigned long power_on_time = 0; /* Save the time the user set */ @@ -201,51 +198,50 @@ int get_location_code(struct individual_ int check_location_string (char *c, char * buf); int check_location (char *c, int idx, char * buf); -/* ****************************************************************** */ -/* MAIN */ -/* ****************************************************************** */ -void proc_rtas_init(void) +static int __init proc_rtas_init(void) { struct proc_dir_entry *entry; - rtas_node = of_find_node_by_name(NULL, "rtas"); - if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) { - return; - } - - if (proc_ppc64.rtas == NULL) { - proc_ppc64_init(); - } - - if (proc_ppc64.rtas == NULL) { - printk(KERN_ERR "Failed to create /proc/rtas in proc_rtas_init\n"); - return; - } - - /* /proc/rtas entries */ - - entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_progress_operations; - - entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_clock_operations; - - entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + if (!(systemcfg->platform & PLATFORM_PSERIES)) + return 1; - create_proc_read_entry("sensors", S_IRUGO, proc_ppc64.rtas, - ppc_rtas_sensor_read, NULL); - - entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + rtas_node = of_find_node_by_name(NULL, "rtas"); + if (rtas_node == NULL) + return 1; - entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_progress_operations; + + entry = create_proc_entry("ppc64/rtas/clock", S_IRUGO|S_IWUSR, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_clock_operations; + + entry = create_proc_entry("ppc64/rtas/poweron", S_IWUSR|S_IRUGO, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_poweron_operations; + + create_proc_read_entry("ppc64/rtas/sensors", S_IRUGO, NULL, + ppc_rtas_sensor_read, NULL); + + entry = create_proc_entry("ppc64/rtas/frequency", S_IWUSR|S_IRUGO, + NULL); + if (entry) + entry->proc_fops = &ppc_rtas_tone_freq_operations; + + entry = create_proc_entry("ppc64/rtas/volume", S_IWUSR|S_IRUGO, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_tone_volume_operations; + + entry = create_proc_entry("ppc64/rtas/rmo_buffer", S_IRUSR, NULL); + if (entry) + entry->proc_fops = &ppc_rtas_rmo_buf_ops; - entry = create_proc_entry("rmo_buffer", S_IRUSR, proc_ppc64.rtas); - if (entry) entry->proc_fops = &ppc_rtas_rmo_buf_ops; + return 0; } +__initcall(proc_rtas_init); + /* ****************************************************************** */ /* POWER-ON-TIME */ /* ****************************************************************** */ diff -puN arch/ppc64/kernel/rtas.c~ppc64-procfs-cleanup arch/ppc64/kernel/rtas.c --- 25/arch/ppc64/kernel/rtas.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.170632296 -0800 +++ 25-akpm/arch/ppc64/kernel/rtas.c 2004-03-14 15:35:15.202627432 -0800 @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff -puN arch/ppc64/kernel/rtas_flash.c~ppc64-procfs-cleanup arch/ppc64/kernel/rtas_flash.c --- 25/arch/ppc64/kernel/rtas_flash.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.171632144 -0800 +++ 25-akpm/arch/ppc64/kernel/rtas_flash.c 2004-03-14 15:35:15.203627280 -0800 @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -106,10 +106,10 @@ struct rtas_validate_flash_t }; static spinlock_t flash_file_open_lock = SPIN_LOCK_UNLOCKED; -static struct proc_dir_entry *firmware_flash_pde = NULL; -static struct proc_dir_entry *firmware_update_pde = NULL; -static struct proc_dir_entry *validate_pde = NULL; -static struct proc_dir_entry *manage_pde = NULL; +static struct proc_dir_entry *firmware_flash_pde; +static struct proc_dir_entry *firmware_update_pde; +static struct proc_dir_entry *validate_pde; +static struct proc_dir_entry *manage_pde; /* Do simple sanity checks on the flash image. */ static int flash_list_valid(struct flash_block_list *flist) @@ -501,7 +501,7 @@ static ssize_t validate_flash_read(struc } static ssize_t validate_flash_write(struct file *file, const char *buf, - size_t count, loff_t *off) + size_t count, loff_t *off) { struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_validate_flash_t *args_buf; @@ -567,18 +567,18 @@ static int validate_flash_release(struct return 0; } -static inline void remove_flash_pde(struct proc_dir_entry *dp) +static void remove_flash_pde(struct proc_dir_entry *dp) { if (dp) { if (dp->data != NULL) kfree(dp->data); - remove_proc_entry(dp->name, proc_ppc64.rtas); + remove_proc_entry(dp->name, NULL); } } -static inline int initialize_flash_pde_data(const char *rtas_call_name, - size_t buf_size, - struct proc_dir_entry *dp) +static int initialize_flash_pde_data(const char *rtas_call_name, + size_t buf_size, + struct proc_dir_entry *dp) { int *status; int token; @@ -591,7 +591,8 @@ static inline int initialize_flash_pde_d memset(dp->data, 0, buf_size); - /* This code assumes that the status int is the first member of the + /* + * This code assumes that the status int is the first member of the * struct */ status = (int *) dp->data; @@ -604,12 +605,12 @@ static inline int initialize_flash_pde_d return 0; } -static inline struct proc_dir_entry * create_flash_pde(const char *filename, - struct file_operations *fops) +static struct proc_dir_entry *create_flash_pde(const char *filename, + struct file_operations *fops) { struct proc_dir_entry *ent = NULL; - ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, proc_ppc64.rtas); + ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, NULL); if (ent != NULL) { ent->nlink = 1; ent->proc_fops = fops; @@ -644,50 +645,79 @@ int __init rtas_flash_init(void) { int rc; - if (!proc_ppc64.rtas) { - printk(KERN_WARNING "rtas proc dir does not already exist"); - return -ENOENT; + if (rtas_token("ibm,update-flash-64-and-reboot") == + RTAS_UNKNOWN_SERVICE) { + printk(KERN_ERR "rtas_flash: no firmware flash support\n"); + return 1; } - firmware_flash_pde = create_flash_pde(FIRMWARE_FLASH_NAME, + firmware_flash_pde = create_flash_pde("ppc64/rtas/" + FIRMWARE_FLASH_NAME, &rtas_flash_operations); + if (firmware_flash_pde == NULL) { + rc = -ENOMEM; + goto cleanup; + } + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", sizeof(struct rtas_update_flash_t), firmware_flash_pde); if (rc != 0) - return rc; - - firmware_update_pde = create_flash_pde(FIRMWARE_UPDATE_NAME, + goto cleanup; + + firmware_update_pde = create_flash_pde("ppc64/rtas/" + FIRMWARE_UPDATE_NAME, &rtas_flash_operations); + if (firmware_update_pde == NULL) { + rc = -ENOMEM; + goto cleanup; + } + rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot", sizeof(struct rtas_update_flash_t), firmware_update_pde); if (rc != 0) - return rc; - - validate_pde = create_flash_pde(VALIDATE_FLASH_NAME, + goto cleanup; + + validate_pde = create_flash_pde("ppc64/rtas/" VALIDATE_FLASH_NAME, &validate_flash_operations); + if (validate_pde == NULL) { + rc = -ENOMEM; + goto cleanup; + } + rc = initialize_flash_pde_data("ibm,validate-flash-image", sizeof(struct rtas_validate_flash_t), validate_pde); if (rc != 0) - return rc; - - manage_pde = create_flash_pde(MANAGE_FLASH_NAME, + goto cleanup; + + manage_pde = create_flash_pde("ppc64/rtas" MANAGE_FLASH_NAME, &manage_flash_operations); + if (manage_pde == NULL) { + rc = -ENOMEM; + goto cleanup; + } + rc = initialize_flash_pde_data("ibm,manage-flash-image", sizeof(struct rtas_manage_flash_t), manage_pde); if (rc != 0) - return rc; - + goto cleanup; + return 0; + +cleanup: + remove_flash_pde(firmware_flash_pde); + remove_flash_pde(firmware_update_pde); + remove_flash_pde(validate_pde); + remove_flash_pde(manage_pde); + + return rc; } void __exit rtas_flash_cleanup(void) { - if (!proc_ppc64.rtas) - return; remove_flash_pde(firmware_flash_pde); remove_flash_pde(firmware_update_pde); remove_flash_pde(validate_pde); diff -puN arch/ppc64/kernel/rtasd.c~ppc64-procfs-cleanup arch/ppc64/kernel/rtasd.c --- 25/arch/ppc64/kernel/rtasd.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.172631992 -0800 +++ 25-akpm/arch/ppc64/kernel/rtasd.c 2004-03-14 15:35:15.204627128 -0800 @@ -26,7 +26,6 @@ #include #include #include -#include #if 0 #define DEBUG(A...) printk(KERN_ERR A) @@ -47,7 +46,6 @@ static unsigned int rtas_event_scan_rate static unsigned int rtas_error_log_max; static unsigned int rtas_error_log_buffer_max; -extern spinlock_t proc_ppc64_lock; extern volatile int no_more_logging; volatile int error_log_cnt = 0; @@ -445,20 +443,18 @@ static int __init rtas_init(void) { struct proc_dir_entry *entry; - if (proc_ppc64.rtas == NULL) { - proc_ppc64_init(); + /* No RTAS, only warn if we are on a pSeries box */ + if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { + if (systemcfg->platform & PLATFORM_PSERIES); + printk(KERN_ERR "rtasd: no RTAS on system\n"); + return 1; } - if (proc_ppc64.rtas == NULL) { - printk(KERN_ERR "rtas_init: /proc/ppc64/rtas does not exist."); - return -EIO; - } - - entry = create_proc_entry("error_log", S_IRUSR, proc_ppc64.rtas); + entry = create_proc_entry("ppc64/error_log", S_IRUSR, NULL); if (entry) entry->proc_fops = &proc_rtas_log_operations; else - printk(KERN_ERR "Failed to create rtas/error_log proc entry\n"); + printk(KERN_ERR "Failed to create error_log proc entry\n"); if (kernel_thread(rtasd, 0, CLONE_FS) < 0) printk(KERN_ERR "Failed to start RTAS daemon\n"); diff -puN arch/ppc64/kernel/scanlog.c~ppc64-procfs-cleanup arch/ppc64/kernel/scanlog.c --- 25/arch/ppc64/kernel/scanlog.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.174631688 -0800 +++ 25-akpm/arch/ppc64/kernel/scanlog.c 2004-03-14 15:35:15.204627128 -0800 @@ -28,7 +28,6 @@ #include #include #include -#include #define MODULE_VERS "1.0" #define MODULE_NAME "scanlog" @@ -212,16 +211,7 @@ int __init scanlog_init(void) return -EIO; } - if (proc_ppc64.rtas == NULL) { - proc_ppc64_init(); - } - - if (proc_ppc64.rtas == NULL) { - printk(KERN_ERR "Failed to create /proc/rtas in scanlog_init\n"); - return -EIO; - } - - ent = create_proc_entry("scan-log-dump", S_IRUSR, proc_ppc64.rtas); + ent = create_proc_entry("ppc64/rtas/scan-log-dump", S_IRUSR, NULL); if (ent) { ent->proc_fops = &scanlog_fops; /* Ideally we could allocate a buffer < 4G */ diff -puN arch/ppc64/kernel/viopath.c~ppc64-procfs-cleanup arch/ppc64/kernel/viopath.c --- 25/arch/ppc64/kernel/viopath.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.175631536 -0800 +++ 25-akpm/arch/ppc64/kernel/viopath.c 2004-03-14 15:35:15.206626824 -0800 @@ -28,7 +28,6 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include #include #include #include @@ -37,9 +36,10 @@ #include #include #include +#include -#include /* for is_atomic */ - +#include +#include #include #include #include @@ -184,21 +184,21 @@ static unsigned char e2a(unsigned char x return ' '; } -/* Handle reads from the proc file system - */ -static int proc_read(char *buf, char **start, off_t offset, - int blen, int *eof, void *data) +static int proc_viopath_show(struct seq_file *m, void *v) { + char *buf; + dma_addr_t handle; HvLpEvent_Rc hvrc; DECLARE_MUTEX_LOCKED(Semaphore); - dma_addr_t dmaa = - dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE, DMA_FROM_DEVICE); - int len = PAGE_SIZE; - if (len > blen) - len = blen; + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return 0; + memset(buf, 0, PAGE_SIZE); + + handle = dma_map_single(iSeries_vio_dev, buf, PAGE_SIZE, + DMA_FROM_DEVICE); - memset(buf, 0x00, len); hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, viomajorsubtype_config | vioconfigget, @@ -206,50 +206,54 @@ static int proc_read(char *buf, char **s viopath_sourceinst(viopath_hostLp), viopath_targetinst(viopath_hostLp), (u64)(unsigned long)&Semaphore, VIOVERSION << 16, - ((u64)dmaa) << 32, len, 0, 0); + ((u64)handle) << 32, PAGE_SIZE, 0, 0); + if (hvrc != HvLpEvent_Rc_Good) - printk("viopath hv error on op %d\n", (int) hvrc); + printk("viopath hv error on op %d\n", (int)hvrc); down(&Semaphore); - dma_unmap_single(iSeries_vio_dev, dmaa, PAGE_SIZE, DMA_FROM_DEVICE); + dma_unmap_single(iSeries_vio_dev, handle, PAGE_SIZE, DMA_FROM_DEVICE); + kfree(buf); + + buf[PAGE_SIZE] = '\0'; + seq_printf(m, "%s", buf); + + seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n", + e2a(xItExtVpdPanel.mfgID[2]), + e2a(xItExtVpdPanel.mfgID[3]), + e2a(xItExtVpdPanel.systemSerial[1]), + e2a(xItExtVpdPanel.systemSerial[2]), + e2a(xItExtVpdPanel.systemSerial[3]), + e2a(xItExtVpdPanel.systemSerial[4]), + e2a(xItExtVpdPanel.systemSerial[5])); - sprintf(buf + strlen(buf), "SRLNBR="); - buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[2]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[3]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[1]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[2]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[3]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[4]); - buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[5]); - buf[strlen(buf)] = '\n'; - *eof = 1; - return strlen(buf); + return 0; } -/* Handle writes to our proc file system - */ -static int proc_write(struct file *file, const char *buffer, - unsigned long count, void *data) +static int proc_viopath_open(struct inode *inode, struct file *file) { - /* Doesn't do anything today!!! - */ - return count; + return single_open(file, proc_viopath_show, NULL); } -/* setup our proc file system entries - */ -static void vio_proc_init(struct proc_dir_entry *iSeries_proc) +static struct file_operations proc_viopath_operations = { + .open = proc_viopath_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init vio_proc_init(void) { - struct proc_dir_entry *ent; - ent = create_proc_entry("config", S_IFREG | S_IRUSR, iSeries_proc); - if (!ent) - return; - ent->nlink = 1; - ent->data = NULL; - ent->read_proc = proc_read; - ent->write_proc = proc_write; + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/config", 0, NULL); + if (e) + e->proc_fops = &proc_viopath_operations; + + return 0; } +__initcall(vio_proc_init); /* See if a given LP is active. Allow for invalid lps to be passed in * and just return invalid @@ -433,13 +437,8 @@ void vio_set_hostlp(void) viopath_ourLp = HvLpConfig_getLpIndex(); viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp); - /* If we have a valid hosting LP, create a proc file system entry - * for config information - */ - if (viopath_hostLp != HvLpIndexInvalid) { - iSeries_proc_callback(&vio_proc_init); + if (viopath_hostLp != HvLpIndexInvalid) vio_setHandler(viomajorsubtype_config, handleConfig); - } } EXPORT_SYMBOL(vio_set_hostlp); diff -puN arch/ppc64/mm/hash_utils.c~ppc64-procfs-cleanup arch/ppc64/mm/hash_utils.c --- 25/arch/ppc64/mm/hash_utils.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.176631384 -0800 +++ 25-akpm/arch/ppc64/mm/hash_utils.c 2004-03-14 15:35:15.206626824 -0800 @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff -puN arch/ppc64/mm/init.c~ppc64-procfs-cleanup arch/ppc64/mm/init.c --- 25/arch/ppc64/mm/init.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.177631232 -0800 +++ 25-akpm/arch/ppc64/mm/init.c 2004-03-14 15:35:15.207626672 -0800 @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff -puN fs/proc/root.c~ppc64-procfs-cleanup fs/proc/root.c --- 25/fs/proc/root.c~ppc64-procfs-cleanup 2004-03-14 15:35:15.179630928 -0800 +++ 25-akpm/fs/proc/root.c 2004-03-14 15:35:15.207626672 -0800 @@ -74,9 +74,6 @@ void __init proc_root_init(void) #ifdef CONFIG_PROC_DEVICETREE proc_device_tree_init(); #endif -#ifdef CONFIG_PPC_RTAS - proc_rtas_init(); -#endif proc_bus = proc_mkdir("bus", 0); } diff -puN include/asm-ppc64/iSeries/iSeries_proc.h~ppc64-procfs-cleanup include/asm-ppc64/iSeries/iSeries_proc.h --- 25/include/asm-ppc64/iSeries/iSeries_proc.h~ppc64-procfs-cleanup 2004-03-14 15:35:15.180630776 -0800 +++ 25-akpm/include/asm-ppc64/iSeries/iSeries_proc.h 2004-03-14 15:35:15.207626672 -0800 @@ -19,12 +19,6 @@ #ifndef _ISERIES_PROC_H #define _ISERIES_PROC_H -#include - extern void iSeries_proc_early_init(void); -typedef void (*iSeriesProcFunction)(struct proc_dir_entry *iSeries_proc); - -extern void iSeries_proc_callback(iSeriesProcFunction initFunction); - #endif /* _iSeries_PROC_H */ diff -puN include/asm-ppc64/iSeries/mf.h~ppc64-procfs-cleanup include/asm-ppc64/iSeries/mf.h --- 25/include/asm-ppc64/iSeries/mf.h~ppc64-procfs-cleanup 2004-03-14 15:35:15.182630472 -0800 +++ 25-akpm/include/asm-ppc64/iSeries/mf.h 2004-03-14 15:35:15.208626520 -0800 @@ -67,6 +67,4 @@ extern int mf_getRtcTime(unsigned long * extern int mf_getRtc( struct rtc_time * tm ); extern int mf_setRtc( struct rtc_time * tm ); -extern void mf_proc_init(struct proc_dir_entry *iSeries_proc); - #endif /* MF_H_INCLUDED */ diff -puN include/asm-ppc64/pmc.h~ppc64-procfs-cleanup include/asm-ppc64/pmc.h --- 25/include/asm-ppc64/pmc.h~ppc64-procfs-cleanup 2004-03-14 15:35:15.184630168 -0800 +++ 25-akpm/include/asm-ppc64/pmc.h 2004-03-14 15:35:15.208626520 -0800 @@ -1,113 +0,0 @@ -/* - * pmc.h - * Copyright (C) 2001 Dave Engebretsen & Mike Corrigan IBM Corporation. - * - * The PPC64 PMC subsystem encompases both the hardware PMC registers and - * a set of software event counters. An interface is provided via the - * proc filesystem which can be used to access this subsystem. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Start Change Log - * 2001/06/05 : engebret : Created. - * End Change Log - */ - -#ifndef _PPC64_TYPES_H -#include -#endif - -#ifndef _PMC_H -#define _PMC_H - -#define STAB_ENTRY_MAX 64 - -struct _pmc_hw -{ - u64 mmcr0; - u64 mmcr1; - u64 mmcra; - - u64 pmc1; - u64 pmc2; - u64 pmc3; - u64 pmc4; - u64 pmc5; - u64 pmc6; - u64 pmc7; - u64 pmc8; -}; - -struct _pmc_sw -{ - u64 stab_faults; /* Count of faults on the stab */ - u64 stab_capacity_castouts;/* Count of castouts from the stab */ - u64 stab_invalidations; /* Count of invalidations from the */ - /* stab, not including castouts */ - u64 stab_entry_use[STAB_ENTRY_MAX]; - - u64 htab_primary_overflows; - u64 htab_capacity_castouts; - u64 htab_read_to_write_fault; -}; - -#define PMC_HW_TEXT_ENTRY_COUNT (sizeof(struct _pmc_hw) / sizeof(u64)) -#define PMC_SW_TEXT_ENTRY_COUNT (sizeof(struct _pmc_sw) / sizeof(u64)) -#define PMC_TEXT_ENTRY_SIZE 64 - -struct _pmc_sw_text { - char buffer[PMC_SW_TEXT_ENTRY_COUNT * PMC_TEXT_ENTRY_SIZE]; -}; - -struct _pmc_hw_text { - char buffer[PMC_HW_TEXT_ENTRY_COUNT * PMC_TEXT_ENTRY_SIZE]; -}; - -extern struct _pmc_sw pmc_sw_system; -extern struct _pmc_sw pmc_sw_cpu[]; - -extern struct _pmc_sw_text pmc_sw_text; -extern struct _pmc_hw_text pmc_hw_text; -extern char *ppc64_pmc_stab(int file); -extern char *ppc64_pmc_htab(int file); -extern char *ppc64_pmc_hw(int file); - -#if 1 -#define PMC_SW_PROCESSOR(F) pmc_sw_cpu[smp_processor_id()].F++ -#define PMC_SW_PROCESSOR_A(F, E) (pmc_sw_cpu[smp_processor_id()].F[(E)])++ -#define PMC_SW_SYSTEM(F) pmc_sw_system.F++ -#else -#define PMC_SW_PROCESSOR(F) do {;} while (0) -#define PMC_SW_PROCESSOR_A(F) do {;} while (0) -#define PMC_SW_SYSTEM(F) do {;} while (0) -#endif - -#define MMCR0 795 -#define MMCR1 798 -#define MMCRA 786 -#define PMC1 787 -#define PMC2 788 -#define PMC3 789 -#define PMC4 790 -#define PMC5 791 -#define PMC6 792 -#define PMC7 793 -#define PMC8 794 - -#define PMC_CONTROL_CPI 1 -#define PMC_CONTROL_TLB 2 - -#endif /* _PMC_H */ diff -puN include/asm-ppc64/proc_fs.h~ppc64-procfs-cleanup include/asm-ppc64/proc_fs.h --- 25/include/asm-ppc64/proc_fs.h~ppc64-procfs-cleanup 2004-03-14 15:35:15.185630016 -0800 +++ 25-akpm/include/asm-ppc64/proc_fs.h 2004-03-14 15:35:15.209626368 -0800 @@ -1,39 +0,0 @@ -#ifndef _PPC64_PROC_FS_H -#define _PPC64_PROC_FS_H -/* - * proc_fs.h - * Copyright (C) 2001 Mike Corrigan IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Change Activity: */ -/* tgall -- merge of iSeries/iSeries_proc.h and proc_pmc.h */ -/* End Change Activity */ - -#include - -struct proc_ppc64_t { - struct proc_dir_entry *root; - struct proc_dir_entry *naca; - struct proc_dir_entry *paca; - struct proc_dir_entry *systemcfg; - struct proc_dir_entry *rtas; -}; - -extern struct proc_ppc64_t proc_ppc64; -extern int proc_ppc64_init(void); - -#endif /* _PPC64_PROC_FS_H */ diff -puN include/asm-ppc64/proc_pmc.h~ppc64-procfs-cleanup include/asm-ppc64/proc_pmc.h --- 25/include/asm-ppc64/proc_pmc.h~ppc64-procfs-cleanup 2004-03-14 15:35:15.186629864 -0800 +++ 25-akpm/include/asm-ppc64/proc_pmc.h 2004-03-14 15:35:15.209626368 -0800 @@ -1,33 +0,0 @@ -/* - * pmc_proc.h - * Copyright (C) 2001 Mike Corrigan IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -/* Change Activity: */ -/* End Change Activity */ - -#ifndef _PMC_PROC_H -#define _PMC_PROC_H - -#include - -void pmc_proc_init(struct proc_dir_entry *iSeries_proc); -void proc_ppc64_init(void); - -#endif /* _PMC_PROC_H */ - _