mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 03:50:24 +09:00
Merge remote-tracking branch 'stable/linux-3.12.y' into rpi-3.12.y
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Required properties:
|
||||
- #address-cells: see spi-bus.txt
|
||||
- #size-cells: see spi-bus.txt
|
||||
- compatible: should be "efm32,spi"
|
||||
- compatible: should be "energymicro,efm32-spi"
|
||||
- reg: Offset and length of the register set for the controller
|
||||
- interrupts: pair specifying rx and tx irq
|
||||
- clocks: phandle to the spi clock
|
||||
@@ -15,7 +15,7 @@ Example:
|
||||
spi1: spi@0x4000c400 { /* USART1 */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "efm32,spi";
|
||||
compatible = "energymicro,efm32-spi";
|
||||
reg = <0x4000c400 0x400>;
|
||||
interrupts = <15 16>;
|
||||
clocks = <&cmu 20>;
|
||||
|
||||
@@ -55,6 +55,7 @@ zc3xx 0458:700f Genius VideoCam Web V2
|
||||
sonixj 0458:7025 Genius Eye 311Q
|
||||
sn9c20x 0458:7029 Genius Look 320s
|
||||
sonixj 0458:702e Genius Slim 310 NB
|
||||
sn9c20x 0458:7045 Genius Look 1320 V2
|
||||
sn9c20x 0458:704a Genius Slim 1320
|
||||
sn9c20x 0458:704c Genius i-Look 1321
|
||||
sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650)
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 19
|
||||
SUBLEVEL = 20
|
||||
EXTRAVERSION =
|
||||
NAME = One Giant Leap for Frogkind
|
||||
|
||||
|
||||
@@ -610,11 +610,13 @@ resume_user_mode_begin:
|
||||
|
||||
resume_kernel_mode:
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
|
||||
; This is a must for preempt_schedule_irq()
|
||||
; Disable Interrupts from this point on
|
||||
; CONFIG_PREEMPT: This is a must for preempt_schedule_irq()
|
||||
; !CONFIG_PREEMPT: To ensure restore_regs is intr safe
|
||||
IRQ_DISABLE r9
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
|
||||
; Can't preempt if preemption disabled
|
||||
GET_CURR_THR_INFO_FROM_SP r10
|
||||
ld r8, [r10, THREAD_INFO_PREEMPT_COUNT]
|
||||
|
||||
@@ -33,7 +33,6 @@ config ISS_SMP_EXTN
|
||||
bool "ARC SMP Extensions (ISS Models only)"
|
||||
default n
|
||||
depends on SMP
|
||||
select ARC_HAS_COH_RTSC
|
||||
help
|
||||
SMP Extensions to ARC700, in a "simulation only" Model, supported in
|
||||
ARC ISS (Instruction Set Simulator).
|
||||
|
||||
@@ -910,7 +910,7 @@ config ARCH_MULTI_V5
|
||||
bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
|
||||
depends on !ARCH_MULTI_V6_V7
|
||||
select ARCH_MULTI_V4_V5
|
||||
select CPU_ARM926T if (!CPU_ARM946E || CPU_ARM1020 || \
|
||||
select CPU_ARM926T if !(CPU_ARM946E || CPU_ARM1020 || \
|
||||
CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
|
||||
CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON)
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
musb: usb@47400000 {
|
||||
status = "okay";
|
||||
|
||||
control@44e10000 {
|
||||
control@44e10620 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
dma-controller@07402000 {
|
||||
dma-controller@47402000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
musb: usb@47400000 {
|
||||
status = "okay";
|
||||
|
||||
control@44e10000 {
|
||||
control@44e10620 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
dma-controller@07402000 {
|
||||
dma-controller@47402000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
musb: usb@47400000 {
|
||||
status = "okay";
|
||||
|
||||
control@44e10000 {
|
||||
control@44e10620 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -346,7 +346,7 @@
|
||||
ti,hwmods = "usb_otg_hs";
|
||||
status = "disabled";
|
||||
|
||||
ctrl_mod: control@44e10000 {
|
||||
ctrl_mod: control@44e10620 {
|
||||
compatible = "ti,am335x-usb-ctrl-module";
|
||||
reg = <0x44e10620 0x10
|
||||
0x44e10648 0x4>;
|
||||
@@ -449,7 +449,7 @@
|
||||
"tx14", "tx15";
|
||||
};
|
||||
|
||||
cppi41dma: dma-controller@07402000 {
|
||||
cppi41dma: dma-controller@47402000 {
|
||||
compatible = "ti,am3359-cppi41";
|
||||
reg = <0x47400000 0x1000
|
||||
0x47402000 0x1000
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0x72004 0x4>;
|
||||
clocks = <&gateclk 4>;
|
||||
};
|
||||
|
||||
eth0: ethernet@70000 {
|
||||
|
||||
@@ -286,6 +286,7 @@
|
||||
regulator-name = "vdd_g3d";
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
op_mode = <1>;
|
||||
};
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
/* Select the best insn combination to perform the */ \
|
||||
/* actual __m * __n / (__p << 64) operation. */ \
|
||||
if (!__c) { \
|
||||
asm ( "umull %Q0, %R0, %1, %Q2\n\t" \
|
||||
asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \
|
||||
"mov %Q0, #0" \
|
||||
: "=&r" (__res) \
|
||||
: "r" (__m), "r" (__n) \
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP)
|
||||
/* ARM doesn't provide unprivileged exclusive memory accessors */
|
||||
#include <asm-generic/futex.h>
|
||||
#else
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
@@ -164,6 +159,5 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !(CPU_USE_DOMAINS && SMP) */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_ARM_FUTEX_H */
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
|
||||
#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
|
||||
#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
|
||||
#define L_PTE_MT_VECTORS (_AT(pteval_t, 0x0f) << 2) /* 1111 */
|
||||
#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -48,6 +48,5 @@
|
||||
*/
|
||||
#define __IGNORE_fadvise64_64
|
||||
#define __IGNORE_migrate_pages
|
||||
#define __IGNORE_kcmp
|
||||
|
||||
#endif /* __ASM_ARM_UNISTD_H */
|
||||
|
||||
@@ -181,3 +181,10 @@ void machine_kexec(struct kimage *image)
|
||||
|
||||
soft_restart(reboot_code_buffer_phys);
|
||||
}
|
||||
|
||||
void arch_crash_save_vmcoreinfo(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
VMCOREINFO_CONFIG(ARM_LPAE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ static unsigned long hyp_idmap_start;
|
||||
static unsigned long hyp_idmap_end;
|
||||
static phys_addr_t hyp_idmap_vector;
|
||||
|
||||
#define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
{
|
||||
/*
|
||||
@@ -172,14 +174,14 @@ void free_boot_hyp_pgd(void)
|
||||
if (boot_hyp_pgd) {
|
||||
unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
|
||||
unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
|
||||
kfree(boot_hyp_pgd);
|
||||
free_pages((unsigned long)boot_hyp_pgd, pgd_order);
|
||||
boot_hyp_pgd = NULL;
|
||||
}
|
||||
|
||||
if (hyp_pgd)
|
||||
unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
|
||||
|
||||
kfree(init_bounce_page);
|
||||
free_page((unsigned long)init_bounce_page);
|
||||
init_bounce_page = NULL;
|
||||
|
||||
mutex_unlock(&kvm_hyp_pgd_mutex);
|
||||
@@ -209,7 +211,7 @@ void free_hyp_pgds(void)
|
||||
for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
|
||||
unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
|
||||
|
||||
kfree(hyp_pgd);
|
||||
free_pages((unsigned long)hyp_pgd, pgd_order);
|
||||
hyp_pgd = NULL;
|
||||
}
|
||||
|
||||
@@ -781,7 +783,7 @@ int kvm_mmu_init(void)
|
||||
size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start;
|
||||
phys_addr_t phys_base;
|
||||
|
||||
init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
init_bounce_page = (void *)__get_free_page(GFP_KERNEL);
|
||||
if (!init_bounce_page) {
|
||||
kvm_err("Couldn't allocate HYP init bounce page\n");
|
||||
err = -ENOMEM;
|
||||
@@ -807,8 +809,9 @@ int kvm_mmu_init(void)
|
||||
(unsigned long)phys_base);
|
||||
}
|
||||
|
||||
hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
|
||||
boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
|
||||
hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order);
|
||||
boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order);
|
||||
|
||||
if (!hyp_pgd || !boot_hyp_pgd) {
|
||||
kvm_err("Hyp mode PGD not allocated\n");
|
||||
err = -ENOMEM;
|
||||
|
||||
@@ -222,6 +222,7 @@ void __init ti81xx_init_irq(void)
|
||||
static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs)
|
||||
{
|
||||
u32 irqnr;
|
||||
int handled_irq = 0;
|
||||
|
||||
do {
|
||||
irqnr = readl_relaxed(base_addr + 0x98);
|
||||
@@ -249,8 +250,15 @@ out:
|
||||
if (irqnr) {
|
||||
irqnr = irq_find_mapping(domain, irqnr);
|
||||
handle_IRQ(irqnr, regs);
|
||||
handled_irq = 1;
|
||||
}
|
||||
} while (irqnr);
|
||||
|
||||
/* If an irq is masked or deasserted while active, we will
|
||||
* keep ending up here with no irq handled. So remove it from
|
||||
* the INTC with an ack.*/
|
||||
if (!handled_irq)
|
||||
omap_ack_irq(NULL);
|
||||
}
|
||||
|
||||
asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs)
|
||||
|
||||
@@ -1968,7 +1968,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
|
||||
static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
|
||||
.name = "usb_host_hs",
|
||||
.class = &omap3xxx_usb_host_hs_hwmod_class,
|
||||
.clkdm_name = "l3_init_clkdm",
|
||||
.clkdm_name = "usbhost_clkdm",
|
||||
.mpu_irqs = omap3xxx_usb_host_hs_irqs,
|
||||
.main_clk = "usbhost_48m_fck",
|
||||
.prcm = {
|
||||
@@ -2053,7 +2053,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = {
|
||||
static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
|
||||
.name = "usb_tll_hs",
|
||||
.class = &omap3xxx_usb_tll_hs_hwmod_class,
|
||||
.clkdm_name = "l3_init_clkdm",
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.mpu_irqs = omap3xxx_usb_tll_hs_irqs,
|
||||
.main_clk = "usbtll_fck",
|
||||
.prcm = {
|
||||
|
||||
@@ -103,7 +103,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
|
||||
|
||||
#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0)
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP4)
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
|
||||
extern u16 pm44xx_errata;
|
||||
#define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id))
|
||||
#else
|
||||
|
||||
@@ -446,7 +446,6 @@ config CPU_32v5
|
||||
|
||||
config CPU_32v6
|
||||
bool
|
||||
select CPU_USE_DOMAINS if CPU_V6 && MMU
|
||||
select TLS_REG_EMUL if !CPU_32v6K && !MMU
|
||||
|
||||
config CPU_32v6K
|
||||
@@ -671,7 +670,7 @@ config ARM_VIRT_EXT
|
||||
|
||||
config SWP_EMULATE
|
||||
bool "Emulate SWP/SWPB instructions"
|
||||
depends on !CPU_USE_DOMAINS && CPU_V7
|
||||
depends on CPU_V7
|
||||
default y if SMP
|
||||
select HAVE_PROC_CPU if PROC_FS
|
||||
help
|
||||
|
||||
@@ -463,6 +463,16 @@ static void __init build_mem_type_table(void)
|
||||
hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
|
||||
s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
|
||||
|
||||
/*
|
||||
* We don't use domains on ARMv6 (since this causes problems with
|
||||
* v6/v7 kernels), so we must use a separate memory type for user
|
||||
* r/o, kernel r/w to map the vectors page.
|
||||
*/
|
||||
#ifndef CONFIG_ARM_LPAE
|
||||
if (cpu_arch == CPU_ARCH_ARMv6)
|
||||
vecs_pgprot |= L_PTE_MT_VECTORS;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ARMv6 and above have extended page tables.
|
||||
*/
|
||||
|
||||
@@ -112,13 +112,9 @@
|
||||
* 100x 1 0 1 r/o no acc
|
||||
* 10x0 1 0 1 r/o no acc
|
||||
* 1011 0 0 1 r/w no acc
|
||||
* 110x 0 1 0 r/w r/o
|
||||
* 11x0 0 1 0 r/w r/o
|
||||
* 1111 0 1 1 r/w r/w
|
||||
*
|
||||
* If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
|
||||
* 110x 1 1 1 r/o r/o
|
||||
* 11x0 1 1 1 r/o r/o
|
||||
* 1111 0 1 1 r/w r/w
|
||||
*/
|
||||
.macro armv6_mt_table pfx
|
||||
\pfx\()_mt_table:
|
||||
@@ -137,7 +133,7 @@
|
||||
.long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED
|
||||
.long 0x00 @ unused
|
||||
.long 0x00 @ unused
|
||||
.long 0x00 @ unused
|
||||
.long PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX @ L_PTE_MT_VECTORS
|
||||
.endm
|
||||
|
||||
.macro armv6_set_pte_ext pfx
|
||||
@@ -158,24 +154,21 @@
|
||||
|
||||
tst r1, #L_PTE_USER
|
||||
orrne r3, r3, #PTE_EXT_AP1
|
||||
#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
@ allow kernel read/write access to read-only user pages
|
||||
tstne r3, #PTE_EXT_APX
|
||||
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
|
||||
#endif
|
||||
|
||||
@ user read-only -> kernel read-only
|
||||
bicne r3, r3, #PTE_EXT_AP0
|
||||
|
||||
tst r1, #L_PTE_XN
|
||||
orrne r3, r3, #PTE_EXT_XN
|
||||
|
||||
orr r3, r3, r2
|
||||
eor r3, r3, r2
|
||||
|
||||
tst r1, #L_PTE_YOUNG
|
||||
tstne r1, #L_PTE_PRESENT
|
||||
moveq r3, #0
|
||||
#ifndef CONFIG_CPU_USE_DOMAINS
|
||||
tstne r1, #L_PTE_NONE
|
||||
movne r3, #0
|
||||
#endif
|
||||
|
||||
str r3, [r0]
|
||||
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
|
||||
|
||||
@@ -90,21 +90,14 @@ ENTRY(cpu_v7_set_pte_ext)
|
||||
|
||||
tst r1, #L_PTE_USER
|
||||
orrne r3, r3, #PTE_EXT_AP1
|
||||
#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
@ allow kernel read/write access to read-only user pages
|
||||
tstne r3, #PTE_EXT_APX
|
||||
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
|
||||
#endif
|
||||
|
||||
tst r1, #L_PTE_XN
|
||||
orrne r3, r3, #PTE_EXT_XN
|
||||
|
||||
tst r1, #L_PTE_YOUNG
|
||||
tstne r1, #L_PTE_VALID
|
||||
#ifndef CONFIG_CPU_USE_DOMAINS
|
||||
eorne r1, r1, #L_PTE_NONE
|
||||
tstne r1, #L_PTE_NONE
|
||||
#endif
|
||||
moveq r3, #0
|
||||
|
||||
ARM( str r3, [r0, #2048]! )
|
||||
|
||||
@@ -168,7 +168,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t pte)
|
||||
{
|
||||
if (pte_valid_user(pte)) {
|
||||
if (pte_exec(pte))
|
||||
if (!pte_special(pte) && pte_exec(pte))
|
||||
__sync_icache_dcache(pte, addr);
|
||||
if (!pte_dirty(pte))
|
||||
pte = pte_wrprotect(pte);
|
||||
@@ -253,11 +253,11 @@ static inline int has_transparent_hugepage(void)
|
||||
* Mark the prot value as uncacheable and unbufferable.
|
||||
*/
|
||||
#define pgprot_noncached(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
|
||||
#define pgprot_writecombine(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
|
||||
#define pgprot_dmacoherent(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
|
||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||
struct file;
|
||||
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
|
||||
@@ -1571,17 +1571,17 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc,
|
||||
arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0);
|
||||
#else
|
||||
/* UserLocal not implemented */
|
||||
er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
|
||||
er = EMULATE_FAIL;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("RDHWR not supported\n");
|
||||
kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc);
|
||||
er = EMULATE_FAIL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printk("Emulate RI not supported @ %p: %#x\n", opc, inst);
|
||||
kvm_debug("Emulate RI not supported @ %p: %#x\n", opc, inst);
|
||||
er = EMULATE_FAIL;
|
||||
}
|
||||
|
||||
@@ -1590,6 +1590,7 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc,
|
||||
*/
|
||||
if (er == EMULATE_FAIL) {
|
||||
vcpu->arch.pc = curr_pc;
|
||||
er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
|
||||
}
|
||||
return er;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ LEAF(swsusp_arch_resume)
|
||||
bne t1, t3, 1b
|
||||
PTR_L t0, PBE_NEXT(t0)
|
||||
bnez t0, 0b
|
||||
jal local_flush_tlb_all /* Avoid TLB mismatch after kernel resume */
|
||||
PTR_LA t0, saved_regs
|
||||
PTR_L ra, PT_R31(t0)
|
||||
PTR_L sp, PT_R29(t0)
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define COMPAT_USER_HZ 100
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define COMPAT_UTS_MACHINE "ppc\0\0"
|
||||
#else
|
||||
#define COMPAT_UTS_MACHINE "ppcle\0\0"
|
||||
#endif
|
||||
|
||||
typedef u32 compat_size_t;
|
||||
typedef s32 compat_ssize_t;
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
#define SPRN_ACOP 0x1F /* Available Coprocessor Register */
|
||||
#define SPRN_TFIAR 0x81 /* Transaction Failure Inst Addr */
|
||||
#define SPRN_TEXASR 0x82 /* Transaction EXception & Summary */
|
||||
#define TEXASR_FS __MASK(63-36) /* Transaction Failure Summary */
|
||||
#define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */
|
||||
#define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */
|
||||
#define SPRN_CTRLF 0x088
|
||||
|
||||
@@ -525,6 +525,31 @@ out_and_saveregs:
|
||||
tm_save_sprs(thr);
|
||||
}
|
||||
|
||||
extern void __tm_recheckpoint(struct thread_struct *thread,
|
||||
unsigned long orig_msr);
|
||||
|
||||
void tm_recheckpoint(struct thread_struct *thread,
|
||||
unsigned long orig_msr)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* We really can't be interrupted here as the TEXASR registers can't
|
||||
* change and later in the trecheckpoint code, we have a userspace R1.
|
||||
* So let's hard disable over this region.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
hard_irq_disable();
|
||||
|
||||
/* The TM SPRs are restored here, so that TEXASR.FS can be set
|
||||
* before the trecheckpoint and no explosion occurs.
|
||||
*/
|
||||
tm_restore_sprs(thread);
|
||||
|
||||
__tm_recheckpoint(thread, orig_msr);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static inline void tm_recheckpoint_new_task(struct task_struct *new)
|
||||
{
|
||||
unsigned long msr;
|
||||
@@ -543,13 +568,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)
|
||||
if (!new->thread.regs)
|
||||
return;
|
||||
|
||||
/* The TM SPRs are restored here, so that TEXASR.FS can be set
|
||||
* before the trecheckpoint and no explosion occurs.
|
||||
*/
|
||||
tm_restore_sprs(&new->thread);
|
||||
|
||||
if (!MSR_TM_ACTIVE(new->thread.regs->msr))
|
||||
if (!MSR_TM_ACTIVE(new->thread.regs->msr)){
|
||||
tm_restore_sprs(&new->thread);
|
||||
return;
|
||||
}
|
||||
msr = new->thread.tm_orig_msr;
|
||||
/* Recheckpoint to restore original checkpointed register state. */
|
||||
TM_DEBUG("*** tm_recheckpoint of pid %d "
|
||||
|
||||
@@ -872,6 +872,8 @@ static long restore_tm_user_regs(struct pt_regs *regs,
|
||||
* transactional versions should be loaded.
|
||||
*/
|
||||
tm_enable();
|
||||
/* Make sure the transaction is marked as failed */
|
||||
current->thread.tm_texasr |= TEXASR_FS;
|
||||
/* This loads the checkpointed FP/VEC state, if used */
|
||||
tm_recheckpoint(¤t->thread, msr);
|
||||
/* Get the top half of the MSR */
|
||||
|
||||
@@ -519,6 +519,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
|
||||
}
|
||||
#endif
|
||||
tm_enable();
|
||||
/* Make sure the transaction is marked as failed */
|
||||
current->thread.tm_texasr |= TEXASR_FS;
|
||||
/* This loads the checkpointed FP/VEC state, if used */
|
||||
tm_recheckpoint(¤t->thread, msr);
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ dont_backup_fp:
|
||||
* Call with IRQs off, stacks get all out of sync for
|
||||
* some periods in here!
|
||||
*/
|
||||
_GLOBAL(tm_recheckpoint)
|
||||
_GLOBAL(__tm_recheckpoint)
|
||||
mfcr r5
|
||||
mflr r0
|
||||
std r5, 8(r1)
|
||||
|
||||
@@ -219,7 +219,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
|
||||
#define to_ccwdev(n) container_of(n, struct ccw_device, dev)
|
||||
#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
|
||||
|
||||
extern struct ccw_device *ccw_device_probe_console(void);
|
||||
extern struct ccw_device *ccw_device_probe_console(struct ccw_driver *);
|
||||
extern void ccw_device_wait_idle(struct ccw_device *);
|
||||
extern int ccw_device_force_console(struct ccw_device *);
|
||||
|
||||
|
||||
@@ -788,7 +788,8 @@ rerun_vcpu:
|
||||
if (rc)
|
||||
break;
|
||||
if (kvm_is_ucontrol(vcpu->kvm))
|
||||
rc = -EOPNOTSUPP;
|
||||
/* Don't exit for host interrupts. */
|
||||
rc = vcpu->arch.sie_block->icptcode ? -EOPNOTSUPP : 0;
|
||||
else
|
||||
rc = kvm_handle_sie_intercept(vcpu);
|
||||
} while (!signal_pending(current) && !rc);
|
||||
|
||||
@@ -276,7 +276,6 @@ static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter)
|
||||
case BPF_S_LD_W_IND:
|
||||
case BPF_S_LD_H_IND:
|
||||
case BPF_S_LD_B_IND:
|
||||
case BPF_S_LDX_B_MSH:
|
||||
case BPF_S_LD_IMM:
|
||||
case BPF_S_LD_MEM:
|
||||
case BPF_S_MISC_TXA:
|
||||
|
||||
@@ -115,7 +115,7 @@ static int print_trace_stack(void *data, char *name)
|
||||
*/
|
||||
static void print_trace_address(void *data, unsigned long addr, int reliable)
|
||||
{
|
||||
printk(data);
|
||||
printk("%s", (char *)data);
|
||||
printk_address(addr, reliable);
|
||||
}
|
||||
|
||||
|
||||
@@ -865,6 +865,9 @@ fail:
|
||||
* Because the x86 boot code expects to be passed a boot_params we
|
||||
* need to create one ourselves (usually the bootloader would create
|
||||
* one for us).
|
||||
*
|
||||
* The caller is responsible for filling out ->code32_start in the
|
||||
* returned boot_params.
|
||||
*/
|
||||
struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
|
||||
{
|
||||
@@ -921,8 +924,6 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
|
||||
hdr->vid_mode = 0xffff;
|
||||
hdr->boot_flag = 0xAA55;
|
||||
|
||||
hdr->code32_start = (__u64)(unsigned long)image->image_base;
|
||||
|
||||
hdr->type_of_loader = 0x21;
|
||||
|
||||
/* Convert unicode cmdline to ascii */
|
||||
|
||||
@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry)
|
||||
pushl %eax
|
||||
pushl %esi
|
||||
pushl %ecx
|
||||
|
||||
call reloc
|
||||
reloc:
|
||||
popl %ecx
|
||||
subl reloc, %ecx
|
||||
movl %ecx, BP_code32_start(%eax)
|
||||
|
||||
sub $0x4, %esp
|
||||
|
||||
ENTRY(efi_stub_entry)
|
||||
@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry)
|
||||
hlt
|
||||
jmp 1b
|
||||
2:
|
||||
call 3f
|
||||
3:
|
||||
popl %eax
|
||||
subl $3b, %eax
|
||||
subl BP_pref_address(%esi), %eax
|
||||
add BP_code32_start(%esi), %eax
|
||||
movl BP_code32_start(%esi), %eax
|
||||
leal preferred_addr(%eax), %eax
|
||||
jmp *%eax
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ ENTRY(efi_pe_entry)
|
||||
cmpq $0,%rax
|
||||
je 1f
|
||||
mov %rax, %rdx
|
||||
leaq startup_32(%rip), %rax
|
||||
movl %eax, BP_code32_start(%rdx)
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
|
||||
@@ -228,12 +230,7 @@ ENTRY(efi_stub_entry)
|
||||
hlt
|
||||
jmp 1b
|
||||
2:
|
||||
call 3f
|
||||
3:
|
||||
popq %rax
|
||||
subq $3b, %rax
|
||||
subq BP_pref_address(%rsi), %rax
|
||||
add BP_code32_start(%esi), %eax
|
||||
movl BP_code32_start(%esi), %eax
|
||||
leaq preferred_addr(%rax), %rax
|
||||
jmp *%rax
|
||||
|
||||
|
||||
@@ -659,8 +659,8 @@ ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
run_sync();
|
||||
out:
|
||||
run_sync();
|
||||
return ret;
|
||||
|
||||
fail_update:
|
||||
|
||||
@@ -229,6 +229,17 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On x86-64 we do not support 16-bit segments due to
|
||||
* IRET leaking the high bits of the kernel stack address.
|
||||
*/
|
||||
#ifdef CONFIG_X86_64
|
||||
if (!ldt_info.seg_32bit) {
|
||||
error = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
#endif
|
||||
|
||||
fill_ldt(&ldt, &ldt_info);
|
||||
if (oldmode)
|
||||
ldt.avl = 0;
|
||||
|
||||
@@ -207,13 +207,30 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info,
|
||||
* this predefined name. Either one return value is expected, or none,
|
||||
* for both methods and other objects.
|
||||
*
|
||||
* Exit now if there is no return object. Warning if one was expected.
|
||||
* Try to fix if there was no return object. Warning if failed to fix.
|
||||
*/
|
||||
if (!return_object) {
|
||||
if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Missing expected return value"));
|
||||
if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO,
|
||||
info->full_pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Found unexpected NULL package element"));
|
||||
|
||||
status =
|
||||
acpi_ns_repair_null_element(info,
|
||||
expected_btypes,
|
||||
package_index,
|
||||
return_object_ptr);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
return (AE_OK); /* Repair was successful */
|
||||
}
|
||||
} else {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO,
|
||||
info->full_pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Missing expected return value"));
|
||||
}
|
||||
|
||||
return (AE_AML_NO_RETURN_VALUE);
|
||||
}
|
||||
|
||||
@@ -1169,18 +1169,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < host->n_ports; i++) {
|
||||
const char* desc;
|
||||
struct ahci_port_priv *pp = host->ports[i]->private_data;
|
||||
|
||||
/* pp is NULL for dummy ports */
|
||||
if (pp)
|
||||
desc = pp->irq_desc;
|
||||
else
|
||||
desc = dev_driver_string(host->dev);
|
||||
/* Do not receive interrupts sent by dummy ports */
|
||||
if (!pp) {
|
||||
disable_irq(irq + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = devm_request_threaded_irq(host->dev,
|
||||
irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
|
||||
desc, host->ports[i]);
|
||||
rc = devm_request_threaded_irq(host->dev, irq + i,
|
||||
ahci_hw_interrupt,
|
||||
ahci_thread_fn, IRQF_SHARED,
|
||||
pp->irq_desc, host->ports[i]);
|
||||
if (rc)
|
||||
goto out_free_irqs;
|
||||
}
|
||||
|
||||
@@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
||||
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
|
||||
|
||||
/* devices that don't properly handle queued TRIM commands */
|
||||
{ "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
{ "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
||||
|
||||
/*
|
||||
* Some WD SATA-I drives spin up and down erratically when the link
|
||||
@@ -4792,21 +4794,26 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
|
||||
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
||||
{
|
||||
struct ata_queued_cmd *qc = NULL;
|
||||
unsigned int i;
|
||||
unsigned int i, tag;
|
||||
|
||||
/* no command while frozen */
|
||||
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
|
||||
return NULL;
|
||||
|
||||
/* the last tag is reserved for internal command. */
|
||||
for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
|
||||
if (!test_and_set_bit(i, &ap->qc_allocated)) {
|
||||
qc = __ata_qc_from_tag(ap, i);
|
||||
for (i = 0; i < ATA_MAX_QUEUE; i++) {
|
||||
tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
|
||||
|
||||
/* the last tag is reserved for internal command. */
|
||||
if (tag == ATA_TAG_INTERNAL)
|
||||
continue;
|
||||
|
||||
if (!test_and_set_bit(tag, &ap->qc_allocated)) {
|
||||
qc = __ata_qc_from_tag(ap, tag);
|
||||
qc->tag = tag;
|
||||
ap->last_tag = tag;
|
||||
break;
|
||||
}
|
||||
|
||||
if (qc)
|
||||
qc->tag = i;
|
||||
}
|
||||
|
||||
return qc;
|
||||
}
|
||||
|
||||
@@ -3053,7 +3053,10 @@ static int raw_cmd_copyout(int cmd, void __user *param,
|
||||
int ret;
|
||||
|
||||
while (ptr) {
|
||||
ret = copy_to_user(param, ptr, sizeof(*ptr));
|
||||
struct floppy_raw_cmd cmd = *ptr;
|
||||
cmd.next = NULL;
|
||||
cmd.kernel_data = NULL;
|
||||
ret = copy_to_user(param, &cmd, sizeof(cmd));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
param += sizeof(struct floppy_raw_cmd);
|
||||
@@ -3107,10 +3110,11 @@ loop:
|
||||
return -ENOMEM;
|
||||
*rcmd = ptr;
|
||||
ret = copy_from_user(ptr, param, sizeof(*ptr));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
ptr->next = NULL;
|
||||
ptr->buffer_length = 0;
|
||||
ptr->kernel_data = NULL;
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
param += sizeof(struct floppy_raw_cmd);
|
||||
if (ptr->cmd_count > 33)
|
||||
/* the command may now also take up the space
|
||||
@@ -3126,7 +3130,6 @@ loop:
|
||||
for (i = 0; i < 16; i++)
|
||||
ptr->reply[i] = 0;
|
||||
ptr->resultcode = 0;
|
||||
ptr->kernel_data = NULL;
|
||||
|
||||
if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
|
||||
if (ptr->length <= 0)
|
||||
|
||||
@@ -621,6 +621,12 @@ static void mtip_timeout_function(unsigned long int data)
|
||||
*/
|
||||
writel(1 << bit, port->completed[group]);
|
||||
|
||||
/* Unmap the DMA scatter list entries */
|
||||
dma_unmap_sg(&port->dd->pdev->dev,
|
||||
command->sg,
|
||||
command->scatter_ents,
|
||||
command->direction);
|
||||
|
||||
/* Call the async completion callback. */
|
||||
if (likely(command->async_callback))
|
||||
command->async_callback(command->async_data,
|
||||
@@ -628,12 +634,6 @@ static void mtip_timeout_function(unsigned long int data)
|
||||
command->async_callback = NULL;
|
||||
command->comp_func = NULL;
|
||||
|
||||
/* Unmap the DMA scatter list entries */
|
||||
dma_unmap_sg(&port->dd->pdev->dev,
|
||||
command->sg,
|
||||
command->scatter_ents,
|
||||
command->direction);
|
||||
|
||||
/*
|
||||
* Clear the allocated bit and active tag for the
|
||||
* command.
|
||||
@@ -711,6 +711,12 @@ static void mtip_async_complete(struct mtip_port *port,
|
||||
"Command tag %d failed due to TFE\n", tag);
|
||||
}
|
||||
|
||||
/* Unmap the DMA scatter list entries */
|
||||
dma_unmap_sg(&dd->pdev->dev,
|
||||
command->sg,
|
||||
command->scatter_ents,
|
||||
command->direction);
|
||||
|
||||
/* Upper layer callback */
|
||||
if (likely(command->async_callback))
|
||||
command->async_callback(command->async_data, cb_status);
|
||||
@@ -718,12 +724,6 @@ static void mtip_async_complete(struct mtip_port *port,
|
||||
command->async_callback = NULL;
|
||||
command->comp_func = NULL;
|
||||
|
||||
/* Unmap the DMA scatter list entries */
|
||||
dma_unmap_sg(&dd->pdev->dev,
|
||||
command->sg,
|
||||
command->scatter_ents,
|
||||
command->direction);
|
||||
|
||||
/* Clear the allocated and active bits for the command */
|
||||
atomic_set(&port->commands[tag].active, 0);
|
||||
release_slot(port, tag);
|
||||
@@ -4040,6 +4040,7 @@ skip_create_disk:
|
||||
blk_queue_max_hw_sectors(dd->queue, 0xffff);
|
||||
blk_queue_max_segment_size(dd->queue, 0x400000);
|
||||
blk_queue_io_min(dd->queue, 4096);
|
||||
blk_queue_bounce_limit(dd->queue, dd->pdev->dma_mask);
|
||||
|
||||
/*
|
||||
* write back cache is not supported in the device. FUA depends on
|
||||
|
||||
@@ -130,7 +130,7 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev)
|
||||
int i;
|
||||
|
||||
if (!iodev->dev->of_node)
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
clk_np = of_find_node_by_name(iodev->dev->of_node, "clocks");
|
||||
if (!clk_np) {
|
||||
|
||||
@@ -170,11 +170,13 @@ static void edma_execute(struct edma_chan *echan)
|
||||
if (edesc->processed == edesc->pset_nr)
|
||||
edma_link(echan->slot[nslots-1], echan->ecc->dummy_slot);
|
||||
|
||||
edma_resume(echan->ch_num);
|
||||
|
||||
if (edesc->processed <= MAX_NR_SG) {
|
||||
dev_dbg(dev, "first transfer starting %d\n", echan->ch_num);
|
||||
edma_start(echan->ch_num);
|
||||
} else {
|
||||
dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
|
||||
echan->ch_num, edesc->processed);
|
||||
edma_resume(echan->ch_num);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -214,7 +214,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
|
||||
ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
|
||||
ct->regs.mask = PINCTRL_IRQEN(port);
|
||||
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
|
||||
IRQ_NOREQUEST, 0);
|
||||
}
|
||||
|
||||
static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/console.h>
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include "cirrus_drv.h"
|
||||
|
||||
@@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
|
||||
drm_put_dev(dev);
|
||||
}
|
||||
|
||||
static int cirrus_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||
struct cirrus_device *cdev = drm_dev->dev_private;
|
||||
|
||||
drm_kms_helper_poll_disable(drm_dev);
|
||||
|
||||
if (cdev->mode_info.gfbdev) {
|
||||
console_lock();
|
||||
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cirrus_pm_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||
struct cirrus_device *cdev = drm_dev->dev_private;
|
||||
|
||||
drm_helper_resume_force_mode(drm_dev);
|
||||
|
||||
if (cdev->mode_info.gfbdev) {
|
||||
console_lock();
|
||||
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations cirrus_driver_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
@@ -104,11 +140,17 @@ static struct drm_driver driver = {
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops cirrus_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
|
||||
cirrus_pm_resume)
|
||||
};
|
||||
|
||||
static struct pci_driver cirrus_pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
.probe = cirrus_pci_probe,
|
||||
.remove = cirrus_pci_remove,
|
||||
.driver.pm = &cirrus_pm_ops,
|
||||
};
|
||||
|
||||
static int __init cirrus_init(void)
|
||||
|
||||
@@ -308,6 +308,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
|
||||
|
||||
WREG_HDR(hdr);
|
||||
cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
|
||||
|
||||
/* Unblank (needed on S3 resume, vgabios doesn't do it then) */
|
||||
outb(0x20, 0x3c0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -758,6 +758,14 @@ static const struct dmi_system_id intel_no_crt[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = intel_no_crt_dmi_callback,
|
||||
.ident = "DELL XPS 8700",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 8700"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u32 current_version)
|
||||
case (VERSION_WIN8):
|
||||
return VERSION_WIN7;
|
||||
|
||||
case (VERSION_WIN8_1):
|
||||
return VERSION_WIN8;
|
||||
|
||||
case (VERSION_WS2008):
|
||||
default:
|
||||
return VERSION_INVAL;
|
||||
@@ -79,6 +82,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
|
||||
msg->monitor_page2 = virt_to_phys(
|
||||
(void *)((unsigned long)vmbus_connection.monitor_pages +
|
||||
PAGE_SIZE));
|
||||
if (version == VERSION_WIN8_1)
|
||||
msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
|
||||
|
||||
/*
|
||||
* Add to list before we send the request since we may
|
||||
|
||||
@@ -119,7 +119,8 @@ static ssize_t iio_scan_el_show(struct device *dev,
|
||||
int ret;
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
|
||||
ret = test_bit(to_iio_dev_attr(attr)->address,
|
||||
/* Ensure ret is 0 or 1. */
|
||||
ret = !!test_bit(to_iio_dev_attr(attr)->address,
|
||||
indio_dev->buffer->scan_mask);
|
||||
|
||||
return sprintf(buf, "%d\n", ret);
|
||||
@@ -789,7 +790,8 @@ int iio_scan_mask_query(struct iio_dev *indio_dev,
|
||||
if (!buffer->scan_mask)
|
||||
return 0;
|
||||
|
||||
return test_bit(bit, buffer->scan_mask);
|
||||
/* Ensure return value is 0 or 1. */
|
||||
return !!test_bit(bit, buffer->scan_mask);
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(iio_scan_mask_query);
|
||||
|
||||
|
||||
@@ -283,6 +283,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
|
||||
(my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
|
||||
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
|
||||
ehca_err(device, "Copy to udata failed.");
|
||||
cq = ERR_PTR(-EFAULT);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
|
||||
size_t count, loff_t *off)
|
||||
{
|
||||
u32 __iomem *piobuf;
|
||||
u32 plen, clen, pbufn;
|
||||
u32 plen, pbufn, maxlen_reserve;
|
||||
struct ipath_diag_pkt odp;
|
||||
struct ipath_diag_xpkt dp;
|
||||
u32 *tmpbuf = NULL;
|
||||
@@ -335,51 +335,29 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
|
||||
u64 val;
|
||||
u32 l_state, lt_state; /* LinkState, LinkTrainingState */
|
||||
|
||||
if (count < sizeof(odp)) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (count == sizeof(dp)) {
|
||||
if (copy_from_user(&dp, data, sizeof(dp))) {
|
||||
ret = -EFAULT;
|
||||
goto bail;
|
||||
}
|
||||
} else if (copy_from_user(&odp, data, sizeof(odp))) {
|
||||
ret = -EFAULT;
|
||||
} else if (count == sizeof(odp)) {
|
||||
if (copy_from_user(&odp, data, sizeof(odp))) {
|
||||
ret = -EFAULT;
|
||||
goto bail;
|
||||
}
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Due to padding/alignment issues (lessened with new struct)
|
||||
* the old and new structs are the same length. We need to
|
||||
* disambiguate them, which we can do because odp.len has never
|
||||
* been less than the total of LRH+BTH+DETH so far, while
|
||||
* dp.unit (same offset) unit is unlikely to get that high.
|
||||
* Similarly, dp.data, the pointer to user at the same offset
|
||||
* as odp.unit, is almost certainly at least one (512byte)page
|
||||
* "above" NULL. The if-block below can be omitted if compatibility
|
||||
* between a new driver and older diagnostic code is unimportant.
|
||||
* compatibility the other direction (new diags, old driver) is
|
||||
* handled in the diagnostic code, with a warning.
|
||||
*/
|
||||
if (dp.unit >= 20 && dp.data < 512) {
|
||||
/* very probable version mismatch. Fix it up */
|
||||
memcpy(&odp, &dp, sizeof(odp));
|
||||
/* We got a legacy dp, copy elements to dp */
|
||||
dp.unit = odp.unit;
|
||||
dp.data = odp.data;
|
||||
dp.len = odp.len;
|
||||
dp.pbc_wd = 0; /* Indicate we need to compute PBC wd */
|
||||
}
|
||||
|
||||
/* send count must be an exact number of dwords */
|
||||
if (dp.len & 3) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
clen = dp.len >> 2;
|
||||
plen = dp.len >> 2;
|
||||
|
||||
dd = ipath_lookup(dp.unit);
|
||||
if (!dd || !(dd->ipath_flags & IPATH_PRESENT) ||
|
||||
@@ -422,16 +400,22 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* need total length before first word written */
|
||||
/* +1 word is for the qword padding */
|
||||
/*
|
||||
* need total length before first word written, plus 2 Dwords. One Dword
|
||||
* is for padding so we get the full user data when not aligned on
|
||||
* a word boundary. The other Dword is to make sure we have room for the
|
||||
* ICRC which gets tacked on later.
|
||||
*/
|
||||
maxlen_reserve = 2 * sizeof(u32);
|
||||
if (dp.len > dd->ipath_ibmaxlen - maxlen_reserve) {
|
||||
ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n",
|
||||
dp.len, dd->ipath_ibmaxlen);
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
plen = sizeof(u32) + dp.len;
|
||||
|
||||
if ((plen + 4) > dd->ipath_ibmaxlen) {
|
||||
ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n",
|
||||
plen - 4, dd->ipath_ibmaxlen);
|
||||
ret = -EINVAL;
|
||||
goto bail; /* before writing pbc */
|
||||
}
|
||||
tmpbuf = vmalloc(plen);
|
||||
if (!tmpbuf) {
|
||||
dev_info(&dd->pcidev->dev, "Unable to allocate tmp buffer, "
|
||||
@@ -473,11 +457,11 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
|
||||
*/
|
||||
if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) {
|
||||
ipath_flush_wc();
|
||||
__iowrite32_copy(piobuf + 2, tmpbuf, clen - 1);
|
||||
__iowrite32_copy(piobuf + 2, tmpbuf, plen - 1);
|
||||
ipath_flush_wc();
|
||||
__raw_writel(tmpbuf[clen - 1], piobuf + clen + 1);
|
||||
__raw_writel(tmpbuf[plen - 1], piobuf + plen + 1);
|
||||
} else
|
||||
__iowrite32_copy(piobuf + 2, tmpbuf, clen);
|
||||
__iowrite32_copy(piobuf + 2, tmpbuf, plen);
|
||||
|
||||
ipath_flush_wc();
|
||||
|
||||
|
||||
@@ -695,6 +695,7 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
|
||||
|
||||
if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
|
||||
mthca_free_cq(to_mdev(ibdev), cq);
|
||||
err = -EFAULT;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
|
||||
@@ -1186,7 +1186,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
|
||||
nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
|
||||
kfree(nesqp->allocated_buffer);
|
||||
nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n");
|
||||
return NULL;
|
||||
return ERR_PTR(-EFAULT);
|
||||
}
|
||||
if (req.user_wqe_buffers) {
|
||||
virt_wqs = 1;
|
||||
|
||||
@@ -1578,7 +1578,7 @@ static int do_qib_user_sdma_queue_create(struct file *fp)
|
||||
struct qib_ctxtdata *rcd = fd->rcd;
|
||||
struct qib_devdata *dd = rcd->dd;
|
||||
|
||||
if (dd->flags & QIB_HAS_SEND_DMA)
|
||||
if (dd->flags & QIB_HAS_SEND_DMA) {
|
||||
|
||||
fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev,
|
||||
dd->unit,
|
||||
@@ -1586,6 +1586,7 @@ static int do_qib_user_sdma_queue_create(struct file *fp)
|
||||
fd->subctxt);
|
||||
if (!fd->pq)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1097,14 +1097,10 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
|
||||
int ret;
|
||||
|
||||
dd = (struct qib_devdata *) ib_alloc_device(sizeof(*dd) + extra);
|
||||
if (!dd) {
|
||||
dd = ERR_PTR(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
if (!dd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
qib_dbg_ibdev_init(&dd->verbs_dev);
|
||||
#endif
|
||||
INIT_LIST_HEAD(&dd->list);
|
||||
|
||||
idr_preload(GFP_KERNEL);
|
||||
spin_lock_irqsave(&qib_devs_lock, flags);
|
||||
@@ -1121,11 +1117,6 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
|
||||
if (ret < 0) {
|
||||
qib_early_err(&pdev->dev,
|
||||
"Could not allocate unit ID: error %d\n", -ret);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
qib_dbg_ibdev_exit(&dd->verbs_dev);
|
||||
#endif
|
||||
ib_dealloc_device(&dd->verbs_dev.ibdev);
|
||||
dd = ERR_PTR(ret);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
@@ -1139,9 +1130,15 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra)
|
||||
qib_early_err(&pdev->dev,
|
||||
"Could not alloc cpulist info, cpu affinity might be wrong\n");
|
||||
}
|
||||
|
||||
bail:
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
qib_dbg_ibdev_init(&dd->verbs_dev);
|
||||
#endif
|
||||
return dd;
|
||||
bail:
|
||||
if (!list_empty(&dd->list))
|
||||
list_del_init(&dd->list);
|
||||
ib_dealloc_device(&dd->verbs_dev.ibdev);
|
||||
return ERR_PTR(ret);;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -426,11 +426,18 @@ isert_conn_create_frwr_pool(struct isert_conn *isert_conn)
|
||||
{
|
||||
struct fast_reg_descriptor *fr_desc;
|
||||
struct isert_device *device = isert_conn->conn_device;
|
||||
int i, ret;
|
||||
struct se_session *se_sess = isert_conn->conn->sess->se_sess;
|
||||
struct se_node_acl *se_nacl = se_sess->se_node_acl;
|
||||
int i, ret, tag_num;
|
||||
/*
|
||||
* Setup the number of FRMRs based upon the number of tags
|
||||
* available to session in iscsi_target_locate_portal().
|
||||
*/
|
||||
tag_num = max_t(u32, ISCSIT_MIN_TAGS, se_nacl->queue_depth);
|
||||
tag_num = (tag_num * 2) + ISCSIT_EXTRA_TAGS;
|
||||
|
||||
INIT_LIST_HEAD(&isert_conn->conn_frwr_pool);
|
||||
isert_conn->conn_frwr_pool_size = 0;
|
||||
for (i = 0; i < ISCSI_DEF_XMIT_CMDS_MAX; i++) {
|
||||
for (i = 0; i < tag_num; i++) {
|
||||
fr_desc = kzalloc(sizeof(*fr_desc), GFP_KERNEL);
|
||||
if (!fr_desc) {
|
||||
pr_err("Failed to allocate fast_reg descriptor\n");
|
||||
@@ -502,6 +509,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
||||
kref_get(&isert_conn->conn_kref);
|
||||
mutex_init(&isert_conn->conn_mutex);
|
||||
spin_lock_init(&isert_conn->conn_lock);
|
||||
INIT_LIST_HEAD(&isert_conn->conn_frwr_pool);
|
||||
|
||||
cma_id->context = isert_conn;
|
||||
isert_conn->conn_cm_id = cma_id;
|
||||
@@ -559,14 +567,6 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
||||
isert_conn->conn_pd = device->dev_pd;
|
||||
isert_conn->conn_mr = device->dev_mr;
|
||||
|
||||
if (device->use_frwr) {
|
||||
ret = isert_conn_create_frwr_pool(isert_conn);
|
||||
if (ret) {
|
||||
pr_err("Conn: %p failed to create frwr_pool\n", isert_conn);
|
||||
goto out_frwr;
|
||||
}
|
||||
}
|
||||
|
||||
ret = isert_conn_setup_qp(isert_conn, cma_id);
|
||||
if (ret)
|
||||
goto out_conn_dev;
|
||||
@@ -580,9 +580,6 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
||||
return 0;
|
||||
|
||||
out_conn_dev:
|
||||
if (device->use_frwr)
|
||||
isert_conn_free_frwr_pool(isert_conn);
|
||||
out_frwr:
|
||||
isert_device_try_release(device);
|
||||
out_rsp_dma_map:
|
||||
ib_dma_unmap_single(ib_dev, isert_conn->login_rsp_dma,
|
||||
@@ -930,6 +927,15 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
|
||||
}
|
||||
if (!login->login_failed) {
|
||||
if (login->login_complete) {
|
||||
if (isert_conn->conn_device->use_frwr) {
|
||||
ret = isert_conn_create_frwr_pool(isert_conn);
|
||||
if (ret) {
|
||||
pr_err("Conn: %p failed to create"
|
||||
" frwr_pool\n", isert_conn);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = isert_alloc_rx_descriptors(isert_conn);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1414,7 +1420,7 @@ isert_unreg_rdma_frwr(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn
|
||||
}
|
||||
|
||||
static void
|
||||
isert_put_cmd(struct isert_cmd *isert_cmd)
|
||||
isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
|
||||
{
|
||||
struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd;
|
||||
struct isert_conn *isert_conn = isert_cmd->conn;
|
||||
@@ -1430,8 +1436,21 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
|
||||
list_del_init(&cmd->i_conn_node);
|
||||
spin_unlock_bh(&conn->cmd_lock);
|
||||
|
||||
if (cmd->data_direction == DMA_TO_DEVICE)
|
||||
if (cmd->data_direction == DMA_TO_DEVICE) {
|
||||
iscsit_stop_dataout_timer(cmd);
|
||||
/*
|
||||
* Check for special case during comp_err where
|
||||
* WRITE_PENDING has been handed off from core,
|
||||
* but requires an extra target_put_sess_cmd()
|
||||
* before transport_generic_free_cmd() below.
|
||||
*/
|
||||
if (comp_err &&
|
||||
cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
|
||||
struct se_cmd *se_cmd = &cmd->se_cmd;
|
||||
|
||||
target_put_sess_cmd(se_cmd->se_sess, se_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
device->unreg_rdma_mem(isert_cmd, isert_conn);
|
||||
transport_generic_free_cmd(&cmd->se_cmd, 0);
|
||||
@@ -1486,7 +1505,7 @@ isert_unmap_tx_desc(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev)
|
||||
|
||||
static void
|
||||
isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
|
||||
struct ib_device *ib_dev)
|
||||
struct ib_device *ib_dev, bool comp_err)
|
||||
{
|
||||
if (isert_cmd->pdu_buf_dma != 0) {
|
||||
pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n");
|
||||
@@ -1496,7 +1515,7 @@ isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
|
||||
}
|
||||
|
||||
isert_unmap_tx_desc(tx_desc, ib_dev);
|
||||
isert_put_cmd(isert_cmd);
|
||||
isert_put_cmd(isert_cmd, comp_err);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1540,14 +1559,14 @@ isert_do_control_comp(struct work_struct *work)
|
||||
iscsit_tmr_post_handler(cmd, cmd->conn);
|
||||
|
||||
cmd->i_state = ISTATE_SENT_STATUS;
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
|
||||
break;
|
||||
case ISTATE_SEND_REJECT:
|
||||
pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n");
|
||||
atomic_dec(&isert_conn->post_send_buf_count);
|
||||
|
||||
cmd->i_state = ISTATE_SENT_STATUS;
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
|
||||
break;
|
||||
case ISTATE_SEND_LOGOUTRSP:
|
||||
pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
|
||||
@@ -1561,7 +1580,7 @@ isert_do_control_comp(struct work_struct *work)
|
||||
case ISTATE_SEND_TEXTRSP:
|
||||
atomic_dec(&isert_conn->post_send_buf_count);
|
||||
cmd->i_state = ISTATE_SENT_STATUS;
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
|
||||
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state);
|
||||
@@ -1592,7 +1611,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc,
|
||||
atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count);
|
||||
|
||||
cmd->i_state = ISTATE_SENT_STATUS;
|
||||
isert_completion_put(tx_desc, isert_cmd, ib_dev);
|
||||
isert_completion_put(tx_desc, isert_cmd, ib_dev, false);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1646,7 +1665,7 @@ isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn
|
||||
if (!isert_cmd)
|
||||
isert_unmap_tx_desc(tx_desc, ib_dev);
|
||||
else
|
||||
isert_completion_put(tx_desc, isert_cmd, ib_dev);
|
||||
isert_completion_put(tx_desc, isert_cmd, ib_dev, true);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1078,6 +1078,7 @@ static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
struct srpt_send_ioctx *ioctx)
|
||||
{
|
||||
struct ib_device *dev = ch->sport->sdev->device;
|
||||
struct se_cmd *cmd;
|
||||
struct scatterlist *sg, *sg_orig;
|
||||
int sg_cnt;
|
||||
@@ -1124,7 +1125,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
|
||||
db = ioctx->rbufs;
|
||||
tsize = cmd->data_length;
|
||||
dma_len = sg_dma_len(&sg[0]);
|
||||
dma_len = ib_sg_dma_len(dev, &sg[0]);
|
||||
riu = ioctx->rdma_ius;
|
||||
|
||||
/*
|
||||
@@ -1155,7 +1156,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
++j;
|
||||
if (j < count) {
|
||||
sg = sg_next(sg);
|
||||
dma_len = sg_dma_len(sg);
|
||||
dma_len = ib_sg_dma_len(
|
||||
dev, sg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1192,8 +1194,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
tsize = cmd->data_length;
|
||||
riu = ioctx->rdma_ius;
|
||||
sg = sg_orig;
|
||||
dma_len = sg_dma_len(&sg[0]);
|
||||
dma_addr = sg_dma_address(&sg[0]);
|
||||
dma_len = ib_sg_dma_len(dev, &sg[0]);
|
||||
dma_addr = ib_sg_dma_address(dev, &sg[0]);
|
||||
|
||||
/* this second loop is really mapped sg_addres to rdma_iu->ib_sge */
|
||||
for (i = 0, j = 0;
|
||||
@@ -1216,8 +1218,10 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
|
||||
++j;
|
||||
if (j < count) {
|
||||
sg = sg_next(sg);
|
||||
dma_len = sg_dma_len(sg);
|
||||
dma_addr = sg_dma_address(sg);
|
||||
dma_len = ib_sg_dma_len(
|
||||
dev, sg);
|
||||
dma_addr = ib_sg_dma_address(
|
||||
dev, sg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1514,6 +1514,22 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
||||
},
|
||||
.driver_data = (int []){1232, 5710, 1156, 4696},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad Edge E431 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5022, 2508, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad T431s */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad T440s */
|
||||
.matches = {
|
||||
@@ -1522,6 +1538,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad L440 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad T540p */
|
||||
.matches = {
|
||||
@@ -1530,6 +1554,32 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = {
|
||||
},
|
||||
.driver_data = (int []){1024, 5056, 2058, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad L540 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
{
|
||||
/* Lenovo Yoga S1 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION,
|
||||
"ThinkPad S1 Yoga"),
|
||||
},
|
||||
.driver_data = (int []){1232, 5710, 1156, 4696},
|
||||
},
|
||||
{
|
||||
/* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION,
|
||||
"ThinkPad X1 Carbon 2nd"),
|
||||
},
|
||||
.driver_data = (int []){1024, 5112, 2024, 4832},
|
||||
},
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -114,6 +114,12 @@ struct dm_cache_metadata {
|
||||
unsigned policy_version[CACHE_POLICY_VERSION_SIZE];
|
||||
size_t policy_hint_size;
|
||||
struct dm_cache_statistics stats;
|
||||
|
||||
/*
|
||||
* Reading the space map root can fail, so we read it into this
|
||||
* buffer before the superblock is locked and updated.
|
||||
*/
|
||||
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
@@ -242,11 +248,31 @@ static void __setup_mapping_info(struct dm_cache_metadata *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
static int __save_sm_root(struct dm_cache_metadata *cmd)
|
||||
{
|
||||
int r;
|
||||
size_t metadata_len;
|
||||
|
||||
r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dm_sm_copy_root(cmd->metadata_sm, &cmd->metadata_space_map_root,
|
||||
metadata_len);
|
||||
}
|
||||
|
||||
static void __copy_sm_root(struct dm_cache_metadata *cmd,
|
||||
struct cache_disk_superblock *disk_super)
|
||||
{
|
||||
memcpy(&disk_super->metadata_space_map_root,
|
||||
&cmd->metadata_space_map_root,
|
||||
sizeof(cmd->metadata_space_map_root));
|
||||
}
|
||||
|
||||
static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||
{
|
||||
int r;
|
||||
struct dm_block *sblock;
|
||||
size_t metadata_len;
|
||||
struct cache_disk_superblock *disk_super;
|
||||
sector_t bdev_size = i_size_read(cmd->bdev->bd_inode) >> SECTOR_SHIFT;
|
||||
|
||||
@@ -254,12 +280,16 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||
if (bdev_size > DM_CACHE_METADATA_MAX_SECTORS)
|
||||
bdev_size = DM_CACHE_METADATA_MAX_SECTORS;
|
||||
|
||||
r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
|
||||
r = dm_tm_pre_commit(cmd->tm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_tm_pre_commit(cmd->tm);
|
||||
if (r < 0)
|
||||
/*
|
||||
* dm_sm_copy_root() can fail. So we need to do it before we start
|
||||
* updating the superblock.
|
||||
*/
|
||||
r = __save_sm_root(cmd);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = superblock_lock_zero(cmd, &sblock);
|
||||
@@ -275,10 +305,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||
memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
|
||||
disk_super->policy_hint_size = 0;
|
||||
|
||||
r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
|
||||
metadata_len);
|
||||
if (r < 0)
|
||||
goto bad_locked;
|
||||
__copy_sm_root(cmd, disk_super);
|
||||
|
||||
disk_super->mapping_root = cpu_to_le64(cmd->root);
|
||||
disk_super->hint_root = cpu_to_le64(cmd->hint_root);
|
||||
@@ -295,10 +322,6 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||
disk_super->write_misses = cpu_to_le32(0);
|
||||
|
||||
return dm_tm_commit(cmd->tm, sblock);
|
||||
|
||||
bad_locked:
|
||||
dm_bm_unlock(sblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int __format_metadata(struct dm_cache_metadata *cmd)
|
||||
@@ -511,8 +534,9 @@ static int __begin_transaction_flags(struct dm_cache_metadata *cmd,
|
||||
disk_super = dm_block_data(sblock);
|
||||
update_flags(disk_super, mutator);
|
||||
read_superblock_fields(cmd, disk_super);
|
||||
dm_bm_unlock(sblock);
|
||||
|
||||
return dm_bm_flush_and_unlock(cmd->bm, sblock);
|
||||
return dm_bm_flush(cmd->bm);
|
||||
}
|
||||
|
||||
static int __begin_transaction(struct dm_cache_metadata *cmd)
|
||||
@@ -540,7 +564,6 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
|
||||
flags_mutator mutator)
|
||||
{
|
||||
int r;
|
||||
size_t metadata_len;
|
||||
struct cache_disk_superblock *disk_super;
|
||||
struct dm_block *sblock;
|
||||
|
||||
@@ -558,8 +581,8 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
|
||||
if (r < 0)
|
||||
r = __save_sm_root(cmd);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = superblock_lock(cmd, &sblock);
|
||||
@@ -586,13 +609,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
|
||||
disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
|
||||
disk_super->write_hits = cpu_to_le32(cmd->stats.write_hits);
|
||||
disk_super->write_misses = cpu_to_le32(cmd->stats.write_misses);
|
||||
|
||||
r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
|
||||
metadata_len);
|
||||
if (r < 0) {
|
||||
dm_bm_unlock(sblock);
|
||||
return r;
|
||||
}
|
||||
__copy_sm_root(cmd, disk_super);
|
||||
|
||||
return dm_tm_commit(cmd->tm, sblock);
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ struct cache {
|
||||
*/
|
||||
dm_dblock_t discard_nr_blocks;
|
||||
unsigned long *discard_bitset;
|
||||
uint32_t discard_block_size; /* a power of 2 times sectors per block */
|
||||
uint32_t discard_block_size;
|
||||
|
||||
/*
|
||||
* Rather than reconstructing the table line for the status we just
|
||||
@@ -1908,35 +1908,6 @@ static int create_cache_policy(struct cache *cache, struct cache_args *ca,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We want the discard block size to be a power of two, at least the size
|
||||
* of the cache block size, and have no more than 2^14 discard blocks
|
||||
* across the origin.
|
||||
*/
|
||||
#define MAX_DISCARD_BLOCKS (1 << 14)
|
||||
|
||||
static bool too_many_discard_blocks(sector_t discard_block_size,
|
||||
sector_t origin_size)
|
||||
{
|
||||
(void) sector_div(origin_size, discard_block_size);
|
||||
|
||||
return origin_size > MAX_DISCARD_BLOCKS;
|
||||
}
|
||||
|
||||
static sector_t calculate_discard_block_size(sector_t cache_block_size,
|
||||
sector_t origin_size)
|
||||
{
|
||||
sector_t discard_block_size;
|
||||
|
||||
discard_block_size = roundup_pow_of_two(cache_block_size);
|
||||
|
||||
if (origin_size)
|
||||
while (too_many_discard_blocks(discard_block_size, origin_size))
|
||||
discard_block_size *= 2;
|
||||
|
||||
return discard_block_size;
|
||||
}
|
||||
|
||||
#define DEFAULT_MIGRATION_THRESHOLD 2048
|
||||
|
||||
static int cache_create(struct cache_args *ca, struct cache **result)
|
||||
@@ -2041,9 +2012,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
|
||||
}
|
||||
clear_bitset(cache->dirty_bitset, from_cblock(cache->cache_size));
|
||||
|
||||
cache->discard_block_size =
|
||||
calculate_discard_block_size(cache->sectors_per_block,
|
||||
cache->origin_sectors);
|
||||
cache->discard_block_size = cache->sectors_per_block;
|
||||
cache->discard_nr_blocks = oblock_to_dblock(cache, cache->origin_blocks);
|
||||
cache->discard_bitset = alloc_bitset(from_dblock(cache->discard_nr_blocks));
|
||||
if (!cache->discard_bitset) {
|
||||
@@ -2630,7 +2599,7 @@ static void set_discard_limits(struct cache *cache, struct queue_limits *limits)
|
||||
/*
|
||||
* FIXME: these limits may be incompatible with the cache device
|
||||
*/
|
||||
limits->max_discard_sectors = cache->discard_block_size * 1024;
|
||||
limits->max_discard_sectors = cache->discard_block_size;
|
||||
limits->discard_granularity = cache->discard_block_size << SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,13 @@ struct dm_pool_metadata {
|
||||
* operation possible in this state is the closing of the device.
|
||||
*/
|
||||
bool fail_io:1;
|
||||
|
||||
/*
|
||||
* Reading the space map roots can fail, so we read it into these
|
||||
* buffers before the superblock is locked and updated.
|
||||
*/
|
||||
__u8 data_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||
__u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
|
||||
};
|
||||
|
||||
struct dm_thin_device {
|
||||
@@ -431,29 +438,56 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
|
||||
pmd->details_info.value_type.equal = NULL;
|
||||
}
|
||||
|
||||
static int save_sm_roots(struct dm_pool_metadata *pmd)
|
||||
{
|
||||
int r;
|
||||
size_t len;
|
||||
|
||||
r = dm_sm_root_size(pmd->metadata_sm, &len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_sm_copy_root(pmd->metadata_sm, &pmd->metadata_space_map_root, len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_sm_root_size(pmd->data_sm, &len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dm_sm_copy_root(pmd->data_sm, &pmd->data_space_map_root, len);
|
||||
}
|
||||
|
||||
static void copy_sm_roots(struct dm_pool_metadata *pmd,
|
||||
struct thin_disk_superblock *disk)
|
||||
{
|
||||
memcpy(&disk->metadata_space_map_root,
|
||||
&pmd->metadata_space_map_root,
|
||||
sizeof(pmd->metadata_space_map_root));
|
||||
|
||||
memcpy(&disk->data_space_map_root,
|
||||
&pmd->data_space_map_root,
|
||||
sizeof(pmd->data_space_map_root));
|
||||
}
|
||||
|
||||
static int __write_initial_superblock(struct dm_pool_metadata *pmd)
|
||||
{
|
||||
int r;
|
||||
struct dm_block *sblock;
|
||||
size_t metadata_len, data_len;
|
||||
struct thin_disk_superblock *disk_super;
|
||||
sector_t bdev_size = i_size_read(pmd->bdev->bd_inode) >> SECTOR_SHIFT;
|
||||
|
||||
if (bdev_size > THIN_METADATA_MAX_SECTORS)
|
||||
bdev_size = THIN_METADATA_MAX_SECTORS;
|
||||
|
||||
r = dm_sm_root_size(pmd->metadata_sm, &metadata_len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_sm_root_size(pmd->data_sm, &data_len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_sm_commit(pmd->data_sm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = save_sm_roots(pmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_tm_pre_commit(pmd->tm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -471,15 +505,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
|
||||
disk_super->trans_id = 0;
|
||||
disk_super->held_root = 0;
|
||||
|
||||
r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root,
|
||||
metadata_len);
|
||||
if (r < 0)
|
||||
goto bad_locked;
|
||||
|
||||
r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root,
|
||||
data_len);
|
||||
if (r < 0)
|
||||
goto bad_locked;
|
||||
copy_sm_roots(pmd, disk_super);
|
||||
|
||||
disk_super->data_mapping_root = cpu_to_le64(pmd->root);
|
||||
disk_super->device_details_root = cpu_to_le64(pmd->details_root);
|
||||
@@ -488,10 +514,6 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
|
||||
disk_super->data_block_size = cpu_to_le32(pmd->data_block_size);
|
||||
|
||||
return dm_tm_commit(pmd->tm, sblock);
|
||||
|
||||
bad_locked:
|
||||
dm_bm_unlock(sblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int __format_metadata(struct dm_pool_metadata *pmd)
|
||||
@@ -769,6 +791,10 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = save_sm_roots(pmd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = superblock_lock(pmd, &sblock);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -780,21 +806,9 @@ static int __commit_transaction(struct dm_pool_metadata *pmd)
|
||||
disk_super->trans_id = cpu_to_le64(pmd->trans_id);
|
||||
disk_super->flags = cpu_to_le32(pmd->flags);
|
||||
|
||||
r = dm_sm_copy_root(pmd->metadata_sm, &disk_super->metadata_space_map_root,
|
||||
metadata_len);
|
||||
if (r < 0)
|
||||
goto out_locked;
|
||||
|
||||
r = dm_sm_copy_root(pmd->data_sm, &disk_super->data_space_map_root,
|
||||
data_len);
|
||||
if (r < 0)
|
||||
goto out_locked;
|
||||
copy_sm_roots(pmd, disk_super);
|
||||
|
||||
return dm_tm_commit(pmd->tm, sblock);
|
||||
|
||||
out_locked:
|
||||
dm_bm_unlock(sblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev,
|
||||
|
||||
@@ -1332,9 +1332,9 @@ static void process_deferred_bios(struct pool *pool)
|
||||
*/
|
||||
if (ensure_next_mapping(pool)) {
|
||||
spin_lock_irqsave(&pool->lock, flags);
|
||||
bio_list_add(&pool->deferred_bios, bio);
|
||||
bio_list_merge(&pool->deferred_bios, &bios);
|
||||
spin_unlock_irqrestore(&pool->lock, flags);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -595,25 +595,14 @@ int dm_bm_unlock(struct dm_block *b)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_bm_unlock);
|
||||
|
||||
int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
|
||||
struct dm_block *superblock)
|
||||
int dm_bm_flush(struct dm_block_manager *bm)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (bm->read_only)
|
||||
return -EPERM;
|
||||
|
||||
r = dm_bufio_write_dirty_buffers(bm->bufio);
|
||||
if (unlikely(r)) {
|
||||
dm_bm_unlock(superblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
dm_bm_unlock(superblock);
|
||||
|
||||
return dm_bufio_write_dirty_buffers(bm->bufio);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock);
|
||||
EXPORT_SYMBOL_GPL(dm_bm_flush);
|
||||
|
||||
void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b)
|
||||
{
|
||||
|
||||
@@ -105,8 +105,7 @@ int dm_bm_unlock(struct dm_block *b);
|
||||
*
|
||||
* This method always blocks.
|
||||
*/
|
||||
int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
|
||||
struct dm_block *superblock);
|
||||
int dm_bm_flush(struct dm_block_manager *bm);
|
||||
|
||||
/*
|
||||
* Request data is prefetched into the cache.
|
||||
|
||||
@@ -154,7 +154,7 @@ int dm_tm_pre_commit(struct dm_transaction_manager *tm)
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return dm_bm_flush(tm->bm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_tm_pre_commit);
|
||||
|
||||
@@ -164,8 +164,9 @@ int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root)
|
||||
return -EWOULDBLOCK;
|
||||
|
||||
wipe_shadow_table(tm);
|
||||
dm_bm_unlock(root);
|
||||
|
||||
return dm_bm_flush_and_unlock(tm->bm, root);
|
||||
return dm_bm_flush(tm->bm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_tm_commit);
|
||||
|
||||
|
||||
@@ -38,18 +38,17 @@ struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transac
|
||||
/*
|
||||
* We use a 2-phase commit here.
|
||||
*
|
||||
* i) In the first phase the block manager is told to start flushing, and
|
||||
* the changes to the space map are written to disk. You should interrogate
|
||||
* your particular space map to get detail of its root node etc. to be
|
||||
* included in your superblock.
|
||||
* i) Make all changes for the transaction *except* for the superblock.
|
||||
* Then call dm_tm_pre_commit() to flush them to disk.
|
||||
*
|
||||
* ii) @root will be committed last. You shouldn't use more than the
|
||||
* first 512 bytes of @root if you wish the transaction to survive a power
|
||||
* failure. You *must* have a write lock held on @root for both stage (i)
|
||||
* and (ii). The commit will drop the write lock.
|
||||
* ii) Lock your superblock. Update. Then call dm_tm_commit() which will
|
||||
* unlock the superblock and flush it. No other blocks should be updated
|
||||
* during this period. Care should be taken to never unlock a partially
|
||||
* updated superblock; perform any operations that could fail *before* you
|
||||
* take the superblock lock.
|
||||
*/
|
||||
int dm_tm_pre_commit(struct dm_transaction_manager *tm);
|
||||
int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root);
|
||||
int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *superblock);
|
||||
|
||||
/*
|
||||
* These methods are the only way to get hold of a writeable block.
|
||||
|
||||
@@ -712,6 +712,22 @@ static int m88rs2000_get_frontend(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m88rs2000_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *tune)
|
||||
{
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
if (c->symbol_rate > 3000000)
|
||||
tune->min_delay_ms = 2000;
|
||||
else
|
||||
tune->min_delay_ms = 3000;
|
||||
|
||||
tune->step_size = c->symbol_rate / 16000;
|
||||
tune->max_drift = c->symbol_rate / 2000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct m88rs2000_state *state = fe->demodulator_priv;
|
||||
@@ -743,7 +759,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
|
||||
.symbol_rate_tolerance = 500, /* ppm */
|
||||
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_QPSK | FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO
|
||||
},
|
||||
|
||||
@@ -763,6 +779,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
|
||||
|
||||
.set_frontend = m88rs2000_set_frontend,
|
||||
.get_frontend = m88rs2000_get_frontend,
|
||||
.get_tune_settings = m88rs2000_get_tune_settings,
|
||||
};
|
||||
|
||||
struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
|
||||
|
||||
@@ -8045,8 +8045,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
|
||||
break;
|
||||
} /* switch() */
|
||||
|
||||
/* initialize tuner */
|
||||
if (TUNER_ABSENT != dev->tuner_type) {
|
||||
/* initialize tuner (don't do this when resuming) */
|
||||
if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) {
|
||||
int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
|
||||
|
||||
/* Note: radio tuner address is always filled in,
|
||||
|
||||
@@ -1079,6 +1079,7 @@ static void preview_config_input_format(struct isp_prev_device *prev,
|
||||
*/
|
||||
static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
|
||||
{
|
||||
const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
|
||||
struct isp_device *isp = to_isp_device(prev);
|
||||
unsigned int sph = prev->crop.left;
|
||||
unsigned int eph = prev->crop.left + prev->crop.width - 1;
|
||||
@@ -1086,6 +1087,14 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
|
||||
unsigned int elv = prev->crop.top + prev->crop.height - 1;
|
||||
u32 features;
|
||||
|
||||
if (format->code != V4L2_MBUS_FMT_Y8_1X8 &&
|
||||
format->code != V4L2_MBUS_FMT_Y10_1X10) {
|
||||
sph -= 2;
|
||||
eph += 2;
|
||||
slv -= 2;
|
||||
elv += 2;
|
||||
}
|
||||
|
||||
features = (prev->params.params[0].features & active)
|
||||
| (prev->params.params[1].features & ~active);
|
||||
|
||||
|
||||
@@ -673,7 +673,8 @@ static void pctv_520e_init(struct em28xx *dev)
|
||||
static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
struct em28xx *dev = fe->dvb->priv;
|
||||
struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv;
|
||||
struct em28xx *dev = i2c_bus->dev;
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct em28xx_dvb *dvb = dev->dvb;
|
||||
int ret;
|
||||
|
||||
@@ -2359,6 +2359,7 @@ static const struct usb_device_id device_table[] = {
|
||||
{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
|
||||
{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
|
||||
{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
|
||||
{USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
|
||||
{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
|
||||
{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
|
||||
{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
|
||||
|
||||
@@ -1846,7 +1846,25 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
|
||||
|
||||
if (!enable) {
|
||||
uvc_uninit_video(stream, 1);
|
||||
usb_set_interface(stream->dev->udev, stream->intfnum, 0);
|
||||
if (stream->intf->num_altsetting > 1) {
|
||||
usb_set_interface(stream->dev->udev,
|
||||
stream->intfnum, 0);
|
||||
} else {
|
||||
/* UVC doesn't specify how to inform a bulk-based device
|
||||
* when the video stream is stopped. Windows sends a
|
||||
* CLEAR_FEATURE(HALT) request to the video streaming
|
||||
* bulk endpoint, mimic the same behaviour.
|
||||
*/
|
||||
unsigned int epnum = stream->header.bEndpointAddress
|
||||
& USB_ENDPOINT_NUMBER_MASK;
|
||||
unsigned int dir = stream->header.bEndpointAddress
|
||||
& USB_ENDPOINT_DIR_MASK;
|
||||
unsigned int pipe;
|
||||
|
||||
pipe = usb_sndbulkpipe(stream->dev->udev, epnum) | dir;
|
||||
usb_clear_halt(stream->dev->udev, pipe);
|
||||
}
|
||||
|
||||
uvc_queue_enable(&stream->queue, 0);
|
||||
uvc_video_clock_cleanup(stream);
|
||||
return 0;
|
||||
|
||||
@@ -787,8 +787,8 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
|
||||
#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
|
||||
#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
|
||||
#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
|
||||
#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 63, struct v4l2_subdev_edid32)
|
||||
#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 64, struct v4l2_subdev_edid32)
|
||||
#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 40, struct v4l2_subdev_edid32)
|
||||
#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 41, struct v4l2_subdev_edid32)
|
||||
#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
|
||||
#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
|
||||
#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include <linux/v4l2-dv-timings.h>
|
||||
#include <media/v4l2-dv-timings.h>
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil");
|
||||
MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
const struct v4l2_dv_timings v4l2_dv_timings_presets[] = {
|
||||
V4L2_DV_BT_CEA_640X480P59_94,
|
||||
V4L2_DV_BT_CEA_720X480I59_94,
|
||||
|
||||
@@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client,
|
||||
ret = pm800_pages_init(chip);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "pm800_pages_init failed!\n");
|
||||
goto err_page_init;
|
||||
goto err_device_init;
|
||||
}
|
||||
|
||||
ret = device_800_init(chip, pdata);
|
||||
@@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client,
|
||||
|
||||
err_device_init:
|
||||
pm800_pages_exit(chip);
|
||||
err_page_init:
|
||||
err_subchip_alloc:
|
||||
pm80x_deinit();
|
||||
out_init:
|
||||
|
||||
@@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client,
|
||||
chip->companion_addr = pdata->companion_addr;
|
||||
chip->companion = i2c_new_dummy(chip->client->adapter,
|
||||
chip->companion_addr);
|
||||
if (!chip->companion) {
|
||||
dev_err(&client->dev,
|
||||
"Failed to allocate I2C companion device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
chip->regmap_companion = regmap_init_i2c(chip->companion,
|
||||
&pm860x_regmap_config);
|
||||
if (IS_ERR(chip->regmap_companion)) {
|
||||
ret = PTR_ERR(chip->regmap_companion);
|
||||
dev_err(&chip->companion->dev,
|
||||
"Failed to allocate register map: %d\n", ret);
|
||||
i2c_unregister_device(chip->companion);
|
||||
return ret;
|
||||
}
|
||||
i2c_set_clientdata(chip->companion, chip);
|
||||
|
||||
@@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Release hardware mutex if aquired */
|
||||
if (!(index_reg & KEMPLD_MUTEX_KEY))
|
||||
/* Release hardware mutex if acquired */
|
||||
if (!(index_reg & KEMPLD_MUTEX_KEY)) {
|
||||
iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
|
||||
/* PXT and COMe-cPC2 boards may require a second release */
|
||||
iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
|
||||
}
|
||||
|
||||
mutex_unlock(&pld->lock);
|
||||
|
||||
|
||||
@@ -120,6 +120,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
|
||||
dev_info(max77686->dev, "device found\n");
|
||||
|
||||
max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
|
||||
if (!max77686->rtc) {
|
||||
dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(max77686->rtc, max77686);
|
||||
|
||||
max77686_irq_init(max77686);
|
||||
|
||||
@@ -149,9 +149,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
|
||||
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
|
||||
|
||||
max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
|
||||
if (!max77693->muic) {
|
||||
dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(max77693->muic, max77693);
|
||||
|
||||
max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
|
||||
if (!max77693->haptic) {
|
||||
dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
|
||||
ret = -ENODEV;
|
||||
goto err_i2c_haptic;
|
||||
}
|
||||
i2c_set_clientdata(max77693->haptic, max77693);
|
||||
|
||||
/*
|
||||
@@ -187,8 +196,9 @@ err_mfd:
|
||||
max77693_irq_exit(max77693);
|
||||
err_irq:
|
||||
err_regmap_muic:
|
||||
i2c_unregister_device(max77693->muic);
|
||||
i2c_unregister_device(max77693->haptic);
|
||||
err_i2c_haptic:
|
||||
i2c_unregister_device(max77693->muic);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client,
|
||||
mutex_init(&chip->io_lock);
|
||||
|
||||
chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
|
||||
if (!chip->rtc) {
|
||||
dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(chip->rtc, chip);
|
||||
|
||||
chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
|
||||
if (!chip->adc) {
|
||||
dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
|
||||
i2c_unregister_device(chip->rtc);
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(chip->adc, chip);
|
||||
|
||||
device_init_wakeup(&client->dev, 1);
|
||||
|
||||
@@ -217,10 +217,26 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
|
||||
mutex_init(&max8997->iolock);
|
||||
|
||||
max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
|
||||
if (!max8997->rtc) {
|
||||
dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(max8997->rtc, max8997);
|
||||
|
||||
max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
|
||||
if (!max8997->haptic) {
|
||||
dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n");
|
||||
ret = -ENODEV;
|
||||
goto err_i2c_haptic;
|
||||
}
|
||||
i2c_set_clientdata(max8997->haptic, max8997);
|
||||
|
||||
max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
|
||||
if (!max8997->muic) {
|
||||
dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n");
|
||||
ret = -ENODEV;
|
||||
goto err_i2c_muic;
|
||||
}
|
||||
i2c_set_clientdata(max8997->muic, max8997);
|
||||
|
||||
pm_runtime_set_active(max8997->dev);
|
||||
@@ -247,7 +263,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
|
||||
err_mfd:
|
||||
mfd_remove_devices(max8997->dev);
|
||||
i2c_unregister_device(max8997->muic);
|
||||
err_i2c_muic:
|
||||
i2c_unregister_device(max8997->haptic);
|
||||
err_i2c_haptic:
|
||||
i2c_unregister_device(max8997->rtc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -215,6 +215,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
|
||||
mutex_init(&max8998->iolock);
|
||||
|
||||
max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
|
||||
if (!max8998->rtc) {
|
||||
dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(max8998->rtc, max8998);
|
||||
|
||||
max8998_irq_init(max8998);
|
||||
|
||||
@@ -274,6 +274,10 @@ static int sec_pmic_probe(struct i2c_client *i2c,
|
||||
}
|
||||
|
||||
sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
|
||||
if (!sec_pmic->rtc) {
|
||||
dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(sec_pmic->rtc, sec_pmic);
|
||||
|
||||
if (pdata && pdata->cfg_pmic_irq)
|
||||
|
||||
@@ -254,8 +254,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
|
||||
ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
|
||||
IRQF_ONESHOT, pdata->irq_base,
|
||||
tps6591x_irqs_chip, &tps65910->irq_data);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
|
||||
tps65910->chip_irq = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,21 +73,67 @@ int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mei_cl_cmp_id - tells if the clients are the same
|
||||
*
|
||||
* @cl1: host client 1
|
||||
* @cl2: host client 2
|
||||
*
|
||||
* returns true - if the clients has same host and me ids
|
||||
* false - otherwise
|
||||
*/
|
||||
static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
|
||||
const struct mei_cl *cl2)
|
||||
{
|
||||
return cl1 && cl2 &&
|
||||
(cl1->host_client_id == cl2->host_client_id) &&
|
||||
(cl1->me_client_id == cl2->me_client_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_flush - removes cbs belonging to cl.
|
||||
*
|
||||
* @list: an instance of our list structure
|
||||
* @cl: host client, can be NULL for flushing the whole list
|
||||
* @free: whether to free the cbs
|
||||
*/
|
||||
static void __mei_io_list_flush(struct mei_cl_cb *list,
|
||||
struct mei_cl *cl, bool free)
|
||||
{
|
||||
struct mei_cl_cb *cb;
|
||||
struct mei_cl_cb *next;
|
||||
|
||||
/* enable removing everything if no cl is specified */
|
||||
list_for_each_entry_safe(cb, next, &list->list, list) {
|
||||
if (!cl || (cb->cl && mei_cl_cmp_id(cl, cb->cl))) {
|
||||
list_del(&cb->list);
|
||||
if (free)
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_flush - removes list entry belonging to cl.
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
static inline void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
struct mei_cl_cb *cb;
|
||||
struct mei_cl_cb *next;
|
||||
__mei_io_list_flush(list, cl, false);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(cb, next, &list->list, list) {
|
||||
if (cb->cl && mei_cl_cmp_id(cl, cb->cl))
|
||||
list_del(&cb->list);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_free - removes cb belonging to cl and free them
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
__mei_io_list_flush(list, cl, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,8 +238,8 @@ int mei_cl_flush_queues(struct mei_cl *cl)
|
||||
|
||||
dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
|
||||
mei_io_list_flush(&cl->dev->read_list, cl);
|
||||
mei_io_list_flush(&cl->dev->write_list, cl);
|
||||
mei_io_list_flush(&cl->dev->write_waiting_list, cl);
|
||||
mei_io_list_free(&cl->dev->write_list, cl);
|
||||
mei_io_list_free(&cl->dev->write_waiting_list, cl);
|
||||
mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
|
||||
mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
|
||||
mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
|
||||
@@ -916,20 +962,8 @@ void mei_cl_all_wakeup(struct mei_device *dev)
|
||||
*/
|
||||
void mei_cl_all_write_clear(struct mei_device *dev)
|
||||
{
|
||||
struct mei_cl_cb *cb, *next;
|
||||
struct list_head *list;
|
||||
|
||||
list = &dev->write_list.list;
|
||||
list_for_each_entry_safe(cb, next, list, list) {
|
||||
list_del(&cb->list);
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
|
||||
list = &dev->write_waiting_list.list;
|
||||
list_for_each_entry_safe(cb, next, list, list) {
|
||||
list_del(&cb->list);
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
mei_io_list_free(&dev->write_list, NULL);
|
||||
mei_io_list_free(&dev->write_waiting_list, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ static inline void mei_io_list_init(struct mei_cl_cb *list)
|
||||
{
|
||||
INIT_LIST_HEAD(&list->list);
|
||||
}
|
||||
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
|
||||
|
||||
/*
|
||||
* MEI Host Client Functions
|
||||
*/
|
||||
@@ -61,22 +59,6 @@ int mei_cl_unlink(struct mei_cl *cl);
|
||||
int mei_cl_flush_queues(struct mei_cl *cl);
|
||||
struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl);
|
||||
|
||||
/**
|
||||
* mei_cl_cmp_id - tells if file private data have same id
|
||||
*
|
||||
* @fe1: private data of 1. file object
|
||||
* @fe2: private data of 2. file object
|
||||
*
|
||||
* returns true - if ids are the same and not NULL
|
||||
*/
|
||||
static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
|
||||
const struct mei_cl *cl2)
|
||||
{
|
||||
return cl1 && cl2 &&
|
||||
(cl1->host_client_id == cl2->host_client_id) &&
|
||||
(cl1->me_client_id == cl2->me_client_id);
|
||||
}
|
||||
|
||||
|
||||
int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
|
||||
|
||||
|
||||
@@ -115,6 +115,11 @@
|
||||
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */
|
||||
|
||||
#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
|
||||
|
||||
/* Host Firmware Status Registers in PCI Config Space */
|
||||
#define PCI_CFG_HFS_1 0x40
|
||||
#define PCI_CFG_HFS_2 0x48
|
||||
|
||||
/*
|
||||
* MEI HW Section
|
||||
*/
|
||||
|
||||
@@ -420,8 +420,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
|
||||
|
||||
cl->status = 0;
|
||||
list_del(&cb->list);
|
||||
if (MEI_WRITING == cl->writing_state &&
|
||||
cb->fop_type == MEI_FOP_WRITE &&
|
||||
if (cb->fop_type == MEI_FOP_WRITE &&
|
||||
cl != &dev->iamthif_cl) {
|
||||
dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
|
||||
cl->writing_state = MEI_WRITE_COMPLETE;
|
||||
|
||||
@@ -648,8 +648,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (MEI_WRITE_COMPLETE == cl->writing_state)
|
||||
mask |= (POLLIN | POLLRDNORM);
|
||||
mask |= (POLLIN | POLLRDNORM);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
||||
@@ -100,15 +100,31 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
u32 reg;
|
||||
if (ent->device == MEI_DEV_ID_PBG_1) {
|
||||
pci_read_config_dword(pdev, 0x48, ®);
|
||||
/* make sure that bit 9 is up and bit 10 is down */
|
||||
if ((reg & 0x600) == 0x200) {
|
||||
dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
|
||||
return false;
|
||||
}
|
||||
/* Cougar Point || Patsburg */
|
||||
if (ent->device == MEI_DEV_ID_CPT_1 ||
|
||||
ent->device == MEI_DEV_ID_PBG_1) {
|
||||
pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®);
|
||||
/* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
|
||||
if ((reg & 0x600) == 0x200)
|
||||
goto no_mei;
|
||||
}
|
||||
|
||||
/* Lynx Point */
|
||||
if (ent->device == MEI_DEV_ID_LPT_H ||
|
||||
ent->device == MEI_DEV_ID_LPT_W ||
|
||||
ent->device == MEI_DEV_ID_LPT_HR) {
|
||||
/* Read ME FW Status check for SPS Firmware */
|
||||
pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®);
|
||||
/* if bits [19:16] = 15, running SPS Firmware */
|
||||
if ((reg & 0xf0000) == 0xf0000)
|
||||
goto no_mei;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
no_mei:
|
||||
dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* mei_probe - Device Initialization Routine
|
||||
|
||||
@@ -314,7 +314,7 @@ err_pltfm_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __exit sdhci_bcm_kona_remove(struct platform_device *pdev)
|
||||
static int sdhci_bcm_kona_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct sdhci_host *host = platform_get_drvdata(pdev);
|
||||
int dead;
|
||||
|
||||
@@ -1249,6 +1249,7 @@ static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nand_chip->options |= NAND_NO_SUBPAGE_WRITE;
|
||||
nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
|
||||
nand_chip->ecc.write_page = atmel_nand_pmecc_write_page;
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand)
|
||||
val = __raw_readl(nand->reg + REG_FMICSR);
|
||||
|
||||
if (!(val & NAND_EN))
|
||||
__raw_writel(val | NAND_EN, REG_FMICSR);
|
||||
__raw_writel(val | NAND_EN, nand->reg + REG_FMICSR);
|
||||
|
||||
val = __raw_readl(nand->reg + REG_SMCSR);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user