Merge branch 'arch-microblaze' into no-rebases

This commit is contained in:
Al Viro 2012-11-16 22:28:43 -05:00
commit 2bf81c8af9
192 changed files with 1599 additions and 1174 deletions

View file

@ -1,7 +1,7 @@
VERSION = 3 VERSION = 3
PATCHLEVEL = 7 PATCHLEVEL = 7
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc4 EXTRAVERSION = -rc5
NAME = Terrified Chipmunk NAME = Terrified Chipmunk
# *DOCUMENTATION* # *DOCUMENTATION*

View file

@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
static inline void __raw_writew(u16 val, volatile void __iomem *addr) static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{ {
asm volatile("strh %1, %0" asm volatile("strh %1, %0"
: "+Qo" (*(volatile u16 __force *)addr) : "+Q" (*(volatile u16 __force *)addr)
: "r" (val)); : "r" (val));
} }
@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
{ {
u16 val; u16 val;
asm volatile("ldrh %1, %0" asm volatile("ldrh %1, %0"
: "+Qo" (*(volatile u16 __force *)addr), : "+Q" (*(volatile u16 __force *)addr),
"=r" (val)); "=r" (val));
return val; return val;
} }

View file

@ -10,7 +10,5 @@
extern void sched_clock_postinit(void); extern void sched_clock_postinit(void);
extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
unsigned long rate);
#endif #endif

View file

@ -27,9 +27,9 @@
#if __LINUX_ARM_ARCH__ <= 6 #if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0] ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16 tst \tmp, #HWCAP_VFPD32
ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space addeq \base, \base, #32*4 @ step over unused register space
#else #else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
@ -51,9 +51,9 @@
#if __LINUX_ARM_ARCH__ <= 6 #if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0] ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16 tst \tmp, #HWCAP_VFPD32
stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space addeq \base, \base, #32*4 @ step over unused register space
#else #else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field

View file

@ -18,11 +18,12 @@
#define HWCAP_THUMBEE (1 << 11) #define HWCAP_THUMBEE (1 << 11)
#define HWCAP_NEON (1 << 12) #define HWCAP_NEON (1 << 12)
#define HWCAP_VFPv3 (1 << 13) #define HWCAP_VFPv3 (1 << 13)
#define HWCAP_VFPv3D16 (1 << 14) #define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */
#define HWCAP_TLS (1 << 15) #define HWCAP_TLS (1 << 15)
#define HWCAP_VFPv4 (1 << 16) #define HWCAP_VFPv4 (1 << 16)
#define HWCAP_IDIVA (1 << 17) #define HWCAP_IDIVA (1 << 17)
#define HWCAP_IDIVT (1 << 18) #define HWCAP_IDIVT (1 << 18)
#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)

View file

@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks)
update_sched_clock(); update_sched_clock();
} }
void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits,
unsigned long rate)
{
setup_sched_clock(read, bits, rate);
cd.needs_suspend = true;
}
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
{ {
unsigned long r, w; unsigned long r, w;
@ -189,18 +182,15 @@ void __init sched_clock_postinit(void)
static int sched_clock_suspend(void) static int sched_clock_suspend(void)
{ {
sched_clock_poll(sched_clock_timer.data); sched_clock_poll(sched_clock_timer.data);
if (cd.needs_suspend) cd.suspended = true;
cd.suspended = true;
return 0; return 0;
} }
static void sched_clock_resume(void) static void sched_clock_resume(void)
{ {
if (cd.needs_suspend) { cd.epoch_cyc = read_sched_clock();
cd.epoch_cyc = read_sched_clock(); cd.epoch_cyc_copy = cd.epoch_cyc;
cd.epoch_cyc_copy = cd.epoch_cyc; cd.suspended = false;
cd.suspended = false;
}
} }
static struct syscore_ops sched_clock_ops = { static struct syscore_ops sched_clock_ops = {

View file

@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
static int static int
do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{ {
union offset_union offset; union offset_union uninitialized_var(offset);
unsigned long instr = 0, instrptr; unsigned long instr = 0, instrptr;
int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
unsigned int type; unsigned int type;

View file

@ -701,11 +701,14 @@ static int __init vfp_init(void)
elf_hwcap |= HWCAP_VFPv3; elf_hwcap |= HWCAP_VFPv3;
/* /*
* Check for VFPv3 D16. CPUs in this configuration * Check for VFPv3 D16 and VFPv4 D16. CPUs in
* only have 16 x 64bit registers. * this configuration only have 16 x 64bit
* registers.
*/ */
if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
elf_hwcap |= HWCAP_VFPv3D16; elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */
else
elf_hwcap |= HWCAP_VFPD32;
} }
#endif #endif
/* /*

View file

@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
*pages = NULL; *pages = NULL;
} }
EXPORT_SYMBOL_GPL(free_xenballooned_pages); EXPORT_SYMBOL_GPL(free_xenballooned_pages);
/* In the hypervisor.S file. */
EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version);
EXPORT_SYMBOL_GPL(HYPERVISOR_console_io);
EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
EXPORT_SYMBOL_GPL(privcmd_call);

View file

@ -1,6 +1,7 @@
config ARM64 config ARM64
def_bool y def_bool y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IOMAP select GENERIC_IOMAP

View file

@ -43,6 +43,8 @@
#else #else
#define STACK_TOP STACK_TOP_MAX #define STACK_TOP STACK_TOP_MAX
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
struct debug_info { struct debug_info {

View file

@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
#define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_COMPAT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_PAUSE

View file

@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
* before we continue. * before we continue.
*/ */
set_cpu_online(cpu, true); set_cpu_online(cpu, true);
while (!cpu_active(cpu)) complete(&cpu_running);
cpu_relax();
/* /*
* OK, it's off to the idle thread for us * OK, it's off to the idle thread for us

View file

@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
#ifdef CONFIG_ZONE_DMA32 #ifdef CONFIG_ZONE_DMA32
/* 4GB maximum for 32-bit only capable devices */ /* 4GB maximum for 32-bit only capable devices */
max_dma32 = min(max, MAX_DMA32_PFN); max_dma32 = min(max, MAX_DMA32_PFN);
zone_size[ZONE_DMA32] = max_dma32 - min; zone_size[ZONE_DMA32] = max(min, max_dma32) - min;
#endif #endif
zone_size[ZONE_NORMAL] = max - max_dma32; zone_size[ZONE_NORMAL] = max - max_dma32;

View file

@ -2,7 +2,8 @@
#define __ARCH_H8300_CACHE_H #define __ARCH_H8300_CACHE_H
/* bytes per L1 cache line */ /* bytes per L1 cache line */
#define L1_CACHE_BYTES 4 #define L1_CACHE_SHIFT 2
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/* m68k-elf-gcc 2.95.2 doesn't like these */ /* m68k-elf-gcc 2.95.2 doesn't like these */

View file

@ -26,6 +26,8 @@ config MICROBLAZE
select GENERIC_ATOMIC64 select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE
config SWAP config SWAP
def_bool n def_bool n

View file

@ -31,6 +31,7 @@ extern const struct seq_operations cpuinfo_op;
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp); void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp);
extern void ret_from_fork(void); extern void ret_from_fork(void);
extern void ret_from_kernel_thread(void);
# endif /* __ASSEMBLY__ */ # endif /* __ASSEMBLY__ */
@ -78,11 +79,6 @@ extern unsigned long thread_saved_pc(struct task_struct *t);
extern unsigned long get_wchan(struct task_struct *p); extern unsigned long get_wchan(struct task_struct *p);
/*
* create a kernel thread without removing it from tasklists
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
# define KSTK_EIP(tsk) (0) # define KSTK_EIP(tsk) (0)
# define KSTK_ESP(tsk) (0) # define KSTK_ESP(tsk) (0)
@ -131,8 +127,6 @@ extern inline void release_thread(struct task_struct *dead_task)
{ {
} }
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/* Free current thread data structures etc. */ /* Free current thread data structures etc. */
static inline void exit_thread(void) static inline void exit_thread(void)
{ {

View file

@ -422,6 +422,7 @@
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
/* /*
* "Conditional" syscalls * "Conditional" syscalls

View file

@ -474,6 +474,14 @@ ENTRY(ret_from_fork)
brid ret_to_user brid ret_to_user
nop nop
ENTRY(ret_from_kernel_thread)
brlid r15, schedule_tail
addk r5, r0, r3
brald r15, r20
addk r5, r0, r19
brid ret_to_user
addk r3, r0, r0
work_pending: work_pending:
enable_irq enable_irq
@ -559,10 +567,6 @@ sys_clone:
brid microblaze_clone brid microblaze_clone
addk r7, r1, r0 addk r7, r1, r0
sys_execve:
brid microblaze_execve
addk r8, r1, r0
sys_rt_sigreturn_wrapper: sys_rt_sigreturn_wrapper:
brid sys_rt_sigreturn brid sys_rt_sigreturn
addk r5, r1, r0 addk r5, r1, r0

View file

@ -293,24 +293,6 @@ C_ENTRY(_user_exception):
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
addi r14, r14, 4 /* return address is 4 byte after call */ addi r14, r14, 4 /* return address is 4 byte after call */
mfs r1, rmsr
nop
andi r1, r1, MSR_UMS
bnei r1, 1f
/* Kernel-mode state save - kernel execve */
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
tophys(r1,r1);
addik r1, r1, -PT_SIZE; /* Make room on the stack. */
SAVE_REGS
swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
brid 2f;
nop; /* Fill delay slot */
/* User-mode state save. */
1:
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
tophys(r1,r1); tophys(r1,r1);
lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
@ -479,11 +461,20 @@ C_ENTRY(sys_fork_wrapper):
saved context). */ saved context). */
C_ENTRY(ret_from_fork): C_ENTRY(ret_from_fork):
bralid r15, schedule_tail; /* ...which is schedule_tail's arg */ bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
add r3, r5, r0; /* switch_thread returns the prev task */ add r5, r3, r0; /* switch_thread returns the prev task */
/* ( in the delay slot ) */ /* ( in the delay slot ) */
brid ret_from_trap; /* Do normal trap return */ brid ret_from_trap; /* Do normal trap return */
add r3, r0, r0; /* Child's fork call should return 0. */ add r3, r0, r0; /* Child's fork call should return 0. */
C_ENTRY(ret_from_kernel_thread):
bralid r15, schedule_tail; /* ...which is schedule_tail's arg */
add r5, r3, r0; /* switch_thread returns the prev task */
/* ( in the delay slot ) */
brald r15, r20 /* fn was left in r20 */
addk r5, r0, r19 /* ... and argument - in r19 */
brid ret_from_trap
add r3, r0, r0
C_ENTRY(sys_vfork): C_ENTRY(sys_vfork):
brid microblaze_vfork /* Do real work (tail-call) */ brid microblaze_vfork /* Do real work (tail-call) */
addik r5, r1, 0 addik r5, r1, 0
@ -498,10 +489,6 @@ C_ENTRY(sys_clone):
brid do_fork /* Do real work (tail-call) */ brid do_fork /* Do real work (tail-call) */
add r8, r0, r0; /* Arg 3: (unused) */ add r8, r0, r0; /* Arg 3: (unused) */
C_ENTRY(sys_execve):
brid microblaze_execve; /* Do real work (tail-call).*/
addik r8, r1, 0; /* add user context as 4th arg */
C_ENTRY(sys_rt_sigreturn_wrapper): C_ENTRY(sys_rt_sigreturn_wrapper):
brid sys_rt_sigreturn /* Do real work */ brid sys_rt_sigreturn /* Do real work */
addik r5, r1, 0; /* add user context as 1st arg */ addik r5, r1, 0; /* add user context as 1st arg */

View file

@ -119,46 +119,38 @@ void flush_thread(void)
} }
int copy_thread(unsigned long clone_flags, unsigned long usp, int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, unsigned long arg,
struct task_struct *p, struct pt_regs *regs) struct task_struct *p, struct pt_regs *regs)
{ {
struct pt_regs *childregs = task_pt_regs(p); struct pt_regs *childregs = task_pt_regs(p);
struct thread_info *ti = task_thread_info(p); struct thread_info *ti = task_thread_info(p);
if (unlikely(p->flags & PF_KTHREAD)) {
/* if we're creating a new kernel thread then just zeroing all
* the registers. That's OK for a brand new thread.*/
memset(childregs, 0, sizeof(struct pt_regs));
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
ti->cpu_context.r1 = (unsigned long)childregs;
ti->cpu_context.r20 = (unsigned long)usp; /* fn */
ti->cpu_context.r19 = (unsigned long)arg;
childregs->pt_mode = 1;
local_save_flags(childregs->msr);
#ifdef CONFIG_MMU
ti->cpu_context.msr = childregs->msr & ~MSR_IE;
#endif
ti->cpu_context.r15 = (unsigned long)ret_from_kernel_thread - 8;
return 0;
}
*childregs = *regs; *childregs = *regs;
if (user_mode(regs)) childregs->r1 = usp;
childregs->r1 = usp;
else
childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
#ifndef CONFIG_MMU
memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
ti->cpu_context.r1 = (unsigned long)childregs; ti->cpu_context.r1 = (unsigned long)childregs;
#ifndef CONFIG_MMU
ti->cpu_context.msr = (unsigned long)childregs->msr; ti->cpu_context.msr = (unsigned long)childregs->msr;
#else #else
childregs->msr |= MSR_UMS;
/* if creating a kernel thread then update the current reg (we don't
* want to use the parent's value when restoring by POP_STATE) */
if (kernel_mode(regs))
/* save new current on stack to use POP_STATE */
childregs->CURRENT_TASK = (unsigned long)p;
/* if returning to user then use the parent's value of this register */
/* if we're creating a new kernel thread then just zeroing all
* the registers. That's OK for a brand new thread.*/
/* Pls. note that some of them will be restored in POP_STATE */
if (kernel_mode(regs))
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
/* if this thread is created for fork/vfork/clone, then we want to
* restore all the parent's context */
/* in addition to the registers which will be restored by POP_STATE */
else {
ti->cpu_context = *(struct cpu_context *)regs;
childregs->msr |= MSR_UMS;
}
/* FIXME STATE_SAVE_PT_OFFSET; */
ti->cpu_context.r1 = (unsigned long)childregs;
/* we should consider the fact that childregs is a copy of the parent /* we should consider the fact that childregs is a copy of the parent
* regs which were saved immediately after entering the kernel state * regs which were saved immediately after entering the kernel state
* before enabling VM. This MSR will be restored in switch_to and * before enabling VM. This MSR will be restored in switch_to and
@ -209,29 +201,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
} }
#endif #endif
static void kernel_thread_helper(int (*fn)(void *), void *arg)
{
fn(arg);
do_exit(-1);
}
int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
/* store them in non-volatile registers */
regs.r5 = (unsigned long)fn;
regs.r6 = (unsigned long)arg;
local_save_flags(regs.msr);
regs.pc = (unsigned long)kernel_thread_helper;
regs.pt_mode = 1;
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
&regs, 0, NULL, NULL);
}
EXPORT_SYMBOL_GPL(kernel_thread);
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
/* TBD (used by procfs) */ /* TBD (used by procfs) */
@ -246,6 +215,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
regs->pt_mode = 0; regs->pt_mode = 0;
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
regs->msr |= MSR_UMS; regs->msr |= MSR_UMS;
regs->msr &= ~MSR_VM;
#endif #endif
} }

View file

@ -48,24 +48,6 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack,
return do_fork(flags, stack, regs, 0, NULL, NULL); return do_fork(flags, stack, regs, 0, NULL, NULL);
} }
asmlinkage long microblaze_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs)
{
int error;
struct filename *filename;
filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
}
asmlinkage long sys_mmap(unsigned long addr, unsigned long len, asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, off_t pgoff) unsigned long fd, off_t pgoff)
@ -75,24 +57,3 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
} }
/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register const char *__a __asm__("r5") = filename;
register const void *__b __asm__("r6") = argv;
register const void *__c __asm__("r7") = envp;
register unsigned long __syscall __asm__("r12") = __NR_execve;
register unsigned long __ret __asm__("r3");
__asm__ __volatile__ ("brki r14, 0x8"
: "=r" (__ret), "=r" (__syscall)
: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
: "r4", "r8", "r9",
"r10", "r11", "r14", "cc", "memory");
return __ret;
}

View file

@ -9,6 +9,8 @@
#define LPM_ANYPATH 0xff #define LPM_ANYPATH 0xff
#define __MAX_CSSID 0 #define __MAX_CSSID 0
#define __MAX_SUBCHANNEL 65535
#define __MAX_SSID 3
#include <asm/scsw.h> #include <asm/scsw.h>

View file

@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud)
static inline int pmd_present(pmd_t pmd) static inline int pmd_present(pmd_t pmd)
{ {
return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO;
return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE ||
!(pmd_val(pmd) & _SEGMENT_ENTRY_INV);
} }
static inline int pmd_none(pmd_t pmd) static inline int pmd_none(pmd_t pmd)
{ {
return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) &&
!(pmd_val(pmd) & _SEGMENT_ENTRY_RO);
} }
static inline int pmd_large(pmd_t pmd) static inline int pmd_large(pmd_t pmd)
@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
} }
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE)
#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO)
#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW)
#define __HAVE_ARCH_PGTABLE_DEPOSIT #define __HAVE_ARCH_PGTABLE_DEPOSIT
extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
{ {
unsigned long pgprot_pmd = 0; /*
* pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx)
if (pgprot_val(pgprot) & _PAGE_INVALID) { * Convert to segment table entry format.
if (pgprot_val(pgprot) & _PAGE_SWT) */
pgprot_pmd |= _HPAGE_TYPE_NONE; if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
pgprot_pmd |= _SEGMENT_ENTRY_INV; return pgprot_val(SEGMENT_NONE);
} if (pgprot_val(pgprot) == pgprot_val(PAGE_RO))
if (pgprot_val(pgprot) & _PAGE_RO) return pgprot_val(SEGMENT_RO);
pgprot_pmd |= _SEGMENT_ENTRY_RO; return pgprot_val(SEGMENT_RW);
return pgprot_pmd;
} }
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
static inline pmd_t pmd_mkwrite(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd)
{ {
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; /* Do not clobber _HPAGE_TYPE_NONE pages! */
if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
return pmd; return pmd;
} }

View file

@ -44,6 +44,12 @@ _sclp_wait_int:
#endif #endif
mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
mvc 0(16,%r8),0(%r9) mvc 0(16,%r8),0(%r9)
#ifdef CONFIG_64BIT
epsw %r6,%r7 # set current addressing mode
nill %r6,0x1 # in new psw (31 or 64 bit mode)
nilh %r7,0x8000
stm %r6,%r7,0(%r8)
#endif
lhi %r6,0x0200 # cr mask for ext int (cr0.54) lhi %r6,0x0200 # cr mask for ext int (cr0.54)
ltr %r2,%r2 ltr %r2,%r2
jz .LsetctS1 jz .LsetctS1
@ -87,7 +93,7 @@ _sclp_wait_int:
.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
.LextpswS1_64: .LextpswS1_64:
.quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit
#endif #endif
.LwaitpswS1: .LwaitpswS1:
.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int

View file

@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm,
pmd = pmd_offset(pud, addr); pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd)) if (pmd_none(*pmd))
return -0x10UL; return -0x10UL;
if (pmd_huge(*pmd)) { if (pmd_large(*pmd)) {
if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
return -0x04UL; return -0x04UL;
return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);

View file

@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr,
*/ */
if (pmd_none(pmd) || pmd_trans_splitting(pmd)) if (pmd_none(pmd) || pmd_trans_splitting(pmd))
return 0; return 0;
if (unlikely(pmd_huge(pmd))) { if (unlikely(pmd_large(pmd))) {
if (!gup_huge_pmd(pmdp, pmd, addr, next, if (!gup_huge_pmd(pmdp, pmd, addr, next,
write, pages, nr)) write, pages, nr))
return 0; return 0;

View file

@ -20,6 +20,7 @@ config SPARC
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select SYSCTL_EXCEPTION_TRACE select SYSCTL_EXCEPTION_TRACE
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select RTC_CLASS select RTC_CLASS
select RTC_DRV_M48T59 select RTC_DRV_M48T59
select HAVE_IRQ_WORK select HAVE_IRQ_WORK

View file

@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o
obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o sha1-sparc64-y := sha1_asm.o sha1_glue.o
sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o sha256-sparc64-y := sha256_asm.o sha256_glue.o
sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o sha512-sparc64-y := sha512_asm.o sha512_glue.o
md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o md5-sparc64-y := md5_asm.o md5_glue.o
aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o aes-sparc64-y := aes_asm.o aes_glue.o
des-sparc64-y := des_asm.o des_glue.o crop_devid.o des-sparc64-y := des_asm.o des_glue.o
camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o camellia-sparc64-y := camellia_asm.o camellia_glue.o
crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o

View file

@ -475,3 +475,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
MODULE_ALIAS("aes"); MODULE_ALIAS("aes");
#include "crop_devid.c"

View file

@ -320,3 +320,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
MODULE_ALIAS("aes"); MODULE_ALIAS("aes");
#include "crop_devid.c"

View file

@ -177,3 +177,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
MODULE_ALIAS("crc32c"); MODULE_ALIAS("crc32c");
#include "crop_devid.c"

View file

@ -527,3 +527,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
MODULE_ALIAS("des"); MODULE_ALIAS("des");
#include "crop_devid.c"

View file

@ -186,3 +186,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated");
MODULE_ALIAS("md5"); MODULE_ALIAS("md5");
#include "crop_devid.c"

View file

@ -181,3 +181,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated");
MODULE_ALIAS("sha1"); MODULE_ALIAS("sha1");
#include "crop_devid.c"

View file

@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op
MODULE_ALIAS("sha224"); MODULE_ALIAS("sha224");
MODULE_ALIAS("sha256"); MODULE_ALIAS("sha256");
#include "crop_devid.c"

View file

@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op
MODULE_ALIAS("sha384"); MODULE_ALIAS("sha384");
MODULE_ALIAS("sha512"); MODULE_ALIAS("sha512");
#include "crop_devid.c"

View file

@ -1,7 +1,7 @@
/* atomic.h: Thankfully the V9 is at least reasonable for this /* atomic.h: Thankfully the V9 is at least reasonable for this
* stuff. * stuff.
* *
* Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com)
*/ */
#ifndef __ARCH_SPARC64_ATOMIC__ #ifndef __ARCH_SPARC64_ATOMIC__
@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
extern long atomic64_dec_if_positive(atomic64_t *v);
/* Atomic operations are already serializing */ /* Atomic operations are already serializing */
#define smp_mb__before_atomic_dec() barrier() #define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier()

View file

@ -1,6 +1,46 @@
#ifndef _SPARC64_BACKOFF_H #ifndef _SPARC64_BACKOFF_H
#define _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H
/* The macros in this file implement an exponential backoff facility
* for atomic operations.
*
* When multiple threads compete on an atomic operation, it is
* possible for one thread to be continually denied a successful
* completion of the compare-and-swap instruction. Heavily
* threaded cpu implementations like Niagara can compound this
* problem even further.
*
* When an atomic operation fails and needs to be retried, we spin a
* certain number of times. At each subsequent failure of the same
* operation we double the spin count, realizing an exponential
* backoff.
*
* When we spin, we try to use an operation that will cause the
* current cpu strand to block, and therefore make the core fully
* available to any other other runnable strands. There are two
* options, based upon cpu capabilities.
*
* On all cpus prior to SPARC-T4 we do three dummy reads of the
* condition code register. Each read blocks the strand for something
* between 40 and 50 cpu cycles.
*
* For SPARC-T4 and later we have a special "pause" instruction
* available. This is implemented using writes to register %asr27.
* The cpu will block the number of cycles written into the register,
* unless a disrupting trap happens first. SPARC-T4 specifically
* implements pause with a granularity of 8 cycles. Each strand has
* an internal pause counter which decrements every 8 cycles. So the
* chip shifts the %asr27 value down by 3 bits, and writes the result
* into the pause counter. If a value smaller than 8 is written, the
* chip blocks for 1 cycle.
*
* To achieve the same amount of backoff as the three %ccr reads give
* on earlier chips, we shift the backoff value up by 7 bits. (Three
* %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the
* whole amount we want to block into the pause register, rather than
* loop writing 128 each time.
*/
#define BACKOFF_LIMIT (4 * 1024) #define BACKOFF_LIMIT (4 * 1024)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
@ -11,16 +51,25 @@
#define BACKOFF_LABEL(spin_label, continue_label) \ #define BACKOFF_LABEL(spin_label, continue_label) \
spin_label spin_label
#define BACKOFF_SPIN(reg, tmp, label) \ #define BACKOFF_SPIN(reg, tmp, label) \
mov reg, tmp; \ mov reg, tmp; \
88: brnz,pt tmp, 88b; \ 88: rd %ccr, %g0; \
sub tmp, 1, tmp; \ rd %ccr, %g0; \
set BACKOFF_LIMIT, tmp; \ rd %ccr, %g0; \
cmp reg, tmp; \ .section .pause_3insn_patch,"ax";\
bg,pn %xcc, label; \ .word 88b; \
nop; \ sllx tmp, 7, tmp; \
ba,pt %xcc, label; \ wr tmp, 0, %asr27; \
sllx reg, 1, reg; clr tmp; \
.previous; \
brnz,pt tmp, 88b; \
sub tmp, 1, tmp; \
set BACKOFF_LIMIT, tmp; \
cmp reg, tmp; \
bg,pn %xcc, label; \
nop; \
ba,pt %xcc, label; \
sllx reg, 1, reg;
#else #else

View file

@ -203,7 +203,22 @@ extern unsigned long get_wchan(struct task_struct *task);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP])
#define cpu_relax() barrier() /* Please see the commentary in asm/backoff.h for a description of
* what these instructions are doing and how they have been choosen.
* To make a long story short, we are trying to yield the current cpu
* strand during busy loops.
*/
#define cpu_relax() asm volatile("\n99:\n\t" \
"rd %%ccr, %%g0\n\t" \
"rd %%ccr, %%g0\n\t" \
"rd %%ccr, %%g0\n\t" \
".section .pause_3insn_patch,\"ax\"\n\t"\
".word 99b\n\t" \
"wr %%g0, 128, %%asr27\n\t" \
"nop\n\t" \
"nop\n\t" \
".previous" \
::: "memory")
/* Prefetch support. This is tuned for UltraSPARC-III and later. /* Prefetch support. This is tuned for UltraSPARC-III and later.
* UltraSPARC-I will treat these as nops, and UltraSPARC-II has * UltraSPARC-I will treat these as nops, and UltraSPARC-II has

View file

@ -63,5 +63,10 @@ extern char *of_console_options;
extern void irq_trans_init(struct device_node *dp); extern void irq_trans_init(struct device_node *dp);
extern char *build_path_component(struct device_node *dp); extern char *build_path_component(struct device_node *dp);
/* SPARC has a local implementation */
extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r);
#define of_address_to_resource of_address_to_resource
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _SPARC_PROM_H */ #endif /* _SPARC_PROM_H */

View file

@ -406,8 +406,9 @@
#define __NR_process_vm_readv 338 #define __NR_process_vm_readv 338
#define __NR_process_vm_writev 339 #define __NR_process_vm_writev 339
#define __NR_kern_features 340 #define __NR_kern_features 340
#define __NR_kcmp 341
#define NR_syscalls 341 #define NR_syscalls 342
/* Bitmask values returned from kern_features system call. */ /* Bitmask values returned from kern_features system call. */
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001

View file

@ -59,6 +59,13 @@ struct popc_6insn_patch_entry {
extern struct popc_6insn_patch_entry __popc_6insn_patch, extern struct popc_6insn_patch_entry __popc_6insn_patch,
__popc_6insn_patch_end; __popc_6insn_patch_end;
struct pause_patch_entry {
unsigned int addr;
unsigned int insns[3];
};
extern struct pause_patch_entry __pause_3insn_patch,
__pause_3insn_patch_end;
extern void __init per_cpu_patch(void); extern void __init per_cpu_patch(void);
extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *); struct sun4v_1insn_patch_entry *);

View file

@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu)
static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
{ {
unsigned int eirq; unsigned int eirq;
struct irq_bucket *p;
int cpu = sparc_leon3_cpuid(); int cpu = sparc_leon3_cpuid();
eirq = leon_eirq_get(cpu); eirq = leon_eirq_get(cpu);
if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ p = irq_map[eirq];
generic_handle_irq(irq_map[eirq]->irq); if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */
generic_handle_irq(p->irq);
} }
/* The extended IRQ controller has been found, this function registers it */ /* The extended IRQ controller has been found, this function registers it */

View file

@ -316,6 +316,25 @@ static void __init popc_patch(void)
} }
} }
static void __init pause_patch(void)
{
struct pause_patch_entry *p;
p = &__pause_3insn_patch;
while (p < &__pause_3insn_patch_end) {
unsigned long i, addr = p->addr;
for (i = 0; i < 3; i++) {
*(unsigned int *) (addr + (i * 4)) = p->insns[i];
wmb();
__asm__ __volatile__("flush %0"
: : "r" (addr + (i * 4)));
}
p++;
}
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void __init boot_cpu_id_too_large(int cpu) void __init boot_cpu_id_too_large(int cpu)
{ {
@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void)
if (sparc64_elf_hwcap & AV_SPARC_POPC) if (sparc64_elf_hwcap & AV_SPARC_POPC)
popc_patch(); popc_patch();
if (sparc64_elf_hwcap & AV_SPARC_PAUSE)
pause_patch();
} }
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)

View file

@ -85,3 +85,4 @@ sys_call_table:
/*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
/*340*/ .long sys_ni_syscall, sys_kcmp

View file

@ -86,7 +86,7 @@ sys_call_table32:
.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
.word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev
/*340*/ .word sys_kern_features /*340*/ .word sys_kern_features, sys_kcmp
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
@ -164,4 +164,4 @@ sys_call_table:
.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
/*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
.word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
/*340*/ .word sys_kern_features /*340*/ .word sys_kern_features, sys_kcmp

View file

@ -132,6 +132,11 @@ SECTIONS
*(.popc_6insn_patch) *(.popc_6insn_patch)
__popc_6insn_patch_end = .; __popc_6insn_patch_end = .;
} }
.pause_3insn_patch : {
__pause_3insn_patch = .;
*(.pause_3insn_patch)
__pause_3insn_patch_end = .;
}
PERCPU_SECTION(SMP_CACHE_BYTES) PERCPU_SECTION(SMP_CACHE_BYTES)
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);

View file

@ -1,6 +1,6 @@
/* atomic.S: These things are too big to do inline. /* atomic.S: These things are too big to do inline.
* *
* Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net)
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
sub %g1, %o0, %o0 sub %g1, %o0, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b) 2: BACKOFF_SPIN(%o2, %o3, 1b)
ENDPROC(atomic64_sub_ret) ENDPROC(atomic64_sub_ret)
ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */
BACKOFF_SETUP(%o2)
1: ldx [%o0], %g1
brlez,pn %g1, 3f
sub %g1, 1, %g7
casx [%o0], %g1, %g7
cmp %g1, %g7
bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
nop
3: retl
sub %g1, 1, %o0
2: BACKOFF_SPIN(%o2, %o3, 1b)
ENDPROC(atomic64_dec_if_positive)

View file

@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add);
EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_add_ret);
EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub);
EXPORT_SYMBOL(atomic64_sub_ret); EXPORT_SYMBOL(atomic64_sub_ret);
EXPORT_SYMBOL(atomic64_dec_if_positive);
/* Atomic bit operations. */ /* Atomic bit operations. */
EXPORT_SYMBOL(test_and_set_bit); EXPORT_SYMBOL(test_and_set_bit);

View file

@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
return _hypercall4(int, update_va_mapping, va, return _hypercall4(int, update_va_mapping, va,
new_val.pte, new_val.pte >> 32, flags); new_val.pte, new_val.pte >> 32, flags);
} }
extern int __must_check xen_event_channel_op_compat(int, void *);
static inline int static inline int
HYPERVISOR_event_channel_op(int cmd, void *arg) HYPERVISOR_event_channel_op(int cmd, void *arg)
{ {
int rc = _hypercall2(int, event_channel_op, cmd, arg); int rc = _hypercall2(int, event_channel_op, cmd, arg);
if (unlikely(rc == -ENOSYS)) { if (unlikely(rc == -ENOSYS))
struct evtchn_op op; rc = xen_event_channel_op_compat(cmd, arg);
op.cmd = cmd;
memcpy(&op.u, arg, sizeof(op.u));
rc = _hypercall1(int, event_channel_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
return rc; return rc;
} }
@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
return _hypercall3(int, console_io, cmd, count, str); return _hypercall3(int, console_io, cmd, count, str);
} }
extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
static inline int static inline int
HYPERVISOR_physdev_op(int cmd, void *arg) HYPERVISOR_physdev_op(int cmd, void *arg)
{ {
int rc = _hypercall2(int, physdev_op, cmd, arg); int rc = _hypercall2(int, physdev_op, cmd, arg);
if (unlikely(rc == -ENOSYS)) { if (unlikely(rc == -ENOSYS))
struct physdev_op op; rc = HYPERVISOR_physdev_op_compat(cmd, arg);
op.cmd = cmd;
memcpy(&op.u, arg, sizeof(op.u));
rc = _hypercall1(int, physdev_op_compat, &op);
memcpy(arg, &op.u, sizeof(op.u));
}
return rc; return rc;
} }

View file

@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
struct crypto_async_request *req, *backlog; struct crypto_async_request *req, *backlog;
cpu_queue = container_of(work, struct cryptd_cpu_queue, work); cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
/* Only handle one request at a time to avoid hogging crypto /*
* workqueue. preempt_disable/enable is used to prevent * Only handle one request at a time to avoid hogging crypto workqueue.
* being preempted by cryptd_enqueue_request() */ * preempt_disable/enable is used to prevent being preempted by
* cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
* cryptd_enqueue_request() being accessed from software interrupts.
*/
local_bh_disable();
preempt_disable(); preempt_disable();
backlog = crypto_get_backlog(&cpu_queue->queue); backlog = crypto_get_backlog(&cpu_queue->queue);
req = crypto_dequeue_request(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue);
preempt_enable(); preempt_enable();
local_bh_enable();
if (!req) if (!req)
return; return;

View file

@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource);
*/ */
int platform_get_irq(struct platform_device *dev, unsigned int num) int platform_get_irq(struct platform_device *dev, unsigned int num)
{ {
#ifdef CONFIG_SPARC
/* sparc does not have irqs represented as IORESOURCE_IRQ resources */
if (!dev || num >= dev->archdata.num_irqs)
return -ENXIO;
return dev->archdata.irqs[num];
#else
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
return r ? r->start : -ENXIO; return r ? r->start : -ENXIO;
#endif
} }
EXPORT_SYMBOL_GPL(platform_get_irq); EXPORT_SYMBOL_GPL(platform_get_irq);

View file

@ -47,7 +47,7 @@ if GPIOLIB
config OF_GPIO config OF_GPIO
def_bool y def_bool y
depends on OF && !SPARC depends on OF
config DEBUG_GPIO config DEBUG_GPIO
bool "Debug GPIO calls" bool "Debug GPIO calls"

View file

@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
int minor_id = iminor(inode); int minor_id = iminor(inode);
struct drm_minor *minor; struct drm_minor *minor;
int retcode = 0; int retcode = 0;
int need_setup = 0;
struct address_space *old_mapping;
minor = idr_find(&drm_minors_idr, minor_id); minor = idr_find(&drm_minors_idr, minor_id);
if (!minor) if (!minor)
@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp)
if (drm_device_is_unplugged(dev)) if (drm_device_is_unplugged(dev))
return -ENODEV; return -ENODEV;
retcode = drm_open_helper(inode, filp, dev); if (!dev->open_count++)
if (!retcode) { need_setup = 1;
atomic_inc(&dev->counts[_DRM_STAT_OPENS]); mutex_lock(&dev->struct_mutex);
if (!dev->open_count++) old_mapping = dev->dev_mapping;
retcode = drm_setup(dev); if (old_mapping == NULL)
} dev->dev_mapping = &inode->i_data;
if (!retcode) { /* ihold ensures nobody can remove inode with our i_data */
mutex_lock(&dev->struct_mutex); ihold(container_of(dev->dev_mapping, struct inode, i_data));
if (dev->dev_mapping == NULL) inode->i_mapping = dev->dev_mapping;
dev->dev_mapping = &inode->i_data; filp->f_mapping = dev->dev_mapping;
/* ihold ensures nobody can remove inode with our i_data */ mutex_unlock(&dev->struct_mutex);
ihold(container_of(dev->dev_mapping, struct inode, i_data));
inode->i_mapping = dev->dev_mapping;
filp->f_mapping = dev->dev_mapping;
mutex_unlock(&dev->struct_mutex);
}
retcode = drm_open_helper(inode, filp, dev);
if (retcode)
goto err_undo;
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
if (need_setup) {
retcode = drm_setup(dev);
if (retcode)
goto err_undo;
}
return 0;
err_undo:
mutex_lock(&dev->struct_mutex);
filp->f_mapping = old_mapping;
inode->i_mapping = old_mapping;
iput(container_of(dev->dev_mapping, struct inode, i_data));
dev->dev_mapping = old_mapping;
mutex_unlock(&dev->struct_mutex);
dev->open_count--;
return retcode; return retcode;
} }
EXPORT_SYMBOL(drm_open); EXPORT_SYMBOL(drm_open);

View file

@ -22,6 +22,8 @@
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include <subdev/bar.h>
#include <engine/software.h> #include <engine/software.h>
#include <engine/disp.h> #include <engine/disp.h>
@ -37,6 +39,7 @@ nv50_disp_sclass[] = {
static void static void
nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
{ {
struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_disp *disp = &priv->base; struct nouveau_disp *disp = &priv->base;
struct nouveau_software_chan *chan, *temp; struct nouveau_software_chan *chan, *temp;
unsigned long flags; unsigned long flags;
@ -46,18 +49,19 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
if (chan->vblank.crtc != crtc) if (chan->vblank.crtc != crtc)
continue; continue;
nv_wr32(priv, 0x001704, chan->vblank.channel);
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
if (nv_device(priv)->chipset == 0x50) { if (nv_device(priv)->chipset == 0x50) {
nv_wr32(priv, 0x001704, chan->vblank.channel);
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
bar->flush(bar);
nv_wr32(priv, 0x001570, chan->vblank.offset); nv_wr32(priv, 0x001570, chan->vblank.offset);
nv_wr32(priv, 0x001574, chan->vblank.value); nv_wr32(priv, 0x001574, chan->vblank.value);
} else { } else {
if (nv_device(priv)->chipset >= 0xc0) { nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
nv_wr32(priv, 0x06000c, bar->flush(bar);
upper_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x06000c,
} upper_32_bits(chan->vblank.offset));
nv_wr32(priv, 0x060010, chan->vblank.offset); nv_wr32(priv, 0x060010,
lower_32_bits(chan->vblank.offset));
nv_wr32(priv, 0x060014, chan->vblank.value); nv_wr32(priv, 0x060014, chan->vblank.value);
} }

View file

@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent,
static int static int
nv40_graph_context_fini(struct nouveau_object *object, bool suspend) nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
{ {
struct nv04_graph_priv *priv = (void *)object->engine; struct nv40_graph_priv *priv = (void *)object->engine;
struct nv04_graph_chan *chan = (void *)object; struct nv40_graph_chan *chan = (void *)object;
u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
int ret = 0; int ret = 0;

View file

@ -38,7 +38,7 @@ struct nv40_mpeg_priv {
}; };
struct nv40_mpeg_chan { struct nv40_mpeg_chan {
struct nouveau_mpeg base; struct nouveau_mpeg_chan base;
}; };
/******************************************************************************* /*******************************************************************************

View file

@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
static void static void
nv41_vm_flush(struct nouveau_vm *vm) nv41_vm_flush(struct nouveau_vm *vm)
{ {
struct nv04_vm_priv *priv = (void *)vm->vmm; struct nv04_vmmgr_priv *priv = (void *)vm->vmm;
mutex_lock(&nv_subdev(priv)->mutex); mutex_lock(&nv_subdev(priv)->mutex);
nv_wr32(priv, 0x100810, 0x00000022); nv_wr32(priv, 0x100810, 0x00000022);

View file

@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
* valid - it's not (rh#613284) * valid - it's not (rh#613284)
*/ */
if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
status = connector_status_connected; status = connector_status_connected;
goto out; goto out;
} }

View file

@ -1696,35 +1696,43 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
return ATOM_PPLL2; return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n"); DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID; return ATOM_PPLL_INVALID;
} else { } else if (ASIC_IS_AVIVO(rdev)) {
if (ASIC_IS_AVIVO(rdev)) { /* in DP mode, the DP ref clock can come from either PPLL
/* in DP mode, the DP ref clock can come from either PPLL * depending on the asic:
* depending on the asic: * DCE3: PPLL1 or PPLL2
* DCE3: PPLL1 or PPLL2 */
*/ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { /* use the same PPLL for all DP monitors */
/* use the same PPLL for all DP monitors */ pll = radeon_get_shared_dp_ppll(crtc);
pll = radeon_get_shared_dp_ppll(crtc); if (pll != ATOM_PPLL_INVALID)
if (pll != ATOM_PPLL_INVALID) return pll;
return pll; } else {
} else { /* use the same PPLL for all monitors with the same clock */
/* use the same PPLL for all monitors with the same clock */ pll = radeon_get_shared_nondp_ppll(crtc);
pll = radeon_get_shared_nondp_ppll(crtc); if (pll != ATOM_PPLL_INVALID)
if (pll != ATOM_PPLL_INVALID) return pll;
return pll; }
} /* all other cases */
/* all other cases */ pll_in_use = radeon_get_pll_use_mask(crtc);
pll_in_use = radeon_get_pll_use_mask(crtc); /* the order shouldn't matter here, but we probably
* need this until we have atomic modeset
*/
if (rdev->flags & RADEON_IS_IGP) {
if (!(pll_in_use & (1 << ATOM_PPLL1))) if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1; return ATOM_PPLL1;
if (!(pll_in_use & (1 << ATOM_PPLL2))) if (!(pll_in_use & (1 << ATOM_PPLL2)))
return ATOM_PPLL2; return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
} else { } else {
/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ if (!(pll_in_use & (1 << ATOM_PPLL2)))
return radeon_crtc->crtc_id; return ATOM_PPLL2;
if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1;
} }
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
} else {
/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
return radeon_crtc->crtc_id;
} }
} }

View file

@ -1372,7 +1372,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
for (i = 0; i < rdev->num_crtc; i++) { for (i = 0; i < rdev->num_crtc; i++) {
if (save->crtc_enabled) { if (save->crtc_enabled[i]) {
if (ASIC_IS_DCE6(rdev)) { if (ASIC_IS_DCE6(rdev)) {
tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;

View file

@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg)
/* check config regs */ /* check config regs */
switch (reg) { switch (reg) {
case GRBM_GFX_INDEX: case GRBM_GFX_INDEX:
case CP_STRMOUT_CNTL:
case CP_COHER_CNTL:
case CP_COHER_SIZE:
case VGT_VTX_VECT_EJECT_REG: case VGT_VTX_VECT_EJECT_REG:
case VGT_CACHE_INVALIDATION: case VGT_CACHE_INVALIDATION:
case VGT_GS_VERTEX_REUSE: case VGT_GS_VERTEX_REUSE:

View file

@ -91,6 +91,10 @@
#define FB_READ_EN (1 << 0) #define FB_READ_EN (1 << 0)
#define FB_WRITE_EN (1 << 1) #define FB_WRITE_EN (1 << 1)
#define CP_STRMOUT_CNTL 0x84FC
#define CP_COHER_CNTL 0x85F0
#define CP_COHER_SIZE 0x85F4
#define CP_COHER_BASE 0x85F8 #define CP_COHER_BASE 0x85F8
#define CP_STALLED_STAT1 0x8674 #define CP_STALLED_STAT1 0x8674
#define CP_STALLED_STAT2 0x8678 #define CP_STALLED_STAT2 0x8678

View file

@ -2474,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg)
/* check config regs */ /* check config regs */
switch (reg) { switch (reg) {
case GRBM_GFX_INDEX: case GRBM_GFX_INDEX:
case CP_STRMOUT_CNTL:
case VGT_VTX_VECT_EJECT_REG: case VGT_VTX_VECT_EJECT_REG:
case VGT_CACHE_INVALIDATION: case VGT_CACHE_INVALIDATION:
case VGT_ESGS_RING_SIZE: case VGT_ESGS_RING_SIZE:

View file

@ -424,6 +424,7 @@
# define RDERR_INT_ENABLE (1 << 0) # define RDERR_INT_ENABLE (1 << 0)
# define GUI_IDLE_INT_ENABLE (1 << 19) # define GUI_IDLE_INT_ENABLE (1 << 19)
#define CP_STRMOUT_CNTL 0x84FC
#define SCRATCH_REG0 0x8500 #define SCRATCH_REG0 0x8500
#define SCRATCH_REG1 0x8504 #define SCRATCH_REG1 0x8504
#define SCRATCH_REG2 0x8508 #define SCRATCH_REG2 0x8508

View file

@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
BUG_ON(!atomic_read(&bo->reserved)); BUG_ON(!atomic_read(&bo->reserved));
BUG_ON(old_mem_type != TTM_PL_VRAM && BUG_ON(old_mem_type != TTM_PL_VRAM &&
old_mem_type != VMW_PL_FLAG_GMR); old_mem_type != VMW_PL_GMR);
pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
if (pin) if (pin)

View file

@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev)
struct drm_device *dev = pci_get_drvdata(pdev); struct drm_device *dev = pci_get_drvdata(pdev);
struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_private *dev_priv = vmw_priv(dev);
mutex_lock(&dev_priv->hw_mutex);
vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
(void) vmw_read(dev_priv, SVGA_REG_ID);
mutex_unlock(&dev_priv->hw_mutex);
/** /**
* Reclaim 3d reference held by fbdev and potentially * Reclaim 3d reference held by fbdev and potentially
* start fifo. * start fifo.

View file

@ -42,7 +42,6 @@ static struct cdev hidraw_cdev;
static struct class *hidraw_class; static struct class *hidraw_class;
static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
static DEFINE_MUTEX(minors_lock); static DEFINE_MUTEX(minors_lock);
static void drop_ref(struct hidraw *hid, int exists_bit);
static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
__u8 *buf; __u8 *buf;
int ret = 0; int ret = 0;
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { if (!hidraw_table[minor]) {
ret = -ENODEV; ret = -ENODEV;
goto out; goto out;
} }
@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
} }
mutex_lock(&minors_lock); mutex_lock(&minors_lock);
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { if (!hidraw_table[minor]) {
err = -ENODEV; err = -ENODEV;
goto out_unlock; goto out_unlock;
} }
@ -299,12 +298,36 @@ out:
static int hidraw_release(struct inode * inode, struct file * file) static int hidraw_release(struct inode * inode, struct file * file)
{ {
unsigned int minor = iminor(inode); unsigned int minor = iminor(inode);
struct hidraw *dev;
struct hidraw_list *list = file->private_data; struct hidraw_list *list = file->private_data;
int ret;
int i;
mutex_lock(&minors_lock);
if (!hidraw_table[minor]) {
ret = -ENODEV;
goto unlock;
}
drop_ref(hidraw_table[minor], 0);
list_del(&list->node); list_del(&list->node);
dev = hidraw_table[minor];
if (!--dev->open) {
if (list->hidraw->exist) {
hid_hw_power(dev->hid, PM_HINT_NORMAL);
hid_hw_close(dev->hid);
} else {
kfree(list->hidraw);
}
}
for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
kfree(list->buffer[i].value);
kfree(list); kfree(list);
return 0; ret = 0;
unlock:
mutex_unlock(&minors_lock);
return ret;
} }
static long hidraw_ioctl(struct file *file, unsigned int cmd, static long hidraw_ioctl(struct file *file, unsigned int cmd,
@ -506,7 +529,21 @@ EXPORT_SYMBOL_GPL(hidraw_connect);
void hidraw_disconnect(struct hid_device *hid) void hidraw_disconnect(struct hid_device *hid)
{ {
struct hidraw *hidraw = hid->hidraw; struct hidraw *hidraw = hid->hidraw;
drop_ref(hidraw, 1);
mutex_lock(&minors_lock);
hidraw->exist = 0;
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
hidraw_table[hidraw->minor] = NULL;
if (hidraw->open) {
hid_hw_close(hid);
wake_up_interruptible(&hidraw->wait);
} else {
kfree(hidraw);
}
mutex_unlock(&minors_lock);
} }
EXPORT_SYMBOL_GPL(hidraw_disconnect); EXPORT_SYMBOL_GPL(hidraw_disconnect);
@ -555,23 +592,3 @@ void hidraw_exit(void)
unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
} }
static void drop_ref(struct hidraw *hidraw, int exists_bit)
{
mutex_lock(&minors_lock);
if (exists_bit) {
hid_hw_close(hidraw->hid);
hidraw->exist = 0;
if (hidraw->open)
wake_up_interruptible(&hidraw->wait);
} else {
--hidraw->open;
}
if (!hidraw->open && !hidraw->exist) {
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
hidraw_table[hidraw->minor] = NULL;
kfree(hidraw);
}
mutex_unlock(&minors_lock);
}

View file

@ -32,7 +32,7 @@
* ASB100-A supports pwm1, while plain ASB100 does not. There is no known * ASB100-A supports pwm1, while plain ASB100 does not. There is no known
* way for the driver to tell which one is there. * way for the driver to tell which one is there.
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* asb100 7 3 1 4 0x31 0x0694 yes no * asb100 7 3 1 4 0x31 0x0694 yes no
*/ */

View file

@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
mutex_init(&data->lock); mutex_init(&data->lock);
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
data->name = w83627ehf_device_names[sio_data->kind]; data->name = w83627ehf_device_names[sio_data->kind];
data->bank = 0xff; /* Force initial bank selection */
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */

View file

@ -25,7 +25,7 @@
/* /*
* Supports following chips: * Supports following chips:
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC)
* w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
* w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC)

View file

@ -24,7 +24,7 @@
/* /*
* Supports following chips: * Supports following chips:
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* as99127f 7 3 0 3 0x31 0x12c3 yes no * as99127f 7 3 0 3 0x31 0x12c3 yes no
* as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
* w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes

View file

@ -22,7 +22,7 @@
/* /*
* Supports following chips: * Supports following chips:
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83791d 10 5 5 3 0x71 0x5ca3 yes no * w83791d 10 5 5 3 0x71 0x5ca3 yes no
* *
* The w83791d chip appears to be part way between the 83781d and the * The w83791d chip appears to be part way between the 83781d and the

View file

@ -31,7 +31,7 @@
/* /*
* Supports following chips: * Supports following chips:
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83792d 9 7 7 3 0x7a 0x5ca3 yes no * w83792d 9 7 7 3 0x7a 0x5ca3 yes no
*/ */

View file

@ -20,7 +20,7 @@
/* /*
* Supports following chips: * Supports following chips:
* *
* Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
* w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no
*/ */

View file

@ -4,7 +4,7 @@
menuconfig ISDN menuconfig ISDN
bool "ISDN support" bool "ISDN support"
depends on NET depends on NET && NETDEVICES
depends on !S390 && !UML depends on !S390 && !UML
---help--- ---help---
ISDN ("Integrated Services Digital Network", called RNIS in France) ISDN ("Integrated Services Digital Network", called RNIS in France)

View file

@ -6,7 +6,7 @@ if ISDN_I4L
config ISDN_PPP config ISDN_PPP
bool "Support synchronous PPP" bool "Support synchronous PPP"
depends on INET && NETDEVICES depends on INET
select SLHC select SLHC
help help
Over digital connections such as ISDN, there is no need to Over digital connections such as ISDN, there is no need to

View file

@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
} else } else
return -EINVAL; return -EINVAL;
break; break;
#ifdef CONFIG_NETDEVICES
case IIOCNETGPN: case IIOCNETGPN:
/* Get peer phone number of a connected /* Get peer phone number of a connected
* isdn network interface */ * isdn network interface */
@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
return isdn_net_getpeer(&phone, argp); return isdn_net_getpeer(&phone, argp);
} else } else
return -EINVAL; return -EINVAL;
#endif
default: default:
return -EINVAL; return -EINVAL;
} }
@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
case IIOCNETLCR: case IIOCNETLCR:
printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
return -ENODEV; return -ENODEV;
#ifdef CONFIG_NETDEVICES
case IIOCNETAIF: case IIOCNETAIF:
/* Add a network-interface */ /* Add a network-interface */
if (arg) { if (arg) {
@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
return -EFAULT; return -EFAULT;
return isdn_net_force_hangup(name); return isdn_net_force_hangup(name);
break; break;
#endif /* CONFIG_NETDEVICES */
case IIOCSETVER: case IIOCSETVER:
dev->net_verbose = arg; dev->net_verbose = arg;
printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);

View file

@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = {
MMC_CAP_CMD23, MMC_CAP_CMD23,
}; };
static struct dw_mci_drv_data exynos5250_drv_data = { static const struct dw_mci_drv_data exynos5250_drv_data = {
.caps = exynos5250_dwmmc_caps, .caps = exynos5250_dwmmc_caps,
.init = dw_mci_exynos_priv_init, .init = dw_mci_exynos_priv_init,
.setup_clock = dw_mci_exynos_setup_clock, .setup_clock = dw_mci_exynos_setup_clock,
@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = {
static const struct of_device_id dw_mci_exynos_match[] = { static const struct of_device_id dw_mci_exynos_match[] = {
{ .compatible = "samsung,exynos5250-dw-mshc", { .compatible = "samsung,exynos5250-dw-mshc",
.data = (void *)&exynos5250_drv_data, }, .data = &exynos5250_drv_data, },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); MODULE_DEVICE_TABLE(of, dw_mci_exynos_match);
int dw_mci_exynos_probe(struct platform_device *pdev) int dw_mci_exynos_probe(struct platform_device *pdev)
{ {
struct dw_mci_drv_data *drv_data; const struct dw_mci_drv_data *drv_data;
const struct of_device_id *match; const struct of_device_id *match;
match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);

View file

@ -24,7 +24,7 @@
#include "dw_mmc.h" #include "dw_mmc.h"
int dw_mci_pltfm_register(struct platform_device *pdev, int dw_mci_pltfm_register(struct platform_device *pdev,
struct dw_mci_drv_data *drv_data) const struct dw_mci_drv_data *drv_data)
{ {
struct dw_mci *host; struct dw_mci *host;
struct resource *regs; struct resource *regs;
@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
if (!host->regs) if (!host->regs)
return -ENOMEM; return -ENOMEM;
if (host->drv_data->init) { if (drv_data && drv_data->init) {
ret = host->drv_data->init(host); ret = drv_data->init(host);
if (ret) if (ret)
return ret; return ret;
} }

View file

@ -13,7 +13,7 @@
#define _DW_MMC_PLTFM_H_ #define _DW_MMC_PLTFM_H_
extern int dw_mci_pltfm_register(struct platform_device *pdev, extern int dw_mci_pltfm_register(struct platform_device *pdev,
struct dw_mci_drv_data *drv_data); const struct dw_mci_drv_data *drv_data);
extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
extern const struct dev_pm_ops dw_mci_pltfm_pmops; extern const struct dev_pm_ops dw_mci_pltfm_pmops;

View file

@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
{ {
struct mmc_data *data; struct mmc_data *data;
struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 cmdr; u32 cmdr;
cmd->error = -EINPROGRESS; cmd->error = -EINPROGRESS;
@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
cmdr |= SDMMC_CMD_DAT_WR; cmdr |= SDMMC_CMD_DAT_WR;
} }
if (slot->host->drv_data->prepare_command) if (drv_data && drv_data->prepare_command)
slot->host->drv_data->prepare_command(slot->host, &cmdr); drv_data->prepare_command(slot->host, &cmdr);
return cmdr; return cmdr;
} }
@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
return 0; return 0;
} }
static struct dw_mci_dma_ops dw_mci_idmac_ops = { static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
.init = dw_mci_idmac_init, .init = dw_mci_idmac_init,
.start = dw_mci_idmac_start_dma, .start = dw_mci_idmac_start_dma,
.stop = dw_mci_idmac_stop_dma, .stop = dw_mci_idmac_stop_dma,
@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{ {
struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci_drv_data *drv_data = slot->host->drv_data;
u32 regs; u32 regs;
/* set default 1 bit mode */ /* set default 1 bit mode */
@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->clock = ios->clock; slot->clock = ios->clock;
} }
if (slot->host->drv_data->set_ios) if (drv_data && drv_data->set_ios)
slot->host->drv_data->set_ios(slot->host, ios); drv_data->set_ios(slot->host, ios);
switch (ios->power_mode) { switch (ios->power_mode) {
case MMC_POWER_UP: case MMC_POWER_UP:
@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
{ {
struct mmc_host *mmc; struct mmc_host *mmc;
struct dw_mci_slot *slot; struct dw_mci_slot *slot;
struct dw_mci_drv_data *drv_data = host->drv_data;
int ctrl_id, ret; int ctrl_id, ret;
u8 bus_width; u8 bus_width;
@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
} else { } else {
ctrl_id = to_platform_device(host->dev)->id; ctrl_id = to_platform_device(host->dev)->id;
} }
if (host->drv_data && host->drv_data->caps) if (drv_data && drv_data->caps)
mmc->caps |= host->drv_data->caps[ctrl_id]; mmc->caps |= drv_data->caps[ctrl_id];
if (host->pdata->caps2) if (host->pdata->caps2)
mmc->caps2 = host->pdata->caps2; mmc->caps2 = host->pdata->caps2;
@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
else else
bus_width = 1; bus_width = 1;
if (host->drv_data->setup_bus) { if (drv_data && drv_data->setup_bus) {
struct device_node *slot_np; struct device_node *slot_np;
slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); slot_np = dw_mci_of_find_slot_node(host->dev, slot->id);
ret = host->drv_data->setup_bus(host, slot_np, bus_width); ret = drv_data->setup_bus(host, slot_np, bus_width);
if (ret) if (ret)
goto err_setup_bus; goto err_setup_bus;
} }
@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
/* Determine which DMA interface to use */ /* Determine which DMA interface to use */
#ifdef CONFIG_MMC_DW_IDMAC #ifdef CONFIG_MMC_DW_IDMAC
host->dma_ops = &dw_mci_idmac_ops; host->dma_ops = &dw_mci_idmac_ops;
dev_info(&host->dev, "Using internal DMA controller.\n"); dev_info(host->dev, "Using internal DMA controller.\n");
#endif #endif
if (!host->dma_ops) if (!host->dma_ops)
@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
struct dw_mci_board *pdata; struct dw_mci_board *pdata;
struct device *dev = host->dev; struct device *dev = host->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct dw_mci_drv_data *drv_data = host->drv_data;
int idx, ret; int idx, ret;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
if (host->drv_data->parse_dt) { if (drv_data && drv_data->parse_dt) {
ret = host->drv_data->parse_dt(host); ret = drv_data->parse_dt(host);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
int dw_mci_probe(struct dw_mci *host) int dw_mci_probe(struct dw_mci *host)
{ {
struct dw_mci_drv_data *drv_data = host->drv_data;
int width, i, ret = 0; int width, i, ret = 0;
u32 fifo_size; u32 fifo_size;
int init_slots = 0; int init_slots = 0;
@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host)
else else
host->bus_hz = clk_get_rate(host->ciu_clk); host->bus_hz = clk_get_rate(host->ciu_clk);
if (host->drv_data->setup_clock) { if (drv_data && drv_data->setup_clock) {
ret = host->drv_data->setup_clock(host); ret = drv_data->setup_clock(host);
if (ret) { if (ret) {
dev_err(host->dev, dev_err(host->dev,
"implementation specific clock setup failed\n"); "implementation specific clock setup failed\n");
@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host)
else else
host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
/*
* Enable interrupts for command done, data over, data empty, card det,
* receive ready and error such as transmit, receive timeout, crc error
*/
mci_writel(host, RINTSTS, 0xFFFFFFFF);
mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
SDMMC_INT_TXDR | SDMMC_INT_RXDR |
DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
dev_info(host->dev, "DW MMC controller at irq %d, "
"%d bit host data width, "
"%u deep fifo\n",
host->irq, width, fifo_size);
/* We need at least one slot to succeed */ /* We need at least one slot to succeed */
for (i = 0; i < host->num_slots; i++) { for (i = 0; i < host->num_slots; i++) {
ret = dw_mci_init_slot(host, i); ret = dw_mci_init_slot(host, i);
@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host)
else else
host->data_offset = DATA_240A_OFFSET; host->data_offset = DATA_240A_OFFSET;
/*
* Enable interrupts for command done, data over, data empty, card det,
* receive ready and error such as transmit, receive timeout, crc error
*/
mci_writel(host, RINTSTS, 0xFFFFFFFF);
mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
SDMMC_INT_TXDR | SDMMC_INT_RXDR |
DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
dev_info(host->dev, "DW MMC controller at irq %d, "
"%d bit host data width, "
"%u deep fifo\n",
host->irq, width, fifo_size);
if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");

View file

@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver);
MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:imx-mmc"); MODULE_ALIAS("platform:mxc-mmc");

View file

@ -178,7 +178,8 @@ struct omap_hsmmc_host {
static int omap_hsmmc_card_detect(struct device *dev, int slot) static int omap_hsmmc_card_detect(struct device *dev, int slot)
{ {
struct omap_mmc_platform_data *mmc = dev->platform_data; struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes card detect signal is active-low */ /* NOTE: assumes card detect signal is active-low */
return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot)
static int omap_hsmmc_get_wp(struct device *dev, int slot) static int omap_hsmmc_get_wp(struct device *dev, int slot)
{ {
struct omap_mmc_platform_data *mmc = dev->platform_data; struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes write protect signal is active-high */ /* NOTE: assumes write protect signal is active-high */
return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot)
static int omap_hsmmc_get_cover_state(struct device *dev, int slot) static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
{ {
struct omap_mmc_platform_data *mmc = dev->platform_data; struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host->pdata;
/* NOTE: assumes card detect signal is active-low */ /* NOTE: assumes card detect signal is active-low */
return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot)
static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
{ {
struct omap_mmc_platform_data *mmc = dev->platform_data; struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host->pdata;
disable_irq(mmc->slots[0].card_detect_irq); disable_irq(mmc->slots[0].card_detect_irq);
return 0; return 0;
@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot)
static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) static int omap_hsmmc_resume_cdirq(struct device *dev, int slot)
{ {
struct omap_mmc_platform_data *mmc = dev->platform_data; struct omap_hsmmc_host *host = dev_get_drvdata(dev);
struct omap_mmc_platform_data *mmc = host->pdata;
enable_irq(mmc->slots[0].card_detect_irq); enable_irq(mmc->slots[0].card_detect_irq);
return 0; return 0;
@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
clk_put(host->dbclk); clk_put(host->dbclk);
} }
mmc_free_host(host->mmc); omap_hsmmc_gpio_free(host->pdata);
iounmap(host->base); iounmap(host->base);
omap_hsmmc_gpio_free(pdev->dev.platform_data); mmc_free_host(host->mmc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res) if (res)

View file

@ -19,6 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev)
struct sdhci_dove_priv *priv; struct sdhci_dove_priv *priv;
int ret; int ret;
ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
if (ret)
goto sdhci_dove_register_fail;
priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv),
GFP_KERNEL); GFP_KERNEL);
if (!priv) { if (!priv) {
dev_err(&pdev->dev, "unable to allocate private data"); dev_err(&pdev->dev, "unable to allocate private data");
ret = -ENOMEM; return -ENOMEM;
goto sdhci_dove_allocate_fail;
} }
priv->clk = clk_get(&pdev->dev, NULL);
if (!IS_ERR(priv->clk))
clk_prepare_enable(priv->clk);
ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata);
if (ret)
goto sdhci_dove_register_fail;
host = platform_get_drvdata(pdev); host = platform_get_drvdata(pdev);
pltfm_host = sdhci_priv(host); pltfm_host = sdhci_priv(host);
pltfm_host->priv = priv; pltfm_host->priv = priv;
priv->clk = clk_get(&pdev->dev, NULL);
if (!IS_ERR(priv->clk))
clk_prepare_enable(priv->clk);
return 0; return 0;
sdhci_dove_allocate_fail:
sdhci_pltfm_unregister(pdev);
sdhci_dove_register_fail: sdhci_dove_register_fail:
if (!IS_ERR(priv->clk)) {
clk_disable_unprepare(priv->clk);
clk_put(priv->clk);
}
return ret; return ret;
} }
@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_dove_priv *priv = pltfm_host->priv; struct sdhci_dove_priv *priv = pltfm_host->priv;
if (priv->clk) { sdhci_pltfm_unregister(pdev);
if (!IS_ERR(priv->clk)) {
clk_disable_unprepare(priv->clk); if (!IS_ERR(priv->clk)) {
clk_put(priv->clk); clk_disable_unprepare(priv->clk);
} clk_put(priv->clk);
devm_kfree(&pdev->dev, priv->clk);
} }
return sdhci_pltfm_unregister(pdev); return 0;
} }
static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {

View file

@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host)
} }
#endif #endif
static void esdhc_of_platform_init(struct sdhci_host *host)
{
u32 vvn;
vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
if (vvn == VENDOR_V_22)
host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
}
static struct sdhci_ops sdhci_esdhc_ops = { static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl, .read_l = esdhc_readl,
.read_w = esdhc_readw, .read_w = esdhc_readw,
@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.enable_dma = esdhc_of_enable_dma, .enable_dma = esdhc_of_enable_dma,
.get_max_clock = esdhc_of_get_max_clock, .get_max_clock = esdhc_of_get_max_clock,
.get_min_clock = esdhc_of_get_min_clock, .get_min_clock = esdhc_of_get_min_clock,
.platform_init = esdhc_of_platform_init,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.platform_suspend = esdhc_of_suspend, .platform_suspend = esdhc_of_suspend,
.platform_resume = esdhc_of_resume, .platform_resume = esdhc_of_resume,

View file

@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
if (pci_resource_len(pdev, bar) != 0x100) { if (pci_resource_len(pdev, bar) < 0x100) {
dev_err(&pdev->dev, "Invalid iomem size. You may " dev_err(&pdev->dev, "Invalid iomem size. You may "
"experience problems.\n"); "experience problems.\n");
} }

View file

@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
goto err_remap; goto err_remap;
} }
/*
* Some platforms need to probe the controller to be able to
* determine which caps should be used.
*/
if (host->ops && host->ops->platform_init)
host->ops->platform_init(host);
platform_set_drvdata(pdev, host); platform_set_drvdata(pdev, host);
return host; return host;

View file

@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
if (ourhost->cur_clk != best_src) { if (ourhost->cur_clk != best_src) {
struct clk *clk = ourhost->clk_bus[best_src]; struct clk *clk = ourhost->clk_bus[best_src];
clk_enable(clk); clk_prepare_enable(clk);
clk_disable(ourhost->clk_bus[ourhost->cur_clk]); clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
/* turn clock off to card before changing clock source */ /* turn clock off to card before changing clock source */
writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
} }
/* enable the local io clock and keep it running for the moment. */ /* enable the local io clock and keep it running for the moment. */
clk_enable(sc->clk_io); clk_prepare_enable(sc->clk_io);
for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
struct clk *clk; struct clk *clk;
@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
} }
#ifndef CONFIG_PM_RUNTIME #ifndef CONFIG_PM_RUNTIME
clk_enable(sc->clk_bus[sc->cur_clk]); clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
#endif #endif
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -747,13 +747,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
sdhci_s3c_setup_card_detect_gpio(sc); sdhci_s3c_setup_card_detect_gpio(sc);
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
clk_disable(sc->clk_io); if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
clk_disable_unprepare(sc->clk_io);
#endif #endif
return 0; return 0;
err_req_regs: err_req_regs:
#ifndef CONFIG_PM_RUNTIME #ifndef CONFIG_PM_RUNTIME
clk_disable(sc->clk_bus[sc->cur_clk]); clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
#endif #endif
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) { if (sc->clk_bus[ptr]) {
@ -762,7 +763,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
} }
err_no_busclks: err_no_busclks:
clk_disable(sc->clk_io); clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io); clk_put(sc->clk_io);
err_io_clk: err_io_clk:
@ -794,7 +795,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
gpio_free(sc->ext_cd_gpio); gpio_free(sc->ext_cd_gpio);
#ifdef CONFIG_PM_RUNTIME #ifdef CONFIG_PM_RUNTIME
clk_enable(sc->clk_io); if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
clk_prepare_enable(sc->clk_io);
#endif #endif
sdhci_remove_host(host, 1); sdhci_remove_host(host, 1);
@ -802,14 +804,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
#ifndef CONFIG_PM_RUNTIME #ifndef CONFIG_PM_RUNTIME
clk_disable(sc->clk_bus[sc->cur_clk]); clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
#endif #endif
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
if (sc->clk_bus[ptr]) { if (sc->clk_bus[ptr]) {
clk_put(sc->clk_bus[ptr]); clk_put(sc->clk_bus[ptr]);
} }
} }
clk_disable(sc->clk_io); clk_disable_unprepare(sc->clk_io);
clk_put(sc->clk_io); clk_put(sc->clk_io);
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
@ -849,8 +851,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(host); ret = sdhci_runtime_suspend_host(host);
clk_disable(ourhost->clk_bus[ourhost->cur_clk]); clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
clk_disable(busclk); clk_disable_unprepare(busclk);
return ret; return ret;
} }
@ -861,8 +863,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
struct clk *busclk = ourhost->clk_io; struct clk *busclk = ourhost->clk_io;
int ret; int ret;
clk_enable(busclk); clk_prepare_enable(busclk);
clk_enable(ourhost->clk_bus[ourhost->cur_clk]); clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
ret = sdhci_runtime_resume_host(host); ret = sdhci_runtime_resume_host(host);
return ret; return ret;
} }

View file

@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
*/ */
if ((host->flags & SDHCI_NEEDS_RETUNING) && if ((host->flags & SDHCI_NEEDS_RETUNING) &&
!(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
/* eMMC uses cmd21 while sd and sdio use cmd19 */ if (mmc->card) {
tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? /* eMMC uses cmd21 but sd and sdio use cmd19 */
MMC_SEND_TUNING_BLOCK_HS200 : tuning_opcode =
MMC_SEND_TUNING_BLOCK; mmc->card->type == MMC_TYPE_MMC ?
spin_unlock_irqrestore(&host->lock, flags); MMC_SEND_TUNING_BLOCK_HS200 :
sdhci_execute_tuning(mmc, tuning_opcode); MMC_SEND_TUNING_BLOCK;
spin_lock_irqsave(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
sdhci_execute_tuning(mmc, tuning_opcode);
spin_lock_irqsave(&host->lock, flags);
/* Restore original mmc_request structure */ /* Restore original mmc_request structure */
host->mrq = mrq; host->mrq = mrq;
}
} }
if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host)
if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
mmc->caps |= MMC_CAP_4_BIT_DATA; mmc->caps |= MMC_CAP_4_BIT_DATA;
if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23)
mmc->caps &= ~MMC_CAP_CMD23;
if (caps[0] & SDHCI_CAN_DO_HISPD) if (caps[0] & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host)
/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
if (IS_ERR(host->vqmmc)) { if (IS_ERR_OR_NULL(host->vqmmc)) {
pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); if (PTR_ERR(host->vqmmc) < 0) {
host->vqmmc = NULL; pr_info("%s: no vqmmc regulator found\n",
mmc_hostname(mmc));
host->vqmmc = NULL;
}
} }
else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
regulator_enable(host->vqmmc); regulator_enable(host->vqmmc);
@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host)
ocr_avail = 0; ocr_avail = 0;
host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
if (IS_ERR(host->vmmc)) { if (IS_ERR_OR_NULL(host->vmmc)) {
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); if (PTR_ERR(host->vmmc) < 0) {
host->vmmc = NULL; pr_info("%s: no vmmc regulator found\n",
mmc_hostname(mmc));
host->vmmc = NULL;
}
} else } else
regulator_enable(host->vmmc); regulator_enable(host->vmmc);

View file

@ -278,6 +278,7 @@ struct sdhci_ops {
void (*hw_reset)(struct sdhci_host *host); void (*hw_reset)(struct sdhci_host *host);
void (*platform_suspend)(struct sdhci_host *host); void (*platform_suspend)(struct sdhci_host *host);
void (*platform_resume)(struct sdhci_host *host); void (*platform_resume)(struct sdhci_host *host);
void (*platform_init)(struct sdhci_host *host);
}; };
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

View file

@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
clk_disable(host->hclk);
mmc_free_host(host->mmc); mmc_free_host(host->mmc);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
clk_disable(host->hclk);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0; return 0;

View file

@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata)
SHMEM_EEE_ADV_STATUS_SHIFT); SHMEM_EEE_ADV_STATUS_SHIFT);
if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) {
DP(BNX2X_MSG_ETHTOOL, DP(BNX2X_MSG_ETHTOOL,
"Direct manipulation of EEE advertisment is not supported\n"); "Direct manipulation of EEE advertisement is not supported\n");
return -EINVAL; return -EINVAL;
} }

View file

@ -9941,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
else else
rc = bnx2x_8483x_disable_eee(phy, params, vars); rc = bnx2x_8483x_disable_eee(phy, params, vars);
if (rc) { if (rc) {
DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n");
return rc; return rc;
} }
} else { } else {
@ -12987,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params,
DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); DP(NETIF_MSG_LINK, "Analyze TX Fault\n");
break; break;
default: default:
DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n");
} }
DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up,
old_status, status); old_status, status);

View file

@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox)
{ {
struct fw_bye_cmd c; struct fw_bye_cmd c;
memset(&c, 0, sizeof(c));
INIT_CMD(c, BYE, WRITE); INIT_CMD(c, BYE, WRITE);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
} }
@ -2535,6 +2536,7 @@ int t4_early_init(struct adapter *adap, unsigned int mbox)
{ {
struct fw_initialize_cmd c; struct fw_initialize_cmd c;
memset(&c, 0, sizeof(c));
INIT_CMD(c, INITIALIZE, WRITE); INIT_CMD(c, INITIALIZE, WRITE);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
} }
@ -2551,6 +2553,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
{ {
struct fw_reset_cmd c; struct fw_reset_cmd c;
memset(&c, 0, sizeof(c));
INIT_CMD(c, RESET, WRITE); INIT_CMD(c, RESET, WRITE);
c.val = htonl(reset); c.val = htonl(reset);
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
@ -2828,7 +2831,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
HOSTPAGESIZEPF7(sge_hps)); HOSTPAGESIZEPF7(sge_hps));
t4_set_reg_field(adap, SGE_CONTROL, t4_set_reg_field(adap, SGE_CONTROL,
INGPADBOUNDARY(INGPADBOUNDARY_MASK) | INGPADBOUNDARY_MASK |
EGRSTATUSPAGESIZE_MASK, EGRSTATUSPAGESIZE_MASK,
INGPADBOUNDARY(fl_align_log - 5) | INGPADBOUNDARY(fl_align_log - 5) |
EGRSTATUSPAGESIZE(stat_len != 64)); EGRSTATUSPAGESIZE(stat_len != 64));
@ -3278,6 +3281,7 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
{ {
struct fw_vi_enable_cmd c; struct fw_vi_enable_cmd c;
memset(&c, 0, sizeof(c));
c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));

View file

@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev)
struct gfar_private *priv = dev_get_drvdata(dev); struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev; struct net_device *ndev = priv->ndev;
if (!netif_running(ndev)) if (!netif_running(ndev)) {
netif_device_attach(ndev);
return 0; return 0;
}
gfar_init_bds(ndev); gfar_init_bds(ndev);
init_registers(ndev); init_registers(ndev);

View file

@ -1948,10 +1948,10 @@ jme_close(struct net_device *netdev)
JME_NAPI_DISABLE(jme); JME_NAPI_DISABLE(jme);
tasklet_disable(&jme->linkch_task); tasklet_kill(&jme->linkch_task);
tasklet_disable(&jme->txclean_task); tasklet_kill(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task); tasklet_kill(&jme->rxclean_task);
tasklet_disable(&jme->rxempty_task); tasklet_kill(&jme->rxempty_task);
jme_disable_rx_engine(jme); jme_disable_rx_engine(jme);
jme_disable_tx_engine(jme); jme_disable_tx_engine(jme);

View file

@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
dev0 = hw->dev[0]; dev0 = hw->dev[0];
unregister_netdev(dev0); unregister_netdev(dev0);
tasklet_disable(&hw->phy_task); tasklet_kill(&hw->phy_task);
spin_lock_irq(&hw->hw_lock); spin_lock_irq(&hw->hw_lock);
hw->intr_mask = 0; hw->intr_mask = 0;

View file

@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev)
/* Delay for receive task to stop scheduling itself. */ /* Delay for receive task to stop scheduling itself. */
msleep(2000 / HZ); msleep(2000 / HZ);
tasklet_disable(&hw_priv->rx_tasklet); tasklet_kill(&hw_priv->rx_tasklet);
tasklet_disable(&hw_priv->tx_tasklet); tasklet_kill(&hw_priv->tx_tasklet);
free_irq(dev->irq, hw_priv->dev); free_irq(dev->irq, hw_priv->dev);
transmit_cleanup(hw_priv, 0); transmit_cleanup(hw_priv, 0);

Some files were not shown because too many files have changed in this diff Show more