mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/phy/amd-xgbe-phy.c drivers/net/wireless/iwlwifi/Kconfig include/net/mac80211.h iwlwifi/Kconfig and mac80211.h were both trivial overlapping changes. The drivers/net/phy/amd-xgbe-phy.c file got removed in 'net-next' and the bug fix that happened on the 'net' side is already integrated into the rest of the amd-xgbe driver. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
dda922c831
@ -162,7 +162,7 @@ Description: Discover CPUs in the same CPU frequency coordination domain
|
||||
What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
|
||||
Date: August 2008
|
||||
KernelVersion: 2.6.27
|
||||
Contact: discuss@x86-64.org
|
||||
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||
Description: Disable L3 cache indices
|
||||
|
||||
These files exist in every CPU's cache/index3 directory. Each
|
||||
|
@ -20,7 +20,7 @@ Supported chips:
|
||||
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp432.html
|
||||
* Texas Instruments TMP435
|
||||
Prefix: 'tmp435'
|
||||
Addresses scanned: I2C 0x37, 0x48 - 0x4f
|
||||
Addresses scanned: I2C 0x48 - 0x4f
|
||||
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html
|
||||
|
||||
Authors:
|
||||
|
@ -15,8 +15,7 @@ Contents:
|
||||
a) Discovering and configuring TCMU uio devices
|
||||
b) Waiting for events on the device(s)
|
||||
c) Managing the command ring
|
||||
3) Command filtering and pass_level
|
||||
4) A final note
|
||||
3) A final note
|
||||
|
||||
|
||||
TCM Userspace Design
|
||||
@ -324,7 +323,7 @@ int handle_device_events(int fd, void *map)
|
||||
/* Process events from cmd ring until we catch up with cmd_head */
|
||||
while (ent != (void *)mb + mb->cmdr_off + mb->cmd_head) {
|
||||
|
||||
if (tcmu_hdr_get_op(&ent->hdr) == TCMU_OP_CMD) {
|
||||
if (tcmu_hdr_get_op(ent->hdr.len_op) == TCMU_OP_CMD) {
|
||||
uint8_t *cdb = (void *)mb + ent->req.cdb_off;
|
||||
bool success = true;
|
||||
|
||||
@ -339,8 +338,12 @@ int handle_device_events(int fd, void *map)
|
||||
ent->rsp.scsi_status = SCSI_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
else if (tcmu_hdr_get_op(ent->hdr.len_op) != TCMU_OP_PAD) {
|
||||
/* Tell the kernel we didn't handle unknown opcodes */
|
||||
ent->hdr.uflags |= TCMU_UFLAG_UNKNOWN_OP;
|
||||
}
|
||||
else {
|
||||
/* Do nothing for PAD entries */
|
||||
/* Do nothing for PAD entries except update cmd_tail */
|
||||
}
|
||||
|
||||
/* update cmd_tail */
|
||||
@ -360,28 +363,6 @@ int handle_device_events(int fd, void *map)
|
||||
}
|
||||
|
||||
|
||||
Command filtering and pass_level
|
||||
--------------------------------
|
||||
|
||||
TCMU supports a "pass_level" option with valid values of 0 or 1. When
|
||||
the value is 0 (the default), nearly all SCSI commands received for
|
||||
the device are passed through to the handler. This allows maximum
|
||||
flexibility but increases the amount of code required by the handler,
|
||||
to support all mandatory SCSI commands. If pass_level is set to 1,
|
||||
then only IO-related commands are presented, and the rest are handled
|
||||
by LIO's in-kernel command emulation. The commands presented at level
|
||||
1 include all versions of:
|
||||
|
||||
READ
|
||||
WRITE
|
||||
WRITE_VERIFY
|
||||
XDWRITEREAD
|
||||
WRITE_SAME
|
||||
COMPARE_AND_WRITE
|
||||
SYNCHRONIZE_CACHE
|
||||
UNMAP
|
||||
|
||||
|
||||
A final note
|
||||
------------
|
||||
|
||||
|
17
MAINTAINERS
17
MAINTAINERS
@ -2433,7 +2433,6 @@ L: linux-security-module@vger.kernel.org
|
||||
S: Supported
|
||||
F: include/linux/capability.h
|
||||
F: include/uapi/linux/capability.h
|
||||
F: security/capability.c
|
||||
F: security/commoncap.c
|
||||
F: kernel/capability.c
|
||||
|
||||
@ -3831,10 +3830,11 @@ M: David Woodhouse <dwmw2@infradead.org>
|
||||
L: linux-embedded@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
EMULEX LPFC FC SCSI DRIVER
|
||||
M: James Smart <james.smart@emulex.com>
|
||||
EMULEX/AVAGO LPFC FC/FCOE SCSI DRIVER
|
||||
M: James Smart <james.smart@avagotech.com>
|
||||
M: Dick Kennedy <dick.kennedy@avagotech.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://sourceforge.net/projects/lpfcxxxx
|
||||
W: http://www.avagotech.com
|
||||
S: Supported
|
||||
F: drivers/scsi/lpfc/
|
||||
|
||||
@ -8835,9 +8835,11 @@ F: drivers/misc/phantom.c
|
||||
F: include/uapi/linux/phantom.h
|
||||
|
||||
SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
|
||||
M: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
|
||||
M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com>
|
||||
M: Minh Tran <minh.tran@avagotech.com>
|
||||
M: John Soni Jose <sony.john-n@avagotech.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
W: http://www.emulex.com
|
||||
W: http://www.avagotech.com
|
||||
S: Supported
|
||||
F: drivers/scsi/be2iscsi/
|
||||
|
||||
@ -10591,8 +10593,7 @@ F: drivers/virtio/virtio_input.c
|
||||
F: include/uapi/linux/virtio_input.h
|
||||
|
||||
VIA RHINE NETWORK DRIVER
|
||||
M: Roger Luethi <rl@hellgate.ch>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/ethernet/via/via-rhine.c
|
||||
|
||||
VIA SD/MMC CARD CONTROLLER DRIVER
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc4
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Hurr durr I'ma sheep
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -14,6 +14,9 @@ targets := vmlinux.gz vmlinux \
|
||||
tools/bootpzh bootloader bootpheader bootpzheader
|
||||
OBJSTRIP := $(obj)/tools/objstrip
|
||||
|
||||
HOSTCFLAGS := -Wall -I$(objtree)/usr/include
|
||||
BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
|
||||
|
||||
# SRM bootable image. Copy to offset 512 of a partition.
|
||||
$(obj)/bootimage: $(addprefix $(obj)/tools/,mkbb lxboot bootlx) $(obj)/vmlinux.nh
|
||||
( cat $(obj)/tools/lxboot $(obj)/tools/bootlx $(obj)/vmlinux.nh ) > $@
|
||||
@ -96,13 +99,14 @@ $(obj)/tools/bootph: $(obj)/bootpheader $(OBJSTRIP) FORCE
|
||||
$(obj)/tools/bootpzh: $(obj)/bootpzheader $(OBJSTRIP) FORCE
|
||||
$(call if_changed,objstrip)
|
||||
|
||||
LDFLAGS_bootloader := -static -uvsprintf -T #-N -relax
|
||||
LDFLAGS_bootpheader := -static -uvsprintf -T #-N -relax
|
||||
LDFLAGS_bootpzheader := -static -uvsprintf -T #-N -relax
|
||||
LDFLAGS_bootloader := -static -T # -N -relax
|
||||
LDFLAGS_bootloader := -static -T # -N -relax
|
||||
LDFLAGS_bootpheader := -static -T # -N -relax
|
||||
LDFLAGS_bootpzheader := -static -T # -N -relax
|
||||
|
||||
OBJ_bootlx := $(obj)/head.o $(obj)/main.o
|
||||
OBJ_bootph := $(obj)/head.o $(obj)/bootp.o
|
||||
OBJ_bootpzh := $(obj)/head.o $(obj)/bootpz.o $(obj)/misc.o
|
||||
OBJ_bootlx := $(obj)/head.o $(obj)/stdio.o $(obj)/main.o
|
||||
OBJ_bootph := $(obj)/head.o $(obj)/stdio.o $(obj)/bootp.o
|
||||
OBJ_bootpzh := $(obj)/head.o $(obj)/stdio.o $(obj)/bootpz.o $(obj)/misc.o
|
||||
|
||||
$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) $(LIBS_Y) FORCE
|
||||
$(call if_changed,ld)
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "ksize.h"
|
||||
|
||||
extern int vsprintf(char *, const char *, va_list);
|
||||
extern unsigned long switch_to_osf_pal(unsigned long nr,
|
||||
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
|
||||
unsigned long *vptb);
|
||||
|
306
arch/alpha/boot/stdio.c
Normal file
306
arch/alpha/boot/stdio.c
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (C) Paul Mackerras 1997.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
size_t strnlen(const char * s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
# define do_div(n, base) ({ \
|
||||
unsigned int __base = (base); \
|
||||
unsigned int __rem; \
|
||||
__rem = ((unsigned long long)(n)) % __base; \
|
||||
(n) = ((unsigned long long)(n)) / __base; \
|
||||
__rem; \
|
||||
})
|
||||
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
|
||||
i = i*10 + c - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
|
||||
{
|
||||
char c,sign,tmp[66];
|
||||
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
int i;
|
||||
|
||||
if (type & LARGE)
|
||||
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
if (type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
if (base < 2 || base > 36)
|
||||
return 0;
|
||||
c = (type & ZEROPAD) ? '0' : ' ';
|
||||
sign = 0;
|
||||
if (type & SIGN) {
|
||||
if ((signed long long)num < 0) {
|
||||
sign = '-';
|
||||
num = - (signed long long)num;
|
||||
size--;
|
||||
} else if (type & PLUS) {
|
||||
sign = '+';
|
||||
size--;
|
||||
} else if (type & SPACE) {
|
||||
sign = ' ';
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (type & SPECIAL) {
|
||||
if (base == 16)
|
||||
size -= 2;
|
||||
else if (base == 8)
|
||||
size--;
|
||||
}
|
||||
i = 0;
|
||||
if (num == 0)
|
||||
tmp[i++]='0';
|
||||
else while (num != 0) {
|
||||
tmp[i++] = digits[do_div(num, base)];
|
||||
}
|
||||
if (i > precision)
|
||||
precision = i;
|
||||
size -= precision;
|
||||
if (!(type&(ZEROPAD+LEFT)))
|
||||
while(size-->0)
|
||||
*str++ = ' ';
|
||||
if (sign)
|
||||
*str++ = sign;
|
||||
if (type & SPECIAL) {
|
||||
if (base==8)
|
||||
*str++ = '0';
|
||||
else if (base==16) {
|
||||
*str++ = '0';
|
||||
*str++ = digits[33];
|
||||
}
|
||||
}
|
||||
if (!(type & LEFT))
|
||||
while (size-- > 0)
|
||||
*str++ = c;
|
||||
while (i < precision--)
|
||||
*str++ = '0';
|
||||
while (i-- > 0)
|
||||
*str++ = tmp[i];
|
||||
while (size-- > 0)
|
||||
*str++ = ' ';
|
||||
return str;
|
||||
}
|
||||
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long long num;
|
||||
int i, base;
|
||||
char * str;
|
||||
const char *s;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
int field_width; /* width of output field */
|
||||
int precision; /* min. # of digits for integers; max
|
||||
number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||
/* 'z' support added 23/7/1999 S.H. */
|
||||
/* 'z' changed to 'Z' --davidm 1/25/99 */
|
||||
|
||||
|
||||
for (str=buf ; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
*str++ = *fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
repeat:
|
||||
++fmt; /* this also skips first '%' */
|
||||
switch (*fmt) {
|
||||
case '-': flags |= LEFT; goto repeat;
|
||||
case '+': flags |= PLUS; goto repeat;
|
||||
case ' ': flags |= SPACE; goto repeat;
|
||||
case '#': flags |= SPECIAL; goto repeat;
|
||||
case '0': flags |= ZEROPAD; goto repeat;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if ('0' <= *fmt && *fmt <= '9')
|
||||
field_width = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
field_width = va_arg(args, int);
|
||||
if (field_width < 0) {
|
||||
field_width = -field_width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if ('0' <= *fmt && *fmt <= '9')
|
||||
precision = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
precision = va_arg(args, int);
|
||||
}
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
/* get the conversion qualifier */
|
||||
qualifier = -1;
|
||||
if (*fmt == 'l' && *(fmt + 1) == 'l') {
|
||||
qualifier = 'q';
|
||||
fmt += 2;
|
||||
} else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
|
||||
|| *fmt == 'Z') {
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
/* default base */
|
||||
base = 10;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT))
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
*str++ = (unsigned char) va_arg(args, int);
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = strnlen(s, precision);
|
||||
|
||||
if (!(flags & LEFT))
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
for (i = 0; i < len; ++i)
|
||||
*str++ = *s++;
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
if (field_width == -1) {
|
||||
field_width = 2*sizeof(void *);
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
str = number(str,
|
||||
(unsigned long) va_arg(args, void *), 16,
|
||||
field_width, precision, flags);
|
||||
continue;
|
||||
|
||||
|
||||
case 'n':
|
||||
if (qualifier == 'l') {
|
||||
long * ip = va_arg(args, long *);
|
||||
*ip = (str - buf);
|
||||
} else if (qualifier == 'Z') {
|
||||
size_t * ip = va_arg(args, size_t *);
|
||||
*ip = (str - buf);
|
||||
} else {
|
||||
int * ip = va_arg(args, int *);
|
||||
*ip = (str - buf);
|
||||
}
|
||||
continue;
|
||||
|
||||
case '%':
|
||||
*str++ = '%';
|
||||
continue;
|
||||
|
||||
/* integer number formats - set up the flags and "break" */
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= LARGE;
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= SIGN;
|
||||
case 'u':
|
||||
break;
|
||||
|
||||
default:
|
||||
*str++ = '%';
|
||||
if (*fmt)
|
||||
*str++ = *fmt;
|
||||
else
|
||||
--fmt;
|
||||
continue;
|
||||
}
|
||||
if (qualifier == 'l') {
|
||||
num = va_arg(args, unsigned long);
|
||||
if (flags & SIGN)
|
||||
num = (signed long) num;
|
||||
} else if (qualifier == 'q') {
|
||||
num = va_arg(args, unsigned long long);
|
||||
if (flags & SIGN)
|
||||
num = (signed long long) num;
|
||||
} else if (qualifier == 'Z') {
|
||||
num = va_arg(args, size_t);
|
||||
} else if (qualifier == 'h') {
|
||||
num = (unsigned short) va_arg(args, int);
|
||||
if (flags & SIGN)
|
||||
num = (signed short) num;
|
||||
} else {
|
||||
num = va_arg(args, unsigned int);
|
||||
if (flags & SIGN)
|
||||
num = (signed int) num;
|
||||
}
|
||||
str = number(str, num, base, field_width, precision, flags);
|
||||
}
|
||||
*str = '\0';
|
||||
return str-buf;
|
||||
}
|
||||
|
||||
int sprintf(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
@ -27,6 +27,9 @@
|
||||
#include <linux/param.h>
|
||||
#ifdef __ELF__
|
||||
# include <linux/elf.h>
|
||||
# define elfhdr elf64_hdr
|
||||
# define elf_phdr elf64_phdr
|
||||
# define elf_check_arch(x) ((x)->e_machine == EM_ALPHA)
|
||||
#endif
|
||||
|
||||
/* bootfile size must be multiple of BLOCK_SIZE: */
|
||||
|
@ -2,6 +2,5 @@
|
||||
#define _ALPHA_TYPES_H
|
||||
|
||||
#include <asm-generic/int-ll64.h>
|
||||
#include <uapi/asm/types.h>
|
||||
|
||||
#endif /* _ALPHA_TYPES_H */
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <uapi/asm/unistd.h>
|
||||
|
||||
#define NR_SYSCALLS 511
|
||||
#define NR_SYSCALLS 514
|
||||
|
||||
#define __ARCH_WANT_OLD_READDIR
|
||||
#define __ARCH_WANT_STAT64
|
||||
|
@ -472,5 +472,8 @@
|
||||
#define __NR_sched_setattr 508
|
||||
#define __NR_sched_getattr 509
|
||||
#define __NR_renameat2 510
|
||||
#define __NR_getrandom 511
|
||||
#define __NR_memfd_create 512
|
||||
#define __NR_execveat 513
|
||||
|
||||
#endif /* _UAPI_ALPHA_UNISTD_H */
|
||||
|
@ -6,7 +6,6 @@
|
||||
* Error handling code supporting Alpha systems
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
@ -1019,14 +1019,13 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
|
||||
if (tv) {
|
||||
if (get_tv32((struct timeval *)&kts, tv))
|
||||
return -EFAULT;
|
||||
kts.tv_nsec *= 1000;
|
||||
}
|
||||
if (tz) {
|
||||
if (copy_from_user(&ktz, tz, sizeof(*tz)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
kts.tv_nsec *= 1000;
|
||||
|
||||
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
|
||||
}
|
||||
|
||||
|
@ -236,12 +236,11 @@ release_thread(struct task_struct *dead_task)
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy an alpha thread..
|
||||
* Copy architecture-specific thread state
|
||||
*/
|
||||
|
||||
int
|
||||
copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long arg,
|
||||
unsigned long kthread_arg,
|
||||
struct task_struct *p)
|
||||
{
|
||||
extern void ret_from_fork(void);
|
||||
@ -262,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
sizeof(struct switch_stack) + sizeof(struct pt_regs));
|
||||
childstack->r26 = (unsigned long) ret_from_kernel_thread;
|
||||
childstack->r9 = usp; /* function */
|
||||
childstack->r10 = arg;
|
||||
childstack->r10 = kthread_arg;
|
||||
childregs->hae = alpha_mv.hae_cache,
|
||||
childti->pcb.usp = 0;
|
||||
return 0;
|
||||
|
@ -63,7 +63,6 @@ static struct {
|
||||
enum ipi_message_type {
|
||||
IPI_RESCHEDULE,
|
||||
IPI_CALL_FUNC,
|
||||
IPI_CALL_FUNC_SINGLE,
|
||||
IPI_CPU_STOP,
|
||||
};
|
||||
|
||||
@ -506,7 +505,6 @@ setup_profiling_timer(unsigned int multiplier)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
|
||||
{
|
||||
@ -552,10 +550,6 @@ handle_ipi(struct pt_regs *regs)
|
||||
generic_smp_call_function_interrupt();
|
||||
break;
|
||||
|
||||
case IPI_CALL_FUNC_SINGLE:
|
||||
generic_smp_call_function_single_interrupt();
|
||||
break;
|
||||
|
||||
case IPI_CPU_STOP:
|
||||
halt();
|
||||
|
||||
@ -606,7 +600,7 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
|
||||
|
||||
void arch_send_call_function_single_ipi(int cpu)
|
||||
{
|
||||
send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
|
||||
send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -237,8 +237,7 @@ srmcons_init(void)
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
module_init(srmcons_init);
|
||||
device_initcall(srmcons_init);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -331,7 +331,7 @@ marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
|
||||
irq = intline;
|
||||
|
||||
msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI);
|
||||
msi_loc = dev->msi_cap;
|
||||
msg_ctl = 0;
|
||||
if (msi_loc)
|
||||
pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl);
|
||||
|
@ -529,6 +529,9 @@ sys_call_table:
|
||||
.quad sys_sched_setattr
|
||||
.quad sys_sched_getattr
|
||||
.quad sys_renameat2 /* 510 */
|
||||
.quad sys_getrandom
|
||||
.quad sys_memfd_create
|
||||
.quad sys_execveat
|
||||
|
||||
.size sys_call_table, . - sys_call_table
|
||||
.type sys_call_table, @object
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
|
@ -223,7 +223,7 @@ dtb-$(CONFIG_SOC_IMX25) += \
|
||||
imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dtb \
|
||||
imx25-karo-tx25.dtb \
|
||||
imx25-pdk.dtb
|
||||
dtb-$(CONFIG_SOC_IMX31) += \
|
||||
dtb-$(CONFIG_SOC_IMX27) += \
|
||||
imx27-apf27.dtb \
|
||||
imx27-apf27dev.dtb \
|
||||
imx27-eukrea-mbimxsd27-baseboard.dtb \
|
||||
|
@ -80,7 +80,3 @@
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&rtc {
|
||||
system-power-controller;
|
||||
};
|
||||
|
@ -654,7 +654,7 @@
|
||||
wlcore: wlcore@2 {
|
||||
compatible = "ti,wl1271";
|
||||
reg = <2>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */
|
||||
ref-clock-frequency = <38400000>;
|
||||
};
|
||||
|
@ -736,7 +736,7 @@
|
||||
|
||||
display-timings {
|
||||
timing-0 {
|
||||
clock-frequency = <0>;
|
||||
clock-frequency = <57153600>;
|
||||
hactive = <720>;
|
||||
vactive = <1280>;
|
||||
hfront-porch = <5>;
|
||||
|
@ -533,7 +533,7 @@
|
||||
|
||||
fec: ethernet@1002b000 {
|
||||
compatible = "fsl,imx27-fec";
|
||||
reg = <0x1002b000 0x4000>;
|
||||
reg = <0x1002b000 0x1000>;
|
||||
interrupts = <50>;
|
||||
clocks = <&clks IMX27_CLK_FEC_IPG_GATE>,
|
||||
<&clks IMX27_CLK_FEC_AHB_GATE>;
|
||||
|
@ -110,6 +110,8 @@
|
||||
nand@0,0 {
|
||||
reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
|
||||
nand-bus-width = <16>;
|
||||
gpmc,device-width = <2>;
|
||||
ti,nand-ecc-opt = "sw";
|
||||
|
||||
gpmc,sync-clk-ps = <0>;
|
||||
gpmc,cs-on-ns = <0>;
|
||||
|
@ -429,7 +429,7 @@ CONFIG_USB_EHCI_EXYNOS=y
|
||||
CONFIG_USB_EHCI_TEGRA=y
|
||||
CONFIG_USB_EHCI_HCD_STI=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_ISP1760_HCD=y
|
||||
CONFIG_USB_ISP1760=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD_STI=y
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=y
|
||||
|
@ -33,7 +33,9 @@ ret_fast_syscall:
|
||||
UNWIND(.fnstart )
|
||||
UNWIND(.cantunwind )
|
||||
disable_irq @ disable interrupts
|
||||
ldr r1, [tsk, #TI_FLAGS]
|
||||
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
|
||||
tst r1, #_TIF_SYSCALL_WORK
|
||||
bne __sys_trace_return
|
||||
tst r1, #_TIF_WORK_MASK
|
||||
bne fast_work_pending
|
||||
asm_trace_hardirqs_on
|
||||
|
@ -304,16 +304,17 @@ static int probe_current_pmu(struct arm_pmu *pmu)
|
||||
static int of_pmu_irq_cfg(struct platform_device *pdev)
|
||||
{
|
||||
int i, irq;
|
||||
int *irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
|
||||
|
||||
if (!irqs)
|
||||
return -ENOMEM;
|
||||
int *irqs;
|
||||
|
||||
/* Don't bother with PPIs; they're already affine */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq >= 0 && irq_is_percpu(irq))
|
||||
return 0;
|
||||
|
||||
irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
|
||||
if (!irqs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < pdev->num_resources; ++i) {
|
||||
struct device_node *dn;
|
||||
int cpu;
|
||||
|
@ -280,9 +280,15 @@ void __init imx_gpc_check_dt(void)
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
|
||||
if (WARN_ON(!np ||
|
||||
!of_find_property(np, "interrupt-controller", NULL)))
|
||||
pr_warn("Outdated DT detected, system is about to crash!!!\n");
|
||||
if (WARN_ON(!np))
|
||||
return;
|
||||
|
||||
if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
|
||||
pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
|
||||
|
||||
/* map GPC, so that at least CPUidle and WARs keep working */
|
||||
gpc_base = of_iomap(np, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_GENERIC_DOMAINS
|
||||
@ -443,6 +449,10 @@ static int imx_gpc_probe(struct platform_device *pdev)
|
||||
struct regulator *pu_reg;
|
||||
int ret;
|
||||
|
||||
/* bail out if DT too old and doesn't provide the necessary info */
|
||||
if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells"))
|
||||
return 0;
|
||||
|
||||
pu_reg = devm_regulator_get_optional(&pdev->dev, "pu");
|
||||
if (PTR_ERR(pu_reg) == -ENODEV)
|
||||
pu_reg = NULL;
|
||||
|
@ -107,7 +107,7 @@ static int cplds_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
struct cplds *fpga;
|
||||
int ret;
|
||||
unsigned int base_irq = 0;
|
||||
int base_irq;
|
||||
unsigned long irqflags = 0;
|
||||
|
||||
fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL);
|
||||
|
@ -1112,22 +1112,22 @@ void __init sanity_check_meminfo(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first non-section-aligned page, and point
|
||||
* Find the first non-pmd-aligned page, and point
|
||||
* memblock_limit at it. This relies on rounding the
|
||||
* limit down to be section-aligned, which happens at
|
||||
* the end of this function.
|
||||
* limit down to be pmd-aligned, which happens at the
|
||||
* end of this function.
|
||||
*
|
||||
* With this algorithm, the start or end of almost any
|
||||
* bank can be non-section-aligned. The only exception
|
||||
* is that the start of the bank 0 must be section-
|
||||
* bank can be non-pmd-aligned. The only exception is
|
||||
* that the start of the bank 0 must be section-
|
||||
* aligned, since otherwise memory would need to be
|
||||
* allocated when mapping the start of bank 0, which
|
||||
* occurs before any free memory is mapped.
|
||||
*/
|
||||
if (!memblock_limit) {
|
||||
if (!IS_ALIGNED(block_start, SECTION_SIZE))
|
||||
if (!IS_ALIGNED(block_start, PMD_SIZE))
|
||||
memblock_limit = block_start;
|
||||
else if (!IS_ALIGNED(block_end, SECTION_SIZE))
|
||||
else if (!IS_ALIGNED(block_end, PMD_SIZE))
|
||||
memblock_limit = arm_lowmem_limit;
|
||||
}
|
||||
|
||||
@ -1137,12 +1137,12 @@ void __init sanity_check_meminfo(void)
|
||||
high_memory = __va(arm_lowmem_limit - 1) + 1;
|
||||
|
||||
/*
|
||||
* Round the memblock limit down to a section size. This
|
||||
* Round the memblock limit down to a pmd size. This
|
||||
* helps to ensure that we will allocate memory from the
|
||||
* last full section, which should be mapped.
|
||||
* last full pmd, which should be mapped.
|
||||
*/
|
||||
if (memblock_limit)
|
||||
memblock_limit = round_down(memblock_limit, SECTION_SIZE);
|
||||
memblock_limit = round_down(memblock_limit, PMD_SIZE);
|
||||
if (!memblock_limit)
|
||||
memblock_limit = arm_lowmem_limit;
|
||||
|
||||
|
@ -478,9 +478,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
|
||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
{
|
||||
struct pci_controller *controller = bridge->bus->sysdata;
|
||||
|
||||
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
||||
/*
|
||||
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||
* here, pci_create_root_bus() has been called by someone else and
|
||||
* sysdata is likely to be different from what we expect. Let it go in
|
||||
* that case.
|
||||
*/
|
||||
if (!bridge->dev.parent) {
|
||||
struct pci_controller *controller = bridge->bus->sysdata;
|
||||
ACPI_COMPANION_SET(&bridge->dev, controller->companion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X specific prom routines
|
||||
*
|
||||
* Copyright (C) 2015 Laurent Fasnacht <l@libres.ch>
|
||||
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
@ -25,12 +26,14 @@ void __init prom_init(void)
|
||||
{
|
||||
fw_init_cmdline();
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
/* Read the initrd address from the firmware environment */
|
||||
initrd_start = fw_getenvl("initrd_start");
|
||||
if (initrd_start) {
|
||||
initrd_start = KSEG0ADDR(initrd_start);
|
||||
initrd_end = initrd_start + fw_getenvl("initrd_size");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
|
@ -194,7 +194,7 @@ CONFIG_USB_WUSB_CBAF=m
|
||||
CONFIG_USB_C67X00_HCD=m
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_ISP1760_HCD=m
|
||||
CONFIG_USB_ISP1760=m
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_UHCI_HCD=m
|
||||
CONFIG_USB_R8A66597_HCD=m
|
||||
|
@ -29,7 +29,7 @@
|
||||
int kgdb_early_setup;
|
||||
#endif
|
||||
|
||||
static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
|
||||
static DECLARE_BITMAP(irq_map, NR_IRQS);
|
||||
|
||||
int allocate_irqno(void)
|
||||
{
|
||||
|
@ -444,7 +444,7 @@ struct plat_smp_ops bmips5000_smp_ops = {
|
||||
static void bmips_wr_vec(unsigned long dst, char *start, char *end)
|
||||
{
|
||||
memcpy((void *)dst, start, end - start);
|
||||
dma_cache_wback((unsigned long)start, end - start);
|
||||
dma_cache_wback(dst, end - start);
|
||||
local_flush_icache_range(dst, dst + (end - start));
|
||||
instruction_hazard();
|
||||
}
|
||||
|
@ -34,7 +34,12 @@ LEAF(__strnlen_\func\()_asm)
|
||||
FEXPORT(__strnlen_\func\()_nocheck_asm)
|
||||
move v0, a0
|
||||
PTR_ADDU a1, a0 # stop pointer
|
||||
1: beq v0, a1, 1f # limit reached?
|
||||
1:
|
||||
#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
|
||||
.set noat
|
||||
li AT, 1
|
||||
#endif
|
||||
beq v0, a1, 1f # limit reached?
|
||||
.ifeqs "\func", "kernel"
|
||||
EX(lb, t0, (v0), .Lfault\@)
|
||||
.else
|
||||
@ -42,7 +47,13 @@ FEXPORT(__strnlen_\func\()_nocheck_asm)
|
||||
.endif
|
||||
.set noreorder
|
||||
bnez t0, 1b
|
||||
1: PTR_ADDIU v0, 1
|
||||
1:
|
||||
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
|
||||
PTR_ADDIU v0, 1
|
||||
#else
|
||||
PTR_ADDU v0, AT
|
||||
.set at
|
||||
#endif
|
||||
.set reorder
|
||||
PTR_SUBU v0, a0
|
||||
jr ra
|
||||
|
@ -24,7 +24,8 @@ typedef struct {
|
||||
unsigned int icache_line_size;
|
||||
unsigned int ecache_size;
|
||||
unsigned int ecache_line_size;
|
||||
int core_id;
|
||||
unsigned short sock_id;
|
||||
unsigned short core_id;
|
||||
int proc_id;
|
||||
} cpuinfo_sparc;
|
||||
|
||||
|
@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
|
||||
" sllx %1, 32, %1\n"
|
||||
" or %0, %1, %0\n"
|
||||
" .previous\n"
|
||||
" .section .sun_m7_2insn_patch, \"ax\"\n"
|
||||
" .word 661b\n"
|
||||
" sethi %%uhi(%4), %1\n"
|
||||
" sethi %%hi(%4), %0\n"
|
||||
" .word 662b\n"
|
||||
" or %1, %%ulo(%4), %1\n"
|
||||
" or %0, %%lo(%4), %0\n"
|
||||
" .word 663b\n"
|
||||
" sllx %1, 32, %1\n"
|
||||
" or %0, %1, %0\n"
|
||||
" .previous\n"
|
||||
: "=r" (mask), "=r" (tmp)
|
||||
: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
|
||||
_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
|
||||
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
|
||||
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
|
||||
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
|
||||
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V),
|
||||
"i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
|
||||
_PAGE_CP_4V | _PAGE_E_4V |
|
||||
_PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
|
||||
|
||||
return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
|
||||
@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
|
||||
" andn %0, %4, %0\n"
|
||||
" or %0, %5, %0\n"
|
||||
" .previous\n"
|
||||
" .section .sun_m7_2insn_patch, \"ax\"\n"
|
||||
" .word 661b\n"
|
||||
" andn %0, %6, %0\n"
|
||||
" or %0, %5, %0\n"
|
||||
" .previous\n"
|
||||
: "=r" (val)
|
||||
: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
|
||||
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
|
||||
"i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V),
|
||||
"i" (_PAGE_CP_4V));
|
||||
|
||||
return __pgprot(val);
|
||||
}
|
||||
|
@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
|
||||
#ifdef CONFIG_SMP
|
||||
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
|
||||
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
|
||||
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
|
||||
#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
|
||||
#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
extern cpumask_t cpu_core_map[NR_CPUS];
|
||||
extern cpumask_t cpu_core_sib_map[NR_CPUS];
|
||||
static inline const struct cpumask *cpu_coregroup_mask(int cpu)
|
||||
{
|
||||
return &cpu_core_map[cpu];
|
||||
|
@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
|
||||
};
|
||||
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
|
||||
__sun4v_2insn_patch_end;
|
||||
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
|
||||
__sun_m7_2insn_patch_end;
|
||||
|
||||
|
||||
#endif /* !(__ASSEMBLY__) */
|
||||
|
@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
|
||||
struct sun4v_1insn_patch_entry *);
|
||||
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
|
||||
struct sun4v_2insn_patch_entry *);
|
||||
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *,
|
||||
struct sun4v_2insn_patch_entry *);
|
||||
extern unsigned int dcache_parity_tl1_occurred;
|
||||
extern unsigned int icache_parity_tl1_occurred;
|
||||
|
||||
|
@ -723,7 +723,6 @@ static int grpci2_of_probe(struct platform_device *ofdev)
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
memset(grpci2priv, 0, sizeof(*grpci2priv));
|
||||
priv->regs = regs;
|
||||
priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
|
||||
priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;
|
||||
|
@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
|
||||
}
|
||||
}
|
||||
|
||||
static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
|
||||
static void find_back_node_value(struct mdesc_handle *hp, u64 node,
|
||||
char *srch_val,
|
||||
void (*func)(struct mdesc_handle *, u64, int),
|
||||
u64 val, int depth)
|
||||
{
|
||||
u64 a;
|
||||
u64 arc;
|
||||
|
||||
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
|
||||
u64 t = mdesc_arc_target(hp, a);
|
||||
const char *name;
|
||||
const u64 *id;
|
||||
/* Since we have an estimate of recursion depth, do a sanity check. */
|
||||
if (depth == 0)
|
||||
return;
|
||||
|
||||
name = mdesc_node_name(hp, t);
|
||||
if (!strcmp(name, "cpu")) {
|
||||
id = mdesc_get_property(hp, t, "id", NULL);
|
||||
if (*id < NR_CPUS)
|
||||
cpu_data(*id).core_id = core_id;
|
||||
} else {
|
||||
u64 j;
|
||||
mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
|
||||
u64 n = mdesc_arc_target(hp, arc);
|
||||
const char *name = mdesc_node_name(hp, n);
|
||||
|
||||
mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) {
|
||||
u64 n = mdesc_arc_target(hp, j);
|
||||
const char *n_name;
|
||||
if (!strcmp(srch_val, name))
|
||||
(*func)(hp, n, val);
|
||||
|
||||
n_name = mdesc_node_name(hp, n);
|
||||
if (strcmp(n_name, "cpu"))
|
||||
continue;
|
||||
|
||||
id = mdesc_get_property(hp, n, "id", NULL);
|
||||
if (*id < NR_CPUS)
|
||||
cpu_data(*id).core_id = core_id;
|
||||
}
|
||||
}
|
||||
find_back_node_value(hp, n, srch_val, func, val, depth-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __mark_core_id(struct mdesc_handle *hp, u64 node,
|
||||
int core_id)
|
||||
{
|
||||
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
|
||||
|
||||
if (*id < num_possible_cpus())
|
||||
cpu_data(*id).core_id = core_id;
|
||||
}
|
||||
|
||||
static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
|
||||
int sock_id)
|
||||
{
|
||||
const u64 *id = mdesc_get_property(hp, node, "id", NULL);
|
||||
|
||||
if (*id < num_possible_cpus())
|
||||
cpu_data(*id).sock_id = sock_id;
|
||||
}
|
||||
|
||||
static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
|
||||
int core_id)
|
||||
{
|
||||
find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
|
||||
}
|
||||
|
||||
static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
|
||||
int sock_id)
|
||||
{
|
||||
find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
|
||||
}
|
||||
|
||||
static void set_core_ids(struct mdesc_handle *hp)
|
||||
{
|
||||
int idx;
|
||||
u64 mp;
|
||||
|
||||
idx = 1;
|
||||
|
||||
/* Identify unique cores by looking for cpus backpointed to by
|
||||
* level 1 instruction caches.
|
||||
*/
|
||||
mdesc_for_each_node_by_name(hp, mp, "cache") {
|
||||
const u64 *level;
|
||||
const char *type;
|
||||
@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
|
||||
continue;
|
||||
|
||||
mark_core_ids(hp, mp, idx);
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
|
||||
{
|
||||
u64 mp;
|
||||
int idx = 1;
|
||||
int fnd = 0;
|
||||
|
||||
/* Identify unique sockets by looking for cpus backpointed to by
|
||||
* shared level n caches.
|
||||
*/
|
||||
mdesc_for_each_node_by_name(hp, mp, "cache") {
|
||||
const u64 *cur_lvl;
|
||||
|
||||
cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
|
||||
if (*cur_lvl != level)
|
||||
continue;
|
||||
|
||||
mark_sock_ids(hp, mp, idx);
|
||||
idx++;
|
||||
fnd = 1;
|
||||
}
|
||||
return fnd;
|
||||
}
|
||||
|
||||
static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
|
||||
{
|
||||
int idx = 1;
|
||||
|
||||
mdesc_for_each_node_by_name(hp, mp, "socket") {
|
||||
u64 a;
|
||||
|
||||
mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
|
||||
u64 t = mdesc_arc_target(hp, a);
|
||||
const char *name;
|
||||
const u64 *id;
|
||||
|
||||
name = mdesc_node_name(hp, t);
|
||||
if (strcmp(name, "cpu"))
|
||||
continue;
|
||||
|
||||
id = mdesc_get_property(hp, t, "id", NULL);
|
||||
if (*id < num_possible_cpus())
|
||||
cpu_data(*id).sock_id = idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_sock_ids(struct mdesc_handle *hp)
|
||||
{
|
||||
u64 mp;
|
||||
|
||||
/* If machine description exposes sockets data use it.
|
||||
* Otherwise fallback to use shared L3 or L2 caches.
|
||||
*/
|
||||
mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
|
||||
if (mp != MDESC_NODE_NULL)
|
||||
return set_sock_ids_by_socket(hp, mp);
|
||||
|
||||
if (!set_sock_ids_by_cache(hp, 3))
|
||||
set_sock_ids_by_cache(hp, 2);
|
||||
}
|
||||
|
||||
static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
|
||||
{
|
||||
u64 a;
|
||||
@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
|
||||
continue;
|
||||
|
||||
mark_proc_ids(hp, mp, idx);
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)
|
||||
|
||||
set_core_ids(hp);
|
||||
set_proc_ids(hp);
|
||||
set_sock_ids(hp);
|
||||
|
||||
mdesc_release(hp);
|
||||
|
||||
|
@ -1002,6 +1002,38 @@ static int __init pcibios_init(void)
|
||||
subsys_initcall(pcibios_init);
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
|
||||
#define SLOT_NAME_SIZE 11 /* Max decimal digits + null in u32 */
|
||||
|
||||
static void pcie_bus_slot_names(struct pci_bus *pbus)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
struct pci_bus *bus;
|
||||
|
||||
list_for_each_entry(pdev, &pbus->devices, bus_list) {
|
||||
char name[SLOT_NAME_SIZE];
|
||||
struct pci_slot *pci_slot;
|
||||
const u32 *slot_num;
|
||||
int len;
|
||||
|
||||
slot_num = of_get_property(pdev->dev.of_node,
|
||||
"physical-slot#", &len);
|
||||
|
||||
if (slot_num == NULL || len != 4)
|
||||
continue;
|
||||
|
||||
snprintf(name, sizeof(name), "%u", slot_num[0]);
|
||||
pci_slot = pci_create_slot(pbus, slot_num[0], name, NULL);
|
||||
|
||||
if (IS_ERR(pci_slot))
|
||||
pr_err("PCI: pci_create_slot returned %ld.\n",
|
||||
PTR_ERR(pci_slot));
|
||||
}
|
||||
|
||||
list_for_each_entry(bus, &pbus->children, node)
|
||||
pcie_bus_slot_names(bus);
|
||||
}
|
||||
|
||||
static void pci_bus_slot_names(struct device_node *node, struct pci_bus *bus)
|
||||
{
|
||||
const struct pci_slot_names {
|
||||
@ -1053,18 +1085,29 @@ static int __init of_pci_slot_init(void)
|
||||
|
||||
while ((pbus = pci_find_next_bus(pbus)) != NULL) {
|
||||
struct device_node *node;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (pbus->self) {
|
||||
/* PCI->PCI bridge */
|
||||
node = pbus->self->dev.of_node;
|
||||
pdev = list_first_entry(&pbus->devices, struct pci_dev,
|
||||
bus_list);
|
||||
|
||||
if (pdev && pci_is_pcie(pdev)) {
|
||||
pcie_bus_slot_names(pbus);
|
||||
} else {
|
||||
struct pci_pbm_info *pbm = pbus->sysdata;
|
||||
|
||||
/* Host PCI controller */
|
||||
node = pbm->op->dev.of_node;
|
||||
if (pbus->self) {
|
||||
|
||||
/* PCI->PCI bridge */
|
||||
node = pbus->self->dev.of_node;
|
||||
|
||||
} else {
|
||||
struct pci_pbm_info *pbm = pbus->sysdata;
|
||||
|
||||
/* Host PCI controller */
|
||||
node = pbm->op->dev.of_node;
|
||||
}
|
||||
|
||||
pci_bus_slot_names(node, pbus);
|
||||
}
|
||||
|
||||
pci_bus_slot_names(node, pbus);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
|
||||
}
|
||||
}
|
||||
|
||||
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
|
||||
struct sun4v_2insn_patch_entry *end)
|
||||
{
|
||||
while (start < end) {
|
||||
unsigned long addr = start->addr;
|
||||
|
||||
*(unsigned int *) (addr + 0) = start->insns[0];
|
||||
wmb();
|
||||
__asm__ __volatile__("flush %0" : : "r" (addr + 0));
|
||||
|
||||
*(unsigned int *) (addr + 4) = start->insns[1];
|
||||
wmb();
|
||||
__asm__ __volatile__("flush %0" : : "r" (addr + 4));
|
||||
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init sun4v_patch(void)
|
||||
{
|
||||
extern void sun4v_hvapi_init(void);
|
||||
@ -267,6 +285,9 @@ static void __init sun4v_patch(void)
|
||||
|
||||
sun4v_patch_2insn_range(&__sun4v_2insn_patch,
|
||||
&__sun4v_2insn_patch_end);
|
||||
if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7)
|
||||
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
|
||||
&__sun_m7_2insn_patch_end);
|
||||
|
||||
sun4v_hvapi_init();
|
||||
}
|
||||
|
@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
|
||||
cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
|
||||
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };
|
||||
|
||||
cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
|
||||
[0 ... NR_CPUS-1] = CPU_MASK_NONE };
|
||||
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
|
||||
EXPORT_SYMBOL(cpu_core_map);
|
||||
EXPORT_SYMBOL(cpu_core_sib_map);
|
||||
|
||||
static cpumask_t smp_commenced_mask;
|
||||
|
||||
@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void)
|
||||
}
|
||||
}
|
||||
|
||||
for_each_present_cpu(i) {
|
||||
unsigned int j;
|
||||
|
||||
for_each_present_cpu(j) {
|
||||
if (cpu_data(i).sock_id == cpu_data(j).sock_id)
|
||||
cpumask_set_cpu(j, &cpu_core_sib_map[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_present_cpu(i) {
|
||||
unsigned int j;
|
||||
|
||||
|
@ -138,6 +138,11 @@ SECTIONS
|
||||
*(.pause_3insn_patch)
|
||||
__pause_3insn_patch_end = .;
|
||||
}
|
||||
.sun_m7_2insn_patch : {
|
||||
__sun_m7_2insn_patch = .;
|
||||
*(.sun_m7_2insn_patch)
|
||||
__sun_m7_2insn_patch_end = .;
|
||||
}
|
||||
PERCPU_SECTION(SMP_CACHE_BYTES)
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "init_64.h"
|
||||
|
||||
unsigned long kern_linear_pte_xor[4] __read_mostly;
|
||||
static unsigned long page_cache4v_flag;
|
||||
|
||||
/* A bitmap, two bits for every 256MB of physical memory. These two
|
||||
* bits determine what page size we use for kernel linear
|
||||
@ -1909,11 +1910,24 @@ static void __init sun4u_linear_pte_xor_finalize(void)
|
||||
|
||||
static void __init sun4v_linear_pte_xor_finalize(void)
|
||||
{
|
||||
unsigned long pagecv_flag;
|
||||
|
||||
/* Bit 9 of TTE is no longer CV bit on M7 processor and it instead
|
||||
* enables MCD error. Do not set bit 9 on M7 processor.
|
||||
*/
|
||||
switch (sun4v_chip_type) {
|
||||
case SUN4V_CHIP_SPARC_M7:
|
||||
pagecv_flag = 0x00;
|
||||
break;
|
||||
default:
|
||||
pagecv_flag = _PAGE_CV_4V;
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_DEBUG_PAGEALLOC
|
||||
if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) {
|
||||
kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
|
||||
PAGE_OFFSET;
|
||||
kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
|
||||
kern_linear_pte_xor[1] |= (_PAGE_CP_4V | pagecv_flag |
|
||||
_PAGE_P_4V | _PAGE_W_4V);
|
||||
} else {
|
||||
kern_linear_pte_xor[1] = kern_linear_pte_xor[0];
|
||||
@ -1922,7 +1936,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
|
||||
if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) {
|
||||
kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
|
||||
PAGE_OFFSET;
|
||||
kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V |
|
||||
kern_linear_pte_xor[2] |= (_PAGE_CP_4V | pagecv_flag |
|
||||
_PAGE_P_4V | _PAGE_W_4V);
|
||||
} else {
|
||||
kern_linear_pte_xor[2] = kern_linear_pte_xor[1];
|
||||
@ -1931,7 +1945,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
|
||||
if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) {
|
||||
kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^
|
||||
PAGE_OFFSET;
|
||||
kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V |
|
||||
kern_linear_pte_xor[3] |= (_PAGE_CP_4V | pagecv_flag |
|
||||
_PAGE_P_4V | _PAGE_W_4V);
|
||||
} else {
|
||||
kern_linear_pte_xor[3] = kern_linear_pte_xor[2];
|
||||
@ -1958,6 +1972,13 @@ static phys_addr_t __init available_memory(void)
|
||||
return available;
|
||||
}
|
||||
|
||||
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
|
||||
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
|
||||
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
|
||||
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
|
||||
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
|
||||
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
|
||||
|
||||
/* We need to exclude reserved regions. This exclusion will include
|
||||
* vmlinux and initrd. To be more precise the initrd size could be used to
|
||||
* compute a new lower limit because it is freed later during initialization.
|
||||
@ -2034,6 +2055,25 @@ void __init paging_init(void)
|
||||
memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
|
||||
#endif
|
||||
|
||||
/* TTE.cv bit on sparc v9 occupies the same position as TTE.mcde
|
||||
* bit on M7 processor. This is a conflicting usage of the same
|
||||
* bit. Enabling TTE.cv on M7 would turn on Memory Corruption
|
||||
* Detection error on all pages and this will lead to problems
|
||||
* later. Kernel does not run with MCD enabled and hence rest
|
||||
* of the required steps to fully configure memory corruption
|
||||
* detection are not taken. We need to ensure TTE.mcde is not
|
||||
* set on M7 processor. Compute the value of cacheability
|
||||
* flag for use later taking this into consideration.
|
||||
*/
|
||||
switch (sun4v_chip_type) {
|
||||
case SUN4V_CHIP_SPARC_M7:
|
||||
page_cache4v_flag = _PAGE_CP_4V;
|
||||
break;
|
||||
default:
|
||||
page_cache4v_flag = _PAGE_CACHE_4V;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tlb_type == hypervisor)
|
||||
sun4v_pgprot_init();
|
||||
else
|
||||
@ -2274,13 +2314,6 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _PAGE_CACHE_4U (_PAGE_CP_4U | _PAGE_CV_4U)
|
||||
#define _PAGE_CACHE_4V (_PAGE_CP_4V | _PAGE_CV_4V)
|
||||
#define __DIRTY_BITS_4U (_PAGE_MODIFIED_4U | _PAGE_WRITE_4U | _PAGE_W_4U)
|
||||
#define __DIRTY_BITS_4V (_PAGE_MODIFIED_4V | _PAGE_WRITE_4V | _PAGE_W_4V)
|
||||
#define __ACCESS_BITS_4U (_PAGE_ACCESSED_4U | _PAGE_READ_4U | _PAGE_R)
|
||||
#define __ACCESS_BITS_4V (_PAGE_ACCESSED_4V | _PAGE_READ_4V | _PAGE_R)
|
||||
|
||||
pgprot_t PAGE_KERNEL __read_mostly;
|
||||
EXPORT_SYMBOL(PAGE_KERNEL);
|
||||
|
||||
@ -2312,8 +2345,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
|
||||
_PAGE_P_4U | _PAGE_W_4U);
|
||||
if (tlb_type == hypervisor)
|
||||
pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
|
||||
_PAGE_CP_4V | _PAGE_CV_4V |
|
||||
_PAGE_P_4V | _PAGE_W_4V);
|
||||
page_cache4v_flag | _PAGE_P_4V | _PAGE_W_4V);
|
||||
|
||||
pte_base |= _PAGE_PMD_HUGE;
|
||||
|
||||
@ -2450,14 +2482,14 @@ static void __init sun4v_pgprot_init(void)
|
||||
int i;
|
||||
|
||||
PAGE_KERNEL = __pgprot (_PAGE_PRESENT_4V | _PAGE_VALID |
|
||||
_PAGE_CACHE_4V | _PAGE_P_4V |
|
||||
page_cache4v_flag | _PAGE_P_4V |
|
||||
__ACCESS_BITS_4V | __DIRTY_BITS_4V |
|
||||
_PAGE_EXEC_4V);
|
||||
PAGE_KERNEL_LOCKED = PAGE_KERNEL;
|
||||
|
||||
_PAGE_IE = _PAGE_IE_4V;
|
||||
_PAGE_E = _PAGE_E_4V;
|
||||
_PAGE_CACHE = _PAGE_CACHE_4V;
|
||||
_PAGE_CACHE = page_cache4v_flag;
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
kern_linear_pte_xor[0] = _PAGE_VALID ^ PAGE_OFFSET;
|
||||
@ -2465,8 +2497,8 @@ static void __init sun4v_pgprot_init(void)
|
||||
kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
|
||||
PAGE_OFFSET;
|
||||
#endif
|
||||
kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V |
|
||||
_PAGE_P_4V | _PAGE_W_4V);
|
||||
kern_linear_pte_xor[0] |= (page_cache4v_flag | _PAGE_P_4V |
|
||||
_PAGE_W_4V);
|
||||
|
||||
for (i = 1; i < 4; i++)
|
||||
kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
|
||||
@ -2479,12 +2511,12 @@ static void __init sun4v_pgprot_init(void)
|
||||
_PAGE_SZ4MB_4V | _PAGE_SZ512K_4V |
|
||||
_PAGE_SZ64K_4V | _PAGE_SZ8K_4V);
|
||||
|
||||
page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | _PAGE_CACHE_4V;
|
||||
page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V |
|
||||
page_none = _PAGE_PRESENT_4V | _PAGE_ACCESSED_4V | page_cache4v_flag;
|
||||
page_shared = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
|
||||
__ACCESS_BITS_4V | _PAGE_WRITE_4V | _PAGE_EXEC_4V);
|
||||
page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V |
|
||||
page_copy = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
|
||||
__ACCESS_BITS_4V | _PAGE_EXEC_4V);
|
||||
page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | _PAGE_CACHE_4V |
|
||||
page_readonly = (_PAGE_VALID | _PAGE_PRESENT_4V | page_cache4v_flag |
|
||||
__ACCESS_BITS_4V | _PAGE_EXEC_4V);
|
||||
|
||||
page_exec_bit = _PAGE_EXEC_4V;
|
||||
@ -2542,7 +2574,7 @@ static unsigned long kern_large_tte(unsigned long paddr)
|
||||
_PAGE_EXEC_4U | _PAGE_L_4U | _PAGE_W_4U);
|
||||
if (tlb_type == hypervisor)
|
||||
val = (_PAGE_VALID | _PAGE_SZ4MB_4V |
|
||||
_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V |
|
||||
page_cache4v_flag | _PAGE_P_4V |
|
||||
_PAGE_EXEC_4V | _PAGE_W_4V);
|
||||
|
||||
return val | paddr;
|
||||
|
@ -140,6 +140,7 @@
|
||||
#define MSR_CORE_C3_RESIDENCY 0x000003fc
|
||||
#define MSR_CORE_C6_RESIDENCY 0x000003fd
|
||||
#define MSR_CORE_C7_RESIDENCY 0x000003fe
|
||||
#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
|
||||
#define MSR_PKG_C2_RESIDENCY 0x0000060d
|
||||
#define MSR_PKG_C8_RESIDENCY 0x00000630
|
||||
#define MSR_PKG_C9_RESIDENCY 0x00000631
|
||||
|
@ -708,6 +708,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int i, ret = 0;
|
||||
char *tmp;
|
||||
|
||||
for (i = 0; i < mca_cfg.banks; i++) {
|
||||
m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
|
||||
@ -716,9 +717,11 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
|
||||
if (quirk_no_way_out)
|
||||
quirk_no_way_out(i, m, regs);
|
||||
}
|
||||
if (mce_severity(m, mca_cfg.tolerant, msg, true) >=
|
||||
MCE_PANIC_SEVERITY)
|
||||
|
||||
if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) {
|
||||
*msg = tmp;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -173,6 +173,21 @@ static void init_thread_xstate(void)
|
||||
xstate_size = sizeof(struct i387_fxsave_struct);
|
||||
else
|
||||
xstate_size = sizeof(struct i387_fsave_struct);
|
||||
|
||||
/*
|
||||
* Quirk: we don't yet handle the XSAVES* instructions
|
||||
* correctly, as we don't correctly convert between
|
||||
* standard and compacted format when interfacing
|
||||
* with user-space - so disable it for now.
|
||||
*
|
||||
* The difference is small: with recent CPUs the
|
||||
* compacted format is only marginally smaller than
|
||||
* the standard FPU state format.
|
||||
*
|
||||
* ( This is easy to backport while we are fixing
|
||||
* XSAVES* support. )
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1068,7 +1068,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
}
|
||||
ctx.cleanup_addr = proglen;
|
||||
|
||||
for (pass = 0; pass < 10; pass++) {
|
||||
/* JITed image shrinks with every pass and the loop iterates
|
||||
* until the image stops shrinking. Very large bpf programs
|
||||
* may converge on the last pass. In such case do one more
|
||||
* pass to emit the final image
|
||||
*/
|
||||
for (pass = 0; pass < 10 || image; pass++) {
|
||||
proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
|
||||
if (proglen <= 0) {
|
||||
image = NULL;
|
||||
|
@ -482,9 +482,16 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||
|
||||
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
|
||||
{
|
||||
struct pci_sysdata *sd = bridge->bus->sysdata;
|
||||
|
||||
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
||||
/*
|
||||
* We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
|
||||
* here, pci_create_root_bus() has been called by someone else and
|
||||
* sysdata is likely to be different from what we expect. Let it go in
|
||||
* that case.
|
||||
*/
|
||||
if (!bridge->dev.parent) {
|
||||
struct pci_sysdata *sd = bridge->bus->sysdata;
|
||||
ACPI_COMPANION_SET(&bridge->dev, sd->companion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -185,4 +185,17 @@ static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline void *dma_alloc_attrs(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void dma_free_attrs(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* _XTENSA_DMA_MAPPING_H */
|
||||
|
@ -1512,15 +1512,6 @@ config CRYPTO_USER_API_RNG
|
||||
This option enables the user-spaces interface for random
|
||||
number generator algorithms.
|
||||
|
||||
config CRYPTO_USER_API_AEAD
|
||||
tristate "User-space interface for AEAD cipher algorithms"
|
||||
depends on NET
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_USER_API
|
||||
help
|
||||
This option enables the user-spaces interface for AEAD
|
||||
cipher algorithms.
|
||||
|
||||
config CRYPTO_HASH_INFO
|
||||
bool
|
||||
|
||||
|
@ -453,7 +453,7 @@ void __iomem *mips_cdmm_early_probe(unsigned int dev_type)
|
||||
|
||||
/* Look for a specific device type */
|
||||
for (; drb < bus->drbs; drb += size + 1) {
|
||||
acsr = readl(cdmm + drb * CDMM_DRB_SIZE);
|
||||
acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE);
|
||||
type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
|
||||
if (type == dev_type)
|
||||
return cdmm + drb * CDMM_DRB_SIZE;
|
||||
@ -500,7 +500,7 @@ static void mips_cdmm_bus_discover(struct mips_cdmm_bus *bus)
|
||||
bus->discovered = true;
|
||||
pr_info("cdmm%u discovery (%u blocks)\n", cpu, bus->drbs);
|
||||
for (; drb < bus->drbs; drb += size + 1) {
|
||||
acsr = readl(cdmm + drb * CDMM_DRB_SIZE);
|
||||
acsr = __raw_readl(cdmm + drb * CDMM_DRB_SIZE);
|
||||
type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
|
||||
size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT;
|
||||
rev = (acsr & CDMM_ACSR_DEVREV) >> CDMM_ACSR_DEVREV_SHIFT;
|
||||
|
@ -117,7 +117,7 @@ static int kempld_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
= container_of(chip, struct kempld_gpio_data, chip);
|
||||
struct kempld_device_data *pld = gpio->pld;
|
||||
|
||||
return kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
|
||||
return !kempld_gpio_get_bit(pld, KEMPLD_GPIO_DIR_NUM(offset), offset);
|
||||
}
|
||||
|
||||
static int kempld_gpio_pincount(struct kempld_device_data *pld)
|
||||
|
@ -53,6 +53,11 @@ static DEFINE_MUTEX(gpio_lookup_lock);
|
||||
static LIST_HEAD(gpio_lookup_list);
|
||||
LIST_HEAD(gpio_chips);
|
||||
|
||||
|
||||
static void gpiochip_free_hogs(struct gpio_chip *chip);
|
||||
static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
|
||||
|
||||
|
||||
static inline void desc_set_label(struct gpio_desc *d, const char *label)
|
||||
{
|
||||
d->label = label;
|
||||
@ -297,6 +302,7 @@ int gpiochip_add(struct gpio_chip *chip)
|
||||
|
||||
err_remove_chip:
|
||||
acpi_gpiochip_remove(chip);
|
||||
gpiochip_free_hogs(chip);
|
||||
of_gpiochip_remove(chip);
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
list_del(&chip->list);
|
||||
@ -313,10 +319,6 @@ err_free_descs:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpiochip_add);
|
||||
|
||||
/* Forward-declaration */
|
||||
static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip);
|
||||
static void gpiochip_free_hogs(struct gpio_chip *chip);
|
||||
|
||||
/**
|
||||
* gpiochip_remove() - unregister a gpio_chip
|
||||
* @chip: the chip to unregister
|
||||
|
@ -465,6 +465,9 @@ int drm_plane_helper_commit(struct drm_plane *plane,
|
||||
if (!crtc[i])
|
||||
continue;
|
||||
|
||||
if (crtc[i]->cursor == plane)
|
||||
continue;
|
||||
|
||||
/* There's no other way to figure out whether the crtc is running. */
|
||||
ret = drm_crtc_vblank_get(crtc[i]);
|
||||
if (ret == 0) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#define FERMI_TWOD_A 0x0000902d
|
||||
|
||||
#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x0000903d
|
||||
#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x00009039
|
||||
|
||||
#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040
|
||||
#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140
|
||||
|
@ -329,7 +329,6 @@ gm204_gr_init(struct nvkm_object *object)
|
||||
nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
|
||||
|
||||
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
||||
printk(KERN_ERR "ppc %d %d\n", gpc, priv->ppc_nr[gpc]);
|
||||
for (ppc = 0; ppc < priv->ppc_nr[gpc]; ppc++)
|
||||
nv_wr32(priv, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
|
||||
nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
|
||||
|
@ -90,12 +90,14 @@ gf100_devinit_disable(struct nvkm_devinit *devinit)
|
||||
return disable;
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
gf100_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
||||
struct nvkm_oclass *oclass, void *data, u32 size,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
struct nvkm_devinit_impl *impl = (void *)oclass;
|
||||
struct nv50_devinit_priv *priv;
|
||||
u64 disable;
|
||||
int ret;
|
||||
|
||||
ret = nvkm_devinit_create(parent, engine, oclass, &priv);
|
||||
@ -103,7 +105,8 @@ gf100_devinit_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (nv_rd32(priv, 0x022500) & 0x00000001)
|
||||
disable = impl->disable(&priv->base);
|
||||
if (disable & (1ULL << NVDEV_ENGINE_DISP))
|
||||
priv->base.post = true;
|
||||
|
||||
return 0;
|
||||
|
@ -48,7 +48,7 @@ struct nvkm_oclass *
|
||||
gm107_devinit_oclass = &(struct nvkm_devinit_impl) {
|
||||
.base.handle = NV_SUBDEV(DEVINIT, 0x07),
|
||||
.base.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.ctor = nv50_devinit_ctor,
|
||||
.ctor = gf100_devinit_ctor,
|
||||
.dtor = _nvkm_devinit_dtor,
|
||||
.init = nv50_devinit_init,
|
||||
.fini = _nvkm_devinit_fini,
|
||||
|
@ -161,7 +161,7 @@ struct nvkm_oclass *
|
||||
gm204_devinit_oclass = &(struct nvkm_devinit_impl) {
|
||||
.base.handle = NV_SUBDEV(DEVINIT, 0x07),
|
||||
.base.ofuncs = &(struct nvkm_ofuncs) {
|
||||
.ctor = nv50_devinit_ctor,
|
||||
.ctor = gf100_devinit_ctor,
|
||||
.dtor = _nvkm_devinit_dtor,
|
||||
.init = nv50_devinit_init,
|
||||
.fini = _nvkm_devinit_fini,
|
||||
|
@ -15,6 +15,9 @@ int nv50_devinit_pll_set(struct nvkm_devinit *, u32, u32);
|
||||
|
||||
int gt215_devinit_pll_set(struct nvkm_devinit *, u32, u32);
|
||||
|
||||
int gf100_devinit_ctor(struct nvkm_object *, struct nvkm_object *,
|
||||
struct nvkm_oclass *, void *, u32,
|
||||
struct nvkm_object **);
|
||||
int gf100_devinit_pll_set(struct nvkm_devinit *, u32, u32);
|
||||
|
||||
u64 gm107_devinit_disable(struct nvkm_devinit *);
|
||||
|
@ -1798,7 +1798,9 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
|
||||
if ((crtc->mode.clock == test_crtc->mode.clock) &&
|
||||
(adjusted_clock == test_adjusted_clock) &&
|
||||
(radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
|
||||
(test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
|
||||
(test_radeon_crtc->pll_id != ATOM_PPLL_INVALID) &&
|
||||
(drm_detect_monitor_audio(radeon_connector_edid(test_radeon_crtc->connector)) ==
|
||||
drm_detect_monitor_audio(radeon_connector_edid(radeon_crtc->connector))))
|
||||
return test_radeon_crtc->pll_id;
|
||||
}
|
||||
}
|
||||
|
@ -5822,7 +5822,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE(4));
|
||||
/* setup context0 */
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
|
||||
(u32)(rdev->dummy_page.addr >> 12));
|
||||
|
@ -2485,7 +2485,7 @@ static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
|
||||
WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
|
||||
|
@ -400,7 +400,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
|
||||
if (enable) {
|
||||
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
||||
|
||||
if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
if (connector && drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset,
|
||||
HDMI_AVI_INFO_SEND | /* enable AVI info frames */
|
||||
HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */
|
||||
@ -438,7 +438,8 @@ void evergreen_dp_enable(struct drm_encoder *encoder, bool enable)
|
||||
if (!dig || !dig->afmt)
|
||||
return;
|
||||
|
||||
if (enable && drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
if (enable && connector &&
|
||||
drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct radeon_connector_atom_dig *dig_connector;
|
||||
|
@ -1282,7 +1282,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE(6));
|
||||
/* setup context0 */
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
|
||||
(u32)(rdev->dummy_page.addr >> 12));
|
||||
|
@ -1112,7 +1112,7 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
|
||||
WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
|
||||
|
@ -460,9 +460,6 @@ void radeon_audio_detect(struct drm_connector *connector,
|
||||
if (!connector || !connector->encoder)
|
||||
return;
|
||||
|
||||
if (!radeon_encoder_is_digital(connector->encoder))
|
||||
return;
|
||||
|
||||
rdev = connector->encoder->dev->dev_private;
|
||||
|
||||
if (!radeon_audio_chipset_supported(rdev))
|
||||
@ -471,26 +468,26 @@ void radeon_audio_detect(struct drm_connector *connector,
|
||||
radeon_encoder = to_radeon_encoder(connector->encoder);
|
||||
dig = radeon_encoder->enc_priv;
|
||||
|
||||
if (!dig->afmt)
|
||||
return;
|
||||
|
||||
if (status == connector_status_connected) {
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
struct radeon_connector *radeon_connector;
|
||||
int sink_type;
|
||||
|
||||
if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
radeon_encoder->audio = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
radeon_connector = to_radeon_connector(connector);
|
||||
sink_type = radeon_dp_getsinktype(radeon_connector);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
|
||||
radeon_dp_getsinktype(radeon_connector) ==
|
||||
CONNECTOR_OBJECT_ID_DISPLAYPORT)
|
||||
sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
|
||||
radeon_encoder->audio = rdev->audio.dp_funcs;
|
||||
else
|
||||
radeon_encoder->audio = rdev->audio.hdmi_funcs;
|
||||
|
||||
dig->afmt->pin = radeon_audio_get_pin(connector->encoder);
|
||||
if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
|
||||
} else {
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0);
|
||||
dig->afmt->pin = NULL;
|
||||
}
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
|
||||
} else {
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0);
|
||||
dig->afmt->pin = NULL;
|
||||
|
@ -1379,10 +1379,8 @@ out:
|
||||
/* updated in get modes as well since we need to know if it's analog or digital */
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
|
||||
if (radeon_audio != 0) {
|
||||
radeon_connector_get_edid(connector);
|
||||
if (radeon_audio != 0)
|
||||
radeon_audio_detect(connector, ret);
|
||||
}
|
||||
|
||||
exit:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
@ -1719,10 +1717,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
||||
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
|
||||
if (radeon_audio != 0) {
|
||||
radeon_connector_get_edid(connector);
|
||||
if (radeon_audio != 0)
|
||||
radeon_audio_detect(connector, ret);
|
||||
}
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
|
@ -921,7 +921,7 @@ static int rv770_pcie_gart_enable(struct radeon_device *rdev)
|
||||
WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
|
||||
WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
|
||||
|
@ -4303,7 +4303,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE(4));
|
||||
/* setup context0 */
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
|
||||
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
|
||||
WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
|
||||
(u32)(rdev->dummy_page.addr >> 12));
|
||||
|
@ -1,4 +1,4 @@
|
||||
ccflags-y := -Iinclude/drm
|
||||
vgem-y := vgem_drv.o vgem_dma_buf.o
|
||||
vgem-y := vgem_drv.o
|
||||
|
||||
obj-$(CONFIG_DRM_VGEM) += vgem.o
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* Copyright © 2014 The Chromium OS Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Ben Widawsky <ben@bwidawsk.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/dma-buf.h>
|
||||
#include "vgem_drv.h"
|
||||
|
||||
struct sg_table *vgem_gem_prime_get_sg_table(struct drm_gem_object *gobj)
|
||||
{
|
||||
struct drm_vgem_gem_object *obj = to_vgem_bo(gobj);
|
||||
BUG_ON(obj->pages == NULL);
|
||||
|
||||
return drm_prime_pages_to_sg(obj->pages, obj->base.size / PAGE_SIZE);
|
||||
}
|
||||
|
||||
int vgem_gem_prime_pin(struct drm_gem_object *gobj)
|
||||
{
|
||||
struct drm_vgem_gem_object *obj = to_vgem_bo(gobj);
|
||||
return vgem_gem_get_pages(obj);
|
||||
}
|
||||
|
||||
void vgem_gem_prime_unpin(struct drm_gem_object *gobj)
|
||||
{
|
||||
struct drm_vgem_gem_object *obj = to_vgem_bo(gobj);
|
||||
vgem_gem_put_pages(obj);
|
||||
}
|
||||
|
||||
void *vgem_gem_prime_vmap(struct drm_gem_object *gobj)
|
||||
{
|
||||
struct drm_vgem_gem_object *obj = to_vgem_bo(gobj);
|
||||
BUG_ON(obj->pages == NULL);
|
||||
|
||||
return vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL);
|
||||
}
|
||||
|
||||
void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
|
||||
{
|
||||
vunmap(vaddr);
|
||||
}
|
||||
|
||||
struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev,
|
||||
struct dma_buf *dma_buf)
|
||||
{
|
||||
struct drm_vgem_gem_object *obj = NULL;
|
||||
int ret;
|
||||
|
||||
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
|
||||
if (obj == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = drm_gem_object_init(dev, &obj->base, dma_buf->size);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
get_dma_buf(dma_buf);
|
||||
|
||||
obj->base.dma_buf = dma_buf;
|
||||
obj->use_dma_buf = true;
|
||||
|
||||
return &obj->base;
|
||||
|
||||
fail_free:
|
||||
kfree(obj);
|
||||
fail:
|
||||
return ERR_PTR(ret);
|
||||
}
|
@ -302,22 +302,13 @@ static const struct file_operations vgem_driver_fops = {
|
||||
};
|
||||
|
||||
static struct drm_driver vgem_driver = {
|
||||
.driver_features = DRIVER_GEM | DRIVER_PRIME,
|
||||
.driver_features = DRIVER_GEM,
|
||||
.gem_free_object = vgem_gem_free_object,
|
||||
.gem_vm_ops = &vgem_gem_vm_ops,
|
||||
.ioctls = vgem_ioctls,
|
||||
.fops = &vgem_driver_fops,
|
||||
.dumb_create = vgem_gem_dumb_create,
|
||||
.dumb_map_offset = vgem_gem_dumb_map,
|
||||
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
||||
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
||||
.gem_prime_export = drm_gem_prime_export,
|
||||
.gem_prime_import = vgem_gem_prime_import,
|
||||
.gem_prime_pin = vgem_gem_prime_pin,
|
||||
.gem_prime_unpin = vgem_gem_prime_unpin,
|
||||
.gem_prime_get_sg_table = vgem_gem_prime_get_sg_table,
|
||||
.gem_prime_vmap = vgem_gem_prime_vmap,
|
||||
.gem_prime_vunmap = vgem_gem_prime_vunmap,
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
.date = DRIVER_DATE,
|
||||
|
@ -43,15 +43,4 @@ struct drm_vgem_gem_object {
|
||||
extern void vgem_gem_put_pages(struct drm_vgem_gem_object *obj);
|
||||
extern int vgem_gem_get_pages(struct drm_vgem_gem_object *obj);
|
||||
|
||||
/* vgem_dma_buf.c */
|
||||
extern struct sg_table *vgem_gem_prime_get_sg_table(
|
||||
struct drm_gem_object *gobj);
|
||||
extern int vgem_gem_prime_pin(struct drm_gem_object *gobj);
|
||||
extern void vgem_gem_prime_unpin(struct drm_gem_object *gobj);
|
||||
extern void *vgem_gem_prime_vmap(struct drm_gem_object *gobj);
|
||||
extern void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
|
||||
extern struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev,
|
||||
struct dma_buf *dma_buf);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -439,6 +439,7 @@ nct6683_create_attr_group(struct device *dev, struct sensor_template_group *tg,
|
||||
(*t)->dev_attr.attr.name, tg->base + i);
|
||||
if ((*t)->s2) {
|
||||
a2 = &su->u.a2;
|
||||
sysfs_attr_init(&a2->dev_attr.attr);
|
||||
a2->dev_attr.attr.name = su->name;
|
||||
a2->nr = (*t)->u.s.nr + i;
|
||||
a2->index = (*t)->u.s.index;
|
||||
@ -449,6 +450,7 @@ nct6683_create_attr_group(struct device *dev, struct sensor_template_group *tg,
|
||||
*attrs = &a2->dev_attr.attr;
|
||||
} else {
|
||||
a = &su->u.a1;
|
||||
sysfs_attr_init(&a->dev_attr.attr);
|
||||
a->dev_attr.attr.name = su->name;
|
||||
a->index = (*t)->u.index + i;
|
||||
a->dev_attr.attr.mode =
|
||||
|
@ -995,6 +995,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
|
||||
(*t)->dev_attr.attr.name, tg->base + i);
|
||||
if ((*t)->s2) {
|
||||
a2 = &su->u.a2;
|
||||
sysfs_attr_init(&a2->dev_attr.attr);
|
||||
a2->dev_attr.attr.name = su->name;
|
||||
a2->nr = (*t)->u.s.nr + i;
|
||||
a2->index = (*t)->u.s.index;
|
||||
@ -1005,6 +1006,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
|
||||
*attrs = &a2->dev_attr.attr;
|
||||
} else {
|
||||
a = &su->u.a1;
|
||||
sysfs_attr_init(&a->dev_attr.attr);
|
||||
a->dev_attr.attr.name = su->name;
|
||||
a->index = (*t)->u.index + i;
|
||||
a->dev_attr.attr.mode =
|
||||
|
@ -239,8 +239,10 @@ static struct ntc_thermistor_platform_data *
|
||||
ntc_thermistor_parse_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_channel *chan;
|
||||
enum iio_chan_type type;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct ntc_thermistor_platform_data *pdata;
|
||||
int ret;
|
||||
|
||||
if (!np)
|
||||
return NULL;
|
||||
@ -253,6 +255,13 @@ ntc_thermistor_parse_dt(struct platform_device *pdev)
|
||||
if (IS_ERR(chan))
|
||||
return ERR_CAST(chan);
|
||||
|
||||
ret = iio_get_channel_type(chan, &type);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (type != IIO_VOLTAGE)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (of_property_read_u32(np, "pullup-uv", &pdata->pullup_uv))
|
||||
return ERR_PTR(-ENODEV);
|
||||
if (of_property_read_u32(np, "pullup-ohm", &pdata->pullup_ohm))
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
/* Addresses to scan */
|
||||
static const unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4c, 0x4d,
|
||||
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d,
|
||||
0x4e, 0x4f, I2C_CLIENT_END };
|
||||
|
||||
enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 };
|
||||
|
@ -547,11 +547,11 @@ isert_create_pi_ctx(struct fast_reg_descriptor *desc,
|
||||
return 0;
|
||||
|
||||
err_prot_mr:
|
||||
ib_dereg_mr(desc->pi_ctx->prot_mr);
|
||||
ib_dereg_mr(pi_ctx->prot_mr);
|
||||
err_prot_frpl:
|
||||
ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl);
|
||||
ib_free_fast_reg_page_list(pi_ctx->prot_frpl);
|
||||
err_pi_ctx:
|
||||
kfree(desc->pi_ctx);
|
||||
kfree(pi_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -828,7 +828,14 @@ static int its_alloc_tables(struct its_node *its)
|
||||
u64 typer = readq_relaxed(its->base + GITS_TYPER);
|
||||
u32 ids = GITS_TYPER_DEVBITS(typer);
|
||||
|
||||
order = get_order((1UL << ids) * entry_size);
|
||||
/*
|
||||
* 'order' was initialized earlier to the default page
|
||||
* granule of the the ITS. We can't have an allocation
|
||||
* smaller than that. If the requested allocation
|
||||
* is smaller, round up to the default page granule.
|
||||
*/
|
||||
order = max(get_order((1UL << ids) * entry_size),
|
||||
order);
|
||||
if (order >= MAX_ORDER) {
|
||||
order = MAX_ORDER - 1;
|
||||
pr_warn("%s: Device Table too large, reduce its page order to %u\n",
|
||||
|
@ -173,7 +173,7 @@ static void unmap_switcher(void)
|
||||
bool lguest_address_ok(const struct lguest *lg,
|
||||
unsigned long addr, unsigned long len)
|
||||
{
|
||||
return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
|
||||
return addr+len <= lg->pfn_limit * PAGE_SIZE && (addr+len >= addr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -429,9 +429,11 @@ static int __multipath_map(struct dm_target *ti, struct request *clone,
|
||||
/* blk-mq request-based interface */
|
||||
*__clone = blk_get_request(bdev_get_queue(bdev),
|
||||
rq_data_dir(rq), GFP_ATOMIC);
|
||||
if (IS_ERR(*__clone))
|
||||
if (IS_ERR(*__clone)) {
|
||||
/* ENOMEM, requeue */
|
||||
clear_mapinfo(m, map_context);
|
||||
return r;
|
||||
}
|
||||
(*__clone)->bio = (*__clone)->biotail = NULL;
|
||||
(*__clone)->rq_disk = bdev->bd_disk;
|
||||
(*__clone)->cmd_flags |= REQ_FAILFAST_TRANSPORT;
|
||||
|
@ -820,6 +820,12 @@ void dm_consume_args(struct dm_arg_set *as, unsigned num_args)
|
||||
}
|
||||
EXPORT_SYMBOL(dm_consume_args);
|
||||
|
||||
static bool __table_type_request_based(unsigned table_type)
|
||||
{
|
||||
return (table_type == DM_TYPE_REQUEST_BASED ||
|
||||
table_type == DM_TYPE_MQ_REQUEST_BASED);
|
||||
}
|
||||
|
||||
static int dm_table_set_type(struct dm_table *t)
|
||||
{
|
||||
unsigned i;
|
||||
@ -852,8 +858,7 @@ static int dm_table_set_type(struct dm_table *t)
|
||||
* Determine the type from the live device.
|
||||
* Default to bio-based if device is new.
|
||||
*/
|
||||
if (live_md_type == DM_TYPE_REQUEST_BASED ||
|
||||
live_md_type == DM_TYPE_MQ_REQUEST_BASED)
|
||||
if (__table_type_request_based(live_md_type))
|
||||
request_based = 1;
|
||||
else
|
||||
bio_based = 1;
|
||||
@ -903,7 +908,7 @@ static int dm_table_set_type(struct dm_table *t)
|
||||
}
|
||||
t->type = DM_TYPE_MQ_REQUEST_BASED;
|
||||
|
||||
} else if (hybrid && list_empty(devices) && live_md_type != DM_TYPE_NONE) {
|
||||
} else if (list_empty(devices) && __table_type_request_based(live_md_type)) {
|
||||
/* inherit live MD type */
|
||||
t->type = live_md_type;
|
||||
|
||||
@ -925,10 +930,7 @@ struct target_type *dm_table_get_immutable_target_type(struct dm_table *t)
|
||||
|
||||
bool dm_table_request_based(struct dm_table *t)
|
||||
{
|
||||
unsigned table_type = dm_table_get_type(t);
|
||||
|
||||
return (table_type == DM_TYPE_REQUEST_BASED ||
|
||||
table_type == DM_TYPE_MQ_REQUEST_BASED);
|
||||
return __table_type_request_based(dm_table_get_type(t));
|
||||
}
|
||||
|
||||
bool dm_table_mq_request_based(struct dm_table *t)
|
||||
|
@ -1082,13 +1082,11 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
|
||||
dm_put(md);
|
||||
}
|
||||
|
||||
static void free_rq_clone(struct request *clone, bool must_be_mapped)
|
||||
static void free_rq_clone(struct request *clone)
|
||||
{
|
||||
struct dm_rq_target_io *tio = clone->end_io_data;
|
||||
struct mapped_device *md = tio->md;
|
||||
|
||||
WARN_ON_ONCE(must_be_mapped && !clone->q);
|
||||
|
||||
blk_rq_unprep_clone(clone);
|
||||
|
||||
if (md->type == DM_TYPE_MQ_REQUEST_BASED)
|
||||
@ -1132,7 +1130,7 @@ static void dm_end_request(struct request *clone, int error)
|
||||
rq->sense_len = clone->sense_len;
|
||||
}
|
||||
|
||||
free_rq_clone(clone, true);
|
||||
free_rq_clone(clone);
|
||||
if (!rq->q->mq_ops)
|
||||
blk_end_request_all(rq, error);
|
||||
else
|
||||
@ -1151,7 +1149,7 @@ static void dm_unprep_request(struct request *rq)
|
||||
}
|
||||
|
||||
if (clone)
|
||||
free_rq_clone(clone, false);
|
||||
free_rq_clone(clone);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1164,6 +1162,7 @@ static void old_requeue_request(struct request *rq)
|
||||
|
||||
spin_lock_irqsave(q->queue_lock, flags);
|
||||
blk_requeue_request(q, rq);
|
||||
blk_run_queue_async(q);
|
||||
spin_unlock_irqrestore(q->queue_lock, flags);
|
||||
}
|
||||
|
||||
@ -1724,8 +1723,7 @@ static int dm_merge_bvec(struct request_queue *q,
|
||||
struct mapped_device *md = q->queuedata;
|
||||
struct dm_table *map = dm_get_live_table_fast(md);
|
||||
struct dm_target *ti;
|
||||
sector_t max_sectors;
|
||||
int max_size = 0;
|
||||
sector_t max_sectors, max_size = 0;
|
||||
|
||||
if (unlikely(!map))
|
||||
goto out;
|
||||
@ -1740,8 +1738,16 @@ static int dm_merge_bvec(struct request_queue *q,
|
||||
max_sectors = min(max_io_len(bvm->bi_sector, ti),
|
||||
(sector_t) queue_max_sectors(q));
|
||||
max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size;
|
||||
if (unlikely(max_size < 0)) /* this shouldn't _ever_ happen */
|
||||
max_size = 0;
|
||||
|
||||
/*
|
||||
* FIXME: this stop-gap fix _must_ be cleaned up (by passing a sector_t
|
||||
* to the targets' merge function since it holds sectors not bytes).
|
||||
* Just doing this as an interim fix for stable@ because the more
|
||||
* comprehensive cleanup of switching to sector_t will impact every
|
||||
* DM target that implements a ->merge hook.
|
||||
*/
|
||||
if (max_size > INT_MAX)
|
||||
max_size = INT_MAX;
|
||||
|
||||
/*
|
||||
* merge_bvec_fn() returns number of bytes
|
||||
@ -1749,7 +1755,7 @@ static int dm_merge_bvec(struct request_queue *q,
|
||||
* max is precomputed maximal io size
|
||||
*/
|
||||
if (max_size && ti->type->merge)
|
||||
max_size = ti->type->merge(ti, bvm, biovec, max_size);
|
||||
max_size = ti->type->merge(ti, bvm, biovec, (int) max_size);
|
||||
/*
|
||||
* If the target doesn't support merge method and some of the devices
|
||||
* provided their merge_bvec method (we know this by looking for the
|
||||
@ -1971,8 +1977,8 @@ static int map_request(struct dm_rq_target_io *tio, struct request *rq,
|
||||
dm_kill_unmapped_request(rq, r);
|
||||
return r;
|
||||
}
|
||||
if (IS_ERR(clone))
|
||||
return DM_MAPIO_REQUEUE;
|
||||
if (r != DM_MAPIO_REMAPPED)
|
||||
return r;
|
||||
if (setup_clone(clone, rq, tio, GFP_ATOMIC)) {
|
||||
/* -ENOMEM */
|
||||
ti->type->release_clone_rq(clone);
|
||||
@ -2753,13 +2759,15 @@ static int dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
|
||||
if (dm_table_get_type(map) == DM_TYPE_REQUEST_BASED) {
|
||||
/* clone request is allocated at the end of the pdu */
|
||||
tio->clone = (void *)blk_mq_rq_to_pdu(rq) + sizeof(struct dm_rq_target_io);
|
||||
if (!clone_rq(rq, md, tio, GFP_ATOMIC))
|
||||
return BLK_MQ_RQ_QUEUE_BUSY;
|
||||
(void) clone_rq(rq, md, tio, GFP_ATOMIC);
|
||||
queue_kthread_work(&md->kworker, &tio->work);
|
||||
} else {
|
||||
/* Direct call is fine since .queue_rq allows allocations */
|
||||
if (map_request(tio, rq, md) == DM_MAPIO_REQUEUE)
|
||||
dm_requeue_unmapped_original_request(md, rq);
|
||||
if (map_request(tio, rq, md) == DM_MAPIO_REQUEUE) {
|
||||
/* Undo dm_start_request() before requeuing */
|
||||
rq_completed(md, rq_data_dir(rq), false);
|
||||
return BLK_MQ_RQ_QUEUE_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
return BLK_MQ_RQ_QUEUE_OK;
|
||||
|
@ -4211,12 +4211,12 @@ action_store(struct mddev *mddev, const char *page, size_t len)
|
||||
if (!mddev->pers || !mddev->pers->sync_request)
|
||||
return -EINVAL;
|
||||
|
||||
if (cmd_match(page, "frozen"))
|
||||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
else
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
|
||||
if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
|
||||
if (cmd_match(page, "frozen"))
|
||||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
else
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
flush_workqueue(md_misc_wq);
|
||||
if (mddev->sync_thread) {
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
@ -4229,16 +4229,17 @@ action_store(struct mddev *mddev, const char *page, size_t len)
|
||||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
|
||||
return -EBUSY;
|
||||
else if (cmd_match(page, "resync"))
|
||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
else if (cmd_match(page, "recover")) {
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||
} else if (cmd_match(page, "reshape")) {
|
||||
int err;
|
||||
if (mddev->pers->start_reshape == NULL)
|
||||
return -EINVAL;
|
||||
err = mddev_lock(mddev);
|
||||
if (!err) {
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
err = mddev->pers->start_reshape(mddev);
|
||||
mddev_unlock(mddev);
|
||||
}
|
||||
@ -4250,6 +4251,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
|
||||
set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
|
||||
else if (!cmd_match(page, "repair"))
|
||||
return -EINVAL;
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
|
||||
}
|
||||
|
@ -749,6 +749,7 @@ static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
|
||||
static bool stripe_can_batch(struct stripe_head *sh)
|
||||
{
|
||||
return test_bit(STRIPE_BATCH_READY, &sh->state) &&
|
||||
!test_bit(STRIPE_BITMAP_PENDING, &sh->state) &&
|
||||
is_full_stripe_write(sh);
|
||||
}
|
||||
|
||||
@ -837,6 +838,15 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh
|
||||
< IO_THRESHOLD)
|
||||
md_wakeup_thread(conf->mddev->thread);
|
||||
|
||||
if (test_and_clear_bit(STRIPE_BIT_DELAY, &sh->state)) {
|
||||
int seq = sh->bm_seq;
|
||||
if (test_bit(STRIPE_BIT_DELAY, &sh->batch_head->state) &&
|
||||
sh->batch_head->bm_seq > seq)
|
||||
seq = sh->batch_head->bm_seq;
|
||||
set_bit(STRIPE_BIT_DELAY, &sh->batch_head->state);
|
||||
sh->batch_head->bm_seq = seq;
|
||||
}
|
||||
|
||||
atomic_inc(&sh->count);
|
||||
unlock_out:
|
||||
unlock_two_stripes(head, sh);
|
||||
@ -2987,14 +2997,32 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx,
|
||||
pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
|
||||
(unsigned long long)(*bip)->bi_iter.bi_sector,
|
||||
(unsigned long long)sh->sector, dd_idx);
|
||||
spin_unlock_irq(&sh->stripe_lock);
|
||||
|
||||
if (conf->mddev->bitmap && firstwrite) {
|
||||
/* Cannot hold spinlock over bitmap_startwrite,
|
||||
* but must ensure this isn't added to a batch until
|
||||
* we have added to the bitmap and set bm_seq.
|
||||
* So set STRIPE_BITMAP_PENDING to prevent
|
||||
* batching.
|
||||
* If multiple add_stripe_bio() calls race here they
|
||||
* much all set STRIPE_BITMAP_PENDING. So only the first one
|
||||
* to complete "bitmap_startwrite" gets to set
|
||||
* STRIPE_BIT_DELAY. This is important as once a stripe
|
||||
* is added to a batch, STRIPE_BIT_DELAY cannot be changed
|
||||
* any more.
|
||||
*/
|
||||
set_bit(STRIPE_BITMAP_PENDING, &sh->state);
|
||||
spin_unlock_irq(&sh->stripe_lock);
|
||||
bitmap_startwrite(conf->mddev->bitmap, sh->sector,
|
||||
STRIPE_SECTORS, 0);
|
||||
sh->bm_seq = conf->seq_flush+1;
|
||||
set_bit(STRIPE_BIT_DELAY, &sh->state);
|
||||
spin_lock_irq(&sh->stripe_lock);
|
||||
clear_bit(STRIPE_BITMAP_PENDING, &sh->state);
|
||||
if (!sh->batch_head) {
|
||||
sh->bm_seq = conf->seq_flush+1;
|
||||
set_bit(STRIPE_BIT_DELAY, &sh->state);
|
||||
}
|
||||
}
|
||||
spin_unlock_irq(&sh->stripe_lock);
|
||||
|
||||
if (stripe_can_batch(sh))
|
||||
stripe_add_to_batch_list(conf, sh);
|
||||
@ -3392,6 +3420,8 @@ static void handle_stripe_fill(struct stripe_head *sh,
|
||||
set_bit(STRIPE_HANDLE, &sh->state);
|
||||
}
|
||||
|
||||
static void break_stripe_batch_list(struct stripe_head *head_sh,
|
||||
unsigned long handle_flags);
|
||||
/* handle_stripe_clean_event
|
||||
* any written block on an uptodate or failed drive can be returned.
|
||||
* Note that if we 'wrote' to a failed drive, it will be UPTODATE, but
|
||||
@ -3405,7 +3435,6 @@ static void handle_stripe_clean_event(struct r5conf *conf,
|
||||
int discard_pending = 0;
|
||||
struct stripe_head *head_sh = sh;
|
||||
bool do_endio = false;
|
||||
int wakeup_nr = 0;
|
||||
|
||||
for (i = disks; i--; )
|
||||
if (sh->dev[i].written) {
|
||||
@ -3494,44 +3523,8 @@ unhash:
|
||||
if (atomic_dec_and_test(&conf->pending_full_writes))
|
||||
md_wakeup_thread(conf->mddev->thread);
|
||||
|
||||
if (!head_sh->batch_head || !do_endio)
|
||||
return;
|
||||
for (i = 0; i < head_sh->disks; i++) {
|
||||
if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags))
|
||||
wakeup_nr++;
|
||||
}
|
||||
while (!list_empty(&head_sh->batch_list)) {
|
||||
int i;
|
||||
sh = list_first_entry(&head_sh->batch_list,
|
||||
struct stripe_head, batch_list);
|
||||
list_del_init(&sh->batch_list);
|
||||
|
||||
set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
|
||||
head_sh->state & ~((1 << STRIPE_ACTIVE) |
|
||||
(1 << STRIPE_PREREAD_ACTIVE) |
|
||||
STRIPE_EXPAND_SYNC_FLAG));
|
||||
sh->check_state = head_sh->check_state;
|
||||
sh->reconstruct_state = head_sh->reconstruct_state;
|
||||
for (i = 0; i < sh->disks; i++) {
|
||||
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
|
||||
wakeup_nr++;
|
||||
sh->dev[i].flags = head_sh->dev[i].flags;
|
||||
}
|
||||
|
||||
spin_lock_irq(&sh->stripe_lock);
|
||||
sh->batch_head = NULL;
|
||||
spin_unlock_irq(&sh->stripe_lock);
|
||||
if (sh->state & STRIPE_EXPAND_SYNC_FLAG)
|
||||
set_bit(STRIPE_HANDLE, &sh->state);
|
||||
release_stripe(sh);
|
||||
}
|
||||
|
||||
spin_lock_irq(&head_sh->stripe_lock);
|
||||
head_sh->batch_head = NULL;
|
||||
spin_unlock_irq(&head_sh->stripe_lock);
|
||||
wake_up_nr(&conf->wait_for_overlap, wakeup_nr);
|
||||
if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG)
|
||||
set_bit(STRIPE_HANDLE, &head_sh->state);
|
||||
if (head_sh->batch_head && do_endio)
|
||||
break_stripe_batch_list(head_sh, STRIPE_EXPAND_SYNC_FLAGS);
|
||||
}
|
||||
|
||||
static void handle_stripe_dirtying(struct r5conf *conf,
|
||||
@ -4172,9 +4165,13 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
|
||||
|
||||
static int clear_batch_ready(struct stripe_head *sh)
|
||||
{
|
||||
/* Return '1' if this is a member of batch, or
|
||||
* '0' if it is a lone stripe or a head which can now be
|
||||
* handled.
|
||||
*/
|
||||
struct stripe_head *tmp;
|
||||
if (!test_and_clear_bit(STRIPE_BATCH_READY, &sh->state))
|
||||
return 0;
|
||||
return (sh->batch_head && sh->batch_head != sh);
|
||||
spin_lock(&sh->stripe_lock);
|
||||
if (!sh->batch_head) {
|
||||
spin_unlock(&sh->stripe_lock);
|
||||
@ -4202,38 +4199,65 @@ static int clear_batch_ready(struct stripe_head *sh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_break_stripe_batch_list(struct stripe_head *sh)
|
||||
static void break_stripe_batch_list(struct stripe_head *head_sh,
|
||||
unsigned long handle_flags)
|
||||
{
|
||||
struct stripe_head *head_sh, *next;
|
||||
struct stripe_head *sh, *next;
|
||||
int i;
|
||||
|
||||
if (!test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state))
|
||||
return;
|
||||
|
||||
head_sh = sh;
|
||||
int do_wakeup = 0;
|
||||
|
||||
list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) {
|
||||
|
||||
list_del_init(&sh->batch_list);
|
||||
|
||||
set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
|
||||
head_sh->state & ~((1 << STRIPE_ACTIVE) |
|
||||
(1 << STRIPE_PREREAD_ACTIVE) |
|
||||
(1 << STRIPE_DEGRADED) |
|
||||
STRIPE_EXPAND_SYNC_FLAG));
|
||||
WARN_ON_ONCE(sh->state & ((1 << STRIPE_ACTIVE) |
|
||||
(1 << STRIPE_SYNCING) |
|
||||
(1 << STRIPE_REPLACED) |
|
||||
(1 << STRIPE_PREREAD_ACTIVE) |
|
||||
(1 << STRIPE_DELAYED) |
|
||||
(1 << STRIPE_BIT_DELAY) |
|
||||
(1 << STRIPE_FULL_WRITE) |
|
||||
(1 << STRIPE_BIOFILL_RUN) |
|
||||
(1 << STRIPE_COMPUTE_RUN) |
|
||||
(1 << STRIPE_OPS_REQ_PENDING) |
|
||||
(1 << STRIPE_DISCARD) |
|
||||
(1 << STRIPE_BATCH_READY) |
|
||||
(1 << STRIPE_BATCH_ERR) |
|
||||
(1 << STRIPE_BITMAP_PENDING)));
|
||||
WARN_ON_ONCE(head_sh->state & ((1 << STRIPE_DISCARD) |
|
||||
(1 << STRIPE_REPLACED)));
|
||||
|
||||
set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS |
|
||||
(1 << STRIPE_DEGRADED)),
|
||||
head_sh->state & (1 << STRIPE_INSYNC));
|
||||
|
||||
sh->check_state = head_sh->check_state;
|
||||
sh->reconstruct_state = head_sh->reconstruct_state;
|
||||
for (i = 0; i < sh->disks; i++)
|
||||
for (i = 0; i < sh->disks; i++) {
|
||||
if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
|
||||
do_wakeup = 1;
|
||||
sh->dev[i].flags = head_sh->dev[i].flags &
|
||||
(~((1 << R5_WriteError) | (1 << R5_Overlap)));
|
||||
|
||||
}
|
||||
spin_lock_irq(&sh->stripe_lock);
|
||||
sh->batch_head = NULL;
|
||||
spin_unlock_irq(&sh->stripe_lock);
|
||||
|
||||
set_bit(STRIPE_HANDLE, &sh->state);
|
||||
if (handle_flags == 0 ||
|
||||
sh->state & handle_flags)
|
||||
set_bit(STRIPE_HANDLE, &sh->state);
|
||||
release_stripe(sh);
|
||||
}
|
||||
spin_lock_irq(&head_sh->stripe_lock);
|
||||
head_sh->batch_head = NULL;
|
||||
spin_unlock_irq(&head_sh->stripe_lock);
|
||||
for (i = 0; i < head_sh->disks; i++)
|
||||
if (test_and_clear_bit(R5_Overlap, &head_sh->dev[i].flags))
|
||||
do_wakeup = 1;
|
||||
if (head_sh->state & handle_flags)
|
||||
set_bit(STRIPE_HANDLE, &head_sh->state);
|
||||
|
||||
if (do_wakeup)
|
||||
wake_up(&head_sh->raid_conf->wait_for_overlap);
|
||||
}
|
||||
|
||||
static void handle_stripe(struct stripe_head *sh)
|
||||
@ -4258,7 +4282,8 @@ static void handle_stripe(struct stripe_head *sh)
|
||||
return;
|
||||
}
|
||||
|
||||
check_break_stripe_batch_list(sh);
|
||||
if (test_and_clear_bit(STRIPE_BATCH_ERR, &sh->state))
|
||||
break_stripe_batch_list(sh, 0);
|
||||
|
||||
if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
|
||||
spin_lock(&sh->stripe_lock);
|
||||
@ -4312,6 +4337,7 @@ static void handle_stripe(struct stripe_head *sh)
|
||||
if (s.failed > conf->max_degraded) {
|
||||
sh->check_state = 0;
|
||||
sh->reconstruct_state = 0;
|
||||
break_stripe_batch_list(sh, 0);
|
||||
if (s.to_read+s.to_write+s.written)
|
||||
handle_failed_stripe(conf, sh, &s, disks, &s.return_bi);
|
||||
if (s.syncing + s.replacing)
|
||||
|
@ -337,9 +337,12 @@ enum {
|
||||
STRIPE_ON_RELEASE_LIST,
|
||||
STRIPE_BATCH_READY,
|
||||
STRIPE_BATCH_ERR,
|
||||
STRIPE_BITMAP_PENDING, /* Being added to bitmap, don't add
|
||||
* to batch yet.
|
||||
*/
|
||||
};
|
||||
|
||||
#define STRIPE_EXPAND_SYNC_FLAG \
|
||||
#define STRIPE_EXPAND_SYNC_FLAGS \
|
||||
((1 << STRIPE_EXPAND_SOURCE) |\
|
||||
(1 << STRIPE_EXPAND_READY) |\
|
||||
(1 << STRIPE_EXPANDING) |\
|
||||
|
@ -431,6 +431,10 @@ int da9052_adc_read_temp(struct da9052 *da9052)
|
||||
EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
|
||||
|
||||
static const struct mfd_cell da9052_subdev_info[] = {
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 0,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 1,
|
||||
@ -483,10 +487,6 @@ static const struct mfd_cell da9052_subdev_info[] = {
|
||||
.name = "da9052-regulator",
|
||||
.id = 13,
|
||||
},
|
||||
{
|
||||
.name = "da9052-regulator",
|
||||
.id = 14,
|
||||
},
|
||||
{
|
||||
.name = "da9052-onkey",
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user