ARM i.MX fixes for 3.7-rc
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABCAAGBQJQplk7AAoJEPFlmONMx+ezYSMP/2oG4bGXA3O0ktyTOC2VA63v VEoElBItx1ZdwKmVOMOQfH5IHHFUnOxrIBB27+67qr22/gfjlrUftpVMkiwpNhqP itYkPZWynkJ+1mZMpV7nJC9PEuyKdw5FKQJovsrsGYkwOfXfylx8kJWJH+zLwXRg wLcTsb33U+H+zyWz2TCLr8+SHEiepVcRrsBgjDp1PlIK1eMhZPztdQWVvD6zZjej vnB4ea+VUE8Q6HS7CwtBf++u97hsehD7ZZ1raEllhdiXi6SXtK0ARMKk0gSalQXU mg/tV2yU3blFZFFcebPG1Mdfow6E+5xzrboCJwB0X3LnkHkdBsUr5KA4AzqedDt9 KmQqXj1vsLpDQaGMrT+icRkZmKgeBnNb84IxU69WJiEiStJeUNz7WWtGhmGcMn7L T9H33gaJbrYqcVj2NSiHP1XbHG0NKv79PgogzfPxQdR0oLXCVpFdw1cgy898bNFj Oche3MG1w9p2hTfDZbQpivJOSZWqh92ug8/yTPFR8EwoM6WHhROv13E1GdO22LF0 QPQOcXtyiYsPlPB02rqpkfAC49At5o03i3IGcT5wn4wTbyEa8BQl5ZyDwAXg2ZAi MBMskQ2V4u5sbf8Ok0Vj7ji/OLgKz/k7D3IfQ6CyBaOtILIF6X96Mh+sWGsX82sj QTwkEhTr/Tgk5wtivn8i =3SGE -----END PGP SIGNATURE----- Merge tag 'imx-fixes-rc' of git://git.pengutronix.de/git/imx/linux-2.6 into fixes From Sascha Hauer <s.hauer@pengutronix.de>: ARM i.MX fixes for 3.7-rc * tag 'imx-fixes-rc' of git://git.pengutronix.de/git/imx/linux-2.6: ARM: imx: ehci: fix host power mask bit ARM i.MX: fix error-valued pointer dereference in clk_register_gate2() Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
57260e4088
@ -27,17 +27,17 @@ Start End Size Use
|
|||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
0000000000000000 0000007fffffffff 512GB user
|
0000000000000000 0000007fffffffff 512GB user
|
||||||
|
|
||||||
ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
|
ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc
|
||||||
|
|
||||||
ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page]
|
ffffffbbffff0000 ffffffbbffffffff 64KB [guard page]
|
||||||
|
|
||||||
ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space
|
|
||||||
|
|
||||||
ffffffbbffff0000 ffffffbcffffffff 64KB [guard page]
|
|
||||||
|
|
||||||
ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
|
ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
|
||||||
|
|
||||||
ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap]
|
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
|
||||||
|
|
||||||
|
ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
|
||||||
|
|
||||||
|
ffffffbbffff0000 ffffffbcffffffff ~2MB [guard]
|
||||||
|
|
||||||
ffffffbffc000000 ffffffbfffffffff 64MB modules
|
ffffffbffc000000 ffffffbfffffffff 64MB modules
|
||||||
|
|
||||||
|
2
Makefile
2
Makefile
@ -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*
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,19 +182,16 @@ 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 = {
|
||||||
.suspend = sched_clock_suspend,
|
.suspend = sched_clock_suspend,
|
||||||
|
@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
|
|||||||
|
|
||||||
clk = clk_register(dev, &gate->hw);
|
clk = clk_register(dev, &gate->hw);
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(clk))
|
||||||
kfree(clk);
|
kfree(gate);
|
||||||
|
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#define MX25_H1_SIC_SHIFT 21
|
#define MX25_H1_SIC_SHIFT 21
|
||||||
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
|
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
|
||||||
#define MX25_H1_PP_BIT (1 << 18)
|
#define MX25_H1_PP_BIT (1 << 18)
|
||||||
#define MX25_H1_PM_BIT (1 << 8)
|
#define MX25_H1_PM_BIT (1 << 16)
|
||||||
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
|
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
|
||||||
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
|
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
|
||||||
#define MX25_H1_TLL_BIT (1 << 5)
|
#define MX25_H1_TLL_BIT (1 << 5)
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#define MX35_H1_SIC_SHIFT 21
|
#define MX35_H1_SIC_SHIFT 21
|
||||||
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
|
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
|
||||||
#define MX35_H1_PP_BIT (1 << 18)
|
#define MX35_H1_PP_BIT (1 << 18)
|
||||||
#define MX35_H1_PM_BIT (1 << 8)
|
#define MX35_H1_PM_BIT (1 << 16)
|
||||||
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
|
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
|
||||||
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
|
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
|
||||||
#define MX35_H1_TLL_BIT (1 << 5)
|
#define MX35_H1_TLL_BIT (1 << 5)
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -25,12 +25,10 @@
|
|||||||
#include <asm/user.h>
|
#include <asm/user.h>
|
||||||
|
|
||||||
typedef unsigned long elf_greg_t;
|
typedef unsigned long elf_greg_t;
|
||||||
typedef unsigned long elf_freg_t[3];
|
|
||||||
|
|
||||||
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
|
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
|
||||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||||
|
typedef struct user_fpsimd_state elf_fpregset_t;
|
||||||
typedef struct user_fp elf_fpregset_t;
|
|
||||||
|
|
||||||
#define EM_AARCH64 183
|
#define EM_AARCH64 183
|
||||||
|
|
||||||
@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t;
|
|||||||
#define R_AARCH64_MOVW_PREL_G2_NC 292
|
#define R_AARCH64_MOVW_PREL_G2_NC 292
|
||||||
#define R_AARCH64_MOVW_PREL_G3 293
|
#define R_AARCH64_MOVW_PREL_G3 293
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are used to set parameters in the core dumps.
|
* These are used to set parameters in the core dumps.
|
||||||
*/
|
*/
|
||||||
|
@ -25,9 +25,8 @@
|
|||||||
* - FPSR and FPCR
|
* - FPSR and FPCR
|
||||||
* - 32 128-bit data registers
|
* - 32 128-bit data registers
|
||||||
*
|
*
|
||||||
* Note that user_fp forms a prefix of this structure, which is relied
|
* Note that user_fpsimd forms a prefix of this structure, which is
|
||||||
* upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
|
* relied upon in the ptrace FP/SIMD accessors.
|
||||||
* form a prefix of struct fpsimd_state.
|
|
||||||
*/
|
*/
|
||||||
struct fpsimd_state {
|
struct fpsimd_state {
|
||||||
union {
|
union {
|
||||||
|
@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
|
|||||||
* I/O port access primitives.
|
* I/O port access primitives.
|
||||||
*/
|
*/
|
||||||
#define IO_SPACE_LIMIT 0xffff
|
#define IO_SPACE_LIMIT 0xffff
|
||||||
#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL)
|
#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
|
||||||
|
|
||||||
static inline u8 inb(unsigned long addr)
|
static inline u8 inb(unsigned long addr)
|
||||||
{
|
{
|
||||||
@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr);
|
|||||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
|
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||||
|
|
||||||
#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
|
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||||
#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
|
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||||
#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC)
|
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
|
||||||
#define iounmap __iounmap
|
#define iounmap __iounmap
|
||||||
|
|
||||||
#define ARCH_HAS_IOREMAP_WC
|
#define ARCH_HAS_IOREMAP_WC
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types {
|
|||||||
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
|
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
|
||||||
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
|
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
|
||||||
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
|
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
|
||||||
|
|
||||||
/*
|
|
||||||
* This isn't an architected event.
|
|
||||||
* We detect this event number and use the cycle counter instead.
|
|
||||||
*/
|
|
||||||
ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PMUv3 HW events mapping. */
|
/* PMUv3 HW events mapping. */
|
||||||
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
|
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
|
||||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
|
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
|
||||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
|
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
|
||||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
|
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
|
||||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
|
[PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
|
||||||
@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
|
|||||||
unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
|
unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
|
||||||
|
|
||||||
/* Always place a cycle counter into the cycle counter. */
|
/* Always place a cycle counter into the cycle counter. */
|
||||||
if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
|
if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
|
||||||
if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
|
if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
|
@ -309,24 +309,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
|||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill in the task's elfregs structure for a core dump.
|
|
||||||
*/
|
|
||||||
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
|
|
||||||
{
|
|
||||||
elf_core_copy_regs(elfregs, task_pt_regs(t));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* fill in the fpe structure for a core dump...
|
|
||||||
*/
|
|
||||||
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dump_fpu);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shuffle the argument into the correct register before calling the
|
* Shuffle the argument into the correct register before calling the
|
||||||
* thread function. x1 is the thread argument, x2 is the pointer to
|
* thread function. x1 is the thread argument, x2 is the pointer to
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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,6 +1276,8 @@ 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)
|
||||||
{
|
{
|
||||||
|
/* Do not clobber _HPAGE_TYPE_NONE pages! */
|
||||||
|
if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV))
|
||||||
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
|
pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
|
||||||
return pmd;
|
return pmd;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
@ -13,7 +53,16 @@
|
|||||||
|
|
||||||
#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; \
|
||||||
|
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; \
|
sub tmp, 1, tmp; \
|
||||||
set BACKOFF_LIMIT, tmp; \
|
set BACKOFF_LIMIT, tmp; \
|
||||||
cmp reg, tmp; \
|
cmp reg, tmp; \
|
||||||
|
@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len)
|
|||||||
struct pt_regs *regs = current_thread_info()->kregs;
|
struct pt_regs *regs = current_thread_info()->kregs;
|
||||||
unsigned long usp = regs->u_regs[UREG_I6];
|
unsigned long usp = regs->u_regs[UREG_I6];
|
||||||
|
|
||||||
if (!(test_thread_flag(TIF_32BIT)))
|
if (test_thread_64bit_stack(usp))
|
||||||
usp += STACK_BIAS;
|
usp += STACK_BIAS;
|
||||||
else
|
|
||||||
|
if (test_thread_flag(TIF_32BIT))
|
||||||
usp &= 0xffffffffUL;
|
usp &= 0xffffffffUL;
|
||||||
|
|
||||||
usp -= len;
|
usp -= len;
|
||||||
|
@ -196,7 +196,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
|
||||||
|
@ -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 */
|
||||||
|
@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void)
|
|||||||
|
|
||||||
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
|
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
|
||||||
|
|
||||||
|
#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0)
|
||||||
|
#define test_thread_64bit_stack(__SP) \
|
||||||
|
((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \
|
||||||
|
false : true)
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
@ -372,6 +372,8 @@ etrap_spill_fixup_64bit: \
|
|||||||
|
|
||||||
/* Normal 32bit spill */
|
/* Normal 32bit spill */
|
||||||
#define SPILL_2_GENERIC(ASI) \
|
#define SPILL_2_GENERIC(ASI) \
|
||||||
|
and %sp, 1, %g3; \
|
||||||
|
brnz,pn %g3, (. - (128 + 4)); \
|
||||||
srl %sp, 0, %sp; \
|
srl %sp, 0, %sp; \
|
||||||
stwa %l0, [%sp + %g0] ASI; \
|
stwa %l0, [%sp + %g0] ASI; \
|
||||||
mov 0x04, %g3; \
|
mov 0x04, %g3; \
|
||||||
@ -398,13 +400,15 @@ etrap_spill_fixup_64bit: \
|
|||||||
stwa %i6, [%g1 + %g0] ASI; \
|
stwa %i6, [%g1 + %g0] ASI; \
|
||||||
stwa %i7, [%g1 + %g3] ASI; \
|
stwa %i7, [%g1 + %g3] ASI; \
|
||||||
saved; \
|
saved; \
|
||||||
retry; nop; nop; \
|
retry; \
|
||||||
b,a,pt %xcc, spill_fixup_dax; \
|
b,a,pt %xcc, spill_fixup_dax; \
|
||||||
b,a,pt %xcc, spill_fixup_mna; \
|
b,a,pt %xcc, spill_fixup_mna; \
|
||||||
b,a,pt %xcc, spill_fixup;
|
b,a,pt %xcc, spill_fixup;
|
||||||
|
|
||||||
#define SPILL_2_GENERIC_ETRAP \
|
#define SPILL_2_GENERIC_ETRAP \
|
||||||
etrap_user_spill_32bit: \
|
etrap_user_spill_32bit: \
|
||||||
|
and %sp, 1, %g3; \
|
||||||
|
brnz,pn %g3, etrap_user_spill_64bit; \
|
||||||
srl %sp, 0, %sp; \
|
srl %sp, 0, %sp; \
|
||||||
stwa %l0, [%sp + 0x00] %asi; \
|
stwa %l0, [%sp + 0x00] %asi; \
|
||||||
stwa %l1, [%sp + 0x04] %asi; \
|
stwa %l1, [%sp + 0x04] %asi; \
|
||||||
@ -427,7 +431,7 @@ etrap_user_spill_32bit: \
|
|||||||
ba,pt %xcc, etrap_save; \
|
ba,pt %xcc, etrap_save; \
|
||||||
wrpr %g1, %cwp; \
|
wrpr %g1, %cwp; \
|
||||||
nop; nop; nop; nop; \
|
nop; nop; nop; nop; \
|
||||||
nop; nop; nop; nop; \
|
nop; nop; \
|
||||||
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
|
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
|
||||||
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
|
ba,a,pt %xcc, etrap_spill_fixup_32bit; \
|
||||||
ba,a,pt %xcc, etrap_spill_fixup_32bit;
|
ba,a,pt %xcc, etrap_spill_fixup_32bit;
|
||||||
@ -592,6 +596,8 @@ user_rtt_fill_64bit: \
|
|||||||
|
|
||||||
/* Normal 32bit fill */
|
/* Normal 32bit fill */
|
||||||
#define FILL_2_GENERIC(ASI) \
|
#define FILL_2_GENERIC(ASI) \
|
||||||
|
and %sp, 1, %g3; \
|
||||||
|
brnz,pn %g3, (. - (128 + 4)); \
|
||||||
srl %sp, 0, %sp; \
|
srl %sp, 0, %sp; \
|
||||||
lduwa [%sp + %g0] ASI, %l0; \
|
lduwa [%sp + %g0] ASI, %l0; \
|
||||||
mov 0x04, %g2; \
|
mov 0x04, %g2; \
|
||||||
@ -616,13 +622,15 @@ user_rtt_fill_64bit: \
|
|||||||
lduwa [%g1 + %g3] ASI, %i6; \
|
lduwa [%g1 + %g3] ASI, %i6; \
|
||||||
lduwa [%g1 + %g5] ASI, %i7; \
|
lduwa [%g1 + %g5] ASI, %i7; \
|
||||||
restored; \
|
restored; \
|
||||||
retry; nop; nop; nop; nop; \
|
retry; nop; nop; \
|
||||||
b,a,pt %xcc, fill_fixup_dax; \
|
b,a,pt %xcc, fill_fixup_dax; \
|
||||||
b,a,pt %xcc, fill_fixup_mna; \
|
b,a,pt %xcc, fill_fixup_mna; \
|
||||||
b,a,pt %xcc, fill_fixup;
|
b,a,pt %xcc, fill_fixup;
|
||||||
|
|
||||||
#define FILL_2_GENERIC_RTRAP \
|
#define FILL_2_GENERIC_RTRAP \
|
||||||
user_rtt_fill_32bit: \
|
user_rtt_fill_32bit: \
|
||||||
|
and %sp, 1, %g3; \
|
||||||
|
brnz,pn %g3, user_rtt_fill_64bit; \
|
||||||
srl %sp, 0, %sp; \
|
srl %sp, 0, %sp; \
|
||||||
lduwa [%sp + 0x00] %asi, %l0; \
|
lduwa [%sp + 0x00] %asi, %l0; \
|
||||||
lduwa [%sp + 0x04] %asi, %l1; \
|
lduwa [%sp + 0x04] %asi, %l1; \
|
||||||
@ -643,7 +651,7 @@ user_rtt_fill_32bit: \
|
|||||||
ba,pt %xcc, user_rtt_pre_restore; \
|
ba,pt %xcc, user_rtt_pre_restore; \
|
||||||
restored; \
|
restored; \
|
||||||
nop; nop; nop; nop; nop; \
|
nop; nop; nop; nop; nop; \
|
||||||
nop; nop; nop; nop; nop; \
|
nop; nop; nop; \
|
||||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||||
ba,a,pt %xcc, user_rtt_fill_fixup;
|
ba,a,pt %xcc, user_rtt_fill_fixup;
|
||||||
|
@ -405,8 +405,13 @@
|
|||||||
#define __NR_setns 337
|
#define __NR_setns 337
|
||||||
#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_kcmp 341
|
||||||
|
|
||||||
#define NR_syscalls 340
|
#define NR_syscalls 342
|
||||||
|
|
||||||
|
/* Bitmask values returned from kern_features system call. */
|
||||||
|
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001
|
||||||
|
|
||||||
#ifdef __32bit_syscall_numbers__
|
#ifdef __32bit_syscall_numbers__
|
||||||
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
|
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
|
||||||
|
@ -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 *);
|
||||||
|
@ -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 */
|
||||||
|
@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
|
|||||||
|
|
||||||
ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
|
ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
|
||||||
do {
|
do {
|
||||||
struct sparc_stackf32 *usf, sf;
|
|
||||||
unsigned long pc;
|
unsigned long pc;
|
||||||
|
|
||||||
|
if (thread32_stack_is_64bit(ufp)) {
|
||||||
|
struct sparc_stackf *usf, sf;
|
||||||
|
|
||||||
|
ufp += STACK_BIAS;
|
||||||
|
usf = (struct sparc_stackf *) ufp;
|
||||||
|
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
||||||
|
break;
|
||||||
|
pc = sf.callers_pc & 0xffffffff;
|
||||||
|
ufp = ((unsigned long) sf.fp) & 0xffffffff;
|
||||||
|
} else {
|
||||||
|
struct sparc_stackf32 *usf, sf;
|
||||||
usf = (struct sparc_stackf32 *) ufp;
|
usf = (struct sparc_stackf32 *) ufp;
|
||||||
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pc = sf.callers_pc;
|
pc = sf.callers_pc;
|
||||||
ufp = (unsigned long)sf.fp;
|
ufp = (unsigned long)sf.fp;
|
||||||
|
}
|
||||||
perf_callchain_store(entry, pc);
|
perf_callchain_store(entry, pc);
|
||||||
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
||||||
}
|
}
|
||||||
|
@ -452,13 +452,16 @@ void flush_thread(void)
|
|||||||
/* It's a bit more tricky when 64-bit tasks are involved... */
|
/* It's a bit more tricky when 64-bit tasks are involved... */
|
||||||
static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
|
static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
|
||||||
{
|
{
|
||||||
|
bool stack_64bit = test_thread_64bit_stack(psp);
|
||||||
unsigned long fp, distance, rval;
|
unsigned long fp, distance, rval;
|
||||||
|
|
||||||
if (!(test_thread_flag(TIF_32BIT))) {
|
if (stack_64bit) {
|
||||||
csp += STACK_BIAS;
|
csp += STACK_BIAS;
|
||||||
psp += STACK_BIAS;
|
psp += STACK_BIAS;
|
||||||
__get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
|
__get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
|
||||||
fp += STACK_BIAS;
|
fp += STACK_BIAS;
|
||||||
|
if (test_thread_flag(TIF_32BIT))
|
||||||
|
fp &= 0xffffffff;
|
||||||
} else
|
} else
|
||||||
__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
|
__get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
|
||||||
|
|
||||||
@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
|
|||||||
rval = (csp - distance);
|
rval = (csp - distance);
|
||||||
if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
|
if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
|
||||||
rval = 0;
|
rval = 0;
|
||||||
else if (test_thread_flag(TIF_32BIT)) {
|
else if (!stack_64bit) {
|
||||||
if (put_user(((u32)csp),
|
if (put_user(((u32)csp),
|
||||||
&(((struct reg_window32 __user *)rval)->ins[6])))
|
&(((struct reg_window32 __user *)rval)->ins[6])))
|
||||||
rval = 0;
|
rval = 0;
|
||||||
@ -507,18 +510,18 @@ void synchronize_user_stack(void)
|
|||||||
|
|
||||||
flush_user_windows();
|
flush_user_windows();
|
||||||
if ((window = get_thread_wsaved()) != 0) {
|
if ((window = get_thread_wsaved()) != 0) {
|
||||||
int winsize = sizeof(struct reg_window);
|
|
||||||
int bias = 0;
|
|
||||||
|
|
||||||
if (test_thread_flag(TIF_32BIT))
|
|
||||||
winsize = sizeof(struct reg_window32);
|
|
||||||
else
|
|
||||||
bias = STACK_BIAS;
|
|
||||||
|
|
||||||
window -= 1;
|
window -= 1;
|
||||||
do {
|
do {
|
||||||
unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
|
|
||||||
struct reg_window *rwin = &t->reg_window[window];
|
struct reg_window *rwin = &t->reg_window[window];
|
||||||
|
int winsize = sizeof(struct reg_window);
|
||||||
|
unsigned long sp;
|
||||||
|
|
||||||
|
sp = t->rwbuf_stkptrs[window];
|
||||||
|
|
||||||
|
if (test_thread_64bit_stack(sp))
|
||||||
|
sp += STACK_BIAS;
|
||||||
|
else
|
||||||
|
winsize = sizeof(struct reg_window32);
|
||||||
|
|
||||||
if (!copy_to_user((char __user *)sp, rwin, winsize)) {
|
if (!copy_to_user((char __user *)sp, rwin, winsize)) {
|
||||||
shift_window_buffer(window, get_thread_wsaved() - 1, t);
|
shift_window_buffer(window, get_thread_wsaved() - 1, t);
|
||||||
@ -544,13 +547,6 @@ void fault_in_user_windows(void)
|
|||||||
{
|
{
|
||||||
struct thread_info *t = current_thread_info();
|
struct thread_info *t = current_thread_info();
|
||||||
unsigned long window;
|
unsigned long window;
|
||||||
int winsize = sizeof(struct reg_window);
|
|
||||||
int bias = 0;
|
|
||||||
|
|
||||||
if (test_thread_flag(TIF_32BIT))
|
|
||||||
winsize = sizeof(struct reg_window32);
|
|
||||||
else
|
|
||||||
bias = STACK_BIAS;
|
|
||||||
|
|
||||||
flush_user_windows();
|
flush_user_windows();
|
||||||
window = get_thread_wsaved();
|
window = get_thread_wsaved();
|
||||||
@ -558,8 +554,16 @@ void fault_in_user_windows(void)
|
|||||||
if (likely(window != 0)) {
|
if (likely(window != 0)) {
|
||||||
window -= 1;
|
window -= 1;
|
||||||
do {
|
do {
|
||||||
unsigned long sp = (t->rwbuf_stkptrs[window] + bias);
|
|
||||||
struct reg_window *rwin = &t->reg_window[window];
|
struct reg_window *rwin = &t->reg_window[window];
|
||||||
|
int winsize = sizeof(struct reg_window);
|
||||||
|
unsigned long sp;
|
||||||
|
|
||||||
|
sp = t->rwbuf_stkptrs[window];
|
||||||
|
|
||||||
|
if (test_thread_64bit_stack(sp))
|
||||||
|
sp += STACK_BIAS;
|
||||||
|
else
|
||||||
|
winsize = sizeof(struct reg_window32);
|
||||||
|
|
||||||
if (unlikely(sp & 0x7UL))
|
if (unlikely(sp & 0x7UL))
|
||||||
stack_unaligned(sp);
|
stack_unaligned(sp);
|
||||||
|
@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target,
|
|||||||
{
|
{
|
||||||
unsigned long rw_addr = regs->u_regs[UREG_I6];
|
unsigned long rw_addr = regs->u_regs[UREG_I6];
|
||||||
|
|
||||||
if (test_tsk_thread_flag(current, TIF_32BIT)) {
|
if (!test_thread_64bit_stack(rw_addr)) {
|
||||||
struct reg_window32 win32;
|
struct reg_window32 win32;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target,
|
|||||||
{
|
{
|
||||||
unsigned long rw_addr = regs->u_regs[UREG_I6];
|
unsigned long rw_addr = regs->u_regs[UREG_I6];
|
||||||
|
|
||||||
if (test_tsk_thread_flag(current, TIF_32BIT)) {
|
if (!test_thread_64bit_stack(rw_addr)) {
|
||||||
struct reg_window32 win32;
|
struct reg_window32 win32;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -751,3 +751,8 @@ int kernel_execve(const char *filename,
|
|||||||
: "cc");
|
: "cc");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmlinkage long sys_kern_features(void)
|
||||||
|
{
|
||||||
|
return KERN_FEATURE_MIXED_MODE_STACK;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -86,6 +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, sys_kcmp
|
||||||
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
|
|
||||||
@ -163,3 +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, sys_kcmp
|
||||||
|
@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm)
|
|||||||
|
|
||||||
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value, fp;
|
||||||
|
|
||||||
if (reg < 16)
|
if (reg < 16)
|
||||||
return (!reg ? 0 : regs->u_regs[reg]);
|
return (!reg ? 0 : regs->u_regs[reg]);
|
||||||
|
|
||||||
|
fp = regs->u_regs[UREG_FP];
|
||||||
|
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
struct reg_window *win;
|
struct reg_window *win;
|
||||||
win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window *)(fp + STACK_BIAS);
|
||||||
value = win->locals[reg - 16];
|
value = win->locals[reg - 16];
|
||||||
} else if (test_thread_flag(TIF_32BIT)) {
|
} else if (!test_thread_64bit_stack(fp)) {
|
||||||
struct reg_window32 __user *win32;
|
struct reg_window32 __user *win32;
|
||||||
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
|
||||||
get_user(value, &win32->locals[reg - 16]);
|
get_user(value, &win32->locals[reg - 16]);
|
||||||
} else {
|
} else {
|
||||||
struct reg_window __user *win;
|
struct reg_window __user *win;
|
||||||
win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window __user *)(fp + STACK_BIAS);
|
||||||
get_user(value, &win->locals[reg - 16]);
|
get_user(value, &win->locals[reg - 16]);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
|||||||
|
|
||||||
static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
|
static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
unsigned long fp;
|
||||||
|
|
||||||
if (reg < 16)
|
if (reg < 16)
|
||||||
return ®s->u_regs[reg];
|
return ®s->u_regs[reg];
|
||||||
|
|
||||||
|
fp = regs->u_regs[UREG_FP];
|
||||||
|
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
struct reg_window *win;
|
struct reg_window *win;
|
||||||
win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window *)(fp + STACK_BIAS);
|
||||||
return &win->locals[reg - 16];
|
return &win->locals[reg - 16];
|
||||||
} else if (test_thread_flag(TIF_32BIT)) {
|
} else if (!test_thread_64bit_stack(fp)) {
|
||||||
struct reg_window32 *win32;
|
struct reg_window32 *win32;
|
||||||
win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 *)((unsigned long)((u32)fp));
|
||||||
return (unsigned long *)&win32->locals[reg - 16];
|
return (unsigned long *)&win32->locals[reg - 16];
|
||||||
} else {
|
} else {
|
||||||
struct reg_window *win;
|
struct reg_window *win;
|
||||||
win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window *)(fp + STACK_BIAS);
|
||||||
return &win->locals[reg - 16];
|
return &win->locals[reg - 16];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs)
|
|||||||
if (rd)
|
if (rd)
|
||||||
regs->u_regs[rd] = ret;
|
regs->u_regs[rd] = ret;
|
||||||
} else {
|
} else {
|
||||||
if (test_thread_flag(TIF_32BIT)) {
|
unsigned long fp = regs->u_regs[UREG_FP];
|
||||||
|
|
||||||
|
if (!test_thread_64bit_stack(fp)) {
|
||||||
struct reg_window32 __user *win32;
|
struct reg_window32 __user *win32;
|
||||||
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
|
||||||
put_user(ret, &win32->locals[rd - 16]);
|
put_user(ret, &win32->locals[rd - 16]);
|
||||||
} else {
|
} else {
|
||||||
struct reg_window __user *win;
|
struct reg_window __user *win;
|
||||||
win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window __user *)(fp + STACK_BIAS);
|
||||||
put_user(ret, &win->locals[rd - 16]);
|
put_user(ret, &win->locals[rd - 16]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs)
|
|||||||
reg[0] = 0;
|
reg[0] = 0;
|
||||||
if ((insn & 0x780000) == 0x180000)
|
if ((insn & 0x780000) == 0x180000)
|
||||||
reg[1] = 0;
|
reg[1] = 0;
|
||||||
} else if (test_thread_flag(TIF_32BIT)) {
|
} else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
|
||||||
put_user(0, (int __user *) reg);
|
put_user(0, (int __user *) reg);
|
||||||
if ((insn & 0x780000) == 0x180000)
|
if ((insn & 0x780000) == 0x180000)
|
||||||
put_user(0, ((int __user *) reg) + 1);
|
put_user(0, ((int __user *) reg) + 1);
|
||||||
|
@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
|
|||||||
|
|
||||||
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value, fp;
|
||||||
|
|
||||||
if (reg < 16)
|
if (reg < 16)
|
||||||
return (!reg ? 0 : regs->u_regs[reg]);
|
return (!reg ? 0 : regs->u_regs[reg]);
|
||||||
|
|
||||||
|
fp = regs->u_regs[UREG_FP];
|
||||||
|
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
struct reg_window *win;
|
struct reg_window *win;
|
||||||
win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window *)(fp + STACK_BIAS);
|
||||||
value = win->locals[reg - 16];
|
value = win->locals[reg - 16];
|
||||||
} else if (test_thread_flag(TIF_32BIT)) {
|
} else if (!test_thread_64bit_stack(fp)) {
|
||||||
struct reg_window32 __user *win32;
|
struct reg_window32 __user *win32;
|
||||||
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
|
||||||
get_user(value, &win32->locals[reg - 16]);
|
get_user(value, &win32->locals[reg - 16]);
|
||||||
} else {
|
} else {
|
||||||
struct reg_window __user *win;
|
struct reg_window __user *win;
|
||||||
win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window __user *)(fp + STACK_BIAS);
|
||||||
get_user(value, &win->locals[reg - 16]);
|
get_user(value, &win->locals[reg - 16]);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
|
|||||||
static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
|
static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
|
||||||
struct pt_regs *regs)
|
struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
unsigned long fp = regs->u_regs[UREG_FP];
|
||||||
|
|
||||||
BUG_ON(reg < 16);
|
BUG_ON(reg < 16);
|
||||||
BUG_ON(regs->tstate & TSTATE_PRIV);
|
BUG_ON(regs->tstate & TSTATE_PRIV);
|
||||||
|
|
||||||
if (test_thread_flag(TIF_32BIT)) {
|
if (!test_thread_64bit_stack(fp)) {
|
||||||
struct reg_window32 __user *win32;
|
struct reg_window32 __user *win32;
|
||||||
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
|
||||||
return (unsigned long __user *)&win32->locals[reg - 16];
|
return (unsigned long __user *)&win32->locals[reg - 16];
|
||||||
} else {
|
} else {
|
||||||
struct reg_window __user *win;
|
struct reg_window __user *win;
|
||||||
win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
|
win = (struct reg_window __user *)(fp + STACK_BIAS);
|
||||||
return &win->locals[reg - 16];
|
return &win->locals[reg - 16];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd)
|
|||||||
} else {
|
} else {
|
||||||
unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
|
unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
|
||||||
|
|
||||||
if (test_thread_flag(TIF_32BIT))
|
if (!test_thread_64bit_stack(regs->u_regs[UREG_FP]))
|
||||||
__put_user((u32)val, (u32 __user *)rd_user);
|
__put_user((u32)val, (u32 __user *)rd_user);
|
||||||
else
|
else
|
||||||
__put_user(val, rd_user);
|
__put_user(val, rd_user);
|
||||||
|
@ -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);
|
||||||
|
@ -43,6 +43,8 @@ spill_fixup_mna:
|
|||||||
spill_fixup_dax:
|
spill_fixup_dax:
|
||||||
TRAP_LOAD_THREAD_REG(%g6, %g1)
|
TRAP_LOAD_THREAD_REG(%g6, %g1)
|
||||||
ldx [%g6 + TI_FLAGS], %g1
|
ldx [%g6 + TI_FLAGS], %g1
|
||||||
|
andcc %sp, 0x1, %g0
|
||||||
|
movne %icc, 0, %g1
|
||||||
andcc %g1, _TIF_32BIT, %g0
|
andcc %g1, _TIF_32BIT, %g0
|
||||||
ldub [%g6 + TI_WSAVED], %g1
|
ldub [%g6 + TI_WSAVED], %g1
|
||||||
sll %g1, 3, %g3
|
sll %g1, 3, %g3
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap)
|
|||||||
XR = 0;
|
XR = 0;
|
||||||
else if (freg < 16)
|
else if (freg < 16)
|
||||||
XR = regs->u_regs[freg];
|
XR = regs->u_regs[freg];
|
||||||
else if (test_thread_flag(TIF_32BIT)) {
|
else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) {
|
||||||
struct reg_window32 __user *win32;
|
struct reg_window32 __user *win32;
|
||||||
flushw_user ();
|
flushw_user ();
|
||||||
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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 (!retcode) {
|
|
||||||
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
|
|
||||||
if (!dev->open_count++)
|
if (!dev->open_count++)
|
||||||
retcode = drm_setup(dev);
|
need_setup = 1;
|
||||||
}
|
|
||||||
if (!retcode) {
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
if (dev->dev_mapping == NULL)
|
old_mapping = dev->dev_mapping;
|
||||||
|
if (old_mapping == NULL)
|
||||||
dev->dev_mapping = &inode->i_data;
|
dev->dev_mapping = &inode->i_data;
|
||||||
/* ihold ensures nobody can remove inode with our i_data */
|
/* ihold ensures nobody can remove inode with our i_data */
|
||||||
ihold(container_of(dev->dev_mapping, struct inode, i_data));
|
ihold(container_of(dev->dev_mapping, struct inode, i_data));
|
||||||
inode->i_mapping = dev->dev_mapping;
|
inode->i_mapping = dev->dev_mapping;
|
||||||
filp->f_mapping = dev->dev_mapping;
|
filp->f_mapping = dev->dev_mapping;
|
||||||
mutex_unlock(&dev->struct_mutex);
|
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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
if (nv_device(priv)->chipset == 0x50) {
|
||||||
nv_wr32(priv, 0x001704, chan->vblank.channel);
|
nv_wr32(priv, 0x001704, chan->vblank.channel);
|
||||||
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
|
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
|
||||||
|
bar->flush(bar);
|
||||||
if (nv_device(priv)->chipset == 0x50) {
|
|
||||||
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);
|
||||||
|
bar->flush(bar);
|
||||||
nv_wr32(priv, 0x06000c,
|
nv_wr32(priv, 0x06000c,
|
||||||
upper_32_bits(chan->vblank.offset));
|
upper_32_bits(chan->vblank.offset));
|
||||||
}
|
nv_wr32(priv, 0x060010,
|
||||||
nv_wr32(priv, 0x060010, chan->vblank.offset);
|
lower_32_bits(chan->vblank.offset));
|
||||||
nv_wr32(priv, 0x060014, chan->vblank.value);
|
nv_wr32(priv, 0x060014, chan->vblank.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -1696,8 +1696,7 @@ 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
|
||||||
@ -1715,10 +1714,20 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||||||
}
|
}
|
||||||
/* 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;
|
||||||
|
} else {
|
||||||
|
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");
|
DRM_ERROR("unable to allocate a PPLL\n");
|
||||||
return ATOM_PPLL_INVALID;
|
return ATOM_PPLL_INVALID;
|
||||||
} else {
|
} else {
|
||||||
@ -1726,7 +1735,6 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||||||
return radeon_crtc->crtc_id;
|
return radeon_crtc->crtc_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
|
void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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)
|
||||||
|
@ -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)) {
|
if (!IS_ERR(priv->clk)) {
|
||||||
clk_disable_unprepare(priv->clk);
|
clk_disable_unprepare(priv->clk);
|
||||||
clk_put(priv->clk);
|
clk_put(priv->clk);
|
||||||
}
|
}
|
||||||
devm_kfree(&pdev->dev, priv->clk);
|
return 0;
|
||||||
}
|
|
||||||
return sdhci_pltfm_unregister(pdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
|
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
|
#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,
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -1315,8 +1315,10 @@ 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 */
|
||||||
|
tuning_opcode =
|
||||||
|
mmc->card->type == MMC_TYPE_MMC ?
|
||||||
MMC_SEND_TUNING_BLOCK_HS200 :
|
MMC_SEND_TUNING_BLOCK_HS200 :
|
||||||
MMC_SEND_TUNING_BLOCK;
|
MMC_SEND_TUNING_BLOCK;
|
||||||
spin_unlock_irqrestore(&host->lock, flags);
|
spin_unlock_irqrestore(&host->lock, flags);
|
||||||
@ -1326,6 +1328,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||||||
/* 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))
|
||||||
sdhci_send_command(host, mrq->sbc);
|
sdhci_send_command(host, mrq->sbc);
|
||||||
@ -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,10 +2852,13 @@ 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) {
|
||||||
|
pr_info("%s: no vqmmc regulator found\n",
|
||||||
|
mmc_hostname(mmc));
|
||||||
host->vqmmc = NULL;
|
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);
|
||||||
else
|
else
|
||||||
@ -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) {
|
||||||
|
pr_info("%s: no vmmc regulator found\n",
|
||||||
|
mmc_hostname(mmc));
|
||||||
host->vmmc = NULL;
|
host->vmmc = NULL;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
regulator_enable(host->vmmc);
|
regulator_enable(host->vmmc);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user