mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
Merge tag 'v4.9.14' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidxu4-4.9.y
This is the 4.9.14 stable release
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 13
|
||||
SUBLEVEL = 14
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -148,6 +148,8 @@
|
||||
uart1: serial@f8020000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1_default>;
|
||||
atmel,use-dma-rx;
|
||||
atmel,use-dma-tx;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -110,6 +110,8 @@
|
||||
};
|
||||
|
||||
usart3: serial@fc00c000 {
|
||||
atmel,use-dma-rx;
|
||||
atmel,use-dma-tx;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -150,18 +150,12 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
* and iterate over the range.
|
||||
*/
|
||||
|
||||
bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
|
||||
|
||||
VM_BUG_ON(size & ~PAGE_MASK);
|
||||
|
||||
if (!need_flush && !icache_is_pipt())
|
||||
goto vipt_cache;
|
||||
|
||||
while (size) {
|
||||
void *va = kmap_atomic_pfn(pfn);
|
||||
|
||||
if (need_flush)
|
||||
kvm_flush_dcache_to_poc(va, PAGE_SIZE);
|
||||
kvm_flush_dcache_to_poc(va, PAGE_SIZE);
|
||||
|
||||
if (icache_is_pipt())
|
||||
__cpuc_coherent_user_range((unsigned long)va,
|
||||
@@ -173,7 +167,6 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
kunmap_atomic(va);
|
||||
}
|
||||
|
||||
vipt_cache:
|
||||
if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
|
||||
/* any kind of VIPT cache */
|
||||
__flush_icache_all();
|
||||
|
||||
@@ -241,8 +241,7 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
void *va = page_address(pfn_to_page(pfn));
|
||||
|
||||
if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached)
|
||||
kvm_flush_dcache_to_poc(va, size);
|
||||
kvm_flush_dcache_to_poc(va, size);
|
||||
|
||||
if (!icache_is_aliasing()) { /* PIPT */
|
||||
flush_icache_range((unsigned long)va,
|
||||
|
||||
@@ -653,15 +653,15 @@ static u64 __raw_read_system_reg(u32 sys_id)
|
||||
case SYS_ID_ISAR2_EL1: return read_cpuid(ID_ISAR2_EL1);
|
||||
case SYS_ID_ISAR3_EL1: return read_cpuid(ID_ISAR3_EL1);
|
||||
case SYS_ID_ISAR4_EL1: return read_cpuid(ID_ISAR4_EL1);
|
||||
case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR4_EL1);
|
||||
case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR5_EL1);
|
||||
case SYS_MVFR0_EL1: return read_cpuid(MVFR0_EL1);
|
||||
case SYS_MVFR1_EL1: return read_cpuid(MVFR1_EL1);
|
||||
case SYS_MVFR2_EL1: return read_cpuid(MVFR2_EL1);
|
||||
|
||||
case SYS_ID_AA64PFR0_EL1: return read_cpuid(ID_AA64PFR0_EL1);
|
||||
case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR0_EL1);
|
||||
case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR1_EL1);
|
||||
case SYS_ID_AA64DFR0_EL1: return read_cpuid(ID_AA64DFR0_EL1);
|
||||
case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR0_EL1);
|
||||
case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR1_EL1);
|
||||
case SYS_ID_AA64MMFR0_EL1: return read_cpuid(ID_AA64MMFR0_EL1);
|
||||
case SYS_ID_AA64MMFR1_EL1: return read_cpuid(ID_AA64MMFR1_EL1);
|
||||
case SYS_ID_AA64MMFR2_EL1: return read_cpuid(ID_AA64MMFR2_EL1);
|
||||
|
||||
@@ -352,6 +352,13 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t addr)
|
||||
{
|
||||
if (swiotlb)
|
||||
return swiotlb_dma_mapping_error(hwdev, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dma_map_ops swiotlb_dma_ops = {
|
||||
.alloc = __dma_alloc,
|
||||
.free = __dma_free,
|
||||
@@ -366,7 +373,7 @@ static struct dma_map_ops swiotlb_dma_ops = {
|
||||
.sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
|
||||
.sync_sg_for_device = __swiotlb_sync_sg_for_device,
|
||||
.dma_supported = __swiotlb_dma_supported,
|
||||
.mapping_error = swiotlb_dma_mapping_error,
|
||||
.mapping_error = __swiotlb_dma_mapping_error,
|
||||
};
|
||||
|
||||
static int __init atomic_pool_init(void)
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
.active_low = 1, \
|
||||
}
|
||||
|
||||
#define BCM47XX_GPIO_KEY_H(_gpio, _code) \
|
||||
{ \
|
||||
.code = _code, \
|
||||
.gpio = _gpio, \
|
||||
}
|
||||
|
||||
/* Asus */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
@@ -79,8 +85,8 @@ bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500w[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY_H(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
|
||||
@@ -208,18 +208,18 @@ EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
|
||||
ADD src, src, 16*NBYTES
|
||||
EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
|
||||
ADD dst, dst, 16*NBYTES
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
|
||||
EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
|
||||
EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
|
||||
EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
|
||||
EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
|
||||
EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
|
||||
@@ -383,6 +383,10 @@ done:
|
||||
nop
|
||||
END(memcpy)
|
||||
|
||||
l_exc_copy_rewind16:
|
||||
/* Rewind src and dst by 16*NBYTES for l_exc_copy */
|
||||
SUB src, src, 16*NBYTES
|
||||
SUB dst, dst, 16*NBYTES
|
||||
l_exc_copy:
|
||||
/*
|
||||
* Copy bytes from src until faulting load address (or until a
|
||||
|
||||
@@ -186,7 +186,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
|
||||
" daddu %0, %4 \n"
|
||||
" dsll32 $1, %0, 0 \n"
|
||||
" daddu %0, $1 \n"
|
||||
" sltu $1, %0, $1 \n"
|
||||
" dsra32 %0, %0, 0 \n"
|
||||
" addu %0, $1 \n"
|
||||
#endif
|
||||
" .set pop"
|
||||
: "=r" (sum)
|
||||
|
||||
@@ -195,11 +195,9 @@ struct mips_frame_info {
|
||||
#define J_TARGET(pc,target) \
|
||||
(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
|
||||
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction mmi;
|
||||
|
||||
/*
|
||||
* swsp ra,offset
|
||||
* swm16 reglist,offset(sp)
|
||||
@@ -209,29 +207,71 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is way more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
|
||||
mmi.mm16_r5_format.rt == 31) ||
|
||||
(mmi.mm16_m_format.opcode == mm_pool16c_op &&
|
||||
mmi.mm16_m_format.func == mm_swm16_op);
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
switch (ip->mm16_r5_format.opcode) {
|
||||
case mm_swsp16_op:
|
||||
if (ip->mm16_r5_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm16_r5_format.simmediate;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool16c_op:
|
||||
switch (ip->mm16_m_format.func) {
|
||||
case mm_swm16_op:
|
||||
*poff = ip->mm16_m_format.imm;
|
||||
*poff += 1 + ip->mm16_m_format.rlist;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mmi.halfword[0] = ip->halfword[1];
|
||||
mmi.halfword[1] = ip->halfword[0];
|
||||
return (mmi.mm_m_format.opcode == mm_pool32b_op &&
|
||||
mmi.mm_m_format.rd > 9 &&
|
||||
mmi.mm_m_format.base == 29 &&
|
||||
mmi.mm_m_format.func == mm_swm32_func) ||
|
||||
(mmi.i_format.opcode == mm_sw32_op &&
|
||||
mmi.i_format.rs == 29 &&
|
||||
mmi.i_format.rt == 31);
|
||||
|
||||
switch (ip->i_format.opcode) {
|
||||
case mm_sw32_op:
|
||||
if (ip->i_format.rs != 29)
|
||||
return 0;
|
||||
if (ip->i_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool32b_op:
|
||||
switch (ip->mm_m_format.func) {
|
||||
case mm_swm32_func:
|
||||
if (ip->mm_m_format.rd < 0x10)
|
||||
return 0;
|
||||
if (ip->mm_m_format.base != 29)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm_m_format.simmediate;
|
||||
*poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
|
||||
*poff /= sizeof(ulong);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* sw / sd $ra, offset($sp) */
|
||||
return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 &&
|
||||
ip->i_format.rt == 31;
|
||||
if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 && ip->i_format.rt == 31) {
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -246,13 +286,16 @@ static inline int is_jump_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is kind of more fun...
|
||||
*/
|
||||
union mips_instruction mmi;
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
|
||||
if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
|
||||
ip->j_format.opcode == mm_jal32_op)
|
||||
if (ip->j_format.opcode == mm_j32_op)
|
||||
return 1;
|
||||
if (ip->j_format.opcode == mm_jal32_op)
|
||||
return 1;
|
||||
if (ip->r_format.opcode != mm_pool32a_op ||
|
||||
ip->r_format.func != mm_pool32axf_op)
|
||||
@@ -280,15 +323,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is not more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
union mips_instruction mmi;
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(mmi.mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r5_format.rt == 29);
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(ip->mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r5_format.rt == 29);
|
||||
}
|
||||
|
||||
return ip->mm_i_format.opcode == mm_addiu32_op &&
|
||||
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
|
||||
#else
|
||||
@@ -303,30 +344,36 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
|
||||
static int get_frame_info(struct mips_frame_info *info)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction *ip = (void *) (((char *) info->func) - 1);
|
||||
#else
|
||||
union mips_instruction *ip = info->func;
|
||||
#endif
|
||||
unsigned max_insns = info->func_size / sizeof(union mips_instruction);
|
||||
unsigned i;
|
||||
bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
|
||||
union mips_instruction insn, *ip, *ip_end;
|
||||
const unsigned int max_insns = 128;
|
||||
unsigned int i;
|
||||
|
||||
info->pc_offset = -1;
|
||||
info->frame_size = 0;
|
||||
|
||||
ip = (void *)msk_isa16_mode((ulong)info->func);
|
||||
if (!ip)
|
||||
goto err;
|
||||
|
||||
if (max_insns == 0)
|
||||
max_insns = 128U; /* unknown function size */
|
||||
max_insns = min(128U, max_insns);
|
||||
ip_end = (void *)ip + info->func_size;
|
||||
|
||||
for (i = 0; i < max_insns; i++, ip++) {
|
||||
for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
|
||||
if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
|
||||
insn.halfword[0] = 0;
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else if (is_mmips) {
|
||||
insn.halfword[0] = ip->halfword[1];
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else {
|
||||
insn.word = ip->word;
|
||||
}
|
||||
|
||||
if (is_jump_ins(ip))
|
||||
if (is_jump_ins(&insn))
|
||||
break;
|
||||
|
||||
if (!info->frame_size) {
|
||||
if (is_sp_move_ins(ip))
|
||||
if (is_sp_move_ins(&insn))
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
if (mm_insn_16bit(ip->halfword[0]))
|
||||
@@ -349,11 +396,9 @@ static int get_frame_info(struct mips_frame_info *info)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
|
||||
info->pc_offset =
|
||||
ip->i_format.simmediate / sizeof(long);
|
||||
if (info->pc_offset == -1 &&
|
||||
is_ra_save_ins(&insn, &info->pc_offset))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info->frame_size && info->pc_offset >= 0) /* nested */
|
||||
return 0;
|
||||
|
||||
@@ -545,7 +545,7 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
|
||||
clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
|
||||
clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
|
||||
} else if (of_machine_is_compatible("lantiq,ar10")) {
|
||||
@@ -553,7 +553,7 @@ void __init ltq_soc_init(void)
|
||||
ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
|
||||
clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
|
||||
clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH |
|
||||
PMU_PPE_DP | PMU_PPE_TC);
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
|
||||
@@ -575,11 +575,11 @@ void __init ltq_soc_init(void)
|
||||
clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
|
||||
|
||||
clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
|
||||
clkdev_add_pmu("1e108000.eth", NULL, 0, 0,
|
||||
PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
|
||||
PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
|
||||
PMU_PPE_QSB | PMU_PPE_TOP);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
|
||||
clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY);
|
||||
clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
|
||||
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
|
||||
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
|
||||
|
||||
@@ -31,26 +31,40 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
".set\tpush\t\t\t# indy_sc_wipe\n\t"
|
||||
".set\tnoreorder\n\t"
|
||||
".set\tmips3\n\t"
|
||||
".set\tnoat\n\t"
|
||||
"mfc0\t%2, $12\n\t"
|
||||
"li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
|
||||
"mtc0\t$1, $12\n\t"
|
||||
|
||||
"dli\t$1, 0x9000000080000000\n\t"
|
||||
"or\t%0, $1\t\t\t# first line to flush\n\t"
|
||||
"or\t%1, $1\t\t\t# last line to flush\n\t"
|
||||
".set\tat\n\t"
|
||||
|
||||
"1:\tsw\t$0, 0(%0)\n\t"
|
||||
"bne\t%0, %1, 1b\n\t"
|
||||
" daddu\t%0, 32\n\t"
|
||||
|
||||
"mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
|
||||
"nop; nop; nop; nop;\n\t"
|
||||
".set\tpop"
|
||||
" .set push # indy_sc_wipe \n"
|
||||
" .set noreorder \n"
|
||||
" .set mips3 \n"
|
||||
" .set noat \n"
|
||||
" mfc0 %2, $12 \n"
|
||||
" li $1, 0x80 # Go 64 bit \n"
|
||||
" mtc0 $1, $12 \n"
|
||||
" \n"
|
||||
" # \n"
|
||||
" # Open code a dli $1, 0x9000000080000000 \n"
|
||||
" # \n"
|
||||
" # Required because binutils 2.25 will happily accept \n"
|
||||
" # 64 bit instructions in .set mips3 mode but puke on \n"
|
||||
" # 64 bit constants when generating 32 bit ELF \n"
|
||||
" # \n"
|
||||
" lui $1,0x9000 \n"
|
||||
" dsll $1,$1,0x10 \n"
|
||||
" ori $1,$1,0x8000 \n"
|
||||
" dsll $1,$1,0x10 \n"
|
||||
" \n"
|
||||
" or %0, $1 # first line to flush \n"
|
||||
" or %1, $1 # last line to flush \n"
|
||||
" .set at \n"
|
||||
" \n"
|
||||
"1: sw $0, 0(%0) \n"
|
||||
" bne %0, %1, 1b \n"
|
||||
" daddu %0, 32 \n"
|
||||
" \n"
|
||||
" mtc0 %2, $12 # Back to 32 bit \n"
|
||||
" nop # pipeline hazard \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" .set pop \n"
|
||||
: "=r" (first), "=r" (last), "=&r" (tmp)
|
||||
: "0" (first), "1" (last));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# Joshua Henderson, <joshua.henderson@microchip.com>
|
||||
# Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
|
||||
#
|
||||
obj-y := init.o time.o config.o
|
||||
obj-y := config.o early_clk.o init.o time.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_console.o \
|
||||
early_pin.o \
|
||||
early_clk.o
|
||||
early_pin.o
|
||||
|
||||
@@ -136,6 +136,7 @@ enum {
|
||||
MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
|
||||
MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
|
||||
MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
|
||||
MMU_FTR_KERNEL_RO |
|
||||
#ifdef CONFIG_PPC_RADIX_MMU
|
||||
MMU_FTR_TYPE_RADIX |
|
||||
#endif
|
||||
|
||||
@@ -100,6 +100,8 @@ _GLOBAL(__setup_cpu_power9)
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
||||
andc r3, r3, r4
|
||||
bl __init_LPCR
|
||||
bl __init_HFSCR
|
||||
bl __init_tlb_power9
|
||||
@@ -120,6 +122,8 @@ _GLOBAL(__restore_cpu_power9)
|
||||
mfspr r3,SPRN_LPCR
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
|
||||
or r3, r3, r4
|
||||
LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
|
||||
andc r3, r3, r4
|
||||
bl __init_LPCR
|
||||
bl __init_HFSCR
|
||||
bl __init_tlb_power9
|
||||
|
||||
@@ -228,8 +228,10 @@ int hw_breakpoint_handler(struct die_args *args)
|
||||
rcu_read_lock();
|
||||
|
||||
bp = __this_cpu_read(bp_per_reg);
|
||||
if (!bp)
|
||||
if (!bp) {
|
||||
rc = NOTIFY_DONE;
|
||||
goto out;
|
||||
}
|
||||
info = counter_arch_bp(bp);
|
||||
|
||||
/*
|
||||
|
||||
@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
|
||||
static inline
|
||||
bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
|
||||
{
|
||||
/*
|
||||
* "Allocated" pkeys are those that have been returned
|
||||
* from pkey_alloc(). pkey 0 is special, and never
|
||||
* returned from pkey_alloc().
|
||||
*/
|
||||
if (pkey <= 0)
|
||||
return false;
|
||||
if (pkey >= arch_max_pkey())
|
||||
return false;
|
||||
return mm_pkey_allocation_map(mm) & (1U << pkey);
|
||||
}
|
||||
|
||||
@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
|
||||
static inline
|
||||
int mm_pkey_free(struct mm_struct *mm, int pkey)
|
||||
{
|
||||
/*
|
||||
* pkey 0 is special, always allocated and can never
|
||||
* be freed.
|
||||
*/
|
||||
if (!pkey)
|
||||
return -EINVAL;
|
||||
if (!mm_pkey_is_allocated(mm, pkey))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -22813,7 +22813,7 @@ static struct aead_testvec aes_ccm_enc_tv_template[] = {
|
||||
"\x09\x75\x9a\x9b\x3c\x9b\x27\x39",
|
||||
.klen = 32,
|
||||
.iv = "\x03\xf9\xd9\x4e\x63\xb5\x3d\x9d"
|
||||
"\x43\xf6\x1e\x50",
|
||||
"\x43\xf6\x1e\x50\0\0\0\0",
|
||||
.assoc = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
|
||||
"\x13\x02\x01\x0c\x83\x4c\x96\x35"
|
||||
"\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
|
||||
|
||||
@@ -633,8 +633,11 @@ static int bcma_device_probe(struct device *dev)
|
||||
drv);
|
||||
int err = 0;
|
||||
|
||||
get_device(dev);
|
||||
if (adrv->probe)
|
||||
err = adrv->probe(core);
|
||||
if (err)
|
||||
put_device(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -647,6 +650,7 @@ static int bcma_device_remove(struct device *dev)
|
||||
|
||||
if (adrv->remove)
|
||||
adrv->remove(core);
|
||||
put_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1097,9 +1097,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/* I/O need to be drained during transfer transition */
|
||||
blk_mq_freeze_queue(lo->lo_queue);
|
||||
|
||||
err = loop_release_xfer(lo);
|
||||
if (err)
|
||||
return err;
|
||||
goto exit;
|
||||
|
||||
if (info->lo_encrypt_type) {
|
||||
unsigned int type = info->lo_encrypt_type;
|
||||
@@ -1114,12 +1117,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
|
||||
err = loop_init_xfer(lo, xfer, info);
|
||||
if (err)
|
||||
return err;
|
||||
goto exit;
|
||||
|
||||
if (lo->lo_offset != info->lo_offset ||
|
||||
lo->lo_sizelimit != info->lo_sizelimit)
|
||||
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
|
||||
return -EFBIG;
|
||||
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
|
||||
err = -EFBIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
loop_config_discard(lo);
|
||||
|
||||
@@ -1137,13 +1142,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
(info->lo_flags & LO_FLAGS_AUTOCLEAR))
|
||||
lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
|
||||
|
||||
if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
|
||||
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
loop_reread_partitions(lo, lo->lo_device);
|
||||
}
|
||||
|
||||
lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
|
||||
lo->lo_init[0] = info->lo_init[0];
|
||||
lo->lo_init[1] = info->lo_init[1];
|
||||
@@ -1156,7 +1154,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
|
||||
/* update dio if lo_offset or transfer is changed */
|
||||
__loop_update_dio(lo, lo->use_dio);
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||
|
||||
if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
|
||||
!(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
|
||||
lo->lo_flags |= LO_FLAGS_PARTSCAN;
|
||||
lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
|
||||
loop_reread_partitions(lo, lo->lo_device);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -421,7 +421,7 @@ err_pnp:
|
||||
acpi_bus_unregister_driver(&tis_acpi_driver);
|
||||
err_acpi:
|
||||
#endif
|
||||
platform_device_unregister(force_pdev);
|
||||
platform_driver_unregister(&tis_drv);
|
||||
err_platform:
|
||||
if (force_pdev)
|
||||
platform_device_unregister(force_pdev);
|
||||
|
||||
@@ -130,7 +130,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
|
||||
* @devfreq: the devfreq instance
|
||||
* @freq: the update target frequency
|
||||
*/
|
||||
static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
{
|
||||
int lev, prev_lev, ret = 0;
|
||||
unsigned long cur_time;
|
||||
@@ -166,6 +166,7 @@ out:
|
||||
devfreq->last_stat_updated = cur_time;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(devfreq_update_status);
|
||||
|
||||
/**
|
||||
* find_devfreq_governor() - find devfreq governor from name
|
||||
@@ -939,6 +940,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
|
||||
if (df->governor == governor) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
} else if (df->governor->immutable || governor->immutable) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (df->governor) {
|
||||
@@ -968,13 +972,33 @@ static ssize_t available_governors_show(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct devfreq_governor *tmp_governor;
|
||||
struct devfreq *df = to_devfreq(d);
|
||||
ssize_t count = 0;
|
||||
|
||||
mutex_lock(&devfreq_list_lock);
|
||||
list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", tmp_governor->name);
|
||||
|
||||
/*
|
||||
* The devfreq with immutable governor (e.g., passive) shows
|
||||
* only own governor.
|
||||
*/
|
||||
if (df->governor->immutable) {
|
||||
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
|
||||
"%s ", df->governor_name);
|
||||
/*
|
||||
* The devfreq device shows the registered governor except for
|
||||
* immutable governors such as passive governor .
|
||||
*/
|
||||
} else {
|
||||
struct devfreq_governor *governor;
|
||||
|
||||
list_for_each_entry(governor, &devfreq_governor_list, node) {
|
||||
if (governor->immutable)
|
||||
continue;
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", governor->name);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
/* Truncate the trailing space */
|
||||
|
||||
@@ -38,4 +38,6 @@ extern void devfreq_interval_update(struct devfreq *devfreq,
|
||||
extern int devfreq_add_governor(struct devfreq_governor *governor);
|
||||
extern int devfreq_remove_governor(struct devfreq_governor *governor);
|
||||
|
||||
extern int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
|
||||
|
||||
#endif /* _GOVERNOR_H */
|
||||
|
||||
@@ -112,6 +112,11 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (devfreq->profile->freq_table
|
||||
&& (devfreq_update_status(devfreq, freq)))
|
||||
dev_err(&devfreq->dev,
|
||||
"Couldn't update frequency transition information.\n");
|
||||
|
||||
devfreq->previous_freq = freq;
|
||||
|
||||
out:
|
||||
@@ -179,6 +184,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
|
||||
|
||||
static struct devfreq_governor devfreq_passive = {
|
||||
.name = "passive",
|
||||
.immutable = 1,
|
||||
.get_target_freq = devfreq_passive_get_target_freq,
|
||||
.event_handler = devfreq_passive_event_handler,
|
||||
};
|
||||
|
||||
@@ -272,7 +272,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
|
||||
u32 status;
|
||||
int i, line;
|
||||
|
||||
for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
|
||||
for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
|
||||
struct ipu_irq_bank *bank = irq_bank + i;
|
||||
|
||||
raw_spin_lock(&bank_lock);
|
||||
|
||||
@@ -157,6 +157,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
}
|
||||
|
||||
init_completion(&open_info->waitevent);
|
||||
open_info->waiting_channel = newchannel;
|
||||
|
||||
open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
|
||||
open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
|
||||
@@ -181,7 +182,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel));
|
||||
sizeof(struct vmbus_channel_open_channel), true);
|
||||
|
||||
if (ret != 0) {
|
||||
err = ret;
|
||||
@@ -194,6 +195,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
if (newchannel->rescind) {
|
||||
err = -ENODEV;
|
||||
goto error_free_gpadl;
|
||||
}
|
||||
|
||||
if (open_info->response.open_result.status) {
|
||||
err = -EAGAIN;
|
||||
goto error_free_gpadl;
|
||||
@@ -233,7 +239,7 @@ int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
|
||||
conn_msg.guest_endpoint_id = *shv_guest_servie_id;
|
||||
conn_msg.host_service_id = *shv_host_servie_id;
|
||||
|
||||
return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
|
||||
return vmbus_post_msg(&conn_msg, sizeof(conn_msg), true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
|
||||
|
||||
@@ -405,6 +411,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
return ret;
|
||||
|
||||
init_completion(&msginfo->waitevent);
|
||||
msginfo->waiting_channel = channel;
|
||||
|
||||
gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
|
||||
gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
|
||||
@@ -419,7 +426,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
|
||||
sizeof(*msginfo));
|
||||
sizeof(*msginfo), true);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
@@ -433,14 +440,19 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
gpadl_body->gpadl = next_gpadl_handle;
|
||||
|
||||
ret = vmbus_post_msg(gpadl_body,
|
||||
submsginfo->msgsize -
|
||||
sizeof(*submsginfo));
|
||||
submsginfo->msgsize - sizeof(*submsginfo),
|
||||
true);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
}
|
||||
wait_for_completion(&msginfo->waitevent);
|
||||
|
||||
if (channel->rescind) {
|
||||
ret = -ENODEV;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* At this point, we received the gpadl created msg */
|
||||
*gpadl_handle = gpadlmsg->gpadl;
|
||||
|
||||
@@ -474,6 +486,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
|
||||
return -ENOMEM;
|
||||
|
||||
init_completion(&info->waitevent);
|
||||
info->waiting_channel = channel;
|
||||
|
||||
msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
|
||||
|
||||
@@ -485,14 +498,19 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
|
||||
list_add_tail(&info->msglistentry,
|
||||
&vmbus_connection.chn_msg_list);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
ret = vmbus_post_msg(msg,
|
||||
sizeof(struct vmbus_channel_gpadl_teardown));
|
||||
ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown),
|
||||
true);
|
||||
|
||||
if (ret)
|
||||
goto post_msg_err;
|
||||
|
||||
wait_for_completion(&info->waitevent);
|
||||
|
||||
if (channel->rescind) {
|
||||
ret = -ENODEV;
|
||||
goto post_msg_err;
|
||||
}
|
||||
|
||||
post_msg_err:
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&info->msglistentry);
|
||||
@@ -557,7 +575,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
|
||||
msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
|
||||
msg->child_relid = channel->offermsg.child_relid;
|
||||
|
||||
ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
|
||||
ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel),
|
||||
true);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Close failed: close post msg return is %d\n", ret);
|
||||
|
||||
@@ -147,6 +147,29 @@ static const struct {
|
||||
{ HV_RDV_GUID },
|
||||
};
|
||||
|
||||
/*
|
||||
* The rescinded channel may be blocked waiting for a response from the host;
|
||||
* take care of that.
|
||||
*/
|
||||
static void vmbus_rescind_cleanup(struct vmbus_channel *channel)
|
||||
{
|
||||
struct vmbus_channel_msginfo *msginfo;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
|
||||
msglistentry) {
|
||||
|
||||
if (msginfo->waiting_channel == channel) {
|
||||
complete(&msginfo->waitevent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
}
|
||||
|
||||
static bool is_unsupported_vmbus_devs(const uuid_le *guid)
|
||||
{
|
||||
int i;
|
||||
@@ -321,7 +344,8 @@ static void vmbus_release_relid(u32 relid)
|
||||
memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
|
||||
msg.child_relid = relid;
|
||||
msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
|
||||
vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
|
||||
vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released),
|
||||
true);
|
||||
}
|
||||
|
||||
void hv_event_tasklet_disable(struct vmbus_channel *channel)
|
||||
@@ -728,7 +752,8 @@ void vmbus_initiate_unload(bool crash)
|
||||
init_completion(&vmbus_connection.unload_event);
|
||||
memset(&hdr, 0, sizeof(struct vmbus_channel_message_header));
|
||||
hdr.msgtype = CHANNELMSG_UNLOAD;
|
||||
vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
|
||||
vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header),
|
||||
!crash);
|
||||
|
||||
/*
|
||||
* vmbus_initiate_unload() is also called on crash and the crash can be
|
||||
@@ -823,6 +848,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
|
||||
channel->rescind = true;
|
||||
spin_unlock_irqrestore(&channel->lock, flags);
|
||||
|
||||
vmbus_rescind_cleanup(channel);
|
||||
|
||||
if (channel->device_obj) {
|
||||
if (channel->chn_rescind_callback) {
|
||||
channel->chn_rescind_callback(channel);
|
||||
@@ -1116,8 +1143,8 @@ int vmbus_request_offers(void)
|
||||
msg->msgtype = CHANNELMSG_REQUESTOFFERS;
|
||||
|
||||
|
||||
ret = vmbus_post_msg(msg,
|
||||
sizeof(struct vmbus_channel_message_header));
|
||||
ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header),
|
||||
true);
|
||||
if (ret != 0) {
|
||||
pr_err("Unable to request offers - %d\n", ret);
|
||||
|
||||
|
||||
@@ -110,7 +110,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
ret = vmbus_post_msg(msg,
|
||||
sizeof(struct vmbus_channel_initiate_contact));
|
||||
sizeof(struct vmbus_channel_initiate_contact),
|
||||
true);
|
||||
if (ret != 0) {
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&msginfo->msglistentry);
|
||||
@@ -434,7 +435,7 @@ void vmbus_on_event(unsigned long data)
|
||||
/*
|
||||
* vmbus_post_msg - Send a msg on the vmbus's message connection
|
||||
*/
|
||||
int vmbus_post_msg(void *buffer, size_t buflen)
|
||||
int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
|
||||
{
|
||||
union hv_connection_id conn_id;
|
||||
int ret = 0;
|
||||
@@ -449,7 +450,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
|
||||
* insufficient resources. Retry the operation a couple of
|
||||
* times before giving up.
|
||||
*/
|
||||
while (retries < 20) {
|
||||
while (retries < 100) {
|
||||
ret = hv_post_message(conn_id, 1, buffer, buflen);
|
||||
|
||||
switch (ret) {
|
||||
@@ -472,8 +473,14 @@ int vmbus_post_msg(void *buffer, size_t buflen)
|
||||
}
|
||||
|
||||
retries++;
|
||||
udelay(usec);
|
||||
if (usec < 2048)
|
||||
if (can_sleep && usec > 1000)
|
||||
msleep(usec / 1000);
|
||||
else if (usec < MAX_UDELAY_MS * 1000)
|
||||
udelay(usec);
|
||||
else
|
||||
mdelay(usec / 1000);
|
||||
|
||||
if (usec < 256000)
|
||||
usec *= 2;
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -309,9 +309,10 @@ void hv_cleanup(bool crash)
|
||||
|
||||
hypercall_msr.as_uint64 = 0;
|
||||
wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
|
||||
if (!crash)
|
||||
if (!crash) {
|
||||
vfree(hv_context.tsc_page);
|
||||
hv_context.tsc_page = NULL;
|
||||
hv_context.tsc_page = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -411,7 +412,7 @@ int hv_synic_alloc(void)
|
||||
goto err;
|
||||
}
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
for_each_present_cpu(cpu) {
|
||||
hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
|
||||
if (hv_context.event_dpc[cpu] == NULL) {
|
||||
pr_err("Unable to allocate event dpc\n");
|
||||
@@ -457,6 +458,8 @@ int hv_synic_alloc(void)
|
||||
pr_err("Unable to allocate post msg page\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -482,7 +485,7 @@ void hv_synic_free(void)
|
||||
int cpu;
|
||||
|
||||
kfree(hv_context.hv_numa_map);
|
||||
for_each_online_cpu(cpu)
|
||||
for_each_present_cpu(cpu)
|
||||
hv_synic_free_cpu(cpu);
|
||||
}
|
||||
|
||||
@@ -552,8 +555,6 @@ void hv_synic_init(void *arg)
|
||||
rdmsrl(HV_X64_MSR_VP_INDEX, vp_index);
|
||||
hv_context.vp_index[cpu] = (u32)vp_index;
|
||||
|
||||
INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
|
||||
|
||||
/*
|
||||
* Register the per-cpu clockevent source.
|
||||
*/
|
||||
|
||||
@@ -61,6 +61,7 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data);
|
||||
static const char fcopy_devname[] = "vmbus/hv_fcopy";
|
||||
static u8 *recv_buffer;
|
||||
static struct hvutil_transport *hvt;
|
||||
static struct completion release_event;
|
||||
/*
|
||||
* This state maintains the version number registered by the daemon.
|
||||
*/
|
||||
@@ -317,6 +318,7 @@ static void fcopy_on_reset(void)
|
||||
|
||||
if (cancel_delayed_work_sync(&fcopy_timeout_work))
|
||||
fcopy_respond_to_host(HV_E_FAIL);
|
||||
complete(&release_event);
|
||||
}
|
||||
|
||||
int hv_fcopy_init(struct hv_util_service *srv)
|
||||
@@ -324,6 +326,7 @@ int hv_fcopy_init(struct hv_util_service *srv)
|
||||
recv_buffer = srv->recv_buffer;
|
||||
fcopy_transaction.recv_channel = srv->channel;
|
||||
|
||||
init_completion(&release_event);
|
||||
/*
|
||||
* When this driver loads, the user level daemon that
|
||||
* processes the host requests may not yet be running.
|
||||
@@ -345,4 +348,5 @@ void hv_fcopy_deinit(void)
|
||||
fcopy_transaction.state = HVUTIL_DEVICE_DYING;
|
||||
cancel_delayed_work_sync(&fcopy_timeout_work);
|
||||
hvutil_transport_destroy(hvt);
|
||||
wait_for_completion(&release_event);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
|
||||
static const char kvp_devname[] = "vmbus/hv_kvp";
|
||||
static u8 *recv_buffer;
|
||||
static struct hvutil_transport *hvt;
|
||||
static struct completion release_event;
|
||||
/*
|
||||
* Register the kernel component with the user-level daemon.
|
||||
* As part of this registration, pass the LIC version number.
|
||||
@@ -716,6 +717,7 @@ static void kvp_on_reset(void)
|
||||
if (cancel_delayed_work_sync(&kvp_timeout_work))
|
||||
kvp_respond_to_host(NULL, HV_E_FAIL);
|
||||
kvp_transaction.state = HVUTIL_DEVICE_INIT;
|
||||
complete(&release_event);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -724,6 +726,7 @@ hv_kvp_init(struct hv_util_service *srv)
|
||||
recv_buffer = srv->recv_buffer;
|
||||
kvp_transaction.recv_channel = srv->channel;
|
||||
|
||||
init_completion(&release_event);
|
||||
/*
|
||||
* When this driver loads, the user level daemon that
|
||||
* processes the host requests may not yet be running.
|
||||
@@ -747,4 +750,5 @@ void hv_kvp_deinit(void)
|
||||
cancel_delayed_work_sync(&kvp_timeout_work);
|
||||
cancel_work_sync(&kvp_sendkey_work);
|
||||
hvutil_transport_destroy(hvt);
|
||||
wait_for_completion(&release_event);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ static int dm_reg_value;
|
||||
static const char vss_devname[] = "vmbus/hv_vss";
|
||||
static __u8 *recv_buffer;
|
||||
static struct hvutil_transport *hvt;
|
||||
static struct completion release_event;
|
||||
|
||||
static void vss_timeout_func(struct work_struct *dummy);
|
||||
static void vss_handle_request(struct work_struct *dummy);
|
||||
@@ -330,11 +331,13 @@ static void vss_on_reset(void)
|
||||
if (cancel_delayed_work_sync(&vss_timeout_work))
|
||||
vss_respond_to_host(HV_E_FAIL);
|
||||
vss_transaction.state = HVUTIL_DEVICE_INIT;
|
||||
complete(&release_event);
|
||||
}
|
||||
|
||||
int
|
||||
hv_vss_init(struct hv_util_service *srv)
|
||||
{
|
||||
init_completion(&release_event);
|
||||
if (vmbus_proto_version < VERSION_WIN8_1) {
|
||||
pr_warn("Integration service 'Backup (volume snapshot)'"
|
||||
" not supported on this host version.\n");
|
||||
@@ -365,4 +368,5 @@ void hv_vss_deinit(void)
|
||||
cancel_delayed_work_sync(&vss_timeout_work);
|
||||
cancel_work_sync(&vss_handle_request_work);
|
||||
hvutil_transport_destroy(hvt);
|
||||
wait_for_completion(&release_event);
|
||||
}
|
||||
|
||||
@@ -683,7 +683,7 @@ void vmbus_free_channels(void);
|
||||
int vmbus_connect(void);
|
||||
void vmbus_disconnect(void);
|
||||
|
||||
int vmbus_post_msg(void *buffer, size_t buflen);
|
||||
int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep);
|
||||
|
||||
void vmbus_on_event(unsigned long data);
|
||||
void vmbus_on_msg_dpc(unsigned long data);
|
||||
|
||||
@@ -298,6 +298,9 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
|
||||
unsigned long flags = 0;
|
||||
struct hv_ring_buffer_info *outring_info = &channel->outbound;
|
||||
|
||||
if (channel->rescind)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < kv_count; i++)
|
||||
totalbytes_towrite += kv_list[i].iov_len;
|
||||
|
||||
@@ -350,6 +353,10 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
|
||||
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
|
||||
hv_signal_on_write(old_write, channel, kick_q);
|
||||
|
||||
if (channel->rescind)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1300,25 +1300,35 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
|
||||
it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
|
||||
data->fan_main_ctrl);
|
||||
} else {
|
||||
u8 ctrl;
|
||||
|
||||
/* No on/off mode, set maximum pwm value */
|
||||
data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
|
||||
it87_write_value(data, IT87_REG_PWM_DUTY[nr],
|
||||
data->pwm_duty[nr]);
|
||||
/* and set manual mode */
|
||||
data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
|
||||
data->pwm_temp_map[nr] :
|
||||
data->pwm_duty[nr];
|
||||
it87_write_value(data, IT87_REG_PWM[nr],
|
||||
data->pwm_ctrl[nr]);
|
||||
if (has_newer_autopwm(data)) {
|
||||
ctrl = (data->pwm_ctrl[nr] & 0x7c) |
|
||||
data->pwm_temp_map[nr];
|
||||
} else {
|
||||
ctrl = data->pwm_duty[nr];
|
||||
}
|
||||
data->pwm_ctrl[nr] = ctrl;
|
||||
it87_write_value(data, IT87_REG_PWM[nr], ctrl);
|
||||
}
|
||||
} else {
|
||||
if (val == 1) /* Manual mode */
|
||||
data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
|
||||
data->pwm_temp_map[nr] :
|
||||
data->pwm_duty[nr];
|
||||
else /* Automatic mode */
|
||||
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
|
||||
it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
|
||||
u8 ctrl;
|
||||
|
||||
if (has_newer_autopwm(data)) {
|
||||
ctrl = (data->pwm_ctrl[nr] & 0x7c) |
|
||||
data->pwm_temp_map[nr];
|
||||
if (val != 1)
|
||||
ctrl |= 0x80;
|
||||
} else {
|
||||
ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
|
||||
}
|
||||
data->pwm_ctrl[nr] = ctrl;
|
||||
it87_write_value(data, IT87_REG_PWM[nr], ctrl);
|
||||
|
||||
if (data->type != it8603 && nr < 3) {
|
||||
/* set SmartGuardian mode */
|
||||
@@ -1344,6 +1354,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
it87_update_pwm_ctrl(data, nr);
|
||||
if (has_newer_autopwm(data)) {
|
||||
/*
|
||||
* If we are in automatic mode, the PWM duty cycle register
|
||||
@@ -1456,13 +1467,15 @@ static ssize_t set_pwm_temp_map(struct device *dev,
|
||||
}
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
it87_update_pwm_ctrl(data, nr);
|
||||
data->pwm_temp_map[nr] = reg;
|
||||
/*
|
||||
* If we are in automatic mode, write the temp mapping immediately;
|
||||
* otherwise, just store it for later use.
|
||||
*/
|
||||
if (data->pwm_ctrl[nr] & 0x80) {
|
||||
data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
|
||||
data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
|
||||
data->pwm_temp_map[nr];
|
||||
it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
|
||||
}
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
@@ -356,7 +356,7 @@ static void stm_generic_unlink(struct stm_data *stm_data,
|
||||
if (!drvdata || !drvdata->csdev)
|
||||
return;
|
||||
|
||||
stm_disable(drvdata->csdev, NULL);
|
||||
coresight_disable(drvdata->csdev);
|
||||
}
|
||||
|
||||
static phys_addr_t
|
||||
|
||||
@@ -137,6 +137,7 @@ static const struct iio_chan_spec mpl115_channels[] = {
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
.info_mask_shared_by_type =
|
||||
BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -182,7 +182,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
|
||||
{
|
||||
.type = IIO_PRESSURE,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 'u',
|
||||
@@ -195,7 +195,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
||||
.scan_index = 1,
|
||||
.scan_type = {
|
||||
.sign = 's',
|
||||
|
||||
@@ -3540,6 +3540,9 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
|
||||
struct iw_cm_conn_param iw_param;
|
||||
int ret;
|
||||
|
||||
if (!conn_param)
|
||||
return -EINVAL;
|
||||
|
||||
ret = cma_modify_qp_rtr(id_priv, conn_param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -3325,13 +3325,14 @@ static int __init init_dmars(void)
|
||||
iommu_identity_mapping |= IDENTMAP_GFX;
|
||||
#endif
|
||||
|
||||
check_tylersburg_isoch();
|
||||
|
||||
if (iommu_identity_mapping) {
|
||||
ret = si_domain_init(hw_pass_through);
|
||||
if (ret)
|
||||
goto free_iommu;
|
||||
}
|
||||
|
||||
check_tylersburg_isoch();
|
||||
|
||||
/*
|
||||
* If we copied translations from a previous kernel in the kdump
|
||||
|
||||
@@ -248,7 +248,7 @@ struct cache {
|
||||
/*
|
||||
* Fields for converting from sectors to blocks.
|
||||
*/
|
||||
uint32_t sectors_per_block;
|
||||
sector_t sectors_per_block;
|
||||
int sectors_per_block_shift;
|
||||
|
||||
spinlock_t lock;
|
||||
@@ -3546,11 +3546,11 @@ static void cache_status(struct dm_target *ti, status_type_t type,
|
||||
|
||||
residency = policy_residency(cache->policy);
|
||||
|
||||
DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %lu ",
|
||||
DMEMIT("%u %llu/%llu %llu %llu/%llu %u %u %u %u %u %u %lu ",
|
||||
(unsigned)DM_CACHE_METADATA_BLOCK_SIZE,
|
||||
(unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
|
||||
(unsigned long long)nr_blocks_metadata,
|
||||
cache->sectors_per_block,
|
||||
(unsigned long long)cache->sectors_per_block,
|
||||
(unsigned long long) from_cblock(residency),
|
||||
(unsigned long long) from_cblock(cache->cache_size),
|
||||
(unsigned) atomic_read(&cache->stats.read_hit),
|
||||
|
||||
@@ -3621,6 +3621,8 @@ static int raid_preresume(struct dm_target *ti)
|
||||
return r;
|
||||
}
|
||||
|
||||
#define RESUME_STAY_FROZEN_FLAGS (CTR_FLAG_DELTA_DISKS | CTR_FLAG_DATA_OFFSET)
|
||||
|
||||
static void raid_resume(struct dm_target *ti)
|
||||
{
|
||||
struct raid_set *rs = ti->private;
|
||||
@@ -3638,7 +3640,15 @@ static void raid_resume(struct dm_target *ti)
|
||||
mddev->ro = 0;
|
||||
mddev->in_sync = 0;
|
||||
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
/*
|
||||
* Keep the RAID set frozen if reshape/rebuild flags are set.
|
||||
* The RAID set is unfrozen once the next table load/resume,
|
||||
* which clears the reshape/rebuild flags, occurs.
|
||||
* This ensures that the constructor for the inactive table
|
||||
* retrieves an up-to-date reshape_position.
|
||||
*/
|
||||
if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
|
||||
if (mddev->suspended)
|
||||
mddev_resume(mddev);
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include <linux/module.h>
|
||||
|
||||
#define DM_MSG_PREFIX "multipath round-robin"
|
||||
#define RR_MIN_IO 1000
|
||||
#define RR_VERSION "1.1.0"
|
||||
#define RR_MIN_IO 1
|
||||
#define RR_VERSION "1.2.0"
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* Path-handling code, paths are held in lists
|
||||
@@ -47,44 +47,19 @@ struct selector {
|
||||
struct list_head valid_paths;
|
||||
struct list_head invalid_paths;
|
||||
spinlock_t lock;
|
||||
struct dm_path * __percpu *current_path;
|
||||
struct percpu_counter repeat_count;
|
||||
};
|
||||
|
||||
static void set_percpu_current_path(struct selector *s, struct dm_path *path)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu)
|
||||
*per_cpu_ptr(s->current_path, cpu) = path;
|
||||
}
|
||||
|
||||
static struct selector *alloc_selector(void)
|
||||
{
|
||||
struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&s->valid_paths);
|
||||
INIT_LIST_HEAD(&s->invalid_paths);
|
||||
spin_lock_init(&s->lock);
|
||||
|
||||
s->current_path = alloc_percpu(struct dm_path *);
|
||||
if (!s->current_path)
|
||||
goto out_current_path;
|
||||
set_percpu_current_path(s, NULL);
|
||||
|
||||
if (percpu_counter_init(&s->repeat_count, 0, GFP_KERNEL))
|
||||
goto out_repeat_count;
|
||||
if (s) {
|
||||
INIT_LIST_HEAD(&s->valid_paths);
|
||||
INIT_LIST_HEAD(&s->invalid_paths);
|
||||
spin_lock_init(&s->lock);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
out_repeat_count:
|
||||
free_percpu(s->current_path);
|
||||
out_current_path:
|
||||
kfree(s);
|
||||
return NULL;;
|
||||
}
|
||||
|
||||
static int rr_create(struct path_selector *ps, unsigned argc, char **argv)
|
||||
@@ -105,8 +80,6 @@ static void rr_destroy(struct path_selector *ps)
|
||||
|
||||
free_paths(&s->valid_paths);
|
||||
free_paths(&s->invalid_paths);
|
||||
free_percpu(s->current_path);
|
||||
percpu_counter_destroy(&s->repeat_count);
|
||||
kfree(s);
|
||||
ps->context = NULL;
|
||||
}
|
||||
@@ -157,6 +130,11 @@ static int rr_add_path(struct path_selector *ps, struct dm_path *path,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (repeat_count > 1) {
|
||||
DMWARN_LIMIT("repeat_count > 1 is deprecated, using 1 instead");
|
||||
repeat_count = 1;
|
||||
}
|
||||
|
||||
/* allocate the path */
|
||||
pi = kmalloc(sizeof(*pi), GFP_KERNEL);
|
||||
if (!pi) {
|
||||
@@ -183,9 +161,6 @@ static void rr_fail_path(struct path_selector *ps, struct dm_path *p)
|
||||
struct path_info *pi = p->pscontext;
|
||||
|
||||
spin_lock_irqsave(&s->lock, flags);
|
||||
if (p == *this_cpu_ptr(s->current_path))
|
||||
set_percpu_current_path(s, NULL);
|
||||
|
||||
list_move(&pi->list, &s->invalid_paths);
|
||||
spin_unlock_irqrestore(&s->lock, flags);
|
||||
}
|
||||
@@ -208,29 +183,15 @@ static struct dm_path *rr_select_path(struct path_selector *ps, size_t nr_bytes)
|
||||
unsigned long flags;
|
||||
struct selector *s = ps->context;
|
||||
struct path_info *pi = NULL;
|
||||
struct dm_path *current_path = NULL;
|
||||
|
||||
local_irq_save(flags);
|
||||
current_path = *this_cpu_ptr(s->current_path);
|
||||
if (current_path) {
|
||||
percpu_counter_dec(&s->repeat_count);
|
||||
if (percpu_counter_read_positive(&s->repeat_count) > 0) {
|
||||
local_irq_restore(flags);
|
||||
return current_path;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock(&s->lock);
|
||||
spin_lock_irqsave(&s->lock, flags);
|
||||
if (!list_empty(&s->valid_paths)) {
|
||||
pi = list_entry(s->valid_paths.next, struct path_info, list);
|
||||
list_move_tail(&pi->list, &s->valid_paths);
|
||||
percpu_counter_set(&s->repeat_count, pi->repeat_count);
|
||||
set_percpu_current_path(s, pi->path);
|
||||
current_path = pi->path;
|
||||
}
|
||||
spin_unlock_irqrestore(&s->lock, flags);
|
||||
|
||||
return current_path;
|
||||
return pi ? pi->path : NULL;
|
||||
}
|
||||
|
||||
static struct path_selector_type rr_ps = {
|
||||
|
||||
@@ -175,6 +175,7 @@ static void dm_stat_free(struct rcu_head *head)
|
||||
int cpu;
|
||||
struct dm_stat *s = container_of(head, struct dm_stat, rcu_head);
|
||||
|
||||
kfree(s->histogram_boundaries);
|
||||
kfree(s->program_id);
|
||||
kfree(s->aux_data);
|
||||
for_each_possible_cpu(cpu) {
|
||||
|
||||
@@ -52,18 +52,26 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
|
||||
return conf->disks + lo;
|
||||
}
|
||||
|
||||
/*
|
||||
* In linear_congested() conf->raid_disks is used as a copy of
|
||||
* mddev->raid_disks to iterate conf->disks[], because conf->raid_disks
|
||||
* and conf->disks[] are created in linear_conf(), they are always
|
||||
* consitent with each other, but mddev->raid_disks does not.
|
||||
*/
|
||||
static int linear_congested(struct mddev *mddev, int bits)
|
||||
{
|
||||
struct linear_conf *conf;
|
||||
int i, ret = 0;
|
||||
|
||||
conf = mddev->private;
|
||||
rcu_read_lock();
|
||||
conf = rcu_dereference(mddev->private);
|
||||
|
||||
for (i = 0; i < mddev->raid_disks && !ret ; i++) {
|
||||
for (i = 0; i < conf->raid_disks && !ret ; i++) {
|
||||
struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
|
||||
ret |= bdi_congested(&q->backing_dev_info, bits);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -143,6 +151,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
|
||||
conf->disks[i-1].end_sector +
|
||||
conf->disks[i].rdev->sectors;
|
||||
|
||||
/*
|
||||
* conf->raid_disks is copy of mddev->raid_disks. The reason to
|
||||
* keep a copy of mddev->raid_disks in struct linear_conf is,
|
||||
* mddev->raid_disks may not be consistent with pointers number of
|
||||
* conf->disks[] when it is updated in linear_add() and used to
|
||||
* iterate old conf->disks[] earray in linear_congested().
|
||||
* Here conf->raid_disks is always consitent with number of
|
||||
* pointers in conf->disks[] array, and mddev->private is updated
|
||||
* with rcu_assign_pointer() in linear_addr(), such race can be
|
||||
* avoided.
|
||||
*/
|
||||
conf->raid_disks = raid_disks;
|
||||
|
||||
return conf;
|
||||
|
||||
out:
|
||||
@@ -195,15 +216,23 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
|
||||
if (!newconf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* newconf->raid_disks already keeps a copy of * the increased
|
||||
* value of mddev->raid_disks, WARN_ONCE() is just used to make
|
||||
* sure of this. It is possible that oldconf is still referenced
|
||||
* in linear_congested(), therefore kfree_rcu() is used to free
|
||||
* oldconf until no one uses it anymore.
|
||||
*/
|
||||
mddev_suspend(mddev);
|
||||
oldconf = mddev->private;
|
||||
oldconf = rcu_dereference(mddev->private);
|
||||
mddev->raid_disks++;
|
||||
mddev->private = newconf;
|
||||
WARN_ONCE(mddev->raid_disks != newconf->raid_disks,
|
||||
"copied raid_disks doesn't match mddev->raid_disks");
|
||||
rcu_assign_pointer(mddev->private, newconf);
|
||||
md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
|
||||
set_capacity(mddev->gendisk, mddev->array_sectors);
|
||||
mddev_resume(mddev);
|
||||
revalidate_disk(mddev->gendisk);
|
||||
kfree(oldconf);
|
||||
kfree_rcu(oldconf, rcu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ struct linear_conf
|
||||
{
|
||||
struct rcu_head rcu;
|
||||
sector_t array_sectors;
|
||||
int raid_disks; /* a copy of mddev->raid_disks */
|
||||
struct dev_info disks[0];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -615,6 +615,7 @@ static int cxd2820r_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
priv->client[0] = client;
|
||||
priv->fe.demodulator_priv = priv;
|
||||
priv->i2c = client->adapter;
|
||||
priv->ts_mode = pdata->ts_mode;
|
||||
priv->ts_clk_inv = pdata->ts_clk_inv;
|
||||
@@ -697,7 +698,6 @@ static int cxd2820r_probe(struct i2c_client *client,
|
||||
memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops));
|
||||
if (!pdata->attach_in_use)
|
||||
priv->fe.ops.release = NULL;
|
||||
priv->fe.demodulator_priv = priv;
|
||||
i2c_set_clientdata(client, priv);
|
||||
|
||||
/* Setup callbacks */
|
||||
|
||||
@@ -130,7 +130,7 @@ static long media_device_enum_entities(struct media_device *mdev,
|
||||
* old range.
|
||||
*/
|
||||
if (ent->function < MEDIA_ENT_F_OLD_BASE ||
|
||||
ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) {
|
||||
ent->function > MEDIA_ENT_F_TUNER) {
|
||||
if (is_media_entity_v4l2_subdev(ent))
|
||||
entd->type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
|
||||
else if (ent->function != MEDIA_ENT_F_IO_V4L)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
config DVB_DM1105
|
||||
tristate "SDMC DM1105 based PCI cards"
|
||||
depends on DVB_CORE && PCI && I2C
|
||||
depends on DVB_CORE && PCI && I2C && I2C_ALGOBIT
|
||||
select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
|
||||
|
||||
@@ -1576,7 +1576,7 @@ static int vpfe_s_fmt(struct file *file, void *priv,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = vpfe_try_fmt(file, priv, &format);
|
||||
ret = __vpfe_get_format(vpfe, &format, &bpp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -589,7 +589,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
result = put_user(ir->d.features, (__u32 __user *)arg);
|
||||
break;
|
||||
case LIRC_GET_REC_MODE:
|
||||
if (LIRC_CAN_REC(ir->d.features)) {
|
||||
if (!LIRC_CAN_REC(ir->d.features)) {
|
||||
result = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
@@ -599,7 +599,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
(__u32 __user *)arg);
|
||||
break;
|
||||
case LIRC_SET_REC_MODE:
|
||||
if (LIRC_CAN_REC(ir->d.features)) {
|
||||
if (!LIRC_CAN_REC(ir->d.features)) {
|
||||
result = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -412,7 +412,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
||||
nextbuf = NULL;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
|
||||
buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
||||
buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
||||
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
|
||||
vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
|
||||
|
||||
|
||||
@@ -182,32 +182,36 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rets == -EBUSY &&
|
||||
!mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, file)) {
|
||||
rets = -ENOMEM;
|
||||
|
||||
again:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
if (wait_event_interruptible(cl->rx_wait,
|
||||
!list_empty(&cl->rd_completed) ||
|
||||
!mei_cl_is_connected(cl))) {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_lock(&dev->device_lock);
|
||||
|
||||
if (!mei_cl_is_connected(cl)) {
|
||||
rets = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
mutex_unlock(&dev->device_lock);
|
||||
cb = mei_cl_read_cb(cl, file);
|
||||
if (!cb) {
|
||||
/*
|
||||
* For amthif all the waiters are woken up,
|
||||
* but only fp with matching cb->fp get the cb,
|
||||
* the others have to return to wait on read.
|
||||
*/
|
||||
if (cl == &dev->iamthif_cl)
|
||||
goto again;
|
||||
|
||||
if (wait_event_interruptible(cl->rx_wait,
|
||||
(!list_empty(&cl->rd_completed)) ||
|
||||
(!mei_cl_is_connected(cl)))) {
|
||||
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->device_lock);
|
||||
if (!mei_cl_is_connected(cl)) {
|
||||
rets = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cb = mei_cl_read_cb(cl, file);
|
||||
} while (!cb);
|
||||
rets = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
copy_buffer:
|
||||
/* now copy the data to user space */
|
||||
|
||||
@@ -466,7 +466,10 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
||||
if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
|
||||
bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
|
||||
|
||||
if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) {
|
||||
err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL);
|
||||
if (err) {
|
||||
if (err == -EPROBE_DEFER)
|
||||
goto err_free;
|
||||
dev_warn(dev, "failed to setup card detect gpio\n");
|
||||
c->use_runtime_pm = false;
|
||||
}
|
||||
|
||||
@@ -258,9 +258,15 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
|
||||
int bufnum = nctrl->page & priv->bufnum_mask;
|
||||
int sector = bufnum * chip->ecc.steps;
|
||||
int sector_end = sector + chip->ecc.steps - 1;
|
||||
__be32 *eccstat_regs;
|
||||
|
||||
if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
|
||||
eccstat_regs = ifc->ifc_nand.v2_nand_eccstat;
|
||||
else
|
||||
eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
|
||||
|
||||
for (i = sector / 4; i <= sector_end / 4; i++)
|
||||
eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
|
||||
eccstat[i] = ifc_in32(&eccstat_regs[i]);
|
||||
|
||||
for (i = sector; i <= sector_end; i++) {
|
||||
errors = check_read_ecc(mtd, ctrl, eccstat, i);
|
||||
|
||||
@@ -908,10 +908,14 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
struct gs_usb *dev;
|
||||
int rc = -ENOMEM;
|
||||
unsigned int icount, i;
|
||||
struct gs_host_config hconf = {
|
||||
.byte_order = 0x0000beef,
|
||||
};
|
||||
struct gs_device_config dconf;
|
||||
struct gs_host_config *hconf;
|
||||
struct gs_device_config *dconf;
|
||||
|
||||
hconf = kmalloc(sizeof(*hconf), GFP_KERNEL);
|
||||
if (!hconf)
|
||||
return -ENOMEM;
|
||||
|
||||
hconf->byte_order = 0x0000beef;
|
||||
|
||||
/* send host config */
|
||||
rc = usb_control_msg(interface_to_usbdev(intf),
|
||||
@@ -920,16 +924,22 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
|
||||
1,
|
||||
intf->altsetting[0].desc.bInterfaceNumber,
|
||||
&hconf,
|
||||
sizeof(hconf),
|
||||
hconf,
|
||||
sizeof(*hconf),
|
||||
1000);
|
||||
|
||||
kfree(hconf);
|
||||
|
||||
if (rc < 0) {
|
||||
dev_err(&intf->dev, "Couldn't send data format (err=%d)\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dconf = kmalloc(sizeof(*dconf), GFP_KERNEL);
|
||||
if (!dconf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* read device config */
|
||||
rc = usb_control_msg(interface_to_usbdev(intf),
|
||||
usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
|
||||
@@ -937,28 +947,33 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
|
||||
1,
|
||||
intf->altsetting[0].desc.bInterfaceNumber,
|
||||
&dconf,
|
||||
sizeof(dconf),
|
||||
dconf,
|
||||
sizeof(*dconf),
|
||||
1000);
|
||||
if (rc < 0) {
|
||||
dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n",
|
||||
rc);
|
||||
kfree(dconf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
icount = dconf.icount + 1;
|
||||
icount = dconf->icount + 1;
|
||||
dev_info(&intf->dev, "Configuring for %d interfaces\n", icount);
|
||||
|
||||
if (icount > GS_MAX_INTF) {
|
||||
dev_err(&intf->dev,
|
||||
"Driver cannot handle more that %d CAN interfaces\n",
|
||||
GS_MAX_INTF);
|
||||
kfree(dconf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
kfree(dconf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_usb_anchor(&dev->rx_submitted);
|
||||
|
||||
atomic_set(&dev->active_channels, 0);
|
||||
@@ -967,7 +982,7 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
dev->udev = interface_to_usbdev(intf);
|
||||
|
||||
for (i = 0; i < icount; i++) {
|
||||
dev->canch[i] = gs_make_candev(i, intf, &dconf);
|
||||
dev->canch[i] = gs_make_candev(i, intf, dconf);
|
||||
if (IS_ERR_OR_NULL(dev->canch[i])) {
|
||||
/* save error code to return later */
|
||||
rc = PTR_ERR(dev->canch[i]);
|
||||
@@ -978,12 +993,15 @@ static int gs_usb_probe(struct usb_interface *intf,
|
||||
gs_destroy_candev(dev->canch[i]);
|
||||
|
||||
usb_kill_anchored_urbs(&dev->rx_submitted);
|
||||
kfree(dconf);
|
||||
kfree(dev);
|
||||
return rc;
|
||||
}
|
||||
dev->canch[i]->parent = dev;
|
||||
}
|
||||
|
||||
kfree(dconf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -951,8 +951,8 @@ static int usb_8dev_probe(struct usb_interface *intf,
|
||||
for (i = 0; i < MAX_TX_URBS; i++)
|
||||
priv->tx_contexts[i].echo_index = MAX_TX_URBS;
|
||||
|
||||
priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
|
||||
GFP_KERNEL);
|
||||
priv->cmd_msg_buffer = devm_kzalloc(&intf->dev, sizeof(struct usb_8dev_cmd_msg),
|
||||
GFP_KERNEL);
|
||||
if (!priv->cmd_msg_buffer)
|
||||
goto cleanup_candev;
|
||||
|
||||
@@ -966,7 +966,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
|
||||
if (err) {
|
||||
netdev_err(netdev,
|
||||
"couldn't register CAN device: %d\n", err);
|
||||
goto cleanup_cmd_msg_buffer;
|
||||
goto cleanup_candev;
|
||||
}
|
||||
|
||||
err = usb_8dev_cmd_version(priv, &version);
|
||||
@@ -987,9 +987,6 @@ static int usb_8dev_probe(struct usb_interface *intf,
|
||||
cleanup_unregister_candev:
|
||||
unregister_netdev(priv->netdev);
|
||||
|
||||
cleanup_cmd_msg_buffer:
|
||||
kfree(priv->cmd_msg_buffer);
|
||||
|
||||
cleanup_candev:
|
||||
free_candev(netdev);
|
||||
|
||||
|
||||
@@ -1901,7 +1901,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
|
||||
ar->hw->wiphy->fw_version);
|
||||
|
||||
if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map)) {
|
||||
if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&
|
||||
mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
||||
val = 0;
|
||||
if (ath10k_peer_stats_enabled(ar))
|
||||
val = WMI_10_4_PEER_STATS;
|
||||
@@ -1954,10 +1955,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
||||
* possible to implicitly make it correct by creating a dummy vdev and
|
||||
* then deleting it.
|
||||
*/
|
||||
status = ath10k_core_reset_rx_filter(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to reset rx filter: %d\n", status);
|
||||
goto err_hif_stop;
|
||||
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
||||
status = ath10k_core_reset_rx_filter(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar,
|
||||
"failed to reset rx filter: %d\n", status);
|
||||
goto err_hif_stop;
|
||||
}
|
||||
}
|
||||
|
||||
/* If firmware indicates Full Rx Reorder support it must be used in a
|
||||
|
||||
@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
break;
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
mutex_lock(&ah->lock);
|
||||
|
||||
@@ -73,13 +73,13 @@
|
||||
#define AR9300_OTP_BASE \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
|
||||
#define AR9300_OTP_STATUS \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
|
||||
#define AR9300_OTP_STATUS_TYPE 0x7
|
||||
#define AR9300_OTP_STATUS_VALID 0x4
|
||||
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
|
||||
#define AR9300_OTP_STATUS_SM_BUSY 0x1
|
||||
#define AR9300_OTP_READ_DATA \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
|
||||
|
||||
enum targetPowerHTRates {
|
||||
HT_TARGET_RATE_0_8_16,
|
||||
|
||||
@@ -959,6 +959,7 @@ struct ath_softc {
|
||||
struct survey_info *cur_survey;
|
||||
struct survey_info survey[ATH9K_NUM_CHANNELS];
|
||||
|
||||
spinlock_t intr_lock;
|
||||
struct tasklet_struct intr_tq;
|
||||
struct tasklet_struct bcon_tasklet;
|
||||
struct ath_hw *sc_ah;
|
||||
|
||||
@@ -626,6 +626,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
|
||||
common->bt_ant_diversity = 1;
|
||||
|
||||
spin_lock_init(&common->cc_lock);
|
||||
spin_lock_init(&sc->intr_lock);
|
||||
spin_lock_init(&sc->sc_serial_rw);
|
||||
spin_lock_init(&sc->sc_pm_lock);
|
||||
spin_lock_init(&sc->chan_lock);
|
||||
|
||||
@@ -805,21 +805,12 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
|
||||
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 sync_default = AR_INTR_SYNC_DEFAULT;
|
||||
u32 async_mask;
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
return;
|
||||
|
||||
if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
|
||||
ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
atomic_read(&ah->intr_ref_cnt));
|
||||
return;
|
||||
}
|
||||
|
||||
if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
|
||||
AR_SREV_9561(ah))
|
||||
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
|
||||
@@ -841,6 +832,39 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
||||
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
||||
}
|
||||
|
||||
void ath9k_hw_resume_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
return;
|
||||
|
||||
if (atomic_read(&ah->intr_ref_cnt) != 0) {
|
||||
ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
atomic_read(&ah->intr_ref_cnt));
|
||||
return;
|
||||
}
|
||||
|
||||
__ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
|
||||
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
return;
|
||||
|
||||
if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
|
||||
ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
atomic_read(&ah->intr_ref_cnt));
|
||||
return;
|
||||
}
|
||||
|
||||
__ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
|
||||
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah)
|
||||
|
||||
@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_disable_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_kill_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_resume_interrupts(struct ath_hw *ah);
|
||||
|
||||
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
|
||||
|
||||
|
||||
@@ -373,21 +373,20 @@ void ath9k_tasklet(unsigned long data)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
enum ath_reset_type type;
|
||||
unsigned long flags;
|
||||
u32 status = sc->intrstatus;
|
||||
u32 status;
|
||||
u32 rxmask;
|
||||
|
||||
spin_lock_irqsave(&sc->intr_lock, flags);
|
||||
status = sc->intrstatus;
|
||||
sc->intrstatus = 0;
|
||||
spin_unlock_irqrestore(&sc->intr_lock, flags);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
spin_lock(&sc->sc_pcu_lock);
|
||||
|
||||
if (status & ATH9K_INT_FATAL) {
|
||||
type = RESET_TYPE_FATAL_INT;
|
||||
ath9k_queue_reset(sc, type);
|
||||
|
||||
/*
|
||||
* Increment the ref. counter here so that
|
||||
* interrupts are enabled in the reset routine.
|
||||
*/
|
||||
atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
|
||||
goto out;
|
||||
}
|
||||
@@ -403,11 +402,6 @@ void ath9k_tasklet(unsigned long data)
|
||||
type = RESET_TYPE_BB_WATCHDOG;
|
||||
ath9k_queue_reset(sc, type);
|
||||
|
||||
/*
|
||||
* Increment the ref. counter here so that
|
||||
* interrupts are enabled in the reset routine.
|
||||
*/
|
||||
atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET,
|
||||
"BB_WATCHDOG: Skipping interrupts\n");
|
||||
goto out;
|
||||
@@ -420,7 +414,6 @@ void ath9k_tasklet(unsigned long data)
|
||||
if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
|
||||
type = RESET_TYPE_TX_GTT;
|
||||
ath9k_queue_reset(sc, type);
|
||||
atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET,
|
||||
"GTT: Skipping interrupts\n");
|
||||
goto out;
|
||||
@@ -477,7 +470,7 @@ void ath9k_tasklet(unsigned long data)
|
||||
ath9k_btcoex_handle_interrupt(sc, status);
|
||||
|
||||
/* re-enable hardware interrupt */
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
ath9k_hw_resume_interrupts(ah);
|
||||
out:
|
||||
spin_unlock(&sc->sc_pcu_lock);
|
||||
ath9k_ps_restore(sc);
|
||||
@@ -541,7 +534,9 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Cache the status */
|
||||
sc->intrstatus = status;
|
||||
spin_lock(&sc->intr_lock);
|
||||
sc->intrstatus |= status;
|
||||
spin_unlock(&sc->intr_lock);
|
||||
|
||||
if (status & SCHED_INTR)
|
||||
sched = true;
|
||||
@@ -587,7 +582,7 @@ chip_reset:
|
||||
|
||||
if (sched) {
|
||||
/* turn off every interrupt */
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ath9k_hw_kill_interrupts(ah);
|
||||
tasklet_schedule(&sc->intr_tq);
|
||||
}
|
||||
|
||||
|
||||
@@ -275,10 +275,10 @@ struct mp_adapter {
|
||||
};
|
||||
|
||||
struct rtl_pci_priv {
|
||||
struct bt_coexist_info bt_coexist;
|
||||
struct rtl_led_ctl ledctl;
|
||||
struct rtl_pci dev;
|
||||
struct mp_adapter ndis_adapter;
|
||||
struct rtl_led_ctl ledctl;
|
||||
struct bt_coexist_info bt_coexist;
|
||||
};
|
||||
|
||||
#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
|
||||
|
||||
@@ -1006,7 +1006,7 @@ static void _rtl92ee_hw_configure(struct ieee80211_hw *hw)
|
||||
rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a);
|
||||
|
||||
/* Note Data sheet don't define */
|
||||
rtl_write_word(rtlpriv, 0x4C7, 0x80);
|
||||
rtl_write_byte(rtlpriv, 0x4C7, 0x80);
|
||||
|
||||
rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
|
||||
|
||||
|
||||
@@ -1128,7 +1128,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
|
||||
}
|
||||
if (0 == tmp) {
|
||||
read_addr = REG_DBI_RDATA + addr % 4;
|
||||
ret = rtl_read_word(rtlpriv, read_addr);
|
||||
ret = rtl_read_byte(rtlpriv, read_addr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -150,8 +150,9 @@ struct rtl_usb {
|
||||
};
|
||||
|
||||
struct rtl_usb_priv {
|
||||
struct rtl_usb dev;
|
||||
struct bt_coexist_info bt_coexist;
|
||||
struct rtl_led_ctl ledctl;
|
||||
struct rtl_usb dev;
|
||||
};
|
||||
|
||||
#define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv))
|
||||
|
||||
@@ -130,7 +130,8 @@ union pci_version {
|
||||
*/
|
||||
union win_slot_encoding {
|
||||
struct {
|
||||
u32 func:8;
|
||||
u32 dev:5;
|
||||
u32 func:3;
|
||||
u32 reserved:24;
|
||||
} bits;
|
||||
u32 slot;
|
||||
@@ -483,7 +484,8 @@ static u32 devfn_to_wslot(int devfn)
|
||||
union win_slot_encoding wslot;
|
||||
|
||||
wslot.slot = 0;
|
||||
wslot.bits.func = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
|
||||
wslot.bits.dev = PCI_SLOT(devfn);
|
||||
wslot.bits.func = PCI_FUNC(devfn);
|
||||
|
||||
return wslot.slot;
|
||||
}
|
||||
@@ -501,7 +503,7 @@ static int wslot_to_devfn(u32 wslot)
|
||||
union win_slot_encoding slot_no;
|
||||
|
||||
slot_no.slot = wslot;
|
||||
return PCI_DEVFN(0, slot_no.bits.func);
|
||||
return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -57,10 +57,14 @@
|
||||
#define TLP_WRITE_TAG 0x10
|
||||
#define RP_DEVFN 0
|
||||
#define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
|
||||
#define TLP_CFG_DW0(pcie, bus) \
|
||||
#define TLP_CFGRD_DW0(pcie, bus) \
|
||||
((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \
|
||||
: TLP_FMTTYPE_CFGRD1) << 24) | \
|
||||
TLP_PAYLOAD_SIZE)
|
||||
#define TLP_CFGWR_DW0(pcie, bus) \
|
||||
((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \
|
||||
: TLP_FMTTYPE_CFGWR1) << 24) | \
|
||||
TLP_PAYLOAD_SIZE)
|
||||
#define TLP_CFG_DW1(pcie, tag, be) \
|
||||
(((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
|
||||
#define TLP_CFG_DW2(bus, devfn, offset) \
|
||||
@@ -222,7 +226,7 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
|
||||
{
|
||||
u32 headers[TLP_HDR_SIZE];
|
||||
|
||||
headers[0] = TLP_CFG_DW0(pcie, bus);
|
||||
headers[0] = TLP_CFGRD_DW0(pcie, bus);
|
||||
headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
|
||||
headers[2] = TLP_CFG_DW2(bus, devfn, where);
|
||||
|
||||
@@ -237,7 +241,7 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
|
||||
u32 headers[TLP_HDR_SIZE];
|
||||
int ret;
|
||||
|
||||
headers[0] = TLP_CFG_DW0(pcie, bus);
|
||||
headers[0] = TLP_CFGWR_DW0(pcie, bus);
|
||||
headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
|
||||
headers[2] = TLP_CFG_DW2(bus, devfn, where);
|
||||
|
||||
|
||||
@@ -35,9 +35,11 @@ static void pnv_php_register(struct device_node *dn);
|
||||
static void pnv_php_unregister_one(struct device_node *dn);
|
||||
static void pnv_php_unregister(struct device_node *dn);
|
||||
|
||||
static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
|
||||
static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
|
||||
bool disable_device)
|
||||
{
|
||||
struct pci_dev *pdev = php_slot->pdev;
|
||||
int irq = php_slot->irq;
|
||||
u16 ctrl;
|
||||
|
||||
if (php_slot->irq > 0) {
|
||||
@@ -56,10 +58,14 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
|
||||
php_slot->wq = NULL;
|
||||
}
|
||||
|
||||
if (pdev->msix_enabled)
|
||||
pci_disable_msix(pdev);
|
||||
else if (pdev->msi_enabled)
|
||||
pci_disable_msi(pdev);
|
||||
if (disable_device || irq > 0) {
|
||||
if (pdev->msix_enabled)
|
||||
pci_disable_msix(pdev);
|
||||
else if (pdev->msi_enabled)
|
||||
pci_disable_msi(pdev);
|
||||
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_php_free_slot(struct kref *kref)
|
||||
@@ -68,7 +74,7 @@ static void pnv_php_free_slot(struct kref *kref)
|
||||
struct pnv_php_slot, kref);
|
||||
|
||||
WARN_ON(!list_empty(&php_slot->children));
|
||||
pnv_php_disable_irq(php_slot);
|
||||
pnv_php_disable_irq(php_slot, false);
|
||||
kfree(php_slot->name);
|
||||
kfree(php_slot);
|
||||
}
|
||||
@@ -759,7 +765,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
|
||||
php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
|
||||
if (!php_slot->wq) {
|
||||
dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
|
||||
pnv_php_disable_irq(php_slot);
|
||||
pnv_php_disable_irq(php_slot, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -772,7 +778,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
|
||||
ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
|
||||
php_slot->name, php_slot);
|
||||
if (ret) {
|
||||
pnv_php_disable_irq(php_slot);
|
||||
pnv_php_disable_irq(php_slot, true);
|
||||
dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ config POWER_RESET_AT91_RESET
|
||||
|
||||
config POWER_RESET_AT91_SAMA5D2_SHDWC
|
||||
tristate "Atmel AT91 SAMA5D2-Compatible shutdown controller driver"
|
||||
depends on ARCH_AT91 || COMPILE_TEST
|
||||
depends on ARCH_AT91
|
||||
default SOC_SAMA5
|
||||
help
|
||||
This driver supports the alternate shutdown controller for some Atmel
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
#include <soc/at91/at91sam9_ddrsdr.h>
|
||||
|
||||
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
|
||||
#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
|
||||
#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
|
||||
@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = {
|
||||
|
||||
static void __iomem *at91_shdwc_base;
|
||||
static struct clk *sclk;
|
||||
static void __iomem *mpddrc_base;
|
||||
|
||||
static void __init at91_wakeup_status(void)
|
||||
{
|
||||
@@ -73,6 +77,29 @@ static void at91_poweroff(void)
|
||||
writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
|
||||
}
|
||||
|
||||
static void at91_lpddr_poweroff(void)
|
||||
{
|
||||
asm volatile(
|
||||
/* Align to cache lines */
|
||||
".balign 32\n\t"
|
||||
|
||||
/* Ensure AT91_SHDW_CR is in the TLB by reading it */
|
||||
" ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
||||
|
||||
/* Power down SDRAM0 */
|
||||
" str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
|
||||
/* Shutdown CPU */
|
||||
" str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
||||
|
||||
" b .\n\t"
|
||||
:
|
||||
: "r" (mpddrc_base),
|
||||
"r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
|
||||
"r" (at91_shdwc_base),
|
||||
"r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
|
||||
: "r0");
|
||||
}
|
||||
|
||||
static int at91_poweroff_get_wakeup_mode(struct device_node *np)
|
||||
{
|
||||
const char *pm;
|
||||
@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
|
||||
static int __init at91_poweroff_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct device_node *np;
|
||||
u32 ddr_type;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
|
||||
|
||||
pm_power_off = at91_poweroff;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
mpddrc_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
|
||||
if (!mpddrc_base)
|
||||
return 0;
|
||||
|
||||
ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
|
||||
if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
|
||||
(ddr_type == AT91_DDRSDRC_MD_LPDDR3))
|
||||
pm_power_off = at91_lpddr_poweroff;
|
||||
else
|
||||
iounmap(mpddrc_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit at91_poweroff_remove(struct platform_device *pdev)
|
||||
{
|
||||
if (pm_power_off == at91_poweroff)
|
||||
if (pm_power_off == at91_poweroff ||
|
||||
pm_power_off == at91_lpddr_poweroff)
|
||||
pm_power_off = NULL;
|
||||
|
||||
clk_disable_unprepare(sclk);
|
||||
@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id at91_ramc_of_match[] = {
|
||||
{ .compatible = "atmel,sama5d3-ddramc", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct of_device_id at91_poweroff_of_match[] = {
|
||||
{ .compatible = "atmel,at91sam9260-shdwc", },
|
||||
{ .compatible = "atmel,at91sam9rl-shdwc", },
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
#include <soc/at91/at91sam9_ddrsdr.h>
|
||||
|
||||
#define SLOW_CLOCK_FREQ 32768
|
||||
|
||||
#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
|
||||
@@ -75,6 +78,7 @@ struct shdwc {
|
||||
*/
|
||||
static struct shdwc *at91_shdwc;
|
||||
static struct clk *sclk;
|
||||
static void __iomem *mpddrc_base;
|
||||
|
||||
static const unsigned long long sdwc_dbc_period[] = {
|
||||
0, 3, 32, 512, 4096, 32768,
|
||||
@@ -108,6 +112,29 @@ static void at91_poweroff(void)
|
||||
at91_shdwc->at91_shdwc_base + AT91_SHDW_CR);
|
||||
}
|
||||
|
||||
static void at91_lpddr_poweroff(void)
|
||||
{
|
||||
asm volatile(
|
||||
/* Align to cache lines */
|
||||
".balign 32\n\t"
|
||||
|
||||
/* Ensure AT91_SHDW_CR is in the TLB by reading it */
|
||||
" ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
||||
|
||||
/* Power down SDRAM0 */
|
||||
" str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
|
||||
/* Shutdown CPU */
|
||||
" str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
|
||||
|
||||
" b .\n\t"
|
||||
:
|
||||
: "r" (mpddrc_base),
|
||||
"r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
|
||||
"r" (at91_shdwc->at91_shdwc_base),
|
||||
"r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
|
||||
: "r0");
|
||||
}
|
||||
|
||||
static u32 at91_shdwc_debouncer_value(struct platform_device *pdev,
|
||||
u32 in_period_us)
|
||||
{
|
||||
@@ -212,6 +239,8 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np;
|
||||
u32 ddr_type;
|
||||
int ret;
|
||||
|
||||
if (!pdev->dev.of_node)
|
||||
@@ -249,6 +278,23 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
|
||||
|
||||
pm_power_off = at91_poweroff;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
mpddrc_base = of_iomap(np, 0);
|
||||
of_node_put(np);
|
||||
|
||||
if (!mpddrc_base)
|
||||
return 0;
|
||||
|
||||
ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
|
||||
if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
|
||||
(ddr_type == AT91_DDRSDRC_MD_LPDDR3))
|
||||
pm_power_off = at91_lpddr_poweroff;
|
||||
else
|
||||
iounmap(mpddrc_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -256,7 +302,8 @@ static int __exit at91_shdwc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct shdwc *shdw = platform_get_drvdata(pdev);
|
||||
|
||||
if (pm_power_off == at91_poweroff)
|
||||
if (pm_power_off == at91_poweroff ||
|
||||
pm_power_off == at91_lpddr_poweroff)
|
||||
pm_power_off = NULL;
|
||||
|
||||
/* Reset values to disable wake-up features */
|
||||
|
||||
@@ -4357,12 +4357,13 @@ static void regulator_summary_show_subtree(struct seq_file *s,
|
||||
seq_puts(s, "\n");
|
||||
|
||||
list_for_each_entry(consumer, &rdev->consumer_list, list) {
|
||||
if (consumer->dev->class == ®ulator_class)
|
||||
if (consumer->dev && consumer->dev->class == ®ulator_class)
|
||||
continue;
|
||||
|
||||
seq_printf(s, "%*s%-*s ",
|
||||
(level + 1) * 3 + 1, "",
|
||||
30 - (level + 1) * 3, dev_name(consumer->dev));
|
||||
30 - (level + 1) * 3,
|
||||
consumer->dev ? dev_name(consumer->dev) : "deviceless");
|
||||
|
||||
switch (rdev->desc->type) {
|
||||
case REGULATOR_VOLTAGE:
|
||||
|
||||
@@ -115,6 +115,7 @@ int qcom_mdt_load(struct rproc *rproc,
|
||||
const struct elf32_phdr *phdrs;
|
||||
const struct elf32_phdr *phdr;
|
||||
const struct elf32_hdr *ehdr;
|
||||
const struct firmware *seg_fw;
|
||||
size_t fw_name_len;
|
||||
char *fw_name;
|
||||
void *ptr;
|
||||
@@ -153,16 +154,16 @@ int qcom_mdt_load(struct rproc *rproc,
|
||||
|
||||
if (phdr->p_filesz) {
|
||||
sprintf(fw_name + fw_name_len - 3, "b%02d", i);
|
||||
ret = request_firmware(&fw, fw_name, &rproc->dev);
|
||||
ret = request_firmware(&seg_fw, fw_name, &rproc->dev);
|
||||
if (ret) {
|
||||
dev_err(&rproc->dev, "failed to load %s\n",
|
||||
fw_name);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(ptr, fw->data, fw->size);
|
||||
memcpy(ptr, seg_fw->data, seg_fw->size);
|
||||
|
||||
release_firmware(fw);
|
||||
release_firmware(seg_fw);
|
||||
}
|
||||
|
||||
if (phdr->p_memsz > phdr->p_filesz)
|
||||
|
||||
@@ -1432,7 +1432,7 @@ config RTC_DRV_SUN4V
|
||||
based RTC on SUN4V systems.
|
||||
|
||||
config RTC_DRV_SUN6I
|
||||
tristate "Allwinner A31 RTC"
|
||||
bool "Allwinner A31 RTC"
|
||||
default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
|
||||
depends on ARCH_SUNXI
|
||||
help
|
||||
|
||||
@@ -37,9 +37,11 @@
|
||||
|
||||
/* Control register */
|
||||
#define SUN6I_LOSC_CTRL 0x0000
|
||||
#define SUN6I_LOSC_CTRL_KEY (0x16aa << 16)
|
||||
#define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9)
|
||||
#define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8)
|
||||
#define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7)
|
||||
#define SUN6I_LOSC_CTRL_EXT_OSC BIT(0)
|
||||
#define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7)
|
||||
|
||||
/* RTC */
|
||||
@@ -114,13 +116,17 @@ struct sun6i_rtc_dev {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
unsigned long alarm;
|
||||
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
|
||||
{
|
||||
struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
u32 val;
|
||||
|
||||
spin_lock(&chip->lock);
|
||||
val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
|
||||
|
||||
if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
|
||||
@@ -129,10 +135,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
|
||||
|
||||
rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
spin_unlock(&chip->lock);
|
||||
|
||||
return IRQ_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
|
||||
@@ -140,6 +147,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
|
||||
u32 alrm_val = 0;
|
||||
u32 alrm_irq_val = 0;
|
||||
u32 alrm_wake_val = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (to) {
|
||||
alrm_val = SUN6I_ALRM_EN_CNT_EN;
|
||||
@@ -150,9 +158,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
|
||||
chip->base + SUN6I_ALRM_IRQ_STA);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
writel(alrm_val, chip->base + SUN6I_ALRM_EN);
|
||||
writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
|
||||
writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
|
||||
spin_unlock_irqrestore(&chip->lock, flags);
|
||||
}
|
||||
|
||||
static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
|
||||
@@ -191,11 +201,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
|
||||
static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
||||
{
|
||||
struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
u32 alrm_st;
|
||||
u32 alrm_en;
|
||||
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
|
||||
alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
|
||||
spin_unlock_irqrestore(&chip->lock, flags);
|
||||
|
||||
wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
|
||||
wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
|
||||
rtc_time_to_tm(chip->alarm, &wkalrm->time);
|
||||
@@ -356,6 +370,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
|
||||
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&chip->lock);
|
||||
|
||||
platform_set_drvdata(pdev, chip);
|
||||
chip->dev = &pdev->dev;
|
||||
@@ -404,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
|
||||
/* disable alarm wakeup */
|
||||
writel(0, chip->base + SUN6I_ALARM_CONFIG);
|
||||
|
||||
/* switch to the external, more precise, oscillator */
|
||||
writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
|
||||
chip->base + SUN6I_LOSC_CTRL);
|
||||
|
||||
chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
|
||||
&sun6i_rtc_ops, THIS_MODULE);
|
||||
if (IS_ERR(chip->rtc)) {
|
||||
@@ -439,9 +458,4 @@ static struct platform_driver sun6i_rtc_driver = {
|
||||
.of_match_table = sun6i_rtc_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(sun6i_rtc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("sun6i RTC driver");
|
||||
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
builtin_platform_driver(sun6i_rtc_driver);
|
||||
|
||||
@@ -413,17 +413,24 @@ static int aac_src_check_health(struct aac_dev *dev)
|
||||
{
|
||||
u32 status = src_readl(dev, MUnit.OMR);
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & SELF_TEST_FAILED))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Check to see if the board panic'd.
|
||||
*/
|
||||
if (unlikely(status & KERNEL_PANIC))
|
||||
return (status >> 16) & 0xFF;
|
||||
goto err_blink;
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & SELF_TEST_FAILED))
|
||||
goto err_out;
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & MONITOR_PANIC))
|
||||
goto err_out;
|
||||
|
||||
/*
|
||||
* Wait for the adapter to be up and running.
|
||||
*/
|
||||
@@ -433,6 +440,12 @@ static int aac_src_check_health(struct aac_dev *dev)
|
||||
* Everything is OK
|
||||
*/
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
return -1;
|
||||
|
||||
err_blink:
|
||||
return (status > 16) & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1185,6 +1185,7 @@ struct lpfc_mbx_wq_create {
|
||||
#define lpfc_mbx_wq_create_page_size_SHIFT 0
|
||||
#define lpfc_mbx_wq_create_page_size_MASK 0x000000FF
|
||||
#define lpfc_mbx_wq_create_page_size_WORD word1
|
||||
#define LPFC_WQ_PAGE_SIZE_4096 0x1
|
||||
#define lpfc_mbx_wq_create_wqe_size_SHIFT 8
|
||||
#define lpfc_mbx_wq_create_wqe_size_MASK 0x0000000F
|
||||
#define lpfc_mbx_wq_create_wqe_size_WORD word1
|
||||
@@ -1256,6 +1257,7 @@ struct rq_context {
|
||||
#define lpfc_rq_context_page_size_SHIFT 0 /* Version 1 Only */
|
||||
#define lpfc_rq_context_page_size_MASK 0x000000FF
|
||||
#define lpfc_rq_context_page_size_WORD word0
|
||||
#define LPFC_RQ_PAGE_SIZE_4096 0x1
|
||||
uint32_t reserved1;
|
||||
uint32_t word2;
|
||||
#define lpfc_rq_context_cq_id_SHIFT 16
|
||||
|
||||
@@ -13678,7 +13678,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
|
||||
LPFC_WQ_WQE_SIZE_128);
|
||||
bf_set(lpfc_mbx_wq_create_page_size,
|
||||
&wq_create->u.request_1,
|
||||
(PAGE_SIZE/SLI4_PAGE_SIZE));
|
||||
LPFC_WQ_PAGE_SIZE_4096);
|
||||
page = wq_create->u.request_1.page;
|
||||
break;
|
||||
}
|
||||
@@ -13704,8 +13704,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
|
||||
LPFC_WQ_WQE_SIZE_128);
|
||||
break;
|
||||
}
|
||||
bf_set(lpfc_mbx_wq_create_page_size, &wq_create->u.request_1,
|
||||
(PAGE_SIZE/SLI4_PAGE_SIZE));
|
||||
bf_set(lpfc_mbx_wq_create_page_size,
|
||||
&wq_create->u.request_1,
|
||||
LPFC_WQ_PAGE_SIZE_4096);
|
||||
page = wq_create->u.request_1.page;
|
||||
break;
|
||||
default:
|
||||
@@ -13891,7 +13892,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
|
||||
LPFC_RQE_SIZE_8);
|
||||
bf_set(lpfc_rq_context_page_size,
|
||||
&rq_create->u.request.context,
|
||||
(PAGE_SIZE/SLI4_PAGE_SIZE));
|
||||
LPFC_RQ_PAGE_SIZE_4096);
|
||||
} else {
|
||||
switch (hrq->entry_count) {
|
||||
default:
|
||||
|
||||
@@ -219,20 +219,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
|
||||
|
||||
static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
|
||||
{
|
||||
struct scsi_device *sdev;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
sdev = q->queuedata;
|
||||
if (!sdev || !get_device(&sdev->sdev_gendev))
|
||||
sdev = NULL;
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
|
||||
return sdev;
|
||||
}
|
||||
|
||||
/*
|
||||
* scsi_dh_activate - activate the path associated with the scsi_device
|
||||
* corresponding to the given request queue.
|
||||
@@ -251,7 +237,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
|
||||
struct scsi_device *sdev;
|
||||
int err = SCSI_DH_NOSYS;
|
||||
|
||||
sdev = get_sdev_from_queue(q);
|
||||
sdev = scsi_device_from_queue(q);
|
||||
if (!sdev) {
|
||||
if (fn)
|
||||
fn(data, err);
|
||||
@@ -298,7 +284,7 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
|
||||
struct scsi_device *sdev;
|
||||
int err = -SCSI_DH_NOSYS;
|
||||
|
||||
sdev = get_sdev_from_queue(q);
|
||||
sdev = scsi_device_from_queue(q);
|
||||
if (!sdev)
|
||||
return err;
|
||||
|
||||
@@ -321,7 +307,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
|
||||
struct scsi_device_handler *scsi_dh;
|
||||
int err = 0;
|
||||
|
||||
sdev = get_sdev_from_queue(q);
|
||||
sdev = scsi_device_from_queue(q);
|
||||
if (!sdev)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -359,7 +345,7 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
|
||||
struct scsi_device *sdev;
|
||||
const char *handler_name = NULL;
|
||||
|
||||
sdev = get_sdev_from_queue(q);
|
||||
sdev = scsi_device_from_queue(q);
|
||||
if (!sdev)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -2127,6 +2127,29 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
|
||||
blk_mq_free_tag_set(&shost->tag_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* scsi_device_from_queue - return sdev associated with a request_queue
|
||||
* @q: The request queue to return the sdev from
|
||||
*
|
||||
* Return the sdev associated with a request queue or NULL if the
|
||||
* request_queue does not reference a SCSI device.
|
||||
*/
|
||||
struct scsi_device *scsi_device_from_queue(struct request_queue *q)
|
||||
{
|
||||
struct scsi_device *sdev = NULL;
|
||||
|
||||
if (q->mq_ops) {
|
||||
if (q->mq_ops == &scsi_mq_ops)
|
||||
sdev = q->queuedata;
|
||||
} else if (q->request_fn == scsi_request_fn)
|
||||
sdev = q->queuedata;
|
||||
if (!sdev || !get_device(&sdev->sdev_gendev))
|
||||
sdev = NULL;
|
||||
|
||||
return sdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scsi_device_from_queue);
|
||||
|
||||
/*
|
||||
* Function: scsi_block_requests()
|
||||
*
|
||||
|
||||
@@ -136,6 +136,8 @@ struct hv_fc_wwn_packet {
|
||||
#define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
|
||||
#define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
|
||||
|
||||
#define SP_UNTAGGED ((unsigned char) ~0)
|
||||
#define SRB_SIMPLE_TAG_REQUEST 0x20
|
||||
|
||||
/*
|
||||
* Platform neutral description of a scsi request -
|
||||
@@ -375,6 +377,7 @@ enum storvsc_request_type {
|
||||
#define SRB_STATUS_SUCCESS 0x01
|
||||
#define SRB_STATUS_ABORTED 0x02
|
||||
#define SRB_STATUS_ERROR 0x04
|
||||
#define SRB_STATUS_DATA_OVERRUN 0x12
|
||||
|
||||
#define SRB_STATUS(status) \
|
||||
(status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
|
||||
@@ -888,6 +891,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
|
||||
|
||||
switch (SRB_STATUS(vm_srb->srb_status)) {
|
||||
case SRB_STATUS_ERROR:
|
||||
/*
|
||||
* Let upper layer deal with error when
|
||||
* sense message is present.
|
||||
*/
|
||||
|
||||
if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
|
||||
break;
|
||||
/*
|
||||
* If there is an error; offline the device since all
|
||||
* error recovery strategies would have already been
|
||||
@@ -953,6 +963,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
|
||||
struct scsi_cmnd *scmnd = cmd_request->cmd;
|
||||
struct scsi_sense_hdr sense_hdr;
|
||||
struct vmscsi_request *vm_srb;
|
||||
u32 data_transfer_length;
|
||||
struct Scsi_Host *host;
|
||||
u32 payload_sz = cmd_request->payload_sz;
|
||||
void *payload = cmd_request->payload;
|
||||
@@ -960,6 +971,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
|
||||
host = stor_dev->host;
|
||||
|
||||
vm_srb = &cmd_request->vstor_packet.vm_srb;
|
||||
data_transfer_length = vm_srb->data_transfer_length;
|
||||
|
||||
scmnd->result = vm_srb->scsi_status;
|
||||
|
||||
@@ -973,13 +985,20 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
|
||||
&sense_hdr);
|
||||
}
|
||||
|
||||
if (vm_srb->srb_status != SRB_STATUS_SUCCESS)
|
||||
if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
|
||||
storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
|
||||
sense_hdr.ascq);
|
||||
/*
|
||||
* The Windows driver set data_transfer_length on
|
||||
* SRB_STATUS_DATA_OVERRUN. On other errors, this value
|
||||
* is untouched. In these cases we set it to 0.
|
||||
*/
|
||||
if (vm_srb->srb_status != SRB_STATUS_DATA_OVERRUN)
|
||||
data_transfer_length = 0;
|
||||
}
|
||||
|
||||
scsi_set_resid(scmnd,
|
||||
cmd_request->payload->range.len -
|
||||
vm_srb->data_transfer_length);
|
||||
cmd_request->payload->range.len - data_transfer_length);
|
||||
|
||||
scmnd->scsi_done(scmnd);
|
||||
|
||||
@@ -1451,6 +1470,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
|
||||
vm_srb->win8_extension.srb_flags |=
|
||||
SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
|
||||
|
||||
if (scmnd->device->tagged_supported) {
|
||||
vm_srb->win8_extension.srb_flags |=
|
||||
(SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
|
||||
vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
|
||||
vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
|
||||
}
|
||||
|
||||
/* Build the SRB */
|
||||
switch (scmnd->sc_data_direction) {
|
||||
case DMA_TO_DEVICE:
|
||||
|
||||
@@ -1003,7 +1003,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
|
||||
sci->num_cs = temp;
|
||||
}
|
||||
|
||||
sci->no_cs = of_property_read_bool(dev->of_node, "broken-cs");
|
||||
sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
|
||||
|
||||
return sci;
|
||||
}
|
||||
|
||||
@@ -1051,8 +1051,13 @@ static int gb_loopback_fn(void *data)
|
||||
gb_loopback_calculate_stats(gb, !!error);
|
||||
}
|
||||
gb->send_count++;
|
||||
if (us_wait)
|
||||
udelay(us_wait);
|
||||
|
||||
if (us_wait) {
|
||||
if (us_wait < 20000)
|
||||
usleep_range(us_wait, us_wait + 100);
|
||||
else
|
||||
msleep(us_wait / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
gb_pm_runtime_put_autosuspend(bundle);
|
||||
|
||||
@@ -252,7 +252,7 @@ srpc_service_init(struct srpc_service *svc)
|
||||
svc->sv_shuttingdown = 0;
|
||||
|
||||
svc->sv_cpt_data = cfs_percpt_alloc(lnet_cpt_table(),
|
||||
sizeof(*svc->sv_cpt_data));
|
||||
sizeof(**svc->sv_cpt_data));
|
||||
if (!svc->sv_cpt_data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -1383,6 +1383,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
|
||||
ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
|
||||
}
|
||||
|
||||
if (!ptr)
|
||||
return _FAIL;
|
||||
|
||||
memcpy(ptr, pattrib->dst, ETH_ALEN);
|
||||
memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
|
||||
|
||||
|
||||
@@ -643,11 +643,16 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
|
||||
/* append rx status for mp test packets */
|
||||
ptr = recvframe_pull(precvframe, (rmv_len -
|
||||
sizeof(struct ethhdr) + 2) - 24);
|
||||
if (!ptr)
|
||||
return _FAIL;
|
||||
memcpy(ptr, get_rxmem(precvframe), 24);
|
||||
ptr += 24;
|
||||
} else
|
||||
} else {
|
||||
ptr = recvframe_pull(precvframe, (rmv_len -
|
||||
sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
|
||||
if (!ptr)
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
memcpy(ptr, pattrib->dst, ETH_ALEN);
|
||||
memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
|
||||
|
||||
@@ -1234,6 +1234,9 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
|
||||
unsigned transfer_in_flight;
|
||||
unsigned started;
|
||||
|
||||
if (dep->flags & DWC3_EP_STALL)
|
||||
return 0;
|
||||
|
||||
if (dep->number > 1)
|
||||
trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
|
||||
else
|
||||
@@ -1258,6 +1261,8 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
|
||||
else
|
||||
dep->flags |= DWC3_EP_STALL;
|
||||
} else {
|
||||
if (!(dep->flags & DWC3_EP_STALL))
|
||||
return 0;
|
||||
|
||||
ret = dwc3_send_clear_stall_ep_cmd(dep);
|
||||
if (ret)
|
||||
|
||||
@@ -50,12 +50,12 @@ struct f_hidg {
|
||||
|
||||
/* recv report */
|
||||
struct list_head completed_out_req;
|
||||
spinlock_t spinlock;
|
||||
spinlock_t read_spinlock;
|
||||
wait_queue_head_t read_queue;
|
||||
unsigned int qlen;
|
||||
|
||||
/* send report */
|
||||
struct mutex lock;
|
||||
spinlock_t write_spinlock;
|
||||
bool write_pending;
|
||||
wait_queue_head_t write_queue;
|
||||
struct usb_request *req;
|
||||
@@ -204,28 +204,35 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
|
||||
if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
spin_lock_irqsave(&hidg->read_spinlock, flags);
|
||||
|
||||
#define READ_COND (!list_empty(&hidg->completed_out_req))
|
||||
|
||||
/* wait for at least one buffer to complete */
|
||||
while (!READ_COND) {
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
if (wait_event_interruptible(hidg->read_queue, READ_COND))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
spin_lock_irqsave(&hidg->read_spinlock, flags);
|
||||
}
|
||||
|
||||
/* pick the first one */
|
||||
list = list_first_entry(&hidg->completed_out_req,
|
||||
struct f_hidg_req_list, list);
|
||||
|
||||
/*
|
||||
* Remove this from list to protect it from beign free()
|
||||
* while host disables our function
|
||||
*/
|
||||
list_del(&list->list);
|
||||
|
||||
req = list->req;
|
||||
count = min_t(unsigned int, count, req->actual - list->pos);
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
||||
|
||||
/* copy to user outside spinlock */
|
||||
count -= copy_to_user(buffer, req->buf + list->pos, count);
|
||||
@@ -238,15 +245,20 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
|
||||
* call, taking into account its current read position.
|
||||
*/
|
||||
if (list->pos == req->actual) {
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
list_del(&list->list);
|
||||
kfree(list);
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
|
||||
req->length = hidg->report_length;
|
||||
ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
free_ep_req(hidg->out_ep, req);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
spin_lock_irqsave(&hidg->read_spinlock, flags);
|
||||
list_add(&list->list, &hidg->completed_out_req);
|
||||
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
||||
|
||||
wake_up(&hidg->read_queue);
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -255,13 +267,16 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
|
||||
static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
struct f_hidg *hidg = (struct f_hidg *)ep->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (req->status != 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"End Point Request ERROR: %d\n", req->status);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
hidg->write_pending = 0;
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
wake_up(&hidg->write_queue);
|
||||
}
|
||||
|
||||
@@ -269,18 +284,19 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *offp)
|
||||
{
|
||||
struct f_hidg *hidg = file->private_data;
|
||||
unsigned long flags;
|
||||
ssize_t status = -ENOMEM;
|
||||
|
||||
if (!access_ok(VERIFY_READ, buffer, count))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&hidg->lock);
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
|
||||
#define WRITE_COND (!hidg->write_pending)
|
||||
|
||||
/* write queue */
|
||||
while (!WRITE_COND) {
|
||||
mutex_unlock(&hidg->lock);
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
@@ -288,17 +304,20 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
||||
hidg->write_queue, WRITE_COND))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
mutex_lock(&hidg->lock);
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
}
|
||||
|
||||
hidg->write_pending = 1;
|
||||
count = min_t(unsigned, count, hidg->report_length);
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
status = copy_from_user(hidg->req->buf, buffer, count);
|
||||
|
||||
if (status != 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"copy_from_user error\n");
|
||||
mutex_unlock(&hidg->lock);
|
||||
return -EINVAL;
|
||||
status = -EINVAL;
|
||||
goto release_write_pending;
|
||||
}
|
||||
|
||||
hidg->req->status = 0;
|
||||
@@ -306,19 +325,23 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
||||
hidg->req->length = count;
|
||||
hidg->req->complete = f_hidg_req_complete;
|
||||
hidg->req->context = hidg;
|
||||
hidg->write_pending = 1;
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
|
||||
if (status < 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"usb_ep_queue error on int endpoint %zd\n", status);
|
||||
hidg->write_pending = 0;
|
||||
wake_up(&hidg->write_queue);
|
||||
goto release_write_pending;
|
||||
} else {
|
||||
status = count;
|
||||
}
|
||||
|
||||
mutex_unlock(&hidg->lock);
|
||||
return status;
|
||||
release_write_pending:
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
hidg->write_pending = 0;
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
|
||||
wake_up(&hidg->write_queue);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -371,20 +394,36 @@ static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
|
||||
static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
{
|
||||
struct f_hidg *hidg = (struct f_hidg *) req->context;
|
||||
struct usb_composite_dev *cdev = hidg->func.config->cdev;
|
||||
struct f_hidg_req_list *req_list;
|
||||
unsigned long flags;
|
||||
|
||||
req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
|
||||
if (!req_list)
|
||||
switch (req->status) {
|
||||
case 0:
|
||||
req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
|
||||
if (!req_list) {
|
||||
ERROR(cdev, "Unable to allocate mem for req_list\n");
|
||||
goto free_req;
|
||||
}
|
||||
|
||||
req_list->req = req;
|
||||
|
||||
spin_lock_irqsave(&hidg->read_spinlock, flags);
|
||||
list_add_tail(&req_list->list, &hidg->completed_out_req);
|
||||
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
||||
|
||||
wake_up(&hidg->read_queue);
|
||||
break;
|
||||
default:
|
||||
ERROR(cdev, "Set report failed %d\n", req->status);
|
||||
/* FALLTHROUGH */
|
||||
case -ECONNABORTED: /* hardware forced ep reset */
|
||||
case -ECONNRESET: /* request dequeued */
|
||||
case -ESHUTDOWN: /* disconnect from host */
|
||||
free_req:
|
||||
free_ep_req(ep, req);
|
||||
return;
|
||||
|
||||
req_list->req = req;
|
||||
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
list_add_tail(&req_list->list, &hidg->completed_out_req);
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
|
||||
wake_up(&hidg->read_queue);
|
||||
}
|
||||
}
|
||||
|
||||
static int hidg_setup(struct usb_function *f,
|
||||
@@ -490,14 +529,18 @@ static void hidg_disable(struct usb_function *f)
|
||||
{
|
||||
struct f_hidg *hidg = func_to_hidg(f);
|
||||
struct f_hidg_req_list *list, *next;
|
||||
unsigned long flags;
|
||||
|
||||
usb_ep_disable(hidg->in_ep);
|
||||
usb_ep_disable(hidg->out_ep);
|
||||
|
||||
spin_lock_irqsave(&hidg->read_spinlock, flags);
|
||||
list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
|
||||
free_ep_req(hidg->out_ep, list->req);
|
||||
list_del(&list->list);
|
||||
kfree(list);
|
||||
}
|
||||
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
|
||||
}
|
||||
|
||||
static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
@@ -646,8 +689,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
mutex_init(&hidg->lock);
|
||||
spin_lock_init(&hidg->spinlock);
|
||||
spin_lock_init(&hidg->write_spinlock);
|
||||
spin_lock_init(&hidg->read_spinlock);
|
||||
init_waitqueue_head(&hidg->write_queue);
|
||||
init_waitqueue_head(&hidg->read_queue);
|
||||
INIT_LIST_HEAD(&hidg->completed_out_req);
|
||||
|
||||
@@ -1080,6 +1080,24 @@ static void usb_udc_nop_release(struct device *dev)
|
||||
dev_vdbg(dev, "%s\n", __func__);
|
||||
}
|
||||
|
||||
/* should be called with udc_lock held */
|
||||
static int check_pending_gadget_drivers(struct usb_udc *udc)
|
||||
{
|
||||
struct usb_gadget_driver *driver;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry(driver, &gadget_driver_pending_list, pending)
|
||||
if (!driver->udc_name || strcmp(driver->udc_name,
|
||||
dev_name(&udc->dev)) == 0) {
|
||||
ret = udc_bind_to_driver(udc, driver);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
list_del(&driver->pending);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
|
||||
* @parent: the parent device to this udc. Usually the controller driver's
|
||||
@@ -1093,7 +1111,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
|
||||
void (*release)(struct device *dev))
|
||||
{
|
||||
struct usb_udc *udc;
|
||||
struct usb_gadget_driver *driver;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
|
||||
@@ -1136,17 +1153,9 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
|
||||
udc->vbus = true;
|
||||
|
||||
/* pick up one of pending gadget drivers */
|
||||
list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
|
||||
if (!driver->udc_name || strcmp(driver->udc_name,
|
||||
dev_name(&udc->dev)) == 0) {
|
||||
ret = udc_bind_to_driver(udc, driver);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
list_del(&driver->pending);
|
||||
if (ret)
|
||||
goto err5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = check_pending_gadget_drivers(udc);
|
||||
if (ret)
|
||||
goto err5;
|
||||
|
||||
mutex_unlock(&udc_lock);
|
||||
|
||||
@@ -1356,14 +1365,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&udc_lock);
|
||||
list_for_each_entry(udc, &udc_list, list)
|
||||
list_for_each_entry(udc, &udc_list, list) {
|
||||
if (udc->driver == driver) {
|
||||
usb_gadget_remove_driver(udc);
|
||||
usb_gadget_set_state(udc->gadget,
|
||||
USB_STATE_NOTATTACHED);
|
||||
USB_STATE_NOTATTACHED);
|
||||
|
||||
/* Maybe there is someone waiting for this UDC? */
|
||||
check_pending_gadget_drivers(udc);
|
||||
/*
|
||||
* For now we ignore bind errors as probably it's
|
||||
* not a valid reason to fail other's gadget unbind
|
||||
*/
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
list_del(&driver->pending);
|
||||
|
||||
@@ -1249,6 +1249,12 @@ static const struct usb_gadget_ops fsl_gadget_ops = {
|
||||
.udc_stop = fsl_udc_stop,
|
||||
};
|
||||
|
||||
/*
|
||||
* Empty complete function used by this driver to fill in the req->complete
|
||||
* field when creating a request since the complete field is mandatory.
|
||||
*/
|
||||
static void fsl_noop_complete(struct usb_ep *ep, struct usb_request *req) { }
|
||||
|
||||
/* Set protocol stall on ep0, protocol stall will automatically be cleared
|
||||
on new transaction */
|
||||
static void ep0stall(struct fsl_udc *udc)
|
||||
@@ -1283,7 +1289,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
|
||||
req->req.length = 0;
|
||||
req->req.status = -EINPROGRESS;
|
||||
req->req.actual = 0;
|
||||
req->req.complete = NULL;
|
||||
req->req.complete = fsl_noop_complete;
|
||||
req->dtd_count = 0;
|
||||
|
||||
ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
|
||||
@@ -1366,7 +1372,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
|
||||
req->req.length = 2;
|
||||
req->req.status = -EINPROGRESS;
|
||||
req->req.actual = 0;
|
||||
req->req.complete = NULL;
|
||||
req->req.complete = fsl_noop_complete;
|
||||
req->dtd_count = 0;
|
||||
|
||||
ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
|
||||
|
||||
@@ -434,15 +434,11 @@ static int da8xx_musb_exit(struct musb *musb)
|
||||
}
|
||||
|
||||
static const struct musb_platform_ops da8xx_ops = {
|
||||
.quirks = MUSB_DMA_CPPI | MUSB_INDEXED_EP,
|
||||
.quirks = MUSB_INDEXED_EP,
|
||||
.init = da8xx_musb_init,
|
||||
.exit = da8xx_musb_exit,
|
||||
|
||||
.fifo_mode = 2,
|
||||
#ifdef CONFIG_USB_TI_CPPI_DMA
|
||||
.dma_init = cppi_dma_controller_create,
|
||||
.dma_exit = cppi_dma_controller_destroy,
|
||||
#endif
|
||||
.enable = da8xx_musb_enable,
|
||||
.disable = da8xx_musb_disable,
|
||||
|
||||
|
||||
@@ -615,8 +615,12 @@ static void virtballoon_remove(struct virtio_device *vdev)
|
||||
cancel_work_sync(&vb->update_balloon_stats_work);
|
||||
|
||||
remove_common(vb);
|
||||
#ifdef CONFIG_BALLOON_COMPACTION
|
||||
if (vb->vb_dev_info.inode)
|
||||
iput(vb->vb_dev_info.inode);
|
||||
|
||||
kern_unmount(balloon_mnt);
|
||||
#endif
|
||||
kfree(vb);
|
||||
}
|
||||
|
||||
|
||||
@@ -1625,10 +1625,25 @@ static int vme_bus_probe(struct device *dev)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int vme_bus_remove(struct device *dev)
|
||||
{
|
||||
int retval = -ENODEV;
|
||||
struct vme_driver *driver;
|
||||
struct vme_dev *vdev = dev_to_vme_dev(dev);
|
||||
|
||||
driver = dev->platform_data;
|
||||
|
||||
if (driver->remove != NULL)
|
||||
retval = driver->remove(vdev);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct bus_type vme_bus_type = {
|
||||
.name = "vme",
|
||||
.match = vme_bus_match,
|
||||
.probe = vme_bus_probe,
|
||||
.remove = vme_bus_remove,
|
||||
};
|
||||
EXPORT_SYMBOL(vme_bus_type);
|
||||
|
||||
|
||||
@@ -153,6 +153,9 @@ struct ds_device
|
||||
*/
|
||||
u16 spu_bit;
|
||||
|
||||
u8 st_buf[ST_SIZE];
|
||||
u8 byte_buf;
|
||||
|
||||
struct w1_bus_master master;
|
||||
};
|
||||
|
||||
@@ -174,7 +177,6 @@ struct ds_status
|
||||
u8 data_in_buffer_status;
|
||||
u8 reserved1;
|
||||
u8 reserved2;
|
||||
|
||||
};
|
||||
|
||||
static struct usb_device_id ds_id_table [] = {
|
||||
@@ -244,28 +246,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
|
||||
unsigned char *buf, int size)
|
||||
{
|
||||
int count, err;
|
||||
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
count = 0;
|
||||
err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev,
|
||||
dev->ep[EP_STATUS]), buf, size, &count, 1000);
|
||||
if (err < 0) {
|
||||
pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
|
||||
dev->ep[EP_STATUS], err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (count >= sizeof(*st))
|
||||
memcpy(st, buf, sizeof(*st));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
|
||||
{
|
||||
pr_info("%45s: %8x\n", str, buf[off]);
|
||||
@@ -324,6 +304,35 @@ static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
|
||||
}
|
||||
}
|
||||
|
||||
static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
|
||||
bool dump)
|
||||
{
|
||||
int count, err;
|
||||
|
||||
if (st)
|
||||
memset(st, 0, sizeof(*st));
|
||||
|
||||
count = 0;
|
||||
err = usb_interrupt_msg(dev->udev,
|
||||
usb_rcvintpipe(dev->udev,
|
||||
dev->ep[EP_STATUS]),
|
||||
dev->st_buf, sizeof(dev->st_buf),
|
||||
&count, 1000);
|
||||
if (err < 0) {
|
||||
pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
|
||||
dev->ep[EP_STATUS], err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (dump)
|
||||
ds_dump_status(dev, dev->st_buf, count);
|
||||
|
||||
if (st && count >= sizeof(*st))
|
||||
memcpy(st, dev->st_buf, sizeof(*st));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void ds_reset_device(struct ds_device *dev)
|
||||
{
|
||||
ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
|
||||
@@ -344,7 +353,6 @@ static void ds_reset_device(struct ds_device *dev)
|
||||
static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
|
||||
{
|
||||
int count, err;
|
||||
struct ds_status st;
|
||||
|
||||
/* Careful on size. If size is less than what is available in
|
||||
* the input buffer, the device fails the bulk transfer and
|
||||
@@ -359,14 +367,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
|
||||
err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
|
||||
buf, size, &count, 1000);
|
||||
if (err < 0) {
|
||||
u8 buf[ST_SIZE];
|
||||
int count;
|
||||
|
||||
pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
|
||||
usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
|
||||
|
||||
count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
|
||||
ds_dump_status(dev, buf, count);
|
||||
ds_recv_status(dev, NULL, true);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -404,7 +407,6 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
|
||||
{
|
||||
struct ds_status st;
|
||||
int count = 0, err = 0;
|
||||
u8 buf[ST_SIZE];
|
||||
|
||||
do {
|
||||
err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
|
||||
@@ -413,7 +415,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
|
||||
err = ds_send_control(dev, CTL_RESUME_EXE, 0);
|
||||
if (err)
|
||||
break;
|
||||
err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
|
||||
err = ds_recv_status(dev, &st, false);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
@@ -456,18 +458,17 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
|
||||
|
||||
static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
|
||||
{
|
||||
u8 buf[ST_SIZE];
|
||||
int err, count = 0;
|
||||
|
||||
do {
|
||||
st->status = 0;
|
||||
err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
|
||||
err = ds_recv_status(dev, st, false);
|
||||
#if 0
|
||||
if (err >= 0) {
|
||||
int i;
|
||||
printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
|
||||
for (i=0; i<err; ++i)
|
||||
printk("%02x ", buf[i]);
|
||||
printk("%02x ", dev->st_buf[i]);
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
@@ -485,7 +486,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
|
||||
* can do something with it).
|
||||
*/
|
||||
if (err > 16 || count >= 100 || err < 0)
|
||||
ds_dump_status(dev, buf, err);
|
||||
ds_dump_status(dev, dev->st_buf, err);
|
||||
|
||||
/* Extended data isn't an error. Well, a short is, but the dump
|
||||
* would have already told the user that and we can't do anything
|
||||
@@ -608,7 +609,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
|
||||
{
|
||||
int err;
|
||||
struct ds_status st;
|
||||
u8 rbyte;
|
||||
|
||||
err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
|
||||
if (err)
|
||||
@@ -621,11 +621,11 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
|
||||
err = ds_recv_data(dev, &dev->byte_buf, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return !(byte == rbyte);
|
||||
return !(byte == dev->byte_buf);
|
||||
}
|
||||
|
||||
static int ds_read_byte(struct ds_device *dev, u8 *byte)
|
||||
@@ -712,7 +712,6 @@ static void ds9490r_search(void *data, struct w1_master *master,
|
||||
int err;
|
||||
u16 value, index;
|
||||
struct ds_status st;
|
||||
u8 st_buf[ST_SIZE];
|
||||
int search_limit;
|
||||
int found = 0;
|
||||
int i;
|
||||
@@ -724,7 +723,12 @@ static void ds9490r_search(void *data, struct w1_master *master,
|
||||
/* FIFO 128 bytes, bulk packet size 64, read a multiple of the
|
||||
* packet size.
|
||||
*/
|
||||
u64 buf[2*64/8];
|
||||
const size_t bufsize = 2 * 64;
|
||||
u64 *buf;
|
||||
|
||||
buf = kmalloc(bufsize, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
mutex_lock(&master->bus_mutex);
|
||||
|
||||
@@ -745,10 +749,9 @@ static void ds9490r_search(void *data, struct w1_master *master,
|
||||
do {
|
||||
schedule_timeout(jtime);
|
||||
|
||||
if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) <
|
||||
sizeof(st)) {
|
||||
err = ds_recv_status(dev, &st, false);
|
||||
if (err < 0 || err < sizeof(st))
|
||||
break;
|
||||
}
|
||||
|
||||
if (st.data_in_buffer_status) {
|
||||
/* Bulk in can receive partial ids, but when it does
|
||||
@@ -758,7 +761,7 @@ static void ds9490r_search(void *data, struct w1_master *master,
|
||||
* bulk without first checking if status says there
|
||||
* is data to read.
|
||||
*/
|
||||
err = ds_recv_data(dev, (u8 *)buf, sizeof(buf));
|
||||
err = ds_recv_data(dev, (u8 *)buf, bufsize);
|
||||
if (err < 0)
|
||||
break;
|
||||
for (i = 0; i < err/8; ++i) {
|
||||
@@ -794,9 +797,14 @@ static void ds9490r_search(void *data, struct w1_master *master,
|
||||
}
|
||||
search_out:
|
||||
mutex_unlock(&master->bus_mutex);
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* FIXME: if this disabled code is ever used in the future all ds_send_data()
|
||||
* calls must be changed to use a DMAable buffer.
|
||||
*/
|
||||
static int ds_match_access(struct ds_device *dev, u64 init)
|
||||
{
|
||||
int err;
|
||||
@@ -845,13 +853,12 @@ static int ds_set_path(struct ds_device *dev, u64 init)
|
||||
|
||||
static u8 ds9490r_touch_bit(void *data, u8 bit)
|
||||
{
|
||||
u8 ret;
|
||||
struct ds_device *dev = data;
|
||||
|
||||
if (ds_touch_bit(dev, bit, &ret))
|
||||
if (ds_touch_bit(dev, bit, &dev->byte_buf))
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
return dev->byte_buf;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -866,13 +873,12 @@ static u8 ds9490r_read_bit(void *data)
|
||||
{
|
||||
struct ds_device *dev = data;
|
||||
int err;
|
||||
u8 bit = 0;
|
||||
|
||||
err = ds_touch_bit(dev, 1, &bit);
|
||||
err = ds_touch_bit(dev, 1, &dev->byte_buf);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return bit & 1;
|
||||
return dev->byte_buf & 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -887,32 +893,52 @@ static u8 ds9490r_read_byte(void *data)
|
||||
{
|
||||
struct ds_device *dev = data;
|
||||
int err;
|
||||
u8 byte = 0;
|
||||
|
||||
err = ds_read_byte(dev, &byte);
|
||||
err = ds_read_byte(dev, &dev->byte_buf);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return byte;
|
||||
return dev->byte_buf;
|
||||
}
|
||||
|
||||
static void ds9490r_write_block(void *data, const u8 *buf, int len)
|
||||
{
|
||||
struct ds_device *dev = data;
|
||||
u8 *tbuf;
|
||||
|
||||
ds_write_block(dev, (u8 *)buf, len);
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
tbuf = kmalloc(len, GFP_KERNEL);
|
||||
if (!tbuf)
|
||||
return;
|
||||
|
||||
memcpy(tbuf, buf, len);
|
||||
ds_write_block(dev, tbuf, len);
|
||||
|
||||
kfree(tbuf);
|
||||
}
|
||||
|
||||
static u8 ds9490r_read_block(void *data, u8 *buf, int len)
|
||||
{
|
||||
struct ds_device *dev = data;
|
||||
int err;
|
||||
u8 *tbuf;
|
||||
|
||||
err = ds_read_block(dev, buf, len);
|
||||
if (err < 0)
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
|
||||
return len;
|
||||
tbuf = kmalloc(len, GFP_KERNEL);
|
||||
if (!tbuf)
|
||||
return 0;
|
||||
|
||||
err = ds_read_block(dev, tbuf, len);
|
||||
if (err >= 0)
|
||||
memcpy(buf, tbuf, len);
|
||||
|
||||
kfree(tbuf);
|
||||
|
||||
return err >= 0 ? len : 0;
|
||||
}
|
||||
|
||||
static u8 ds9490r_reset(void *data)
|
||||
|
||||
@@ -763,6 +763,7 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
|
||||
dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
|
||||
sl->name);
|
||||
w1_family_put(sl->family);
|
||||
atomic_dec(&sl->master->refcnt);
|
||||
kfree(sl);
|
||||
return err;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user