Commit a3a543a5 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5

into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents b46aedbc b60ccde5
...@@ -152,7 +152,7 @@ void free_irq(unsigned int irq, void *dev_id) ...@@ -152,7 +152,7 @@ void free_irq(unsigned int irq, void *dev_id)
return sun4d_free_irq(irq, dev_id); return sun4d_free_irq(irq, dev_id);
} }
cpu_irq = irq & NR_IRQS; cpu_irq = irq & (NR_IRQS - 1);
action = *(cpu_irq + irq_action); action = *(cpu_irq + irq_action);
if (cpu_irq > 14) { /* 14 irq levels on the sparc */ if (cpu_irq > 14) { /* 14 irq levels on the sparc */
printk("Trying to free bogus IRQ %d\n", irq); printk("Trying to free bogus IRQ %d\n", irq);
...@@ -391,7 +391,7 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) ...@@ -391,7 +391,7 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
struct irqaction * action; struct irqaction * action;
unsigned int cpu_irq; unsigned int cpu_irq;
cpu_irq = irq & NR_IRQS; cpu_irq = irq & (NR_IRQS - 1);
action = *(cpu_irq + irq_action); action = *(cpu_irq + irq_action);
printk("IO device interrupt, irq = %d\n", irq); printk("IO device interrupt, irq = %d\n", irq);
...@@ -469,7 +469,7 @@ int request_fast_irq(unsigned int irq, ...@@ -469,7 +469,7 @@ int request_fast_irq(unsigned int irq,
extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3; extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;
#endif #endif
cpu_irq = irq & NR_IRQS; cpu_irq = irq & (NR_IRQS - 1);
if(cpu_irq > 14) if(cpu_irq > 14)
return -EINVAL; return -EINVAL;
if(!handler) if(!handler)
...@@ -559,7 +559,7 @@ int request_irq(unsigned int irq, ...@@ -559,7 +559,7 @@ int request_irq(unsigned int irq,
unsigned long, const char *, void *); unsigned long, const char *, void *);
return sun4d_request_irq(irq, handler, irqflags, devname, dev_id); return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
} }
cpu_irq = irq & NR_IRQS; cpu_irq = irq & (NR_IRQS - 1);
if(cpu_irq > 14) if(cpu_irq > 14)
return -EINVAL; return -EINVAL;
......
...@@ -57,7 +57,7 @@ static void sun4c_disable_irq(unsigned int irq_nr) ...@@ -57,7 +57,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)
unsigned char current_mask, new_mask; unsigned char current_mask, new_mask;
save_and_cli(flags); save_and_cli(flags);
irq_nr &= NR_IRQS; irq_nr &= (NR_IRQS - 1);
current_mask = *interrupt_enable; current_mask = *interrupt_enable;
switch(irq_nr) { switch(irq_nr) {
case 1: case 1:
...@@ -86,7 +86,7 @@ static void sun4c_enable_irq(unsigned int irq_nr) ...@@ -86,7 +86,7 @@ static void sun4c_enable_irq(unsigned int irq_nr)
unsigned char current_mask, new_mask; unsigned char current_mask, new_mask;
save_and_cli(flags); save_and_cli(flags);
irq_nr &= NR_IRQS; irq_nr &= (NR_IRQS - 1);
current_mask = *interrupt_enable; current_mask = *interrupt_enable;
switch(irq_nr) { switch(irq_nr) {
case 1: case 1:
......
...@@ -1646,6 +1646,7 @@ config SOFT_WATCHDOG ...@@ -1646,6 +1646,7 @@ config SOFT_WATCHDOG
endmenu endmenu
source "arch/sparc64/oprofile/Kconfig"
menu "Kernel hacking" menu "Kernel hacking"
......
...@@ -68,6 +68,9 @@ core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/ ...@@ -68,6 +68,9 @@ core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
core-y += arch/sparc64/math-emu/ core-y += arch/sparc64/math-emu/
libs-y += arch/sparc64/prom/ arch/sparc64/lib/ libs-y += arch/sparc64/prom/ arch/sparc64/lib/
# FIXME: is drivers- right?
drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/sparc64/boot $(1) makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/sparc64/boot $(1)
tftpboot.img vmlinux.aout: tftpboot.img vmlinux.aout:
......
...@@ -955,6 +955,12 @@ CONFIG_BT_HCIVHCI=m ...@@ -955,6 +955,12 @@ CONFIG_BT_HCIVHCI=m
# #
# CONFIG_SOFT_WATCHDOG is not set # CONFIG_SOFT_WATCHDOG is not set
#
# Profiling support
#
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
# #
# Kernel hacking # Kernel hacking
# #
......
...@@ -16,6 +16,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ ...@@ -16,6 +16,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
pci_psycho.o pci_sabre.o pci_schizo.o pci_psycho.o pci_sabre.o pci_schizo.o
obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SMP) += smp.o trampoline.o
obj-$(CONFIG_PROFILING) += profile.o
obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
......
/* arch/sparc64/kernel/profile.c
*
* Almost entirely copied from ppc64 which is:
* (C) 2002 John Levon <levon@movementarian.org>
*/
#include <linux/profile.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <asm/irq.h>
static struct notifier_block *profile_listeners;
static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
int register_profile_notifier(struct notifier_block *nb)
{
int err;
write_lock_irq(&profile_lock);
err = notifier_chain_register(&profile_listeners, nb);
write_unlock_irq(&profile_lock);
return err;
}
int unregister_profile_notifier(struct notifier_block *nb)
{
int err;
write_lock_irq(&profile_lock);
err = notifier_chain_unregister(&profile_listeners, nb);
write_unlock_irq(&profile_lock);
return err;
}
void sparc64_profile_hook(struct pt_regs *regs)
{
read_lock(&profile_lock);
notifier_call_chain(&profile_listeners, 0, regs);
read_unlock(&profile_lock);
}
...@@ -926,7 +926,7 @@ void smp_promstop_others(void) ...@@ -926,7 +926,7 @@ void smp_promstop_others(void)
smp_cross_call(&xcall_promstop, 0, 0, 0); smp_cross_call(&xcall_promstop, 0, 0, 0);
} }
extern void sparc64_do_profile(unsigned long pc, unsigned long o7); extern void sparc64_do_profile(struct pt_regs *regs);
static unsigned long current_tick_offset; static unsigned long current_tick_offset;
...@@ -960,9 +960,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) ...@@ -960,9 +960,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
} }
do { do {
if (!user) sparc64_do_profile(regs);
sparc64_do_profile(regs->tpc,
regs->u_regs[UREG_RETPC]);
if (!--prof_counter(cpu)) { if (!--prof_counter(cpu)) {
if (cpu == boot_cpu_id) { if (cpu == boot_cpu_id) {
irq_enter(); irq_enter();
......
...@@ -190,6 +190,7 @@ EXPORT_SYMBOL(tlb_type); ...@@ -190,6 +190,7 @@ EXPORT_SYMBOL(tlb_type);
EXPORT_SYMBOL(get_fb_unmapped_area); EXPORT_SYMBOL(get_fb_unmapped_area);
EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(flush_icache_range);
EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(flush_dcache_page);
EXPORT_SYMBOL(__flush_dcache_range);
EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mostek_lock);
EXPORT_SYMBOL(mstk48t02_regs); EXPORT_SYMBOL(mstk48t02_regs);
...@@ -373,3 +374,8 @@ EXPORT_SYMBOL(do_BUG); ...@@ -373,3 +374,8 @@ EXPORT_SYMBOL(do_BUG);
/* for ns8703 */ /* for ns8703 */
EXPORT_SYMBOL(ns87303_lock); EXPORT_SYMBOL(ns87303_lock);
#ifdef CONFIG_PROFILING
EXPORT_SYMBOL_GPL(register_profile_notifier);
EXPORT_SYMBOL_GPL(unregister_profile_notifier);
#endif
...@@ -952,25 +952,40 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -952,25 +952,40 @@ static long do_readv_writev32(int type, struct file *file,
io_fn_t fn; io_fn_t fn;
iov_fn_t fnv; iov_fn_t fnv;
/*
* SuS says "The readv() function *may* fail if the iovcnt argument
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
* traditionally returned zero for zero segments, so...
*/
retval = 0;
if (count == 0)
goto out;
/* First get the "struct iovec" from user memory and /* First get the "struct iovec" from user memory and
* verify all the pointers * verify all the pointers
*/ */
retval = 0;
if (!count)
goto out_nofree;
retval = -EFAULT;
if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
goto out_nofree;
retval = -EINVAL; retval = -EINVAL;
if (count > UIO_MAXIOV) if (count > UIO_MAXIOV)
goto out_nofree; goto out;
if (!file->f_op)
goto out;
if (count > UIO_FASTIOV) { if (count > UIO_FASTIOV) {
retval = -ENOMEM; retval = -ENOMEM;
iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL); iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
if (!iov) if (!iov)
goto out_nofree; goto out;
} }
retval = -EFAULT;
if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
goto out;
/*
* Single unix specification:
* We should -EINVAL if an element length is not >= 0 and fitting an
* ssize_t. The total length is fitting an ssize_t
*
* Be careful here because iov_len is a size_t not an ssize_t
*/
tot_len = 0; tot_len = 0;
i = count; i = count;
ivp = iov; ivp = iov;
...@@ -980,9 +995,12 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -980,9 +995,12 @@ static long do_readv_writev32(int type, struct file *file,
compat_ssize_t len; compat_ssize_t len;
u32 buf; u32 buf;
__get_user(len, &vector->iov_len); if (__get_user(len, &vector->iov_len) ||
__get_user(buf, &vector->iov_base); __get_user(buf, &vector->iov_base)) {
if (len < 0) /* size_t not fittina an compat_ssize_t .. */ retval = -EFAULT;
goto out;
}
if (len < 0) /* size_t not fitting an ssize_t32 .. */
goto out; goto out;
tot_len += len; tot_len += len;
if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
...@@ -993,25 +1011,32 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -993,25 +1011,32 @@ static long do_readv_writev32(int type, struct file *file,
ivp++; ivp++;
i--; i--;
} }
if (tot_len == 0) {
retval = 0;
goto out;
}
inode = file->f_dentry->d_inode; inode = file->f_dentry->d_inode;
/* VERIFY_WRITE actually means a read, as we write to user space */ /* VERIFY_WRITE actually means a read, as we write to user space */
retval = locks_verify_area((type == VERIFY_WRITE retval = locks_verify_area((type == READ
? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
inode, file, file->f_pos, tot_len); inode, file, file->f_pos, tot_len);
if (retval) if (retval)
goto out; goto out;
/* VERIFY_WRITE actually means a read, as we write to user space */ if (type == READ) {
fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev); fn = file->f_op->read;
fnv = file->f_op->readv;
} else {
fn = (io_fn_t)file->f_op->write;
fnv = file->f_op->writev;
}
if (fnv) { if (fnv) {
retval = fnv(file, iov, count, &file->f_pos); retval = fnv(file, iov, count, &file->f_pos);
goto out; goto out;
} }
fn = (type == VERIFY_WRITE ? file->f_op->read : /* Do it by hand, with file-ops */
(io_fn_t) file->f_op->write);
ivp = iov; ivp = iov;
while (count > 0) { while (count > 0) {
void * base; void * base;
...@@ -1021,7 +1046,9 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -1021,7 +1046,9 @@ static long do_readv_writev32(int type, struct file *file,
len = ivp->iov_len; len = ivp->iov_len;
ivp++; ivp++;
count--; count--;
nr = fn(file, base, len, &file->f_pos); nr = fn(file, base, len, &file->f_pos);
if (nr < 0) { if (nr < 0) {
if (!retval) if (!retval)
retval = nr; retval = nr;
...@@ -1034,11 +1061,9 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -1034,11 +1061,9 @@ static long do_readv_writev32(int type, struct file *file,
out: out:
if (iov != iovstack) if (iov != iovstack)
kfree(iov); kfree(iov);
out_nofree: if ((retval + (type == READ)) > 0)
/* VERIFY_WRITE actually means a read, as we write to user space */
if ((retval + (type == VERIFY_WRITE)) > 0)
dnotify_parent(file->f_dentry, dnotify_parent(file->f_dentry,
(type == VERIFY_WRITE) ? DN_ACCESS : DN_MODIFY); (type == READ) ? DN_ACCESS : DN_MODIFY);
return retval; return retval;
} }
...@@ -1046,35 +1071,46 @@ static long do_readv_writev32(int type, struct file *file, ...@@ -1046,35 +1071,46 @@ static long do_readv_writev32(int type, struct file *file,
asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count) asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
{ {
struct file *file; struct file *file;
long ret = -EBADF; int ret;
file = fget(fd); file = fget(fd);
if(!file) if(!file)
goto bad_file; return -EBADF;
if (file->f_op && (file->f_mode & FMODE_READ) && ret = -EBADF;
(file->f_op->readv || file->f_op->read)) if (!(file->f_mode & FMODE_READ))
ret = do_readv_writev32(VERIFY_WRITE, file, vector, count); goto out;
fput(file); ret = -EINVAL;
if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
goto out;
ret = do_readv_writev32(READ, file, vector, count);
bad_file: out:
fput(file);
return ret; return ret;
} }
asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count) asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
{ {
struct file *file; struct file *file;
int ret = -EBADF; int ret;
file = fget(fd); file = fget(fd);
if(!file) if(!file)
goto bad_file; return -EBADF;
if (file->f_op && (file->f_mode & FMODE_WRITE) &&
(file->f_op->writev || file->f_op->write)) ret = -EBADF;
ret = do_readv_writev32(VERIFY_READ, file, vector, count); if (!(file->f_mode & FMODE_WRITE))
fput(file); goto out;
ret = -EINVAL;
if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
goto out;
ret = do_readv_writev32(WRITE, file, vector, count);
bad_file: out:
fput(file);
return ret; return ret;
} }
...@@ -3835,3 +3871,11 @@ asmlinkage int sys32_sched_getaffinity(__kernel_pid_t32 pid, unsigned int len, ...@@ -3835,3 +3871,11 @@ asmlinkage int sys32_sched_getaffinity(__kernel_pid_t32 pid, unsigned int len,
return ret; return ret;
} }
extern int sys_lookup_dcookie(u64 cookie64, char *buf, size_t len);
int sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf, size_t len)
{
return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
buf, len);
}
...@@ -60,7 +60,7 @@ sys_call_table32: ...@@ -60,7 +60,7 @@ sys_call_table32:
/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
.word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir /*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
.word sys32_readahead, sys32_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys_nis_syscall
/*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo /*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo
.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
/*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid /*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
......
...@@ -84,9 +84,23 @@ static __inline__ void timer_check_rtc(void) ...@@ -84,9 +84,23 @@ static __inline__ void timer_check_rtc(void)
} }
} }
void sparc64_do_profile(unsigned long pc, unsigned long o7) void sparc64_do_profile(struct pt_regs *regs)
{ {
if (prof_buffer && current->pid) { unsigned long pc = regs->tpc;
unsigned long o7 = regs->u_regs[UREG_RETPC];
#ifdef CONFIG_PROFILING
extern void sparc64_profile_hook(struct pt_regs *);
sparc64_profile_hook(regs);
#endif
if (user_mode(regs))
return;
if (!prof_buffer)
return;
{
extern int _stext; extern int _stext;
extern int rwlock_impl_begin, rwlock_impl_end; extern int rwlock_impl_begin, rwlock_impl_end;
extern int atomic_impl_begin, atomic_impl_end; extern int atomic_impl_begin, atomic_impl_end;
...@@ -123,8 +137,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -123,8 +137,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
do { do {
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
if ((regs->tstate & TSTATE_PRIV) != 0) sparc64_do_profile(regs);
sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
#endif #endif
do_timer(regs); do_timer(regs);
......
menu "Profiling support"
depends on EXPERIMENTAL
config PROFILING
bool "Profiling support (EXPERIMENTAL)"
help
Say Y here to enable the extended profiling support mechanisms used
by profilers such as OProfile.
config OPROFILE
tristate "OProfile system profiling (EXPERIMENTAL)"
depends on PROFILING
help
OProfile is a profiling system capable of profiling the
whole system, include the kernel, kernel modules, libraries,
and applications.
If unsure, say N.
endmenu
obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o )
oprofile-y := $(DRIVER_OBJS) init.o timer_int.o
/**
* @file init.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/oprofile.h>
#include <linux/init.h>
extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
{
timer_init(ops, cpu);
return 0;
}
/**
* @file timer_int.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/oprofile.h>
#include <asm/ptrace.h>
static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
{
struct pt_regs * regs = (struct pt_regs *)data;
int cpu = smp_processor_id();
oprofile_add_sample(instruction_pointer(regs), 0, cpu);
return 0;
}
static struct notifier_block timer_notifier = {
.notifier_call = timer_notify,
};
static int timer_start(void)
{
return register_profile_notifier(&timer_notifier);
}
static void timer_stop(void)
{
unregister_profile_notifier(&timer_notifier);
}
static struct oprofile_operations timer_ops = {
.start = timer_start,
.stop = timer_stop
};
void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
{
*ops = &timer_ops;
*cpu = OPROFILE_CPU_TIMER;
printk(KERN_INFO "oprofile: using timer interrupt.\n");
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h>
#include <asm/pil.h> #include <asm/pil.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -156,4 +157,25 @@ static __inline__ unsigned long get_softint(void) ...@@ -156,4 +157,25 @@ static __inline__ unsigned long get_softint(void)
return retval; return retval;
} }
struct notifier_block;
#ifdef CONFIG_PROFILING
int register_profile_notifier(struct notifier_block *nb);
int unregister_profile_notifier(struct notifier_block *nb);
#else
static inline int register_profile_notifier(struct notifier_block *nb)
{
return -ENOSYS;
}
static inline int unregister_profile_notifier(struct notifier_block *nb)
{
return -ENOSYS;
}
#endif /* CONFIG_PROFILING */
#endif #endif
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