mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
Merge tag 'v4.9.16' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidxu4-4.9.y
This is the 4.9.16 stable release
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 15
|
||||
SUBLEVEL = 16
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ CONFIG_NETFILTER_NETLINK_QUEUE=m
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -133,7 +133,7 @@ CONFIG_LIBFC=m
|
||||
CONFIG_SCSI_QLOGIC_1280=y
|
||||
CONFIG_SCSI_PMCRAID=m
|
||||
CONFIG_SCSI_BFA_FC=m
|
||||
CONFIG_SCSI_DH=m
|
||||
CONFIG_SCSI_DH=y
|
||||
CONFIG_SCSI_DH_RDAC=m
|
||||
CONFIG_SCSI_DH_HP_SW=m
|
||||
CONFIG_SCSI_DH_EMC=m
|
||||
@@ -205,7 +205,6 @@ CONFIG_MLX4_EN=m
|
||||
# CONFIG_MLX4_DEBUG is not set
|
||||
CONFIG_TEHUTI=m
|
||||
CONFIG_BNX2X=m
|
||||
CONFIG_QLGE=m
|
||||
CONFIG_SFC=m
|
||||
CONFIG_BE2NET=m
|
||||
CONFIG_LIBERTAS_THINFIRM=m
|
||||
|
||||
@@ -39,7 +39,7 @@ CONFIG_HIBERNATION=y
|
||||
CONFIG_PM_STD_PARTITION="/dev/hda3"
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEBUG=y
|
||||
CONFIG_CPU_FREQ_STAT=m
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
|
||||
|
||||
@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -60,8 +60,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -59,8 +59,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -61,8 +61,8 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_DCCP=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_DCCP=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -110,7 +110,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -90,7 +90,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
CONFIG_NF_CT_PROTO_UDPLITE=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_H323=m
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
|
||||
/*
|
||||
* IP27 uses the R10000's uncached attribute feature. Attribute 3 selects
|
||||
* uncached memory addressing.
|
||||
* uncached memory addressing. Hide the definitions on 32-bit compilation
|
||||
* of the compat-vdso code.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define HSPEC_BASE 0x9000000000000000
|
||||
#define IO_BASE 0x9200000000000000
|
||||
#define MSPEC_BASE 0x9400000000000000
|
||||
#define UNCAC_BASE 0x9600000000000000
|
||||
#define CAC_BASE 0xa800000000000000
|
||||
#endif
|
||||
|
||||
#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
|
||||
#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK))
|
||||
|
||||
@@ -30,8 +30,10 @@ const char *get_system_type(void)
|
||||
return soc_info.sys_type;
|
||||
}
|
||||
|
||||
static __init void prom_init_cmdline(int argc, char **argv)
|
||||
static __init void prom_init_cmdline(void)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
int i;
|
||||
|
||||
pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
|
||||
@@ -60,14 +62,11 @@ static __init void prom_init_cmdline(int argc, char **argv)
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
prom_soc_init(&soc_info);
|
||||
|
||||
pr_info("SoC Type: %s\n", get_system_type());
|
||||
|
||||
prom_init_cmdline(argc, argv);
|
||||
prom_init_cmdline();
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
|
||||
@@ -40,16 +40,6 @@ static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt288x_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on pin SRAM_CS_N */
|
||||
t = rt_sysc_r32(SYSC_REG_CLKCFG);
|
||||
t |= CLKCFG_SRAM_CS_N_WDT;
|
||||
rt_sysc_w32(t, SYSC_REG_CLKCFG);
|
||||
}
|
||||
|
||||
void __init ralink_clk_init(void)
|
||||
{
|
||||
unsigned long cpu_rate, wmac_rate = 40000000;
|
||||
|
||||
@@ -89,17 +89,6 @@ static struct rt2880_pmx_group rt5350_pinmux_data[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt305x_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on pin SRAM_CS_N */
|
||||
t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
|
||||
t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT <<
|
||||
RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT;
|
||||
rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
|
||||
}
|
||||
|
||||
static unsigned long rt5350_get_mem_size(void)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
|
||||
|
||||
@@ -63,16 +63,6 @@ static struct rt2880_pmx_group rt3883_pinmux_data[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void rt3883_wdt_reset(void)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
/* enable WDT reset output on GPIO 2 */
|
||||
t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
|
||||
t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
|
||||
rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
|
||||
}
|
||||
|
||||
void __init ralink_clk_init(void)
|
||||
{
|
||||
unsigned long cpu_rate, sys_rate;
|
||||
|
||||
@@ -71,11 +71,6 @@ static int rt_timer_request(struct rt_timer *rt)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void rt_timer_free(struct rt_timer *rt)
|
||||
{
|
||||
free_irq(rt->irq, rt);
|
||||
}
|
||||
|
||||
static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
|
||||
{
|
||||
if (rt->timer_freq < divisor)
|
||||
@@ -101,15 +96,6 @@ static int rt_timer_enable(struct rt_timer *rt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt_timer_disable(struct rt_timer *rt)
|
||||
{
|
||||
u32 t;
|
||||
|
||||
t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
|
||||
t &= ~TMR0CTL_ENABLE;
|
||||
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
|
||||
}
|
||||
|
||||
static int rt_timer_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
@@ -25,7 +25,7 @@ endif
|
||||
# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
|
||||
#
|
||||
ifdef CONFIG_SGI_IP28
|
||||
ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
|
||||
ifeq ($(call cc-option-yn,-march=r10000 -mr10k-cache-barrier=store), n)
|
||||
$(error gcc doesn't support needed option -mr10k-cache-barrier=store)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -1807,8 +1807,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto instr_done;
|
||||
|
||||
case LARX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (op.ea & (size - 1))
|
||||
break; /* can't handle misaligned */
|
||||
err = -EFAULT;
|
||||
@@ -1832,8 +1830,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto ldst_done;
|
||||
|
||||
case STCX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (op.ea & (size - 1))
|
||||
break; /* can't handle misaligned */
|
||||
err = -EFAULT;
|
||||
@@ -1859,8 +1855,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto ldst_done;
|
||||
|
||||
case LOAD:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = read_mem(®s->gpr[op.reg], op.ea, size, regs);
|
||||
if (!err) {
|
||||
if (op.type & SIGNEXT)
|
||||
@@ -1872,8 +1866,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
#ifdef CONFIG_PPC_FPU
|
||||
case LOAD_FP:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (size == 4)
|
||||
err = do_fp_load(op.reg, do_lfs, op.ea, size, regs);
|
||||
else
|
||||
@@ -1882,15 +1874,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
case LOAD_VMX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
#ifdef CONFIG_VSX
|
||||
case LOAD_VSX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
@@ -1913,8 +1901,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
goto instr_done;
|
||||
|
||||
case STORE:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if ((op.type & UPDATE) && size == sizeof(long) &&
|
||||
op.reg == 1 && op.update_reg == 1 &&
|
||||
!(regs->msr & MSR_PR) &&
|
||||
@@ -1927,8 +1913,6 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
|
||||
#ifdef CONFIG_PPC_FPU
|
||||
case STORE_FP:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
if (size == 4)
|
||||
err = do_fp_store(op.reg, do_stfs, op.ea, size, regs);
|
||||
else
|
||||
@@ -1937,15 +1921,11 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
case STORE_VMX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
#ifdef CONFIG_VSX
|
||||
case STORE_VSX:
|
||||
if (regs->msr & MSR_LE)
|
||||
return 0;
|
||||
err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs);
|
||||
goto ldst_done;
|
||||
#endif
|
||||
|
||||
@@ -91,6 +91,16 @@ static unsigned int icp_opal_get_irq(void)
|
||||
|
||||
static void icp_opal_set_cpu_priority(unsigned char cppr)
|
||||
{
|
||||
/*
|
||||
* Here be dragons. The caller has asked to allow only IPI's and not
|
||||
* external interrupts. But OPAL XIVE doesn't support that. So instead
|
||||
* of allowing no interrupts allow all. That's still not right, but
|
||||
* currently the only caller who does this is xics_migrate_irqs_away()
|
||||
* and it works in that case.
|
||||
*/
|
||||
if (cppr >= DEFAULT_PRIORITY)
|
||||
cppr = LOWEST_PRIORITY;
|
||||
|
||||
xics_set_base_cppr(cppr);
|
||||
opal_int_set_cppr(cppr);
|
||||
iosync();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/io.h>
|
||||
@@ -198,9 +199,6 @@ void xics_migrate_irqs_away(void)
|
||||
/* Remove ourselves from the global interrupt queue */
|
||||
xics_set_cpu_giq(xics_default_distrib_server, 0);
|
||||
|
||||
/* Allow IPIs again... */
|
||||
icp_ops->set_priority(DEFAULT_PRIORITY);
|
||||
|
||||
for_each_irq_desc(virq, desc) {
|
||||
struct irq_chip *chip;
|
||||
long server;
|
||||
@@ -255,6 +253,19 @@ void xics_migrate_irqs_away(void)
|
||||
unlock:
|
||||
raw_spin_unlock_irqrestore(&desc->lock, flags);
|
||||
}
|
||||
|
||||
/* Allow "sufficient" time to drop any inflight IRQ's */
|
||||
mdelay(5);
|
||||
|
||||
/*
|
||||
* Allow IPIs again. This is done at the very end, after migrating all
|
||||
* interrupts, the expectation is that we'll only get woken up by an IPI
|
||||
* interrupt beyond this point, but leave externals masked just to be
|
||||
* safe. If we're using icp-opal this may actually allow all
|
||||
* interrupts anyway, but that should be OK.
|
||||
*/
|
||||
icp_ops->set_priority(DEFAULT_PRIORITY);
|
||||
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
|
||||
@@ -606,12 +606,29 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||
bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
spinlock_t *ptl;
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pgste_t pgste;
|
||||
pte_t *ptep;
|
||||
pte_t pte;
|
||||
bool dirty;
|
||||
|
||||
ptep = get_locked_pte(mm, addr, &ptl);
|
||||
pgd = pgd_offset(mm, addr);
|
||||
pud = pud_alloc(mm, pgd, addr);
|
||||
if (!pud)
|
||||
return false;
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
if (!pmd)
|
||||
return false;
|
||||
/* We can't run guests backed by huge pages, but userspace can
|
||||
* still set them up and then try to migrate them without any
|
||||
* migration support.
|
||||
*/
|
||||
if (pmd_large(*pmd))
|
||||
return true;
|
||||
|
||||
ptep = pte_alloc_map_lock(mm, pmd, addr, &ptl);
|
||||
if (unlikely(!ptep))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
|
||||
obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
|
||||
obj-$(CONFIG_CRYPTO_SHA3) += sha3_generic.o
|
||||
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
|
||||
CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
|
||||
obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
|
||||
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
|
||||
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
|
||||
@@ -94,6 +95,7 @@ obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
|
||||
obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
|
||||
CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
|
||||
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
|
||||
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
|
||||
obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o
|
||||
|
||||
@@ -65,6 +65,7 @@ static bool __init efi_virtmap_init(void)
|
||||
bool systab_found;
|
||||
|
||||
efi_mm.pgd = pgd_alloc(&efi_mm);
|
||||
mm_init_cpumask(&efi_mm);
|
||||
init_new_context(NULL, &efi_mm);
|
||||
|
||||
systab_found = false;
|
||||
|
||||
@@ -429,6 +429,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
|
||||
while (muxc->num_adapters) {
|
||||
struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters];
|
||||
struct i2c_mux_priv *priv = adap->algo_data;
|
||||
struct device_node *np = adap->dev.of_node;
|
||||
|
||||
muxc->adapter[muxc->num_adapters] = NULL;
|
||||
|
||||
@@ -438,6 +439,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
|
||||
|
||||
sysfs_remove_link(&priv->adap.dev.kobj, "mux_device");
|
||||
i2c_del_adapter(adap);
|
||||
of_node_put(np);
|
||||
kfree(priv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3141,9 +3141,11 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
|
||||
if (err)
|
||||
goto err_rsrc;
|
||||
|
||||
err = mlx5_ib_alloc_q_counters(dev);
|
||||
if (err)
|
||||
goto err_odp;
|
||||
if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) {
|
||||
err = mlx5_ib_alloc_q_counters(dev);
|
||||
if (err)
|
||||
goto err_odp;
|
||||
}
|
||||
|
||||
err = ib_register_device(&dev->ib_dev, NULL);
|
||||
if (err)
|
||||
@@ -3171,7 +3173,8 @@ err_dev:
|
||||
ib_unregister_device(&dev->ib_dev);
|
||||
|
||||
err_q_cnt:
|
||||
mlx5_ib_dealloc_q_counters(dev);
|
||||
if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
|
||||
mlx5_ib_dealloc_q_counters(dev);
|
||||
|
||||
err_odp:
|
||||
mlx5_ib_odp_remove_one(dev);
|
||||
@@ -3201,7 +3204,8 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
|
||||
|
||||
mlx5_remove_roce_notifier(dev);
|
||||
ib_unregister_device(&dev->ib_dev);
|
||||
mlx5_ib_dealloc_q_counters(dev);
|
||||
if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
|
||||
mlx5_ib_dealloc_q_counters(dev);
|
||||
destroy_umrc_res(dev);
|
||||
mlx5_ib_odp_remove_one(dev);
|
||||
destroy_dev_resources(&dev->devr);
|
||||
|
||||
@@ -972,10 +972,61 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_accept_partial_bio);
|
||||
|
||||
/*
|
||||
* Flush current->bio_list when the target map method blocks.
|
||||
* This fixes deadlocks in snapshot and possibly in other targets.
|
||||
*/
|
||||
struct dm_offload {
|
||||
struct blk_plug plug;
|
||||
struct blk_plug_cb cb;
|
||||
};
|
||||
|
||||
static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
|
||||
{
|
||||
struct dm_offload *o = container_of(cb, struct dm_offload, cb);
|
||||
struct bio_list list;
|
||||
struct bio *bio;
|
||||
|
||||
INIT_LIST_HEAD(&o->cb.list);
|
||||
|
||||
if (unlikely(!current->bio_list))
|
||||
return;
|
||||
|
||||
list = *current->bio_list;
|
||||
bio_list_init(current->bio_list);
|
||||
|
||||
while ((bio = bio_list_pop(&list))) {
|
||||
struct bio_set *bs = bio->bi_pool;
|
||||
if (unlikely(!bs) || bs == fs_bio_set) {
|
||||
bio_list_add(current->bio_list, bio);
|
||||
continue;
|
||||
}
|
||||
|
||||
spin_lock(&bs->rescue_lock);
|
||||
bio_list_add(&bs->rescue_list, bio);
|
||||
queue_work(bs->rescue_workqueue, &bs->rescue_work);
|
||||
spin_unlock(&bs->rescue_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void dm_offload_start(struct dm_offload *o)
|
||||
{
|
||||
blk_start_plug(&o->plug);
|
||||
o->cb.callback = flush_current_bio_list;
|
||||
list_add(&o->cb.list, ¤t->plug->cb_list);
|
||||
}
|
||||
|
||||
static void dm_offload_end(struct dm_offload *o)
|
||||
{
|
||||
list_del(&o->cb.list);
|
||||
blk_finish_plug(&o->plug);
|
||||
}
|
||||
|
||||
static void __map_bio(struct dm_target_io *tio)
|
||||
{
|
||||
int r;
|
||||
sector_t sector;
|
||||
struct dm_offload o;
|
||||
struct bio *clone = &tio->clone;
|
||||
struct dm_target *ti = tio->ti;
|
||||
|
||||
@@ -988,7 +1039,11 @@ static void __map_bio(struct dm_target_io *tio)
|
||||
*/
|
||||
atomic_inc(&tio->io->io_count);
|
||||
sector = clone->bi_iter.bi_sector;
|
||||
|
||||
dm_offload_start(&o);
|
||||
r = ti->type->map(ti, clone);
|
||||
dm_offload_end(&o);
|
||||
|
||||
if (r == DM_MAPIO_REMAPPED) {
|
||||
/* the bio has been remapped so dispatch it */
|
||||
|
||||
|
||||
@@ -1411,6 +1411,7 @@ int rc_register_device(struct rc_dev *dev)
|
||||
int attr = 0;
|
||||
int minor;
|
||||
int rc;
|
||||
u64 rc_type;
|
||||
|
||||
if (!dev || !dev->map_name)
|
||||
return -EINVAL;
|
||||
@@ -1496,14 +1497,18 @@ int rc_register_device(struct rc_dev *dev)
|
||||
goto out_input;
|
||||
}
|
||||
|
||||
rc_type = BIT_ULL(rc_map->rc_type);
|
||||
|
||||
if (dev->change_protocol) {
|
||||
u64 rc_type = (1ll << rc_map->rc_type);
|
||||
rc = dev->change_protocol(dev, &rc_type);
|
||||
if (rc < 0)
|
||||
goto out_raw;
|
||||
dev->enabled_protocols = rc_type;
|
||||
}
|
||||
|
||||
if (dev->driver_type == RC_DRIVER_IR_RAW)
|
||||
ir_raw_load_modules(&rc_type);
|
||||
|
||||
/* Allow the RC sysfs nodes to be accessible */
|
||||
atomic_set(&dev->initialized, 1);
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
struct dw2102_state {
|
||||
u8 initialized;
|
||||
u8 last_lock;
|
||||
u8 data[MAX_XFER_SIZE + 4];
|
||||
struct i2c_client *i2c_client_demod;
|
||||
struct i2c_client *i2c_client_tuner;
|
||||
|
||||
@@ -662,62 +663,72 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
u8 obuf[0x40], ibuf[0x40];
|
||||
struct dw2102_state *state;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
|
||||
state = d->priv;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
if (mutex_lock_interruptible(&d->data_mutex) < 0) {
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case 1:
|
||||
switch (msg[0].addr) {
|
||||
case SU3000_STREAM_CTRL:
|
||||
obuf[0] = msg[0].buf[0] + 0x36;
|
||||
obuf[1] = 3;
|
||||
obuf[2] = 0;
|
||||
if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
|
||||
state->data[0] = msg[0].buf[0] + 0x36;
|
||||
state->data[1] = 3;
|
||||
state->data[2] = 0;
|
||||
if (dvb_usb_generic_rw(d, state->data, 3,
|
||||
state->data, 0, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
break;
|
||||
case DW2102_RC_QUERY:
|
||||
obuf[0] = 0x10;
|
||||
if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
|
||||
state->data[0] = 0x10;
|
||||
if (dvb_usb_generic_rw(d, state->data, 1,
|
||||
state->data, 2, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
msg[0].buf[1] = ibuf[0];
|
||||
msg[0].buf[0] = ibuf[1];
|
||||
msg[0].buf[1] = state->data[0];
|
||||
msg[0].buf[0] = state->data[1];
|
||||
break;
|
||||
default:
|
||||
/* always i2c write*/
|
||||
obuf[0] = 0x08;
|
||||
obuf[1] = msg[0].addr;
|
||||
obuf[2] = msg[0].len;
|
||||
state->data[0] = 0x08;
|
||||
state->data[1] = msg[0].addr;
|
||||
state->data[2] = msg[0].len;
|
||||
|
||||
memcpy(&obuf[3], msg[0].buf, msg[0].len);
|
||||
memcpy(&state->data[3], msg[0].buf, msg[0].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
|
||||
ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
|
||||
state->data, 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* always i2c read */
|
||||
obuf[0] = 0x09;
|
||||
obuf[1] = msg[0].len;
|
||||
obuf[2] = msg[1].len;
|
||||
obuf[3] = msg[0].addr;
|
||||
memcpy(&obuf[4], msg[0].buf, msg[0].len);
|
||||
state->data[0] = 0x09;
|
||||
state->data[1] = msg[0].len;
|
||||
state->data[2] = msg[1].len;
|
||||
state->data[3] = msg[0].addr;
|
||||
memcpy(&state->data[4], msg[0].buf, msg[0].len);
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
|
||||
ibuf, msg[1].len + 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
|
||||
state->data, msg[1].len + 1, 0) < 0)
|
||||
err("i2c transfer failed.");
|
||||
|
||||
memcpy(msg[1].buf, &ibuf[1], msg[1].len);
|
||||
memcpy(msg[1].buf, &state->data[1], msg[1].len);
|
||||
break;
|
||||
default:
|
||||
warn("more than 2 i2c messages at a time is not handled yet.");
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&d->data_mutex);
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return num;
|
||||
}
|
||||
@@ -845,17 +856,23 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||
static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
|
||||
{
|
||||
struct dw2102_state *state = (struct dw2102_state *)d->priv;
|
||||
u8 obuf[] = {0xde, 0};
|
||||
int ret = 0;
|
||||
|
||||
info("%s: %d, initialized %d", __func__, i, state->initialized);
|
||||
|
||||
if (i && !state->initialized) {
|
||||
mutex_lock(&d->data_mutex);
|
||||
|
||||
state->data[0] = 0xde;
|
||||
state->data[1] = 0;
|
||||
|
||||
state->initialized = 1;
|
||||
/* reset board */
|
||||
return dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
|
||||
ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0);
|
||||
mutex_unlock(&d->data_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
|
||||
@@ -1310,49 +1327,57 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int su3000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
static int su3000_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
u8 obuf[3] = { 0xe, 0x80, 0 };
|
||||
u8 ibuf[] = { 0 };
|
||||
struct dvb_usb_device *d = adap->dev;
|
||||
struct dw2102_state *state = d->priv;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
mutex_lock(&d->data_mutex);
|
||||
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x80;
|
||||
state->data[2] = 0;
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x02;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x02;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
msleep(300);
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x83;
|
||||
obuf[2] = 0;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x83;
|
||||
state->data[2] = 0;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x83;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x83;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0x51;
|
||||
state->data[0] = 0x51;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
|
||||
err("command 0x51 transfer failed.");
|
||||
|
||||
d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe_adap[0].fe == NULL)
|
||||
mutex_unlock(&d->data_mutex);
|
||||
|
||||
adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
|
||||
&d->i2c_adap);
|
||||
if (adap->fe_adap[0].fe == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
|
||||
if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
|
||||
&dw2104_ts2020_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
&d->i2c_adap)) {
|
||||
info("Attached DS3000/TS2020!");
|
||||
return 0;
|
||||
}
|
||||
@@ -1361,47 +1386,55 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int t220_frontend_attach(struct dvb_usb_adapter *d)
|
||||
static int t220_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
u8 obuf[3] = { 0xe, 0x87, 0 };
|
||||
u8 ibuf[] = { 0 };
|
||||
struct dvb_usb_device *d = adap->dev;
|
||||
struct dw2102_state *state = d->priv;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
mutex_lock(&d->data_mutex);
|
||||
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x87;
|
||||
state->data[2] = 0x0;
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x86;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x86;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x80;
|
||||
obuf[2] = 0;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x80;
|
||||
state->data[2] = 0;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
msleep(50);
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x80;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x80;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0x51;
|
||||
state->data[0] = 0x51;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
|
||||
err("command 0x51 transfer failed.");
|
||||
|
||||
d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
|
||||
&d->dev->i2c_adap, NULL);
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
|
||||
&d->dev->i2c_adap, &tda18271_config)) {
|
||||
mutex_unlock(&d->data_mutex);
|
||||
|
||||
adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config,
|
||||
&d->i2c_adap, NULL);
|
||||
if (adap->fe_adap[0].fe != NULL) {
|
||||
if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60,
|
||||
&d->i2c_adap, &tda18271_config)) {
|
||||
info("Attached TDA18271HD/CXD2820R!");
|
||||
return 0;
|
||||
}
|
||||
@@ -1411,23 +1444,30 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
u8 obuf[] = { 0x51 };
|
||||
u8 ibuf[] = { 0 };
|
||||
struct dvb_usb_device *d = adap->dev;
|
||||
struct dw2102_state *state = d->priv;
|
||||
|
||||
if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
|
||||
mutex_lock(&d->data_mutex);
|
||||
|
||||
state->data[0] = 0x51;
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
|
||||
err("command 0x51 transfer failed.");
|
||||
|
||||
d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config,
|
||||
&d->dev->i2c_adap);
|
||||
mutex_unlock(&d->data_mutex);
|
||||
|
||||
if (d->fe_adap[0].fe == NULL)
|
||||
adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
|
||||
&s421_m88rs2000_config,
|
||||
&d->i2c_adap);
|
||||
|
||||
if (adap->fe_adap[0].fe == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
|
||||
if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe,
|
||||
&dw2104_ts2020_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
&d->i2c_adap)) {
|
||||
info("Attached RS2000/TS2020!");
|
||||
return 0;
|
||||
}
|
||||
@@ -1440,44 +1480,50 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct dvb_usb_device *d = adap->dev;
|
||||
struct dw2102_state *state = d->priv;
|
||||
u8 obuf[3] = { 0xe, 0x80, 0 };
|
||||
u8 ibuf[] = { 0 };
|
||||
struct i2c_adapter *i2c_adapter;
|
||||
struct i2c_client *client;
|
||||
struct i2c_board_info board_info;
|
||||
struct m88ds3103_platform_data m88ds3103_pdata = {};
|
||||
struct ts2020_config ts2020_config = {};
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
|
||||
mutex_lock(&d->data_mutex);
|
||||
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x80;
|
||||
state->data[2] = 0x0;
|
||||
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x02;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x02;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
msleep(300);
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x83;
|
||||
obuf[2] = 0;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x83;
|
||||
state->data[2] = 0;
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0xe;
|
||||
obuf[1] = 0x83;
|
||||
obuf[2] = 1;
|
||||
state->data[0] = 0xe;
|
||||
state->data[1] = 0x83;
|
||||
state->data[2] = 1;
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0)
|
||||
err("command 0x0e transfer failed.");
|
||||
|
||||
obuf[0] = 0x51;
|
||||
state->data[0] = 0x51;
|
||||
|
||||
if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0)
|
||||
if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0)
|
||||
err("command 0x51 transfer failed.");
|
||||
|
||||
mutex_unlock(&d->data_mutex);
|
||||
|
||||
/* attach demod */
|
||||
m88ds3103_pdata.clk = 27000000;
|
||||
m88ds3103_pdata.i2c_wr_max = 33;
|
||||
|
||||
@@ -139,15 +139,13 @@ static int __init init_msp_flash(void)
|
||||
}
|
||||
|
||||
msp_maps[i].bankwidth = 1;
|
||||
msp_maps[i].name = kmalloc(7, GFP_KERNEL);
|
||||
msp_maps[i].name = kstrndup(flash_name, 7, GFP_KERNEL);
|
||||
if (!msp_maps[i].name) {
|
||||
iounmap(msp_maps[i].virt);
|
||||
kfree(msp_parts[i]);
|
||||
goto cleanup_loop;
|
||||
}
|
||||
|
||||
msp_maps[i].name = strncpy(msp_maps[i].name, flash_name, 7);
|
||||
|
||||
for (j = 0; j < pcnt; j++) {
|
||||
part_name[5] = '0' + i;
|
||||
part_name[7] = '0' + j;
|
||||
|
||||
@@ -913,6 +913,8 @@ static int bcm_enet_open(struct net_device *dev)
|
||||
priv->old_link = 0;
|
||||
priv->old_duplex = -1;
|
||||
priv->old_pause = -1;
|
||||
} else {
|
||||
phydev = NULL;
|
||||
}
|
||||
|
||||
/* mask all interrupts and request them */
|
||||
@@ -1083,7 +1085,7 @@ static int bcm_enet_open(struct net_device *dev)
|
||||
enet_dmac_writel(priv, priv->dma_chan_int_mask,
|
||||
ENETDMAC_IRMASK, priv->tx_chan);
|
||||
|
||||
if (priv->has_phy)
|
||||
if (phydev)
|
||||
phy_start(phydev);
|
||||
else
|
||||
bcm_enet_adjust_link(dev);
|
||||
@@ -1126,7 +1128,7 @@ out_freeirq:
|
||||
free_irq(dev->irq, dev);
|
||||
|
||||
out_phy_disconnect:
|
||||
if (priv->has_phy)
|
||||
if (phydev)
|
||||
phy_disconnect(phydev);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1211,7 +1211,7 @@ int cpmac_init(void)
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
#warning FIXME: unhardcode gpio&reset bits
|
||||
/* FIXME: unhardcode gpio&reset bits */
|
||||
ar7_gpio_disable(26);
|
||||
ar7_gpio_disable(27);
|
||||
ar7_device_reset(AR7_RESET_BIT_CPMAC_LO);
|
||||
|
||||
@@ -2173,6 +2173,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005d, quirk_blacklist_vpd);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID,
|
||||
quirk_blacklist_vpd);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd);
|
||||
|
||||
/*
|
||||
* For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
|
||||
|
||||
@@ -1036,8 +1036,10 @@ static int s3c64xx_serial_startup(struct uart_port *port)
|
||||
if (ourport->dma) {
|
||||
ret = s3c24xx_serial_request_dma(ourport);
|
||||
if (ret < 0) {
|
||||
dev_warn(port->dev, "DMA request failed\n");
|
||||
return ret;
|
||||
dev_warn(port->dev,
|
||||
"DMA request failed, DMA will not be used\n");
|
||||
devm_kfree(port->dev, ourport->dma);
|
||||
ourport->dma = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +249,7 @@ static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
|
||||
val = dwc3_omap_read_utmi_ctrl(omap);
|
||||
val |= USBOTGSS_UTMI_OTG_CTRL_IDDIG;
|
||||
dwc3_omap_write_utmi_ctrl(omap, val);
|
||||
break;
|
||||
|
||||
case OMAP_DWC3_VBUS_OFF:
|
||||
val = dwc3_omap_read_utmi_ctrl(omap);
|
||||
|
||||
@@ -28,23 +28,23 @@ struct dwc3;
|
||||
#define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget))
|
||||
|
||||
/* DEPCFG parameter 1 */
|
||||
#define DWC3_DEPCFG_INT_NUM(n) ((n) << 0)
|
||||
#define DWC3_DEPCFG_INT_NUM(n) (((n) & 0x1f) << 0)
|
||||
#define DWC3_DEPCFG_XFER_COMPLETE_EN (1 << 8)
|
||||
#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN (1 << 9)
|
||||
#define DWC3_DEPCFG_XFER_NOT_READY_EN (1 << 10)
|
||||
#define DWC3_DEPCFG_FIFO_ERROR_EN (1 << 11)
|
||||
#define DWC3_DEPCFG_STREAM_EVENT_EN (1 << 13)
|
||||
#define DWC3_DEPCFG_BINTERVAL_M1(n) ((n) << 16)
|
||||
#define DWC3_DEPCFG_BINTERVAL_M1(n) (((n) & 0xff) << 16)
|
||||
#define DWC3_DEPCFG_STREAM_CAPABLE (1 << 24)
|
||||
#define DWC3_DEPCFG_EP_NUMBER(n) ((n) << 25)
|
||||
#define DWC3_DEPCFG_EP_NUMBER(n) (((n) & 0x1f) << 25)
|
||||
#define DWC3_DEPCFG_BULK_BASED (1 << 30)
|
||||
#define DWC3_DEPCFG_FIFO_BASED (1 << 31)
|
||||
|
||||
/* DEPCFG parameter 0 */
|
||||
#define DWC3_DEPCFG_EP_TYPE(n) ((n) << 1)
|
||||
#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3)
|
||||
#define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17)
|
||||
#define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22)
|
||||
#define DWC3_DEPCFG_EP_TYPE(n) (((n) & 0x3) << 1)
|
||||
#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) (((n) & 0x7ff) << 3)
|
||||
#define DWC3_DEPCFG_FIFO_NUMBER(n) (((n) & 0x1f) << 17)
|
||||
#define DWC3_DEPCFG_BURST_SIZE(n) (((n) & 0xf) << 22)
|
||||
#define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26)
|
||||
/* This applies for core versions earlier than 1.94a */
|
||||
#define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31)
|
||||
|
||||
@@ -1833,11 +1833,14 @@ static int ffs_func_eps_enable(struct ffs_function *func)
|
||||
spin_lock_irqsave(&func->ffs->eps_lock, flags);
|
||||
do {
|
||||
struct usb_endpoint_descriptor *ds;
|
||||
struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
|
||||
int needs_comp_desc = false;
|
||||
int desc_idx;
|
||||
|
||||
if (ffs->gadget->speed == USB_SPEED_SUPER)
|
||||
if (ffs->gadget->speed == USB_SPEED_SUPER) {
|
||||
desc_idx = 2;
|
||||
else if (ffs->gadget->speed == USB_SPEED_HIGH)
|
||||
needs_comp_desc = true;
|
||||
} else if (ffs->gadget->speed == USB_SPEED_HIGH)
|
||||
desc_idx = 1;
|
||||
else
|
||||
desc_idx = 0;
|
||||
@@ -1854,6 +1857,14 @@ static int ffs_func_eps_enable(struct ffs_function *func)
|
||||
|
||||
ep->ep->driver_data = ep;
|
||||
ep->ep->desc = ds;
|
||||
|
||||
comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
|
||||
USB_DT_ENDPOINT_SIZE);
|
||||
ep->ep->maxburst = comp_desc->bMaxBurst + 1;
|
||||
|
||||
if (needs_comp_desc)
|
||||
ep->ep->comp_desc = comp_desc;
|
||||
|
||||
ret = usb_ep_enable(ep->ep);
|
||||
if (likely(!ret)) {
|
||||
epfile->ep = ep;
|
||||
|
||||
@@ -258,13 +258,6 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
|
||||
memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req));
|
||||
v4l2_event_queue(&uvc->vdev, &v4l2_event);
|
||||
|
||||
/* Pass additional setup data to userspace */
|
||||
if (uvc->event_setup_out && uvc->event_length) {
|
||||
uvc->control_req->length = uvc->event_length;
|
||||
return usb_ep_queue(uvc->func.config->cdev->gadget->ep0,
|
||||
uvc->control_req, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1031,6 +1031,8 @@ static int dummy_udc_probe(struct platform_device *pdev)
|
||||
int rc;
|
||||
|
||||
dum = *((void **)dev_get_platdata(&pdev->dev));
|
||||
/* Clear usb_gadget region for new registration to udc-core */
|
||||
memzero_explicit(&dum->gadget, sizeof(struct usb_gadget));
|
||||
dum->gadget.name = gadget_name;
|
||||
dum->gadget.ops = &dummy_ops;
|
||||
dum->gadget.max_speed = USB_SPEED_SUPER;
|
||||
|
||||
@@ -361,7 +361,7 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(hcd->self.controller, "SetPortFeat: SUSPEND\n");
|
||||
if (valid_port(wIndex)) {
|
||||
if (valid_port(wIndex) && ohci_at91->sfr_regmap) {
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap,
|
||||
1);
|
||||
return 0;
|
||||
@@ -404,7 +404,7 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
|
||||
case USB_PORT_FEAT_SUSPEND:
|
||||
dev_dbg(hcd->self.controller, "ClearPortFeature: SUSPEND\n");
|
||||
if (valid_port(wIndex)) {
|
||||
if (valid_port(wIndex) && ohci_at91->sfr_regmap) {
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap,
|
||||
0);
|
||||
return 0;
|
||||
|
||||
@@ -111,7 +111,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
|
||||
xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK);
|
||||
|
||||
/* xhci 1.1 controllers have the HCCPARAMS2 register */
|
||||
if (hci_version > 100) {
|
||||
if (hci_version > 0x100) {
|
||||
temp = readl(&xhci->cap_regs->hcc_params2);
|
||||
xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp);
|
||||
xhci_dbg(xhci, " HC %s Force save context capability",
|
||||
|
||||
@@ -304,6 +304,8 @@ static int xhci_plat_remove(struct platform_device *dev)
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct clk *clk = xhci->clk;
|
||||
|
||||
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
||||
|
||||
usb_remove_hcd(xhci->shared_hcd);
|
||||
usb_phy_shutdown(hcd->usb_phy);
|
||||
|
||||
|
||||
@@ -781,12 +781,6 @@ static int iowarrior_probe(struct usb_interface *interface,
|
||||
iface_desc = interface->cur_altsetting;
|
||||
dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 1) {
|
||||
dev_err(&interface->dev, "Invalid number of endpoints\n");
|
||||
retval = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set up the endpoint information */
|
||||
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
|
||||
endpoint = &iface_desc->endpoint[i].desc;
|
||||
@@ -797,6 +791,21 @@ static int iowarrior_probe(struct usb_interface *interface,
|
||||
/* this one will match for the IOWarrior56 only */
|
||||
dev->int_out_endpoint = endpoint;
|
||||
}
|
||||
|
||||
if (!dev->int_in_endpoint) {
|
||||
dev_err(&interface->dev, "no interrupt-in endpoint found\n");
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) {
|
||||
if (!dev->int_out_endpoint) {
|
||||
dev_err(&interface->dev, "no interrupt-out endpoint found\n");
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* we have to check the report_size often, so remember it in the endianness suitable for our machine */
|
||||
dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
|
||||
if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
|
||||
|
||||
@@ -1482,16 +1482,20 @@ static int digi_read_oob_callback(struct urb *urb)
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct tty_struct *tty;
|
||||
struct digi_port *priv = usb_get_serial_port_data(port);
|
||||
unsigned char *buf = urb->transfer_buffer;
|
||||
int opcode, line, status, val;
|
||||
int i;
|
||||
unsigned int rts;
|
||||
|
||||
if (urb->actual_length < 4)
|
||||
return -1;
|
||||
|
||||
/* handle each oob command */
|
||||
for (i = 0; i < urb->actual_length - 3;) {
|
||||
opcode = ((unsigned char *)urb->transfer_buffer)[i++];
|
||||
line = ((unsigned char *)urb->transfer_buffer)[i++];
|
||||
status = ((unsigned char *)urb->transfer_buffer)[i++];
|
||||
val = ((unsigned char *)urb->transfer_buffer)[i++];
|
||||
for (i = 0; i < urb->actual_length - 3; i += 4) {
|
||||
opcode = buf[i];
|
||||
line = buf[i + 1];
|
||||
status = buf[i + 2];
|
||||
val = buf[i + 3];
|
||||
|
||||
dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n",
|
||||
opcode, line, status, val);
|
||||
|
||||
@@ -1674,6 +1674,12 @@ static void edge_interrupt_callback(struct urb *urb)
|
||||
function = TIUMP_GET_FUNC_FROM_CODE(data[0]);
|
||||
dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__,
|
||||
port_number, function, data[1]);
|
||||
|
||||
if (port_number >= edge_serial->serial->num_ports) {
|
||||
dev_err(dev, "bad port number %d\n", port_number);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
port = edge_serial->serial->port[port_number];
|
||||
edge_port = usb_get_serial_port_data(port);
|
||||
if (!edge_port) {
|
||||
@@ -1755,7 +1761,7 @@ static void edge_bulk_in_callback(struct urb *urb)
|
||||
|
||||
port_number = edge_port->port->port_number;
|
||||
|
||||
if (edge_port->lsr_event) {
|
||||
if (urb->actual_length > 0 && edge_port->lsr_event) {
|
||||
edge_port->lsr_event = 0;
|
||||
dev_dbg(dev, "%s ===== Port %u LSR Status = %02x, Data = %02x ======\n",
|
||||
__func__, port_number, edge_port->lsr_mask, *data);
|
||||
|
||||
@@ -142,12 +142,6 @@ static int omninet_port_remove(struct usb_serial_port *port)
|
||||
|
||||
static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct usb_serial_port *wport;
|
||||
|
||||
wport = serial->port[1];
|
||||
tty_port_tty_set(&wport->port, tty);
|
||||
|
||||
return usb_serial_generic_open(tty, port);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,11 @@ static void safe_process_read_urb(struct urb *urb)
|
||||
if (!safe)
|
||||
goto out;
|
||||
|
||||
if (length < 2) {
|
||||
dev_err(&port->dev, "malformed packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fcs = fcs_compute10(data, length, CRC10_INITFCS);
|
||||
if (fcs) {
|
||||
dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
|
||||
|
||||
@@ -3824,6 +3824,10 @@ static int ext4_block_truncate_page(handle_t *handle,
|
||||
unsigned blocksize;
|
||||
struct inode *inode = mapping->host;
|
||||
|
||||
/* If we are processing an encrypted inode during orphan list handling */
|
||||
if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
|
||||
return 0;
|
||||
|
||||
blocksize = inode->i_sb->s_blocksize;
|
||||
length = blocksize - (offset & (blocksize - 1));
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ struct ucounts {
|
||||
struct hlist_node node;
|
||||
struct user_namespace *ns;
|
||||
kuid_t uid;
|
||||
atomic_t count;
|
||||
int count;
|
||||
atomic_t ucount[UCOUNT_COUNTS];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM raw_syscalls
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE syscalls
|
||||
|
||||
#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
||||
@@ -139,7 +139,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
|
||||
|
||||
new->ns = ns;
|
||||
new->uid = uid;
|
||||
atomic_set(&new->count, 0);
|
||||
new->count = 0;
|
||||
|
||||
spin_lock_irq(&ucounts_lock);
|
||||
ucounts = find_ucounts(ns, uid, hashent);
|
||||
@@ -150,8 +150,10 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
|
||||
ucounts = new;
|
||||
}
|
||||
}
|
||||
if (!atomic_add_unless(&ucounts->count, 1, INT_MAX))
|
||||
if (ucounts->count == INT_MAX)
|
||||
ucounts = NULL;
|
||||
else
|
||||
ucounts->count += 1;
|
||||
spin_unlock_irq(&ucounts_lock);
|
||||
return ucounts;
|
||||
}
|
||||
@@ -160,13 +162,15 @@ static void put_ucounts(struct ucounts *ucounts)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (atomic_dec_and_test(&ucounts->count)) {
|
||||
spin_lock_irqsave(&ucounts_lock, flags);
|
||||
spin_lock_irqsave(&ucounts_lock, flags);
|
||||
ucounts->count -= 1;
|
||||
if (!ucounts->count)
|
||||
hlist_del_init(&ucounts->node);
|
||||
spin_unlock_irqrestore(&ucounts_lock, flags);
|
||||
else
|
||||
ucounts = NULL;
|
||||
spin_unlock_irqrestore(&ucounts_lock, flags);
|
||||
|
||||
kfree(ucounts);
|
||||
}
|
||||
kfree(ucounts);
|
||||
}
|
||||
|
||||
static inline bool atomic_inc_below(atomic_t *v, int u)
|
||||
|
||||
@@ -187,21 +187,37 @@ unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu,
|
||||
static void vgic_mmio_change_active(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
|
||||
bool new_active_state)
|
||||
{
|
||||
struct kvm_vcpu *requester_vcpu;
|
||||
spin_lock(&irq->irq_lock);
|
||||
|
||||
/*
|
||||
* The vcpu parameter here can mean multiple things depending on how
|
||||
* this function is called; when handling a trap from the kernel it
|
||||
* depends on the GIC version, and these functions are also called as
|
||||
* part of save/restore from userspace.
|
||||
*
|
||||
* Therefore, we have to figure out the requester in a reliable way.
|
||||
*
|
||||
* When accessing VGIC state from user space, the requester_vcpu is
|
||||
* NULL, which is fine, because we guarantee that no VCPUs are running
|
||||
* when accessing VGIC state from user space so irq->vcpu->cpu is
|
||||
* always -1.
|
||||
*/
|
||||
requester_vcpu = kvm_arm_get_running_vcpu();
|
||||
|
||||
/*
|
||||
* If this virtual IRQ was written into a list register, we
|
||||
* have to make sure the CPU that runs the VCPU thread has
|
||||
* synced back LR state to the struct vgic_irq. We can only
|
||||
* know this for sure, when either this irq is not assigned to
|
||||
* anyone's AP list anymore, or the VCPU thread is not
|
||||
* running on any CPUs.
|
||||
* synced back the LR state to the struct vgic_irq.
|
||||
*
|
||||
* In the opposite case, we know the VCPU thread may be on its
|
||||
* way back from the guest and still has to sync back this
|
||||
* IRQ, so we release and re-acquire the spin_lock to let the
|
||||
* other thread sync back the IRQ.
|
||||
* As long as the conditions below are true, we know the VCPU thread
|
||||
* may be on its way back from the guest (we kicked the VCPU thread in
|
||||
* vgic_change_active_prepare) and still has to sync back this IRQ,
|
||||
* so we release and re-acquire the spin_lock to let the other thread
|
||||
* sync back the IRQ.
|
||||
*/
|
||||
while (irq->vcpu && /* IRQ may have state in an LR somewhere */
|
||||
irq->vcpu != requester_vcpu && /* Current thread is not the VCPU thread */
|
||||
irq->vcpu->cpu != -1) /* VCPU thread is running */
|
||||
cond_resched_lock(&irq->irq_lock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user