Merge branch 'arch-microblaze' into no-rebases
This commit is contained in:
commit
2bf81c8af9
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 7
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Terrified Chipmunk
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
asm volatile("strh %1, %0"
|
||||
: "+Qo" (*(volatile u16 __force *)addr)
|
||||
: "+Q" (*(volatile u16 __force *)addr)
|
||||
: "r" (val));
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
|
|||
{
|
||||
u16 val;
|
||||
asm volatile("ldrh %1, %0"
|
||||
: "+Qo" (*(volatile u16 __force *)addr),
|
||||
: "+Q" (*(volatile u16 __force *)addr),
|
||||
"=r" (val));
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,5 @@
|
|||
|
||||
extern void sched_clock_postinit(void);
|
||||
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
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
#if __LINUX_ARM_ARCH__ <= 6
|
||||
ldr \tmp, =elf_hwcap @ may not have MVFR regs
|
||||
ldr \tmp, [\tmp, #0]
|
||||
tst \tmp, #HWCAP_VFPv3D16
|
||||
ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
|
||||
addne \base, \base, #32*4 @ step over unused register space
|
||||
tst \tmp, #HWCAP_VFPD32
|
||||
ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
|
||||
addeq \base, \base, #32*4 @ step over unused register space
|
||||
#else
|
||||
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
|
||||
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
|
||||
|
@ -51,9 +51,9 @@
|
|||
#if __LINUX_ARM_ARCH__ <= 6
|
||||
ldr \tmp, =elf_hwcap @ may not have MVFR regs
|
||||
ldr \tmp, [\tmp, #0]
|
||||
tst \tmp, #HWCAP_VFPv3D16
|
||||
stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
|
||||
addne \base, \base, #32*4 @ step over unused register space
|
||||
tst \tmp, #HWCAP_VFPD32
|
||||
stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
|
||||
addeq \base, \base, #32*4 @ step over unused register space
|
||||
#else
|
||||
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
|
||||
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
#define HWCAP_THUMBEE (1 << 11)
|
||||
#define HWCAP_NEON (1 << 12)
|
||||
#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_VFPv4 (1 << 16)
|
||||
#define HWCAP_IDIVA (1 << 17)
|
||||
#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)
|
||||
|
||||
|
||||
|
|
|
@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks)
|
|||
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)
|
||||
{
|
||||
unsigned long r, w;
|
||||
|
@ -189,18 +182,15 @@ void __init sched_clock_postinit(void)
|
|||
static int sched_clock_suspend(void)
|
||||
{
|
||||
sched_clock_poll(sched_clock_timer.data);
|
||||
if (cd.needs_suspend)
|
||||
cd.suspended = true;
|
||||
cd.suspended = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sched_clock_resume(void)
|
||||
{
|
||||
if (cd.needs_suspend) {
|
||||
cd.epoch_cyc = read_sched_clock();
|
||||
cd.epoch_cyc_copy = cd.epoch_cyc;
|
||||
cd.suspended = false;
|
||||
}
|
||||
cd.epoch_cyc = read_sched_clock();
|
||||
cd.epoch_cyc_copy = cd.epoch_cyc;
|
||||
cd.suspended = false;
|
||||
}
|
||||
|
||||
static struct syscore_ops sched_clock_ops = {
|
||||
|
|
|
@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
|
|||
static int
|
||||
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;
|
||||
int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
|
||||
unsigned int type;
|
||||
|
|
|
@ -701,11 +701,14 @@ static int __init vfp_init(void)
|
|||
elf_hwcap |= HWCAP_VFPv3;
|
||||
|
||||
/*
|
||||
* Check for VFPv3 D16. CPUs in this configuration
|
||||
* only have 16 x 64bit registers.
|
||||
* Check for VFPv3 D16 and VFPv4 D16. CPUs in
|
||||
* this configuration only have 16 x 64bit
|
||||
* registers.
|
||||
*/
|
||||
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
|
||||
/*
|
||||
|
|
|
@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages)
|
|||
*pages = NULL;
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
config ARM64
|
||||
def_bool y
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_HARDIRQS_NO_DEPRECATED
|
||||
select GENERIC_IOMAP
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#else
|
||||
#define STACK_TOP STACK_TOP_MAX
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
struct debug_info {
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION
|
||||
#define __ARCH_WANT_COMPAT_STAT64
|
||||
#define __ARCH_WANT_SYS_GETHOSTNAME
|
||||
#define __ARCH_WANT_SYS_PAUSE
|
||||
|
|
|
@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
|
|||
* before we continue.
|
||||
*/
|
||||
set_cpu_online(cpu, true);
|
||||
while (!cpu_active(cpu))
|
||||
cpu_relax();
|
||||
complete(&cpu_running);
|
||||
|
||||
/*
|
||||
* OK, it's off to the idle thread for us
|
||||
|
|
|
@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
|
|||
#ifdef CONFIG_ZONE_DMA32
|
||||
/* 4GB maximum for 32-bit only capable devices */
|
||||
max_dma32 = min(max, MAX_DMA32_PFN);
|
||||
zone_size[ZONE_DMA32] = max_dma32 - min;
|
||||
zone_size[ZONE_DMA32] = max(min, max_dma32) - min;
|
||||
#endif
|
||||
zone_size[ZONE_NORMAL] = max - max_dma32;
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#define __ARCH_H8300_CACHE_H
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ config MICROBLAZE
|
|||
select GENERIC_ATOMIC64
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select MODULES_USE_ELF_RELA
|
||||
select GENERIC_KERNEL_THREAD
|
||||
select GENERIC_KERNEL_EXECVE
|
||||
|
||||
config SWAP
|
||||
def_bool n
|
||||
|
|
|
@ -31,6 +31,7 @@ extern const struct seq_operations cpuinfo_op;
|
|||
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp);
|
||||
|
||||
extern void ret_from_fork(void);
|
||||
extern void ret_from_kernel_thread(void);
|
||||
|
||||
# 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);
|
||||
|
||||
/*
|
||||
* 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_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. */
|
||||
static inline void exit_thread(void)
|
||||
{
|
||||
|
|
|
@ -422,6 +422,7 @@
|
|||
#define __ARCH_WANT_SYS_SIGPROCMASK
|
||||
#define __ARCH_WANT_SYS_RT_SIGACTION
|
||||
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
|
||||
#define __ARCH_WANT_SYS_EXECVE
|
||||
|
||||
/*
|
||||
* "Conditional" syscalls
|
||||
|
|
|
@ -474,6 +474,14 @@ ENTRY(ret_from_fork)
|
|||
brid ret_to_user
|
||||
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:
|
||||
enable_irq
|
||||
|
||||
|
@ -559,10 +567,6 @@ sys_clone:
|
|||
brid microblaze_clone
|
||||
addk r7, r1, r0
|
||||
|
||||
sys_execve:
|
||||
brid microblaze_execve
|
||||
addk r8, r1, r0
|
||||
|
||||
sys_rt_sigreturn_wrapper:
|
||||
brid sys_rt_sigreturn
|
||||
addk r5, r1, r0
|
||||
|
|
|
@ -293,24 +293,6 @@ C_ENTRY(_user_exception):
|
|||
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
|
||||
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 */
|
||||
tophys(r1,r1);
|
||||
lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
|
||||
|
@ -479,11 +461,20 @@ C_ENTRY(sys_fork_wrapper):
|
|||
saved context). */
|
||||
C_ENTRY(ret_from_fork):
|
||||
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 ) */
|
||||
brid ret_from_trap; /* Do normal trap return */
|
||||
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):
|
||||
brid microblaze_vfork /* Do real work (tail-call) */
|
||||
addik r5, r1, 0
|
||||
|
@ -498,10 +489,6 @@ C_ENTRY(sys_clone):
|
|||
brid do_fork /* Do real work (tail-call) */
|
||||
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):
|
||||
brid sys_rt_sigreturn /* Do real work */
|
||||
addik r5, r1, 0; /* add user context as 1st arg */
|
||||
|
|
|
@ -119,46 +119,38 @@ void flush_thread(void)
|
|||
}
|
||||
|
||||
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 pt_regs *childregs = task_pt_regs(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;
|
||||
if (user_mode(regs))
|
||||
childregs->r1 = usp;
|
||||
else
|
||||
childregs->r1 = ((unsigned long) ti) + THREAD_SIZE;
|
||||
childregs->r1 = usp;
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
memset(&ti->cpu_context, 0, sizeof(struct cpu_context));
|
||||
ti->cpu_context.r1 = (unsigned long)childregs;
|
||||
#ifndef CONFIG_MMU
|
||||
ti->cpu_context.msr = (unsigned long)childregs->msr;
|
||||
#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
|
||||
* regs which were saved immediately after entering the kernel state
|
||||
* 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
|
||||
|
||||
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(®s, 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,
|
||||
®s, 0, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kernel_thread);
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
/* 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;
|
||||
#ifdef CONFIG_MMU
|
||||
regs->msr |= MSR_UMS;
|
||||
regs->msr &= ~MSR_VM;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -48,24 +48,6 @@ asmlinkage long microblaze_clone(int flags, unsigned long stack,
|
|||
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,
|
||||
unsigned long prot, unsigned long flags,
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#define LPM_ANYPATH 0xff
|
||||
#define __MAX_CSSID 0
|
||||
#define __MAX_SUBCHANNEL 65535
|
||||
#define __MAX_SSID 3
|
||||
|
||||
#include <asm/scsw.h>
|
||||
|
||||
|
|
|
@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud)
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
|
|||
}
|
||||
|
||||
#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
|
||||
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)
|
||||
{
|
||||
unsigned long pgprot_pmd = 0;
|
||||
|
||||
if (pgprot_val(pgprot) & _PAGE_INVALID) {
|
||||
if (pgprot_val(pgprot) & _PAGE_SWT)
|
||||
pgprot_pmd |= _HPAGE_TYPE_NONE;
|
||||
pgprot_pmd |= _SEGMENT_ENTRY_INV;
|
||||
}
|
||||
if (pgprot_val(pgprot) & _PAGE_RO)
|
||||
pgprot_pmd |= _SEGMENT_ENTRY_RO;
|
||||
return pgprot_pmd;
|
||||
/*
|
||||
* pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx)
|
||||
* Convert to segment table entry format.
|
||||
*/
|
||||
if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE))
|
||||
return pgprot_val(SEGMENT_NONE);
|
||||
if (pgprot_val(pgprot) == pgprot_val(PAGE_RO))
|
||||
return pgprot_val(SEGMENT_RO);
|
||||
return pgprot_val(SEGMENT_RW);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@ _sclp_wait_int:
|
|||
#endif
|
||||
mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
|
||||
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)
|
||||
ltr %r2,%r2
|
||||
jz .LsetctS1
|
||||
|
@ -87,7 +93,7 @@ _sclp_wait_int:
|
|||
.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
|
||||
#ifdef CONFIG_64BIT
|
||||
.LextpswS1_64:
|
||||
.quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit
|
||||
.quad 0, .LwaitS1 # PSW to handle ext int, 64 bit
|
||||
#endif
|
||||
.LwaitpswS1:
|
||||
.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
|
||||
|
|
|
@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm,
|
|||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd))
|
||||
return -0x10UL;
|
||||
if (pmd_huge(*pmd)) {
|
||||
if (pmd_large(*pmd)) {
|
||||
if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
|
||||
return -0x04UL;
|
||||
return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
|
||||
|
|
|
@ -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))
|
||||
return 0;
|
||||
if (unlikely(pmd_huge(pmd))) {
|
||||
if (unlikely(pmd_large(pmd))) {
|
||||
if (!gup_huge_pmd(pmdp, pmd, addr, next,
|
||||
write, pages, nr))
|
||||
return 0;
|
||||
|
|
|
@ -20,6 +20,7 @@ config SPARC
|
|||
select HAVE_ARCH_TRACEHOOK
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
select RTC_CLASS
|
||||
select RTC_DRV_M48T59
|
||||
select HAVE_IRQ_WORK
|
||||
|
|
|
@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o
|
|||
|
||||
obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o
|
||||
|
||||
sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o
|
||||
sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o
|
||||
sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o
|
||||
md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o
|
||||
sha1-sparc64-y := sha1_asm.o sha1_glue.o
|
||||
sha256-sparc64-y := sha256_asm.o sha256_glue.o
|
||||
sha512-sparc64-y := sha512_asm.o sha512_glue.o
|
||||
md5-sparc64-y := md5_asm.o md5_glue.o
|
||||
|
||||
aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o
|
||||
des-sparc64-y := des_asm.o des_glue.o crop_devid.o
|
||||
camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o
|
||||
aes-sparc64-y := aes_asm.o aes_glue.o
|
||||
des-sparc64-y := des_asm.o des_glue.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
|
||||
|
|
|
@ -475,3 +475,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("aes");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -320,3 +320,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("aes");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -177,3 +177,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("crc32c");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -527,3 +527,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("des");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -186,3 +186,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("md5");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -181,3 +181,5 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated");
|
||||
|
||||
MODULE_ALIAS("sha1");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op
|
|||
|
||||
MODULE_ALIAS("sha224");
|
||||
MODULE_ALIAS("sha256");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op
|
|||
|
||||
MODULE_ALIAS("sha384");
|
||||
MODULE_ALIAS("sha512");
|
||||
|
||||
#include "crop_devid.c"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* atomic.h: Thankfully the V9 is at least reasonable for this
|
||||
* 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__
|
||||
|
@ -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)
|
||||
|
||||
extern long atomic64_dec_if_positive(atomic64_t *v);
|
||||
|
||||
/* Atomic operations are already serializing */
|
||||
#define smp_mb__before_atomic_dec() barrier()
|
||||
#define smp_mb__after_atomic_dec() barrier()
|
||||
|
|
|
@ -1,6 +1,46 @@
|
|||
#ifndef _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)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -11,16 +51,25 @@
|
|||
#define BACKOFF_LABEL(spin_label, continue_label) \
|
||||
spin_label
|
||||
|
||||
#define BACKOFF_SPIN(reg, tmp, label) \
|
||||
mov reg, tmp; \
|
||||
88: 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;
|
||||
#define BACKOFF_SPIN(reg, tmp, label) \
|
||||
mov reg, tmp; \
|
||||
88: rd %ccr, %g0; \
|
||||
rd %ccr, %g0; \
|
||||
rd %ccr, %g0; \
|
||||
.section .pause_3insn_patch,"ax";\
|
||||
.word 88b; \
|
||||
sllx tmp, 7, tmp; \
|
||||
wr tmp, 0, %asr27; \
|
||||
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
|
||||
|
||||
|
|
|
@ -203,7 +203,22 @@ extern unsigned long get_wchan(struct task_struct *task);
|
|||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc)
|
||||
#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.
|
||||
* UltraSPARC-I will treat these as nops, and UltraSPARC-II has
|
||||
|
|
|
@ -63,5 +63,10 @@ extern char *of_console_options;
|
|||
extern void irq_trans_init(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 /* _SPARC_PROM_H */
|
||||
|
|
|
@ -406,8 +406,9 @@
|
|||
#define __NR_process_vm_readv 338
|
||||
#define __NR_process_vm_writev 339
|
||||
#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. */
|
||||
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
|
||||
|
|
|
@ -59,6 +59,13 @@ struct popc_6insn_patch_entry {
|
|||
extern struct popc_6insn_patch_entry __popc_6insn_patch,
|
||||
__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 sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
|
||||
struct sun4v_1insn_patch_entry *);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
unsigned int eirq;
|
||||
struct irq_bucket *p;
|
||||
int cpu = sparc_leon3_cpuid();
|
||||
|
||||
eirq = leon_eirq_get(cpu);
|
||||
if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
|
||||
generic_handle_irq(irq_map[eirq]->irq);
|
||||
p = irq_map[eirq];
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
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)
|
||||
popc_patch();
|
||||
if (sparc64_elf_hwcap & AV_SPARC_PAUSE)
|
||||
pause_patch();
|
||||
}
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
|
|
|
@ -85,3 +85,4 @@ sys_call_table:
|
|||
/*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
|
||||
/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev
|
||||
/*340*/ .long sys_ni_syscall, sys_kcmp
|
||||
|
|
|
@ -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
|
||||
/*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
|
||||
/*340*/ .word sys_kern_features
|
||||
/*340*/ .word sys_kern_features, sys_kcmp
|
||||
|
||||
#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
|
||||
/*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
|
||||
/*340*/ .word sys_kern_features
|
||||
/*340*/ .word sys_kern_features, sys_kcmp
|
||||
|
|
|
@ -132,6 +132,11 @@ SECTIONS
|
|||
*(.popc_6insn_patch)
|
||||
__popc_6insn_patch_end = .;
|
||||
}
|
||||
.pause_3insn_patch : {
|
||||
__pause_3insn_patch = .;
|
||||
*(.pause_3insn_patch)
|
||||
__pause_3insn_patch_end = .;
|
||||
}
|
||||
PERCPU_SECTION(SMP_CACHE_BYTES)
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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>
|
||||
|
@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
|
|||
sub %g1, %o0, %o0
|
||||
2: BACKOFF_SPIN(%o2, %o3, 1b)
|
||||
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)
|
||||
|
|
|
@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add);
|
|||
EXPORT_SYMBOL(atomic64_add_ret);
|
||||
EXPORT_SYMBOL(atomic64_sub);
|
||||
EXPORT_SYMBOL(atomic64_sub_ret);
|
||||
EXPORT_SYMBOL(atomic64_dec_if_positive);
|
||||
|
||||
/* Atomic bit operations. */
|
||||
EXPORT_SYMBOL(test_and_set_bit);
|
||||
|
|
|
@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
|
|||
return _hypercall4(int, update_va_mapping, va,
|
||||
new_val.pte, new_val.pte >> 32, flags);
|
||||
}
|
||||
extern int __must_check xen_event_channel_op_compat(int, void *);
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_event_channel_op(int cmd, void *arg)
|
||||
{
|
||||
int rc = _hypercall2(int, event_channel_op, cmd, arg);
|
||||
if (unlikely(rc == -ENOSYS)) {
|
||||
struct evtchn_op op;
|
||||
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));
|
||||
}
|
||||
if (unlikely(rc == -ENOSYS))
|
||||
rc = xen_event_channel_op_compat(cmd, arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
|
|||
return _hypercall3(int, console_io, cmd, count, str);
|
||||
}
|
||||
|
||||
extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_physdev_op(int cmd, void *arg)
|
||||
{
|
||||
int rc = _hypercall2(int, physdev_op, cmd, arg);
|
||||
if (unlikely(rc == -ENOSYS)) {
|
||||
struct physdev_op op;
|
||||
op.cmd = cmd;
|
||||
memcpy(&op.u, arg, sizeof(op.u));
|
||||
rc = _hypercall1(int, physdev_op_compat, &op);
|
||||
memcpy(arg, &op.u, sizeof(op.u));
|
||||
}
|
||||
if (unlikely(rc == -ENOSYS))
|
||||
rc = HYPERVISOR_physdev_op_compat(cmd, arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
|
|||
struct crypto_async_request *req, *backlog;
|
||||
|
||||
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
|
||||
* being preempted by cryptd_enqueue_request() */
|
||||
/*
|
||||
* Only handle one request at a time to avoid hogging crypto workqueue.
|
||||
* 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();
|
||||
backlog = crypto_get_backlog(&cpu_queue->queue);
|
||||
req = crypto_dequeue_request(&cpu_queue->queue);
|
||||
preempt_enable();
|
||||
local_bh_enable();
|
||||
|
||||
if (!req)
|
||||
return;
|
||||
|
|
|
@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource);
|
|||
*/
|
||||
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);
|
||||
|
||||
return r ? r->start : -ENXIO;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_irq);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ if GPIOLIB
|
|||
|
||||
config OF_GPIO
|
||||
def_bool y
|
||||
depends on OF && !SPARC
|
||||
depends on OF
|
||||
|
||||
config DEBUG_GPIO
|
||||
bool "Debug GPIO calls"
|
||||
|
|
|
@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp)
|
|||
int minor_id = iminor(inode);
|
||||
struct drm_minor *minor;
|
||||
int retcode = 0;
|
||||
int need_setup = 0;
|
||||
struct address_space *old_mapping;
|
||||
|
||||
minor = idr_find(&drm_minors_idr, minor_id);
|
||||
if (!minor)
|
||||
|
@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp)
|
|||
if (drm_device_is_unplugged(dev))
|
||||
return -ENODEV;
|
||||
|
||||
retcode = drm_open_helper(inode, filp, dev);
|
||||
if (!retcode) {
|
||||
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
|
||||
if (!dev->open_count++)
|
||||
retcode = drm_setup(dev);
|
||||
}
|
||||
if (!retcode) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
if (dev->dev_mapping == NULL)
|
||||
dev->dev_mapping = &inode->i_data;
|
||||
/* ihold ensures nobody can remove inode with our i_data */
|
||||
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);
|
||||
}
|
||||
if (!dev->open_count++)
|
||||
need_setup = 1;
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
old_mapping = dev->dev_mapping;
|
||||
if (old_mapping == NULL)
|
||||
dev->dev_mapping = &inode->i_data;
|
||||
/* ihold ensures nobody can remove inode with our i_data */
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_open);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/bar.h>
|
||||
|
||||
#include <engine/software.h>
|
||||
#include <engine/disp.h>
|
||||
|
||||
|
@ -37,6 +39,7 @@ nv50_disp_sclass[] = {
|
|||
static void
|
||||
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_software_chan *chan, *temp;
|
||||
unsigned long flags;
|
||||
|
@ -46,18 +49,19 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
|
|||
if (chan->vblank.crtc != crtc)
|
||||
continue;
|
||||
|
||||
nv_wr32(priv, 0x001704, chan->vblank.channel);
|
||||
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
|
||||
|
||||
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, 0x001574, chan->vblank.value);
|
||||
} else {
|
||||
if (nv_device(priv)->chipset >= 0xc0) {
|
||||
nv_wr32(priv, 0x06000c,
|
||||
upper_32_bits(chan->vblank.offset));
|
||||
}
|
||||
nv_wr32(priv, 0x060010, chan->vblank.offset);
|
||||
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
|
||||
bar->flush(bar);
|
||||
nv_wr32(priv, 0x06000c,
|
||||
upper_32_bits(chan->vblank.offset));
|
||||
nv_wr32(priv, 0x060010,
|
||||
lower_32_bits(chan->vblank.offset));
|
||||
nv_wr32(priv, 0x060014, chan->vblank.value);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent,
|
|||
static int
|
||||
nv40_graph_context_fini(struct nouveau_object *object, bool suspend)
|
||||
{
|
||||
struct nv04_graph_priv *priv = (void *)object->engine;
|
||||
struct nv04_graph_chan *chan = (void *)object;
|
||||
struct nv40_graph_priv *priv = (void *)object->engine;
|
||||
struct nv40_graph_chan *chan = (void *)object;
|
||||
u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4;
|
||||
int ret = 0;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ struct nv40_mpeg_priv {
|
|||
};
|
||||
|
||||
struct nv40_mpeg_chan {
|
||||
struct nouveau_mpeg base;
|
||||
struct nouveau_mpeg_chan base;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
|
|||
static void
|
||||
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);
|
||||
nv_wr32(priv, 0x100810, 0x00000022);
|
||||
|
|
|
@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
|
|||
* valid - it's not (rh#613284)
|
||||
*/
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -1696,35 +1696,43 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
return ATOM_PPLL2;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else {
|
||||
if (ASIC_IS_AVIVO(rdev)) {
|
||||
/* in DP mode, the DP ref clock can come from either PPLL
|
||||
* depending on the asic:
|
||||
* DCE3: PPLL1 or PPLL2
|
||||
*/
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
} else {
|
||||
/* use the same PPLL for all monitors with the same clock */
|
||||
pll = radeon_get_shared_nondp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
/* all other cases */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
} else if (ASIC_IS_AVIVO(rdev)) {
|
||||
/* in DP mode, the DP ref clock can come from either PPLL
|
||||
* depending on the asic:
|
||||
* DCE3: PPLL1 or PPLL2
|
||||
*/
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
} else {
|
||||
/* use the same PPLL for all monitors with the same clock */
|
||||
pll = radeon_get_shared_nondp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
/* all other cases */
|
||||
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)))
|
||||
return ATOM_PPLL1;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
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;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
if (save->crtc_enabled) {
|
||||
if (save->crtc_enabled[i]) {
|
||||
if (ASIC_IS_DCE6(rdev)) {
|
||||
tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
|
||||
tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
|
||||
|
|
|
@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg)
|
|||
/* check config regs */
|
||||
switch (reg) {
|
||||
case GRBM_GFX_INDEX:
|
||||
case CP_STRMOUT_CNTL:
|
||||
case CP_COHER_CNTL:
|
||||
case CP_COHER_SIZE:
|
||||
case VGT_VTX_VECT_EJECT_REG:
|
||||
case VGT_CACHE_INVALIDATION:
|
||||
case VGT_GS_VERTEX_REUSE:
|
||||
|
|
|
@ -91,6 +91,10 @@
|
|||
#define FB_READ_EN (1 << 0)
|
||||
#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_STALLED_STAT1 0x8674
|
||||
#define CP_STALLED_STAT2 0x8678
|
||||
|
|
|
@ -2474,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg)
|
|||
/* check config regs */
|
||||
switch (reg) {
|
||||
case GRBM_GFX_INDEX:
|
||||
case CP_STRMOUT_CNTL:
|
||||
case VGT_VTX_VECT_EJECT_REG:
|
||||
case VGT_CACHE_INVALIDATION:
|
||||
case VGT_ESGS_RING_SIZE:
|
||||
|
|
|
@ -424,6 +424,7 @@
|
|||
# define RDERR_INT_ENABLE (1 << 0)
|
||||
# define GUI_IDLE_INT_ENABLE (1 << 19)
|
||||
|
||||
#define CP_STRMOUT_CNTL 0x84FC
|
||||
#define SCRATCH_REG0 0x8500
|
||||
#define SCRATCH_REG1 0x8504
|
||||
#define SCRATCH_REG2 0x8508
|
||||
|
|
|
@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
|
|||
|
||||
BUG_ON(!atomic_read(&bo->reserved));
|
||||
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;
|
||||
if (pin)
|
||||
|
|
|
@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev)
|
|||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
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
|
||||
* start fifo.
|
||||
|
|
|
@ -42,7 +42,6 @@ static struct cdev hidraw_cdev;
|
|||
static struct class *hidraw_class;
|
||||
static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
|
||||
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)
|
||||
{
|
||||
|
@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
|
|||
__u8 *buf;
|
||||
int ret = 0;
|
||||
|
||||
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
|
||||
if (!hidraw_table[minor]) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
mutex_lock(&minors_lock);
|
||||
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
|
||||
if (!hidraw_table[minor]) {
|
||||
err = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -299,12 +298,36 @@ out:
|
|||
static int hidraw_release(struct inode * inode, struct file * file)
|
||||
{
|
||||
unsigned int minor = iminor(inode);
|
||||
struct hidraw *dev;
|
||||
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);
|
||||
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);
|
||||
return 0;
|
||||
ret = 0;
|
||||
unlock:
|
||||
mutex_unlock(&minors_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -555,23 +592,3 @@ void hidraw_exit(void)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* ASB100-A supports pwm1, while plain ASB100 does not. There is no known
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
|
|
@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
|||
mutex_init(&data->lock);
|
||||
mutex_init(&data->update_lock);
|
||||
data->name = w83627ehf_device_names[sio_data->kind];
|
||||
data->bank = 0xff; /* Force initial bank selection */
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
/*
|
||||
* 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)
|
||||
* w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
|
||||
* w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
/*
|
||||
* 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 rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
|
||||
* w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* The w83791d chip appears to be part way between the 83781d and the
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
menuconfig ISDN
|
||||
bool "ISDN support"
|
||||
depends on NET
|
||||
depends on NET && NETDEVICES
|
||||
depends on !S390 && !UML
|
||||
---help---
|
||||
ISDN ("Integrated Services Digital Network", called RNIS in France)
|
||||
|
|
|
@ -6,7 +6,7 @@ if ISDN_I4L
|
|||
|
||||
config ISDN_PPP
|
||||
bool "Support synchronous PPP"
|
||||
depends on INET && NETDEVICES
|
||||
depends on INET
|
||||
select SLHC
|
||||
help
|
||||
Over digital connections such as ISDN, there is no need to
|
||||
|
|
|
@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
|
|||
} else
|
||||
return -EINVAL;
|
||||
break;
|
||||
#ifdef CONFIG_NETDEVICES
|
||||
case IIOCNETGPN:
|
||||
/* Get peer phone number of a connected
|
||||
* isdn network interface */
|
||||
|
@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
|
|||
return isdn_net_getpeer(&phone, argp);
|
||||
} else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
|
|||
case IIOCNETLCR:
|
||||
printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
|
||||
return -ENODEV;
|
||||
#ifdef CONFIG_NETDEVICES
|
||||
case IIOCNETAIF:
|
||||
/* Add a network-interface */
|
||||
if (arg) {
|
||||
|
@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
|
|||
return -EFAULT;
|
||||
return isdn_net_force_hangup(name);
|
||||
break;
|
||||
#endif /* CONFIG_NETDEVICES */
|
||||
case IIOCSETVER:
|
||||
dev->net_verbose = arg;
|
||||
printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
|
||||
|
|
|
@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = {
|
|||
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,
|
||||
.init = dw_mci_exynos_priv_init,
|
||||
.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[] = {
|
||||
{ .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)
|
||||
{
|
||||
struct dw_mci_drv_data *drv_data;
|
||||
const struct dw_mci_drv_data *drv_data;
|
||||
const struct of_device_id *match;
|
||||
|
||||
match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "dw_mmc.h"
|
||||
|
||||
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 resource *regs;
|
||||
|
@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
|
|||
if (!host->regs)
|
||||
return -ENOMEM;
|
||||
|
||||
if (host->drv_data->init) {
|
||||
ret = host->drv_data->init(host);
|
||||
if (drv_data && drv_data->init) {
|
||||
ret = drv_data->init(host);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#define _DW_MMC_PLTFM_H_
|
||||
|
||||
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 const struct dev_pm_ops dw_mci_pltfm_pmops;
|
||||
|
||||
|
|
|
@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
|
|||
{
|
||||
struct mmc_data *data;
|
||||
struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
struct dw_mci_drv_data *drv_data = slot->host->drv_data;
|
||||
u32 cmdr;
|
||||
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;
|
||||
}
|
||||
|
||||
if (slot->host->drv_data->prepare_command)
|
||||
slot->host->drv_data->prepare_command(slot->host, &cmdr);
|
||||
if (drv_data && drv_data->prepare_command)
|
||||
drv_data->prepare_command(slot->host, &cmdr);
|
||||
|
||||
return cmdr;
|
||||
}
|
||||
|
@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)
|
|||
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,
|
||||
.start = dw_mci_idmac_start_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)
|
||||
{
|
||||
struct dw_mci_slot *slot = mmc_priv(mmc);
|
||||
struct dw_mci_drv_data *drv_data = slot->host->drv_data;
|
||||
u32 regs;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (slot->host->drv_data->set_ios)
|
||||
slot->host->drv_data->set_ios(slot->host, ios);
|
||||
if (drv_data && drv_data->set_ios)
|
||||
drv_data->set_ios(slot->host, ios);
|
||||
|
||||
switch (ios->power_mode) {
|
||||
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 dw_mci_slot *slot;
|
||||
struct dw_mci_drv_data *drv_data = host->drv_data;
|
||||
int ctrl_id, ret;
|
||||
u8 bus_width;
|
||||
|
||||
|
@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
|||
} else {
|
||||
ctrl_id = to_platform_device(host->dev)->id;
|
||||
}
|
||||
if (host->drv_data && host->drv_data->caps)
|
||||
mmc->caps |= host->drv_data->caps[ctrl_id];
|
||||
if (drv_data && drv_data->caps)
|
||||
mmc->caps |= drv_data->caps[ctrl_id];
|
||||
|
||||
if (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
|
||||
bus_width = 1;
|
||||
|
||||
if (host->drv_data->setup_bus) {
|
||||
if (drv_data && drv_data->setup_bus) {
|
||||
struct device_node *slot_np;
|
||||
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)
|
||||
goto err_setup_bus;
|
||||
}
|
||||
|
@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
|
|||
/* Determine which DMA interface to use */
|
||||
#ifdef CONFIG_MMC_DW_IDMAC
|
||||
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
|
||||
|
||||
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 device *dev = host->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct dw_mci_drv_data *drv_data = host->drv_data;
|
||||
int idx, ret;
|
||||
|
||||
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);
|
||||
|
||||
if (host->drv_data->parse_dt) {
|
||||
ret = host->drv_data->parse_dt(host);
|
||||
if (drv_data && drv_data->parse_dt) {
|
||||
ret = drv_data->parse_dt(host);
|
||||
if (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)
|
||||
{
|
||||
struct dw_mci_drv_data *drv_data = host->drv_data;
|
||||
int width, i, ret = 0;
|
||||
u32 fifo_size;
|
||||
int init_slots = 0;
|
||||
|
@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host)
|
|||
else
|
||||
host->bus_hz = clk_get_rate(host->ciu_clk);
|
||||
|
||||
if (host->drv_data->setup_clock) {
|
||||
ret = host->drv_data->setup_clock(host);
|
||||
if (drv_data && drv_data->setup_clock) {
|
||||
ret = drv_data->setup_clock(host);
|
||||
if (ret) {
|
||||
dev_err(host->dev,
|
||||
"implementation specific clock setup failed\n");
|
||||
|
@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host)
|
|||
else
|
||||
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 */
|
||||
for (i = 0; i < host->num_slots; i++) {
|
||||
ret = dw_mci_init_slot(host, i);
|
||||
|
@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host)
|
|||
else
|
||||
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)
|
||||
dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
|
||||
|
||||
|
|
|
@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver);
|
|||
MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
|
||||
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:imx-mmc");
|
||||
MODULE_ALIAS("platform:mxc-mmc");
|
||||
|
|
|
@ -178,7 +178,8 @@ struct omap_hsmmc_host {
|
|||
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
|
@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
|
|||
clk_put(host->dbclk);
|
||||
}
|
||||
|
||||
mmc_free_host(host->mmc);
|
||||
omap_hsmmc_gpio_free(host->pdata);
|
||||
iounmap(host->base);
|
||||
omap_hsmmc_gpio_free(pdev->dev.platform_data);
|
||||
mmc_free_host(host->mmc);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev)
|
|||
struct sdhci_dove_priv *priv;
|
||||
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),
|
||||
GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&pdev->dev, "unable to allocate private data");
|
||||
ret = -ENOMEM;
|
||||
goto sdhci_dove_allocate_fail;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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);
|
||||
pltfm_host = sdhci_priv(host);
|
||||
pltfm_host->priv = priv;
|
||||
|
||||
priv->clk = clk_get(&pdev->dev, NULL);
|
||||
if (!IS_ERR(priv->clk))
|
||||
clk_prepare_enable(priv->clk);
|
||||
return 0;
|
||||
|
||||
sdhci_dove_allocate_fail:
|
||||
sdhci_pltfm_unregister(pdev);
|
||||
sdhci_dove_register_fail:
|
||||
if (!IS_ERR(priv->clk)) {
|
||||
clk_disable_unprepare(priv->clk);
|
||||
clk_put(priv->clk);
|
||||
}
|
||||
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_dove_priv *priv = pltfm_host->priv;
|
||||
|
||||
if (priv->clk) {
|
||||
if (!IS_ERR(priv->clk)) {
|
||||
clk_disable_unprepare(priv->clk);
|
||||
clk_put(priv->clk);
|
||||
}
|
||||
devm_kfree(&pdev->dev, priv->clk);
|
||||
sdhci_pltfm_unregister(pdev);
|
||||
|
||||
if (!IS_ERR(priv->clk)) {
|
||||
clk_disable_unprepare(priv->clk);
|
||||
clk_put(priv->clk);
|
||||
}
|
||||
return sdhci_pltfm_unregister(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
|
||||
|
|
|
@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host)
|
|||
}
|
||||
#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 = {
|
||||
.read_l = esdhc_readl,
|
||||
.read_w = esdhc_readw,
|
||||
|
@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
|
|||
.enable_dma = esdhc_of_enable_dma,
|
||||
.get_max_clock = esdhc_of_get_max_clock,
|
||||
.get_min_clock = esdhc_of_get_min_clock,
|
||||
.platform_init = esdhc_of_platform_init,
|
||||
#ifdef CONFIG_PM
|
||||
.platform_suspend = esdhc_of_suspend,
|
||||
.platform_resume = esdhc_of_resume,
|
||||
|
|
|
@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
|
|||
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 "
|
||||
"experience problems.\n");
|
||||
}
|
||||
|
|
|
@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
|
|||
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);
|
||||
|
||||
return host;
|
||||
|
|
|
@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
|
|||
if (ourhost->cur_clk != best_src) {
|
||||
struct clk *clk = ourhost->clk_bus[best_src];
|
||||
|
||||
clk_enable(clk);
|
||||
clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
clk_prepare_enable(clk);
|
||||
clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
|
||||
/* turn clock off to card before changing clock source */
|
||||
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. */
|
||||
clk_enable(sc->clk_io);
|
||||
clk_prepare_enable(sc->clk_io);
|
||||
|
||||
for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
|
||||
struct clk *clk;
|
||||
|
@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_PM_RUNTIME
|
||||
clk_enable(sc->clk_bus[sc->cur_clk]);
|
||||
clk_prepare_enable(sc->clk_bus[sc->cur_clk]);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
clk_disable(sc->clk_io);
|
||||
if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
|
||||
clk_disable_unprepare(sc->clk_io);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
err_req_regs:
|
||||
#ifndef CONFIG_PM_RUNTIME
|
||||
clk_disable(sc->clk_bus[sc->cur_clk]);
|
||||
clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
|
||||
#endif
|
||||
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
|
||||
if (sc->clk_bus[ptr]) {
|
||||
|
@ -762,7 +763,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
err_no_busclks:
|
||||
clk_disable(sc->clk_io);
|
||||
clk_disable_unprepare(sc->clk_io);
|
||||
clk_put(sc->clk_io);
|
||||
|
||||
err_io_clk:
|
||||
|
@ -794,7 +795,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
|
|||
gpio_free(sc->ext_cd_gpio);
|
||||
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
clk_enable(sc->clk_io);
|
||||
if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
|
||||
clk_prepare_enable(sc->clk_io);
|
||||
#endif
|
||||
sdhci_remove_host(host, 1);
|
||||
|
||||
|
@ -802,14 +804,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
|
|||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
#ifndef CONFIG_PM_RUNTIME
|
||||
clk_disable(sc->clk_bus[sc->cur_clk]);
|
||||
clk_disable_unprepare(sc->clk_bus[sc->cur_clk]);
|
||||
#endif
|
||||
for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
|
||||
if (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);
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
|
@ -849,8 +851,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
|
|||
|
||||
ret = sdhci_runtime_suspend_host(host);
|
||||
|
||||
clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
clk_disable(busclk);
|
||||
clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
clk_disable_unprepare(busclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -861,8 +863,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
|
|||
struct clk *busclk = ourhost->clk_io;
|
||||
int ret;
|
||||
|
||||
clk_enable(busclk);
|
||||
clk_enable(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
clk_prepare_enable(busclk);
|
||||
clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
ret = sdhci_runtime_resume_host(host);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
*/
|
||||
if ((host->flags & SDHCI_NEEDS_RETUNING) &&
|
||||
!(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
|
||||
/* eMMC uses cmd21 while sd and sdio use cmd19 */
|
||||
tuning_opcode = mmc->card->type == MMC_TYPE_MMC ?
|
||||
MMC_SEND_TUNING_BLOCK_HS200 :
|
||||
MMC_SEND_TUNING_BLOCK;
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
sdhci_execute_tuning(mmc, tuning_opcode);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
if (mmc->card) {
|
||||
/* eMMC uses cmd21 but sd and sdio use cmd19 */
|
||||
tuning_opcode =
|
||||
mmc->card->type == MMC_TYPE_MMC ?
|
||||
MMC_SEND_TUNING_BLOCK_HS200 :
|
||||
MMC_SEND_TUNING_BLOCK;
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
sdhci_execute_tuning(mmc, tuning_opcode);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
/* Restore original mmc_request structure */
|
||||
host->mrq = mrq;
|
||||
/* Restore original mmc_request structure */
|
||||
host->mrq = mrq;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
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)
|
||||
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 */
|
||||
host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
|
||||
if (IS_ERR(host->vqmmc)) {
|
||||
pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
|
||||
host->vqmmc = NULL;
|
||||
if (IS_ERR_OR_NULL(host->vqmmc)) {
|
||||
if (PTR_ERR(host->vqmmc) < 0) {
|
||||
pr_info("%s: no vqmmc regulator found\n",
|
||||
mmc_hostname(mmc));
|
||||
host->vqmmc = NULL;
|
||||
}
|
||||
}
|
||||
else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
|
||||
regulator_enable(host->vqmmc);
|
||||
|
@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
ocr_avail = 0;
|
||||
|
||||
host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
|
||||
if (IS_ERR(host->vmmc)) {
|
||||
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
|
||||
host->vmmc = NULL;
|
||||
if (IS_ERR_OR_NULL(host->vmmc)) {
|
||||
if (PTR_ERR(host->vmmc) < 0) {
|
||||
pr_info("%s: no vmmc regulator found\n",
|
||||
mmc_hostname(mmc));
|
||||
host->vmmc = NULL;
|
||||
}
|
||||
} else
|
||||
regulator_enable(host->vmmc);
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ struct sdhci_ops {
|
|||
void (*hw_reset)(struct sdhci_host *host);
|
||||
void (*platform_suspend)(struct sdhci_host *host);
|
||||
void (*platform_resume)(struct sdhci_host *host);
|
||||
void (*platform_init)(struct sdhci_host *host);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
|
||||
|
|
|
@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
clk_disable(host->hclk);
|
||||
mmc_free_host(host->mmc);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
clk_disable(host->hclk);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata)
|
|||
SHMEM_EEE_ADV_STATUS_SHIFT);
|
||||
if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) {
|
||||
DP(BNX2X_MSG_ETHTOOL,
|
||||
"Direct manipulation of EEE advertisment is not supported\n");
|
||||
"Direct manipulation of EEE advertisement is not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -9941,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
|
|||
else
|
||||
rc = bnx2x_8483x_disable_eee(phy, params, vars);
|
||||
if (rc) {
|
||||
DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n");
|
||||
DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n");
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
|
@ -12987,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params,
|
|||
DP(NETIF_MSG_LINK, "Analyze TX Fault\n");
|
||||
break;
|
||||
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,
|
||||
old_status, status);
|
||||
|
|
|
@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox)
|
|||
{
|
||||
struct fw_bye_cmd c;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
INIT_CMD(c, BYE, WRITE);
|
||||
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;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
INIT_CMD(c, INITIALIZE, WRITE);
|
||||
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;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
INIT_CMD(c, RESET, WRITE);
|
||||
c.val = htonl(reset);
|
||||
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));
|
||||
|
||||
t4_set_reg_field(adap, SGE_CONTROL,
|
||||
INGPADBOUNDARY(INGPADBOUNDARY_MASK) |
|
||||
INGPADBOUNDARY_MASK |
|
||||
EGRSTATUSPAGESIZE_MASK,
|
||||
INGPADBOUNDARY(fl_align_log - 5) |
|
||||
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;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
|
||||
FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
|
||||
c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c));
|
||||
|
|
|
@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev)
|
|||
struct gfar_private *priv = dev_get_drvdata(dev);
|
||||
struct net_device *ndev = priv->ndev;
|
||||
|
||||
if (!netif_running(ndev))
|
||||
if (!netif_running(ndev)) {
|
||||
netif_device_attach(ndev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gfar_init_bds(ndev);
|
||||
init_registers(ndev);
|
||||
|
|
|
@ -1948,10 +1948,10 @@ jme_close(struct net_device *netdev)
|
|||
|
||||
JME_NAPI_DISABLE(jme);
|
||||
|
||||
tasklet_disable(&jme->linkch_task);
|
||||
tasklet_disable(&jme->txclean_task);
|
||||
tasklet_disable(&jme->rxclean_task);
|
||||
tasklet_disable(&jme->rxempty_task);
|
||||
tasklet_kill(&jme->linkch_task);
|
||||
tasklet_kill(&jme->txclean_task);
|
||||
tasklet_kill(&jme->rxclean_task);
|
||||
tasklet_kill(&jme->rxempty_task);
|
||||
|
||||
jme_disable_rx_engine(jme);
|
||||
jme_disable_tx_engine(jme);
|
||||
|
|
|
@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
|
|||
dev0 = hw->dev[0];
|
||||
unregister_netdev(dev0);
|
||||
|
||||
tasklet_disable(&hw->phy_task);
|
||||
tasklet_kill(&hw->phy_task);
|
||||
|
||||
spin_lock_irq(&hw->hw_lock);
|
||||
hw->intr_mask = 0;
|
||||
|
|
|
@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev)
|
|||
/* Delay for receive task to stop scheduling itself. */
|
||||
msleep(2000 / HZ);
|
||||
|
||||
tasklet_disable(&hw_priv->rx_tasklet);
|
||||
tasklet_disable(&hw_priv->tx_tasklet);
|
||||
tasklet_kill(&hw_priv->rx_tasklet);
|
||||
tasklet_kill(&hw_priv->tx_tasklet);
|
||||
free_irq(dev->irq, hw_priv->dev);
|
||||
|
||||
transmit_cleanup(hw_priv, 0);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue