This is the 4.4.136 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAlsX88AACgkQONu9yGCS aT4fEBAAygf8GZqR8ql76DdEBREkgTgGrne2+Rq56eylWZyycU2FpZVLe2ct7yjf rbF2XCtxdPmia++z0WvmslDbtUeqSSPOz1jZBEERmyZpjpOkDTwsMUfz75Gvpi83 ZJS4KXseL9W/jrSyIAbHJ4Fq1ffmoWzN8mEepde26Ic2DJ/3mB2Dphgg95UjI7rw KGg3+Jjr21ojrEmI1BOVItgZ6iU0jTgCkwrYrP1eI+OzRjasGMMJRh/HYBfr3GEY N6Ggi5PyIWF/DOeTp53hajOAFbt5WTFK6hiiwLqz+6XQuhY45N1YuXgT/vszZmKz nngD5p5+GWKZoXtRXoLMXts8EdZ55yoyj6dkIOM5W62C3HhxjqpPrLXJMdtm5eO/ tL8/vbB6AzniFB/hQS4IqfqQ6sizcAzGi/vP0eOW2I7K9WIsbXR9vt1BcvVaIrRF O/9xX4QJrceNIUzq25sdS7vv4fk7O0AUq/bZtYWWjKY+4E2LhAPoHgmB7cF/M8jJ K8BtMtClyDqfpIhJiH3PDYdY6jRfYKcNUhMZLBYN9uRwa/5l8cC4AIKBEY8IyhgB i05G8YadInSSqf2eRGZ97Qpn5MVYm2G/r2BtpNLbCfIYUfvnHD7mWfteVjVw4Yjh Q6ERVHkvjEFsn1BPBd34OMVJlDz0oqNT92NwiAlXiA4Sxizvvh4= =0oNX -----END PGP SIGNATURE----- Merge 4.4.136 into android-4.4 Changes in 4.4.136 arm64: lse: Add early clobbers to some input/output asm operands powerpc/64s: Clear PCR on boot USB: serial: cp210x: use tcflag_t to fix incompatible pointer type sh: New gcc support xfs: detect agfl count corruption and reset agfl Revert "ima: limit file hash setting by user to fix and log modes" Input: elan_i2c_smbus - fix corrupted stack tracing: Fix crash when freeing instances with event triggers selinux: KASAN: slab-out-of-bounds in xattr_getsecurity cfg80211: further limit wiphy names to 64 bytes rtlwifi: rtl8192cu: Remove variable self-assignment in rf.c ASoC: Intel: sst: remove redundant variable dma_dev_name irda: fix overly long udelay() tcp: avoid integer overflows in tcp_rcv_space_adjust() i2c: rcar: make sure clocks are on when doing clock calculation i2c: rcar: rework hw init i2c: rcar: remove unused IOERROR state i2c: rcar: remove spinlock i2c: rcar: refactor setup of a msg i2c: rcar: init new messages in irq i2c: rcar: don't issue stop when HW does it automatically i2c: rcar: check master irqs before slave irqs i2c: rcar: revoke START request early dmaengine: usb-dmac: fix endless loop in usb_dmac_chan_terminate_all() iio:kfifo_buf: check for uint overflow MIPS: ptrace: Fix PTRACE_PEEKUSR requests for 64-bit FGRs MIPS: prctl: Disallow FRE without FR with PR_SET_FP_MODE requests scsi: scsi_transport_srp: Fix shost to rport translation stm class: Use vmalloc for the master map hwtracing: stm: fix build error on some arches drm/i915: Disable LVDS on Radiant P845 Kbuild: change CC_OPTIMIZE_FOR_SIZE definition fix io_destroy()/aio_complete() race mm: fix the NULL mapping case in __isolate_lru_page() sparc64: Fix build warnings with gcc 7. Linux 4.4.136 Change-Id: I3457f995cf22c65952271ecd517a46144ac4dc79 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
fb7e319634
34 changed files with 375 additions and 205 deletions
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 4
|
PATCHLEVEL = 4
|
||||||
SUBLEVEL = 135
|
SUBLEVEL = 136
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Blurry Fish Butt
|
NAME = Blurry Fish Butt
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ static inline void atomic_and(int i, atomic_t *v)
|
||||||
/* LSE atomics */
|
/* LSE atomics */
|
||||||
" mvn %w[i], %w[i]\n"
|
" mvn %w[i], %w[i]\n"
|
||||||
" stclr %w[i], %[v]")
|
" stclr %w[i], %[v]")
|
||||||
: [i] "+r" (w0), [v] "+Q" (v->counter)
|
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||||
: "r" (x1)
|
: "r" (x1)
|
||||||
: __LL_SC_CLOBBERS);
|
: __LL_SC_CLOBBERS);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ static inline void atomic_sub(int i, atomic_t *v)
|
||||||
/* LSE atomics */
|
/* LSE atomics */
|
||||||
" neg %w[i], %w[i]\n"
|
" neg %w[i], %w[i]\n"
|
||||||
" stadd %w[i], %[v]")
|
" stadd %w[i], %[v]")
|
||||||
: [i] "+r" (w0), [v] "+Q" (v->counter)
|
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||||
: "r" (x1)
|
: "r" (x1)
|
||||||
: __LL_SC_CLOBBERS);
|
: __LL_SC_CLOBBERS);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \
|
||||||
" neg %w[i], %w[i]\n" \
|
" neg %w[i], %w[i]\n" \
|
||||||
" ldadd" #mb " %w[i], w30, %[v]\n" \
|
" ldadd" #mb " %w[i], w30, %[v]\n" \
|
||||||
" add %w[i], %w[i], w30") \
|
" add %w[i], %w[i], w30") \
|
||||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||||
: "r" (x1) \
|
: "r" (x1) \
|
||||||
: __LL_SC_CLOBBERS , ##cl); \
|
: __LL_SC_CLOBBERS , ##cl); \
|
||||||
\
|
\
|
||||||
|
@ -255,7 +255,7 @@ static inline void atomic64_and(long i, atomic64_t *v)
|
||||||
/* LSE atomics */
|
/* LSE atomics */
|
||||||
" mvn %[i], %[i]\n"
|
" mvn %[i], %[i]\n"
|
||||||
" stclr %[i], %[v]")
|
" stclr %[i], %[v]")
|
||||||
: [i] "+r" (x0), [v] "+Q" (v->counter)
|
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||||
: "r" (x1)
|
: "r" (x1)
|
||||||
: __LL_SC_CLOBBERS);
|
: __LL_SC_CLOBBERS);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ static inline void atomic64_sub(long i, atomic64_t *v)
|
||||||
/* LSE atomics */
|
/* LSE atomics */
|
||||||
" neg %[i], %[i]\n"
|
" neg %[i], %[i]\n"
|
||||||
" stadd %[i], %[v]")
|
" stadd %[i], %[v]")
|
||||||
: [i] "+r" (x0), [v] "+Q" (v->counter)
|
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||||
: "r" (x1)
|
: "r" (x1)
|
||||||
: __LL_SC_CLOBBERS);
|
: __LL_SC_CLOBBERS);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
|
||||||
" neg %[i], %[i]\n" \
|
" neg %[i], %[i]\n" \
|
||||||
" ldadd" #mb " %[i], x30, %[v]\n" \
|
" ldadd" #mb " %[i], x30, %[v]\n" \
|
||||||
" add %[i], %[i], x30") \
|
" add %[i], %[i], x30") \
|
||||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||||
: "r" (x1) \
|
: "r" (x1) \
|
||||||
: __LL_SC_CLOBBERS, ##cl); \
|
: __LL_SC_CLOBBERS, ##cl); \
|
||||||
\
|
\
|
||||||
|
@ -412,7 +412,7 @@ static inline long __cmpxchg_double##name(unsigned long old1, \
|
||||||
" eor %[old1], %[old1], %[oldval1]\n" \
|
" eor %[old1], %[old1], %[oldval1]\n" \
|
||||||
" eor %[old2], %[old2], %[oldval2]\n" \
|
" eor %[old2], %[old2], %[oldval2]\n" \
|
||||||
" orr %[old1], %[old1], %[old2]") \
|
" orr %[old1], %[old1], %[old2]") \
|
||||||
: [old1] "+r" (x0), [old2] "+r" (x1), \
|
: [old1] "+&r" (x0), [old2] "+&r" (x1), \
|
||||||
[v] "+Q" (*(unsigned long *)ptr) \
|
[v] "+Q" (*(unsigned long *)ptr) \
|
||||||
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
|
: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \
|
||||||
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
|
[oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \
|
||||||
|
|
|
@ -684,6 +684,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
|
||||||
if (value & ~known_bits)
|
if (value & ~known_bits)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* Setting FRE without FR is not supported. */
|
||||||
|
if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* Avoid inadvertently triggering emulation */
|
/* Avoid inadvertently triggering emulation */
|
||||||
if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
|
if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
|
||||||
!(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
|
!(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
|
||||||
|
|
|
@ -840,7 +840,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
|
tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
|
||||||
break;
|
break;
|
||||||
case PC:
|
case PC:
|
||||||
tmp = regs->cp0_epc;
|
tmp = regs->cp0_epc;
|
||||||
|
|
|
@ -107,7 +107,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||||
addr & 1);
|
addr & 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
|
tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
|
||||||
break;
|
break;
|
||||||
case PC:
|
case PC:
|
||||||
tmp = regs->cp0_epc;
|
tmp = regs->cp0_epc;
|
||||||
|
|
|
@ -27,6 +27,7 @@ _GLOBAL(__setup_cpu_power7)
|
||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mtspr SPRN_PCR,r0
|
||||||
mfspr r3,SPRN_LPCR
|
mfspr r3,SPRN_LPCR
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
bl __init_tlb_power7
|
bl __init_tlb_power7
|
||||||
|
@ -40,6 +41,7 @@ _GLOBAL(__restore_cpu_power7)
|
||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mtspr SPRN_PCR,r0
|
||||||
mfspr r3,SPRN_LPCR
|
mfspr r3,SPRN_LPCR
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
bl __init_tlb_power7
|
bl __init_tlb_power7
|
||||||
|
@ -55,6 +57,7 @@ _GLOBAL(__setup_cpu_power8)
|
||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mtspr SPRN_PCR,r0
|
||||||
mfspr r3,SPRN_LPCR
|
mfspr r3,SPRN_LPCR
|
||||||
ori r3, r3, LPCR_PECEDH
|
ori r3, r3, LPCR_PECEDH
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
|
@ -74,6 +77,7 @@ _GLOBAL(__restore_cpu_power8)
|
||||||
beqlr
|
beqlr
|
||||||
li r0,0
|
li r0,0
|
||||||
mtspr SPRN_LPID,r0
|
mtspr SPRN_LPID,r0
|
||||||
|
mtspr SPRN_PCR,r0
|
||||||
mfspr r3,SPRN_LPCR
|
mfspr r3,SPRN_LPCR
|
||||||
ori r3, r3, LPCR_PECEDH
|
ori r3, r3, LPCR_PECEDH
|
||||||
bl __init_LPCR
|
bl __init_LPCR
|
||||||
|
|
|
@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3);
|
||||||
DECLARE_EXPORT(__lshrsi3);
|
DECLARE_EXPORT(__lshrsi3);
|
||||||
DECLARE_EXPORT(__ashrsi3);
|
DECLARE_EXPORT(__ashrsi3);
|
||||||
DECLARE_EXPORT(__ashlsi3);
|
DECLARE_EXPORT(__ashlsi3);
|
||||||
|
DECLARE_EXPORT(__lshrsi3_r0);
|
||||||
|
DECLARE_EXPORT(__ashrsi3_r0);
|
||||||
|
DECLARE_EXPORT(__ashlsi3_r0);
|
||||||
DECLARE_EXPORT(__ashiftrt_r4_6);
|
DECLARE_EXPORT(__ashiftrt_r4_6);
|
||||||
DECLARE_EXPORT(__ashiftrt_r4_7);
|
DECLARE_EXPORT(__ashiftrt_r4_7);
|
||||||
DECLARE_EXPORT(__ashiftrt_r4_8);
|
DECLARE_EXPORT(__ashiftrt_r4_8);
|
||||||
|
|
|
@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */
|
||||||
!
|
!
|
||||||
! (none)
|
! (none)
|
||||||
!
|
!
|
||||||
|
! __ashlsi3_r0
|
||||||
|
!
|
||||||
|
! Entry:
|
||||||
|
!
|
||||||
|
! r4: Value to shift
|
||||||
|
! r0: Shifts
|
||||||
|
!
|
||||||
|
! Exit:
|
||||||
|
!
|
||||||
|
! r0: Result
|
||||||
|
!
|
||||||
|
! Destroys:
|
||||||
|
!
|
||||||
|
! (none)
|
||||||
|
|
||||||
|
|
||||||
.global __ashlsi3
|
.global __ashlsi3
|
||||||
|
.global __ashlsi3_r0
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
__ashlsi3:
|
__ashlsi3:
|
||||||
mov #31,r0
|
mov r5,r0
|
||||||
and r0,r5
|
.align 2
|
||||||
|
__ashlsi3_r0:
|
||||||
|
and #31,r0
|
||||||
|
mov.l r4,@-r15
|
||||||
|
mov r0,r4
|
||||||
mova ashlsi3_table,r0
|
mova ashlsi3_table,r0
|
||||||
mov.b @(r0,r5),r5
|
mov.b @(r0,r4),r4
|
||||||
#ifdef __sh1__
|
add r4,r0
|
||||||
add r5,r0
|
|
||||||
jmp @r0
|
jmp @r0
|
||||||
#else
|
mov.l @r15+,r0
|
||||||
braf r5
|
|
||||||
#endif
|
|
||||||
mov r4,r0
|
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
ashlsi3_table:
|
ashlsi3_table:
|
||||||
|
|
|
@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */
|
||||||
!
|
!
|
||||||
! (none)
|
! (none)
|
||||||
!
|
!
|
||||||
|
! __ashrsi3_r0
|
||||||
|
!
|
||||||
|
! Entry:
|
||||||
|
!
|
||||||
|
! r4: Value to shift
|
||||||
|
! r0: Shifts
|
||||||
|
!
|
||||||
|
! Exit:
|
||||||
|
!
|
||||||
|
! r0: Result
|
||||||
|
!
|
||||||
|
! Destroys:
|
||||||
|
!
|
||||||
|
! (none)
|
||||||
|
|
||||||
.global __ashrsi3
|
.global __ashrsi3
|
||||||
|
.global __ashrsi3_r0
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
__ashrsi3:
|
__ashrsi3:
|
||||||
mov #31,r0
|
mov r5,r0
|
||||||
and r0,r5
|
.align 2
|
||||||
|
__ashrsi3_r0:
|
||||||
|
and #31,r0
|
||||||
|
mov.l r4,@-r15
|
||||||
|
mov r0,r4
|
||||||
mova ashrsi3_table,r0
|
mova ashrsi3_table,r0
|
||||||
mov.b @(r0,r5),r5
|
mov.b @(r0,r4),r4
|
||||||
#ifdef __sh1__
|
add r4,r0
|
||||||
add r5,r0
|
|
||||||
jmp @r0
|
jmp @r0
|
||||||
#else
|
mov.l @r15+,r0
|
||||||
braf r5
|
|
||||||
#endif
|
|
||||||
mov r4,r0
|
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
ashrsi3_table:
|
ashrsi3_table:
|
||||||
|
|
|
@ -53,22 +53,38 @@ Boston, MA 02110-1301, USA. */
|
||||||
! Destroys:
|
! Destroys:
|
||||||
!
|
!
|
||||||
! (none)
|
! (none)
|
||||||
|
!
|
||||||
|
! __lshrsi3_r0
|
||||||
|
!
|
||||||
|
! Entry:
|
||||||
|
!
|
||||||
|
! r0: Value to shift
|
||||||
|
! r5: Shifts
|
||||||
|
!
|
||||||
|
! Exit:
|
||||||
|
!
|
||||||
|
! r0: Result
|
||||||
|
!
|
||||||
|
! Destroys:
|
||||||
|
!
|
||||||
|
! (none)
|
||||||
!
|
!
|
||||||
.global __lshrsi3
|
.global __lshrsi3
|
||||||
|
.global __lshrsi3_r0
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
__lshrsi3:
|
__lshrsi3:
|
||||||
mov #31,r0
|
mov r5,r0
|
||||||
and r0,r5
|
.align 2
|
||||||
|
__lshrsi3_r0:
|
||||||
|
and #31,r0
|
||||||
|
mov.l r4,@-r15
|
||||||
|
mov r0,r4
|
||||||
mova lshrsi3_table,r0
|
mova lshrsi3_table,r0
|
||||||
mov.b @(r0,r5),r5
|
mov.b @(r0,r4),r4
|
||||||
#ifdef __sh1__
|
add r4,r0
|
||||||
add r5,r0
|
|
||||||
jmp @r0
|
jmp @r0
|
||||||
#else
|
mov.l @r15+,r0
|
||||||
braf r5
|
|
||||||
#endif
|
|
||||||
mov r4,r0
|
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
lshrsi3_table:
|
lshrsi3_table:
|
||||||
|
|
|
@ -908,7 +908,7 @@ static int register_services(struct ds_info *dp)
|
||||||
pbuf.req.handle = cp->handle;
|
pbuf.req.handle = cp->handle;
|
||||||
pbuf.req.major = 1;
|
pbuf.req.major = 1;
|
||||||
pbuf.req.minor = 0;
|
pbuf.req.minor = 0;
|
||||||
strcpy(pbuf.req.svc_id, cp->service_id);
|
strcpy(pbuf.id_buf, cp->service_id);
|
||||||
|
|
||||||
err = __ds_send(lp, &pbuf, msg_len);
|
err = __ds_send(lp, &pbuf, msg_len);
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
|
|
|
@ -448,7 +448,7 @@ usb_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
||||||
static int usb_dmac_chan_terminate_all(struct dma_chan *chan)
|
static int usb_dmac_chan_terminate_all(struct dma_chan *chan)
|
||||||
{
|
{
|
||||||
struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
|
struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
|
||||||
struct usb_dmac_desc *desc;
|
struct usb_dmac_desc *desc, *_desc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
LIST_HEAD(head);
|
LIST_HEAD(head);
|
||||||
LIST_HEAD(list);
|
LIST_HEAD(list);
|
||||||
|
@ -459,7 +459,7 @@ static int usb_dmac_chan_terminate_all(struct dma_chan *chan)
|
||||||
if (uchan->desc)
|
if (uchan->desc)
|
||||||
uchan->desc = NULL;
|
uchan->desc = NULL;
|
||||||
list_splice_init(&uchan->desc_got, &list);
|
list_splice_init(&uchan->desc_got, &list);
|
||||||
list_for_each_entry(desc, &list, node)
|
list_for_each_entry_safe(desc, _desc, &list, node)
|
||||||
list_move_tail(&desc->node, &uchan->desc_freed);
|
list_move_tail(&desc->node, &uchan->desc_freed);
|
||||||
spin_unlock_irqrestore(&uchan->vc.lock, flags);
|
spin_unlock_irqrestore(&uchan->vc.lock, flags);
|
||||||
vchan_dma_desc_free_list(&uchan->vc, &head);
|
vchan_dma_desc_free_list(&uchan->vc, &head);
|
||||||
|
|
|
@ -768,6 +768,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
|
||||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
|
DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = intel_no_lvds_dmi_callback,
|
||||||
|
.ident = "Radiant P845",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
{ } /* terminating entry */
|
{ } /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/stm.h>
|
#include <linux/stm.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
#include "stm.h"
|
#include "stm.h"
|
||||||
|
|
||||||
#include <uapi/linux/stm.h>
|
#include <uapi/linux/stm.h>
|
||||||
|
@ -602,7 +603,7 @@ static void stm_device_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct stm_device *stm = to_stm_device(dev);
|
struct stm_device *stm = to_stm_device(dev);
|
||||||
|
|
||||||
kfree(stm);
|
vfree(stm);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stm_register_device(struct device *parent, struct stm_data *stm_data,
|
int stm_register_device(struct device *parent, struct stm_data *stm_data,
|
||||||
|
@ -619,7 +620,7 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
nmasters = stm_data->sw_end - stm_data->sw_start;
|
nmasters = stm_data->sw_end - stm_data->sw_start;
|
||||||
stm = kzalloc(sizeof(*stm) + nmasters * sizeof(void *), GFP_KERNEL);
|
stm = vzalloc(sizeof(*stm) + nmasters * sizeof(void *));
|
||||||
if (!stm)
|
if (!stm)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -656,7 +657,7 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
|
||||||
err_device:
|
err_device:
|
||||||
put_device(&stm->dev);
|
put_device(&stm->dev);
|
||||||
err_free:
|
err_free:
|
||||||
kfree(stm);
|
vfree(stm);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spinlock.h>
|
|
||||||
|
|
||||||
/* register offsets */
|
/* register offsets */
|
||||||
#define ICSCR 0x00 /* slave ctrl */
|
#define ICSCR 0x00 /* slave ctrl */
|
||||||
|
@ -84,6 +83,7 @@
|
||||||
|
|
||||||
#define RCAR_BUS_PHASE_START (MDBS | MIE | ESG)
|
#define RCAR_BUS_PHASE_START (MDBS | MIE | ESG)
|
||||||
#define RCAR_BUS_PHASE_DATA (MDBS | MIE)
|
#define RCAR_BUS_PHASE_DATA (MDBS | MIE)
|
||||||
|
#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF)
|
||||||
#define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB)
|
#define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB)
|
||||||
|
|
||||||
#define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE)
|
#define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE)
|
||||||
|
@ -94,7 +94,6 @@
|
||||||
#define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF)
|
#define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF)
|
||||||
|
|
||||||
#define ID_LAST_MSG (1 << 0)
|
#define ID_LAST_MSG (1 << 0)
|
||||||
#define ID_IOERROR (1 << 1)
|
|
||||||
#define ID_DONE (1 << 2)
|
#define ID_DONE (1 << 2)
|
||||||
#define ID_ARBLOST (1 << 3)
|
#define ID_ARBLOST (1 << 3)
|
||||||
#define ID_NACK (1 << 4)
|
#define ID_NACK (1 << 4)
|
||||||
|
@ -108,10 +107,10 @@ enum rcar_i2c_type {
|
||||||
struct rcar_i2c_priv {
|
struct rcar_i2c_priv {
|
||||||
void __iomem *io;
|
void __iomem *io;
|
||||||
struct i2c_adapter adap;
|
struct i2c_adapter adap;
|
||||||
struct i2c_msg *msg;
|
struct i2c_msg *msg;
|
||||||
|
int msgs_left;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
|
||||||
spinlock_t lock;
|
|
||||||
wait_queue_head_t wait;
|
wait_queue_head_t wait;
|
||||||
|
|
||||||
int pos;
|
int pos;
|
||||||
|
@ -144,9 +143,10 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
|
||||||
{
|
{
|
||||||
/* reset master mode */
|
/* reset master mode */
|
||||||
rcar_i2c_write(priv, ICMIER, 0);
|
rcar_i2c_write(priv, ICMIER, 0);
|
||||||
rcar_i2c_write(priv, ICMCR, 0);
|
rcar_i2c_write(priv, ICMCR, MDBS);
|
||||||
rcar_i2c_write(priv, ICMSR, 0);
|
rcar_i2c_write(priv, ICMSR, 0);
|
||||||
rcar_i2c_write(priv, ICMAR, 0);
|
/* start clock */
|
||||||
|
rcar_i2c_write(priv, ICCCR, priv->icccr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
|
static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
|
||||||
|
@ -257,16 +257,28 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
|
||||||
{
|
{
|
||||||
int read = !!rcar_i2c_is_recv(priv);
|
int read = !!rcar_i2c_is_recv(priv);
|
||||||
|
|
||||||
|
priv->pos = 0;
|
||||||
|
priv->flags = 0;
|
||||||
|
if (priv->msgs_left == 1)
|
||||||
|
rcar_i2c_flags_set(priv, ID_LAST_MSG);
|
||||||
|
|
||||||
rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read);
|
rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | read);
|
||||||
rcar_i2c_write(priv, ICMSR, 0);
|
rcar_i2c_write(priv, ICMSR, 0);
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
|
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
|
||||||
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
|
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv)
|
||||||
|
{
|
||||||
|
priv->msg++;
|
||||||
|
priv->msgs_left--;
|
||||||
|
rcar_i2c_prepare_msg(priv);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* interrupt functions
|
* interrupt functions
|
||||||
*/
|
*/
|
||||||
static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
|
static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
{
|
{
|
||||||
struct i2c_msg *msg = priv->msg;
|
struct i2c_msg *msg = priv->msg;
|
||||||
|
|
||||||
|
@ -276,14 +288,7 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
* Do nothing
|
* Do nothing
|
||||||
*/
|
*/
|
||||||
if (!(msr & MDE))
|
if (!(msr & MDE))
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
* If address transfer phase finished,
|
|
||||||
* goto data phase.
|
|
||||||
*/
|
|
||||||
if (msr & MAT)
|
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);
|
|
||||||
|
|
||||||
if (priv->pos < msg->len) {
|
if (priv->pos < msg->len) {
|
||||||
/*
|
/*
|
||||||
|
@ -305,29 +310,23 @@ static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
* [ICRXTX] -> [SHIFT] -> [I2C bus]
|
* [ICRXTX] -> [SHIFT] -> [I2C bus]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->flags & ID_LAST_MSG)
|
if (priv->flags & ID_LAST_MSG) {
|
||||||
/*
|
/*
|
||||||
* If current msg is the _LAST_ msg,
|
* If current msg is the _LAST_ msg,
|
||||||
* prepare stop condition here.
|
* prepare stop condition here.
|
||||||
* ID_DONE will be set on STOP irq.
|
* ID_DONE will be set on STOP irq.
|
||||||
*/
|
*/
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
|
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
|
||||||
else
|
} else {
|
||||||
/*
|
rcar_i2c_next_msg(priv);
|
||||||
* If current msg is _NOT_ last msg,
|
return;
|
||||||
* it doesn't call stop phase.
|
}
|
||||||
* thus, there is no STOP irq.
|
|
||||||
* return ID_DONE here.
|
|
||||||
*/
|
|
||||||
return ID_DONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND);
|
rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
|
static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
{
|
{
|
||||||
struct i2c_msg *msg = priv->msg;
|
struct i2c_msg *msg = priv->msg;
|
||||||
|
|
||||||
|
@ -337,14 +336,10 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
* Do nothing
|
* Do nothing
|
||||||
*/
|
*/
|
||||||
if (!(msr & MDR))
|
if (!(msr & MDR))
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (msr & MAT) {
|
if (msr & MAT) {
|
||||||
/*
|
/* Address transfer phase finished, but no data at this point. */
|
||||||
* Address transfer phase finished,
|
|
||||||
* but, there is no data at this point.
|
|
||||||
* Do nothing.
|
|
||||||
*/
|
|
||||||
} else if (priv->pos < msg->len) {
|
} else if (priv->pos < msg->len) {
|
||||||
/*
|
/*
|
||||||
* get received data
|
* get received data
|
||||||
|
@ -360,12 +355,11 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
|
||||||
*/
|
*/
|
||||||
if (priv->pos + 1 >= msg->len)
|
if (priv->pos + 1 >= msg->len)
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
|
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
|
||||||
|
|
||||||
|
if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG))
|
||||||
|
rcar_i2c_next_msg(priv);
|
||||||
else
|
else
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);
|
rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV);
|
||||||
|
|
||||||
rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
||||||
|
@ -426,22 +420,21 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
|
||||||
static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
||||||
{
|
{
|
||||||
struct rcar_i2c_priv *priv = ptr;
|
struct rcar_i2c_priv *priv = ptr;
|
||||||
irqreturn_t result = IRQ_HANDLED;
|
u32 msr, val;
|
||||||
u32 msr;
|
|
||||||
|
|
||||||
/*-------------- spin lock -----------------*/
|
/* Clear START or STOP as soon as we can */
|
||||||
spin_lock(&priv->lock);
|
val = rcar_i2c_read(priv, ICMCR);
|
||||||
|
rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
|
||||||
if (rcar_i2c_slave_irq(priv))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
msr = rcar_i2c_read(priv, ICMSR);
|
msr = rcar_i2c_read(priv, ICMSR);
|
||||||
|
|
||||||
/* Only handle interrupts that are currently enabled */
|
/* Only handle interrupts that are currently enabled */
|
||||||
msr &= rcar_i2c_read(priv, ICMIER);
|
msr &= rcar_i2c_read(priv, ICMIER);
|
||||||
if (!msr) {
|
if (!msr) {
|
||||||
result = IRQ_NONE;
|
if (rcar_i2c_slave_irq(priv))
|
||||||
goto exit;
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arbitration lost */
|
/* Arbitration lost */
|
||||||
|
@ -452,8 +445,7 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
||||||
|
|
||||||
/* Nack */
|
/* Nack */
|
||||||
if (msr & MNR) {
|
if (msr & MNR) {
|
||||||
/* go to stop phase */
|
/* HW automatically sends STOP after received NACK */
|
||||||
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
|
|
||||||
rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);
|
rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);
|
||||||
rcar_i2c_flags_set(priv, ID_NACK);
|
rcar_i2c_flags_set(priv, ID_NACK);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -461,14 +453,15 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
|
||||||
|
|
||||||
/* Stop */
|
/* Stop */
|
||||||
if (msr & MST) {
|
if (msr & MST) {
|
||||||
|
priv->msgs_left--; /* The last message also made it */
|
||||||
rcar_i2c_flags_set(priv, ID_DONE);
|
rcar_i2c_flags_set(priv, ID_DONE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcar_i2c_is_recv(priv))
|
if (rcar_i2c_is_recv(priv))
|
||||||
rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));
|
rcar_i2c_irq_recv(priv, msr);
|
||||||
else
|
else
|
||||||
rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr));
|
rcar_i2c_irq_send(priv, msr);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (rcar_i2c_flags_has(priv, ID_DONE)) {
|
if (rcar_i2c_flags_has(priv, ID_DONE)) {
|
||||||
|
@ -477,11 +470,7 @@ out:
|
||||||
wake_up(&priv->wait);
|
wake_up(&priv->wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
return IRQ_HANDLED;
|
||||||
spin_unlock(&priv->lock);
|
|
||||||
/*-------------- spin unlock -----------------*/
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
||||||
|
@ -490,22 +479,11 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
||||||
{
|
{
|
||||||
struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
|
struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
|
||||||
struct device *dev = rcar_i2c_priv_to_dev(priv);
|
struct device *dev = rcar_i2c_priv_to_dev(priv);
|
||||||
unsigned long flags;
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
long timeout;
|
long time_left;
|
||||||
|
|
||||||
pm_runtime_get_sync(dev);
|
pm_runtime_get_sync(dev);
|
||||||
|
|
||||||
/*-------------- spin lock -----------------*/
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
|
|
||||||
rcar_i2c_init(priv);
|
|
||||||
/* start clock */
|
|
||||||
rcar_i2c_write(priv, ICCCR, priv->icccr);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
/*-------------- spin unlock -----------------*/
|
|
||||||
|
|
||||||
ret = rcar_i2c_bus_barrier(priv);
|
ret = rcar_i2c_bus_barrier(priv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -514,48 +492,28 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
|
||||||
/* This HW can't send STOP after address phase */
|
/* This HW can't send STOP after address phase */
|
||||||
if (msgs[i].len == 0) {
|
if (msgs[i].len == 0) {
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-------------- spin lock -----------------*/
|
/* init data */
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
priv->msg = msgs;
|
||||||
|
priv->msgs_left = num;
|
||||||
|
|
||||||
/* init each data */
|
rcar_i2c_prepare_msg(priv);
|
||||||
priv->msg = &msgs[i];
|
|
||||||
priv->pos = 0;
|
|
||||||
priv->flags = 0;
|
|
||||||
if (i == num - 1)
|
|
||||||
rcar_i2c_flags_set(priv, ID_LAST_MSG);
|
|
||||||
|
|
||||||
rcar_i2c_prepare_msg(priv);
|
time_left = wait_event_timeout(priv->wait,
|
||||||
|
rcar_i2c_flags_has(priv, ID_DONE),
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
num * adap->timeout);
|
||||||
/*-------------- spin unlock -----------------*/
|
if (!time_left) {
|
||||||
|
rcar_i2c_init(priv);
|
||||||
timeout = wait_event_timeout(priv->wait,
|
ret = -ETIMEDOUT;
|
||||||
rcar_i2c_flags_has(priv, ID_DONE),
|
} else if (rcar_i2c_flags_has(priv, ID_NACK)) {
|
||||||
adap->timeout);
|
ret = -ENXIO;
|
||||||
if (!timeout) {
|
} else if (rcar_i2c_flags_has(priv, ID_ARBLOST)) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -EAGAIN;
|
||||||
break;
|
} else {
|
||||||
}
|
ret = num - priv->msgs_left; /* The number of transfer */
|
||||||
|
|
||||||
if (rcar_i2c_flags_has(priv, ID_NACK)) {
|
|
||||||
ret = -ENXIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rcar_i2c_flags_has(priv, ID_ARBLOST)) {
|
|
||||||
ret = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rcar_i2c_flags_has(priv, ID_IOERROR)) {
|
|
||||||
ret = -EIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = i + 1; /* The number of transfer */
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
pm_runtime_put(dev);
|
pm_runtime_put(dev);
|
||||||
|
@ -650,23 +608,27 @@ static int rcar_i2c_probe(struct platform_device *pdev)
|
||||||
return PTR_ERR(priv->clk);
|
return PTR_ERR(priv->clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
bus_speed = 100000; /* default 100 kHz */
|
|
||||||
of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed);
|
|
||||||
|
|
||||||
priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data;
|
|
||||||
|
|
||||||
ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
priv->io = devm_ioremap_resource(dev, res);
|
priv->io = devm_ioremap_resource(dev, res);
|
||||||
if (IS_ERR(priv->io))
|
if (IS_ERR(priv->io))
|
||||||
return PTR_ERR(priv->io);
|
return PTR_ERR(priv->io);
|
||||||
|
|
||||||
|
bus_speed = 100000; /* default 100 kHz */
|
||||||
|
of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed);
|
||||||
|
|
||||||
|
priv->devtype = (enum rcar_i2c_type)of_match_device(rcar_i2c_dt_ids, dev)->data;
|
||||||
|
|
||||||
|
pm_runtime_enable(dev);
|
||||||
|
pm_runtime_get_sync(dev);
|
||||||
|
ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out_pm_put;
|
||||||
|
|
||||||
|
rcar_i2c_init(priv);
|
||||||
|
pm_runtime_put(dev);
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
init_waitqueue_head(&priv->wait);
|
init_waitqueue_head(&priv->wait);
|
||||||
spin_lock_init(&priv->lock);
|
|
||||||
|
|
||||||
adap = &priv->adap;
|
adap = &priv->adap;
|
||||||
adap->nr = pdev->id;
|
adap->nr = pdev->id;
|
||||||
|
@ -682,22 +644,26 @@ static int rcar_i2c_probe(struct platform_device *pdev)
|
||||||
dev_name(dev), priv);
|
dev_name(dev), priv);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "cannot get irq %d\n", irq);
|
dev_err(dev, "cannot get irq %d\n", irq);
|
||||||
return ret;
|
goto out_pm_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_runtime_enable(dev);
|
|
||||||
platform_set_drvdata(pdev, priv);
|
platform_set_drvdata(pdev, priv);
|
||||||
|
|
||||||
ret = i2c_add_numbered_adapter(adap);
|
ret = i2c_add_numbered_adapter(adap);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "reg adap failed: %d\n", ret);
|
dev_err(dev, "reg adap failed: %d\n", ret);
|
||||||
pm_runtime_disable(dev);
|
goto out_pm_disable;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(dev, "probed\n");
|
dev_info(dev, "probed\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_pm_put:
|
||||||
|
pm_runtime_put(dev);
|
||||||
|
out_pm_disable:
|
||||||
|
pm_runtime_disable(dev);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rcar_i2c_remove(struct platform_device *pdev)
|
static int rcar_i2c_remove(struct platform_device *pdev)
|
||||||
|
|
|
@ -24,6 +24,13 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
|
||||||
if ((length == 0) || (bytes_per_datum == 0))
|
if ((length == 0) || (bytes_per_datum == 0))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we don't overflow an unsigned int after kfifo rounds up to
|
||||||
|
* the next power of 2.
|
||||||
|
*/
|
||||||
|
if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
|
return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
|
||||||
bytes_per_datum, GFP_KERNEL);
|
bytes_per_datum, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ static int elan_smbus_get_baseline_data(struct i2c_client *client,
|
||||||
bool max_baseline, u8 *value)
|
bool max_baseline, u8 *value)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
max_baseline ?
|
max_baseline ?
|
||||||
|
@ -149,7 +149,7 @@ static int elan_smbus_get_version(struct i2c_client *client,
|
||||||
bool iap, u8 *version)
|
bool iap, u8 *version)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
iap ? ETP_SMBUS_IAP_VERSION_CMD :
|
iap ? ETP_SMBUS_IAP_VERSION_CMD :
|
||||||
|
@ -169,7 +169,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client,
|
||||||
u8 *ic_type, u8 *version)
|
u8 *ic_type, u8 *version)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
ETP_SMBUS_SM_VERSION_CMD, val);
|
ETP_SMBUS_SM_VERSION_CMD, val);
|
||||||
|
@ -186,7 +186,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client,
|
||||||
static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
|
static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
ETP_SMBUS_UNIQUEID_CMD, val);
|
ETP_SMBUS_UNIQUEID_CMD, val);
|
||||||
|
@ -203,7 +203,7 @@ static int elan_smbus_get_checksum(struct i2c_client *client,
|
||||||
bool iap, u16 *csum)
|
bool iap, u16 *csum)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
|
iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
|
||||||
|
@ -223,7 +223,7 @@ static int elan_smbus_get_max(struct i2c_client *client,
|
||||||
unsigned int *max_x, unsigned int *max_y)
|
unsigned int *max_x, unsigned int *max_y)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
|
error = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -241,7 +241,7 @@ static int elan_smbus_get_resolution(struct i2c_client *client,
|
||||||
u8 *hw_res_x, u8 *hw_res_y)
|
u8 *hw_res_x, u8 *hw_res_y)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
ETP_SMBUS_RESOLUTION_CMD, val);
|
ETP_SMBUS_RESOLUTION_CMD, val);
|
||||||
|
@ -261,7 +261,7 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
|
||||||
unsigned int *y_traces)
|
unsigned int *y_traces)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client,
|
error = i2c_smbus_read_block_data(client,
|
||||||
ETP_SMBUS_XY_TRACENUM_CMD, val);
|
ETP_SMBUS_XY_TRACENUM_CMD, val);
|
||||||
|
@ -288,7 +288,7 @@ static int elan_smbus_iap_get_mode(struct i2c_client *client,
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
u16 constant;
|
u16 constant;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
|
error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
|
@ -339,7 +339,7 @@ static int elan_smbus_prepare_fw_update(struct i2c_client *client)
|
||||||
int len;
|
int len;
|
||||||
int error;
|
int error;
|
||||||
enum tp_mode mode;
|
enum tp_mode mode;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
|
u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
|
||||||
u16 password;
|
u16 password;
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ static int elan_smbus_write_fw_block(struct i2c_client *client,
|
||||||
struct device *dev = &client->dev;
|
struct device *dev = &client->dev;
|
||||||
int error;
|
int error;
|
||||||
u16 result;
|
u16 result;
|
||||||
u8 val[3];
|
u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Due to the limitation of smbus protocol limiting
|
* Due to the limitation of smbus protocol limiting
|
||||||
|
|
|
@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
|
||||||
|
|
||||||
mtt = irda_get_mtt(skb);
|
mtt = irda_get_mtt(skb);
|
||||||
pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
|
pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
|
||||||
if (mtt)
|
if (mtt > 1000)
|
||||||
|
mdelay(mtt/1000);
|
||||||
|
else if (mtt)
|
||||||
udelay(mtt);
|
udelay(mtt);
|
||||||
|
|
||||||
/* Enable DMA interrupt */
|
/* Enable DMA interrupt */
|
||||||
|
|
|
@ -304,9 +304,6 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
|
||||||
writeVal = 0x00000000;
|
writeVal = 0x00000000;
|
||||||
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
|
if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
|
||||||
writeVal = writeVal - 0x06060606;
|
writeVal = writeVal - 0x06060606;
|
||||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
|
||||||
TXHIGHPWRLEVEL_BT2)
|
|
||||||
writeVal = writeVal;
|
|
||||||
*(p_outwriteval + rf) = writeVal;
|
*(p_outwriteval + rf) = writeVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@ struct srp_internal {
|
||||||
struct transport_container rport_attr_cont;
|
struct transport_container rport_attr_cont;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int scsi_is_srp_rport(const struct device *dev);
|
||||||
|
|
||||||
#define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t)
|
#define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t)
|
||||||
|
|
||||||
#define dev_to_rport(d) container_of(d, struct srp_rport, dev)
|
#define dev_to_rport(d) container_of(d, struct srp_rport, dev)
|
||||||
|
@ -61,9 +63,24 @@ static inline struct Scsi_Host *rport_to_shost(struct srp_rport *r)
|
||||||
return dev_to_shost(r->dev.parent);
|
return dev_to_shost(r->dev.parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int find_child_rport(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct device **child = data;
|
||||||
|
|
||||||
|
if (scsi_is_srp_rport(dev)) {
|
||||||
|
WARN_ON_ONCE(*child);
|
||||||
|
*child = dev;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct srp_rport *shost_to_rport(struct Scsi_Host *shost)
|
static inline struct srp_rport *shost_to_rport(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
return transport_class_to_srp_rport(&shost->shost_gendev);
|
struct device *child = NULL;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(device_for_each_child(&shost->shost_gendev, &child,
|
||||||
|
find_child_rport) < 0);
|
||||||
|
return child ? dev_to_rport(child) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -637,7 +654,8 @@ static enum blk_eh_timer_return srp_timed_out(struct scsi_cmnd *scmd)
|
||||||
struct srp_rport *rport = shost_to_rport(shost);
|
struct srp_rport *rport = shost_to_rport(shost);
|
||||||
|
|
||||||
pr_debug("timeout for sdev %s\n", dev_name(&sdev->sdev_gendev));
|
pr_debug("timeout for sdev %s\n", dev_name(&sdev->sdev_gendev));
|
||||||
return rport->fast_io_fail_tmo < 0 && rport->dev_loss_tmo < 0 &&
|
return rport && rport->fast_io_fail_tmo < 0 &&
|
||||||
|
rport->dev_loss_tmo < 0 &&
|
||||||
i->f->reset_timer_if_blocked && scsi_device_blocked(sdev) ?
|
i->f->reset_timer_if_blocked && scsi_device_blocked(sdev) ?
|
||||||
BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
|
BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
|
||||||
static void cp210x_close(struct usb_serial_port *);
|
static void cp210x_close(struct usb_serial_port *);
|
||||||
static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *);
|
static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *);
|
||||||
static void cp210x_get_termios_port(struct usb_serial_port *port,
|
static void cp210x_get_termios_port(struct usb_serial_port *port,
|
||||||
unsigned int *cflagp, unsigned int *baudp);
|
tcflag_t *cflagp, unsigned int *baudp);
|
||||||
static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
|
static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
|
||||||
struct ktermios *);
|
struct ktermios *);
|
||||||
static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
|
static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
|
||||||
|
@ -515,7 +515,7 @@ static void cp210x_get_termios(struct tty_struct *tty,
|
||||||
&tty->termios.c_cflag, &baud);
|
&tty->termios.c_cflag, &baud);
|
||||||
tty_encode_baud_rate(tty, baud, baud);
|
tty_encode_baud_rate(tty, baud, baud);
|
||||||
} else {
|
} else {
|
||||||
unsigned int cflag;
|
tcflag_t cflag;
|
||||||
cflag = 0;
|
cflag = 0;
|
||||||
cp210x_get_termios_port(port, &cflag, &baud);
|
cp210x_get_termios_port(port, &cflag, &baud);
|
||||||
}
|
}
|
||||||
|
@ -526,10 +526,11 @@ static void cp210x_get_termios(struct tty_struct *tty,
|
||||||
* This is the heart of cp210x_get_termios which always uses a &usb_serial_port.
|
* This is the heart of cp210x_get_termios which always uses a &usb_serial_port.
|
||||||
*/
|
*/
|
||||||
static void cp210x_get_termios_port(struct usb_serial_port *port,
|
static void cp210x_get_termios_port(struct usb_serial_port *port,
|
||||||
unsigned int *cflagp, unsigned int *baudp)
|
tcflag_t *cflagp, unsigned int *baudp)
|
||||||
{
|
{
|
||||||
struct device *dev = &port->dev;
|
struct device *dev = &port->dev;
|
||||||
unsigned int cflag, modem_ctl[4];
|
tcflag_t cflag;
|
||||||
|
unsigned int modem_ctl[4];
|
||||||
unsigned int baud;
|
unsigned int baud;
|
||||||
unsigned int bits;
|
unsigned int bits;
|
||||||
|
|
||||||
|
|
3
fs/aio.c
3
fs/aio.c
|
@ -628,9 +628,8 @@ static void free_ioctx_users(struct percpu_ref *ref)
|
||||||
while (!list_empty(&ctx->active_reqs)) {
|
while (!list_empty(&ctx->active_reqs)) {
|
||||||
req = list_first_entry(&ctx->active_reqs,
|
req = list_first_entry(&ctx->active_reqs,
|
||||||
struct aio_kiocb, ki_list);
|
struct aio_kiocb, ki_list);
|
||||||
|
|
||||||
list_del_init(&req->ki_list);
|
|
||||||
kiocb_cancel(req);
|
kiocb_cancel(req);
|
||||||
|
list_del_init(&req->ki_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irq(&ctx->ctx_lock);
|
spin_unlock_irq(&ctx->ctx_lock);
|
||||||
|
|
|
@ -1923,6 +1923,93 @@ xfs_alloc_space_available(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the agfl fields of the agf for inconsistency or corruption. The purpose
|
||||||
|
* is to detect an agfl header padding mismatch between current and early v5
|
||||||
|
* kernels. This problem manifests as a 1-slot size difference between the
|
||||||
|
* on-disk flcount and the active [first, last] range of a wrapped agfl. This
|
||||||
|
* may also catch variants of agfl count corruption unrelated to padding. Either
|
||||||
|
* way, we'll reset the agfl and warn the user.
|
||||||
|
*
|
||||||
|
* Return true if a reset is required before the agfl can be used, false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
xfs_agfl_needs_reset(
|
||||||
|
struct xfs_mount *mp,
|
||||||
|
struct xfs_agf *agf)
|
||||||
|
{
|
||||||
|
uint32_t f = be32_to_cpu(agf->agf_flfirst);
|
||||||
|
uint32_t l = be32_to_cpu(agf->agf_fllast);
|
||||||
|
uint32_t c = be32_to_cpu(agf->agf_flcount);
|
||||||
|
int agfl_size = XFS_AGFL_SIZE(mp);
|
||||||
|
int active;
|
||||||
|
|
||||||
|
/* no agfl header on v4 supers */
|
||||||
|
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The agf read verifier catches severe corruption of these fields.
|
||||||
|
* Repeat some sanity checks to cover a packed -> unpacked mismatch if
|
||||||
|
* the verifier allows it.
|
||||||
|
*/
|
||||||
|
if (f >= agfl_size || l >= agfl_size)
|
||||||
|
return true;
|
||||||
|
if (c > agfl_size)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check consistency between the on-disk count and the active range. An
|
||||||
|
* agfl padding mismatch manifests as an inconsistent flcount.
|
||||||
|
*/
|
||||||
|
if (c && l >= f)
|
||||||
|
active = l - f + 1;
|
||||||
|
else if (c)
|
||||||
|
active = agfl_size - f + l + 1;
|
||||||
|
else
|
||||||
|
active = 0;
|
||||||
|
|
||||||
|
return active != c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the agfl to an empty state. Ignore/drop any existing blocks since the
|
||||||
|
* agfl content cannot be trusted. Warn the user that a repair is required to
|
||||||
|
* recover leaked blocks.
|
||||||
|
*
|
||||||
|
* The purpose of this mechanism is to handle filesystems affected by the agfl
|
||||||
|
* header padding mismatch problem. A reset keeps the filesystem online with a
|
||||||
|
* relatively minor free space accounting inconsistency rather than suffer the
|
||||||
|
* inevitable crash from use of an invalid agfl block.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xfs_agfl_reset(
|
||||||
|
struct xfs_trans *tp,
|
||||||
|
struct xfs_buf *agbp,
|
||||||
|
struct xfs_perag *pag)
|
||||||
|
{
|
||||||
|
struct xfs_mount *mp = tp->t_mountp;
|
||||||
|
struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
|
||||||
|
|
||||||
|
ASSERT(pag->pagf_agflreset);
|
||||||
|
trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_);
|
||||||
|
|
||||||
|
xfs_warn(mp,
|
||||||
|
"WARNING: Reset corrupted AGFL on AG %u. %d blocks leaked. "
|
||||||
|
"Please unmount and run xfs_repair.",
|
||||||
|
pag->pag_agno, pag->pagf_flcount);
|
||||||
|
|
||||||
|
agf->agf_flfirst = 0;
|
||||||
|
agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
|
||||||
|
agf->agf_flcount = 0;
|
||||||
|
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLLAST |
|
||||||
|
XFS_AGF_FLCOUNT);
|
||||||
|
|
||||||
|
pag->pagf_flcount = 0;
|
||||||
|
pag->pagf_agflreset = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decide whether to use this allocation group for this allocation.
|
* Decide whether to use this allocation group for this allocation.
|
||||||
* If so, fix up the btree freelist's size.
|
* If so, fix up the btree freelist's size.
|
||||||
|
@ -1983,6 +2070,10 @@ xfs_alloc_fix_freelist(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reset a padding mismatched agfl before final free space check */
|
||||||
|
if (pag->pagf_agflreset)
|
||||||
|
xfs_agfl_reset(tp, agbp, pag);
|
||||||
|
|
||||||
/* If there isn't enough total space or single-extent, reject it. */
|
/* If there isn't enough total space or single-extent, reject it. */
|
||||||
need = xfs_alloc_min_freelist(mp, pag);
|
need = xfs_alloc_min_freelist(mp, pag);
|
||||||
if (!xfs_alloc_space_available(args, need, flags))
|
if (!xfs_alloc_space_available(args, need, flags))
|
||||||
|
@ -2121,6 +2212,7 @@ xfs_alloc_get_freelist(
|
||||||
agf->agf_flfirst = 0;
|
agf->agf_flfirst = 0;
|
||||||
|
|
||||||
pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
|
pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
|
||||||
|
ASSERT(!pag->pagf_agflreset);
|
||||||
be32_add_cpu(&agf->agf_flcount, -1);
|
be32_add_cpu(&agf->agf_flcount, -1);
|
||||||
xfs_trans_agflist_delta(tp, -1);
|
xfs_trans_agflist_delta(tp, -1);
|
||||||
pag->pagf_flcount--;
|
pag->pagf_flcount--;
|
||||||
|
@ -2226,6 +2318,7 @@ xfs_alloc_put_freelist(
|
||||||
agf->agf_fllast = 0;
|
agf->agf_fllast = 0;
|
||||||
|
|
||||||
pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
|
pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
|
||||||
|
ASSERT(!pag->pagf_agflreset);
|
||||||
be32_add_cpu(&agf->agf_flcount, 1);
|
be32_add_cpu(&agf->agf_flcount, 1);
|
||||||
xfs_trans_agflist_delta(tp, 1);
|
xfs_trans_agflist_delta(tp, 1);
|
||||||
pag->pagf_flcount++;
|
pag->pagf_flcount++;
|
||||||
|
@ -2417,6 +2510,7 @@ xfs_alloc_read_agf(
|
||||||
pag->pagb_count = 0;
|
pag->pagb_count = 0;
|
||||||
pag->pagb_tree = RB_ROOT;
|
pag->pagb_tree = RB_ROOT;
|
||||||
pag->pagf_init = 1;
|
pag->pagf_init = 1;
|
||||||
|
pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
else if (!XFS_FORCED_SHUTDOWN(mp)) {
|
else if (!XFS_FORCED_SHUTDOWN(mp)) {
|
||||||
|
|
|
@ -278,6 +278,7 @@ typedef struct xfs_perag {
|
||||||
char pagi_inodeok; /* The agi is ok for inodes */
|
char pagi_inodeok; /* The agi is ok for inodes */
|
||||||
__uint8_t pagf_levels[XFS_BTNUM_AGF];
|
__uint8_t pagf_levels[XFS_BTNUM_AGF];
|
||||||
/* # of levels in bno & cnt btree */
|
/* # of levels in bno & cnt btree */
|
||||||
|
bool pagf_agflreset; /* agfl requires reset before use */
|
||||||
__uint32_t pagf_flcount; /* count of blocks in freelist */
|
__uint32_t pagf_flcount; /* count of blocks in freelist */
|
||||||
xfs_extlen_t pagf_freeblks; /* total free blocks */
|
xfs_extlen_t pagf_freeblks; /* total free blocks */
|
||||||
xfs_extlen_t pagf_longest; /* longest free space */
|
xfs_extlen_t pagf_longest; /* longest free space */
|
||||||
|
|
|
@ -1485,7 +1485,7 @@ TRACE_EVENT(xfs_trans_commit_lsn,
|
||||||
__entry->lsn)
|
__entry->lsn)
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(xfs_agf,
|
DECLARE_EVENT_CLASS(xfs_agf_class,
|
||||||
TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags,
|
TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags,
|
||||||
unsigned long caller_ip),
|
unsigned long caller_ip),
|
||||||
TP_ARGS(mp, agf, flags, caller_ip),
|
TP_ARGS(mp, agf, flags, caller_ip),
|
||||||
|
@ -1541,6 +1541,13 @@ TRACE_EVENT(xfs_agf,
|
||||||
__entry->longest,
|
__entry->longest,
|
||||||
(void *)__entry->caller_ip)
|
(void *)__entry->caller_ip)
|
||||||
);
|
);
|
||||||
|
#define DEFINE_AGF_EVENT(name) \
|
||||||
|
DEFINE_EVENT(xfs_agf_class, name, \
|
||||||
|
TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, \
|
||||||
|
unsigned long caller_ip), \
|
||||||
|
TP_ARGS(mp, agf, flags, caller_ip))
|
||||||
|
DEFINE_AGF_EVENT(xfs_agf);
|
||||||
|
DEFINE_AGF_EVENT(xfs_agfl_reset);
|
||||||
|
|
||||||
TRACE_EVENT(xfs_free_extent,
|
TRACE_EVENT(xfs_free_extent,
|
||||||
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
|
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
|
||||||
|
|
|
@ -324,7 +324,7 @@ struct tcp_sock {
|
||||||
|
|
||||||
/* Receiver queue space */
|
/* Receiver queue space */
|
||||||
struct {
|
struct {
|
||||||
int space;
|
u32 space;
|
||||||
u32 seq;
|
u32 seq;
|
||||||
u32 time;
|
u32 time;
|
||||||
} rcvq_space;
|
} rcvq_space;
|
||||||
|
|
|
@ -2195,7 +2195,7 @@ enum nl80211_attrs {
|
||||||
#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
|
#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
|
||||||
#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
|
#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
|
||||||
|
|
||||||
#define NL80211_WIPHY_NAME_MAXLEN 128
|
#define NL80211_WIPHY_NAME_MAXLEN 64
|
||||||
|
|
||||||
#define NL80211_MAX_SUPP_RATES 32
|
#define NL80211_MAX_SUPP_RATES 32
|
||||||
#define NL80211_MAX_SUPP_HT_RATES 77
|
#define NL80211_MAX_SUPP_HT_RATES 77
|
||||||
|
|
13
init/Kconfig
13
init/Kconfig
|
@ -1382,6 +1382,17 @@ source "usr/Kconfig"
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Compiler optimization level"
|
||||||
|
default CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
|
||||||
|
|
||||||
|
config CC_OPTIMIZE_FOR_PERFORMANCE
|
||||||
|
bool "Optimize for performance"
|
||||||
|
help
|
||||||
|
This is the default optimization level for the kernel, building
|
||||||
|
with the "-O2" compiler flag for best performance and most
|
||||||
|
helpful compile-time warnings.
|
||||||
|
|
||||||
config CC_OPTIMIZE_FOR_SIZE
|
config CC_OPTIMIZE_FOR_SIZE
|
||||||
bool "Optimize for size"
|
bool "Optimize for size"
|
||||||
help
|
help
|
||||||
|
@ -1390,6 +1401,8 @@ config CC_OPTIMIZE_FOR_SIZE
|
||||||
|
|
||||||
If unsure, say N.
|
If unsure, say N.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
config SYSCTL
|
config SYSCTL
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
|
|
@ -469,9 +469,10 @@ clear_event_triggers(struct trace_array *tr)
|
||||||
struct trace_event_file *file;
|
struct trace_event_file *file;
|
||||||
|
|
||||||
list_for_each_entry(file, &tr->events, list) {
|
list_for_each_entry(file, &tr->events, list) {
|
||||||
struct event_trigger_data *data;
|
struct event_trigger_data *data, *n;
|
||||||
list_for_each_entry_rcu(data, &file->triggers, list) {
|
list_for_each_entry_safe(data, n, &file->triggers, list) {
|
||||||
trace_event_trigger_enable_disable(file, 0);
|
trace_event_trigger_enable_disable(file, 0);
|
||||||
|
list_del_rcu(&data->list);
|
||||||
if (data->ops->free)
|
if (data->ops->free)
|
||||||
data->ops->free(data->ops, data);
|
data->ops->free(data->ops, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1331,7 +1331,7 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mapping = page_mapping(page);
|
mapping = page_mapping(page);
|
||||||
migrate_dirty = mapping && mapping->a_ops->migratepage;
|
migrate_dirty = !mapping || mapping->a_ops->migratepage;
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
if (!migrate_dirty)
|
if (!migrate_dirty)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -558,8 +558,8 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk,
|
||||||
void tcp_rcv_space_adjust(struct sock *sk)
|
void tcp_rcv_space_adjust(struct sock *sk)
|
||||||
{
|
{
|
||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
|
u32 copied;
|
||||||
int time;
|
int time;
|
||||||
int copied;
|
|
||||||
|
|
||||||
time = tcp_time_stamp - tp->rcvq_space.time;
|
time = tcp_time_stamp - tp->rcvq_space.time;
|
||||||
if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
|
if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
|
||||||
|
@ -581,12 +581,13 @@ void tcp_rcv_space_adjust(struct sock *sk)
|
||||||
|
|
||||||
if (sysctl_tcp_moderate_rcvbuf &&
|
if (sysctl_tcp_moderate_rcvbuf &&
|
||||||
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
|
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
|
||||||
int rcvwin, rcvmem, rcvbuf;
|
int rcvmem, rcvbuf;
|
||||||
|
u64 rcvwin;
|
||||||
|
|
||||||
/* minimal window to cope with packet losses, assuming
|
/* minimal window to cope with packet losses, assuming
|
||||||
* steady state. Add some cushion because of small variations.
|
* steady state. Add some cushion because of small variations.
|
||||||
*/
|
*/
|
||||||
rcvwin = (copied << 1) + 16 * tp->advmss;
|
rcvwin = ((u64)copied << 1) + 16 * tp->advmss;
|
||||||
|
|
||||||
/* If rate increased by 25%,
|
/* If rate increased by 25%,
|
||||||
* assume slow start, rcvwin = 3 * copied
|
* assume slow start, rcvwin = 3 * copied
|
||||||
|
@ -606,7 +607,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
|
||||||
while (tcp_win_from_space(rcvmem) < tp->advmss)
|
while (tcp_win_from_space(rcvmem) < tp->advmss)
|
||||||
rcvmem += 128;
|
rcvmem += 128;
|
||||||
|
|
||||||
rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]);
|
do_div(rcvwin, tp->advmss);
|
||||||
|
rcvbuf = min_t(u64, rcvwin * rcvmem, sysctl_tcp_rmem[2]);
|
||||||
if (rcvbuf > sk->sk_rcvbuf) {
|
if (rcvbuf > sk->sk_rcvbuf) {
|
||||||
sk->sk_rcvbuf = rcvbuf;
|
sk->sk_rcvbuf = rcvbuf;
|
||||||
|
|
||||||
|
|
|
@ -383,14 +383,10 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
|
||||||
result = ima_protect_xattr(dentry, xattr_name, xattr_value,
|
result = ima_protect_xattr(dentry, xattr_name, xattr_value,
|
||||||
xattr_value_len);
|
xattr_value_len);
|
||||||
if (result == 1) {
|
if (result == 1) {
|
||||||
bool digsig;
|
|
||||||
|
|
||||||
if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
|
if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
|
ima_reset_appraise_flags(d_backing_inode(dentry),
|
||||||
if (!digsig && (ima_appraise & IMA_APPRAISE_ENFORCE))
|
(xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0);
|
||||||
return -EPERM;
|
|
||||||
ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
|
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1441,7 +1441,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
|
||||||
scontext_len, &context, def_sid);
|
scontext_len, &context, def_sid);
|
||||||
if (rc == -EINVAL && force) {
|
if (rc == -EINVAL && force) {
|
||||||
context.str = str;
|
context.str = str;
|
||||||
context.len = scontext_len;
|
context.len = strlen(str) + 1;
|
||||||
str = NULL;
|
str = NULL;
|
||||||
} else if (rc)
|
} else if (rc)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
|
@ -260,7 +260,6 @@ int sst_dma_new(struct sst_dsp *sst)
|
||||||
struct sst_pdata *sst_pdata = sst->pdata;
|
struct sst_pdata *sst_pdata = sst->pdata;
|
||||||
struct sst_dma *dma;
|
struct sst_dma *dma;
|
||||||
struct resource mem;
|
struct resource mem;
|
||||||
const char *dma_dev_name;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (sst->pdata->resindex_dma_base == -1)
|
if (sst->pdata->resindex_dma_base == -1)
|
||||||
|
@ -271,7 +270,6 @@ int sst_dma_new(struct sst_dsp *sst)
|
||||||
* is attached to the ADSP IP. */
|
* is attached to the ADSP IP. */
|
||||||
switch (sst->pdata->dma_engine) {
|
switch (sst->pdata->dma_engine) {
|
||||||
case SST_DMA_TYPE_DW:
|
case SST_DMA_TYPE_DW:
|
||||||
dma_dev_name = "dw_dmac";
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(sst->dev, "error: invalid DMA engine %d\n",
|
dev_err(sst->dev, "error: invalid DMA engine %d\n",
|
||||||
|
|
Loading…
Add table
Reference in a new issue