mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 06:25:52 +02:00
Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
This commit is contained in:
commit
6e93543c4e
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 7
|
||||
SUBLEVEL = 9
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
|
|
|||
|
|
@ -404,6 +404,12 @@ config CLONE_BACKWARDS2
|
|||
help
|
||||
Architecture has the first two arguments of clone(2) swapped.
|
||||
|
||||
config CLONE_BACKWARDS3
|
||||
bool
|
||||
help
|
||||
Architecture has tls passed as the 3rd argument of clone(2),
|
||||
not the 5th one.
|
||||
|
||||
config ODD_RT_SIGACTION
|
||||
bool
|
||||
help
|
||||
|
|
|
|||
|
|
@ -37,16 +37,18 @@
|
|||
#define c5_AIFSR 15 /* Auxilary Instrunction Fault Status R */
|
||||
#define c6_DFAR 16 /* Data Fault Address Register */
|
||||
#define c6_IFAR 17 /* Instruction Fault Address Register */
|
||||
#define c9_L2CTLR 18 /* Cortex A15 L2 Control Register */
|
||||
#define c10_PRRR 19 /* Primary Region Remap Register */
|
||||
#define c10_NMRR 20 /* Normal Memory Remap Register */
|
||||
#define c12_VBAR 21 /* Vector Base Address Register */
|
||||
#define c13_CID 22 /* Context ID Register */
|
||||
#define c13_TID_URW 23 /* Thread ID, User R/W */
|
||||
#define c13_TID_URO 24 /* Thread ID, User R/O */
|
||||
#define c13_TID_PRIV 25 /* Thread ID, Privileged */
|
||||
#define c14_CNTKCTL 26 /* Timer Control Register (PL1) */
|
||||
#define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */
|
||||
#define c7_PAR 18 /* Physical Address Register */
|
||||
#define c7_PAR_high 19 /* PAR top 32 bits */
|
||||
#define c9_L2CTLR 20 /* Cortex A15 L2 Control Register */
|
||||
#define c10_PRRR 21 /* Primary Region Remap Register */
|
||||
#define c10_NMRR 22 /* Normal Memory Remap Register */
|
||||
#define c12_VBAR 23 /* Vector Base Address Register */
|
||||
#define c13_CID 24 /* Context ID Register */
|
||||
#define c13_TID_URW 25 /* Thread ID, User R/W */
|
||||
#define c13_TID_URO 26 /* Thread ID, User R/O */
|
||||
#define c13_TID_PRIV 27 /* Thread ID, Privileged */
|
||||
#define c14_CNTKCTL 28 /* Timer Control Register (PL1) */
|
||||
#define NR_CP15_REGS 29 /* Number of regs (incl. invalid) */
|
||||
|
||||
#define ARM_EXCEPTION_RESET 0
|
||||
#define ARM_EXCEPTION_UNDEFINED 1
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct mmu_gather {
|
|||
struct mm_struct *mm;
|
||||
unsigned int fullmm;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long start, end;
|
||||
unsigned long range_start;
|
||||
unsigned long range_end;
|
||||
unsigned int nr;
|
||||
|
|
@ -107,10 +108,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->fullmm = fullmm;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->vma = NULL;
|
||||
tlb->max = ARRAY_SIZE(tlb->local);
|
||||
tlb->pages = tlb->local;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,12 @@ armpmu_map_cache_event(const unsigned (*cache_map)
|
|||
static int
|
||||
armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
|
||||
{
|
||||
int mapping = (*event_map)[config];
|
||||
int mapping;
|
||||
|
||||
if (config >= PERF_COUNT_HW_MAX)
|
||||
return -ENOENT;
|
||||
|
||||
mapping = (*event_map)[config];
|
||||
return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +273,9 @@ validate_event(struct pmu_hw_events *hw_events,
|
|||
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
|
||||
struct pmu *leader_pmu = event->group_leader->pmu;
|
||||
|
||||
if (is_software_event(event))
|
||||
return 1;
|
||||
|
||||
if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
|
||||
return 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,10 @@ static const struct coproc_reg cp15_regs[] = {
|
|||
NULL, reset_unknown, c6_DFAR },
|
||||
{ CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32,
|
||||
NULL, reset_unknown, c6_IFAR },
|
||||
|
||||
/* PAR swapped by interrupt.S */
|
||||
{ CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
|
||||
|
||||
/*
|
||||
* DC{C,I,CI}SW operations:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ __kvm_hyp_code_start:
|
|||
ENTRY(__kvm_tlb_flush_vmid_ipa)
|
||||
push {r2, r3}
|
||||
|
||||
dsb ishst
|
||||
add r0, r0, #KVM_VTTBR
|
||||
ldrd r2, r3, [r0]
|
||||
mcrr p15, 6, r2, r3, c2 @ Write VTTBR
|
||||
|
|
@ -291,6 +292,7 @@ THUMB( orr r2, r2, #PSR_T_BIT )
|
|||
ldr r2, =BSYM(panic)
|
||||
msr ELR_hyp, r2
|
||||
ldr r0, =\panic_str
|
||||
clrex @ Clear exclusive monitor
|
||||
eret
|
||||
.endm
|
||||
|
||||
|
|
@ -414,6 +416,10 @@ guest_trap:
|
|||
mrcne p15, 4, r2, c6, c0, 4 @ HPFAR
|
||||
bne 3f
|
||||
|
||||
/* Preserve PAR */
|
||||
mrrc p15, 0, r0, r1, c7 @ PAR
|
||||
push {r0, r1}
|
||||
|
||||
/* Resolve IPA using the xFAR */
|
||||
mcr p15, 0, r2, c7, c8, 0 @ ATS1CPR
|
||||
isb
|
||||
|
|
@ -424,13 +430,20 @@ guest_trap:
|
|||
lsl r2, r2, #4
|
||||
orr r2, r2, r1, lsl #24
|
||||
|
||||
/* Restore PAR */
|
||||
pop {r0, r1}
|
||||
mcrr p15, 0, r0, r1, c7 @ PAR
|
||||
|
||||
3: load_vcpu @ Load VCPU pointer to r0
|
||||
str r2, [r0, #VCPU_HPFAR]
|
||||
|
||||
1: mov r1, #ARM_EXCEPTION_HVC
|
||||
b __kvm_vcpu_return
|
||||
|
||||
4: pop {r0, r1, r2} @ Failed translation, return to guest
|
||||
4: pop {r0, r1} @ Failed translation, return to guest
|
||||
mcrr p15, 0, r0, r1, c7 @ PAR
|
||||
clrex
|
||||
pop {r0, r1, r2}
|
||||
eret
|
||||
|
||||
/*
|
||||
|
|
@ -456,6 +469,7 @@ switch_to_guest_vfp:
|
|||
|
||||
pop {r3-r7}
|
||||
pop {r0-r2}
|
||||
clrex
|
||||
eret
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -302,11 +302,14 @@ vcpu .req r0 @ vcpu pointer always in r0
|
|||
.endif
|
||||
|
||||
mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL
|
||||
mrrc p15, 0, r4, r5, c7 @ PAR
|
||||
|
||||
.if \store_to_vcpu == 0
|
||||
push {r2}
|
||||
push {r2,r4-r5}
|
||||
.else
|
||||
str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
|
||||
add r12, vcpu, #CP15_OFFSET(c7_PAR)
|
||||
strd r4, r5, [r12]
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
|
@ -319,12 +322,15 @@ vcpu .req r0 @ vcpu pointer always in r0
|
|||
*/
|
||||
.macro write_cp15_state read_from_vcpu
|
||||
.if \read_from_vcpu == 0
|
||||
pop {r2}
|
||||
pop {r2,r4-r5}
|
||||
.else
|
||||
ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
|
||||
add r12, vcpu, #CP15_OFFSET(c7_PAR)
|
||||
ldrd r4, r5, [r12]
|
||||
.endif
|
||||
|
||||
mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL
|
||||
mcrr p15, 0, r4, r5, c7 @ PAR
|
||||
|
||||
.if \read_from_vcpu == 0
|
||||
pop {r2-r12}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct mmu_gather {
|
|||
struct mm_struct *mm;
|
||||
unsigned int fullmm;
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long start, end;
|
||||
unsigned long range_start;
|
||||
unsigned long range_end;
|
||||
unsigned int nr;
|
||||
|
|
@ -97,10 +98,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->fullmm = fullmm;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->vma = NULL;
|
||||
tlb->max = ARRAY_SIZE(tlb->local);
|
||||
tlb->pages = tlb->local;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* unmapping a portion of the virtual address space, these hooks are called according to
|
||||
* the following template:
|
||||
*
|
||||
* tlb <- tlb_gather_mmu(mm, full_mm_flush); // start unmap for address space MM
|
||||
* tlb <- tlb_gather_mmu(mm, start, end); // start unmap for address space MM
|
||||
* {
|
||||
* for each vma that needs a shootdown do {
|
||||
* tlb_start_vma(tlb, vma);
|
||||
|
|
@ -58,6 +58,7 @@ struct mmu_gather {
|
|||
unsigned int max;
|
||||
unsigned char fullmm; /* non-zero means full mm flush */
|
||||
unsigned char need_flush; /* really unmapped some PTEs? */
|
||||
unsigned long start, end;
|
||||
unsigned long start_addr;
|
||||
unsigned long end_addr;
|
||||
struct page **pages;
|
||||
|
|
@ -155,13 +156,15 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
|
|||
|
||||
|
||||
static inline void
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->max = ARRAY_SIZE(tlb->local);
|
||||
tlb->pages = tlb->local;
|
||||
tlb->nr = 0;
|
||||
tlb->fullmm = full_mm_flush;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->start_addr = ~0UL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/natfeat.h>
|
||||
|
||||
extern long nf_get_id2(const char *feature_name);
|
||||
|
||||
asm("\n"
|
||||
" .global nf_get_id,nf_call\n"
|
||||
"nf_get_id:\n"
|
||||
" .global nf_get_id2,nf_call\n"
|
||||
"nf_get_id2:\n"
|
||||
" .short 0x7300\n"
|
||||
" rts\n"
|
||||
"nf_call:\n"
|
||||
|
|
@ -29,12 +31,25 @@ asm("\n"
|
|||
"1: moveq.l #0,%d0\n"
|
||||
" rts\n"
|
||||
" .section __ex_table,\"a\"\n"
|
||||
" .long nf_get_id,1b\n"
|
||||
" .long nf_get_id2,1b\n"
|
||||
" .long nf_call,1b\n"
|
||||
" .previous");
|
||||
EXPORT_SYMBOL_GPL(nf_get_id);
|
||||
EXPORT_SYMBOL_GPL(nf_call);
|
||||
|
||||
long nf_get_id(const char *feature_name)
|
||||
{
|
||||
/* feature_name may be in vmalloc()ed memory, so make a copy */
|
||||
char name_copy[32];
|
||||
size_t n;
|
||||
|
||||
n = strlcpy(name_copy, feature_name, sizeof(name_copy));
|
||||
if (n >= sizeof(name_copy))
|
||||
return 0;
|
||||
|
||||
return nf_get_id2(name_copy);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_get_id);
|
||||
|
||||
void nfprint(const char *fmt, ...)
|
||||
{
|
||||
static char buf[256];
|
||||
|
|
|
|||
|
|
@ -15,16 +15,17 @@
|
|||
unsigned long long n64; \
|
||||
} __n; \
|
||||
unsigned long __rem, __upper; \
|
||||
unsigned long __base = (base); \
|
||||
\
|
||||
__n.n64 = (n); \
|
||||
if ((__upper = __n.n32[0])) { \
|
||||
asm ("divul.l %2,%1:%0" \
|
||||
: "=d" (__n.n32[0]), "=d" (__upper) \
|
||||
: "d" (base), "0" (__n.n32[0])); \
|
||||
: "=d" (__n.n32[0]), "=d" (__upper) \
|
||||
: "d" (__base), "0" (__n.n32[0])); \
|
||||
} \
|
||||
asm ("divu.l %2,%1:%0" \
|
||||
: "=d" (__n.n32[1]), "=d" (__rem) \
|
||||
: "d" (base), "1" (__upper), "0" (__n.n32[1])); \
|
||||
: "=d" (__n.n32[1]), "=d" (__rem) \
|
||||
: "d" (__base), "1" (__upper), "0" (__n.n32[1])); \
|
||||
(n) = __n.n64; \
|
||||
__rem; \
|
||||
})
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ config MICROBLAZE
|
|||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_IDLE_POLL_SETUP
|
||||
select MODULES_USE_ELF_RELA
|
||||
select CLONE_BACKWARDS
|
||||
select CLONE_BACKWARDS3
|
||||
|
||||
config SWAP
|
||||
def_bool n
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ struct mmu_gather {
|
|||
struct mm_struct *mm;
|
||||
struct mmu_table_batch *batch;
|
||||
unsigned int fullmm;
|
||||
unsigned long start, end;
|
||||
};
|
||||
|
||||
struct mmu_table_batch {
|
||||
|
|
@ -48,10 +49,13 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
|
|||
|
||||
static inline void tlb_gather_mmu(struct mmu_gather *tlb,
|
||||
struct mm_struct *mm,
|
||||
unsigned int full_mm_flush)
|
||||
unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->fullmm = full_mm_flush;
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
tlb->batch = NULL;
|
||||
if (tlb->fullmm)
|
||||
__tlb_flush_mm(mm);
|
||||
|
|
|
|||
|
|
@ -36,10 +36,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->fullmm = full_mm_flush;
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
|
||||
init_tlb_gather(tlb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
|
|||
}
|
||||
|
||||
static inline void
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
|
||||
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
tlb->fullmm = full_mm_flush;
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
|
||||
init_tlb_gather(tlb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,8 +314,8 @@ static struct uncore_event_desc snbep_uncore_imc_events[] = {
|
|||
static struct uncore_event_desc snbep_uncore_qpi_events[] = {
|
||||
INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"),
|
||||
INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
|
||||
INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"),
|
||||
INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"),
|
||||
INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"),
|
||||
INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"),
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static void find_start_end(unsigned long flags, unsigned long *begin,
|
|||
*begin = new_begin;
|
||||
}
|
||||
} else {
|
||||
*begin = TASK_UNMAPPED_BASE;
|
||||
*begin = mmap_legacy_base();
|
||||
*end = TASK_SIZE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ static unsigned long mmap_base(void)
|
|||
* Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
|
||||
* does, but not when emulating X86_32
|
||||
*/
|
||||
static unsigned long mmap_legacy_base(void)
|
||||
unsigned long mmap_legacy_base(void)
|
||||
{
|
||||
if (mmap_is_ia32())
|
||||
return TASK_UNMAPPED_BASE;
|
||||
|
|
|
|||
|
|
@ -4347,18 +4347,28 @@ static void cfq_exit_queue(struct elevator_queue *e)
|
|||
kfree(cfqd);
|
||||
}
|
||||
|
||||
static int cfq_init_queue(struct request_queue *q)
|
||||
static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
{
|
||||
struct cfq_data *cfqd;
|
||||
struct blkcg_gq *blkg __maybe_unused;
|
||||
int i, ret;
|
||||
struct elevator_queue *eq;
|
||||
|
||||
cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
|
||||
if (!cfqd)
|
||||
eq = elevator_alloc(q, e);
|
||||
if (!eq)
|
||||
return -ENOMEM;
|
||||
|
||||
cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
|
||||
if (!cfqd) {
|
||||
kobject_put(&eq->kobj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
eq->elevator_data = cfqd;
|
||||
|
||||
cfqd->queue = q;
|
||||
q->elevator->elevator_data = cfqd;
|
||||
spin_lock_irq(q->queue_lock);
|
||||
q->elevator = eq;
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
/* Init root service tree */
|
||||
cfqd->grp_service_tree = CFQ_RB_ROOT;
|
||||
|
|
@ -4433,6 +4443,7 @@ static int cfq_init_queue(struct request_queue *q)
|
|||
|
||||
out_free:
|
||||
kfree(cfqd);
|
||||
kobject_put(&eq->kobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -337,13 +337,21 @@ static void deadline_exit_queue(struct elevator_queue *e)
|
|||
/*
|
||||
* initialize elevator private data (deadline_data).
|
||||
*/
|
||||
static int deadline_init_queue(struct request_queue *q)
|
||||
static int deadline_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
{
|
||||
struct deadline_data *dd;
|
||||
struct elevator_queue *eq;
|
||||
|
||||
eq = elevator_alloc(q, e);
|
||||
if (!eq)
|
||||
return -ENOMEM;
|
||||
|
||||
dd = kmalloc_node(sizeof(*dd), GFP_KERNEL | __GFP_ZERO, q->node);
|
||||
if (!dd)
|
||||
if (!dd) {
|
||||
kobject_put(&eq->kobj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
eq->elevator_data = dd;
|
||||
|
||||
INIT_LIST_HEAD(&dd->fifo_list[READ]);
|
||||
INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
|
||||
|
|
@ -355,7 +363,9 @@ static int deadline_init_queue(struct request_queue *q)
|
|||
dd->front_merges = 1;
|
||||
dd->fifo_batch = fifo_batch;
|
||||
|
||||
q->elevator->elevator_data = dd;
|
||||
spin_lock_irq(q->queue_lock);
|
||||
q->elevator = eq;
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ void __init load_default_elevator_module(void)
|
|||
|
||||
static struct kobj_type elv_ktype;
|
||||
|
||||
static struct elevator_queue *elevator_alloc(struct request_queue *q,
|
||||
struct elevator_queue *elevator_alloc(struct request_queue *q,
|
||||
struct elevator_type *e)
|
||||
{
|
||||
struct elevator_queue *eq;
|
||||
|
|
@ -170,6 +170,7 @@ static struct elevator_queue *elevator_alloc(struct request_queue *q,
|
|||
elevator_put(e);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(elevator_alloc);
|
||||
|
||||
static void elevator_release(struct kobject *kobj)
|
||||
{
|
||||
|
|
@ -221,16 +222,7 @@ int elevator_init(struct request_queue *q, char *name)
|
|||
}
|
||||
}
|
||||
|
||||
q->elevator = elevator_alloc(q, e);
|
||||
if (!q->elevator)
|
||||
return -ENOMEM;
|
||||
|
||||
err = e->ops.elevator_init_fn(q);
|
||||
if (err) {
|
||||
kobject_put(&q->elevator->kobj);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = e->ops.elevator_init_fn(q, e);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(elevator_init);
|
||||
|
|
@ -935,17 +927,10 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
|||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
/* allocate, init and register new elevator */
|
||||
err = -ENOMEM;
|
||||
q->elevator = elevator_alloc(q, new_e);
|
||||
if (!q->elevator)
|
||||
err = new_e->ops.elevator_init_fn(q, new_e);
|
||||
if (err)
|
||||
goto fail_init;
|
||||
|
||||
err = new_e->ops.elevator_init_fn(q);
|
||||
if (err) {
|
||||
kobject_put(&q->elevator->kobj);
|
||||
goto fail_init;
|
||||
}
|
||||
|
||||
if (registered) {
|
||||
err = elv_register_queue(q);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -59,16 +59,27 @@ noop_latter_request(struct request_queue *q, struct request *rq)
|
|||
return list_entry(rq->queuelist.next, struct request, queuelist);
|
||||
}
|
||||
|
||||
static int noop_init_queue(struct request_queue *q)
|
||||
static int noop_init_queue(struct request_queue *q, struct elevator_type *e)
|
||||
{
|
||||
struct noop_data *nd;
|
||||
struct elevator_queue *eq;
|
||||
|
||||
nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node);
|
||||
if (!nd)
|
||||
eq = elevator_alloc(q, e);
|
||||
if (!eq)
|
||||
return -ENOMEM;
|
||||
|
||||
nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node);
|
||||
if (!nd) {
|
||||
kobject_put(&eq->kobj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
eq->elevator_data = nd;
|
||||
|
||||
INIT_LIST_HEAD(&nd->queue);
|
||||
q->elevator->elevator_data = nd;
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
q->elevator = eq;
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
|
|||
if ((mc->ptr + rec_len) > mc->end)
|
||||
goto decode_failed;
|
||||
|
||||
memcpy(cf->data, mc->ptr, rec_len);
|
||||
memcpy(cf->data, mc->ptr, cf->can_dlc);
|
||||
mc->ptr += rec_len;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4442,12 +4442,12 @@ il4965_irq_tasklet(struct il_priv *il)
|
|||
* is killed. Hence update the killswitch state here. The
|
||||
* rfkill handler will care about restarting if needed.
|
||||
*/
|
||||
if (!test_bit(S_ALIVE, &il->status)) {
|
||||
if (hw_rf_kill)
|
||||
set_bit(S_RFKILL, &il->status);
|
||||
else
|
||||
clear_bit(S_RFKILL, &il->status);
|
||||
if (hw_rf_kill) {
|
||||
set_bit(S_RFKILL, &il->status);
|
||||
} else {
|
||||
clear_bit(S_RFKILL, &il->status);
|
||||
wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
|
||||
il_force_reset(il, true);
|
||||
}
|
||||
|
||||
handled |= CSR_INT_BIT_RF_KILL;
|
||||
|
|
@ -5316,6 +5316,9 @@ il4965_alive_start(struct il_priv *il)
|
|||
|
||||
il->active_rate = RATES_MASK;
|
||||
|
||||
il_power_update_mode(il, true);
|
||||
D_INFO("Updated power mode\n");
|
||||
|
||||
if (il_is_associated(il)) {
|
||||
struct il_rxon_cmd *active_rxon =
|
||||
(struct il_rxon_cmd *)&il->active;
|
||||
|
|
@ -5346,9 +5349,6 @@ il4965_alive_start(struct il_priv *il)
|
|||
D_INFO("ALIVE processing complete.\n");
|
||||
wake_up(&il->wait_command_queue);
|
||||
|
||||
il_power_update_mode(il, true);
|
||||
D_INFO("Updated power mode\n");
|
||||
|
||||
return;
|
||||
|
||||
restart:
|
||||
|
|
|
|||
|
|
@ -4660,6 +4660,7 @@ il_force_reset(struct il_priv *il, bool external)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(il_force_reset);
|
||||
|
||||
int
|
||||
il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
|
|
|
|||
|
|
@ -78,6 +78,12 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x04d8, 0x000c), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* CarrolTouch 4000U */
|
||||
{ USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* CarrolTouch 4500U */
|
||||
{ USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Samsung Android phone modem - ID conflict with SPH-I500 */
|
||||
{ USB_DEVICE(0x04e8, 0x6601), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
|
|
|||
|
|
@ -1391,21 +1391,20 @@ iso_stream_schedule (
|
|||
|
||||
/* Behind the scheduling threshold? */
|
||||
if (unlikely(start < next)) {
|
||||
unsigned now2 = (now - base) & (mod - 1);
|
||||
|
||||
/* USB_ISO_ASAP: Round up to the first available slot */
|
||||
if (urb->transfer_flags & URB_ISO_ASAP)
|
||||
start += (next - start + period - 1) & -period;
|
||||
|
||||
/*
|
||||
* Not ASAP: Use the next slot in the stream. If
|
||||
* the entire URB falls before the threshold, fail.
|
||||
* Not ASAP: Use the next slot in the stream,
|
||||
* no matter what.
|
||||
*/
|
||||
else if (start + span - period < next) {
|
||||
ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
|
||||
else if (start + span - period < now2) {
|
||||
ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n",
|
||||
urb, start + base,
|
||||
span - period, next + base);
|
||||
status = -EXDEV;
|
||||
goto fail;
|
||||
span - period, now2 + base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2315,7 +2315,7 @@ static int keyspan_startup(struct usb_serial *serial)
|
|||
if (d_details == NULL) {
|
||||
dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
|
||||
__func__, le16_to_cpu(serial->dev->descriptor.idProduct));
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Setup private data for serial driver */
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ struct urbtracker {
|
|||
struct list_head urblist_entry;
|
||||
struct kref ref_count;
|
||||
struct urb *urb;
|
||||
struct usb_ctrlrequest *setup;
|
||||
};
|
||||
|
||||
enum mos7715_pp_modes {
|
||||
|
|
@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref)
|
|||
struct mos7715_parport *mos_parport = urbtrack->mos_parport;
|
||||
|
||||
usb_free_urb(urbtrack->urb);
|
||||
kfree(urbtrack->setup);
|
||||
kfree(urbtrack);
|
||||
kref_put(&mos_parport->ref_count, destroy_mos_parport);
|
||||
}
|
||||
|
|
@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
|||
struct urbtracker *urbtrack;
|
||||
int ret_val;
|
||||
unsigned long flags;
|
||||
struct usb_ctrlrequest setup;
|
||||
struct usb_serial *serial = mos_parport->serial;
|
||||
struct usb_device *usbdev = serial->dev;
|
||||
|
||||
|
|
@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
|||
kfree(urbtrack);
|
||||
return -ENOMEM;
|
||||
}
|
||||
setup.bRequestType = (__u8)0x40;
|
||||
setup.bRequest = (__u8)0x0e;
|
||||
setup.wValue = get_reg_value(reg, dummy);
|
||||
setup.wIndex = get_reg_index(reg);
|
||||
setup.wLength = 0;
|
||||
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
|
||||
if (!urbtrack->setup) {
|
||||
usb_free_urb(urbtrack->urb);
|
||||
kfree(urbtrack);
|
||||
return -ENOMEM;
|
||||
}
|
||||
urbtrack->setup->bRequestType = (__u8)0x40;
|
||||
urbtrack->setup->bRequest = (__u8)0x0e;
|
||||
urbtrack->setup->wValue = get_reg_value(reg, dummy);
|
||||
urbtrack->setup->wIndex = get_reg_index(reg);
|
||||
urbtrack->setup->wLength = 0;
|
||||
usb_fill_control_urb(urbtrack->urb, usbdev,
|
||||
usb_sndctrlpipe(usbdev, 0),
|
||||
(unsigned char *)&setup,
|
||||
(unsigned char *)urbtrack->setup,
|
||||
NULL, 0, async_complete, urbtrack);
|
||||
kref_init(&urbtrack->ref_count);
|
||||
INIT_LIST_HEAD(&urbtrack->urblist_entry);
|
||||
|
|
|
|||
|
|
@ -2208,7 +2208,7 @@ static int mos7810_check(struct usb_serial *serial)
|
|||
static int mos7840_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
u16 product = serial->dev->descriptor.idProduct;
|
||||
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
|
||||
u8 *buf;
|
||||
int device_type;
|
||||
|
||||
|
|
|
|||
|
|
@ -1536,14 +1536,15 @@ static int ti_download_firmware(struct ti_device *tdev)
|
|||
char buf[32];
|
||||
|
||||
/* try ID specific firmware first, then try generic firmware */
|
||||
sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
|
||||
dev->descriptor.idProduct);
|
||||
sprintf(buf, "ti_usb-v%04x-p%04x.fw",
|
||||
le16_to_cpu(dev->descriptor.idVendor),
|
||||
le16_to_cpu(dev->descriptor.idProduct));
|
||||
status = request_firmware(&fw_p, buf, &dev->dev);
|
||||
|
||||
if (status != 0) {
|
||||
buf[0] = '\0';
|
||||
if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
|
||||
switch (dev->descriptor.idProduct) {
|
||||
if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) {
|
||||
switch (le16_to_cpu(dev->descriptor.idProduct)) {
|
||||
case MTS_CDMA_PRODUCT_ID:
|
||||
strcpy(buf, "mts_cdma.fw");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -291,18 +291,18 @@ static void usb_wwan_indat_callback(struct urb *urb)
|
|||
tty_flip_buffer_push(&port->port);
|
||||
} else
|
||||
dev_dbg(dev, "%s: empty read urb received\n", __func__);
|
||||
|
||||
/* Resubmit urb so we continue receiving */
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
if (err != -EPERM) {
|
||||
dev_err(dev, "%s: resubmit read urb failed. (%d)\n", __func__, err);
|
||||
/* busy also in error unless we are killed */
|
||||
usb_mark_last_busy(port->serial->dev);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
/* Resubmit urb so we continue receiving */
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
if (err != -EPERM) {
|
||||
dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
|
||||
__func__, err);
|
||||
/* busy also in error unless we are killed */
|
||||
usb_mark_last_busy(port->serial->dev);
|
||||
}
|
||||
} else {
|
||||
usb_mark_last_busy(port->serial->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1110,6 +1110,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb)
|
|||
}
|
||||
spin_lock_irqsave(&xfer->lock, flags);
|
||||
rpipe = xfer->ep->hcpriv;
|
||||
if (rpipe == NULL) {
|
||||
pr_debug("%s: xfer id 0x%08X has no RPIPE. %s",
|
||||
__func__, wa_xfer_id(xfer),
|
||||
"Probably already aborted.\n" );
|
||||
goto out_unlock;
|
||||
}
|
||||
/* Check the delayed list -> if there, release and complete */
|
||||
spin_lock_irqsave(&wa->xfer_list_lock, flags2);
|
||||
if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
|
||||
|
|
@ -1493,8 +1499,7 @@ static void wa_xfer_result_cb(struct urb *urb)
|
|||
break;
|
||||
}
|
||||
usb_status = xfer_result->bTransferStatus & 0x3f;
|
||||
if (usb_status == WA_XFER_STATUS_ABORTED
|
||||
|| usb_status == WA_XFER_STATUS_NOT_FOUND)
|
||||
if (usb_status == WA_XFER_STATUS_NOT_FOUND)
|
||||
/* taken care of already */
|
||||
break;
|
||||
xfer_id = xfer_result->dwTransferID;
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
|
|||
return -ENOMEM;
|
||||
|
||||
lru_add_drain();
|
||||
tlb_gather_mmu(&tlb, mm, 0);
|
||||
tlb_gather_mmu(&tlb, mm, old_start, old_end);
|
||||
if (new_end > old_start) {
|
||||
/*
|
||||
* when the old and new regions overlap clear from new_end.
|
||||
|
|
@ -624,7 +624,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
|
|||
free_pgd_range(&tlb, old_start, old_end, new_end,
|
||||
vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);
|
||||
}
|
||||
tlb_finish_mmu(&tlb, new_end, old_end);
|
||||
tlb_finish_mmu(&tlb, old_start, old_end);
|
||||
|
||||
/*
|
||||
* Shrink the vma to just the new range. Always succeeds.
|
||||
|
|
|
|||
|
|
@ -219,10 +219,10 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
|
|||
set_buffer_prio(bh);
|
||||
if (ext4_handle_valid(handle)) {
|
||||
err = jbd2_journal_dirty_metadata(handle, bh);
|
||||
if (err) {
|
||||
/* Errors can only happen if there is a bug */
|
||||
handle->h_err = err;
|
||||
__ext4_journal_stop(where, line, handle);
|
||||
/* Errors can only happen if there is a bug */
|
||||
if (WARN_ON_ONCE(err)) {
|
||||
ext4_journal_abort_handle(where, line, __func__, bh,
|
||||
handle, err);
|
||||
}
|
||||
} else {
|
||||
if (inode)
|
||||
|
|
|
|||
|
|
@ -792,14 +792,14 @@ typedef struct {
|
|||
} pagemap_entry_t;
|
||||
|
||||
struct pagemapread {
|
||||
int pos, len;
|
||||
int pos, len; /* units: PM_ENTRY_BYTES, not bytes */
|
||||
pagemap_entry_t *buffer;
|
||||
};
|
||||
|
||||
#define PAGEMAP_WALK_SIZE (PMD_SIZE)
|
||||
#define PAGEMAP_WALK_MASK (PMD_MASK)
|
||||
|
||||
#define PM_ENTRY_BYTES sizeof(u64)
|
||||
#define PM_ENTRY_BYTES sizeof(pagemap_entry_t)
|
||||
#define PM_STATUS_BITS 3
|
||||
#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS)
|
||||
#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
|
||||
|
|
@ -1038,8 +1038,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
|
|||
if (!count)
|
||||
goto out_task;
|
||||
|
||||
pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
|
||||
pm.buffer = kmalloc(pm.len, GFP_TEMPORARY);
|
||||
pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
|
||||
pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY);
|
||||
ret = -ENOMEM;
|
||||
if (!pm.buffer)
|
||||
goto out_task;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ struct mmu_gather {
|
|||
|
||||
#define HAVE_GENERIC_MMU_GATHER
|
||||
|
||||
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
|
||||
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end);
|
||||
void tlb_flush_mmu(struct mmu_gather *tlb);
|
||||
void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
|
||||
unsigned long end);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#ifdef CONFIG_BLOCK
|
||||
|
||||
struct io_cq;
|
||||
struct elevator_type;
|
||||
|
||||
typedef int (elevator_merge_fn) (struct request_queue *, struct request **,
|
||||
struct bio *);
|
||||
|
|
@ -35,7 +36,8 @@ typedef void (elevator_put_req_fn) (struct request *);
|
|||
typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *);
|
||||
typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *);
|
||||
|
||||
typedef int (elevator_init_fn) (struct request_queue *);
|
||||
typedef int (elevator_init_fn) (struct request_queue *,
|
||||
struct elevator_type *e);
|
||||
typedef void (elevator_exit_fn) (struct elevator_queue *);
|
||||
|
||||
struct elevator_ops
|
||||
|
|
@ -155,6 +157,8 @@ extern int elevator_init(struct request_queue *, char *);
|
|||
extern void elevator_exit(struct elevator_queue *);
|
||||
extern int elevator_change(struct request_queue *, const char *);
|
||||
extern bool elv_rq_merge_ok(struct request *, struct bio *);
|
||||
extern struct elevator_queue *elevator_alloc(struct request_queue *,
|
||||
struct elevator_type *);
|
||||
|
||||
/*
|
||||
* Helper functions.
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ struct nsproxy;
|
|||
struct user_namespace;
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
extern unsigned long mmap_legacy_base(void);
|
||||
extern void arch_pick_mmap_layout(struct mm_struct *mm);
|
||||
extern unsigned long
|
||||
arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
|
||||
|
|
|
|||
|
|
@ -802,9 +802,14 @@ asmlinkage long sys_vfork(void);
|
|||
asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int,
|
||||
int __user *);
|
||||
#else
|
||||
#ifdef CONFIG_CLONE_BACKWARDS3
|
||||
asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *,
|
||||
int __user *, int);
|
||||
#else
|
||||
asmlinkage long sys_clone(unsigned long, unsigned long, int __user *,
|
||||
int __user *, int);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
asmlinkage long sys_execve(const char __user *filename,
|
||||
const char __user *const __user *argv,
|
||||
|
|
|
|||
|
|
@ -1502,11 +1502,13 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
|
|||
{
|
||||
struct cpuset *cs = cgroup_cs(cgrp);
|
||||
cpuset_filetype_t type = cft->private;
|
||||
int retval = -ENODEV;
|
||||
int retval = 0;
|
||||
|
||||
mutex_lock(&cpuset_mutex);
|
||||
if (!is_cpuset_online(cs))
|
||||
if (!is_cpuset_online(cs)) {
|
||||
retval = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case FILE_CPU_EXCLUSIVE:
|
||||
|
|
|
|||
|
|
@ -1692,6 +1692,12 @@ SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
|
|||
int __user *, parent_tidptr,
|
||||
int __user *, child_tidptr,
|
||||
int, tls_val)
|
||||
#elif defined(CONFIG_CLONE_BACKWARDS3)
|
||||
SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,
|
||||
int, stack_size,
|
||||
int __user *, parent_tidptr,
|
||||
int __user *, child_tidptr,
|
||||
int, tls_val)
|
||||
#else
|
||||
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
||||
int __user *, parent_tidptr,
|
||||
|
|
|
|||
|
|
@ -293,6 +293,15 @@ int pm_qos_request_active(struct pm_qos_request *req)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pm_qos_request_active);
|
||||
|
||||
static void __pm_qos_update_request(struct pm_qos_request *req,
|
||||
s32 new_value)
|
||||
{
|
||||
if (new_value != req->node.prio)
|
||||
pm_qos_update_target(
|
||||
pm_qos_array[req->pm_qos_class]->constraints,
|
||||
&req->node, PM_QOS_UPDATE_REQ, new_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout
|
||||
* @work: work struct for the delayed work (timeout)
|
||||
|
|
@ -305,7 +314,7 @@ static void pm_qos_work_fn(struct work_struct *work)
|
|||
struct pm_qos_request,
|
||||
work);
|
||||
|
||||
pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE);
|
||||
__pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -365,6 +374,8 @@ void pm_qos_update_request(struct pm_qos_request *req,
|
|||
pm_qos_update_target(
|
||||
pm_qos_array[req->pm_qos_class]->constraints,
|
||||
&req->node, PM_QOS_UPDATE_REQ, new_value);
|
||||
|
||||
__pm_qos_update_request(req, new_value);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pm_qos_update_request);
|
||||
|
||||
|
|
|
|||
|
|
@ -2178,6 +2178,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
|
|||
*/
|
||||
update_entity_load_avg(curr, 1);
|
||||
update_cfs_rq_blocked_load(cfs_rq, 1);
|
||||
update_cfs_shares(cfs_rq);
|
||||
|
||||
#ifdef CONFIG_SCHED_HRTICK
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -2490,7 +2490,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
|
|||
|
||||
mm = vma->vm_mm;
|
||||
|
||||
tlb_gather_mmu(&tlb, mm, 0);
|
||||
tlb_gather_mmu(&tlb, mm, start, end);
|
||||
__unmap_hugepage_range(&tlb, vma, start, end, ref_page);
|
||||
tlb_finish_mmu(&tlb, start, end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3186,11 +3186,11 @@ int memcg_register_cache(struct mem_cgroup *memcg, struct kmem_cache *s,
|
|||
if (!s->memcg_params)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&s->memcg_params->destroy,
|
||||
kmem_cache_destroy_work_func);
|
||||
if (memcg) {
|
||||
s->memcg_params->memcg = memcg;
|
||||
s->memcg_params->root_cache = root_cache;
|
||||
INIT_WORK(&s->memcg_params->destroy,
|
||||
kmem_cache_destroy_work_func);
|
||||
} else
|
||||
s->memcg_params->is_root_cache = true;
|
||||
|
||||
|
|
|
|||
36
mm/memory.c
36
mm/memory.c
|
|
@ -211,14 +211,15 @@ static int tlb_next_batch(struct mmu_gather *tlb)
|
|||
* tear-down from @mm. The @fullmm argument is used when @mm is without
|
||||
* users and we're going to destroy the full address space (exit/execve).
|
||||
*/
|
||||
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
|
||||
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
|
||||
{
|
||||
tlb->mm = mm;
|
||||
|
||||
tlb->fullmm = fullmm;
|
||||
/* Is it from 0 to ~0? */
|
||||
tlb->fullmm = !(start | (end+1));
|
||||
tlb->need_flush_all = 0;
|
||||
tlb->start = -1UL;
|
||||
tlb->end = 0;
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb->need_flush = 0;
|
||||
tlb->local.next = NULL;
|
||||
tlb->local.nr = 0;
|
||||
|
|
@ -258,8 +259,6 @@ void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long e
|
|||
{
|
||||
struct mmu_gather_batch *batch, *next;
|
||||
|
||||
tlb->start = start;
|
||||
tlb->end = end;
|
||||
tlb_flush_mmu(tlb);
|
||||
|
||||
/* keep the page table cache within bounds */
|
||||
|
|
@ -1101,7 +1100,6 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
|||
spinlock_t *ptl;
|
||||
pte_t *start_pte;
|
||||
pte_t *pte;
|
||||
unsigned long range_start = addr;
|
||||
|
||||
again:
|
||||
init_rss_vec(rss);
|
||||
|
|
@ -1204,17 +1202,25 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
|||
* and page-free while holding it.
|
||||
*/
|
||||
if (force_flush) {
|
||||
unsigned long old_end;
|
||||
|
||||
force_flush = 0;
|
||||
|
||||
#ifdef HAVE_GENERIC_MMU_GATHER
|
||||
tlb->start = range_start;
|
||||
/*
|
||||
* Flush the TLB just for the previous segment,
|
||||
* then update the range to be the remaining
|
||||
* TLB range.
|
||||
*/
|
||||
old_end = tlb->end;
|
||||
tlb->end = addr;
|
||||
#endif
|
||||
|
||||
tlb_flush_mmu(tlb);
|
||||
if (addr != end) {
|
||||
range_start = addr;
|
||||
|
||||
tlb->start = addr;
|
||||
tlb->end = old_end;
|
||||
|
||||
if (addr != end)
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
|
|
@ -1399,7 +1405,7 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start,
|
|||
unsigned long end = start + size;
|
||||
|
||||
lru_add_drain();
|
||||
tlb_gather_mmu(&tlb, mm, 0);
|
||||
tlb_gather_mmu(&tlb, mm, start, end);
|
||||
update_hiwater_rss(mm);
|
||||
mmu_notifier_invalidate_range_start(mm, start, end);
|
||||
for ( ; vma && vma->vm_start < end; vma = vma->vm_next)
|
||||
|
|
@ -1425,7 +1431,7 @@ static void zap_page_range_single(struct vm_area_struct *vma, unsigned long addr
|
|||
unsigned long end = address + size;
|
||||
|
||||
lru_add_drain();
|
||||
tlb_gather_mmu(&tlb, mm, 0);
|
||||
tlb_gather_mmu(&tlb, mm, address, end);
|
||||
update_hiwater_rss(mm);
|
||||
mmu_notifier_invalidate_range_start(mm, address, end);
|
||||
unmap_single_vma(&tlb, vma, address, end, details);
|
||||
|
|
|
|||
|
|
@ -2356,7 +2356,7 @@ static void unmap_region(struct mm_struct *mm,
|
|||
struct mmu_gather tlb;
|
||||
|
||||
lru_add_drain();
|
||||
tlb_gather_mmu(&tlb, mm, 0);
|
||||
tlb_gather_mmu(&tlb, mm, start, end);
|
||||
update_hiwater_rss(mm);
|
||||
unmap_vmas(&tlb, vma, start, end);
|
||||
free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
|
||||
|
|
@ -2735,7 +2735,7 @@ void exit_mmap(struct mm_struct *mm)
|
|||
|
||||
lru_add_drain();
|
||||
flush_cache_mm(mm);
|
||||
tlb_gather_mmu(&tlb, mm, 1);
|
||||
tlb_gather_mmu(&tlb, mm, 0, -1);
|
||||
/* update_hiwater_rss(mm) here? but nobody should be looking */
|
||||
/* Use -1 here to ensure all VMAs in the mm are unmapped */
|
||||
unmap_vmas(&tlb, vma, 0, -1);
|
||||
|
|
|
|||
|
|
@ -237,8 +237,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_channel *channel,
|
||||
const struct ieee80211_ht_operation *ht_oper,
|
||||
const struct ieee80211_vht_operation *vht_oper,
|
||||
struct cfg80211_chan_def *chandef, bool verbose)
|
||||
struct cfg80211_chan_def *chandef, bool tracking)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct cfg80211_chan_def vht_chandef;
|
||||
u32 ht_cfreq, ret;
|
||||
|
||||
|
|
@ -257,7 +258,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
|
||||
channel->band);
|
||||
/* check that channel matches the right operating channel */
|
||||
if (channel->center_freq != ht_cfreq) {
|
||||
if (!tracking && channel->center_freq != ht_cfreq) {
|
||||
/*
|
||||
* It's possible that some APs are confused here;
|
||||
* Netgear WNDR3700 sometimes reports 4 higher than
|
||||
|
|
@ -265,11 +266,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
* since we look at probe response/beacon data here
|
||||
* it should be OK.
|
||||
*/
|
||||
if (verbose)
|
||||
sdata_info(sdata,
|
||||
"Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
|
||||
channel->center_freq, ht_cfreq,
|
||||
ht_oper->primary_chan, channel->band);
|
||||
sdata_info(sdata,
|
||||
"Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
|
||||
channel->center_freq, ht_cfreq,
|
||||
ht_oper->primary_chan, channel->band);
|
||||
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -323,7 +323,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
channel->band);
|
||||
break;
|
||||
default:
|
||||
if (verbose)
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
sdata_info(sdata,
|
||||
"AP VHT operation IE has invalid channel width (%d), disable VHT\n",
|
||||
vht_oper->chan_width);
|
||||
|
|
@ -332,7 +332,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(&vht_chandef)) {
|
||||
if (verbose)
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
sdata_info(sdata,
|
||||
"AP VHT information is invalid, disable VHT\n");
|
||||
ret = IEEE80211_STA_DISABLE_VHT;
|
||||
|
|
@ -345,7 +345,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
|
||||
if (verbose)
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
sdata_info(sdata,
|
||||
"AP VHT information doesn't match HT, disable VHT\n");
|
||||
ret = IEEE80211_STA_DISABLE_VHT;
|
||||
|
|
@ -361,18 +361,27 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
|
|||
if (ret & IEEE80211_STA_DISABLE_VHT)
|
||||
vht_chandef = *chandef;
|
||||
|
||||
/*
|
||||
* Ignore the DISABLED flag when we're already connected and only
|
||||
* tracking the APs beacon for bandwidth changes - otherwise we
|
||||
* might get disconnected here if we connect to an AP, update our
|
||||
* regulatory information based on the AP's country IE and the
|
||||
* information we have is wrong/outdated and disables the channel
|
||||
* that we're actually using for the connection to the AP.
|
||||
*/
|
||||
while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
|
||||
IEEE80211_CHAN_DISABLED)) {
|
||||
tracking ? 0 :
|
||||
IEEE80211_CHAN_DISABLED)) {
|
||||
if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
|
||||
ret = IEEE80211_STA_DISABLE_HT |
|
||||
IEEE80211_STA_DISABLE_VHT;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
ret |= chandef_downgrade(chandef);
|
||||
}
|
||||
|
||||
if (chandef->width != vht_chandef.width && verbose)
|
||||
if (chandef->width != vht_chandef.width && !tracking)
|
||||
sdata_info(sdata,
|
||||
"capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
|
||||
|
||||
|
|
@ -412,7 +421,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* calculate new channel (type) based on HT/VHT operation IEs */
|
||||
flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper,
|
||||
vht_oper, &chandef, false);
|
||||
vht_oper, &chandef, true);
|
||||
|
||||
/*
|
||||
* Downgrade the new channel if we associated with restricted
|
||||
|
|
@ -3906,7 +3915,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
|||
ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
|
||||
cbss->channel,
|
||||
ht_oper, vht_oper,
|
||||
&chandef, true);
|
||||
&chandef, false);
|
||||
|
||||
sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
|
||||
local->rx_chains);
|
||||
|
|
|
|||
|
|
@ -876,6 +876,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
|
|||
cfg80211_leave_mesh(rdev, dev);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
cfg80211_stop_ap(rdev, dev);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -471,10 +471,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
|
|||
goto out_unlock;
|
||||
}
|
||||
*rdev = wiphy_to_dev((*wdev)->wiphy);
|
||||
cb->args[0] = (*rdev)->wiphy_idx;
|
||||
/* 0 is the first index - add 1 to parse only once */
|
||||
cb->args[0] = (*rdev)->wiphy_idx + 1;
|
||||
cb->args[1] = (*wdev)->identifier;
|
||||
} else {
|
||||
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]);
|
||||
/* subtract the 1 again here */
|
||||
struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
|
||||
struct wireless_dev *tmp;
|
||||
|
||||
if (!wiphy) {
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1,
|
|||
}
|
||||
|
||||
#define nid_has_mute(codec, nid, dir) \
|
||||
check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
|
||||
check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
|
||||
#define nid_has_volume(codec, nid, dir) \
|
||||
check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
|
||||
|
||||
|
|
@ -621,7 +621,7 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
|
|||
if (enable)
|
||||
val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
|
||||
}
|
||||
if (caps & AC_AMPCAP_MUTE) {
|
||||
if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) {
|
||||
if (!enable)
|
||||
val |= HDA_AMP_MUTE;
|
||||
}
|
||||
|
|
@ -645,7 +645,7 @@ static unsigned int get_amp_mask_to_modify(struct hda_codec *codec,
|
|||
{
|
||||
unsigned int mask = 0xff;
|
||||
|
||||
if (caps & AC_AMPCAP_MUTE) {
|
||||
if (caps & (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) {
|
||||
if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_MUTE_CTL))
|
||||
mask &= ~0x80;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1027,6 +1027,7 @@ enum {
|
|||
ALC880_FIXUP_GPIO2,
|
||||
ALC880_FIXUP_MEDION_RIM,
|
||||
ALC880_FIXUP_LG,
|
||||
ALC880_FIXUP_LG_LW25,
|
||||
ALC880_FIXUP_W810,
|
||||
ALC880_FIXUP_EAPD_COEF,
|
||||
ALC880_FIXUP_TCL_S700,
|
||||
|
|
@ -1085,6 +1086,14 @@ static const struct hda_fixup alc880_fixups[] = {
|
|||
{ }
|
||||
}
|
||||
},
|
||||
[ALC880_FIXUP_LG_LW25] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x1a, 0x0181344f }, /* line-in */
|
||||
{ 0x1b, 0x0321403f }, /* headphone */
|
||||
{ }
|
||||
}
|
||||
},
|
||||
[ALC880_FIXUP_W810] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
|
|
@ -1337,6 +1346,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
|
||||
SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
|
||||
SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
|
||||
SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
|
||||
SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
|
||||
|
||||
/* Below is the copied entries from alc880_quirks.c.
|
||||
|
|
@ -4200,6 +4210,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
|
||||
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
|
|||
SOC_ENUM("Beep Pitch", beep_pitch_enum),
|
||||
SOC_ENUM("Beep on Time", beep_ontime_enum),
|
||||
SOC_ENUM("Beep off Time", beep_offtime_enum),
|
||||
SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv),
|
||||
SOC_SINGLE_SX_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x07, 0x1f, hl_tlv),
|
||||
SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1),
|
||||
SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
|
||||
SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
|
||||
|
|
|
|||
|
|
@ -682,13 +682,14 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
path = list_first_entry(&w->sources, struct snd_soc_dapm_path,
|
||||
list_sink);
|
||||
if (!path) {
|
||||
if (list_empty(&w->sources)) {
|
||||
dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
path = list_first_entry(&w->sources, struct snd_soc_dapm_path,
|
||||
list_sink);
|
||||
|
||||
ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
reg = TEGRA30_I2S_CIF_RX_CTRL;
|
||||
} else {
|
||||
val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
|
||||
reg = TEGRA30_I2S_CIF_RX_CTRL;
|
||||
reg = TEGRA30_I2S_CIF_TX_CTRL;
|
||||
}
|
||||
|
||||
regmap_write(i2s->regmap, reg, val);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
#include "chip.h"
|
||||
#include "comm.h"
|
||||
|
||||
enum {
|
||||
MIDI_BUFSIZE = 64
|
||||
};
|
||||
|
||||
static void usb6fire_midi_out_handler(struct urb *urb)
|
||||
{
|
||||
struct midi_runtime *rt = urb->context;
|
||||
|
|
@ -156,6 +160,12 @@ int usb6fire_midi_init(struct sfire_chip *chip)
|
|||
if (!rt)
|
||||
return -ENOMEM;
|
||||
|
||||
rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL);
|
||||
if (!rt->out_buffer) {
|
||||
kfree(rt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rt->chip = chip;
|
||||
rt->in_received = usb6fire_midi_in_received;
|
||||
rt->out_buffer[0] = 0x80; /* 'send midi' command */
|
||||
|
|
@ -169,6 +179,7 @@ int usb6fire_midi_init(struct sfire_chip *chip)
|
|||
|
||||
ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
|
||||
if (ret < 0) {
|
||||
kfree(rt->out_buffer);
|
||||
kfree(rt);
|
||||
snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
|
||||
return ret;
|
||||
|
|
@ -197,6 +208,9 @@ void usb6fire_midi_abort(struct sfire_chip *chip)
|
|||
|
||||
void usb6fire_midi_destroy(struct sfire_chip *chip)
|
||||
{
|
||||
kfree(chip->midi);
|
||||
struct midi_runtime *rt = chip->midi;
|
||||
|
||||
kfree(rt->out_buffer);
|
||||
kfree(rt);
|
||||
chip->midi = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
enum {
|
||||
MIDI_BUFSIZE = 64
|
||||
};
|
||||
|
||||
struct midi_runtime {
|
||||
struct sfire_chip *chip;
|
||||
struct snd_rawmidi *instance;
|
||||
|
|
@ -32,7 +28,7 @@ struct midi_runtime {
|
|||
struct snd_rawmidi_substream *out;
|
||||
struct urb out_urb;
|
||||
u8 out_serial; /* serial number of out packet */
|
||||
u8 out_buffer[MIDI_BUFSIZE];
|
||||
u8 *out_buffer;
|
||||
int buffer_offset;
|
||||
|
||||
void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
|
||||
|
|
|
|||
|
|
@ -580,6 +580,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
|
|||
urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
|
||||
}
|
||||
|
||||
static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCM_N_URBS; i++) {
|
||||
rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
|
||||
* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
|
||||
if (!rt->out_urbs[i].buffer)
|
||||
return -ENOMEM;
|
||||
rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB
|
||||
* PCM_MAX_PACKET_SIZE, GFP_KERNEL);
|
||||
if (!rt->in_urbs[i].buffer)
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < PCM_N_URBS; i++) {
|
||||
kfree(rt->out_urbs[i].buffer);
|
||||
kfree(rt->in_urbs[i].buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int usb6fire_pcm_init(struct sfire_chip *chip)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -591,6 +618,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
|
|||
if (!rt)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb6fire_pcm_buffers_init(rt);
|
||||
if (ret) {
|
||||
usb6fire_pcm_buffers_destroy(rt);
|
||||
kfree(rt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rt->chip = chip;
|
||||
rt->stream_state = STREAM_DISABLED;
|
||||
rt->rate = ARRAY_SIZE(rates);
|
||||
|
|
@ -612,6 +646,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
|
|||
|
||||
ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
|
||||
if (ret < 0) {
|
||||
usb6fire_pcm_buffers_destroy(rt);
|
||||
kfree(rt);
|
||||
snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
|
||||
return ret;
|
||||
|
|
@ -627,6 +662,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
|
|||
snd_dma_continuous_data(GFP_KERNEL),
|
||||
MAX_BUFSIZE, MAX_BUFSIZE);
|
||||
if (ret) {
|
||||
usb6fire_pcm_buffers_destroy(rt);
|
||||
kfree(rt);
|
||||
snd_printk(KERN_ERR PREFIX
|
||||
"error preallocating pcm buffers.\n");
|
||||
|
|
@ -671,6 +707,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)
|
|||
|
||||
void usb6fire_pcm_destroy(struct sfire_chip *chip)
|
||||
{
|
||||
kfree(chip->pcm);
|
||||
struct pcm_runtime *rt = chip->pcm;
|
||||
|
||||
usb6fire_pcm_buffers_destroy(rt);
|
||||
kfree(rt);
|
||||
chip->pcm = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ struct pcm_urb {
|
|||
struct urb instance;
|
||||
struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
|
||||
/* END DO NOT SEPARATE */
|
||||
u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
|
||||
u8 *buffer;
|
||||
|
||||
struct pcm_urb *peer;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -888,6 +888,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
|
|||
case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
|
||||
case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
|
||||
case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
|
||||
case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
|
||||
case USB_ID(0x046d, 0x0991):
|
||||
/* Most audio usb devices lie about volume resolution.
|
||||
* Most Logitech webcams have res = 384.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user