Commit 30ffc51d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Cleanup ppc64 procfs code

From: Anton Blanchard <anton@samba.org>

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.
parent 7836b827
......@@ -20,6 +20,7 @@
#include <linux/ctype.h>
#include <linux/time.h>
#include <linux/string.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
......@@ -194,18 +195,18 @@ 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 = 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 */
......
......@@ -9,7 +9,7 @@ obj-y := setup.o entry.o traps.o irq.o idle.o dma.o \
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.o \
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 \
......
/*
* 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 <linux/proc_fs.h>
#include <linux/spinlock.h>
* 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 <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/paca.h>
#include <asm/processor.h>
#include <asm/time.h>
#include <asm/naca.h>
#include <asm/iSeries/ItLpPaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/IoHriMainStore.h>
#include <asm/iSeries/LparData.h>
#include <asm/iSeries/iSeries_proc.h>
static struct proc_dir_entry *iSeries_proc_root;
static int iSeries_proc_initializationDone;
static spinlock_t iSeries_proc_lock;
static int __init iseries_proc_create(void)
{
struct proc_dir_entry *e = proc_mkdir("iSeries", 0);
if (!e)
return 1;
struct iSeries_proc_registration {
struct iSeries_proc_registration *next;
iSeriesProcFunction functionMember;
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];
#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)
static int proc_lpevents_show(struct seq_file *m, void *v)
{
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);
unsigned int i;
seq_printf(m, "LpEventQueue 0\n");
seq_printf(m, " events processed:\t%lu\n",
(unsigned long)xItLpQueue.xLpIntCount);
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);
return 0;
}
static int iSeries_proc_create(void)
static int proc_lpevents_open(struct inode *inode, struct file *file)
{
unsigned long flags;
struct iSeries_proc_registration *reg;
return single_open(file, proc_lpevents_show, NULL);
}
printk("iSeries_proc: Creating /proc/iSeries\n");
static struct file_operations proc_lpevents_operations = {
.open = proc_lpevents_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
spin_lock_irqsave(&iSeries_proc_lock, flags);
iSeries_proc_root = proc_mkdir("iSeries", 0);
if (!iSeries_proc_root)
goto out;
static unsigned long startTitan = 0;
static unsigned long startTb = 0;
MYQUEUEDEQ(&iSeries_queued, reg);
while (reg != NULL) {
(*(reg->functionMember))(iSeries_proc_root);
MYQUEUEDEQ(&iSeries_queued, reg);
static int proc_titantod_show(struct seq_file *m, void *v)
{
unsigned long tb0, titan_tod;
tb0 = get_tb();
titan_tod = HvCallXm_loadTod();
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);
}
iSeries_proc_initializationDone = 1;
out:
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
return 0;
}
arch_initcall(iSeries_proc_create);
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,
};
void iSeries_proc_callback(iSeriesProcFunction initFunction)
static int __init iseries_proc_init(void)
{
unsigned long flags;
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");
}
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
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);
......@@ -51,7 +51,6 @@
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/IoHriMainStore.h>
#include <asm/iSeries/iSeries_proc.h>
#include <asm/proc_pmc.h>
#include <asm/iSeries/mf.h>
/* Function Prototypes */
......@@ -393,12 +392,9 @@ void __init iSeries_init(unsigned long r3, unsigned long r4, unsigned long r5,
iSeries_setup_dprofile();
iSeries_proc_early_init();
mf_init();
mf_initialized = 1;
mb();
iSeries_proc_callback(&pmc_proc_init);
}
/*
......
......@@ -37,7 +37,6 @@
#include <asm/nvram.h>
#include <asm/time.h>
#include <asm/iSeries/ItSpCommArea.h>
#include <asm/iSeries/iSeries_proc.h>
#include <asm/uaccess.h>
#include <linux/dma-mapping.h>
#include <linux/bcd.h>
......@@ -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)
......
......@@ -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 <linux/init.h>
#include <asm/uaccess.h>
#include <asm/iSeries/mf.h>
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 file *file, const char *buffer,
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 *iSeries_proc)
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 *iSeries_proc)
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 *iSeries_proc)
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);
/*
* 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 <asm/proc_fs.h>
#include <asm/paca.h>
#include <asm/iSeries/ItLpPaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/processor.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <asm/pmc.h>
#include <asm/uaccess.h>
#include <asm/naca.h>
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);
}
......@@ -40,7 +40,6 @@
#include <asm/hw_irq.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/proc_fs.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/HvCallSc.h>
#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);
This diff is collapsed.
......@@ -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 <linux/config.h>
#include <linux/init.h>
#include <linux/mm.h>
......@@ -34,7 +25,6 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <asm/proc_fs.h>
#include <asm/naca.h>
#include <asm/paca.h>
#include <asm/systemcfg.h>
......@@ -42,10 +32,6 @@
#include <asm/uaccess.h>
#include <asm/prom.h>
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_fops = {
#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 *file, struct vm_area_struct *vma )
#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 struct property *prop)
}
#endif /* defined(CONFIG_PPC_PSERIES) */
fs_initcall(proc_ppc64_init);
......@@ -36,7 +36,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/random.h>
#include <linux/sysrq.h>
......
......@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/proc_fs.h>
#include <asm/machdep.h> /* for ppc_md */
#include <asm/time.h>
......@@ -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_sensor s, char * buf);
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;
if (!(systemcfg->platform & PLATFORM_PSERIES))
return 1;
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 (rtas_node == NULL)
return 1;
if (proc_ppc64.rtas == NULL) {
printk(KERN_ERR "Failed to create /proc/rtas in proc_rtas_init\n");
return;
}
entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL);
if (entry)
entry->proc_fops = &ppc_rtas_progress_operations;
/* /proc/rtas entries */
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("progress", S_IRUGO|S_IWUSR, proc_ppc64.rtas);
if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
entry = create_proc_entry("ppc64/rtas/poweron", S_IWUSR|S_IRUGO, NULL);
if (entry)
entry->proc_fops = &ppc_rtas_poweron_operations;
entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_ppc64.rtas);
if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
create_proc_read_entry("ppc64/rtas/sensors", S_IRUGO, NULL,
ppc_rtas_sensor_read, NULL);
entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_ppc64.rtas);
if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
entry = create_proc_entry("ppc64/rtas/frequency", S_IWUSR|S_IRUGO,
NULL);
if (entry)
entry->proc_fops = &ppc_rtas_tone_freq_operations;
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;
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("volume", S_IWUSR|S_IRUGO, proc_ppc64.rtas);
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 */
/* ****************************************************************** */
......
......@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <asm/prom.h>
#include <asm/proc_fs.h>
#include <asm/rtas.h>
#include <asm/semaphore.h>
#include <asm/machdep.h>
......
......@@ -15,7 +15,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <asm/proc_fs.h>
#include <linux/proc_fs.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
......@@ -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(struct file *file, char *buf,
}
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 inode *inode, struct file *file)
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_data(const char *rtas_call_name,
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_data(const char *rtas_call_name,
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);
......
......@@ -26,7 +26,6 @@
#include <asm/prom.h>
#include <asm/nvram.h>
#include <asm/atomic.h>
#include <asm/proc_fs.h>
#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");
......
......@@ -28,7 +28,6 @@
#include <asm/uaccess.h>
#include <asm/rtas.h>
#include <asm/prom.h>
#include <asm/proc_fs.h>
#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 */
......
......@@ -28,7 +28,6 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
......@@ -37,9 +36,10 @@
#include <linux/proc_fs.h>
#include <linux/dma-mapping.h>
#include <linux/wait.h>
#include <linux/seq_file.h>
#include <asm/hardirq.h> /* for is_atomic */
#include <asm/hardirq.h>
#include <asm/uaccess.h>
#include <asm/iSeries/LparData.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvLpConfig.h>
......@@ -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 **start, off_t offset,
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);
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);
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]));
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);
......
......@@ -39,7 +39,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/naca.h>
#include <asm/pmc.h>
#include <asm/machdep.h>
#include <asm/lmb.h>
#include <asm/abs_addr.h>
......
......@@ -36,7 +36,6 @@
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/proc_fs.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
......
......@@ -73,9 +73,6 @@ void __init proc_root_init(void)
proc_tty_init();
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init();
#endif
#ifdef CONFIG_PPC_RTAS
proc_rtas_init();
#endif
proc_bus = proc_mkdir("bus", 0);
}
......
......@@ -19,12 +19,6 @@
#ifndef _ISERIES_PROC_H
#define _ISERIES_PROC_H
#include <linux/proc_fs.h>
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 */
......@@ -67,6 +67,4 @@ extern int mf_getRtcTime(unsigned long *time);
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 */
/*
* 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 <asm/types.h>
#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 */
#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 <linux/proc_fs.h>
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 */
/*
* 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 <linux/proc_fs.h>
void pmc_proc_init(struct proc_dir_entry *iSeries_proc);
void proc_ppc64_init(void);
#endif /* _PMC_PROC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment