From f7ab093f74bf638ed98fd1115f3efa17e308bb7f Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:11 -0400 Subject: [PATCH 0001/5324] Orangefs: kernel client part 1 OrangeFS (formerly PVFS) is an lgpl licensed userspace networked parallel file system. OrangeFS can be accessed through included system utilities, user integration libraries, MPI-IO and can be used by the Hadoop ecosystem as an alternative to the HDFS filesystem. OrangeFS is used widely for parallel science, data analytics and engineering applications. While applications often don't require Orangefs to be mounted into the VFS, users do like to be able to access their files in the normal way. The Orangefs kernel client allows Orangefs filesystems to be mounted as a VFS. The kernel client communicates with a userspace daemon which in turn communicates with the Orangefs server daemons that implement the filesystem. The server daemons (there's almost always more than one) need not be running on the same host as the kernel client. Orangefs filesystems can also be mounted with FUSE, and we ship code and instructions to facilitate that, but most of our users report preferring to use our kernel module instead. Further, as an example of a problem we can't solve with fuse, we have in the works a not-yet-ready-for-prime-time version of a file_operations lock function that accounts for the server daemons being distributed across more than one running kernel. Many people and organizations, including Clemson University, Argonne National Laboratories and Acxiom Corporation have helped to create what has become Orangefs over more than twenty years. Some of the more recent contributors to the kernel client include: Mike Marshall Christoph Hellwig Randy Martin Becky Ligon Walt Ligon Michael Moore Rob Ross Phil Carnes Signed-off-by: Mike Marshall --- fs/orangefs/downcall.h | 138 ++++++ fs/orangefs/protocol.h | 681 +++++++++++++++++++++++++++ fs/orangefs/pvfs2-bufmap.h | 76 +++ fs/orangefs/pvfs2-debug.h | 290 ++++++++++++ fs/orangefs/pvfs2-debugfs.h | 3 + fs/orangefs/pvfs2-dev-proto.h | 102 ++++ fs/orangefs/pvfs2-kernel.h | 864 ++++++++++++++++++++++++++++++++++ fs/orangefs/pvfs2-sysfs.h | 2 + fs/orangefs/upcall.h | 255 ++++++++++ 9 files changed, 2411 insertions(+) create mode 100644 fs/orangefs/downcall.h create mode 100644 fs/orangefs/protocol.h create mode 100644 fs/orangefs/pvfs2-bufmap.h create mode 100644 fs/orangefs/pvfs2-debug.h create mode 100644 fs/orangefs/pvfs2-debugfs.h create mode 100644 fs/orangefs/pvfs2-dev-proto.h create mode 100644 fs/orangefs/pvfs2-kernel.h create mode 100644 fs/orangefs/pvfs2-sysfs.h create mode 100644 fs/orangefs/upcall.h diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h new file mode 100644 index 000000000000..a79129f875f3 --- /dev/null +++ b/fs/orangefs/downcall.h @@ -0,0 +1,138 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Definitions of downcalls used in Linux kernel module. + */ + +#ifndef __DOWNCALL_H +#define __DOWNCALL_H + +/* + * Sanitized the device-client core interaction + * for clean 32-64 bit usage + */ +struct pvfs2_io_response { + __s64 amt_complete; +}; + +struct pvfs2_iox_response { + __s64 amt_complete; +}; + +struct pvfs2_lookup_response { + struct pvfs2_object_kref refn; +}; + +struct pvfs2_create_response { + struct pvfs2_object_kref refn; +}; + +struct pvfs2_symlink_response { + struct pvfs2_object_kref refn; +}; + +struct pvfs2_getattr_response { + struct PVFS_sys_attr_s attributes; + char link_target[PVFS2_NAME_LEN]; +}; + +struct pvfs2_mkdir_response { + struct pvfs2_object_kref refn; +}; + +/* + * duplication of some system interface structures so that I don't have + * to allocate extra memory + */ +struct pvfs2_dirent { + char *d_name; + int d_length; + struct pvfs2_khandle khandle; +}; + +struct pvfs2_statfs_response { + __s64 block_size; + __s64 blocks_total; + __s64 blocks_avail; + __s64 files_total; + __s64 files_avail; +}; + +struct pvfs2_fs_mount_response { + __s32 fs_id; + __s32 id; + struct pvfs2_khandle root_khandle; +}; + +/* the getxattr response is the attribute value */ +struct pvfs2_getxattr_response { + __s32 val_sz; + __s32 __pad1; + char val[PVFS_MAX_XATTR_VALUELEN]; +}; + +/* the listxattr response is an array of attribute names */ +struct pvfs2_listxattr_response { + __s32 returned_count; + __s32 __pad1; + __u64 token; + char key[PVFS_MAX_XATTR_LISTLEN * PVFS_MAX_XATTR_NAMELEN]; + __s32 keylen; + __s32 __pad2; + __s32 lengths[PVFS_MAX_XATTR_LISTLEN]; +}; + +struct pvfs2_param_response { + __s64 value; +}; + +#define PERF_COUNT_BUF_SIZE 4096 +struct pvfs2_perf_count_response { + char buffer[PERF_COUNT_BUF_SIZE]; +}; + +#define FS_KEY_BUF_SIZE 4096 +struct pvfs2_fs_key_response { + __s32 fs_keylen; + __s32 __pad1; + char fs_key[FS_KEY_BUF_SIZE]; +}; + +struct pvfs2_downcall_s { + __s32 type; + __s32 status; + /* currently trailer is used only by readdir */ + __s64 trailer_size; + char * trailer_buf; + + union { + struct pvfs2_io_response io; + struct pvfs2_iox_response iox; + struct pvfs2_lookup_response lookup; + struct pvfs2_create_response create; + struct pvfs2_symlink_response sym; + struct pvfs2_getattr_response getattr; + struct pvfs2_mkdir_response mkdir; + struct pvfs2_statfs_response statfs; + struct pvfs2_fs_mount_response fs_mount; + struct pvfs2_getxattr_response getxattr; + struct pvfs2_listxattr_response listxattr; + struct pvfs2_param_response param; + struct pvfs2_perf_count_response perf_count; + struct pvfs2_fs_key_response fs_key; + } resp; +}; + +struct pvfs2_readdir_response_s { + __u64 token; + __u64 directory_version; + __u32 __pad2; + __u32 pvfs_dirent_outcount; + struct pvfs2_dirent *dirent_array; +}; + +#endif /* __DOWNCALL_H */ diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h new file mode 100644 index 000000000000..2fb3a63ae9ab --- /dev/null +++ b/fs/orangefs/protocol.h @@ -0,0 +1,681 @@ +#include +#include +#include + +extern struct client_debug_mask *cdm_array; +extern char *debug_help_string; +extern int help_string_initialized; +extern struct dentry *debug_dir; +extern struct dentry *help_file_dentry; +extern struct dentry *client_debug_dentry; +extern const struct file_operations debug_help_fops; +extern int client_all_index; +extern int client_verbose_index; +extern int cdm_element_count; +#define DEBUG_HELP_STRING_SIZE 4096 +#define HELP_STRING_UNINITIALIZED \ + "Client Debug Keywords are unknown until the first time\n" \ + "the client is started after boot.\n" +#define ORANGEFS_KMOD_DEBUG_HELP_FILE "debug-help" +#define ORANGEFS_KMOD_DEBUG_FILE "kernel-debug" +#define ORANGEFS_CLIENT_DEBUG_FILE "client-debug" +#define PVFS2_VERBOSE "verbose" +#define PVFS2_ALL "all" + +/* pvfs2-config.h ***********************************************************/ +#define PVFS2_VERSION_MAJOR 2 +#define PVFS2_VERSION_MINOR 9 +#define PVFS2_VERSION_SUB 0 + +/* khandle stuff ***********************************************************/ + +/* + * The 2.9 core will put 64 bit handles in here like this: + * 1234 0000 0000 5678 + * The 3.0 and beyond cores will put 128 bit handles in here like this: + * 1234 5678 90AB CDEF + * The kernel module will always use the first four bytes and + * the last four bytes as an inum. + */ +struct pvfs2_khandle { + unsigned char u[16]; +} __aligned(8); + +/* + * kernel version of an object ref. + */ +struct pvfs2_object_kref { + struct pvfs2_khandle khandle; + __s32 fs_id; + __s32 __pad1; +}; + +/* + * compare 2 khandles assumes little endian thus from large address to + * small address + */ +static inline int PVFS_khandle_cmp(const struct pvfs2_khandle *kh1, + const struct pvfs2_khandle *kh2) +{ + int i; + + for (i = 15; i >= 0; i--) { + if (kh1->u[i] > kh2->u[i]) + return 1; + if (kh1->u[i] < kh2->u[i]) + return -1; + } + + return 0; +} + +/* copy a khandle to a field of arbitrary size */ +static inline void PVFS_khandle_to(const struct pvfs2_khandle *kh, + void *p, int size) +{ + int i; + unsigned char *c = p; + + memset(p, 0, size); + + for (i = 0; i < 16 && i < size; i++) + c[i] = kh->u[i]; +} + +/* copy a khandle from a field of arbitrary size */ +static inline void PVFS_khandle_from(struct pvfs2_khandle *kh, + void *p, int size) +{ + int i; + unsigned char *c = p; + + memset(kh, 0, 16); + + for (i = 0; i < 16 && i < size; i++) + kh->u[i] = c[i]; +} + +/* pvfs2-types.h ************************************************************/ +typedef __u32 PVFS_uid; +typedef __u32 PVFS_gid; +typedef __s32 PVFS_fs_id; +typedef __u32 PVFS_permissions; +typedef __u64 PVFS_time; +typedef __s64 PVFS_size; +typedef __u64 PVFS_flags; +typedef __u64 PVFS_ds_position; +typedef __s32 PVFS_error; +typedef __s64 PVFS_offset; + +#define PVFS2_SUPER_MAGIC 0x20030528 +#define PVFS_ERROR_BIT (1 << 30) +#define PVFS_NON_ERRNO_ERROR_BIT (1 << 29) +#define IS_PVFS_ERROR(__error) ((__error)&(PVFS_ERROR_BIT)) +#define IS_PVFS_NON_ERRNO_ERROR(__error) \ +(((__error)&(PVFS_NON_ERRNO_ERROR_BIT)) && IS_PVFS_ERROR(__error)) +#define PVFS_ERROR_TO_ERRNO(__error) PVFS_get_errno_mapping(__error) + +/* 7 bits are used for the errno mapped error codes */ +#define PVFS_ERROR_CODE(__error) \ +((__error) & (__s32)(0x7f|PVFS_ERROR_BIT)) +#define PVFS_ERROR_CLASS(__error) \ +((__error) & ~((__s32)(0x7f|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT))) +#define PVFS_NON_ERRNO_ERROR_CODE(__error) \ +((__error) & (__s32)(127|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT)) + +/* PVFS2 error codes, compliments of asm/errno.h */ +#define PVFS_EPERM E(1) /* Operation not permitted */ +#define PVFS_ENOENT E(2) /* No such file or directory */ +#define PVFS_EINTR E(3) /* Interrupted system call */ +#define PVFS_EIO E(4) /* I/O error */ +#define PVFS_ENXIO E(5) /* No such device or address */ +#define PVFS_EBADF E(6) /* Bad file number */ +#define PVFS_EAGAIN E(7) /* Try again */ +#define PVFS_ENOMEM E(8) /* Out of memory */ +#define PVFS_EFAULT E(9) /* Bad address */ +#define PVFS_EBUSY E(10) /* Device or resource busy */ +#define PVFS_EEXIST E(11) /* File exists */ +#define PVFS_ENODEV E(12) /* No such device */ +#define PVFS_ENOTDIR E(13) /* Not a directory */ +#define PVFS_EISDIR E(14) /* Is a directory */ +#define PVFS_EINVAL E(15) /* Invalid argument */ +#define PVFS_EMFILE E(16) /* Too many open files */ +#define PVFS_EFBIG E(17) /* File too large */ +#define PVFS_ENOSPC E(18) /* No space left on device */ +#define PVFS_EROFS E(19) /* Read-only file system */ +#define PVFS_EMLINK E(20) /* Too many links */ +#define PVFS_EPIPE E(21) /* Broken pipe */ +#define PVFS_EDEADLK E(22) /* Resource deadlock would occur */ +#define PVFS_ENAMETOOLONG E(23) /* File name too long */ +#define PVFS_ENOLCK E(24) /* No record locks available */ +#define PVFS_ENOSYS E(25) /* Function not implemented */ +#define PVFS_ENOTEMPTY E(26) /* Directory not empty */ + /* +#define PVFS_ELOOP E(27) * Too many symbolic links encountered + */ +#define PVFS_EWOULDBLOCK E(28) /* Operation would block */ +#define PVFS_ENOMSG E(29) /* No message of desired type */ +#define PVFS_EUNATCH E(30) /* Protocol driver not attached */ +#define PVFS_EBADR E(31) /* Invalid request descriptor */ +#define PVFS_EDEADLOCK E(32) +#define PVFS_ENODATA E(33) /* No data available */ +#define PVFS_ETIME E(34) /* Timer expired */ +#define PVFS_ENONET E(35) /* Machine is not on the network */ +#define PVFS_EREMOTE E(36) /* Object is remote */ +#define PVFS_ECOMM E(37) /* Communication error on send */ +#define PVFS_EPROTO E(38) /* Protocol error */ +#define PVFS_EBADMSG E(39) /* Not a data message */ + /* +#define PVFS_EOVERFLOW E(40) * Value too large for defined data + * type + */ + /* +#define PVFS_ERESTART E(41) * Interrupted system call should be + * restarted + */ +#define PVFS_EMSGSIZE E(42) /* Message too long */ +#define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */ +#define PVFS_ENOPROTOOPT E(44) /* Protocol not available */ +#define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */ + /* +#define PVFS_EOPNOTSUPP E(46) * Operation not supported on transport + * endpoint + */ +#define PVFS_EADDRINUSE E(47) /* Address already in use */ +#define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */ +#define PVFS_ENETDOWN E(49) /* Network is down */ +#define PVFS_ENETUNREACH E(50) /* Network is unreachable */ + /* +#define PVFS_ENETRESET E(51) * Network dropped connection because + * of reset + */ +#define PVFS_ENOBUFS E(52) /* No buffer space available */ +#define PVFS_ETIMEDOUT E(53) /* Connection timed out */ +#define PVFS_ECONNREFUSED E(54) /* Connection refused */ +#define PVFS_EHOSTDOWN E(55) /* Host is down */ +#define PVFS_EHOSTUNREACH E(56) /* No route to host */ +#define PVFS_EALREADY E(57) /* Operation already in progress */ +#define PVFS_EACCES E(58) /* Access not allowed */ +#define PVFS_ECONNRESET E(59) /* Connection reset by peer */ +#define PVFS_ERANGE E(60) /* Math out of range or buf too small */ + +/***************** non-errno/pvfs2 specific error codes *****************/ +#define PVFS_ECANCEL (1|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_EDEVINIT (2|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_EDETAIL (3|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_EHOSTNTFD (4|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_EADDRNTFD (5|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_ENORECVR (6|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_ETRYAGAIN (7|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_ENOTPVFS (8|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) +#define PVFS_ESECURITY (9|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) + +/* + * NOTE: PLEASE DO NOT ARBITRARILY ADD NEW ERRNO ERROR CODES! + * + * IF YOU CHOOSE TO ADD A NEW ERROR CODE (DESPITE OUR PLEA), YOU ALSO + * NEED TO INCREMENT PVFS_ERRNO MAX (BELOW) AND ADD A MAPPING TO A + * UNIX ERRNO VALUE IN THE MACROS BELOW (USED IN + * src/common/misc/errno-mapping.c and the kernel module) + */ +#define PVFS_ERRNO_MAX 61 + +#define PVFS_ERROR_BMI (1 << 7) /* BMI-specific error */ +#define PVFS_ERROR_TROVE (2 << 7) /* Trove-specific error */ +#define PVFS_ERROR_FLOW (3 << 7) +#define PVFS_ERROR_SM (4 << 7) /* state machine specific error */ +#define PVFS_ERROR_SCHED (5 << 7) +#define PVFS_ERROR_CLIENT (6 << 7) +#define PVFS_ERROR_DEV (7 << 7) /* device file interaction */ + +#define PVFS_ERROR_CLASS_BITS \ + (PVFS_ERROR_BMI | \ + PVFS_ERROR_TROVE | \ + PVFS_ERROR_FLOW | \ + PVFS_ERROR_SM | \ + PVFS_ERROR_SCHED | \ + PVFS_ERROR_CLIENT | \ + PVFS_ERROR_DEV) + +#define DECLARE_ERRNO_MAPPING() \ +__s32 PINT_errno_mapping[PVFS_ERRNO_MAX + 1] = { \ + 0, /* leave this one empty */ \ + EPERM, /* 1 */ \ + ENOENT, \ + EINTR, \ + EIO, \ + ENXIO, \ + EBADF, \ + EAGAIN, \ + ENOMEM, \ + EFAULT, \ + EBUSY, /* 10 */ \ + EEXIST, \ + ENODEV, \ + ENOTDIR, \ + EISDIR, \ + EINVAL, \ + EMFILE, \ + EFBIG, \ + ENOSPC, \ + EROFS, \ + EMLINK, /* 20 */ \ + EPIPE, \ + EDEADLK, \ + ENAMETOOLONG, \ + ENOLCK, \ + ENOSYS, \ + ENOTEMPTY, \ + ELOOP, \ + EWOULDBLOCK, \ + ENOMSG, \ + EUNATCH, /* 30 */ \ + EBADR, \ + EDEADLOCK, \ + ENODATA, \ + ETIME, \ + ENONET, \ + EREMOTE, \ + ECOMM, \ + EPROTO, \ + EBADMSG, \ + EOVERFLOW, /* 40 */ \ + ERESTART, \ + EMSGSIZE, \ + EPROTOTYPE, \ + ENOPROTOOPT, \ + EPROTONOSUPPORT, \ + EOPNOTSUPP, \ + EADDRINUSE, \ + EADDRNOTAVAIL, \ + ENETDOWN, \ + ENETUNREACH, /* 50 */ \ + ENETRESET, \ + ENOBUFS, \ + ETIMEDOUT, \ + ECONNREFUSED, \ + EHOSTDOWN, \ + EHOSTUNREACH, \ + EALREADY, \ + EACCES, \ + ECONNRESET, /* 59 */ \ + ERANGE, \ + 0 /* PVFS_ERRNO_MAX */ \ +}; \ +const char *PINT_non_errno_strerror_mapping[] = { \ + "Success", /* 0 */ \ + "Operation cancelled (possibly due to timeout)", \ + "Device initialization failed", \ + "Detailed per-server errors are available", \ + "Unknown host", \ + "No address associated with name", \ + "Unknown server error", \ + "Host name lookup failure", \ + "Path contains non-PVFS elements", \ + "Security error", \ +}; \ +__s32 PINT_non_errno_mapping[] = { \ + 0, /* leave this one empty */ \ + PVFS_ECANCEL, /* 1 */ \ + PVFS_EDEVINIT, /* 2 */ \ + PVFS_EDETAIL, /* 3 */ \ + PVFS_EHOSTNTFD, /* 4 */ \ + PVFS_EADDRNTFD, /* 5 */ \ + PVFS_ENORECVR, /* 6 */ \ + PVFS_ETRYAGAIN, /* 7 */ \ + PVFS_ENOTPVFS, /* 8 */ \ + PVFS_ESECURITY, /* 9 */ \ +} + +/* + * NOTE: PVFS_get_errno_mapping will convert a PVFS_ERROR_CODE to an + * errno value. If the error code is a pvfs2 specific error code + * (i.e. a PVFS_NON_ERRNO_ERROR_CODE), PVFS_get_errno_mapping will + * return an index into the PINT_non_errno_strerror_mapping array which + * can be used for getting the pvfs2 specific strerror message given + * the error code. if the value is not a recognized error code, the + * passed in value will be returned unchanged. + */ +#define DECLARE_ERRNO_MAPPING_AND_FN() \ +extern __s32 PINT_errno_mapping[]; \ +extern __s32 PINT_non_errno_mapping[]; \ +extern const char *PINT_non_errno_strerror_mapping[]; \ +__s32 PVFS_get_errno_mapping(__s32 error) \ +{ \ + __s32 ret = error, mask = 0; \ + __s32 positive = ((error > -1) ? 1 : 0); \ + if (IS_PVFS_NON_ERRNO_ERROR((positive ? error : -error))) { \ + mask = (PVFS_NON_ERRNO_ERROR_BIT | \ + PVFS_ERROR_BIT | \ + PVFS_ERROR_CLASS_BITS); \ + ret = PVFS_NON_ERRNO_ERROR_CODE(((positive ? \ + error : \ + abs(error))) & \ + ~mask); \ + } \ + else if (IS_PVFS_ERROR((positive ? error : -error))) { \ + mask = (PVFS_ERROR_BIT | \ + PVFS_ERROR_CLASS_BITS); \ + ret = PINT_errno_mapping[PVFS_ERROR_CODE(((positive ? \ + error : \ + abs(error))) & \ + ~mask)]; \ + } \ + return ret; \ +} \ +__s32 PVFS_errno_to_error(int err) \ +{ \ + __s32 e = 0; \ + \ + for (; e < PVFS_ERRNO_MAX; ++e) \ + if (PINT_errno_mapping[e] == err) \ + return e | PVFS_ERROR_BIT; \ + \ + return err; \ +} \ +DECLARE_ERRNO_MAPPING() + +/* permission bits */ +#define PVFS_O_EXECUTE (1 << 0) +#define PVFS_O_WRITE (1 << 1) +#define PVFS_O_READ (1 << 2) +#define PVFS_G_EXECUTE (1 << 3) +#define PVFS_G_WRITE (1 << 4) +#define PVFS_G_READ (1 << 5) +#define PVFS_U_EXECUTE (1 << 6) +#define PVFS_U_WRITE (1 << 7) +#define PVFS_U_READ (1 << 8) +/* no PVFS_U_VTX (sticky bit) */ +#define PVFS_G_SGID (1 << 10) +#define PVFS_U_SUID (1 << 11) + +/* definition taken from stdint.h */ +#define INT32_MAX (2147483647) +#define PVFS_ITERATE_START (INT32_MAX - 1) +#define PVFS_ITERATE_END (INT32_MAX - 2) +#define PVFS_READDIR_START PVFS_ITERATE_START +#define PVFS_READDIR_END PVFS_ITERATE_END +#define PVFS_IMMUTABLE_FL FS_IMMUTABLE_FL +#define PVFS_APPEND_FL FS_APPEND_FL +#define PVFS_NOATIME_FL FS_NOATIME_FL +#define PVFS_MIRROR_FL 0x01000000ULL +#define PVFS_O_EXECUTE (1 << 0) +#define PVFS_FS_ID_NULL ((__s32)0) +#define PVFS_ATTR_SYS_UID (1 << 0) +#define PVFS_ATTR_SYS_GID (1 << 1) +#define PVFS_ATTR_SYS_PERM (1 << 2) +#define PVFS_ATTR_SYS_ATIME (1 << 3) +#define PVFS_ATTR_SYS_CTIME (1 << 4) +#define PVFS_ATTR_SYS_MTIME (1 << 5) +#define PVFS_ATTR_SYS_TYPE (1 << 6) +#define PVFS_ATTR_SYS_ATIME_SET (1 << 7) +#define PVFS_ATTR_SYS_MTIME_SET (1 << 8) +#define PVFS_ATTR_SYS_SIZE (1 << 20) +#define PVFS_ATTR_SYS_LNK_TARGET (1 << 24) +#define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25) +#define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26) +#define PVFS_ATTR_SYS_BLKSIZE (1 << 28) +#define PVFS_ATTR_SYS_MIRROR_COPIES_COUNT (1 << 29) +#define PVFS_ATTR_SYS_COMMON_ALL \ + (PVFS_ATTR_SYS_UID | \ + PVFS_ATTR_SYS_GID | \ + PVFS_ATTR_SYS_PERM | \ + PVFS_ATTR_SYS_ATIME | \ + PVFS_ATTR_SYS_CTIME | \ + PVFS_ATTR_SYS_MTIME | \ + PVFS_ATTR_SYS_TYPE) + +#define PVFS_ATTR_SYS_ALL_SETABLE \ +(PVFS_ATTR_SYS_COMMON_ALL-PVFS_ATTR_SYS_TYPE) + +#define PVFS_ATTR_SYS_ALL_NOHINT \ + (PVFS_ATTR_SYS_COMMON_ALL | \ + PVFS_ATTR_SYS_SIZE | \ + PVFS_ATTR_SYS_LNK_TARGET | \ + PVFS_ATTR_SYS_DFILE_COUNT | \ + PVFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ + PVFS_ATTR_SYS_DIRENT_COUNT | \ + PVFS_ATTR_SYS_BLKSIZE) +#define PVFS_XATTR_REPLACE 0x2 +#define PVFS_XATTR_CREATE 0x1 +#define PVFS_MAX_SERVER_ADDR_LEN 256 +#define PVFS_NAME_MAX 256 +/* + * max extended attribute name len as imposed by the VFS and exploited for the + * upcall request types. + * NOTE: Please retain them as multiples of 8 even if you wish to change them + * This is *NECESSARY* for supporting 32 bit user-space binaries on a 64-bit + * kernel. Due to implementation within DBPF, this really needs to be + * PVFS_NAME_MAX, which it was the same value as, but no reason to let it + * break if that changes in the future. + */ +#define PVFS_MAX_XATTR_NAMELEN PVFS_NAME_MAX /* Not the same as + * XATTR_NAME_MAX defined + * by + */ +#define PVFS_MAX_XATTR_VALUELEN 8192 /* Not the same as XATTR_SIZE_MAX + * defined by + */ +#define PVFS_MAX_XATTR_LISTLEN 16 /* Not the same as XATTR_LIST_MAX + * defined by + */ +/* + * PVFS I/O operation types, used in both system and server interfaces. + */ +enum PVFS_io_type { + PVFS_IO_READ = 1, + PVFS_IO_WRITE = 2 +}; + +/* + * If this enum is modified the server parameters related to the precreate pool + * batch and low threshold sizes may need to be modified to reflect this + * change. + */ +enum pvfs2_ds_type { + PVFS_TYPE_NONE = 0, + PVFS_TYPE_METAFILE = (1 << 0), + PVFS_TYPE_DATAFILE = (1 << 1), + PVFS_TYPE_DIRECTORY = (1 << 2), + PVFS_TYPE_SYMLINK = (1 << 3), + PVFS_TYPE_DIRDATA = (1 << 4), + PVFS_TYPE_INTERNAL = (1 << 5) /* for the server's private use */ +}; + +/* + * PVFS_certificate simply stores a buffer with the buffer size. + * The buffer can be converted to an OpenSSL X509 struct for use. + */ +struct PVFS_certificate { + __u32 buf_size; + unsigned char *buf; +}; + +/* + * A credential identifies a user and is signed by the client/user + * private key. + */ +struct PVFS_credential { + __u32 userid; /* user id */ + __u32 num_groups; /* length of group_array */ + __u32 *group_array; /* groups for which the user is a member */ + char *issuer; /* alias of the issuing server */ + __u64 timeout; /* seconds after epoch to time out */ + __u32 sig_size; /* length of the signature in bytes */ + unsigned char *signature; /* digital signature */ + struct PVFS_certificate certificate; /* user certificate buffer */ +}; +#define extra_size_PVFS_credential (PVFS_REQ_LIMIT_GROUPS * \ + sizeof(__u32) + \ + PVFS_REQ_LIMIT_ISSUER + \ + PVFS_REQ_LIMIT_SIGNATURE + \ + extra_size_PVFS_certificate) + +/* This structure is used by the VFS-client interaction alone */ +struct PVFS_keyval_pair { + char key[PVFS_MAX_XATTR_NAMELEN]; + __s32 key_sz; /* __s32 for portable, fixed-size structures */ + __s32 val_sz; + char val[PVFS_MAX_XATTR_VALUELEN]; +}; + +/* pvfs2-sysint.h ***********************************************************/ +/* Describes attributes for a file, directory, or symlink. */ +struct PVFS_sys_attr_s { + __u32 owner; + __u32 group; + __u32 perms; + __u64 atime; + __u64 mtime; + __u64 ctime; + __s64 size; + + /* NOTE: caller must free if valid */ + char *link_target; + + /* Changed to __s32 so that size of structure does not change */ + __s32 dfile_count; + + /* Changed to __s32 so that size of structure does not change */ + __s32 distr_dir_servers_initial; + + /* Changed to __s32 so that size of structure does not change */ + __s32 distr_dir_servers_max; + + /* Changed to __s32 so that size of structure does not change */ + __s32 distr_dir_split_size; + + __u32 mirror_copies_count; + + /* NOTE: caller must free if valid */ + char *dist_name; + + /* NOTE: caller must free if valid */ + char *dist_params; + + __s64 dirent_count; + enum pvfs2_ds_type objtype; + __u64 flags; + __u32 mask; + __s64 blksize; +}; + +#define PVFS2_LOOKUP_LINK_NO_FOLLOW 0 +#define PVFS2_LOOKUP_LINK_FOLLOW 1 + +/* pint-dev.h ***************************************************************/ + +/* parameter structure used in PVFS_DEV_DEBUG ioctl command */ +struct dev_mask_info_s { + enum { + KERNEL_MASK, + CLIENT_MASK, + } mask_type; + __u64 mask_value; +}; + +struct dev_mask2_info_s { + __u64 mask1_value; + __u64 mask2_value; +}; + +/* pvfs2-util.h *************************************************************/ +#define PVFS_util_min(x1, x2) (((x1) > (x2)) ? (x2) : (x1)) +__s32 PVFS_util_translate_mode(int mode); + +/* pvfs2-debug.h ************************************************************/ +#include "pvfs2-debug.h" + +/* pvfs2-internal.h *********************************************************/ +#define llu(x) (unsigned long long)(x) +#define lld(x) (long long)(x) + +/* pint-dev-shared.h ********************************************************/ +#define PVFS_DEV_MAGIC 'k' + +#define PVFS2_READDIR_DEFAULT_DESC_COUNT 5 + +#define DEV_GET_MAGIC 0x1 +#define DEV_GET_MAX_UPSIZE 0x2 +#define DEV_GET_MAX_DOWNSIZE 0x3 +#define DEV_MAP 0x4 +#define DEV_REMOUNT_ALL 0x5 +#define DEV_DEBUG 0x6 +#define DEV_UPSTREAM 0x7 +#define DEV_CLIENT_MASK 0x8 +#define DEV_CLIENT_STRING 0x9 +#define DEV_MAX_NR 0xa + +/* supported ioctls, codes are with respect to user-space */ +enum { + PVFS_DEV_GET_MAGIC = _IOW(PVFS_DEV_MAGIC, DEV_GET_MAGIC, __s32), + PVFS_DEV_GET_MAX_UPSIZE = + _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_UPSIZE, __s32), + PVFS_DEV_GET_MAX_DOWNSIZE = + _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_DOWNSIZE, __s32), + PVFS_DEV_MAP = _IO(PVFS_DEV_MAGIC, DEV_MAP), + PVFS_DEV_REMOUNT_ALL = _IO(PVFS_DEV_MAGIC, DEV_REMOUNT_ALL), + PVFS_DEV_DEBUG = _IOR(PVFS_DEV_MAGIC, DEV_DEBUG, __s32), + PVFS_DEV_UPSTREAM = _IOW(PVFS_DEV_MAGIC, DEV_UPSTREAM, int), + PVFS_DEV_CLIENT_MASK = _IOW(PVFS_DEV_MAGIC, + DEV_CLIENT_MASK, + struct dev_mask2_info_s), + PVFS_DEV_CLIENT_STRING = _IOW(PVFS_DEV_MAGIC, + DEV_CLIENT_STRING, + char *), + PVFS_DEV_MAXNR = DEV_MAX_NR, +}; + +/* + * version number for use in communicating between kernel space and user + * space + */ +/* +#define PVFS_KERNEL_PROTO_VERSION \ + ((PVFS2_VERSION_MAJOR * 10000) + \ + (PVFS2_VERSION_MINOR * 100) + \ + PVFS2_VERSION_SUB) +*/ +#define PVFS_KERNEL_PROTO_VERSION 0 + +/* + * describes memory regions to map in the PVFS_DEV_MAP ioctl. + * NOTE: See devpvfs2-req.c for 32 bit compat structure. + * Since this structure has a variable-sized layout that is different + * on 32 and 64 bit platforms, we need to normalize to a 64 bit layout + * on such systems before servicing ioctl calls from user-space binaries + * that may be 32 bit! + */ +struct PVFS_dev_map_desc { + void *ptr; + __s32 total_size; + __s32 size; + __s32 count; +}; + +/* gossip.h *****************************************************************/ + +#ifdef GOSSIP_DISABLE_DEBUG +#define gossip_debug(mask, format, f...) do {} while (0) +#else +extern __u64 gossip_debug_mask; +extern struct client_debug_mask client_debug_mask; + +/* try to avoid function call overhead by checking masks in macro */ +#define gossip_debug(mask, format, f...) \ +do { \ + if (gossip_debug_mask & mask) \ + printk(format, ##f); \ +} while (0) +#endif /* GOSSIP_DISABLE_DEBUG */ + +/* do file and line number printouts w/ the GNU preprocessor */ +#define gossip_ldebug(mask, format, f...) \ + gossip_debug(mask, "%s: " format, __func__, ##f) + +#define gossip_err printk +#define gossip_lerr(format, f...) \ + gossip_err("%s line %d: " format, \ + __FILE__, \ + __LINE__, \ + ##f) diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/pvfs2-bufmap.h new file mode 100644 index 000000000000..e269deafbb74 --- /dev/null +++ b/fs/orangefs/pvfs2-bufmap.h @@ -0,0 +1,76 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#ifndef __PVFS2_BUFMAP_H +#define __PVFS2_BUFMAP_H + +/* used to describe mapped buffers */ +struct pvfs_bufmap_desc { + void *uaddr; /* user space address pointer */ + struct page **page_array; /* array of mapped pages */ + int array_count; /* size of above arrays */ + struct list_head list_link; +}; + +struct pvfs2_bufmap; + +struct pvfs2_bufmap *pvfs2_bufmap_ref(void); +void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap); + +/* + * pvfs_bufmap_size_query is now an inline function because buffer + * sizes are not hardcoded + */ +int pvfs_bufmap_size_query(void); + +int pvfs_bufmap_shift_query(void); + +int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc); + +int get_bufmap_init(void); + +void pvfs_bufmap_finalize(void); + +int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index); + +void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index); + +int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index); + +void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index); + +int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *iov, + unsigned long nr_segs, + size_t size); + +int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *iov, + unsigned long nr_segs, + size_t size); + +int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *iov, + unsigned long nr_segs, + size_t size); + +int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *iov, + unsigned long nr_segs, + size_t size); + +size_t pvfs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk, + struct iovec *iovec, + unsigned long nr_segs, + struct pvfs2_bufmap *bufmap, + int buffer_index, + size_t bytes_to_be_copied); + +#endif /* __PVFS2_BUFMAP_H */ diff --git a/fs/orangefs/pvfs2-debug.h b/fs/orangefs/pvfs2-debug.h new file mode 100644 index 000000000000..4c27ad77fa16 --- /dev/null +++ b/fs/orangefs/pvfs2-debug.h @@ -0,0 +1,290 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* This file just defines debugging masks to be used with the gossip + * logging utility. All debugging masks for PVFS2 are kept here to make + * sure we don't have collisions. + */ + +#ifndef __PVFS2_DEBUG_H +#define __PVFS2_DEBUG_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#define GOSSIP_NO_DEBUG (__u64)0 +#define GOSSIP_BMI_DEBUG_TCP ((__u64)1 << 0) +#define GOSSIP_BMI_DEBUG_CONTROL ((__u64)1 << 1) +#define GOSSIP_BMI_DEBUG_OFFSETS ((__u64)1 << 2) +#define GOSSIP_BMI_DEBUG_GM ((__u64)1 << 3) +#define GOSSIP_JOB_DEBUG ((__u64)1 << 4) +#define GOSSIP_SERVER_DEBUG ((__u64)1 << 5) +#define GOSSIP_STO_DEBUG_CTRL ((__u64)1 << 6) +#define GOSSIP_STO_DEBUG_DEFAULT ((__u64)1 << 7) +#define GOSSIP_FLOW_DEBUG ((__u64)1 << 8) +#define GOSSIP_BMI_DEBUG_GM_MEM ((__u64)1 << 9) +#define GOSSIP_REQUEST_DEBUG ((__u64)1 << 10) +#define GOSSIP_FLOW_PROTO_DEBUG ((__u64)1 << 11) +#define GOSSIP_NCACHE_DEBUG ((__u64)1 << 12) +#define GOSSIP_CLIENT_DEBUG ((__u64)1 << 13) +#define GOSSIP_REQ_SCHED_DEBUG ((__u64)1 << 14) +#define GOSSIP_ACACHE_DEBUG ((__u64)1 << 15) +#define GOSSIP_TROVE_DEBUG ((__u64)1 << 16) +#define GOSSIP_TROVE_OP_DEBUG ((__u64)1 << 17) +#define GOSSIP_DIST_DEBUG ((__u64)1 << 18) +#define GOSSIP_BMI_DEBUG_IB ((__u64)1 << 19) +#define GOSSIP_DBPF_ATTRCACHE_DEBUG ((__u64)1 << 20) +#define GOSSIP_MMAP_RCACHE_DEBUG ((__u64)1 << 21) +#define GOSSIP_LOOKUP_DEBUG ((__u64)1 << 22) +#define GOSSIP_REMOVE_DEBUG ((__u64)1 << 23) +#define GOSSIP_GETATTR_DEBUG ((__u64)1 << 24) +#define GOSSIP_READDIR_DEBUG ((__u64)1 << 25) +#define GOSSIP_IO_DEBUG ((__u64)1 << 26) +#define GOSSIP_DBPF_OPEN_CACHE_DEBUG ((__u64)1 << 27) +#define GOSSIP_PERMISSIONS_DEBUG ((__u64)1 << 28) +#define GOSSIP_CANCEL_DEBUG ((__u64)1 << 29) +#define GOSSIP_MSGPAIR_DEBUG ((__u64)1 << 30) +#define GOSSIP_CLIENTCORE_DEBUG ((__u64)1 << 31) +#define GOSSIP_CLIENTCORE_TIMING_DEBUG ((__u64)1 << 32) +#define GOSSIP_SETATTR_DEBUG ((__u64)1 << 33) +#define GOSSIP_MKDIR_DEBUG ((__u64)1 << 34) +#define GOSSIP_VARSTRIP_DEBUG ((__u64)1 << 35) +#define GOSSIP_GETEATTR_DEBUG ((__u64)1 << 36) +#define GOSSIP_SETEATTR_DEBUG ((__u64)1 << 37) +#define GOSSIP_ENDECODE_DEBUG ((__u64)1 << 38) +#define GOSSIP_DELEATTR_DEBUG ((__u64)1 << 39) +#define GOSSIP_ACCESS_DEBUG ((__u64)1 << 40) +#define GOSSIP_ACCESS_DETAIL_DEBUG ((__u64)1 << 41) +#define GOSSIP_LISTEATTR_DEBUG ((__u64)1 << 42) +#define GOSSIP_PERFCOUNTER_DEBUG ((__u64)1 << 43) +#define GOSSIP_STATE_MACHINE_DEBUG ((__u64)1 << 44) +#define GOSSIP_DBPF_KEYVAL_DEBUG ((__u64)1 << 45) +#define GOSSIP_LISTATTR_DEBUG ((__u64)1 << 46) +#define GOSSIP_DBPF_COALESCE_DEBUG ((__u64)1 << 47) +#define GOSSIP_ACCESS_HOSTNAMES ((__u64)1 << 48) +#define GOSSIP_FSCK_DEBUG ((__u64)1 << 49) +#define GOSSIP_BMI_DEBUG_MX ((__u64)1 << 50) +#define GOSSIP_BSTREAM_DEBUG ((__u64)1 << 51) +#define GOSSIP_BMI_DEBUG_PORTALS ((__u64)1 << 52) +#define GOSSIP_USER_DEV_DEBUG ((__u64)1 << 53) +#define GOSSIP_DIRECTIO_DEBUG ((__u64)1 << 54) +#define GOSSIP_MGMT_DEBUG ((__u64)1 << 55) +#define GOSSIP_MIRROR_DEBUG ((__u64)1 << 56) +#define GOSSIP_WIN_CLIENT_DEBUG ((__u64)1 << 57) +#define GOSSIP_SECURITY_DEBUG ((__u64)1 << 58) +#define GOSSIP_USRINT_DEBUG ((__u64)1 << 59) +#define GOSSIP_RCACHE_DEBUG ((__u64)1 << 60) +#define GOSSIP_SECCACHE_DEBUG ((__u64)1 << 61) + +#define GOSSIP_BMI_DEBUG_ALL ((__u64) (GOSSIP_BMI_DEBUG_TCP + \ + GOSSIP_BMI_DEBUG_CONTROL + \ + GOSSIP_BMI_DEBUG_GM + \ + GOSSIP_BMI_DEBUG_OFFSETS + \ + GOSSIP_BMI_DEBUG_IB + \ + GOSSIP_BMI_DEBUG_MX + \ + GOSSIP_BMI_DEBUG_PORTALS)) + +const char *PVFS_debug_get_next_debug_keyword(int position); + +#define GOSSIP_SUPER_DEBUG ((__u64)1 << 0) +#define GOSSIP_INODE_DEBUG ((__u64)1 << 1) +#define GOSSIP_FILE_DEBUG ((__u64)1 << 2) +#define GOSSIP_DIR_DEBUG ((__u64)1 << 3) +#define GOSSIP_UTILS_DEBUG ((__u64)1 << 4) +#define GOSSIP_WAIT_DEBUG ((__u64)1 << 5) +#define GOSSIP_ACL_DEBUG ((__u64)1 << 6) +#define GOSSIP_DCACHE_DEBUG ((__u64)1 << 7) +#define GOSSIP_DEV_DEBUG ((__u64)1 << 8) +#define GOSSIP_NAME_DEBUG ((__u64)1 << 9) +#define GOSSIP_BUFMAP_DEBUG ((__u64)1 << 10) +#define GOSSIP_CACHE_DEBUG ((__u64)1 << 11) +#define GOSSIP_DEBUGFS_DEBUG ((__u64)1 << 12) +#define GOSSIP_XATTR_DEBUG ((__u64)1 << 13) +#define GOSSIP_INIT_DEBUG ((__u64)1 << 14) +#define GOSSIP_SYSFS_DEBUG ((__u64)1 << 15) + +#define GOSSIP_MAX_NR 16 +#define GOSSIP_MAX_DEBUG (((__u64)1 << GOSSIP_MAX_NR) - 1) + +/*function prototypes*/ +__u64 PVFS_kmod_eventlog_to_mask(const char *event_logging); +__u64 PVFS_debug_eventlog_to_mask(const char *event_logging); +char *PVFS_debug_mask_to_eventlog(__u64 mask); +char *PVFS_kmod_mask_to_eventlog(__u64 mask); + +/* a private internal type */ +struct __keyword_mask_s { + const char *keyword; + __u64 mask_val; +}; + +#define __DEBUG_ALL ((__u64) -1) + +/* map all config keywords to pvfs2 debug masks here */ +static struct __keyword_mask_s s_keyword_mask_map[] = { + /* Log trove debugging info. Same as 'trove'. */ + {"storage", GOSSIP_TROVE_DEBUG}, + /* Log trove debugging info. Same as 'storage'. */ + {"trove", GOSSIP_TROVE_DEBUG}, + /* Log trove operations. */ + {"trove_op", GOSSIP_TROVE_OP_DEBUG}, + /* Log network debug info. */ + {"network", GOSSIP_BMI_DEBUG_ALL}, + /* Log server info, including new operations. */ + {"server", GOSSIP_SERVER_DEBUG}, + /* Log client sysint info. This is only useful for the client. */ + {"client", GOSSIP_CLIENT_DEBUG}, + /* Debug the varstrip distribution */ + {"varstrip", GOSSIP_VARSTRIP_DEBUG}, + /* Log job info */ + {"job", GOSSIP_JOB_DEBUG}, + /* Debug PINT_process_request calls. EXTREMELY verbose! */ + {"request", GOSSIP_REQUEST_DEBUG}, + /* Log request scheduler events */ + {"reqsched", GOSSIP_REQ_SCHED_DEBUG}, + /* Log the flow protocol events, including flowproto_multiqueue */ + {"flowproto", GOSSIP_FLOW_PROTO_DEBUG}, + /* Log flow calls */ + {"flow", GOSSIP_FLOW_DEBUG}, + /* Debug the client name cache. Only useful on the client. */ + {"ncache", GOSSIP_NCACHE_DEBUG}, + /* Debug read-ahead cache events. Only useful on the client. */ + {"mmaprcache", GOSSIP_MMAP_RCACHE_DEBUG}, + /* Debug the attribute cache. Only useful on the client. */ + {"acache", GOSSIP_ACACHE_DEBUG}, + /* Log/Debug distribution calls */ + {"distribution", GOSSIP_DIST_DEBUG}, + /* Debug the server-side dbpf attribute cache */ + {"dbpfattrcache", GOSSIP_DBPF_ATTRCACHE_DEBUG}, + /* Debug the client lookup state machine. */ + {"lookup", GOSSIP_LOOKUP_DEBUG}, + /* Debug the client remove state macine. */ + {"remove", GOSSIP_REMOVE_DEBUG}, + /* Debug the server getattr state machine. */ + {"getattr", GOSSIP_GETATTR_DEBUG}, + /* Debug the server setattr state machine. */ + {"setattr", GOSSIP_SETATTR_DEBUG}, + /* vectored getattr server state machine */ + {"listattr", GOSSIP_LISTATTR_DEBUG}, + /* Debug the client and server get ext attributes SM. */ + {"geteattr", GOSSIP_GETEATTR_DEBUG}, + /* Debug the client and server set ext attributes SM. */ + {"seteattr", GOSSIP_SETEATTR_DEBUG}, + /* Debug the readdir operation (client and server) */ + {"readdir", GOSSIP_READDIR_DEBUG}, + /* Debug the mkdir operation (server only) */ + {"mkdir", GOSSIP_MKDIR_DEBUG}, + /* Debug the io operation (reads and writes) + * for both the client and server */ + {"io", GOSSIP_IO_DEBUG}, + /* Debug the server's open file descriptor cache */ + {"open_cache", GOSSIP_DBPF_OPEN_CACHE_DEBUG}, + /* Debug permissions checking on the server */ + {"permissions", GOSSIP_PERMISSIONS_DEBUG}, + /* Debug the cancel operation */ + {"cancel", GOSSIP_CANCEL_DEBUG}, + /* Debug the msgpair state machine */ + {"msgpair", GOSSIP_MSGPAIR_DEBUG}, + /* Debug the client core app */ + {"clientcore", GOSSIP_CLIENTCORE_DEBUG}, + /* Debug the client timing state machines (job timeout, etc.) */ + {"clientcore_timing", GOSSIP_CLIENTCORE_TIMING_DEBUG}, + /* network encoding */ + {"endecode", GOSSIP_ENDECODE_DEBUG}, + /* Show server file (metadata) accesses (both modify and read-only). */ + {"access", GOSSIP_ACCESS_DEBUG}, + /* Show more detailed server file accesses */ + {"access_detail", GOSSIP_ACCESS_DETAIL_DEBUG}, + /* Debug the listeattr operation */ + {"listeattr", GOSSIP_LISTEATTR_DEBUG}, + /* Debug the state machine management code */ + {"sm", GOSSIP_STATE_MACHINE_DEBUG}, + /* Debug the metadata dbpf keyval functions */ + {"keyval", GOSSIP_DBPF_KEYVAL_DEBUG}, + /* Debug the metadata sync coalescing code */ + {"coalesce", GOSSIP_DBPF_COALESCE_DEBUG}, + /* Display the hostnames instead of IP addrs in debug output */ + {"access_hostnames", GOSSIP_ACCESS_HOSTNAMES}, + /* Show the client device events */ + {"user_dev", GOSSIP_USER_DEV_DEBUG}, + /* Debug the fsck tool */ + {"fsck", GOSSIP_FSCK_DEBUG}, + /* Debug the bstream code */ + {"bstream", GOSSIP_BSTREAM_DEBUG}, + /* Debug trove in direct io mode */ + {"directio", GOSSIP_DIRECTIO_DEBUG}, + /* Debug direct io thread management */ + {"mgmt", GOSSIP_MGMT_DEBUG}, + /* Debug mirroring process */ + {"mirror", GOSSIP_MIRROR_DEBUG}, + /* Windows client */ + {"win_client", GOSSIP_WIN_CLIENT_DEBUG}, + /* Debug robust security code */ + {"security", GOSSIP_SECURITY_DEBUG}, + /* Capability Cache */ + {"seccache", GOSSIP_SECCACHE_DEBUG}, + /* Client User Interface */ + {"usrint", GOSSIP_USRINT_DEBUG}, + /* rcache */ + {"rcache", GOSSIP_RCACHE_DEBUG}, + /* Everything except the periodic events. Useful for debugging */ + {"verbose", + (__DEBUG_ALL & + ~(GOSSIP_PERFCOUNTER_DEBUG | GOSSIP_STATE_MACHINE_DEBUG | + GOSSIP_ENDECODE_DEBUG | GOSSIP_USER_DEV_DEBUG)) + }, + /* No debug output */ + {"none", GOSSIP_NO_DEBUG}, + /* Everything */ + {"all", __DEBUG_ALL} +}; + +#undef __DEBUG_ALL + +/* + * Map all kmod keywords to kmod debug masks here. Keep this + * structure "packed": + * + * "all" is always last... + * + * keyword mask_val index + * foo 1 0 + * bar 2 1 + * baz 4 2 + * qux 8 3 + * . . . + */ +static struct __keyword_mask_s s_kmod_keyword_mask_map[] = { + {"super", GOSSIP_SUPER_DEBUG}, + {"inode", GOSSIP_INODE_DEBUG}, + {"file", GOSSIP_FILE_DEBUG}, + {"dir", GOSSIP_DIR_DEBUG}, + {"utils", GOSSIP_UTILS_DEBUG}, + {"wait", GOSSIP_WAIT_DEBUG}, + {"acl", GOSSIP_ACL_DEBUG}, + {"dcache", GOSSIP_DCACHE_DEBUG}, + {"dev", GOSSIP_DEV_DEBUG}, + {"name", GOSSIP_NAME_DEBUG}, + {"bufmap", GOSSIP_BUFMAP_DEBUG}, + {"cache", GOSSIP_CACHE_DEBUG}, + {"debugfs", GOSSIP_DEBUGFS_DEBUG}, + {"xattr", GOSSIP_XATTR_DEBUG}, + {"init", GOSSIP_INIT_DEBUG}, + {"sysfs", GOSSIP_SYSFS_DEBUG}, + {"none", GOSSIP_NO_DEBUG}, + {"all", GOSSIP_MAX_DEBUG} +}; + +static const int num_kmod_keyword_mask_map = (int) + (sizeof(s_kmod_keyword_mask_map) / sizeof(struct __keyword_mask_s)); + +static const int num_keyword_mask_map = (int) + (sizeof(s_keyword_mask_map) / sizeof(struct __keyword_mask_s)); + +#endif /* __PVFS2_DEBUG_H */ diff --git a/fs/orangefs/pvfs2-debugfs.h b/fs/orangefs/pvfs2-debugfs.h new file mode 100644 index 000000000000..a66b7d08c14d --- /dev/null +++ b/fs/orangefs/pvfs2-debugfs.h @@ -0,0 +1,3 @@ +int pvfs2_debugfs_init(void); +int pvfs2_kernel_debug_init(void); +void pvfs2_debugfs_cleanup(void); diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/pvfs2-dev-proto.h new file mode 100644 index 000000000000..9c82e6e651f3 --- /dev/null +++ b/fs/orangefs/pvfs2-dev-proto.h @@ -0,0 +1,102 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#ifndef _PVFS2_DEV_PROTO_H +#define _PVFS2_DEV_PROTO_H + +/* + * types and constants shared between user space and kernel space for + * device interaction using a common protocol + */ + +/* + * valid pvfs2 kernel operation types + */ +#define PVFS2_VFS_OP_INVALID 0xFF000000 +#define PVFS2_VFS_OP_FILE_IO 0xFF000001 +#define PVFS2_VFS_OP_LOOKUP 0xFF000002 +#define PVFS2_VFS_OP_CREATE 0xFF000003 +#define PVFS2_VFS_OP_GETATTR 0xFF000004 +#define PVFS2_VFS_OP_REMOVE 0xFF000005 +#define PVFS2_VFS_OP_MKDIR 0xFF000006 +#define PVFS2_VFS_OP_READDIR 0xFF000007 +#define PVFS2_VFS_OP_SETATTR 0xFF000008 +#define PVFS2_VFS_OP_SYMLINK 0xFF000009 +#define PVFS2_VFS_OP_RENAME 0xFF00000A +#define PVFS2_VFS_OP_STATFS 0xFF00000B +#define PVFS2_VFS_OP_TRUNCATE 0xFF00000C +#define PVFS2_VFS_OP_MMAP_RA_FLUSH 0xFF00000D +#define PVFS2_VFS_OP_FS_MOUNT 0xFF00000E +#define PVFS2_VFS_OP_FS_UMOUNT 0xFF00000F +#define PVFS2_VFS_OP_GETXATTR 0xFF000010 +#define PVFS2_VFS_OP_SETXATTR 0xFF000011 +#define PVFS2_VFS_OP_LISTXATTR 0xFF000012 +#define PVFS2_VFS_OP_REMOVEXATTR 0xFF000013 +#define PVFS2_VFS_OP_PARAM 0xFF000014 +#define PVFS2_VFS_OP_PERF_COUNT 0xFF000015 +#define PVFS2_VFS_OP_CANCEL 0xFF00EE00 +#define PVFS2_VFS_OP_FSYNC 0xFF00EE01 +#define PVFS2_VFS_OP_FSKEY 0xFF00EE02 +#define PVFS2_VFS_OP_READDIRPLUS 0xFF00EE03 +#define PVFS2_VFS_OP_FILE_IOX 0xFF00EE04 + +/* + * Misc constants. Please retain them as multiples of 8! + * Otherwise 32-64 bit interactions will be messed up :) + */ +#define PVFS2_NAME_LEN 0x00000100 +#define PVFS2_MAX_DEBUG_STRING_LEN 0x00000400 +#define PVFS2_MAX_DEBUG_ARRAY_LEN 0x00000800 + +/* + * MAX_DIRENT_COUNT cannot be larger than PVFS_REQ_LIMIT_LISTATTR. + * The value of PVFS_REQ_LIMIT_LISTATTR has been changed from 113 to 60 + * to accomodate an attribute object with mirrored handles. + * MAX_DIRENT_COUNT is replaced by MAX_DIRENT_COUNT_READDIR and + * MAX_DIRENT_COUNT_READDIRPLUS, since readdir doesn't trigger a listattr + * but readdirplus might. +*/ +#define MAX_DIRENT_COUNT_READDIR 0x00000060 +#define MAX_DIRENT_COUNT_READDIRPLUS 0x0000003C + +#include "upcall.h" +#include "downcall.h" + +/* + * These macros differ from proto macros in that they don't do any + * byte-swappings and are used to ensure that kernel-clientcore interactions + * don't cause any unaligned accesses etc on 64 bit machines + */ +#ifndef roundup4 +#define roundup4(x) (((x)+3) & ~3) +#endif + +#ifndef roundup8 +#define roundup8(x) (((x)+7) & ~7) +#endif + +/* strings; decoding just points into existing character data */ +#define enc_string(pptr, pbuf) do { \ + __u32 len = strlen(*pbuf); \ + *(__u32 *) *(pptr) = (len); \ + memcpy(*(pptr)+4, *pbuf, len+1); \ + *(pptr) += roundup8(4 + len + 1); \ +} while (0) + +#define dec_string(pptr, pbuf, plen) do { \ + __u32 len = (*(__u32 *) *(pptr)); \ + *pbuf = *(pptr) + 4; \ + *(pptr) += roundup8(4 + len + 1); \ + if (plen) \ + *plen = len;\ +} while (0) + +struct read_write_x { + __s64 off; + __s64 len; +}; + +#endif diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h new file mode 100644 index 000000000000..6c787c4797d0 --- /dev/null +++ b/fs/orangefs/pvfs2-kernel.h @@ -0,0 +1,864 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * The PVFS2 Linux kernel support allows PVFS2 volumes to be mounted and + * accessed through the Linux VFS (i.e. using standard I/O system calls). + * This support is only needed on clients that wish to mount the file system. + * + */ + +/* + * Declarations and macros for the PVFS2 Linux kernel support. + */ + +#ifndef __PVFS2KERNEL_H +#define __PVFS2KERNEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pvfs2-dev-proto.h" + +#ifdef PVFS2_KERNEL_DEBUG +#define PVFS2_DEFAULT_OP_TIMEOUT_SECS 10 +#else +#define PVFS2_DEFAULT_OP_TIMEOUT_SECS 20 +#endif + +#define PVFS2_BUFMAP_WAIT_TIMEOUT_SECS 30 + +#define PVFS2_DEFAULT_SLOT_TIMEOUT_SECS 900 /* 15 minutes */ + +#define PVFS2_REQDEVICE_NAME "pvfs2-req" + +#define PVFS2_DEVREQ_MAGIC 0x20030529 +#define PVFS2_LINK_MAX 0x000000FF +#define PVFS2_PURGE_RETRY_COUNT 0x00000005 +#define PVFS2_SEEK_END 0x00000002 +#define PVFS2_MAX_NUM_OPTIONS 0x00000004 +#define PVFS2_MAX_MOUNT_OPT_LEN 0x00000080 +#define PVFS2_MAX_FSKEY_LEN 64 + +#define MAX_DEV_REQ_UPSIZE (2*sizeof(__s32) + \ +sizeof(__u64) + sizeof(struct pvfs2_upcall_s)) +#define MAX_DEV_REQ_DOWNSIZE (2*sizeof(__s32) + \ +sizeof(__u64) + sizeof(struct pvfs2_downcall_s)) + +#define BITS_PER_LONG_DIV_8 (BITS_PER_LONG >> 3) + +/* borrowed from irda.h */ +#ifndef MSECS_TO_JIFFIES +#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) +#endif + +#define MAX_ALIGNED_DEV_REQ_UPSIZE \ + (MAX_DEV_REQ_UPSIZE + \ + ((((MAX_DEV_REQ_UPSIZE / \ + (BITS_PER_LONG_DIV_8)) * \ + (BITS_PER_LONG_DIV_8)) + \ + (BITS_PER_LONG_DIV_8)) - \ + MAX_DEV_REQ_UPSIZE)) + +#define MAX_ALIGNED_DEV_REQ_DOWNSIZE \ + (MAX_DEV_REQ_DOWNSIZE + \ + ((((MAX_DEV_REQ_DOWNSIZE / \ + (BITS_PER_LONG_DIV_8)) * \ + (BITS_PER_LONG_DIV_8)) + \ + (BITS_PER_LONG_DIV_8)) - \ + MAX_DEV_REQ_DOWNSIZE)) + +/* + * valid pvfs2 kernel operation states + * + * unknown - op was just initialized + * waiting - op is on request_list (upward bound) + * inprogr - op is in progress (waiting for downcall) + * serviced - op has matching downcall; ok + * purged - op has to start a timer since client-core + * exited uncleanly before servicing op + */ +enum pvfs2_vfs_op_states { + OP_VFS_STATE_UNKNOWN = 0, + OP_VFS_STATE_WAITING = 1, + OP_VFS_STATE_INPROGR = 2, + OP_VFS_STATE_SERVICED = 4, + OP_VFS_STATE_PURGED = 8, +}; + +#define set_op_state_waiting(op) ((op)->op_state = OP_VFS_STATE_WAITING) +#define set_op_state_inprogress(op) ((op)->op_state = OP_VFS_STATE_INPROGR) +#define set_op_state_serviced(op) ((op)->op_state = OP_VFS_STATE_SERVICED) +#define set_op_state_purged(op) ((op)->op_state |= OP_VFS_STATE_PURGED) + +#define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING) +#define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR) +#define op_state_serviced(op) ((op)->op_state & OP_VFS_STATE_SERVICED) +#define op_state_purged(op) ((op)->op_state & OP_VFS_STATE_PURGED) + +#define get_op(op) \ + do { \ + atomic_inc(&(op)->aio_ref_count); \ + gossip_debug(GOSSIP_DEV_DEBUG, \ + "(get) Alloced OP (%p:%llu)\n", \ + op, \ + llu((op)->tag)); \ + } while (0) + +#define put_op(op) \ + do { \ + if (atomic_sub_and_test(1, &(op)->aio_ref_count) == 1) { \ + gossip_debug(GOSSIP_DEV_DEBUG, \ + "(put) Releasing OP (%p:%llu)\n", \ + op, \ + llu((op)->tag)); \ + op_release(op); \ + } \ + } while (0) + +#define op_wait(op) (atomic_read(&(op)->aio_ref_count) <= 2 ? 0 : 1) + +/* + * Defines for controlling whether I/O upcalls are for async or sync operations + */ +enum PVFS_async_io_type { + PVFS_VFS_SYNC_IO = 0, + PVFS_VFS_ASYNC_IO = 1, +}; + +/* + * An array of client_debug_mask will be built to hold debug keyword/mask + * values fetched from userspace. + */ +struct client_debug_mask { + char *keyword; + __u64 mask1; + __u64 mask2; +}; + +/* + * pvfs2 kernel memory related flags + */ + +#if ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) +#define PVFS2_CACHE_CREATE_FLAGS SLAB_RED_ZONE +#else +#define PVFS2_CACHE_CREATE_FLAGS 0 +#endif /* ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */ + +#define PVFS2_CACHE_ALLOC_FLAGS (GFP_KERNEL) +#define PVFS2_GFP_FLAGS (GFP_KERNEL) +#define PVFS2_BUFMAP_GFP_FLAGS (GFP_KERNEL) + +#define pvfs2_kmap(page) kmap(page) +#define pvfs2_kunmap(page) kunmap(page) + +/* pvfs2 xattr and acl related defines */ +#define PVFS2_XATTR_INDEX_POSIX_ACL_ACCESS 1 +#define PVFS2_XATTR_INDEX_POSIX_ACL_DEFAULT 2 +#define PVFS2_XATTR_INDEX_TRUSTED 3 +#define PVFS2_XATTR_INDEX_DEFAULT 4 + +#if 0 +#ifndef POSIX_ACL_XATTR_ACCESS +#define POSIX_ACL_XATTR_ACCESS "system.posix_acl_access" +#endif +#ifndef POSIX_ACL_XATTR_DEFAULT +#define POSIX_ACL_XATTR_DEFAULT "system.posix_acl_default" +#endif +#endif + +#define PVFS2_XATTR_NAME_ACL_ACCESS POSIX_ACL_XATTR_ACCESS +#define PVFS2_XATTR_NAME_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT +#define PVFS2_XATTR_NAME_TRUSTED_PREFIX "trusted." +#define PVFS2_XATTR_NAME_DEFAULT_PREFIX "" + +/* these functions are defined in pvfs2-utils.c */ +int orangefs_prepare_cdm_array(char *debug_array_string); +int orangefs_prepare_debugfs_help_string(int); + +/* defined in pvfs2-debugfs.c */ +int pvfs2_client_debug_init(void); + +void debug_string_to_mask(char *, void *, int); +void do_c_mask(int, char *, struct client_debug_mask **); +void do_k_mask(int, char *, __u64 **); + +void debug_mask_to_string(void *, int); +void do_k_string(void *, int); +void do_c_string(void *, int); +int check_amalgam_keyword(void *, int); +int keyword_is_amalgam(char *); + +/*these variables are defined in pvfs2-mod.c */ +extern char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; +extern char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; +extern char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN]; +/* HELLO +extern struct client_debug_mask current_client_mask; +*/ +extern unsigned int kernel_mask_set_mod_init; + +extern int pvfs2_init_acl(struct inode *inode, struct inode *dir); +extern const struct xattr_handler *pvfs2_xattr_handlers[]; + +extern struct posix_acl *pvfs2_get_acl(struct inode *inode, int type); +extern int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); + +int pvfs2_xattr_set_default(struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags, + int handler_flags); + +int pvfs2_xattr_get_default(struct dentry *dentry, + const char *name, + void *buffer, + size_t size, + int handler_flags); + +/* + * Redefine xtvec structure so that we could move helper functions out of + * the define + */ +struct xtvec { + __kernel_off_t xtv_off; /* must be off_t */ + __kernel_size_t xtv_len; /* must be size_t */ +}; + +/* + * pvfs2 data structures + */ +struct pvfs2_kernel_op_s { + enum pvfs2_vfs_op_states op_state; + __u64 tag; + + /* + * Set uses_shared_memory to 1 if this operation uses shared memory. + * If true, then a retry on the op must also get a new shared memory + * buffer and re-populate it. + */ + int uses_shared_memory; + + struct pvfs2_upcall_s upcall; + struct pvfs2_downcall_s downcall; + + wait_queue_head_t waitq; + spinlock_t lock; + + int io_completed; + wait_queue_head_t io_completion_waitq; + + /* + * upcalls requiring variable length trailers require that this struct + * be in the request list even after client-core does a read() on the + * device to dequeue the upcall. + * if op_linger field goes to 0, we dequeue this op off the list. + * else we let it stay. What gets passed to the read() is + * a) if op_linger field is = 1, pvfs2_kernel_op_s itself + * b) else if = 0, we pass ->upcall.trailer_buf + * We expect to have only a single upcall trailer buffer, + * so we expect callers with trailers + * to set this field to 2 and others to set it to 1. + */ + __s32 op_linger, op_linger_tmp; + /* VFS aio fields */ + + /* used by the async I/O code to stash the pvfs2_kiocb_s structure */ + void *priv; + + /* used again for the async I/O code for deallocation */ + atomic_t aio_ref_count; + + int attempts; + + struct list_head list; +}; + +/* per inode private pvfs2 info */ +struct pvfs2_inode_s { + struct pvfs2_object_kref refn; + char link_target[PVFS_NAME_MAX]; + __s64 blksize; + /* + * Reading/Writing Extended attributes need to acquire the appropriate + * reader/writer semaphore on the pvfs2_inode_s structure. + */ + struct rw_semaphore xattr_sem; + + struct inode vfs_inode; + sector_t last_failed_block_index_read; + + /* + * State of in-memory attributes not yet flushed to disk associated + * with this object + */ + unsigned long pinode_flags; + + /* All allocated pvfs2_inode_s objects are chained to a list */ + struct list_head list; +}; + +#define P_ATIME_FLAG 0 +#define P_MTIME_FLAG 1 +#define P_CTIME_FLAG 2 +#define P_MODE_FLAG 3 + +#define ClearAtimeFlag(pinode) clear_bit(P_ATIME_FLAG, &(pinode)->pinode_flags) +#define SetAtimeFlag(pinode) set_bit(P_ATIME_FLAG, &(pinode)->pinode_flags) +#define AtimeFlag(pinode) test_bit(P_ATIME_FLAG, &(pinode)->pinode_flags) + +#define ClearMtimeFlag(pinode) clear_bit(P_MTIME_FLAG, &(pinode)->pinode_flags) +#define SetMtimeFlag(pinode) set_bit(P_MTIME_FLAG, &(pinode)->pinode_flags) +#define MtimeFlag(pinode) test_bit(P_MTIME_FLAG, &(pinode)->pinode_flags) + +#define ClearCtimeFlag(pinode) clear_bit(P_CTIME_FLAG, &(pinode)->pinode_flags) +#define SetCtimeFlag(pinode) set_bit(P_CTIME_FLAG, &(pinode)->pinode_flags) +#define CtimeFlag(pinode) test_bit(P_CTIME_FLAG, &(pinode)->pinode_flags) + +#define ClearModeFlag(pinode) clear_bit(P_MODE_FLAG, &(pinode)->pinode_flags) +#define SetModeFlag(pinode) set_bit(P_MODE_FLAG, &(pinode)->pinode_flags) +#define ModeFlag(pinode) test_bit(P_MODE_FLAG, &(pinode)->pinode_flags) + +/* per superblock private pvfs2 info */ +struct pvfs2_sb_info_s { + struct pvfs2_khandle root_khandle; + __s32 fs_id; + int id; + int flags; +#define PVFS2_OPT_INTR 0x01 +#define PVFS2_OPT_LOCAL_LOCK 0x02 + char devname[PVFS_MAX_SERVER_ADDR_LEN]; + struct super_block *sb; + int mount_pending; + struct list_head list; +}; + +/* + * a temporary structure used only for sb mount time that groups the + * mount time data provided along with a private superblock structure + * that is allocated before a 'kernel' superblock is allocated. +*/ +struct pvfs2_mount_sb_info_s { + void *data; + struct pvfs2_khandle root_khandle; + __s32 fs_id; + int id; +}; + +/* + * structure that holds the state of any async I/O operation issued + * through the VFS. Needed especially to handle cancellation requests + * or even completion notification so that the VFS client-side daemon + * can free up its vfs_request slots. + */ +struct pvfs2_kiocb_s { + /* the pointer to the task that initiated the AIO */ + struct task_struct *tsk; + + /* pointer to the kiocb that kicked this operation */ + struct kiocb *kiocb; + + /* buffer index that was used for the I/O */ + struct pvfs2_bufmap *bufmap; + int buffer_index; + + /* pvfs2 kernel operation type */ + struct pvfs2_kernel_op_s *op; + + /* The user space buffers from/to which I/O is being staged */ + struct iovec *iov; + + /* number of elements in the iovector */ + unsigned long nr_segs; + + /* set to indicate the type of the operation */ + int rw; + + /* file offset */ + loff_t offset; + + /* and the count in bytes */ + size_t bytes_to_be_copied; + + ssize_t bytes_copied; + int needs_cleanup; +}; + +struct pvfs2_stats { + unsigned long cache_hits; + unsigned long cache_misses; + unsigned long reads; + unsigned long writes; +}; + +extern struct pvfs2_stats g_pvfs2_stats; + +/* + NOTE: See Documentation/filesystems/porting for information + on implementing FOO_I and properly accessing fs private data +*/ +static inline struct pvfs2_inode_s *PVFS2_I(struct inode *inode) +{ + return container_of(inode, struct pvfs2_inode_s, vfs_inode); +} + +static inline struct pvfs2_sb_info_s *PVFS2_SB(struct super_block *sb) +{ + return (struct pvfs2_sb_info_s *) sb->s_fs_info; +} + +/* ino_t descends from "unsigned long", 8 bytes, 64 bits. */ +static inline ino_t pvfs2_khandle_to_ino(struct pvfs2_khandle *khandle) +{ + union { + unsigned char u[8]; + __u64 ino; + } ihandle; + + ihandle.u[0] = khandle->u[0] ^ khandle->u[4]; + ihandle.u[1] = khandle->u[1] ^ khandle->u[5]; + ihandle.u[2] = khandle->u[2] ^ khandle->u[6]; + ihandle.u[3] = khandle->u[3] ^ khandle->u[7]; + ihandle.u[4] = khandle->u[12] ^ khandle->u[8]; + ihandle.u[5] = khandle->u[13] ^ khandle->u[9]; + ihandle.u[6] = khandle->u[14] ^ khandle->u[10]; + ihandle.u[7] = khandle->u[15] ^ khandle->u[11]; + + return ihandle.ino; +} + +static inline struct pvfs2_khandle *get_khandle_from_ino(struct inode *inode) +{ + return &(PVFS2_I(inode)->refn.khandle); +} + +static inline __s32 get_fsid_from_ino(struct inode *inode) +{ + return PVFS2_I(inode)->refn.fs_id; +} + +static inline ino_t get_ino_from_khandle(struct inode *inode) +{ + struct pvfs2_khandle *khandle; + ino_t ino; + + khandle = get_khandle_from_ino(inode); + ino = pvfs2_khandle_to_ino(khandle); + return ino; +} + +static inline ino_t get_parent_ino_from_dentry(struct dentry *dentry) +{ + return get_ino_from_khandle(dentry->d_parent->d_inode); +} + +static inline int is_root_handle(struct inode *inode) +{ + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: root handle: %pU, this handle: %pU:\n", + __func__, + &PVFS2_SB(inode->i_sb)->root_khandle, + get_khandle_from_ino(inode)); + + if (PVFS_khandle_cmp(&(PVFS2_SB(inode->i_sb)->root_khandle), + get_khandle_from_ino(inode))) + return 0; + else + return 1; +} + +static inline int match_handle(struct pvfs2_khandle resp_handle, + struct inode *inode) +{ + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: one handle: %pU, another handle:%pU:\n", + __func__, + &resp_handle, + get_khandle_from_ino(inode)); + + if (PVFS_khandle_cmp(&resp_handle, get_khandle_from_ino(inode))) + return 0; + else + return 1; +} + +/* + * defined in pvfs2-cache.c + */ +int op_cache_initialize(void); +int op_cache_finalize(void); +struct pvfs2_kernel_op_s *op_alloc(__s32 type); +struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type); +char *get_opname_string(struct pvfs2_kernel_op_s *new_op); +void op_release(struct pvfs2_kernel_op_s *op); + +int dev_req_cache_initialize(void); +int dev_req_cache_finalize(void); +void *dev_req_alloc(void); +void dev_req_release(void *); + +int pvfs2_inode_cache_initialize(void); +int pvfs2_inode_cache_finalize(void); + +int kiocb_cache_initialize(void); +int kiocb_cache_finalize(void); +struct pvfs2_kiocb_s *kiocb_alloc(void); +void kiocb_release(struct pvfs2_kiocb_s *ptr); + +/* + * defined in pvfs2-mod.c + */ +void purge_inprogress_ops(void); + +/* + * defined in waitqueue.c + */ +int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op); +int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op); +void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op); +void purge_waiting_ops(void); + +/* + * defined in super.c + */ +struct dentry *pvfs2_mount(struct file_system_type *fst, + int flags, + const char *devname, + void *data); + +void pvfs2_kill_sb(struct super_block *sb); +int pvfs2_remount(struct super_block *sb); + +int fsid_key_table_initialize(void); +void fsid_key_table_finalize(void); + +/* + * defined in inode.c + */ +__u32 convert_to_pvfs2_mask(unsigned long lite_mask); +struct inode *pvfs2_new_inode(struct super_block *sb, + struct inode *dir, + int mode, + dev_t dev, + struct pvfs2_object_kref *ref); + +int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr); + +int pvfs2_getattr(struct vfsmount *mnt, + struct dentry *dentry, + struct kstat *kstat); + +/* + * defined in xattr.c + */ +int pvfs2_setxattr(struct dentry *dentry, + const char *name, + const void *value, + size_t size, + int flags); + +ssize_t pvfs2_getxattr(struct dentry *dentry, + const char *name, + void *buffer, + size_t size); + +ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size); + +/* + * defined in namei.c + */ +struct inode *pvfs2_iget(struct super_block *sb, + struct pvfs2_object_kref *ref); + +ssize_t pvfs2_inode_read(struct inode *inode, + char *buf, + size_t count, + loff_t *offset, + loff_t readahead_size); + +/* + * defined in devpvfs2-req.c + */ +int pvfs2_dev_init(void); +void pvfs2_dev_cleanup(void); +int is_daemon_in_service(void); +int fs_mount_pending(__s32 fsid); + +/* + * defined in pvfs2-utils.c + */ +__s32 fsid_of_op(struct pvfs2_kernel_op_s *op); + +int pvfs2_flush_inode(struct inode *inode); + +ssize_t pvfs2_inode_getxattr(struct inode *inode, + const char *prefix, + const char *name, + void *buffer, + size_t size); + +int pvfs2_inode_setxattr(struct inode *inode, + const char *prefix, + const char *name, + const void *value, + size_t size, + int flags); + +int pvfs2_inode_getattr(struct inode *inode, __u32 mask); + +int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr); + +void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op); + +void pvfs2_make_bad_inode(struct inode *inode); + +void mask_blocked_signals(sigset_t *orig_sigset); + +void unmask_blocked_signals(sigset_t *orig_sigset); + +int pvfs2_unmount_sb(struct super_block *sb); + +int pvfs2_cancel_op_in_progress(__u64 tag); + +__u64 pvfs2_convert_time_field(void *time_ptr); + +int pvfs2_normalize_to_errno(__s32 error_code); + +extern struct mutex devreq_mutex; +extern struct mutex request_mutex; +extern int debug; +extern int op_timeout_secs; +extern int slot_timeout_secs; +extern struct list_head pvfs2_superblocks; +extern spinlock_t pvfs2_superblocks_lock; +extern struct list_head pvfs2_request_list; +extern spinlock_t pvfs2_request_list_lock; +extern wait_queue_head_t pvfs2_request_list_waitq; +extern struct list_head *htable_ops_in_progress; +extern spinlock_t htable_ops_in_progress_lock; +extern int hash_table_size; + +extern const struct address_space_operations pvfs2_address_operations; +extern struct backing_dev_info pvfs2_backing_dev_info; +extern struct inode_operations pvfs2_file_inode_operations; +extern const struct file_operations pvfs2_file_operations; +extern struct inode_operations pvfs2_symlink_inode_operations; +extern struct inode_operations pvfs2_dir_inode_operations; +extern const struct file_operations pvfs2_dir_operations; +extern const struct dentry_operations pvfs2_dentry_operations; +extern const struct file_operations pvfs2_devreq_file_operations; + +extern wait_queue_head_t pvfs2_bufmap_init_waitq; + +/* + * misc convenience macros + */ +#define add_op_to_request_list(op) \ +do { \ + spin_lock(&pvfs2_request_list_lock); \ + spin_lock(&op->lock); \ + set_op_state_waiting(op); \ + list_add_tail(&op->list, &pvfs2_request_list); \ + spin_unlock(&pvfs2_request_list_lock); \ + spin_unlock(&op->lock); \ + wake_up_interruptible(&pvfs2_request_list_waitq); \ +} while (0) + +#define add_priority_op_to_request_list(op) \ + do { \ + spin_lock(&pvfs2_request_list_lock); \ + spin_lock(&op->lock); \ + set_op_state_waiting(op); \ + \ + list_add(&op->list, &pvfs2_request_list); \ + spin_unlock(&pvfs2_request_list_lock); \ + spin_unlock(&op->lock); \ + wake_up_interruptible(&pvfs2_request_list_waitq); \ +} while (0) + +#define remove_op_from_request_list(op) \ + do { \ + struct list_head *tmp = NULL; \ + struct list_head *tmp_safe = NULL; \ + struct pvfs2_kernel_op_s *tmp_op = NULL; \ + \ + spin_lock(&pvfs2_request_list_lock); \ + list_for_each_safe(tmp, tmp_safe, &pvfs2_request_list) { \ + tmp_op = list_entry(tmp, \ + struct pvfs2_kernel_op_s, \ + list); \ + if (tmp_op && (tmp_op == op)) { \ + list_del(&tmp_op->list); \ + break; \ + } \ + } \ + spin_unlock(&pvfs2_request_list_lock); \ + } while (0) + +#define PVFS2_OP_INTERRUPTIBLE 1 /* service_operation() is interruptible */ +#define PVFS2_OP_PRIORITY 2 /* service_operation() is high priority */ +#define PVFS2_OP_CANCELLATION 4 /* this is a cancellation */ +#define PVFS2_OP_NO_SEMAPHORE 8 /* don't acquire semaphore */ +#define PVFS2_OP_ASYNC 16 /* Queue it, but don't wait */ + +int service_operation(struct pvfs2_kernel_op_s *op, + const char *op_name, + int flags); + +/* + * handles two possible error cases, depending on context. + * + * by design, our vfs i/o errors need to be handled in one of two ways, + * depending on where the error occured. + * + * if the error happens in the waitqueue code because we either timed + * out or a signal was raised while waiting, we need to cancel the + * userspace i/o operation and free the op manually. this is done to + * avoid having the device start writing application data to our shared + * bufmap pages without us expecting it. + * + * FIXME: POSSIBLE OPTIMIZATION: + * However, if we timed out or if we got a signal AND our upcall was never + * picked off the queue (i.e. we were in OP_VFS_STATE_WAITING), then we don't + * need to send a cancellation upcall. The way we can handle this is + * set error_exit to 2 in such cases and 1 whenever cancellation has to be + * sent and have handle_error + * take care of this situation as well.. + * + * if a pvfs2 sysint level error occured and i/o has been completed, + * there is no need to cancel the operation, as the user has finished + * using the bufmap page and so there is no danger in this case. in + * this case, we wake up the device normally so that it may free the + * op, as normal. + * + * note the only reason this is a macro is because both read and write + * cases need the exact same handling code. + */ +#define handle_io_error() \ +do { \ + if (!op_state_serviced(new_op)) { \ + pvfs2_cancel_op_in_progress(new_op->tag); \ + op_release(new_op); \ + } else { \ + wake_up_daemon_for_return(new_op); \ + } \ + new_op = NULL; \ + pvfs_bufmap_put(bufmap, buffer_index); \ + buffer_index = -1; \ +} while (0) + +#define get_interruptible_flag(inode) \ + ((PVFS2_SB(inode->i_sb)->flags & PVFS2_OPT_INTR) ? \ + PVFS2_OP_INTERRUPTIBLE : 0) + +#define add_pvfs2_sb(sb) \ +do { \ + gossip_debug(GOSSIP_SUPER_DEBUG, \ + "Adding SB %p to pvfs2 superblocks\n", \ + PVFS2_SB(sb)); \ + spin_lock(&pvfs2_superblocks_lock); \ + list_add_tail(&PVFS2_SB(sb)->list, &pvfs2_superblocks); \ + spin_unlock(&pvfs2_superblocks_lock); \ +} while (0) + +#define remove_pvfs2_sb(sb) \ +do { \ + struct list_head *tmp = NULL; \ + struct list_head *tmp_safe = NULL; \ + struct pvfs2_sb_info_s *pvfs2_sb = NULL; \ + \ + spin_lock(&pvfs2_superblocks_lock); \ + list_for_each_safe(tmp, tmp_safe, &pvfs2_superblocks) { \ + pvfs2_sb = list_entry(tmp, \ + struct pvfs2_sb_info_s, \ + list); \ + if (pvfs2_sb && (pvfs2_sb->sb == sb)) { \ + gossip_debug(GOSSIP_SUPER_DEBUG, \ + "Removing SB %p from pvfs2 superblocks\n", \ + pvfs2_sb); \ + list_del(&pvfs2_sb->list); \ + break; \ + } \ + } \ + spin_unlock(&pvfs2_superblocks_lock); \ +} while (0) + +#define pvfs2_lock_inode(inode) spin_lock(&inode->i_lock) +#define pvfs2_unlock_inode(inode) spin_unlock(&inode->i_lock) +#define pvfs2_current_signal_lock current->sighand->siglock +#define pvfs2_current_sigaction current->sighand->action + +#define fill_default_sys_attrs(sys_attr, type, mode) \ +do { \ + sys_attr.owner = from_kuid(current_user_ns(), current_fsuid()); \ + sys_attr.group = from_kgid(current_user_ns(), current_fsgid()); \ + sys_attr.size = 0; \ + sys_attr.perms = PVFS_util_translate_mode(mode); \ + sys_attr.objtype = type; \ + sys_attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; \ +} while (0) + +#define pvfs2_inode_lock(__i) mutex_lock(&(__i)->i_mutex) + +#define pvfs2_inode_unlock(__i) mutex_unlock(&(__i)->i_mutex) + +static inline void pvfs2_i_size_write(struct inode *inode, loff_t i_size) +{ +#if BITS_PER_LONG == 32 && defined(CONFIG_SMP) + pvfs2_inode_lock(inode); +#endif + i_size_write(inode, i_size); +#if BITS_PER_LONG == 32 && defined(CONFIG_SMP) + pvfs2_inode_unlock(inode); +#endif +} + +static inline unsigned int diff(struct timeval *end, struct timeval *begin) +{ + if (end->tv_usec < begin->tv_usec) { + end->tv_usec += 1000000; + end->tv_sec--; + } + end->tv_sec -= begin->tv_sec; + end->tv_usec -= begin->tv_usec; + return (end->tv_sec * 1000000) + end->tv_usec; +} + +#endif /* __PVFS2KERNEL_H */ diff --git a/fs/orangefs/pvfs2-sysfs.h b/fs/orangefs/pvfs2-sysfs.h new file mode 100644 index 000000000000..f0b76382db02 --- /dev/null +++ b/fs/orangefs/pvfs2-sysfs.h @@ -0,0 +1,2 @@ +extern int orangefs_sysfs_init(void); +extern void orangefs_sysfs_exit(void); diff --git a/fs/orangefs/upcall.h b/fs/orangefs/upcall.h new file mode 100644 index 000000000000..1e07f626aac6 --- /dev/null +++ b/fs/orangefs/upcall.h @@ -0,0 +1,255 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#ifndef __UPCALL_H +#define __UPCALL_H + +/* + * Sanitized this header file to fix + * 32-64 bit interaction issues between + * client-core and device + */ +struct pvfs2_io_request_s { + __s32 async_vfs_io; + __s32 buf_index; + __s32 count; + __s32 __pad1; + __s64 offset; + struct pvfs2_object_kref refn; + enum PVFS_io_type io_type; + __s32 readahead_size; +}; + +struct pvfs2_iox_request_s { + __s32 buf_index; + __s32 count; + struct pvfs2_object_kref refn; + enum PVFS_io_type io_type; + __s32 __pad1; +}; + +struct pvfs2_lookup_request_s { + __s32 sym_follow; + __s32 __pad1; + struct pvfs2_object_kref parent_refn; + char d_name[PVFS2_NAME_LEN]; +}; + +struct pvfs2_create_request_s { + struct pvfs2_object_kref parent_refn; + struct PVFS_sys_attr_s attributes; + char d_name[PVFS2_NAME_LEN]; +}; + +struct pvfs2_symlink_request_s { + struct pvfs2_object_kref parent_refn; + struct PVFS_sys_attr_s attributes; + char entry_name[PVFS2_NAME_LEN]; + char target[PVFS2_NAME_LEN]; +}; + +struct pvfs2_getattr_request_s { + struct pvfs2_object_kref refn; + __u32 mask; + __u32 __pad1; +}; + +struct pvfs2_setattr_request_s { + struct pvfs2_object_kref refn; + struct PVFS_sys_attr_s attributes; +}; + +struct pvfs2_remove_request_s { + struct pvfs2_object_kref parent_refn; + char d_name[PVFS2_NAME_LEN]; +}; + +struct pvfs2_mkdir_request_s { + struct pvfs2_object_kref parent_refn; + struct PVFS_sys_attr_s attributes; + char d_name[PVFS2_NAME_LEN]; +}; + +struct pvfs2_readdir_request_s { + struct pvfs2_object_kref refn; + __u64 token; + __s32 max_dirent_count; + __s32 buf_index; +}; + +struct pvfs2_readdirplus_request_s { + struct pvfs2_object_kref refn; + __u64 token; + __s32 max_dirent_count; + __u32 mask; + __s32 buf_index; + __s32 __pad1; +}; + +struct pvfs2_rename_request_s { + struct pvfs2_object_kref old_parent_refn; + struct pvfs2_object_kref new_parent_refn; + char d_old_name[PVFS2_NAME_LEN]; + char d_new_name[PVFS2_NAME_LEN]; +}; + +struct pvfs2_statfs_request_s { + __s32 fs_id; + __s32 __pad1; +}; + +struct pvfs2_truncate_request_s { + struct pvfs2_object_kref refn; + __s64 size; +}; + +struct pvfs2_mmap_ra_cache_flush_request_s { + struct pvfs2_object_kref refn; +}; + +struct pvfs2_fs_mount_request_s { + char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN]; +}; + +struct pvfs2_fs_umount_request_s { + __s32 id; + __s32 fs_id; + char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN]; +}; + +struct pvfs2_getxattr_request_s { + struct pvfs2_object_kref refn; + __s32 key_sz; + __s32 __pad1; + char key[PVFS_MAX_XATTR_NAMELEN]; +}; + +struct pvfs2_setxattr_request_s { + struct pvfs2_object_kref refn; + struct PVFS_keyval_pair keyval; + __s32 flags; + __s32 __pad1; +}; + +struct pvfs2_listxattr_request_s { + struct pvfs2_object_kref refn; + __s32 requested_count; + __s32 __pad1; + __u64 token; +}; + +struct pvfs2_removexattr_request_s { + struct pvfs2_object_kref refn; + __s32 key_sz; + __s32 __pad1; + char key[PVFS_MAX_XATTR_NAMELEN]; +}; + +struct pvfs2_op_cancel_s { + __u64 op_tag; +}; + +struct pvfs2_fsync_request_s { + struct pvfs2_object_kref refn; +}; + +enum pvfs2_param_request_type { + PVFS2_PARAM_REQUEST_SET = 1, + PVFS2_PARAM_REQUEST_GET = 2 +}; + +enum pvfs2_param_request_op { + PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS = 1, + PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT = 2, + PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT = 3, + PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE = 4, + PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS = 5, + PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE = 6, + PVFS2_PARAM_REQUEST_OP_PERF_RESET = 7, + PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS = 8, + PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT = 9, + PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT = 10, + PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE = 11, + PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_TIMEOUT_MSECS = 12, + PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_HARD_LIMIT = 13, + PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_SOFT_LIMIT = 14, + PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_RECLAIM_PERCENTAGE = 15, + PVFS2_PARAM_REQUEST_OP_CLIENT_DEBUG = 16, + PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS = 17, + PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT = 18, + PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT = 19, + PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE = 20, + PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS = 21, + PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT = 22, + PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT = 23, + PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE = 24, + PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES = 25, +}; + +struct pvfs2_param_request_s { + enum pvfs2_param_request_type type; + enum pvfs2_param_request_op op; + __s64 value; + char s_value[PVFS2_MAX_DEBUG_STRING_LEN]; +}; + +enum pvfs2_perf_count_request_type { + PVFS2_PERF_COUNT_REQUEST_ACACHE = 1, + PVFS2_PERF_COUNT_REQUEST_NCACHE = 2, + PVFS2_PERF_COUNT_REQUEST_CAPCACHE = 3, +}; + +struct pvfs2_perf_count_request_s { + enum pvfs2_perf_count_request_type type; + __s32 __pad1; +}; + +struct pvfs2_fs_key_request_s { + __s32 fsid; + __s32 __pad1; +}; + +struct pvfs2_upcall_s { + __s32 type; + __u32 uid; + __u32 gid; + int pid; + int tgid; + /* currently trailer is used only by readx/writex (iox) */ + __s64 trailer_size; + char *trailer_buf; + + union { + struct pvfs2_io_request_s io; + struct pvfs2_iox_request_s iox; + struct pvfs2_lookup_request_s lookup; + struct pvfs2_create_request_s create; + struct pvfs2_symlink_request_s sym; + struct pvfs2_getattr_request_s getattr; + struct pvfs2_setattr_request_s setattr; + struct pvfs2_remove_request_s remove; + struct pvfs2_mkdir_request_s mkdir; + struct pvfs2_readdir_request_s readdir; + struct pvfs2_readdirplus_request_s readdirplus; + struct pvfs2_rename_request_s rename; + struct pvfs2_statfs_request_s statfs; + struct pvfs2_truncate_request_s truncate; + struct pvfs2_mmap_ra_cache_flush_request_s ra_cache_flush; + struct pvfs2_fs_mount_request_s fs_mount; + struct pvfs2_fs_umount_request_s fs_umount; + struct pvfs2_getxattr_request_s getxattr; + struct pvfs2_setxattr_request_s setxattr; + struct pvfs2_listxattr_request_s listxattr; + struct pvfs2_removexattr_request_s removexattr; + struct pvfs2_op_cancel_s cancel; + struct pvfs2_fsync_request_s fsync; + struct pvfs2_param_request_s param; + struct pvfs2_perf_count_request_s perf_count; + struct pvfs2_fs_key_request_s fs_key; + } req; +}; + +#endif /* __UPCALL_H */ -- GitLab From 5db11c21a929cd9d8c0484006efb1014fc723c93 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:12 -0400 Subject: [PATCH 0002/5324] Orangefs: kernel client part 2 Signed-off-by: Mike Marshall --- fs/orangefs/acl.c | 175 +++++++ fs/orangefs/dcache.c | 142 +++++ fs/orangefs/devpvfs2-req.c | 997 +++++++++++++++++++++++++++++++++++ fs/orangefs/dir.c | 394 ++++++++++++++ fs/orangefs/file.c | 1019 ++++++++++++++++++++++++++++++++++++ fs/orangefs/inode.c | 469 +++++++++++++++++ 6 files changed, 3196 insertions(+) create mode 100644 fs/orangefs/acl.c create mode 100644 fs/orangefs/dcache.c create mode 100644 fs/orangefs/devpvfs2-req.c create mode 100644 fs/orangefs/dir.c create mode 100644 fs/orangefs/file.c create mode 100644 fs/orangefs/inode.c diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c new file mode 100644 index 000000000000..e462b81a3ba1 --- /dev/null +++ b/fs/orangefs/acl.c @@ -0,0 +1,175 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" +#include +#include + +struct posix_acl *pvfs2_get_acl(struct inode *inode, int type) +{ + struct posix_acl *acl; + int ret; + char *key = NULL, *value = NULL; + + switch (type) { + case ACL_TYPE_ACCESS: + key = PVFS2_XATTR_NAME_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + key = PVFS2_XATTR_NAME_ACL_DEFAULT; + break; + default: + gossip_err("pvfs2_get_acl: bogus value of type %d\n", type); + return ERR_PTR(-EINVAL); + } + /* + * Rather than incurring a network call just to determine the exact + * length of the attribute, I just allocate a max length to save on + * the network call. Conceivably, we could pass NULL to + * pvfs2_inode_getxattr() to probe the length of the value, but + * I don't do that for now. + */ + value = kmalloc(PVFS_MAX_XATTR_VALUELEN, GFP_KERNEL); + if (value == NULL) + return ERR_PTR(-ENOMEM); + + gossip_debug(GOSSIP_ACL_DEBUG, + "inode %pU, key %s, type %d\n", + get_khandle_from_ino(inode), + key, + type); + ret = pvfs2_inode_getxattr(inode, + "", + key, + value, + PVFS_MAX_XATTR_VALUELEN); + /* if the key exists, convert it to an in-memory rep */ + if (ret > 0) { + acl = posix_acl_from_xattr(&init_user_ns, value, ret); + } else if (ret == -ENODATA || ret == -ENOSYS) { + acl = NULL; + } else { + gossip_err("inode %pU retrieving acl's failed with error %d\n", + get_khandle_from_ino(inode), + ret); + acl = ERR_PTR(ret); + } + /* kfree(NULL) is safe, so don't worry if value ever got used */ + kfree(value); + return acl; +} + +int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + int error = 0; + void *value = NULL; + size_t size = 0; + const char *name = NULL; + + switch (type) { + case ACL_TYPE_ACCESS: + name = PVFS2_XATTR_NAME_ACL_ACCESS; + if (acl) { + umode_t mode = inode->i_mode; + /* + * can we represent this with the traditional file + * mode permission bits? + */ + error = posix_acl_equiv_mode(acl, &mode); + if (error < 0) { + gossip_err("%s: posix_acl_equiv_mode err: %d\n", + __func__, + error); + return error; + } + + if (inode->i_mode != mode) + SetModeFlag(pvfs2_inode); + inode->i_mode = mode; + mark_inode_dirty_sync(inode); + if (error == 0) + acl = NULL; + } + break; + case ACL_TYPE_DEFAULT: + name = PVFS2_XATTR_NAME_ACL_DEFAULT; + break; + default: + gossip_err("%s: invalid type %d!\n", __func__, type); + return -EINVAL; + } + + gossip_debug(GOSSIP_ACL_DEBUG, + "%s: inode %pU, key %s type %d\n", + __func__, get_khandle_from_ino(inode), + name, + type); + + if (acl) { + size = posix_acl_xattr_size(acl->a_count); + value = kmalloc(size, GFP_KERNEL); + if (!value) + return -ENOMEM; + + error = posix_acl_to_xattr(&init_user_ns, acl, value, size); + if (error < 0) + goto out; + } + + gossip_debug(GOSSIP_ACL_DEBUG, + "%s: name %s, value %p, size %zd, acl %p\n", + __func__, name, value, size, acl); + /* + * Go ahead and set the extended attribute now. NOTE: Suppose acl + * was NULL, then value will be NULL and size will be 0 and that + * will xlate to a removexattr. However, we don't want removexattr + * complain if attributes does not exist. + */ + error = pvfs2_inode_setxattr(inode, "", name, value, size, 0); + +out: + kfree(value); + if (!error) + set_cached_acl(inode, type, acl); + return error; +} + +int pvfs2_init_acl(struct inode *inode, struct inode *dir) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct posix_acl *default_acl, *acl; + umode_t mode = inode->i_mode; + int error = 0; + + ClearModeFlag(pvfs2_inode); + + error = posix_acl_create(dir, &mode, &default_acl, &acl); + if (error) + return error; + + if (default_acl) { + error = pvfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + posix_acl_release(default_acl); + } + + if (acl) { + if (!error) + error = pvfs2_set_acl(inode, acl, ACL_TYPE_ACCESS); + posix_acl_release(acl); + } + + /* If mode of the inode was changed, then do a forcible ->setattr */ + if (mode != inode->i_mode) { + SetModeFlag(pvfs2_inode); + inode->i_mode = mode; + pvfs2_flush_inode(inode); + } + + return error; +} diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c new file mode 100644 index 000000000000..9466b179bf24 --- /dev/null +++ b/fs/orangefs/dcache.c @@ -0,0 +1,142 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Implementation of dentry (directory cache) functions. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" + +/* Returns 1 if dentry can still be trusted, else 0. */ +static int pvfs2_revalidate_lookup(struct dentry *dentry) +{ + struct dentry *parent_dentry = dget_parent(dentry); + struct inode *parent_inode = parent_dentry->d_inode; + struct pvfs2_inode_s *parent = PVFS2_I(parent_inode); + struct inode *inode = dentry->d_inode; + struct pvfs2_kernel_op_s *new_op; + int ret = 0; + int err = 0; + + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__); + + new_op = op_alloc(PVFS2_VFS_OP_LOOKUP); + if (!new_op) + goto out_put_parent; + + new_op->upcall.req.lookup.sym_follow = PVFS2_LOOKUP_LINK_NO_FOLLOW; + new_op->upcall.req.lookup.parent_refn = parent->refn; + strncpy(new_op->upcall.req.lookup.d_name, + dentry->d_name.name, + PVFS2_NAME_LEN); + + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d interrupt flag [%d]\n", + __FILE__, + __func__, + __LINE__, + get_interruptible_flag(parent_inode)); + + err = service_operation(new_op, "pvfs2_lookup", + get_interruptible_flag(parent_inode)); + if (err) + goto out_drop; + + if (new_op->downcall.status != 0 || + !match_handle(new_op->downcall.resp.lookup.refn.khandle, inode)) { + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d " + "lookup failure |%s| or no match |%s|.\n", + __FILE__, + __func__, + __LINE__, + new_op->downcall.status ? "true" : "false", + match_handle(new_op->downcall.resp.lookup.refn.khandle, + inode) ? "false" : "true"); + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d revalidate failed\n", + __FILE__, __func__, __LINE__); + goto out_drop; + } + + ret = 1; +out_release_op: + op_release(new_op); +out_put_parent: + dput(parent_dentry); + return ret; +out_drop: + d_drop(dentry); + goto out_release_op; +} + +/* + * Verify that dentry is valid. + * + * Should return 1 if dentry can still be trusted, else 0 + */ +static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags) +{ + struct inode *inode; + int ret = 0; + + if (flags & LOOKUP_RCU) + return -ECHILD; + + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p.\n", + __func__, dentry); + + /* find inode from dentry */ + if (!dentry->d_inode) { + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n", + __func__); + goto invalid_exit; + } + + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: inode valid.\n", __func__); + inode = dentry->d_inode; + + /* + * first perform a lookup to make sure that the object not only + * exists, but is still in the expected place in the name space + */ + if (!is_root_handle(inode)) { + if (!pvfs2_revalidate_lookup(dentry)) + goto invalid_exit; + } else { + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: root handle, lookup skipped.\n", + __func__); + } + + /* now perform getattr */ + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: doing getattr: inode: %p, handle: %pU\n", + __func__, + inode, + get_khandle_from_ino(inode)); + ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: getattr %s (ret = %d), returning %s for dentry i_count=%d\n", + __func__, + (ret == 0 ? "succeeded" : "failed"), + ret, + (ret == 0 ? "valid" : "INVALID"), + atomic_read(&inode->i_count)); + if (ret != 0) + goto invalid_exit; + + /* dentry is valid! */ + return 1; + +invalid_exit: + return 0; +} + +const struct dentry_operations pvfs2_dentry_operations = { + .d_revalidate = pvfs2_d_revalidate, +}; diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c new file mode 100644 index 000000000000..3e450228f3dc --- /dev/null +++ b/fs/orangefs/devpvfs2-req.c @@ -0,0 +1,997 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * Changes by Acxiom Corporation to add protocol version to kernel + * communication, Copyright Acxiom Corporation, 2005. + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-dev-proto.h" +#include "pvfs2-bufmap.h" + +#include +#include + +/* this file implements the /dev/pvfs2-req device node */ + +static int open_access_count; + +#define DUMP_DEVICE_ERROR() \ +do { \ + gossip_err("*****************************************************\n");\ + gossip_err("PVFS2 Device Error: You cannot open the device file "); \ + gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \ + "are no ", PVFS2_REQDEVICE_NAME); \ + gossip_err("instances of a program using this device\ncurrently " \ + "running. (You must verify this!)\n"); \ + gossip_err("For example, you can use the lsof program as follows:\n");\ + gossip_err("'lsof | grep %s' (run this as root)\n", \ + PVFS2_REQDEVICE_NAME); \ + gossip_err(" open_access_count = %d\n", open_access_count); \ + gossip_err("*****************************************************\n");\ +} while (0) + +static int hash_func(__u64 tag, int table_size) +{ + return tag % ((unsigned int)table_size); +} + +static void pvfs2_devreq_add_op(struct pvfs2_kernel_op_s *op) +{ + int index = hash_func(op->tag, hash_table_size); + + spin_lock(&htable_ops_in_progress_lock); + list_add_tail(&op->list, &htable_ops_in_progress[index]); + spin_unlock(&htable_ops_in_progress_lock); +} + +static struct pvfs2_kernel_op_s *pvfs2_devreq_remove_op(__u64 tag) +{ + struct pvfs2_kernel_op_s *op, *next; + int index; + + index = hash_func(tag, hash_table_size); + + spin_lock(&htable_ops_in_progress_lock); + list_for_each_entry_safe(op, + next, + &htable_ops_in_progress[index], + list) { + if (op->tag == tag) { + list_del(&op->list); + spin_unlock(&htable_ops_in_progress_lock); + return op; + } + } + + spin_unlock(&htable_ops_in_progress_lock); + return NULL; +} + +static int pvfs2_devreq_open(struct inode *inode, struct file *file) +{ + int ret = -EINVAL; + + if (!(file->f_flags & O_NONBLOCK)) { + gossip_err("pvfs2: device cannot be opened in blocking mode\n"); + goto out; + } + ret = -EACCES; + gossip_debug(GOSSIP_DEV_DEBUG, "pvfs2-client-core: opening device\n"); + mutex_lock(&devreq_mutex); + + if (open_access_count == 0) { + ret = generic_file_open(inode, file); + if (ret == 0) + open_access_count++; + } else { + DUMP_DEVICE_ERROR(); + } + mutex_unlock(&devreq_mutex); + +out: + + gossip_debug(GOSSIP_DEV_DEBUG, + "pvfs2-client-core: open device complete (ret = %d)\n", + ret); + return ret; +} + +static ssize_t pvfs2_devreq_read(struct file *file, + char __user *buf, + size_t count, loff_t *offset) +{ + int ret = 0; + ssize_t len = 0; + struct pvfs2_kernel_op_s *cur_op = NULL; + static __s32 magic = PVFS2_DEVREQ_MAGIC; + __s32 proto_ver = PVFS_KERNEL_PROTO_VERSION; + + if (!(file->f_flags & O_NONBLOCK)) { + /* We do not support blocking reads/opens any more */ + gossip_err("pvfs2: blocking reads are not supported! (pvfs2-client-core bug)\n"); + return -EINVAL; + } else { + struct pvfs2_kernel_op_s *op = NULL, *temp = NULL; + /* get next op (if any) from top of list */ + spin_lock(&pvfs2_request_list_lock); + list_for_each_entry_safe(op, temp, &pvfs2_request_list, list) { + __s32 fsid = fsid_of_op(op); + /* + * Check if this op's fsid is known and needs + * remounting + */ + if (fsid != PVFS_FS_ID_NULL && + fs_mount_pending(fsid) == 1) { + gossip_debug(GOSSIP_DEV_DEBUG, + "Skipping op tag %llu %s\n", + llu(op->tag), + get_opname_string(op)); + continue; + } else { + /* + * op does not belong to any particular fsid + * or already mounted.. let it through + */ + cur_op = op; + spin_lock(&cur_op->lock); + list_del(&cur_op->list); + cur_op->op_linger_tmp--; + /* + * if there is a trailer, re-add it to + * the request list. + */ + if (cur_op->op_linger == 2 && + cur_op->op_linger_tmp == 1) { + if (cur_op->upcall.trailer_size <= 0 || + cur_op->upcall.trailer_buf == NULL) + gossip_err("BUG:trailer_size is %ld and trailer buf is %p\n", (long)cur_op->upcall.trailer_size, cur_op->upcall.trailer_buf); + /* re-add it to the head of the list */ + list_add(&cur_op->list, + &pvfs2_request_list); + } + spin_unlock(&cur_op->lock); + break; + } + } + spin_unlock(&pvfs2_request_list_lock); + } + + if (cur_op) { + spin_lock(&cur_op->lock); + + gossip_debug(GOSSIP_DEV_DEBUG, + "client-core: reading op tag %llu %s\n", + llu(cur_op->tag), get_opname_string(cur_op)); + if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) { + if (cur_op->op_linger == 1) + gossip_err("WARNING: Current op already queued...skipping\n"); + } else if (cur_op->op_linger == 1 || + (cur_op->op_linger == 2 && + cur_op->op_linger_tmp == 0)) { + /* + * atomically move the operation to the + * htable_ops_in_progress + */ + set_op_state_inprogress(cur_op); + pvfs2_devreq_add_op(cur_op); + } + + spin_unlock(&cur_op->lock); + + /* 2 cases + * a) OPs with no trailers + * b) OPs with trailers, Stage 1 + * Either way push the upcall out + */ + if (cur_op->op_linger == 1 || + (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 1)) { + len = MAX_ALIGNED_DEV_REQ_UPSIZE; + if ((size_t) len <= count) { + ret = copy_to_user(buf, + &proto_ver, + sizeof(__s32)); + if (ret == 0) { + ret = copy_to_user(buf + sizeof(__s32), + &magic, + sizeof(__s32)); + if (ret == 0) { + ret = copy_to_user(buf+2 * sizeof(__s32), + &cur_op->tag, + sizeof(__u64)); + if (ret == 0) { + ret = copy_to_user( + buf + + 2 * + sizeof(__s32) + + sizeof(__u64), + &cur_op->upcall, + sizeof(struct pvfs2_upcall_s)); + } + } + } + + if (ret) { + gossip_err("Failed to copy data to user space\n"); + len = -EFAULT; + } + } else { + gossip_err + ("Failed to copy data to user space\n"); + len = -EIO; + } + } + /* Stage 2: Push the trailer out */ + else if (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 0) { + len = cur_op->upcall.trailer_size; + if ((size_t) len <= count) { + ret = copy_to_user(buf, + cur_op->upcall.trailer_buf, + len); + if (ret) { + gossip_err("Failed to copy trailer to user space\n"); + len = -EFAULT; + } + } else { + gossip_err("Read buffer for trailer is too small (%ld as opposed to %ld)\n", + (long)count, + (long)len); + len = -EIO; + } + } else { + gossip_err("cur_op: %p (op_linger %d), (op_linger_tmp %d), erroneous request list?\n", + cur_op, + cur_op->op_linger, + cur_op->op_linger_tmp); + len = 0; + } + } else if (file->f_flags & O_NONBLOCK) { + /* + * if in non-blocking mode, return EAGAIN since no requests are + * ready yet + */ + len = -EAGAIN; + } + return len; +} + +/* Function for writev() callers into the device */ +static ssize_t pvfs2_devreq_writev(struct file *file, + const struct iovec *iov, + size_t count, + loff_t *offset) +{ + struct pvfs2_kernel_op_s *op = NULL; + void *buffer = NULL; + void *ptr = NULL; + unsigned long i = 0; + static int max_downsize = MAX_ALIGNED_DEV_REQ_DOWNSIZE; + int ret = 0, num_remaining = max_downsize; + int notrailer_count = 4; /* num elements in iovec without trailer */ + int payload_size = 0; + __s32 magic = 0; + __s32 proto_ver = 0; + __u64 tag = 0; + ssize_t total_returned_size = 0; + + /* Either there is a trailer or there isn't */ + if (count != notrailer_count && count != (notrailer_count + 1)) { + gossip_err("Error: Number of iov vectors is (%ld) and notrailer count is %d\n", + count, + notrailer_count); + return -EPROTO; + } + buffer = dev_req_alloc(); + if (!buffer) + return -ENOMEM; + ptr = buffer; + + for (i = 0; i < notrailer_count; i++) { + if (iov[i].iov_len > num_remaining) { + gossip_err + ("writev error: Freeing buffer and returning\n"); + dev_req_release(buffer); + return -EMSGSIZE; + } + ret = copy_from_user(ptr, iov[i].iov_base, iov[i].iov_len); + if (ret) { + gossip_err("Failed to copy data from user space\n"); + dev_req_release(buffer); + return -EIO; + } + num_remaining -= iov[i].iov_len; + ptr += iov[i].iov_len; + payload_size += iov[i].iov_len; + } + total_returned_size = payload_size; + + /* these elements are currently 8 byte aligned (8 bytes for (version + + * magic) 8 bytes for tag). If you add another element, either + * make it 8 bytes big, or use get_unaligned when asigning. + */ + ptr = buffer; + proto_ver = *((__s32 *) ptr); + ptr += sizeof(__s32); + + magic = *((__s32 *) ptr); + ptr += sizeof(__s32); + + tag = *((__u64 *) ptr); + ptr += sizeof(__u64); + + if (magic != PVFS2_DEVREQ_MAGIC) { + gossip_err("Error: Device magic number does not match.\n"); + dev_req_release(buffer); + return -EPROTO; + } + + /* + * proto_ver = 20902 for 2.9.2 + */ + + op = pvfs2_devreq_remove_op(tag); + if (op) { + /* Increase ref count! */ + get_op(op); + /* cut off magic and tag from payload size */ + payload_size -= (2 * sizeof(__s32) + sizeof(__u64)); + if (payload_size <= sizeof(struct pvfs2_downcall_s)) + /* copy the passed in downcall into the op */ + memcpy(&op->downcall, + ptr, + sizeof(struct pvfs2_downcall_s)); + else + gossip_debug(GOSSIP_DEV_DEBUG, + "writev: Ignoring %d bytes\n", + payload_size); + + /* Do not allocate needlessly if client-core forgets + * to reset trailer size on op errors. + */ + if (op->downcall.status == 0 && op->downcall.trailer_size > 0) { + gossip_debug(GOSSIP_DEV_DEBUG, + "writev: trailer size %ld\n", + (unsigned long)op->downcall.trailer_size); + if (count != (notrailer_count + 1)) { + gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%ld)\n", (unsigned long)op->downcall.trailer_size, count); + dev_req_release(buffer); + put_op(op); + return -EPROTO; + } + if (iov[notrailer_count].iov_len > + op->downcall.trailer_size) { + gossip_err("writev error: trailer size (%ld) != iov_len (%ld)\n", (unsigned long)op->downcall.trailer_size, (unsigned long)iov[notrailer_count].iov_len); + dev_req_release(buffer); + put_op(op); + return -EMSGSIZE; + } + /* Allocate a buffer large enough to hold the + * trailer bytes. + */ + op->downcall.trailer_buf = + vmalloc(op->downcall.trailer_size); + if (op->downcall.trailer_buf != NULL) { + gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n", + op->downcall.trailer_buf); + ret = copy_from_user(op->downcall.trailer_buf, + iov[notrailer_count]. + iov_base, + iov[notrailer_count]. + iov_len); + if (ret) { + gossip_err("Failed to copy trailer data from user space\n"); + dev_req_release(buffer); + gossip_debug(GOSSIP_DEV_DEBUG, + "vfree: %p\n", + op->downcall.trailer_buf); + vfree(op->downcall.trailer_buf); + op->downcall.trailer_buf = NULL; + put_op(op); + return -EIO; + } + } else { + /* Change downcall status */ + op->downcall.status = -ENOMEM; + gossip_err("writev: could not vmalloc for trailer!\n"); + } + } + + /* if this operation is an I/O operation and if it was + * initiated on behalf of a *synchronous* VFS I/O operation, + * only then we need to wait + * for all data to be copied before we can return to avoid + * buffer corruption and races that can pull the buffers + * out from under us. + * + * Essentially we're synchronizing with other parts of the + * vfs implicitly by not allowing the user space + * application reading/writing this device to return until + * the buffers are done being used. + */ + if ((op->upcall.type == PVFS2_VFS_OP_FILE_IO && + op->upcall.req.io.async_vfs_io == PVFS_VFS_SYNC_IO) || + op->upcall.type == PVFS2_VFS_OP_FILE_IOX) { + int timed_out = 0; + DECLARE_WAITQUEUE(wait_entry, current); + + /* tell the vfs op waiting on a waitqueue + * that this op is done + */ + spin_lock(&op->lock); + set_op_state_serviced(op); + spin_unlock(&op->lock); + + add_wait_queue_exclusive(&op->io_completion_waitq, + &wait_entry); + wake_up_interruptible(&op->waitq); + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + spin_lock(&op->lock); + if (op->io_completed) { + spin_unlock(&op->lock); + break; + } + spin_unlock(&op->lock); + + if (!signal_pending(current)) { + int timeout = + MSECS_TO_JIFFIES(1000 * + op_timeout_secs); + if (!schedule_timeout(timeout)) { + gossip_debug(GOSSIP_DEV_DEBUG, "*** I/O wait time is up\n"); + timed_out = 1; + break; + } + continue; + } + + gossip_debug(GOSSIP_DEV_DEBUG, "*** signal on I/O wait -- aborting\n"); + break; + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&op->io_completion_waitq, + &wait_entry); + + /* NOTE: for I/O operations we handle releasing the op + * object except in the case of timeout. the reason we + * can't free the op in timeout cases is that the op + * service logic in the vfs retries operations using + * the same op ptr, thus it can't be freed. + */ + if (!timed_out) + op_release(op); + } else { + + /* + * tell the vfs op waiting on a waitqueue that + * this op is done + */ + spin_lock(&op->lock); + set_op_state_serviced(op); + spin_unlock(&op->lock); + /* + for every other operation (i.e. non-I/O), we need to + wake up the callers for downcall completion + notification + */ + wake_up_interruptible(&op->waitq); + } + } else { + /* ignore downcalls that we're not interested in */ + gossip_debug(GOSSIP_DEV_DEBUG, + "WARNING: No one's waiting for tag %llu\n", + llu(tag)); + } + dev_req_release(buffer); + + return total_returned_size; +} + +static ssize_t pvfs2_devreq_write_iter(struct kiocb *iocb, + struct iov_iter *iter) +{ + return pvfs2_devreq_writev(iocb->ki_filp, + iter->iov, + iter->nr_segs, + &iocb->ki_pos); +} + +/* Returns whether any FS are still pending remounted */ +static int mark_all_pending_mounts(void) +{ + int unmounted = 1; + struct pvfs2_sb_info_s *pvfs2_sb = NULL; + + spin_lock(&pvfs2_superblocks_lock); + list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) { + /* All of these file system require a remount */ + pvfs2_sb->mount_pending = 1; + unmounted = 0; + } + spin_unlock(&pvfs2_superblocks_lock); + return unmounted; +} + +/* + * Determine if a given file system needs to be remounted or not + * Returns -1 on error + * 0 if already mounted + * 1 if needs remount + */ +int fs_mount_pending(__s32 fsid) +{ + int mount_pending = -1; + struct pvfs2_sb_info_s *pvfs2_sb = NULL; + + spin_lock(&pvfs2_superblocks_lock); + list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) { + if (pvfs2_sb->fs_id == fsid) { + mount_pending = pvfs2_sb->mount_pending; + break; + } + } + spin_unlock(&pvfs2_superblocks_lock); + return mount_pending; +} + +/* + * NOTE: gets called when the last reference to this device is dropped. + * Using the open_access_count variable, we enforce a reference count + * on this file so that it can be opened by only one process at a time. + * the devreq_mutex is used to make sure all i/o has completed + * before we call pvfs_bufmap_finalize, and similar such tricky + * situations + */ +static int pvfs2_devreq_release(struct inode *inode, struct file *file) +{ + int unmounted = 0; + + gossip_debug(GOSSIP_DEV_DEBUG, + "%s:pvfs2-client-core: exiting, closing device\n", + __func__); + + mutex_lock(&devreq_mutex); + pvfs_bufmap_finalize(); + + open_access_count--; + + unmounted = mark_all_pending_mounts(); + gossip_debug(GOSSIP_DEV_DEBUG, "PVFS2 Device Close: Filesystem(s) %s\n", + (unmounted ? "UNMOUNTED" : "MOUNTED")); + mutex_unlock(&devreq_mutex); + + /* + * Walk through the list of ops in the request list, mark them + * as purged and wake them up. + */ + purge_waiting_ops(); + /* + * Walk through the hash table of in progress operations; mark + * them as purged and wake them up + */ + purge_inprogress_ops(); + gossip_debug(GOSSIP_DEV_DEBUG, + "pvfs2-client-core: device close complete\n"); + return 0; +} + +int is_daemon_in_service(void) +{ + int in_service; + + /* + * What this function does is checks if client-core is alive + * based on the access count we maintain on the device. + */ + mutex_lock(&devreq_mutex); + in_service = open_access_count == 1 ? 0 : -EIO; + mutex_unlock(&devreq_mutex); + return in_service; +} + +static inline long check_ioctl_command(unsigned int command) +{ + /* Check for valid ioctl codes */ + if (_IOC_TYPE(command) != PVFS_DEV_MAGIC) { + gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n", + command, + _IOC_TYPE(command), + PVFS_DEV_MAGIC); + return -EINVAL; + } + /* and valid ioctl commands */ + if (_IOC_NR(command) >= PVFS_DEV_MAXNR || _IOC_NR(command) <= 0) { + gossip_err("Invalid ioctl command number [%d >= %d]\n", + _IOC_NR(command), PVFS_DEV_MAXNR); + return -ENOIOCTLCMD; + } + return 0; +} + +static long dispatch_ioctl_command(unsigned int command, unsigned long arg) +{ + static __s32 magic = PVFS2_DEVREQ_MAGIC; + static __s32 max_up_size = MAX_ALIGNED_DEV_REQ_UPSIZE; + static __s32 max_down_size = MAX_ALIGNED_DEV_REQ_DOWNSIZE; + struct PVFS_dev_map_desc user_desc; + int ret = 0; + struct dev_mask_info_s mask_info = { 0 }; + struct dev_mask2_info_s mask2_info = { 0, 0 }; + int upstream_kmod = 1; + struct list_head *tmp = NULL; + struct pvfs2_sb_info_s *pvfs2_sb = NULL; + + /* mtmoore: add locking here */ + + switch (command) { + case PVFS_DEV_GET_MAGIC: + return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ? + -EIO : + 0); + case PVFS_DEV_GET_MAX_UPSIZE: + return ((put_user(max_up_size, + (__s32 __user *) arg) == -EFAULT) ? + -EIO : + 0); + case PVFS_DEV_GET_MAX_DOWNSIZE: + return ((put_user(max_down_size, + (__s32 __user *) arg) == -EFAULT) ? + -EIO : + 0); + case PVFS_DEV_MAP: + ret = copy_from_user(&user_desc, + (struct PVFS_dev_map_desc __user *) + arg, + sizeof(struct PVFS_dev_map_desc)); + return ret ? -EIO : pvfs_bufmap_initialize(&user_desc); + case PVFS_DEV_REMOUNT_ALL: + gossip_debug(GOSSIP_DEV_DEBUG, + "pvfs2_devreq_ioctl: got PVFS_DEV_REMOUNT_ALL\n"); + + /* + * remount all mounted pvfs2 volumes to regain the lost + * dynamic mount tables (if any) -- NOTE: this is done + * without keeping the superblock list locked due to the + * upcall/downcall waiting. also, the request semaphore is + * used to ensure that no operations will be serviced until + * all of the remounts are serviced (to avoid ops between + * mounts to fail) + */ + ret = mutex_lock_interruptible(&request_mutex); + if (ret < 0) + return ret; + gossip_debug(GOSSIP_DEV_DEBUG, + "pvfs2_devreq_ioctl: priority remount in progress\n"); + list_for_each(tmp, &pvfs2_superblocks) { + pvfs2_sb = + list_entry(tmp, struct pvfs2_sb_info_s, list); + if (pvfs2_sb && (pvfs2_sb->sb)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "Remounting SB %p\n", + pvfs2_sb); + + ret = pvfs2_remount(pvfs2_sb->sb); + if (ret) { + gossip_debug(GOSSIP_DEV_DEBUG, + "SB %p remount failed\n", + pvfs2_sb); + break; + } + } + } + gossip_debug(GOSSIP_DEV_DEBUG, + "pvfs2_devreq_ioctl: priority remount complete\n"); + mutex_unlock(&request_mutex); + return ret; + + case PVFS_DEV_UPSTREAM: + ret = copy_to_user((void __user *)arg, + &upstream_kmod, + sizeof(upstream_kmod)); + + if (ret != 0) + return -EIO; + else + return ret; + + case PVFS_DEV_CLIENT_MASK: + ret = copy_from_user(&mask2_info, + (void __user *)arg, + sizeof(struct dev_mask2_info_s)); + + if (ret != 0) + return -EIO; + + client_debug_mask.mask1 = mask2_info.mask1_value; + client_debug_mask.mask2 = mask2_info.mask2_value; + + pr_info("%s: client debug mask has been been received " + ":%llx: :%llx:\n", + __func__, + (unsigned long long)client_debug_mask.mask1, + (unsigned long long)client_debug_mask.mask2); + + return ret; + + case PVFS_DEV_CLIENT_STRING: + ret = copy_from_user(&client_debug_array_string, + (void __user *)arg, + PVFS2_MAX_DEBUG_STRING_LEN); + if (ret != 0) { + pr_info("%s: " + "PVFS_DEV_CLIENT_STRING: copy_from_user failed" + "\n", + __func__); + return -EIO; + } + + pr_info("%s: client debug array string has been been received." + "\n", + __func__); + + if (!help_string_initialized) { + + /* Free the "we don't know yet" default string... */ + kfree(debug_help_string); + + /* build a proper debug help string */ + if (orangefs_prepare_debugfs_help_string(0)) { + gossip_err("%s: " + "prepare_debugfs_help_string failed" + "\n", + __func__); + return -EIO; + } + + /* Replace the boilerplate boot-time debug-help file. */ + debugfs_remove(help_file_dentry); + + help_file_dentry = + debugfs_create_file( + ORANGEFS_KMOD_DEBUG_HELP_FILE, + 0444, + debug_dir, + debug_help_string, + &debug_help_fops); + + if (!help_file_dentry) { + gossip_err("%s: debugfs_create_file failed for" + " :%s:!\n", + __func__, + ORANGEFS_KMOD_DEBUG_HELP_FILE); + return -EIO; + } + } + + debug_mask_to_string(&client_debug_mask, 1); + + debugfs_remove(client_debug_dentry); + + pvfs2_client_debug_init(); + + help_string_initialized++; + + return ret; + + case PVFS_DEV_DEBUG: + ret = copy_from_user(&mask_info, + (void __user *)arg, + sizeof(mask_info)); + + if (ret != 0) + return -EIO; + + if (mask_info.mask_type == KERNEL_MASK) { + if ((mask_info.mask_value == 0) + && (kernel_mask_set_mod_init)) { + /* + * the kernel debug mask was set when the + * kernel module was loaded; don't override + * it if the client-core was started without + * a value for PVFS2_KMODMASK. + */ + return 0; + } + debug_mask_to_string(&mask_info.mask_value, + mask_info.mask_type); + gossip_debug_mask = mask_info.mask_value; + pr_info("PVFS: kernel debug mask has been modified to " + ":%s: :%llx:\n", + kernel_debug_string, + (unsigned long long)gossip_debug_mask); + } else if (mask_info.mask_type == CLIENT_MASK) { + debug_mask_to_string(&mask_info.mask_value, + mask_info.mask_type); + pr_info("PVFS: client debug mask has been modified to" + ":%s: :%llx:\n", + client_debug_string, + llu(mask_info.mask_value)); + } else { + gossip_lerr("Invalid mask type....\n"); + return -EINVAL; + } + + return ret; + + default: + return -ENOIOCTLCMD; + } + return -ENOIOCTLCMD; +} + +static long pvfs2_devreq_ioctl(struct file *file, + unsigned int command, unsigned long arg) +{ + long ret; + + /* Check for properly constructed commands */ + ret = check_ioctl_command(command); + if (ret < 0) + return (int)ret; + + return (int)dispatch_ioctl_command(command, arg); +} + +#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ + +/* Compat structure for the PVFS_DEV_MAP ioctl */ +struct PVFS_dev_map_desc32 { + compat_uptr_t ptr; + __s32 total_size; + __s32 size; + __s32 count; +}; + +static unsigned long translate_dev_map26(unsigned long args, long *error) +{ + struct PVFS_dev_map_desc32 __user *p32 = (void __user *)args; + /* + * Depending on the architecture, allocate some space on the + * user-call-stack based on our expected layout. + */ + struct PVFS_dev_map_desc __user *p = + compat_alloc_user_space(sizeof(*p)); + u32 addr; + + *error = 0; + /* get the ptr from the 32 bit user-space */ + if (get_user(addr, &p32->ptr)) + goto err; + /* try to put that into a 64-bit layout */ + if (put_user(compat_ptr(addr), &p->ptr)) + goto err; + /* copy the remaining fields */ + if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32))) + goto err; + if (copy_in_user(&p->size, &p32->size, sizeof(__s32))) + goto err; + if (copy_in_user(&p->count, &p32->count, sizeof(__s32))) + goto err; + return (unsigned long)p; +err: + *error = -EFAULT; + return 0; +} + +/* + * 32 bit user-space apps' ioctl handlers when kernel modules + * is compiled as a 64 bit one + */ +static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long args) +{ + long ret; + unsigned long arg = args; + + /* Check for properly constructed commands */ + ret = check_ioctl_command(cmd); + if (ret < 0) + return ret; + if (cmd == PVFS_DEV_MAP) { + /* + * convert the arguments to what we expect internally + * in kernel space + */ + arg = translate_dev_map26(args, &ret); + if (ret < 0) { + gossip_err("Could not translate dev map\n"); + return ret; + } + } + /* no other ioctl requires translation */ + return dispatch_ioctl_command(cmd, arg); +} + +static int pvfs2_ioctl32_init(void) +{ + return 0; +} + +static void pvfs2_ioctl32_cleanup(void) +{ + return; +} + +#endif /* CONFIG_COMPAT is in .config */ + +/* the assigned character device major number */ +static int pvfs2_dev_major; + +/* + * Initialize pvfs2 device specific state: + * Must be called at module load time only + */ +int pvfs2_dev_init(void) +{ + int ret; + + /* register the ioctl32 sub-system */ + ret = pvfs2_ioctl32_init(); + if (ret < 0) + return ret; + + /* register pvfs2-req device */ + pvfs2_dev_major = register_chrdev(0, + PVFS2_REQDEVICE_NAME, + &pvfs2_devreq_file_operations); + if (pvfs2_dev_major < 0) { + gossip_debug(GOSSIP_DEV_DEBUG, + "Failed to register /dev/%s (error %d)\n", + PVFS2_REQDEVICE_NAME, pvfs2_dev_major); + pvfs2_ioctl32_cleanup(); + return pvfs2_dev_major; + } + + gossip_debug(GOSSIP_DEV_DEBUG, + "*** /dev/%s character device registered ***\n", + PVFS2_REQDEVICE_NAME); + gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n", + PVFS2_REQDEVICE_NAME, pvfs2_dev_major); + return 0; +} + +void pvfs2_dev_cleanup(void) +{ + unregister_chrdev(pvfs2_dev_major, PVFS2_REQDEVICE_NAME); + gossip_debug(GOSSIP_DEV_DEBUG, + "*** /dev/%s character device unregistered ***\n", + PVFS2_REQDEVICE_NAME); + /* unregister the ioctl32 sub-system */ + pvfs2_ioctl32_cleanup(); +} + +static unsigned int pvfs2_devreq_poll(struct file *file, + struct poll_table_struct *poll_table) +{ + int poll_revent_mask = 0; + + if (open_access_count == 1) { + poll_wait(file, &pvfs2_request_list_waitq, poll_table); + + spin_lock(&pvfs2_request_list_lock); + if (!list_empty(&pvfs2_request_list)) + poll_revent_mask |= POLL_IN; + spin_unlock(&pvfs2_request_list_lock); + } + return poll_revent_mask; +} + +const struct file_operations pvfs2_devreq_file_operations = { + .owner = THIS_MODULE, + .read = pvfs2_devreq_read, + .write_iter = pvfs2_devreq_write_iter, + .open = pvfs2_devreq_open, + .release = pvfs2_devreq_release, + .unlocked_ioctl = pvfs2_devreq_ioctl, + +#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ + .compat_ioctl = pvfs2_devreq_compat_ioctl, +#endif + .poll = pvfs2_devreq_poll +}; diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c new file mode 100644 index 000000000000..9b5f4bb17874 --- /dev/null +++ b/fs/orangefs/dir.c @@ -0,0 +1,394 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +struct readdir_handle_s { + int buffer_index; + struct pvfs2_readdir_response_s readdir_response; + void *dents_buf; +}; + +/* + * decode routine needed by kmod to make sense of the shared page for readdirs. + */ +static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) +{ + int i; + struct pvfs2_readdir_response_s *rd = + (struct pvfs2_readdir_response_s *) ptr; + char *buf = ptr; + char **pptr = &buf; + + readdir->token = rd->token; + readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount; + readdir->dirent_array = kmalloc(readdir->pvfs_dirent_outcount * + sizeof(*readdir->dirent_array), + GFP_KERNEL); + if (readdir->dirent_array == NULL) + return -ENOMEM; + *pptr += offsetof(struct pvfs2_readdir_response_s, dirent_array); + for (i = 0; i < readdir->pvfs_dirent_outcount; i++) { + dec_string(pptr, &readdir->dirent_array[i].d_name, + &readdir->dirent_array[i].d_length); + readdir->dirent_array[i].khandle = + *(struct pvfs2_khandle *) *pptr; + *pptr += 16; + } + return (unsigned long)*pptr - (unsigned long)ptr; +} + +static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, + int buffer_index) +{ + long ret; + + if (buf == NULL) { + gossip_err + ("Invalid NULL buffer specified in readdir_handle_ctor\n"); + return -ENOMEM; + } + if (buffer_index < 0) { + gossip_err + ("Invalid buffer index specified in readdir_handle_ctor\n"); + return -EINVAL; + } + rhandle->buffer_index = buffer_index; + rhandle->dents_buf = buf; + ret = decode_dirents(buf, &rhandle->readdir_response); + if (ret < 0) { + gossip_err("Could not decode readdir from buffer %ld\n", ret); + rhandle->buffer_index = -1; + gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n", buf); + vfree(buf); + rhandle->dents_buf = NULL; + } + return ret; +} + +static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap, + struct readdir_handle_s *rhandle) +{ + if (rhandle == NULL) + return; + + /* kfree(NULL) is safe */ + kfree(rhandle->readdir_response.dirent_array); + rhandle->readdir_response.dirent_array = NULL; + + if (rhandle->buffer_index >= 0) { + readdir_index_put(bufmap, rhandle->buffer_index); + rhandle->buffer_index = -1; + } + if (rhandle->dents_buf) { + gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n", + rhandle->dents_buf); + vfree(rhandle->dents_buf); + rhandle->dents_buf = NULL; + } +} + +/* + * Read directory entries from an instance of an open directory. + * + * \note This routine was converted for the readdir to iterate change + * in "struct file_operations". "converted" mostly amounts to + * changing occurrences of "readdir" and "filldir" in the + * comments to "iterate" and "dir_emit". Also filldir calls + * were changed to dir_emit calls. + * + * \param dir_emit callback function called for each entry read. + * + * \retval <0 on error + * \retval 0 when directory has been completely traversed + * \retval >0 if we don't call dir_emit for all entries + * + * \note If the dir_emit call-back returns non-zero, then iterate should + * assume that it has had enough, and should return as well. + */ +static int pvfs2_readdir(struct file *file, struct dir_context *ctx) +{ + struct pvfs2_bufmap *bufmap = NULL; + int ret = 0; + int buffer_index; + __u64 *ptoken = file->private_data; + __u64 pos = 0; + ino_t ino = 0; + struct dentry *dentry = file->f_path.dentry; + struct pvfs2_kernel_op_s *new_op = NULL; + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(dentry->d_inode); + int buffer_full = 0; + struct readdir_handle_s rhandle; + int i = 0; + int len = 0; + ino_t current_ino = 0; + char *current_entry = NULL; + long bytes_decoded; + + gossip_ldebug(GOSSIP_DIR_DEBUG, + "%s: ctx->pos:%lld, token = %llu\n", + __func__, + lld(ctx->pos), + llu(*ptoken)); + + pos = (__u64) ctx->pos; + + /* are we done? */ + if (pos == PVFS_READDIR_END) { + gossip_debug(GOSSIP_DIR_DEBUG, + "Skipping to termination path\n"); + return 0; + } + + gossip_debug(GOSSIP_DIR_DEBUG, + "pvfs2_readdir called on %s (pos=%llu)\n", + dentry->d_name.name, llu(pos)); + + rhandle.buffer_index = -1; + rhandle.dents_buf = NULL; + memset(&rhandle.readdir_response, 0, sizeof(rhandle.readdir_response)); + + new_op = op_alloc(PVFS2_VFS_OP_READDIR); + if (!new_op) + return -ENOMEM; + + new_op->uses_shared_memory = 1; + new_op->upcall.req.readdir.refn = pvfs2_inode->refn; + new_op->upcall.req.readdir.max_dirent_count = MAX_DIRENT_COUNT_READDIR; + + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: upcall.req.readdir.refn.khandle: %pU\n", + __func__, + &new_op->upcall.req.readdir.refn.khandle); + + /* + * NOTE: the position we send to the readdir upcall is out of + * sync with ctx->pos since: + * 1. pvfs2 doesn't include the "." and ".." entries that are + * added below. + * 2. the introduction of distributed directory logic makes token no + * longer be related to f_pos and pos. Instead an independent + * variable is used inside the function and stored in the + * private_data of the file structure. + */ + new_op->upcall.req.readdir.token = *ptoken; + +get_new_buffer_index: + ret = readdir_index_get(&bufmap, &buffer_index); + if (ret < 0) { + gossip_lerr("pvfs2_readdir: readdir_index_get() failure (%d)\n", + ret); + goto out_free_op; + } + new_op->upcall.req.readdir.buf_index = buffer_index; + + ret = service_operation(new_op, + "pvfs2_readdir", + get_interruptible_flag(dentry->d_inode)); + + gossip_debug(GOSSIP_DIR_DEBUG, + "Readdir downcall status is %d. ret:%d\n", + new_op->downcall.status, + ret); + + if (ret == -EAGAIN && op_state_purged(new_op)) { + /* + * readdir shared memory aread has been wiped due to + * pvfs2-client-core restarting, so we must get a new + * index into the shared memory. + */ + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: Getting new buffer_index for retry of readdir..\n", + __func__); + readdir_index_put(bufmap, buffer_index); + goto get_new_buffer_index; + } + + if (ret == -EIO && op_state_purged(new_op)) { + gossip_err("%s: Client is down. Aborting readdir call.\n", + __func__); + readdir_index_put(bufmap, buffer_index); + goto out_free_op; + } + + if (ret < 0 || new_op->downcall.status != 0) { + gossip_debug(GOSSIP_DIR_DEBUG, + "Readdir request failed. Status:%d\n", + new_op->downcall.status); + readdir_index_put(bufmap, buffer_index); + if (ret >= 0) + ret = new_op->downcall.status; + goto out_free_op; + } + + bytes_decoded = + readdir_handle_ctor(&rhandle, + new_op->downcall.trailer_buf, + buffer_index); + if (bytes_decoded < 0) { + gossip_err("pvfs2_readdir: Could not decode trailer buffer into a readdir response %d\n", + ret); + ret = bytes_decoded; + readdir_index_put(bufmap, buffer_index); + goto out_free_op; + } + + if (bytes_decoded != new_op->downcall.trailer_size) { + gossip_err("pvfs2_readdir: # bytes decoded (%ld) != trailer size (%ld)\n", + bytes_decoded, + (long)new_op->downcall.trailer_size); + ret = -EINVAL; + goto out_destroy_handle; + } + + if (pos == 0) { + ino = get_ino_from_khandle(dentry->d_inode); + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: calling dir_emit of \".\" with pos = %llu\n", + __func__, + llu(pos)); + ret = dir_emit(ctx, ".", 1, ino, DT_DIR); + if (ret < 0) + goto out_destroy_handle; + ctx->pos++; + gossip_ldebug(GOSSIP_DIR_DEBUG, + "%s: ctx->pos:%lld\n", + __func__, + lld(ctx->pos)); + pos++; + } + + if (pos == 1) { + ino = get_parent_ino_from_dentry(dentry); + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: calling dir_emit of \"..\" with pos = %llu\n", + __func__, + llu(pos)); + ret = dir_emit(ctx, "..", 2, ino, DT_DIR); + if (ret < 0) + goto out_destroy_handle; + ctx->pos++; + gossip_ldebug(GOSSIP_DIR_DEBUG, + "%s: ctx->pos:%lld\n", + __func__, + lld(ctx->pos)); + pos++; + } + + for (i = 0; i < rhandle.readdir_response.pvfs_dirent_outcount; i++) { + len = rhandle.readdir_response.dirent_array[i].d_length; + current_entry = rhandle.readdir_response.dirent_array[i].d_name; + current_ino = pvfs2_khandle_to_ino( + &(rhandle.readdir_response.dirent_array[i].khandle)); + + gossip_debug(GOSSIP_DIR_DEBUG, + "calling dir_emit for %s with len %d, pos %ld\n", + current_entry, + len, + (unsigned long)pos); + ret = + dir_emit(ctx, current_entry, len, current_ino, DT_UNKNOWN); + if (ret < 0) { + gossip_debug(GOSSIP_DIR_DEBUG, + "dir_emit() failed. ret:%d\n", + ret); + if (i < 2) { + gossip_err("dir_emit failed on one of the first two true PVFS directory entries.\n"); + gossip_err("Duplicate entries may appear.\n"); + } + buffer_full = 1; + break; + } + ctx->pos++; + gossip_ldebug(GOSSIP_DIR_DEBUG, + "%s: ctx->pos:%lld\n", + __func__, + lld(ctx->pos)); + + pos++; + } + + /* this means that all of the dir_emit calls succeeded */ + if (i == rhandle.readdir_response.pvfs_dirent_outcount) { + /* update token */ + *ptoken = rhandle.readdir_response.token; + } else { + /* this means a dir_emit call failed */ + if (rhandle.readdir_response.token == PVFS_READDIR_END) { + /* + * If PVFS hit end of directory, then there + * is no way to do math on the token that it + * returned. Instead we go by ctx->pos but + * back up to account for the artificial . + * and .. entries. + */ + ctx->pos -= 3; + } else { + /* + * this means a dir_emit call failed. !!! need to set + * back to previous ctx->pos, no middle value allowed + */ + pos -= (i - 1); + ctx->pos -= (i - 1); + } + gossip_debug(GOSSIP_DIR_DEBUG, + "at least one dir_emit call failed. Setting ctx->pos to: %lld\n", + lld(ctx->pos)); + } + + /* + * Did we hit the end of the directory? + */ + if (rhandle.readdir_response.token == PVFS_READDIR_END && + !buffer_full) { + gossip_debug(GOSSIP_DIR_DEBUG, "End of dir detected; setting ctx->pos to PVFS_READDIR_END.\n"); + ctx->pos = PVFS_READDIR_END; + } + + gossip_debug(GOSSIP_DIR_DEBUG, + "pos = %llu, token = %llu" + ", ctx->pos should have been %lld\n", + llu(pos), + llu(*ptoken), + lld(ctx->pos)); + +out_destroy_handle: + readdir_handle_dtor(bufmap, &rhandle); +out_free_op: + op_release(new_op); + gossip_debug(GOSSIP_DIR_DEBUG, "pvfs2_readdir returning %d\n", ret); + return ret; +} + +static int pvfs2_dir_open(struct inode *inode, struct file *file) +{ + __u64 *ptoken; + + file->private_data = kmalloc(sizeof(__u64), GFP_KERNEL); + if (!file->private_data) + return -ENOMEM; + + ptoken = file->private_data; + *ptoken = PVFS_READDIR_START; + return 0; +} + +static int pvfs2_dir_release(struct inode *inode, struct file *file) +{ + pvfs2_flush_inode(inode); + kfree(file->private_data); + return 0; +} + +/** PVFS2 implementation of VFS directory operations */ +const struct file_operations pvfs2_dir_operations = { + .read = generic_read_dir, + .iterate = pvfs2_readdir, + .open = pvfs2_dir_open, + .release = pvfs2_dir_release, +}; diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c new file mode 100644 index 000000000000..8e26f9fac289 --- /dev/null +++ b/fs/orangefs/file.c @@ -0,0 +1,1019 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Linux VFS file operations. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" +#include +#include + +#define wake_up_daemon_for_return(op) \ +do { \ + spin_lock(&op->lock); \ + op->io_completed = 1; \ + spin_unlock(&op->lock); \ + wake_up_interruptible(&op->io_completion_waitq);\ +} while (0) + +/* + * Copy to client-core's address space from the buffers specified + * by the iovec upto total_size bytes. + * NOTE: the iovector can either contain addresses which + * can futher be kernel-space or user-space addresses. + * or it can pointers to struct page's + */ +static int precopy_buffers(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *vec, + unsigned long nr_segs, + size_t total_size, + int from_user) +{ + int ret = 0; + + /* + * copy data from application/kernel by pulling it out + * of the iovec. + */ + /* Are we copying from User Virtual Addresses? */ + if (from_user) + ret = pvfs_bufmap_copy_iovec_from_user( + bufmap, + buffer_index, + vec, + nr_segs, + total_size); + /* Are we copying from Kernel Virtual Addresses? */ + else + ret = pvfs_bufmap_copy_iovec_from_kernel( + bufmap, + buffer_index, + vec, + nr_segs, + total_size); + if (ret < 0) + gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", + __func__, + (long)ret); + return ret; +} + +/* + * Copy from client-core's address space to the buffers specified + * by the iovec upto total_size bytes. + * NOTE: the iovector can either contain addresses which + * can futher be kernel-space or user-space addresses. + * or it can pointers to struct page's + */ +static int postcopy_buffers(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *vec, + int nr_segs, + size_t total_size, + int to_user) +{ + int ret = 0; + + /* + * copy data to application/kernel by pushing it out to + * the iovec. NOTE; target buffers can be addresses or + * struct page pointers. + */ + if (total_size) { + /* Are we copying to User Virtual Addresses? */ + if (to_user) + ret = pvfs_bufmap_copy_to_user_iovec( + bufmap, + buffer_index, + vec, + nr_segs, + total_size); + /* Are we copying to Kern Virtual Addresses? */ + else + ret = pvfs_bufmap_copy_to_kernel_iovec( + bufmap, + buffer_index, + vec, + nr_segs, + total_size); + if (ret < 0) + gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", + __func__, + (long)ret); + } + return ret; +} + +/* + * Post and wait for the I/O upcall to finish + */ +static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, + loff_t *offset, struct iovec *vec, unsigned long nr_segs, + size_t total_size, loff_t readahead_size, int to_user) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; + struct pvfs2_bufmap *bufmap = NULL; + struct pvfs2_kernel_op_s *new_op = NULL; + int buffer_index = -1; + ssize_t ret; + + new_op = op_alloc(PVFS2_VFS_OP_FILE_IO); + if (!new_op) { + ret = -ENOMEM; + goto out; + } + /* synchronous I/O */ + new_op->upcall.req.io.async_vfs_io = PVFS_VFS_SYNC_IO; + new_op->upcall.req.io.readahead_size = readahead_size; + new_op->upcall.req.io.io_type = type; + new_op->upcall.req.io.refn = pvfs2_inode->refn; + +populate_shared_memory: + /* get a shared buffer index */ + ret = pvfs_bufmap_get(&bufmap, &buffer_index); + if (ret < 0) { + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: pvfs_bufmap_get failure (%ld)\n", + __func__, (long)ret); + goto out; + } + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): GET op %p -> buffer_index %d\n", + __func__, + handle, + new_op, + buffer_index); + + new_op->uses_shared_memory = 1; + new_op->upcall.req.io.buf_index = buffer_index; + new_op->upcall.req.io.count = total_size; + new_op->upcall.req.io.offset = *offset; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): copy_to_user %d nr_segs %lu, offset: %llu total_size: %zd\n", + __func__, + handle, + to_user, + nr_segs, + llu(*offset), + total_size); + /* + * Stage 1: copy the buffers into client-core's address space + * precopy_buffers only pertains to writes. + */ + if (type == PVFS_IO_WRITE) { + ret = precopy_buffers(bufmap, + buffer_index, + vec, + nr_segs, + total_size, + to_user); + if (ret < 0) + goto out; + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): Calling post_io_request with tag (%llu)\n", + __func__, + handle, + llu(new_op->tag)); + + /* Stage 2: Service the I/O operation */ + ret = service_operation(new_op, + type == PVFS_IO_WRITE ? + "file_write" : + "file_read", + get_interruptible_flag(inode)); + + /* + * If service_operation() returns -EAGAIN #and# the operation was + * purged from pvfs2_request_list or htable_ops_in_progress, then + * we know that the client was restarted, causing the shared memory + * area to be wiped clean. To restart a write operation in this + * case, we must re-copy the data from the user's iovec to a NEW + * shared memory location. To restart a read operation, we must get + * a new shared memory location. + */ + if (ret == -EAGAIN && op_state_purged(new_op)) { + pvfs_bufmap_put(bufmap, buffer_index); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s:going to repopulate_shared_memory.\n", + __func__); + goto populate_shared_memory; + } + + if (ret < 0) { + handle_io_error(); /* defined in pvfs2-kernel.h */ + /* + don't write an error to syslog on signaled operation + termination unless we've got debugging turned on, as + this can happen regularly (i.e. ctrl-c) + */ + if (ret == -EINTR) + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: returning error %ld\n", __func__, + (long)ret); + else + gossip_err("%s: error in %s handle %pU, returning %zd\n", + __func__, + type == PVFS_IO_READ ? + "read from" : "write to", + handle, ret); + goto out; + } + + /* + * Stage 3: Post copy buffers from client-core's address space + * postcopy_buffers only pertains to reads. + */ + if (type == PVFS_IO_READ) { + ret = postcopy_buffers(bufmap, + buffer_index, + vec, + nr_segs, + new_op->downcall.resp.io.amt_complete, + to_user); + if (ret < 0) { + /* + * put error codes in downcall so that handle_io_error() + * preserves it properly + */ + new_op->downcall.status = ret; + handle_io_error(); + goto out; + } + } + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): Amount written as returned by the sys-io call:%d\n", + __func__, + handle, + (int)new_op->downcall.resp.io.amt_complete); + + ret = new_op->downcall.resp.io.amt_complete; + + /* + tell the device file owner waiting on I/O that this read has + completed and it can return now. in this exact case, on + wakeup the daemon will free the op, so we *cannot* touch it + after this. + */ + wake_up_daemon_for_return(new_op); + new_op = NULL; + +out: + if (buffer_index >= 0) { + pvfs_bufmap_put(bufmap, buffer_index); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): PUT buffer_index %d\n", + __func__, handle, buffer_index); + buffer_index = -1; + } + if (new_op) { + op_release(new_op); + new_op = NULL; + } + return ret; +} + +/* + * The reason we need to do this is to be able to support readv and writev + * that are larger than (pvfs_bufmap_size_query()) Default is + * PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB. What that means is that we will + * create a new io vec descriptor for those memory addresses that + * go beyond the limit. Return value for this routine is negative in case + * of errors and 0 in case of success. + * + * Further, the new_nr_segs pointer is updated to hold the new value + * of number of iovecs, the new_vec pointer is updated to hold the pointer + * to the new split iovec, and the size array is an array of integers holding + * the number of iovecs that straddle pvfs_bufmap_size_query(). + * The max_new_nr_segs value is computed by the caller and returned. + * (It will be (count of all iov_len/ block_size) + 1). + */ +static int split_iovecs(unsigned long max_new_nr_segs, /* IN */ + unsigned long nr_segs, /* IN */ + const struct iovec *original_iovec, /* IN */ + unsigned long *new_nr_segs, /* OUT */ + struct iovec **new_vec, /* OUT */ + unsigned long *seg_count, /* OUT */ + unsigned long **seg_array) /* OUT */ +{ + unsigned long seg; + unsigned long count = 0; + unsigned long begin_seg; + unsigned long tmpnew_nr_segs = 0; + struct iovec *new_iovec = NULL; + struct iovec *orig_iovec; + unsigned long *sizes = NULL; + unsigned long sizes_count = 0; + + if (nr_segs <= 0 || + original_iovec == NULL || + new_nr_segs == NULL || + new_vec == NULL || + seg_count == NULL || + seg_array == NULL || + max_new_nr_segs <= 0) { + gossip_err("Invalid parameters to split_iovecs\n"); + return -EINVAL; + } + *new_nr_segs = 0; + *new_vec = NULL; + *seg_count = 0; + *seg_array = NULL; + /* copy the passed in iovec descriptor to a temp structure */ + orig_iovec = kmalloc_array(nr_segs, + sizeof(*orig_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (orig_iovec == NULL) { + gossip_err( + "split_iovecs: Could not allocate memory for %lu bytes!\n", + (unsigned long)(nr_segs * sizeof(*orig_iovec))); + return -ENOMEM; + } + new_iovec = kcalloc(max_new_nr_segs, + sizeof(*new_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (new_iovec == NULL) { + kfree(orig_iovec); + gossip_err( + "split_iovecs: Could not allocate memory for %lu bytes!\n", + (unsigned long)(max_new_nr_segs * sizeof(*new_iovec))); + return -ENOMEM; + } + sizes = kcalloc(max_new_nr_segs, + sizeof(*sizes), + PVFS2_BUFMAP_GFP_FLAGS); + if (sizes == NULL) { + kfree(new_iovec); + kfree(orig_iovec); + gossip_err( + "split_iovecs: Could not allocate memory for %lu bytes!\n", + (unsigned long)(max_new_nr_segs * sizeof(*sizes))); + return -ENOMEM; + } + /* copy the passed in iovec to a temp structure */ + memcpy(orig_iovec, original_iovec, nr_segs * sizeof(*orig_iovec)); + begin_seg = 0; +repeat: + for (seg = begin_seg; seg < nr_segs; seg++) { + if (tmpnew_nr_segs >= max_new_nr_segs || + sizes_count >= max_new_nr_segs) { + kfree(sizes); + kfree(orig_iovec); + kfree(new_iovec); + gossip_err + ("split_iovecs: exceeded the index limit (%lu)\n", + tmpnew_nr_segs); + return -EINVAL; + } + if (count + orig_iovec[seg].iov_len < + pvfs_bufmap_size_query()) { + count += orig_iovec[seg].iov_len; + memcpy(&new_iovec[tmpnew_nr_segs], + &orig_iovec[seg], + sizeof(*new_iovec)); + tmpnew_nr_segs++; + sizes[sizes_count]++; + } else { + new_iovec[tmpnew_nr_segs].iov_base = + orig_iovec[seg].iov_base; + new_iovec[tmpnew_nr_segs].iov_len = + (pvfs_bufmap_size_query() - count); + tmpnew_nr_segs++; + sizes[sizes_count]++; + sizes_count++; + begin_seg = seg; + orig_iovec[seg].iov_base += + (pvfs_bufmap_size_query() - count); + orig_iovec[seg].iov_len -= + (pvfs_bufmap_size_query() - count); + count = 0; + break; + } + } + if (seg != nr_segs) + goto repeat; + else + sizes_count++; + + *new_nr_segs = tmpnew_nr_segs; + /* new_iovec is freed by the caller */ + *new_vec = new_iovec; + *seg_count = sizes_count; + /* seg_array is also freed by the caller */ + *seg_array = sizes; + kfree(orig_iovec); + return 0; +} + +static long bound_max_iovecs(const struct iovec *curr, unsigned long nr_segs, + ssize_t *total_count) +{ + unsigned long i; + long max_nr_iovecs; + ssize_t total; + ssize_t count; + + total = 0; + count = 0; + max_nr_iovecs = 0; + for (i = 0; i < nr_segs; i++) { + const struct iovec *iv = &curr[i]; + + count += iv->iov_len; + if (unlikely((ssize_t) (count | iv->iov_len) < 0)) + return -EINVAL; + if (total + iv->iov_len < pvfs_bufmap_size_query()) { + total += iv->iov_len; + max_nr_iovecs++; + } else { + total = + (total + iv->iov_len - pvfs_bufmap_size_query()); + max_nr_iovecs += (total / pvfs_bufmap_size_query() + 2); + } + } + *total_count = count; + return max_nr_iovecs; +} + +/* + * Common entry point for read/write/readv/writev + * This function will dispatch it to either the direct I/O + * or buffered I/O path depending on the mount options and/or + * augmented/extended metadata attached to the file. + * Note: File extended attributes override any mount options. + */ +static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, + loff_t *offset, const struct iovec *iov, unsigned long nr_segs) +{ + struct inode *inode = file->f_mapping->host; + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; + ssize_t ret; + ssize_t total_count; + unsigned int to_free; + size_t count; + unsigned long seg; + unsigned long new_nr_segs = 0; + unsigned long max_new_nr_segs = 0; + unsigned long seg_count = 0; + unsigned long *seg_array = NULL; + struct iovec *iovecptr = NULL; + struct iovec *ptr = NULL; + + total_count = 0; + ret = -EINVAL; + count = 0; + to_free = 0; + + /* Compute total and max number of segments after split */ + max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count); + if (max_new_nr_segs < 0) { + gossip_lerr("%s: could not bound iovec %lu\n", + __func__, + max_new_nr_segs); + goto out; + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n", + __func__, + handle, + (int)count); + + if (type == PVFS_IO_WRITE) { + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): proceeding with offset : %llu, " + "size %d\n", + __func__, + handle, + llu(*offset), + (int)count); + } + + if (count == 0) { + ret = 0; + goto out; + } + + /* + * if the total size of data transfer requested is greater than + * the kernel-set blocksize of PVFS2, then we split the iovecs + * such that no iovec description straddles a block size limit + */ + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: pvfs_bufmap_size:%d\n", + __func__, + pvfs_bufmap_size_query()); + + if (count > pvfs_bufmap_size_query()) { + /* + * Split up the given iovec description such that + * no iovec descriptor straddles over the block-size limitation. + * This makes us our job easier to stage the I/O. + * In addition, this function will also compute an array + * with seg_count entries that will store the number of + * segments that straddle the block-size boundaries. + */ + ret = split_iovecs(max_new_nr_segs, /* IN */ + nr_segs, /* IN */ + iov, /* IN */ + &new_nr_segs, /* OUT */ + &iovecptr, /* OUT */ + &seg_count, /* OUT */ + &seg_array); /* OUT */ + if (ret < 0) { + gossip_err("%s: Failed to split iovecs to satisfy larger than blocksize readv/writev request %zd\n", + __func__, + ret); + goto out; + } + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: Splitting iovecs from %lu to %lu" + " [max_new %lu]\n", + __func__, + nr_segs, + new_nr_segs, + max_new_nr_segs); + /* We must free seg_array and iovecptr */ + to_free = 1; + } else { + new_nr_segs = nr_segs; + /* use the given iovec description */ + iovecptr = (struct iovec *)iov; + /* There is only 1 element in the seg_array */ + seg_count = 1; + /* and its value is the number of segments passed in */ + seg_array = &nr_segs; + /* We dont have to free up anything */ + to_free = 0; + } + ptr = iovecptr; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU) %zd@%llu\n", + __func__, + handle, + count, + llu(*offset)); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): new_nr_segs: %lu, seg_count: %lu\n", + __func__, + handle, + new_nr_segs, seg_count); + +/* PVFS2_KERNEL_DEBUG is a CFLAGS define. */ +#ifdef PVFS2_KERNEL_DEBUG + for (seg = 0; seg < new_nr_segs; seg++) + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: %d) %p to %p [%d bytes]\n", + __func__, + (int)seg + 1, + iovecptr[seg].iov_base, + iovecptr[seg].iov_base + iovecptr[seg].iov_len, + (int)iovecptr[seg].iov_len); + for (seg = 0; seg < seg_count; seg++) + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: %zd) %lu\n", + __func__, + seg + 1, + seg_array[seg]); +#endif + seg = 0; + while (total_count < count) { + size_t each_count; + size_t amt_complete; + + /* how much to transfer in this loop iteration */ + each_count = + (((count - total_count) > pvfs_bufmap_size_query()) ? + pvfs_bufmap_size_query() : + (count - total_count)); + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): size of each_count(%d)\n", + __func__, + handle, + (int)each_count); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): BEFORE wait_for_io: offset is %d\n", + __func__, + handle, + (int)*offset); + + ret = wait_for_direct_io(type, inode, offset, ptr, + seg_array[seg], each_count, 0, 1); + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): return from wait_for_io:%d\n", + __func__, + handle, + (int)ret); + + if (ret < 0) + goto out; + + /* advance the iovec pointer */ + ptr += seg_array[seg]; + seg++; + *offset += ret; + total_count += ret; + amt_complete = ret; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): AFTER wait_for_io: offset is %d\n", + __func__, + handle, + (int)*offset); + + /* + * if we got a short I/O operations, + * fall out and return what we got so far + */ + if (amt_complete < each_count) + break; + } /*end while */ + + if (total_count > 0) + ret = total_count; +out: + if (to_free) { + kfree(iovecptr); + kfree(seg_array); + } + if (ret > 0) { + if (type == PVFS_IO_READ) { + file_accessed(file); + } else { + SetMtimeFlag(pvfs2_inode); + inode->i_mtime = CURRENT_TIME; + mark_inode_dirty_sync(inode); + } + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): Value(%d) returned.\n", + __func__, + handle, + (int)ret); + + return ret; +} + +/* + * Read data from a specified offset in a file (referenced by inode). + * Data may be placed either in a user or kernel buffer. + */ +ssize_t pvfs2_inode_read(struct inode *inode, + char __user *buf, + size_t count, + loff_t *offset, + loff_t readahead_size) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + size_t bufmap_size; + struct iovec vec; + ssize_t ret = -EINVAL; + + g_pvfs2_stats.reads++; + + vec.iov_base = buf; + vec.iov_len = count; + + bufmap_size = pvfs_bufmap_size_query(); + if (count > bufmap_size) { + gossip_debug(GOSSIP_FILE_DEBUG, + "%s: count is too large (%zd/%zd)!\n", + __func__, count, bufmap_size); + return -EINVAL; + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU) %zd@%llu\n", + __func__, + &pvfs2_inode->refn.khandle, + count, + llu(*offset)); + + ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &vec, 1, + count, readahead_size, 0); + if (ret > 0) + *offset += ret; + + gossip_debug(GOSSIP_FILE_DEBUG, + "%s(%pU): Value(%zd) returned.\n", + __func__, + &pvfs2_inode->refn.khandle, + ret); + + return ret; +} + +static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct file *file = iocb->ki_filp; + loff_t pos = *(&iocb->ki_pos); + ssize_t rc = 0; + unsigned long nr_segs = iter->nr_segs; + + BUG_ON(iocb->private); + + gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_read_iter\n"); + + g_pvfs2_stats.reads++; + + rc = do_readv_writev(PVFS_IO_READ, + file, + &pos, + iter->iov, + nr_segs); + iocb->ki_pos = pos; + + return rc; +} + +static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct file *file = iocb->ki_filp; + loff_t pos = *(&iocb->ki_pos); + unsigned long nr_segs = iter->nr_segs; + ssize_t rc; + + BUG_ON(iocb->private); + + gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_write_iter\n"); + + mutex_lock(&file->f_mapping->host->i_mutex); + + /* Make sure generic_write_checks sees an up to date inode size. */ + if (file->f_flags & O_APPEND) { + rc = pvfs2_inode_getattr(file->f_mapping->host, + PVFS_ATTR_SYS_SIZE); + if (rc) { + gossip_err("%s: pvfs2_inode_getattr failed, rc:%zd:.\n", + __func__, rc); + goto out; + } + } + + if (file->f_pos > i_size_read(file->f_mapping->host)) + pvfs2_i_size_write(file->f_mapping->host, file->f_pos); + + rc = generic_write_checks(iocb, iter); + + if (rc <= 0) { + gossip_err("%s: generic_write_checks failed, rc:%zd:.\n", + __func__, rc); + goto out; + } + + rc = do_readv_writev(PVFS_IO_WRITE, + file, + &pos, + iter->iov, + nr_segs); + if (rc < 0) { + gossip_err("%s: do_readv_writev failed, rc:%zd:.\n", + __func__, rc); + goto out; + } + + iocb->ki_pos = pos; + g_pvfs2_stats.writes++; + +out: + + mutex_unlock(&file->f_mapping->host->i_mutex); + return rc; +} + +/* + * Perform a miscellaneous operation on a file. + */ +long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -ENOTTY; + __u64 val = 0; + unsigned long uval; + + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_ioctl: called with cmd %d\n", + cmd); + + /* + * we understand some general ioctls on files, such as the immutable + * and append flags + */ + if (cmd == FS_IOC_GETFLAGS) { + val = 0; + ret = pvfs2_xattr_get_default(file->f_path.dentry, + "user.pvfs2.meta_hint", + &val, + sizeof(val), + 0); + if (ret < 0 && ret != -ENODATA) + return ret; + else if (ret == -ENODATA) + val = 0; + uval = val; + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_ioctl: FS_IOC_GETFLAGS: %llu\n", + (unsigned long long)uval); + return put_user(uval, (int __user *)arg); + } else if (cmd == FS_IOC_SETFLAGS) { + ret = 0; + if (get_user(uval, (int __user *)arg)) + return -EFAULT; + /* + * PVFS_MIRROR_FL is set internally when the mirroring mode + * is turned on for a file. The user is not allowed to turn + * on this bit, but the bit is present if the user first gets + * the flags and then updates the flags with some new + * settings. So, we ignore it in the following edit. bligon. + */ + if ((uval & ~PVFS_MIRROR_FL) & + (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) { + gossip_err("pvfs2_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n"); + return -EINVAL; + } + val = uval; + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_ioctl: FS_IOC_SETFLAGS: %llu\n", + (unsigned long long)val); + ret = pvfs2_xattr_set_default(file->f_path.dentry, + "user.pvfs2.meta_hint", + &val, + sizeof(val), + 0, + 0); + } + + return ret; +} + +/* + * Memory map a region of a file. + */ +static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_file_mmap: called on %s\n", + (file ? + (char *)file->f_path.dentry->d_name.name : + (char *)"Unknown")); + + /* set the sequential readahead hint */ + vma->vm_flags |= VM_SEQ_READ; + vma->vm_flags &= ~VM_RAND_READ; + return generic_file_mmap(file, vma); +} + +#define mapping_nrpages(idata) ((idata)->nrpages) + +/* + * Called to notify the module that there are no more references to + * this file (i.e. no processes have it open). + * + * \note Not called when each file is closed. + */ +int pvfs2_file_release(struct inode *inode, struct file *file) +{ + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_file_release: called on %s\n", + file->f_path.dentry->d_name.name); + + pvfs2_flush_inode(inode); + + /* + remove all associated inode pages from the page cache and mmap + readahead cache (if any); this forces an expensive refresh of + data for the next caller of mmap (or 'get_block' accesses) + */ + if (file->f_path.dentry->d_inode && + file->f_path.dentry->d_inode->i_mapping && + mapping_nrpages(&file->f_path.dentry->d_inode->i_data)) + truncate_inode_pages(file->f_path.dentry->d_inode->i_mapping, + 0); + return 0; +} + +/* + * Push all data for a specific file onto permanent storage. + */ +int pvfs2_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + int ret = -EINVAL; + struct pvfs2_inode_s *pvfs2_inode = + PVFS2_I(file->f_path.dentry->d_inode); + struct pvfs2_kernel_op_s *new_op = NULL; + + /* required call */ + filemap_write_and_wait_range(file->f_mapping, start, end); + + new_op = op_alloc(PVFS2_VFS_OP_FSYNC); + if (!new_op) + return -ENOMEM; + new_op->upcall.req.fsync.refn = pvfs2_inode->refn; + + ret = service_operation(new_op, + "pvfs2_fsync", + get_interruptible_flag(file->f_path.dentry->d_inode)); + + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_fsync got return value of %d\n", + ret); + + op_release(new_op); + + pvfs2_flush_inode(file->f_path.dentry->d_inode); + return ret; +} + +/* + * Change the file pointer position for an instance of an open file. + * + * \note If .llseek is overriden, we must acquire lock as described in + * Documentation/filesystems/Locking. + * + * Future upgrade could support SEEK_DATA and SEEK_HOLE but would + * require much changes to the FS + */ +loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) +{ + int ret = -EINVAL; + struct inode *inode = file->f_path.dentry->d_inode; + + if (!inode) { + gossip_err("pvfs2_file_llseek: invalid inode (NULL)\n"); + return ret; + } + + if (origin == PVFS2_SEEK_END) { + /* + * revalidate the inode's file size. + * NOTE: We are only interested in file size here, + * so we set mask accordingly. + */ + ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_SIZE); + if (ret) { + gossip_debug(GOSSIP_FILE_DEBUG, + "%s:%s:%d calling make bad inode\n", + __FILE__, + __func__, + __LINE__); + pvfs2_make_bad_inode(inode); + return ret; + } + } + + gossip_debug(GOSSIP_FILE_DEBUG, + "pvfs2_file_llseek: offset is %ld | origin is %d | " + "inode size is %lu\n", + (long)offset, + origin, + (unsigned long)file->f_path.dentry->d_inode->i_size); + + return generic_file_llseek(file, offset, origin); +} + +/* + * Support local locks (locks that only this kernel knows about) + * if Orangefs was mounted -o local_lock. + */ +int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) +{ + int rc = -ENOLCK; + + if (PVFS2_SB(filp->f_inode->i_sb)->flags & PVFS2_OPT_LOCAL_LOCK) { + if (cmd == F_GETLK) { + rc = 0; + posix_test_lock(filp, fl); + } else { + rc = posix_lock_file(filp, fl, NULL); + } + } + + return rc; +} + +/** PVFS2 implementation of VFS file operations */ +const struct file_operations pvfs2_file_operations = { + .llseek = pvfs2_file_llseek, + .read_iter = pvfs2_file_read_iter, + .write_iter = pvfs2_file_write_iter, + .lock = pvfs2_lock, + .unlocked_ioctl = pvfs2_ioctl, + .mmap = pvfs2_file_mmap, + .open = generic_file_open, + .release = pvfs2_file_release, + .fsync = pvfs2_fsync, +}; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c new file mode 100644 index 000000000000..feda00fcdd7d --- /dev/null +++ b/fs/orangefs/inode.c @@ -0,0 +1,469 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Linux VFS inode operations. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +static int read_one_page(struct page *page) +{ + void *page_data; + int ret; + int max_block; + ssize_t bytes_read = 0; + struct inode *inode = page->mapping->host; + const __u32 blocksize = PAGE_CACHE_SIZE; /* inode->i_blksize */ + const __u32 blockbits = PAGE_CACHE_SHIFT; /* inode->i_blkbits */ + + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_readpage called with page %p\n", + page); + page_data = pvfs2_kmap(page); + + max_block = ((inode->i_size / blocksize) + 1); + + if (page->index < max_block) { + loff_t blockptr_offset = (((loff_t) page->index) << blockbits); + + bytes_read = pvfs2_inode_read(inode, + page_data, + blocksize, + &blockptr_offset, + inode->i_size); + } + /* only zero remaining unread portions of the page data */ + if (bytes_read > 0) + memset(page_data + bytes_read, 0, blocksize - bytes_read); + else + memset(page_data, 0, blocksize); + /* takes care of potential aliasing */ + flush_dcache_page(page); + if (bytes_read < 0) { + ret = bytes_read; + SetPageError(page); + } else { + SetPageUptodate(page); + if (PageError(page)) + ClearPageError(page); + ret = 0; + } + pvfs2_kunmap(page); + /* unlock the page after the ->readpage() routine completes */ + unlock_page(page); + return ret; +} + +static int pvfs2_readpage(struct file *file, struct page *page) +{ + return read_one_page(page); +} + +static int pvfs2_readpages(struct file *file, + struct address_space *mapping, + struct list_head *pages, + unsigned nr_pages) +{ + int page_idx; + int ret; + + gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpages called\n"); + + for (page_idx = 0; page_idx < nr_pages; page_idx++) { + struct page *page; + + page = list_entry(pages->prev, struct page, lru); + list_del(&page->lru); + if (!add_to_page_cache(page, + mapping, + page->index, + GFP_KERNEL)) { + ret = read_one_page(page); + gossip_debug(GOSSIP_INODE_DEBUG, + "failure adding page to cache, read_one_page returned: %d\n", + ret); + } else { + page_cache_release(page); + } + } + BUG_ON(!list_empty(pages)); + return 0; +} + +static void pvfs2_invalidatepage(struct page *page, + unsigned int offset, + unsigned int length) +{ + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_invalidatepage called on page %p " + "(offset is %u)\n", + page, + offset); + + ClearPageUptodate(page); + ClearPageMappedToDisk(page); + return; + +} + +static int pvfs2_releasepage(struct page *page, gfp_t foo) +{ + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_releasepage called on page %p\n", + page); + return 0; +} + +/* + * Having a direct_IO entry point in the address_space_operations + * struct causes the kernel to allows us to use O_DIRECT on + * open. Nothing will ever call this thing, but in the future we + * will need to be able to use O_DIRECT on open in order to support + * AIO. Modeled after NFS, they do this too. + */ +/* +static ssize_t pvfs2_direct_IO(int rw, + struct kiocb *iocb, + struct iov_iter *iter, + loff_t offset) +{ + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_direct_IO: %s\n", + iocb->ki_filp->f_path.dentry->d_name.name); + + return -EINVAL; +} +*/ + +struct backing_dev_info pvfs2_backing_dev_info = { + .name = "pvfs2", + .ra_pages = 0, + .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, +}; + +/** PVFS2 implementation of address space operations */ +const struct address_space_operations pvfs2_address_operations = { + .readpage = pvfs2_readpage, + .readpages = pvfs2_readpages, + .invalidatepage = pvfs2_invalidatepage, + .releasepage = pvfs2_releasepage, +/* .direct_IO = pvfs2_direct_IO */ +}; + +static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op; + loff_t orig_size = i_size_read(inode); + int ret = -EINVAL; + + gossip_debug(GOSSIP_INODE_DEBUG, + "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n", + __func__, + get_khandle_from_ino(inode), + &pvfs2_inode->refn.khandle, + pvfs2_inode->refn.fs_id, + iattr->ia_size); + + truncate_setsize(inode, iattr->ia_size); + + new_op = op_alloc(PVFS2_VFS_OP_TRUNCATE); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.truncate.refn = pvfs2_inode->refn; + new_op->upcall.req.truncate.size = (__s64) iattr->ia_size; + + ret = service_operation(new_op, __func__, + get_interruptible_flag(inode)); + + /* + * the truncate has no downcall members to retrieve, but + * the status value tells us if it went through ok or not + */ + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2: pvfs2_truncate got return value of %d\n", + ret); + + op_release(new_op); + + if (ret != 0) + return ret; + + /* + * Only change the c/mtime if we are changing the size or we are + * explicitly asked to change it. This handles the semantic difference + * between truncate() and ftruncate() as implemented in the VFS. + * + * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a + * special case where we need to update the times despite not having + * these flags set. For all other operations the VFS set these flags + * explicitly if it wants a timestamp update. + */ + if (orig_size != i_size_read(inode) && + !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { + iattr->ia_ctime = iattr->ia_mtime = + current_fs_time(inode->i_sb); + iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; + } + + return ret; +} + +/* + * Change attributes of an object referenced by dentry. + */ +int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr) +{ + int ret = -EINVAL; + struct inode *inode = dentry->d_inode; + + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_setattr: called on %s\n", + dentry->d_name.name); + + ret = inode_change_ok(inode, iattr); + if (ret) + goto out; + + if ((iattr->ia_valid & ATTR_SIZE) && + iattr->ia_size != i_size_read(inode)) { + ret = pvfs2_setattr_size(inode, iattr); + if (ret) + goto out; + } + + setattr_copy(inode, iattr); + mark_inode_dirty(inode); + + ret = pvfs2_inode_setattr(inode, iattr); + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_setattr: inode_setattr returned %d\n", + ret); + + if (!ret && (iattr->ia_valid & ATTR_MODE)) + /* change mod on a file that has ACLs */ + ret = posix_acl_chmod(inode, inode->i_mode); + +out: + gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: returning %d\n", ret); + return ret; +} + +/* + * Obtain attributes of an object given a dentry + */ +int pvfs2_getattr(struct vfsmount *mnt, + struct dentry *dentry, + struct kstat *kstat) +{ + int ret = -ENOENT; + struct inode *inode = dentry->d_inode; + struct pvfs2_inode_s *pvfs2_inode = NULL; + + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_getattr: called on %s\n", + dentry->d_name.name); + + /* + * Similar to the above comment, a getattr also expects that all + * fields/attributes of the inode would be refreshed. So again, we + * dont have too much of a choice but refresh all the attributes. + */ + ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + if (ret == 0) { + generic_fillattr(inode, kstat); + /* override block size reported to stat */ + pvfs2_inode = PVFS2_I(inode); + kstat->blksize = pvfs2_inode->blksize; + } else { + /* assume an I/O error and flag inode as bad */ + gossip_debug(GOSSIP_INODE_DEBUG, + "%s:%s:%d calling make bad inode\n", + __FILE__, + __func__, + __LINE__); + pvfs2_make_bad_inode(inode); + } + return ret; +} + +/* PVFS2 implementation of VFS inode operations for files */ +struct inode_operations pvfs2_file_inode_operations = { + .get_acl = pvfs2_get_acl, + .set_acl = pvfs2_set_acl, + .setattr = pvfs2_setattr, + .getattr = pvfs2_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .listxattr = pvfs2_listxattr, + .removexattr = generic_removexattr, +}; + +static int pvfs2_init_iops(struct inode *inode) +{ + inode->i_mapping->a_ops = &pvfs2_address_operations; + + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + inode->i_op = &pvfs2_file_inode_operations; + inode->i_fop = &pvfs2_file_operations; + inode->i_blkbits = PAGE_CACHE_SHIFT; + break; + case S_IFLNK: + inode->i_op = &pvfs2_symlink_inode_operations; + break; + case S_IFDIR: + inode->i_op = &pvfs2_dir_inode_operations; + inode->i_fop = &pvfs2_dir_operations; + break; + default: + gossip_debug(GOSSIP_INODE_DEBUG, + "%s: unsupported mode\n", + __func__); + return -EINVAL; + } + + return 0; +} + +/* + * Given a PVFS2 object identifier (fsid, handle), convert it into a ino_t type + * that will be used as a hash-index from where the handle will + * be searched for in the VFS hash table of inodes. + */ +static inline ino_t pvfs2_handle_hash(struct pvfs2_object_kref *ref) +{ + if (!ref) + return 0; + return pvfs2_khandle_to_ino(&(ref->khandle)); +} + +/* + * Called to set up an inode from iget5_locked. + */ +static int pvfs2_set_inode(struct inode *inode, void *data) +{ + struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data; + struct pvfs2_inode_s *pvfs2_inode = NULL; + + /* Make sure that we have sane parameters */ + if (!data || !inode) + return 0; + pvfs2_inode = PVFS2_I(inode); + if (!pvfs2_inode) + return 0; + pvfs2_inode->refn.fs_id = ref->fs_id; + pvfs2_inode->refn.khandle = ref->khandle; + return 0; +} + +/* + * Called to determine if handles match. + */ +static int pvfs2_test_inode(struct inode *inode, void *data) +{ + struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data; + struct pvfs2_inode_s *pvfs2_inode = NULL; + + pvfs2_inode = PVFS2_I(inode); + return (!PVFS_khandle_cmp(&(pvfs2_inode->refn.khandle), &(ref->khandle)) + && pvfs2_inode->refn.fs_id == ref->fs_id); +} + +/* + * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2 + * file handle. + * + * @sb: the file system super block instance. + * @ref: The PVFS2 object for which we are trying to locate an inode structure. + */ +struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref) +{ + struct inode *inode = NULL; + unsigned long hash; + int error; + + hash = pvfs2_handle_hash(ref); + inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref); + if (!inode || !(inode->i_state & I_NEW)) + return inode; + + error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + if (error) { + iget_failed(inode); + return ERR_PTR(error); + } + + inode->i_ino = hash; /* needed for stat etc */ + pvfs2_init_iops(inode); + unlock_new_inode(inode); + + gossip_debug(GOSSIP_INODE_DEBUG, + "iget handle %pU, fsid %d hash %ld i_ino %lu\n", + &ref->khandle, + ref->fs_id, + hash, + inode->i_ino); + + return inode; +} + +/* + * Allocate an inode for a newly created file and insert it into the inode hash. + */ +struct inode *pvfs2_new_inode(struct super_block *sb, struct inode *dir, + int mode, dev_t dev, struct pvfs2_object_kref *ref) +{ + unsigned long hash = pvfs2_handle_hash(ref); + struct inode *inode; + int error; + + gossip_debug(GOSSIP_INODE_DEBUG, + "pvfs2_get_custom_inode_common: called\n" + "(sb is %p | MAJOR(dev)=%u | MINOR(dev)=%u mode=%o)\n", + sb, + MAJOR(dev), + MINOR(dev), + mode); + + inode = new_inode(sb); + if (!inode) + return NULL; + + pvfs2_set_inode(inode, ref); + inode->i_ino = hash; /* needed for stat etc */ + + error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + if (error) + goto out_iput; + + pvfs2_init_iops(inode); + + inode->i_mode = mode; + inode->i_uid = current_fsuid(); + inode->i_gid = current_fsgid(); + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_size = PAGE_CACHE_SIZE; + inode->i_rdev = dev; + + error = insert_inode_locked4(inode, hash, pvfs2_test_inode, ref); + if (error < 0) + goto out_iput; + + gossip_debug(GOSSIP_INODE_DEBUG, + "Initializing ACL's for inode %pU\n", + get_khandle_from_ino(inode)); + pvfs2_init_acl(inode, dir); + return inode; + +out_iput: + iput(inode); + return ERR_PTR(error); +} -- GitLab From 274dcf55bd4ab12af1cc1d3b77416285bef8ebf4 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:13 -0400 Subject: [PATCH 0003/5324] Orangefs: kernel client part 3 Signed-off-by: Mike Marshall --- fs/orangefs/namei.c | 473 ++++++++++++++++++ fs/orangefs/pvfs2-bufmap.c | 970 ++++++++++++++++++++++++++++++++++++ fs/orangefs/pvfs2-cache.c | 260 ++++++++++ fs/orangefs/pvfs2-debugfs.c | 458 +++++++++++++++++ fs/orangefs/pvfs2-mod.c | 316 ++++++++++++ 5 files changed, 2477 insertions(+) create mode 100644 fs/orangefs/namei.c create mode 100644 fs/orangefs/pvfs2-bufmap.c create mode 100644 fs/orangefs/pvfs2-cache.c create mode 100644 fs/orangefs/pvfs2-debugfs.c create mode 100644 fs/orangefs/pvfs2-mod.c diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c new file mode 100644 index 000000000000..747fe6a690af --- /dev/null +++ b/fs/orangefs/namei.c @@ -0,0 +1,473 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Linux VFS namei operations. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" + +/* + * Get a newly allocated inode to go with a negative dentry. + */ +static int pvfs2_create(struct inode *dir, + struct dentry *dentry, + umode_t mode, + bool exclusive) +{ + struct pvfs2_inode_s *parent = PVFS2_I(dir); + struct pvfs2_kernel_op_s *new_op; + struct inode *inode; + int ret; + + gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); + + new_op = op_alloc(PVFS2_VFS_OP_CREATE); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.create.parent_refn = parent->refn; + + fill_default_sys_attrs(new_op->upcall.req.create.attributes, + PVFS_TYPE_METAFILE, mode); + + strncpy(new_op->upcall.req.create.d_name, + dentry->d_name.name, PVFS2_NAME_LEN); + + ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Create Got PVFS2 handle %pU on fsid %d (ret=%d)\n", + &new_op->downcall.resp.create.refn.khandle, + new_op->downcall.resp.create.refn.fs_id, ret); + + if (ret < 0) { + gossip_debug(GOSSIP_NAME_DEBUG, + "%s: failed with error code %d\n", + __func__, ret); + goto out; + } + + inode = pvfs2_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, + &new_op->downcall.resp.create.refn); + if (IS_ERR(inode)) { + gossip_err("*** Failed to allocate pvfs2 file inode\n"); + ret = PTR_ERR(inode); + goto out; + } + + gossip_debug(GOSSIP_NAME_DEBUG, + "Assigned file inode new number of %pU\n", + get_khandle_from_ino(inode)); + + d_instantiate(dentry, inode); + unlock_new_inode(inode); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Inode (Regular File) %pU -> %s\n", + get_khandle_from_ino(inode), + dentry->d_name.name); + + SetMtimeFlag(parent); + dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); + mark_inode_dirty_sync(dir); + ret = 0; +out: + op_release(new_op); + gossip_debug(GOSSIP_NAME_DEBUG, "%s: returning %d\n", __func__, ret); + return ret; +} + +/* + * Attempt to resolve an object name (dentry->d_name), parent handle, and + * fsid into a handle for the object. + */ +static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags) +{ + struct pvfs2_inode_s *parent = PVFS2_I(dir); + struct pvfs2_kernel_op_s *new_op; + struct inode *inode; + struct dentry *res; + int ret = -EINVAL; + + /* + * in theory we could skip a lookup here (if the intent is to + * create) in order to avoid a potentially failed lookup, but + * leaving it in can skip a valid lookup and try to create a file + * that already exists (e.g. the vfs already handles checking for + * -EEXIST on O_EXCL opens, which is broken if we skip this lookup + * in the create path) + */ + gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %s\n", + __func__, dentry->d_name.name); + + if (dentry->d_name.len > (PVFS2_NAME_LEN - 1)) + return ERR_PTR(-ENAMETOOLONG); + + new_op = op_alloc(PVFS2_VFS_OP_LOOKUP); + if (!new_op) + return ERR_PTR(-ENOMEM); + + new_op->upcall.req.lookup.sym_follow = flags & LOOKUP_FOLLOW; + + gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", + __FILE__, + __func__, + __LINE__, + &parent->refn.khandle); + new_op->upcall.req.lookup.parent_refn = parent->refn; + + strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, + PVFS2_NAME_LEN); + + gossip_debug(GOSSIP_NAME_DEBUG, + "%s: doing lookup on %s under %pU,%d (follow=%s)\n", + __func__, + new_op->upcall.req.lookup.d_name, + &new_op->upcall.req.lookup.parent_refn.khandle, + new_op->upcall.req.lookup.parent_refn.fs_id, + ((new_op->upcall.req.lookup.sym_follow == + PVFS2_LOOKUP_LINK_FOLLOW) ? "yes" : "no")); + + ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Lookup Got %pU, fsid %d (ret=%d)\n", + &new_op->downcall.resp.lookup.refn.khandle, + new_op->downcall.resp.lookup.refn.fs_id, + ret); + + if (ret < 0) { + if (ret == -ENOENT) { + /* + * if no inode was found, add a negative dentry to + * dcache anyway; if we don't, we don't hold expected + * lookup semantics and we most noticeably break + * during directory renames. + * + * however, if the operation failed or exited, do not + * add the dentry (e.g. in the case that a touch is + * issued on a file that already exists that was + * interrupted during this lookup -- no need to add + * another negative dentry for an existing file) + */ + + gossip_debug(GOSSIP_NAME_DEBUG, + "pvfs2_lookup: Adding *negative* dentry " + "%p for %s\n", + dentry, + dentry->d_name.name); + + d_add(dentry, NULL); + res = NULL; + goto out; + } + + /* must be a non-recoverable error */ + res = ERR_PTR(ret); + goto out; + } + + inode = pvfs2_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); + if (IS_ERR(inode)) { + gossip_debug(GOSSIP_NAME_DEBUG, + "error %ld from iget\n", PTR_ERR(inode)); + res = ERR_CAST(inode); + goto out; + } + + gossip_debug(GOSSIP_NAME_DEBUG, + "%s:%s:%d " + "Found good inode [%lu] with count [%d]\n", + __FILE__, + __func__, + __LINE__, + inode->i_ino, + (int)atomic_read(&inode->i_count)); + + /* update dentry/inode pair into dcache */ + res = d_splice_alias(inode, dentry); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Lookup success (inode ct = %d)\n", + (int)atomic_read(&inode->i_count)); +out: + op_release(new_op); + return res; +} + +/* return 0 on success; non-zero otherwise */ +static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct pvfs2_inode_s *parent = PVFS2_I(dir); + struct pvfs2_kernel_op_s *new_op; + int ret; + + gossip_debug(GOSSIP_NAME_DEBUG, + "%s: called on %s\n" + " (inode %pU): Parent is %pU | fs_id %d\n", + __func__, + dentry->d_name.name, + get_khandle_from_ino(inode), + &parent->refn.khandle, + parent->refn.fs_id); + + new_op = op_alloc(PVFS2_VFS_OP_REMOVE); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.remove.parent_refn = parent->refn; + strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name, + PVFS2_NAME_LEN); + + ret = service_operation(new_op, "pvfs2_unlink", + get_interruptible_flag(inode)); + + /* when request is serviced properly, free req op struct */ + op_release(new_op); + + if (!ret) { + drop_nlink(inode); + + SetMtimeFlag(parent); + dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); + mark_inode_dirty_sync(dir); + } + return ret; +} + +/* + * pvfs2_link() is only implemented here to make sure that we return a + * reasonable error code (the kernel will return a misleading EPERM + * otherwise). PVFS2 does not support hard links. + */ +static int pvfs2_link(struct dentry *old_dentry, + struct inode *dir, + struct dentry *dentry) +{ + return -EOPNOTSUPP; +} + +/* + * pvfs2_mknod() is only implemented here to make sure that we return a + * reasonable error code (the kernel will return a misleading EPERM + * otherwise). PVFS2 does not support special files such as fifos or devices. + */ +static int pvfs2_mknod(struct inode *dir, + struct dentry *dentry, + umode_t mode, + dev_t rdev) +{ + return -EOPNOTSUPP; +} + +static int pvfs2_symlink(struct inode *dir, + struct dentry *dentry, + const char *symname) +{ + struct pvfs2_inode_s *parent = PVFS2_I(dir); + struct pvfs2_kernel_op_s *new_op; + struct inode *inode; + int mode = 755; + int ret; + + gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); + + if (!symname) + return -EINVAL; + + new_op = op_alloc(PVFS2_VFS_OP_SYMLINK); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.sym.parent_refn = parent->refn; + + fill_default_sys_attrs(new_op->upcall.req.sym.attributes, + PVFS_TYPE_SYMLINK, + mode); + + strncpy(new_op->upcall.req.sym.entry_name, + dentry->d_name.name, + PVFS2_NAME_LEN); + strncpy(new_op->upcall.req.sym.target, symname, PVFS2_NAME_LEN); + + ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Symlink Got PVFS2 handle %pU on fsid %d (ret=%d)\n", + &new_op->downcall.resp.sym.refn.khandle, + new_op->downcall.resp.sym.refn.fs_id, ret); + + if (ret < 0) { + gossip_debug(GOSSIP_NAME_DEBUG, + "%s: failed with error code %d\n", + __func__, ret); + goto out; + } + + inode = pvfs2_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, + &new_op->downcall.resp.sym.refn); + if (IS_ERR(inode)) { + gossip_err + ("*** Failed to allocate pvfs2 symlink inode\n"); + ret = PTR_ERR(inode); + goto out; + } + + gossip_debug(GOSSIP_NAME_DEBUG, + "Assigned symlink inode new number of %pU\n", + get_khandle_from_ino(inode)); + + d_instantiate(dentry, inode); + unlock_new_inode(inode); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Inode (Symlink) %pU -> %s\n", + get_khandle_from_ino(inode), + dentry->d_name.name); + + SetMtimeFlag(parent); + dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); + mark_inode_dirty_sync(dir); + ret = 0; +out: + op_release(new_op); + return ret; +} + +static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +{ + struct pvfs2_inode_s *parent = PVFS2_I(dir); + struct pvfs2_kernel_op_s *new_op; + struct inode *inode; + int ret; + + new_op = op_alloc(PVFS2_VFS_OP_MKDIR); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.mkdir.parent_refn = parent->refn; + + fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes, + PVFS_TYPE_DIRECTORY, mode); + + strncpy(new_op->upcall.req.mkdir.d_name, + dentry->d_name.name, PVFS2_NAME_LEN); + + ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Mkdir Got PVFS2 handle %pU on fsid %d\n", + &new_op->downcall.resp.mkdir.refn.khandle, + new_op->downcall.resp.mkdir.refn.fs_id); + + if (ret < 0) { + gossip_debug(GOSSIP_NAME_DEBUG, + "%s: failed with error code %d\n", + __func__, ret); + goto out; + } + + inode = pvfs2_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, + &new_op->downcall.resp.mkdir.refn); + if (IS_ERR(inode)) { + gossip_err("*** Failed to allocate pvfs2 dir inode\n"); + ret = PTR_ERR(inode); + goto out; + } + + gossip_debug(GOSSIP_NAME_DEBUG, + "Assigned dir inode new number of %pU\n", + get_khandle_from_ino(inode)); + + d_instantiate(dentry, inode); + unlock_new_inode(inode); + + gossip_debug(GOSSIP_NAME_DEBUG, + "Inode (Directory) %pU -> %s\n", + get_khandle_from_ino(inode), + dentry->d_name.name); + + /* + * NOTE: we have no good way to keep nlink consistent for directories + * across clients; keep constant at 1. + */ + SetMtimeFlag(parent); + dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); + mark_inode_dirty_sync(dir); +out: + op_release(new_op); + return ret; +} + +static int pvfs2_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry) +{ + struct pvfs2_kernel_op_s *new_op; + int ret; + + gossip_debug(GOSSIP_NAME_DEBUG, + "pvfs2_rename: called (%s/%s => %s/%s) ct=%d\n", + old_dentry->d_parent->d_name.name, + old_dentry->d_name.name, + new_dentry->d_parent->d_name.name, + new_dentry->d_name.name, + d_count(new_dentry)); + + new_op = op_alloc(PVFS2_VFS_OP_RENAME); + if (!new_op) + return -EINVAL; + + new_op->upcall.req.rename.old_parent_refn = PVFS2_I(old_dir)->refn; + new_op->upcall.req.rename.new_parent_refn = PVFS2_I(new_dir)->refn; + + strncpy(new_op->upcall.req.rename.d_old_name, + old_dentry->d_name.name, + PVFS2_NAME_LEN); + strncpy(new_op->upcall.req.rename.d_new_name, + new_dentry->d_name.name, + PVFS2_NAME_LEN); + + ret = service_operation(new_op, + "pvfs2_rename", + get_interruptible_flag(old_dentry->d_inode)); + + gossip_debug(GOSSIP_NAME_DEBUG, + "pvfs2_rename: got downcall status %d\n", + ret); + + if (new_dentry->d_inode) + new_dentry->d_inode->i_ctime = CURRENT_TIME; + + op_release(new_op); + return ret; +} + +/* PVFS2 implementation of VFS inode operations for directories */ +struct inode_operations pvfs2_dir_inode_operations = { + .lookup = pvfs2_lookup, + .get_acl = pvfs2_get_acl, + .set_acl = pvfs2_set_acl, + .create = pvfs2_create, + .link = pvfs2_link, + .unlink = pvfs2_unlink, + .symlink = pvfs2_symlink, + .mkdir = pvfs2_mkdir, + .rmdir = pvfs2_unlink, + .mknod = pvfs2_mknod, + .rename = pvfs2_rename, + .setattr = pvfs2_setattr, + .getattr = pvfs2_getattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, + .removexattr = generic_removexattr, + .listxattr = pvfs2_listxattr, +}; diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c new file mode 100644 index 000000000000..aa14c37d0216 --- /dev/null +++ b/fs/orangefs/pvfs2-bufmap.c @@ -0,0 +1,970 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +DECLARE_WAIT_QUEUE_HEAD(pvfs2_bufmap_init_waitq); + +struct pvfs2_bufmap { + atomic_t refcnt; + + int desc_size; + int desc_shift; + int desc_count; + int total_size; + int page_count; + + struct page **page_array; + struct pvfs_bufmap_desc *desc_array; + + /* array to track usage of buffer descriptors */ + int *buffer_index_array; + spinlock_t buffer_index_lock; + + /* array to track usage of buffer descriptors for readdir */ + int readdir_index_array[PVFS2_READDIR_DEFAULT_DESC_COUNT]; + spinlock_t readdir_index_lock; +} *__pvfs2_bufmap; + +static DEFINE_SPINLOCK(pvfs2_bufmap_lock); + +static void +pvfs2_bufmap_unmap(struct pvfs2_bufmap *bufmap) +{ + int i; + + for (i = 0; i < bufmap->page_count; i++) + page_cache_release(bufmap->page_array[i]); +} + +static void +pvfs2_bufmap_free(struct pvfs2_bufmap *bufmap) +{ + kfree(bufmap->page_array); + kfree(bufmap->desc_array); + kfree(bufmap->buffer_index_array); + kfree(bufmap); +} + +struct pvfs2_bufmap *pvfs2_bufmap_ref(void) +{ + struct pvfs2_bufmap *bufmap = NULL; + + spin_lock(&pvfs2_bufmap_lock); + if (__pvfs2_bufmap) { + bufmap = __pvfs2_bufmap; + atomic_inc(&bufmap->refcnt); + } + spin_unlock(&pvfs2_bufmap_lock); + return bufmap; +} + +void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap) +{ + if (atomic_dec_and_lock(&bufmap->refcnt, &pvfs2_bufmap_lock)) { + __pvfs2_bufmap = NULL; + spin_unlock(&pvfs2_bufmap_lock); + + pvfs2_bufmap_unmap(bufmap); + pvfs2_bufmap_free(bufmap); + } +} + +inline int pvfs_bufmap_size_query(void) +{ + struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + int size = bufmap ? bufmap->desc_size : 0; + + pvfs2_bufmap_unref(bufmap); + return size; +} + +inline int pvfs_bufmap_shift_query(void) +{ + struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + int shift = bufmap ? bufmap->desc_shift : 0; + + pvfs2_bufmap_unref(bufmap); + return shift; +} + +static DECLARE_WAIT_QUEUE_HEAD(bufmap_waitq); +static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq); + +/* + * get_bufmap_init + * + * If bufmap_init is 1, then the shared memory system, including the + * buffer_index_array, is available. Otherwise, it is not. + * + * returns the value of bufmap_init + */ +int get_bufmap_init(void) +{ + return __pvfs2_bufmap ? 1 : 0; +} + + +static struct pvfs2_bufmap * +pvfs2_bufmap_alloc(struct PVFS_dev_map_desc *user_desc) +{ + struct pvfs2_bufmap *bufmap; + + bufmap = kzalloc(sizeof(*bufmap), GFP_KERNEL); + if (!bufmap) + goto out; + + atomic_set(&bufmap->refcnt, 1); + bufmap->total_size = user_desc->total_size; + bufmap->desc_count = user_desc->count; + bufmap->desc_size = user_desc->size; + bufmap->desc_shift = ilog2(bufmap->desc_size); + + spin_lock_init(&bufmap->buffer_index_lock); + bufmap->buffer_index_array = + kcalloc(bufmap->desc_count, sizeof(int), GFP_KERNEL); + if (!bufmap->buffer_index_array) { + gossip_err("pvfs2: could not allocate %d buffer indices\n", + bufmap->desc_count); + goto out_free_bufmap; + } + spin_lock_init(&bufmap->readdir_index_lock); + + bufmap->desc_array = + kcalloc(bufmap->desc_count, sizeof(struct pvfs_bufmap_desc), + GFP_KERNEL); + if (!bufmap->desc_array) { + gossip_err("pvfs2: could not allocate %d descriptors\n", + bufmap->desc_count); + goto out_free_index_array; + } + + bufmap->page_count = bufmap->total_size / PAGE_SIZE; + + /* allocate storage to track our page mappings */ + bufmap->page_array = + kcalloc(bufmap->page_count, sizeof(struct page *), GFP_KERNEL); + if (!bufmap->page_array) + goto out_free_desc_array; + + return bufmap; + +out_free_desc_array: + kfree(bufmap->desc_array); +out_free_index_array: + kfree(bufmap->buffer_index_array); +out_free_bufmap: + kfree(bufmap); +out: + return NULL; +} + +static int +pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap, + struct PVFS_dev_map_desc *user_desc) +{ + int pages_per_desc = bufmap->desc_size / PAGE_SIZE; + int offset = 0, ret, i; + + /* map the pages */ + down_write(¤t->mm->mmap_sem); + ret = get_user_pages(current, + current->mm, + (unsigned long)user_desc->ptr, + bufmap->page_count, + 1, + 0, + bufmap->page_array, + NULL); + up_write(¤t->mm->mmap_sem); + + if (ret < 0) + return ret; + + if (ret != bufmap->page_count) { + gossip_err("pvfs2 error: asked for %d pages, only got %d.\n", + bufmap->page_count, ret); + + for (i = 0; i < ret; i++) { + SetPageError(bufmap->page_array[i]); + page_cache_release(bufmap->page_array[i]); + } + return -ENOMEM; + } + + /* + * ideally we want to get kernel space pointers for each page, but + * we can't kmap that many pages at once if highmem is being used. + * so instead, we just kmap/kunmap the page address each time the + * kaddr is needed. + */ + for (i = 0; i < bufmap->page_count; i++) + flush_dcache_page(bufmap->page_array[i]); + + /* build a list of available descriptors */ + for (offset = 0, i = 0; i < bufmap->desc_count; i++) { + bufmap->desc_array[i].page_array = &bufmap->page_array[offset]; + bufmap->desc_array[i].array_count = pages_per_desc; + bufmap->desc_array[i].uaddr = + (user_desc->ptr + (i * pages_per_desc * PAGE_SIZE)); + offset += pages_per_desc; + } + + return 0; +} + +/* + * pvfs_bufmap_initialize() + * + * initializes the mapped buffer interface + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc) +{ + struct pvfs2_bufmap *bufmap; + int ret = -EINVAL; + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_initialize: called (ptr (" + "%p) sz (%d) cnt(%d).\n", + user_desc->ptr, + user_desc->size, + user_desc->count); + + /* + * sanity check alignment and size of buffer that caller wants to + * work with + */ + if (PAGE_ALIGN((unsigned long)user_desc->ptr) != + (unsigned long)user_desc->ptr) { + gossip_err("pvfs2 error: memory alignment (front). %p\n", + user_desc->ptr); + goto out; + } + + if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->total_size)) + != (unsigned long)(user_desc->ptr + user_desc->total_size)) { + gossip_err("pvfs2 error: memory alignment (back).(%p + %d)\n", + user_desc->ptr, + user_desc->total_size); + goto out; + } + + if (user_desc->total_size != (user_desc->size * user_desc->count)) { + gossip_err("pvfs2 error: user provided an oddly sized buffer: (%d, %d, %d)\n", + user_desc->total_size, + user_desc->size, + user_desc->count); + goto out; + } + + if ((user_desc->size % PAGE_SIZE) != 0) { + gossip_err("pvfs2 error: bufmap size not page size divisible (%d).\n", + user_desc->size); + goto out; + } + + ret = -ENOMEM; + bufmap = pvfs2_bufmap_alloc(user_desc); + if (!bufmap) + goto out; + + ret = pvfs2_bufmap_map(bufmap, user_desc); + if (ret) + goto out_free_bufmap; + + + spin_lock(&pvfs2_bufmap_lock); + if (__pvfs2_bufmap) { + spin_unlock(&pvfs2_bufmap_lock); + gossip_err("pvfs2: error: bufmap already initialized.\n"); + ret = -EALREADY; + goto out_unmap_bufmap; + } + __pvfs2_bufmap = bufmap; + spin_unlock(&pvfs2_bufmap_lock); + + /* + * If there are operations in pvfs2_bufmap_init_waitq, wake them up. + * This scenario occurs when the client-core is restarted and I/O + * requests in the in-progress or waiting tables are restarted. I/O + * requests cannot be restarted until the shared memory system is + * completely re-initialized, so we put the I/O requests in this + * waitq until initialization has completed. NOTE: the I/O requests + * are also on a timer, so they don't wait forever just in case the + * client-core doesn't come back up. + */ + wake_up_interruptible(&pvfs2_bufmap_init_waitq); + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_initialize: exiting normally\n"); + return 0; + +out_unmap_bufmap: + pvfs2_bufmap_unmap(bufmap); +out_free_bufmap: + pvfs2_bufmap_free(bufmap); +out: + return ret; +} + +/* + * pvfs_bufmap_finalize() + * + * shuts down the mapped buffer interface and releases any resources + * associated with it + * + * no return value + */ +void pvfs_bufmap_finalize(void) +{ + gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: called\n"); + BUG_ON(!__pvfs2_bufmap); + pvfs2_bufmap_unref(__pvfs2_bufmap); + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs2_bufmap_finalize: exiting normally\n"); +} + +struct slot_args { + int slot_count; + int *slot_array; + spinlock_t *slot_lock; + wait_queue_head_t *slot_wq; +}; + +static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) +{ + int ret = -1; + int i = 0; + DECLARE_WAITQUEUE(my_wait, current); + + + add_wait_queue_exclusive(slargs->slot_wq, &my_wait); + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + /* + * check for available desc, slot_lock is the appropriate + * index_lock + */ + spin_lock(slargs->slot_lock); + for (i = 0; i < slargs->slot_count; i++) + if (slargs->slot_array[i] == 0) { + slargs->slot_array[i] = 1; + *buffer_index = i; + ret = 0; + break; + } + spin_unlock(slargs->slot_lock); + + /* if we acquired a buffer, then break out of while */ + if (ret == 0) + break; + + if (!signal_pending(current)) { + int timeout = + MSECS_TO_JIFFIES(1000 * slot_timeout_secs); + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "[BUFMAP]: waiting %d " + "seconds for a slot\n", + slot_timeout_secs); + if (!schedule_timeout(timeout)) { + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "*** wait_for_a_slot timed out\n"); + ret = -ETIMEDOUT; + break; + } + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "[BUFMAP]: woken up by a slot becoming available.\n"); + continue; + } + + gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2: %s interrupted.\n", + __func__); + ret = -EINTR; + break; + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(slargs->slot_wq, &my_wait); + return ret; +} + +static void put_back_slot(struct slot_args *slargs, int buffer_index) +{ + /* slot_lock is the appropriate index_lock */ + spin_lock(slargs->slot_lock); + if (buffer_index < 0 || buffer_index >= slargs->slot_count) { + spin_unlock(slargs->slot_lock); + return; + } + + /* put the desc back on the queue */ + slargs->slot_array[buffer_index] = 0; + spin_unlock(slargs->slot_lock); + + /* wake up anyone who may be sleeping on the queue */ + wake_up_interruptible(slargs->slot_wq); +} + +/* + * pvfs_bufmap_get() + * + * gets a free mapped buffer descriptor, will sleep until one becomes + * available if necessary + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index) +{ + struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct slot_args slargs; + int ret; + + if (!bufmap) { + gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n"); + return -EIO; + } + + slargs.slot_count = bufmap->desc_count; + slargs.slot_array = bufmap->buffer_index_array; + slargs.slot_lock = &bufmap->buffer_index_lock; + slargs.slot_wq = &bufmap_waitq; + ret = wait_for_a_slot(&slargs, buffer_index); + if (ret) + pvfs2_bufmap_unref(bufmap); + *mapp = bufmap; + return ret; +} + +/* + * pvfs_bufmap_put() + * + * returns a mapped buffer descriptor to the collection + * + * no return value + */ +void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index) +{ + struct slot_args slargs; + + slargs.slot_count = bufmap->desc_count; + slargs.slot_array = bufmap->buffer_index_array; + slargs.slot_lock = &bufmap->buffer_index_lock; + slargs.slot_wq = &bufmap_waitq; + put_back_slot(&slargs, buffer_index); + pvfs2_bufmap_unref(bufmap); +} + +/* + * readdir_index_get() + * + * gets a free descriptor, will sleep until one becomes + * available if necessary. + * Although the readdir buffers are not mapped into kernel space + * we could do that at a later point of time. Regardless, these + * indices are used by the client-core. + * + * returns 0 on success, -errno on failure + */ +int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index) +{ + struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct slot_args slargs; + int ret; + + if (!bufmap) { + gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n"); + return -EIO; + } + + slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT; + slargs.slot_array = bufmap->readdir_index_array; + slargs.slot_lock = &bufmap->readdir_index_lock; + slargs.slot_wq = &readdir_waitq; + ret = wait_for_a_slot(&slargs, buffer_index); + if (ret) + pvfs2_bufmap_unref(bufmap); + *mapp = bufmap; + return ret; +} + +void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index) +{ + struct slot_args slargs; + + slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT; + slargs.slot_array = bufmap->readdir_index_array; + slargs.slot_lock = &bufmap->readdir_index_lock; + slargs.slot_wq = &readdir_waitq; + put_back_slot(&slargs, buffer_index); + pvfs2_bufmap_unref(bufmap); +} + +/* + * pvfs_bufmap_copy_iovec_from_user() + * + * copies data from several user space address's in an iovec + * to a mapped buffer + * + * Note that the mapped buffer is a series of pages and therefore + * the copies have to be split by PAGE_SIZE bytes at a time. + * Note that this routine checks that summation of iov_len + * across all the elements of iov is equal to size. + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap, + int buffer_index, + const struct iovec *iov, + unsigned long nr_segs, + size_t size) +{ + size_t ret = 0; + size_t amt_copied = 0; + size_t cur_copy_size = 0; + unsigned int to_page_offset = 0; + unsigned int to_page_index = 0; + void *to_kaddr = NULL; + void __user *from_addr = NULL; + struct iovec *copied_iovec = NULL; + struct pvfs_bufmap_desc *to; + unsigned int seg; + char *tmp_printer = NULL; + int tmp_int = 0; + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_copy_iovec_from_user: index %d, " + "size %zd\n", + buffer_index, + size); + + to = &bufmap->desc_array[buffer_index]; + + /* + * copy the passed in iovec so that we can change some of its fields + */ + copied_iovec = kmalloc_array(nr_segs, + sizeof(*copied_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (copied_iovec == NULL) + return -ENOMEM; + + memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); + /* + * Go through each segment in the iovec and make sure that + * the summation of iov_len matches the given size. + */ + for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) + amt_copied += copied_iovec[seg].iov_len; + if (amt_copied != size) { + gossip_err( + "pvfs2_bufmap_copy_iovec_from_user: computed total (" + "%zd) is not equal to (%zd)\n", + amt_copied, + size); + kfree(copied_iovec); + return -EINVAL; + } + + to_page_index = 0; + to_page_offset = 0; + amt_copied = 0; + seg = 0; + /* + * Go through each segment in the iovec and copy its + * buffer into the mapped buffer one page at a time though + */ + while (amt_copied < size) { + struct iovec *iv = &copied_iovec[seg]; + int inc_to_page_index; + + if (iv->iov_len < (PAGE_SIZE - to_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + from_addr = iv->iov_base; + inc_to_page_index = 0; + } else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + from_addr = iv->iov_base; + inc_to_page_index = 1; + } else { + cur_copy_size = + PVFS_util_min(PAGE_SIZE - to_page_offset, + size - amt_copied); + from_addr = iv->iov_base; + iv->iov_base += cur_copy_size; + iv->iov_len -= cur_copy_size; + inc_to_page_index = 1; + } + to_kaddr = pvfs2_kmap(to->page_array[to_page_index]); + ret = + copy_from_user(to_kaddr + to_page_offset, + from_addr, + cur_copy_size); + if (!PageReserved(to->page_array[to_page_index])) + SetPageDirty(to->page_array[to_page_index]); + + if (!tmp_printer) { + tmp_printer = (char *)(to_kaddr + to_page_offset); + tmp_int += tmp_printer[0]; + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n", + tmp_int); + } + + pvfs2_kunmap(to->page_array[to_page_index]); + if (ret) { + gossip_err("Failed to copy data from user space\n"); + kfree(copied_iovec); + return -EFAULT; + } + + amt_copied += cur_copy_size; + if (inc_to_page_index) { + to_page_offset = 0; + to_page_index++; + } else { + to_page_offset += cur_copy_size; + } + } + kfree(copied_iovec); + return 0; +} + +/* + * pvfs_bufmap_copy_iovec_from_kernel() + * + * copies data from several kernel space address's in an iovec + * to a mapped buffer + * + * Note that the mapped buffer is a series of pages and therefore + * the copies have to be split by PAGE_SIZE bytes at a time. + * Note that this routine checks that summation of iov_len + * across all the elements of iov is equal to size. + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, + int buffer_index, const struct iovec *iov, + unsigned long nr_segs, size_t size) +{ + size_t amt_copied = 0; + size_t cur_copy_size = 0; + int to_page_index = 0; + void *to_kaddr = NULL; + void *from_kaddr = NULL; + struct iovec *copied_iovec = NULL; + struct pvfs_bufmap_desc *to; + unsigned int seg; + unsigned to_page_offset = 0; + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_copy_iovec_from_kernel: index %d, " + "size %zd\n", + buffer_index, + size); + + to = &bufmap->desc_array[buffer_index]; + /* + * copy the passed in iovec so that we can change some of its fields + */ + copied_iovec = kmalloc_array(nr_segs, + sizeof(*copied_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (copied_iovec == NULL) + return -ENOMEM; + + memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); + /* + * Go through each segment in the iovec and make sure that + * the summation of iov_len matches the given size. + */ + for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) + amt_copied += copied_iovec[seg].iov_len; + if (amt_copied != size) { + gossip_err("pvfs2_bufmap_copy_iovec_from_kernel: computed total(%zd) is not equal to (%zd)\n", + amt_copied, + size); + kfree(copied_iovec); + return -EINVAL; + } + + to_page_index = 0; + amt_copied = 0; + seg = 0; + to_page_offset = 0; + /* + * Go through each segment in the iovec and copy its + * buffer into the mapped buffer one page at a time though + */ + while (amt_copied < size) { + struct iovec *iv = &copied_iovec[seg]; + int inc_to_page_index; + + if (iv->iov_len < (PAGE_SIZE - to_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + from_kaddr = iv->iov_base; + inc_to_page_index = 0; + } else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + from_kaddr = iv->iov_base; + inc_to_page_index = 1; + } else { + cur_copy_size = + PVFS_util_min(PAGE_SIZE - to_page_offset, + size - amt_copied); + from_kaddr = iv->iov_base; + iv->iov_base += cur_copy_size; + iv->iov_len -= cur_copy_size; + inc_to_page_index = 1; + } + to_kaddr = pvfs2_kmap(to->page_array[to_page_index]); + memcpy(to_kaddr + to_page_offset, from_kaddr, cur_copy_size); + if (!PageReserved(to->page_array[to_page_index])) + SetPageDirty(to->page_array[to_page_index]); + pvfs2_kunmap(to->page_array[to_page_index]); + amt_copied += cur_copy_size; + if (inc_to_page_index) { + to_page_offset = 0; + to_page_index++; + } else { + to_page_offset += cur_copy_size; + } + } + kfree(copied_iovec); + return 0; +} + +/* + * pvfs_bufmap_copy_to_user_iovec() + * + * copies data to several user space address's in an iovec + * from a mapped buffer + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap, + int buffer_index, const struct iovec *iov, + unsigned long nr_segs, size_t size) +{ + size_t ret = 0; + size_t amt_copied = 0; + size_t cur_copy_size = 0; + int from_page_index = 0; + void *from_kaddr = NULL; + void __user *to_addr = NULL; + struct iovec *copied_iovec = NULL; + struct pvfs_bufmap_desc *from; + unsigned int seg; + unsigned from_page_offset = 0; + char *tmp_printer = NULL; + int tmp_int = 0; + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_copy_to_user_iovec: index %d, size %zd\n", + buffer_index, + size); + + from = &bufmap->desc_array[buffer_index]; + /* + * copy the passed in iovec so that we can change some of its fields + */ + copied_iovec = kmalloc_array(nr_segs, + sizeof(*copied_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (copied_iovec == NULL) + return -ENOMEM; + + memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); + /* + * Go through each segment in the iovec and make sure that + * the summation of iov_len is greater than the given size. + */ + for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) + amt_copied += copied_iovec[seg].iov_len; + if (amt_copied < size) { + gossip_err("pvfs2_bufmap_copy_to_user_iovec: computed total (%zd) is less than (%zd)\n", + amt_copied, + size); + kfree(copied_iovec); + return -EINVAL; + } + + from_page_index = 0; + amt_copied = 0; + seg = 0; + from_page_offset = 0; + /* + * Go through each segment in the iovec and copy from the mapper buffer, + * but make sure that we do so one page at a time. + */ + while (amt_copied < size) { + struct iovec *iv = &copied_iovec[seg]; + int inc_from_page_index; + + if (iv->iov_len < (PAGE_SIZE - from_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + to_addr = iv->iov_base; + inc_from_page_index = 0; + } else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + to_addr = iv->iov_base; + inc_from_page_index = 1; + } else { + cur_copy_size = + PVFS_util_min(PAGE_SIZE - from_page_offset, + size - amt_copied); + to_addr = iv->iov_base; + iv->iov_base += cur_copy_size; + iv->iov_len -= cur_copy_size; + inc_from_page_index = 1; + } + from_kaddr = pvfs2_kmap(from->page_array[from_page_index]); + if (!tmp_printer) { + tmp_printer = (char *)(from_kaddr + from_page_offset); + tmp_int += tmp_printer[0]; + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "First character (integer value) in pvfs_bufmap_copy_to_user_iovec: %d\n", + tmp_int); + } + ret = + copy_to_user(to_addr, + from_kaddr + from_page_offset, + cur_copy_size); + pvfs2_kunmap(from->page_array[from_page_index]); + if (ret) { + gossip_err("Failed to copy data to user space\n"); + kfree(copied_iovec); + return -EFAULT; + } + + amt_copied += cur_copy_size; + if (inc_from_page_index) { + from_page_offset = 0; + from_page_index++; + } else { + from_page_offset += cur_copy_size; + } + } + kfree(copied_iovec); + return 0; +} + +/* + * pvfs_bufmap_copy_to_kernel_iovec() + * + * copies data to several kernel space address's in an iovec + * from a mapped buffer + * + * returns 0 on success, -errno on failure + */ +int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, + int buffer_index, const struct iovec *iov, + unsigned long nr_segs, size_t size) +{ + size_t amt_copied = 0; + size_t cur_copy_size = 0; + int from_page_index = 0; + void *from_kaddr = NULL; + void *to_kaddr = NULL; + struct iovec *copied_iovec = NULL; + struct pvfs_bufmap_desc *from; + unsigned int seg; + unsigned int from_page_offset = 0; + + gossip_debug(GOSSIP_BUFMAP_DEBUG, + "pvfs_bufmap_copy_to_kernel_iovec: index %d, size %zd\n", + buffer_index, + size); + + from = &bufmap->desc_array[buffer_index]; + /* + * copy the passed in iovec so that we can change some of its fields + */ + copied_iovec = kmalloc_array(nr_segs, + sizeof(*copied_iovec), + PVFS2_BUFMAP_GFP_FLAGS); + if (copied_iovec == NULL) + return -ENOMEM; + + memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); + /* + * Go through each segment in the iovec and make sure that + * the summation of iov_len is greater than the given size. + */ + for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) + amt_copied += copied_iovec[seg].iov_len; + + if (amt_copied < size) { + gossip_err("pvfs2_bufmap_copy_to_kernel_iovec: computed total (%zd) is less than (%zd)\n", + amt_copied, + size); + kfree(copied_iovec); + return -EINVAL; + } + + from_page_index = 0; + amt_copied = 0; + seg = 0; + from_page_offset = 0; + /* + * Go through each segment in the iovec and copy from the mapper buffer, + * but make sure that we do so one page at a time. + */ + while (amt_copied < size) { + struct iovec *iv = &copied_iovec[seg]; + int inc_from_page_index; + + if (iv->iov_len < (PAGE_SIZE - from_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + to_kaddr = iv->iov_base; + inc_from_page_index = 0; + } else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) { + cur_copy_size = + PVFS_util_min(iv->iov_len, size - amt_copied); + seg++; + to_kaddr = iv->iov_base; + inc_from_page_index = 1; + } else { + cur_copy_size = + PVFS_util_min(PAGE_SIZE - from_page_offset, + size - amt_copied); + to_kaddr = iv->iov_base; + iv->iov_base += cur_copy_size; + iv->iov_len -= cur_copy_size; + inc_from_page_index = 1; + } + from_kaddr = pvfs2_kmap(from->page_array[from_page_index]); + memcpy(to_kaddr, from_kaddr + from_page_offset, cur_copy_size); + pvfs2_kunmap(from->page_array[from_page_index]); + amt_copied += cur_copy_size; + if (inc_from_page_index) { + from_page_offset = 0; + from_page_index++; + } else { + from_page_offset += cur_copy_size; + } + } + kfree(copied_iovec); + return 0; +} diff --git a/fs/orangefs/pvfs2-cache.c b/fs/orangefs/pvfs2-cache.c new file mode 100644 index 000000000000..15251884ba4a --- /dev/null +++ b/fs/orangefs/pvfs2-cache.c @@ -0,0 +1,260 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" + +/* tags assigned to kernel upcall operations */ +static __u64 next_tag_value; +static DEFINE_SPINLOCK(next_tag_value_lock); + +/* the pvfs2 memory caches */ + +/* a cache for pvfs2 upcall/downcall operations */ +static struct kmem_cache *op_cache; + +/* a cache for device (/dev/pvfs2-req) communication */ +static struct kmem_cache *dev_req_cache; + +/* a cache for pvfs2_kiocb objects (i.e pvfs2 iocb structures ) */ +static struct kmem_cache *pvfs2_kiocb_cache; + +int op_cache_initialize(void) +{ + op_cache = kmem_cache_create("pvfs2_op_cache", + sizeof(struct pvfs2_kernel_op_s), + 0, + PVFS2_CACHE_CREATE_FLAGS, + NULL); + + if (!op_cache) { + gossip_err("Cannot create pvfs2_op_cache\n"); + return -ENOMEM; + } + + /* initialize our atomic tag counter */ + spin_lock(&next_tag_value_lock); + next_tag_value = 100; + spin_unlock(&next_tag_value_lock); + return 0; +} + +int op_cache_finalize(void) +{ + kmem_cache_destroy(op_cache); + return 0; +} + +char *get_opname_string(struct pvfs2_kernel_op_s *new_op) +{ + if (new_op) { + __s32 type = new_op->upcall.type; + + if (type == PVFS2_VFS_OP_FILE_IO) + return "OP_FILE_IO"; + else if (type == PVFS2_VFS_OP_LOOKUP) + return "OP_LOOKUP"; + else if (type == PVFS2_VFS_OP_CREATE) + return "OP_CREATE"; + else if (type == PVFS2_VFS_OP_GETATTR) + return "OP_GETATTR"; + else if (type == PVFS2_VFS_OP_REMOVE) + return "OP_REMOVE"; + else if (type == PVFS2_VFS_OP_MKDIR) + return "OP_MKDIR"; + else if (type == PVFS2_VFS_OP_READDIR) + return "OP_READDIR"; + else if (type == PVFS2_VFS_OP_READDIRPLUS) + return "OP_READDIRPLUS"; + else if (type == PVFS2_VFS_OP_SETATTR) + return "OP_SETATTR"; + else if (type == PVFS2_VFS_OP_SYMLINK) + return "OP_SYMLINK"; + else if (type == PVFS2_VFS_OP_RENAME) + return "OP_RENAME"; + else if (type == PVFS2_VFS_OP_STATFS) + return "OP_STATFS"; + else if (type == PVFS2_VFS_OP_TRUNCATE) + return "OP_TRUNCATE"; + else if (type == PVFS2_VFS_OP_MMAP_RA_FLUSH) + return "OP_MMAP_RA_FLUSH"; + else if (type == PVFS2_VFS_OP_FS_MOUNT) + return "OP_FS_MOUNT"; + else if (type == PVFS2_VFS_OP_FS_UMOUNT) + return "OP_FS_UMOUNT"; + else if (type == PVFS2_VFS_OP_GETXATTR) + return "OP_GETXATTR"; + else if (type == PVFS2_VFS_OP_SETXATTR) + return "OP_SETXATTR"; + else if (type == PVFS2_VFS_OP_LISTXATTR) + return "OP_LISTXATTR"; + else if (type == PVFS2_VFS_OP_REMOVEXATTR) + return "OP_REMOVEXATTR"; + else if (type == PVFS2_VFS_OP_PARAM) + return "OP_PARAM"; + else if (type == PVFS2_VFS_OP_PERF_COUNT) + return "OP_PERF_COUNT"; + else if (type == PVFS2_VFS_OP_CANCEL) + return "OP_CANCEL"; + else if (type == PVFS2_VFS_OP_FSYNC) + return "OP_FSYNC"; + else if (type == PVFS2_VFS_OP_FSKEY) + return "OP_FSKEY"; + else if (type == PVFS2_VFS_OP_FILE_IOX) + return "OP_FILE_IOX"; + } + return "OP_UNKNOWN?"; +} + +static struct pvfs2_kernel_op_s *op_alloc_common(__s32 op_linger, __s32 type) +{ + struct pvfs2_kernel_op_s *new_op = NULL; + + new_op = kmem_cache_alloc(op_cache, PVFS2_CACHE_ALLOC_FLAGS); + if (new_op) { + memset(new_op, 0, sizeof(struct pvfs2_kernel_op_s)); + + INIT_LIST_HEAD(&new_op->list); + spin_lock_init(&new_op->lock); + init_waitqueue_head(&new_op->waitq); + + init_waitqueue_head(&new_op->io_completion_waitq); + atomic_set(&new_op->aio_ref_count, 0); + + pvfs2_op_initialize(new_op); + + /* initialize the op specific tag and upcall credentials */ + spin_lock(&next_tag_value_lock); + new_op->tag = next_tag_value++; + if (next_tag_value == 0) + next_tag_value = 100; + spin_unlock(&next_tag_value_lock); + new_op->upcall.type = type; + new_op->attempts = 0; + gossip_debug(GOSSIP_CACHE_DEBUG, + "Alloced OP (%p: %llu %s)\n", + new_op, + llu(new_op->tag), + get_opname_string(new_op)); + + new_op->upcall.uid = from_kuid(current_user_ns(), + current_fsuid()); + + new_op->upcall.gid = from_kgid(current_user_ns(), + current_fsgid()); + + new_op->op_linger = new_op->op_linger_tmp = op_linger; + } else { + gossip_err("op_alloc: kmem_cache_alloc failed!\n"); + } + return new_op; +} + +struct pvfs2_kernel_op_s *op_alloc(__s32 type) +{ + return op_alloc_common(1, type); +} + +struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type) +{ + return op_alloc_common(2, type); +} + +void op_release(struct pvfs2_kernel_op_s *pvfs2_op) +{ + if (pvfs2_op) { + gossip_debug(GOSSIP_CACHE_DEBUG, + "Releasing OP (%p: %llu)\n", + pvfs2_op, + llu(pvfs2_op->tag)); + pvfs2_op_initialize(pvfs2_op); + kmem_cache_free(op_cache, pvfs2_op); + } else { + gossip_err("NULL pointer in op_release\n"); + } +} + +int dev_req_cache_initialize(void) +{ + dev_req_cache = kmem_cache_create("pvfs2_devreqcache", + MAX_ALIGNED_DEV_REQ_DOWNSIZE, + 0, + PVFS2_CACHE_CREATE_FLAGS, + NULL); + + if (!dev_req_cache) { + gossip_err("Cannot create pvfs2_dev_req_cache\n"); + return -ENOMEM; + } + return 0; +} + +int dev_req_cache_finalize(void) +{ + kmem_cache_destroy(dev_req_cache); + return 0; +} + +void *dev_req_alloc(void) +{ + void *buffer; + + buffer = kmem_cache_alloc(dev_req_cache, PVFS2_CACHE_ALLOC_FLAGS); + if (buffer == NULL) + gossip_err("Failed to allocate from dev_req_cache\n"); + else + memset(buffer, 0, sizeof(MAX_ALIGNED_DEV_REQ_DOWNSIZE)); + return buffer; +} + +void dev_req_release(void *buffer) +{ + if (buffer) + kmem_cache_free(dev_req_cache, buffer); + else + gossip_err("NULL pointer passed to dev_req_release\n"); +} + +int kiocb_cache_initialize(void) +{ + pvfs2_kiocb_cache = kmem_cache_create("pvfs2_kiocbcache", + sizeof(struct pvfs2_kiocb_s), + 0, + PVFS2_CACHE_CREATE_FLAGS, + NULL); + + if (!pvfs2_kiocb_cache) { + gossip_err("Cannot create pvfs2_kiocb_cache!\n"); + return -ENOMEM; + } + return 0; +} + +int kiocb_cache_finalize(void) +{ + kmem_cache_destroy(pvfs2_kiocb_cache); + return 0; +} + +struct pvfs2_kiocb_s *kiocb_alloc(void) +{ + struct pvfs2_kiocb_s *x = NULL; + + x = kmem_cache_alloc(pvfs2_kiocb_cache, PVFS2_CACHE_ALLOC_FLAGS); + if (x == NULL) + gossip_err("kiocb_alloc: kmem_cache_alloc failed!\n"); + else + memset(x, 0, sizeof(struct pvfs2_kiocb_s)); + return x; +} + +void kiocb_release(struct pvfs2_kiocb_s *x) +{ + if (x) + kmem_cache_free(pvfs2_kiocb_cache, x); + else + gossip_err("kiocb_release: kmem_cache_free NULL pointer!\n"); +} diff --git a/fs/orangefs/pvfs2-debugfs.c b/fs/orangefs/pvfs2-debugfs.c new file mode 100644 index 000000000000..8d118da9b88f --- /dev/null +++ b/fs/orangefs/pvfs2-debugfs.c @@ -0,0 +1,458 @@ +/* + * What: /sys/kernel/debug/orangefs/debug-help + * Date: June 2015 + * Contact: Mike Marshall + * Description: + * List of client and kernel debug keywords. + * + * + * What: /sys/kernel/debug/orangefs/client-debug + * Date: June 2015 + * Contact: Mike Marshall + * Description: + * Debug setting for "the client", the userspace + * helper for the kernel module. + * + * + * What: /sys/kernel/debug/orangefs/kernel-debug + * Date: June 2015 + * Contact: Mike Marshall + * Description: + * Debug setting for the orangefs kernel module. + * + * Any of the keywords, or comma-separated lists + * of keywords, from debug-help can be catted to + * client-debug or kernel-debug. + * + * "none", "all" and "verbose" are special keywords + * for client-debug. Setting client-debug to "all" + * is kind of like trying to drink water from a + * fire hose, "verbose" triggers most of the same + * output except for the constant flow of output + * from the main wait loop. + * + * "none" and "all" are similar settings for kernel-debug + * no need for a "verbose". + */ +#include +#include + +#include + +#include "pvfs2-debugfs.h" +#include "protocol.h" +#include "pvfs2-kernel.h" + +static int orangefs_debug_disabled = 1; + +static int orangefs_debug_help_open(struct inode *, struct file *); + +const struct file_operations debug_help_fops = { + .open = orangefs_debug_help_open, + .read = seq_read, + .release = seq_release, + .llseek = seq_lseek, +}; + +static void *help_start(struct seq_file *, loff_t *); +static void *help_next(struct seq_file *, void *, loff_t *); +static void help_stop(struct seq_file *, void *); +static int help_show(struct seq_file *, void *); + +static const struct seq_operations help_debug_ops = { + .start = help_start, + .next = help_next, + .stop = help_stop, + .show = help_show, +}; + +/* + * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and + * ORANGEFS_KMOD_DEBUG_FILE. + */ +DEFINE_MUTEX(orangefs_debug_lock); + +int orangefs_debug_open(struct inode *, struct file *); + +static ssize_t orangefs_debug_read(struct file *, + char __user *, + size_t, + loff_t *); + +static ssize_t orangefs_debug_write(struct file *, + const char __user *, + size_t, + loff_t *); + +static const struct file_operations kernel_debug_fops = { + .open = orangefs_debug_open, + .read = orangefs_debug_read, + .write = orangefs_debug_write, + .llseek = generic_file_llseek, +}; + +/* + * initialize kmod debug operations, create orangefs debugfs dir and + * ORANGEFS_KMOD_DEBUG_HELP_FILE. + */ +int pvfs2_debugfs_init(void) +{ + + int rc = -ENOMEM; + + debug_dir = debugfs_create_dir("orangefs", NULL); + if (!debug_dir) + goto out; + + help_file_dentry = debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE, + 0444, + debug_dir, + debug_help_string, + &debug_help_fops); + if (!help_file_dentry) + goto out; + + orangefs_debug_disabled = 0; + rc = 0; + +out: + if (rc) + pvfs2_debugfs_cleanup(); + + return rc; +} + +void pvfs2_debugfs_cleanup(void) +{ + debugfs_remove_recursive(debug_dir); +} + +/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */ +static int orangefs_debug_help_open(struct inode *inode, struct file *file) +{ + int rc = -ENODEV; + int ret; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_help_open: start\n"); + + if (orangefs_debug_disabled) + goto out; + + ret = seq_open(file, &help_debug_ops); + if (ret) + goto out; + + ((struct seq_file *)(file->private_data))->private = inode->i_private; + + rc = 0; + +out: + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_help_open: rc:%d:\n", + rc); + return rc; +} + +/* + * I think start always gets called again after stop. Start + * needs to return NULL when it is done. The whole "payload" + * in this case is a single (long) string, so by the second + * time we get to start (pos = 1), we're done. + */ +static void *help_start(struct seq_file *m, loff_t *pos) +{ + void *payload = NULL; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n"); + + if (*pos == 0) + payload = m->private; + + return payload; +} + +static void *help_next(struct seq_file *m, void *v, loff_t *pos) +{ + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n"); + + return NULL; +} + +static void help_stop(struct seq_file *m, void *p) +{ + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n"); +} + +static int help_show(struct seq_file *m, void *v) +{ + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_show: start\n"); + + seq_puts(m, v); + + return 0; +} + +/* + * initialize the kernel-debug file. + */ +int pvfs2_kernel_debug_init(void) +{ + + int rc = -ENOMEM; + struct dentry *ret; + char *k_buffer = NULL; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); + + k_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + if (!k_buffer) + goto out; + + if (strlen(kernel_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) { + strcpy(k_buffer, kernel_debug_string); + strcat(k_buffer, "\n"); + } else { + strcpy(k_buffer, "none\n"); + pr_info("%s: overflow 1!\n", __func__); + } + + ret = debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, + 0444, + debug_dir, + k_buffer, + &kernel_debug_fops); + if (!ret) { + pr_info("%s: failed to create %s.\n", + __func__, + ORANGEFS_KMOD_DEBUG_FILE); + goto out; + } + + rc = 0; + +out: + if (rc) + pvfs2_debugfs_cleanup(); + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); + return rc; +} + +/* + * initialize the client-debug file. + */ +int pvfs2_client_debug_init(void) +{ + + int rc = -ENOMEM; + char *c_buffer = NULL; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); + + c_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + if (!c_buffer) + goto out; + + if (strlen(client_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) { + strcpy(c_buffer, client_debug_string); + strcat(c_buffer, "\n"); + } else { + strcpy(c_buffer, "none\n"); + pr_info("%s: overflow! 2\n", __func__); + } + + client_debug_dentry = debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE, + 0444, + debug_dir, + c_buffer, + &kernel_debug_fops); + if (!client_debug_dentry) { + pr_info("%s: failed to create %s.\n", + __func__, + ORANGEFS_CLIENT_DEBUG_FILE); + goto out; + } + + rc = 0; + +out: + if (rc) + pvfs2_debugfs_cleanup(); + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); + return rc; +} + +/* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/ +int orangefs_debug_open(struct inode *inode, struct file *file) +{ + int rc = -ENODEV; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "%s: orangefs_debug_disabled: %d\n", + __func__, + orangefs_debug_disabled); + + if (orangefs_debug_disabled) + goto out; + + rc = 0; + mutex_lock(&orangefs_debug_lock); + file->private_data = inode->i_private; + mutex_unlock(&orangefs_debug_lock); + +out: + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_open: rc: %d\n", + rc); + return rc; +} + +static ssize_t orangefs_debug_read(struct file *file, + char __user *ubuf, + size_t count, + loff_t *ppos) +{ + char *buf; + int sprintf_ret; + ssize_t read_ret = -ENOMEM; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, "orangefs_debug_read: start\n"); + + buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + if (!buf) + goto out; + + mutex_lock(&orangefs_debug_lock); + sprintf_ret = sprintf(buf, "%s", (char *)file->private_data); + mutex_unlock(&orangefs_debug_lock); + + read_ret = simple_read_from_buffer(ubuf, count, ppos, buf, sprintf_ret); + + kfree(buf); + +out: + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_read: ret: %zu\n", + read_ret); + + return read_ret; +} + +static ssize_t orangefs_debug_write(struct file *file, + const char __user *ubuf, + size_t count, + loff_t *ppos) +{ + char *buf; + int rc = -EFAULT; + size_t silly = 0; + char *debug_string; + struct pvfs2_kernel_op_s *new_op = NULL; + struct client_debug_mask c_mask = { NULL, 0, 0 }; + + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_write: %s\n", + file->f_path.dentry->d_name.name); + + /* + * Thwart users who try to jamb a ridiculous number + * of bytes into the debug file... + */ + if (count > PVFS2_MAX_DEBUG_STRING_LEN + 1) { + silly = count; + count = PVFS2_MAX_DEBUG_STRING_LEN + 1; + } + + buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + if (!buf) + goto out; + memset(buf, 0, PVFS2_MAX_DEBUG_STRING_LEN); + + if (copy_from_user(buf, ubuf, count - 1)) { + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "%s: copy_from_user failed!\n", + __func__); + goto out; + } + + /* + * Map the keyword string from userspace into a valid debug mask. + * The mapping process involves mapping the human-inputted string + * into a valid mask, and then rebuilding the string from the + * verified valid mask. + * + * A service operation is required to set a new client-side + * debug mask. + */ + if (!strcmp(file->f_path.dentry->d_name.name, + ORANGEFS_KMOD_DEBUG_FILE)) { + debug_string_to_mask(buf, &gossip_debug_mask, 0); + debug_mask_to_string(&gossip_debug_mask, 0); + debug_string = kernel_debug_string; + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "New kernel debug string is %s\n", + kernel_debug_string); + } else { + /* Can't reset client debug mask if client is not running. */ + if (is_daemon_in_service()) { + pr_info("%s: Client not running :%d:\n", + __func__, + is_daemon_in_service()); + goto out; + } + + debug_string_to_mask(buf, &c_mask, 1); + debug_mask_to_string(&c_mask, 1); + debug_string = client_debug_string; + + new_op = op_alloc(PVFS2_VFS_OP_PARAM); + if (!new_op) { + pr_info("%s: op_alloc failed!\n", __func__); + goto out; + } + + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES; + new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET; + memset(new_op->upcall.req.param.s_value, + 0, + PVFS2_MAX_DEBUG_STRING_LEN); + sprintf(new_op->upcall.req.param.s_value, + "%llx %llx\n", + c_mask.mask1, + c_mask.mask2); + + /* service_operation returns 0 on success... */ + rc = service_operation(new_op, + "pvfs2_param", + PVFS2_OP_INTERRUPTIBLE); + + if (rc) + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "%s: service_operation failed! rc:%d:\n", + __func__, + rc); + + op_release(new_op); + } + + mutex_lock(&orangefs_debug_lock); + memset(file->f_inode->i_private, 0, PVFS2_MAX_DEBUG_STRING_LEN); + sprintf((char *)file->f_inode->i_private, "%s\n", debug_string); + mutex_unlock(&orangefs_debug_lock); + + *ppos += count; + if (silly) + rc = silly; + else + rc = count; + +out: + gossip_debug(GOSSIP_DEBUGFS_DEBUG, + "orangefs_debug_write: rc: %d\n", + rc); + kfree(buf); + return rc; +} diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c new file mode 100644 index 000000000000..9cbc992731d6 --- /dev/null +++ b/fs/orangefs/pvfs2-mod.c @@ -0,0 +1,316 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * Changes by Acxiom Corporation to add proc file handler for pvfs2 client + * parameters, Copyright Acxiom Corporation, 2005. + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-debugfs.h" +#include "pvfs2-sysfs.h" + +/* PVFS2_VERSION is a ./configure define */ +#ifndef PVFS2_VERSION +#define PVFS2_VERSION "Unknown" +#endif + +/* + * global variables declared here + */ + +/* array of client debug keyword/mask values */ +struct client_debug_mask *cdm_array; +int cdm_element_count; + +char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN] = "none"; +char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; +char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN]; + +char *debug_help_string; +int help_string_initialized; +struct dentry *help_file_dentry; +struct dentry *client_debug_dentry; +struct dentry *debug_dir; +int client_verbose_index; +int client_all_index; +struct pvfs2_stats g_pvfs2_stats; + +/* the size of the hash tables for ops in progress */ +int hash_table_size = 509; + +static ulong module_parm_debug_mask; +__u64 gossip_debug_mask; +struct client_debug_mask client_debug_mask = { NULL, 0, 0 }; +unsigned int kernel_mask_set_mod_init; /* implicitly false */ +int op_timeout_secs = PVFS2_DEFAULT_OP_TIMEOUT_SECS; +int slot_timeout_secs = PVFS2_DEFAULT_SLOT_TIMEOUT_SECS; +__u32 DEBUG_LINE = 50; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("PVFS2 Development Team"); +MODULE_DESCRIPTION("The Linux Kernel VFS interface to PVFS2"); +MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see pvfs2-debug.h for values)"); +MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds"); +MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds"); +MODULE_PARM_DESC(hash_table_size, + "size of hash table for operations in progress"); + +static struct file_system_type pvfs2_fs_type = { + .name = "pvfs2", + .mount = pvfs2_mount, + .kill_sb = pvfs2_kill_sb, + .owner = THIS_MODULE, +}; + +module_param(hash_table_size, int, 0); +module_param(module_parm_debug_mask, ulong, 0755); +module_param(op_timeout_secs, int, 0); +module_param(slot_timeout_secs, int, 0); + +/* synchronizes the request device file */ +struct mutex devreq_mutex; + +/* + blocks non-priority requests from being queued for servicing. this + could be used for protecting the request list data structure, but + for now it's only being used to stall the op addition to the request + list +*/ +struct mutex request_mutex; + +/* hash table for storing operations waiting for matching downcall */ +struct list_head *htable_ops_in_progress; +DEFINE_SPINLOCK(htable_ops_in_progress_lock); + +/* list for queueing upcall operations */ +LIST_HEAD(pvfs2_request_list); + +/* used to protect the above pvfs2_request_list */ +DEFINE_SPINLOCK(pvfs2_request_list_lock); + +/* used for incoming request notification */ +DECLARE_WAIT_QUEUE_HEAD(pvfs2_request_list_waitq); + +static int __init pvfs2_init(void) +{ + int ret = -1; + __u32 i = 0; + + /* convert input debug mask to a 64-bit unsigned integer */ + gossip_debug_mask = (unsigned long long) module_parm_debug_mask; + + /* + * set the kernel's gossip debug string; invalid mask values will + * be ignored. + */ + debug_mask_to_string(&gossip_debug_mask, 0); + + /* remove any invalid values from the mask */ + debug_string_to_mask(kernel_debug_string, &gossip_debug_mask, 0); + + /* + * if the mask has a non-zero value, then indicate that the mask + * was set when the kernel module was loaded. The pvfs2 dev ioctl + * command will look at this boolean to determine if the kernel's + * debug mask should be overwritten when the client-core is started. + */ + if (gossip_debug_mask != 0) + kernel_mask_set_mod_init = true; + + /* print information message to the system log */ + pr_info("pvfs2: pvfs2_init called with debug mask: :%s: :%llx:\n", + kernel_debug_string, + (unsigned long long)gossip_debug_mask); + + ret = bdi_init(&pvfs2_backing_dev_info); + + if (ret) + return ret; + + if (op_timeout_secs < 0) + op_timeout_secs = 0; + + if (slot_timeout_secs < 0) + slot_timeout_secs = 0; + + /* initialize global book keeping data structures */ + ret = op_cache_initialize(); + if (ret < 0) + goto err; + + ret = dev_req_cache_initialize(); + if (ret < 0) + goto cleanup_op; + + ret = pvfs2_inode_cache_initialize(); + if (ret < 0) + goto cleanup_req; + + ret = kiocb_cache_initialize(); + if (ret < 0) + goto cleanup_inode; + + /* Initialize the pvfsdev subsystem. */ + ret = pvfs2_dev_init(); + if (ret < 0) { + gossip_err("pvfs2: could not initialize device subsystem %d!\n", + ret); + goto cleanup_kiocb; + } + + mutex_init(&devreq_mutex); + mutex_init(&request_mutex); + + htable_ops_in_progress = + kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL); + if (!htable_ops_in_progress) { + gossip_err("Failed to initialize op hashtable"); + ret = -ENOMEM; + goto cleanup_device; + } + + /* initialize a doubly linked at each hash table index */ + for (i = 0; i < hash_table_size; i++) + INIT_LIST_HEAD(&htable_ops_in_progress[i]); + + ret = fsid_key_table_initialize(); + if (ret < 0) + goto cleanup_progress_table; + + /* + * Build the contents of /sys/kernel/debug/orangefs/debug-help + * from the keywords in the kernel keyword/mask array. + * + * The keywords in the client keyword/mask array are + * unknown at boot time. + * + * orangefs_prepare_debugfs_help_string will be used again + * later to rebuild the debug-help file after the client starts + * and passes along the needed info. The argument signifies + * which time orangefs_prepare_debugfs_help_string is being + * called. + * + */ + ret = orangefs_prepare_debugfs_help_string(1); + if (ret) + goto out; + + pvfs2_debugfs_init(); + pvfs2_kernel_debug_init(); + orangefs_sysfs_init(); + + ret = register_filesystem(&pvfs2_fs_type); + if (ret == 0) { + pr_info("pvfs2: module version %s loaded\n", PVFS2_VERSION); + return 0; + } + + pvfs2_debugfs_cleanup(); + orangefs_sysfs_exit(); + fsid_key_table_finalize(); + +cleanup_progress_table: + kfree(htable_ops_in_progress); + +cleanup_device: + pvfs2_dev_cleanup(); + +cleanup_kiocb: + kiocb_cache_finalize(); + +cleanup_inode: + pvfs2_inode_cache_finalize(); + +cleanup_req: + dev_req_cache_finalize(); + +cleanup_op: + op_cache_finalize(); + +err: + bdi_destroy(&pvfs2_backing_dev_info); + +out: + return ret; +} + +static void __exit pvfs2_exit(void) +{ + int i = 0; + struct pvfs2_kernel_op_s *cur_op = NULL; + + gossip_debug(GOSSIP_INIT_DEBUG, "pvfs2: pvfs2_exit called\n"); + + unregister_filesystem(&pvfs2_fs_type); + pvfs2_debugfs_cleanup(); + orangefs_sysfs_exit(); + fsid_key_table_finalize(); + pvfs2_dev_cleanup(); + /* clear out all pending upcall op requests */ + spin_lock(&pvfs2_request_list_lock); + while (!list_empty(&pvfs2_request_list)) { + cur_op = list_entry(pvfs2_request_list.next, + struct pvfs2_kernel_op_s, + list); + list_del(&cur_op->list); + gossip_debug(GOSSIP_INIT_DEBUG, + "Freeing unhandled upcall request type %d\n", + cur_op->upcall.type); + op_release(cur_op); + } + spin_unlock(&pvfs2_request_list_lock); + + for (i = 0; i < hash_table_size; i++) + while (!list_empty(&htable_ops_in_progress[i])) { + cur_op = list_entry(htable_ops_in_progress[i].next, + struct pvfs2_kernel_op_s, + list); + op_release(cur_op); + } + + kiocb_cache_finalize(); + pvfs2_inode_cache_finalize(); + dev_req_cache_finalize(); + op_cache_finalize(); + + kfree(htable_ops_in_progress); + + bdi_destroy(&pvfs2_backing_dev_info); + + pr_info("pvfs2: module version %s unloaded\n", PVFS2_VERSION); +} + +/* + * What we do in this function is to walk the list of operations + * that are in progress in the hash table and mark them as purged as well. + */ +void purge_inprogress_ops(void) +{ + int i; + + for (i = 0; i < hash_table_size; i++) { + struct pvfs2_kernel_op_s *op; + struct pvfs2_kernel_op_s *next; + + list_for_each_entry_safe(op, + next, + &htable_ops_in_progress[i], + list) { + spin_lock(&op->lock); + gossip_debug(GOSSIP_INIT_DEBUG, + "pvfs2-client-core: purging in-progress op tag " + "%llu %s\n", + llu(op->tag), + get_opname_string(op)); + set_op_state_purged(op); + spin_unlock(&op->lock); + wake_up_interruptible(&op->waitq); + } + } +} + +module_init(pvfs2_init); +module_exit(pvfs2_exit); -- GitLab From f7be4ee07fb72a516563bc2870ef41fa589a964a Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:14 -0400 Subject: [PATCH 0004/5324] Orangefs: kernel client part 4 Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-sysfs.c | 1787 +++++++++++++++++++++++++++++++++++++ fs/orangefs/pvfs2-utils.c | 1128 +++++++++++++++++++++++ 2 files changed, 2915 insertions(+) create mode 100644 fs/orangefs/pvfs2-sysfs.c create mode 100644 fs/orangefs/pvfs2-utils.c diff --git a/fs/orangefs/pvfs2-sysfs.c b/fs/orangefs/pvfs2-sysfs.c new file mode 100644 index 000000000000..6d0e18b7239f --- /dev/null +++ b/fs/orangefs/pvfs2-sysfs.c @@ -0,0 +1,1787 @@ +/* + * Documentation/ABI/stable/orangefs-sysfs: + * + * What: /sys/fs/orangefs/perf_counter_reset + * Date: June 2015 + * Contact: Mike Marshall + * Description: + * echo a 0 or a 1 into perf_counter_reset to + * reset all the counters in + * /sys/fs/orangefs/perf_counters + * except ones with PINT_PERF_PRESERVE set. + * + * + * What: /sys/fs/orangefs/perf_counters/... + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Counters and settings for various caches. + * Read only. + * + * + * What: /sys/fs/orangefs/perf_time_interval_secs + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Length of perf counter intervals in + * seconds. + * + * + * What: /sys/fs/orangefs/perf_history_size + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * The perf_counters cache statistics have N, or + * perf_history_size, samples. The default is + * one. + * + * Every perf_time_interval_secs the (first) + * samples are reset. + * + * If N is greater than one, the "current" set + * of samples is reset, and the samples from the + * other N-1 intervals remain available. + * + * + * What: /sys/fs/orangefs/op_timeout_secs + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Service operation timeout in seconds. + * + * + * What: /sys/fs/orangefs/slot_timeout_secs + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * "Slot" timeout in seconds. A "slot" + * is an indexed buffer in the shared + * memory segment used for communication + * between the kernel module and userspace. + * Slots are requested and waited for, + * the wait times out after slot_timeout_secs. + * + * + * What: /sys/fs/orangefs/acache/... + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Attribute cache configurable settings. + * + * + * What: /sys/fs/orangefs/ncache/... + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Name cache configurable settings. + * + * + * What: /sys/fs/orangefs/capcache/... + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Capability cache configurable settings. + * + * + * What: /sys/fs/orangefs/ccache/... + * Date: Jun 2015 + * Contact: Mike Marshall + * Description: + * Credential cache configurable settings. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-sysfs.h" + +#define ORANGEFS_KOBJ_ID "orangefs" +#define ACACHE_KOBJ_ID "acache" +#define CAPCACHE_KOBJ_ID "capcache" +#define CCACHE_KOBJ_ID "ccache" +#define NCACHE_KOBJ_ID "ncache" +#define PC_KOBJ_ID "pc" +#define STATS_KOBJ_ID "stats" + +struct orangefs_obj { + struct kobject kobj; + int op_timeout_secs; + int perf_counter_reset; + int perf_history_size; + int perf_time_interval_secs; + int slot_timeout_secs; +}; + +struct acache_orangefs_obj { + struct kobject kobj; + int hard_limit; + int reclaim_percentage; + int soft_limit; + int timeout_msecs; +}; + +struct capcache_orangefs_obj { + struct kobject kobj; + int hard_limit; + int reclaim_percentage; + int soft_limit; + int timeout_secs; +}; + +struct ccache_orangefs_obj { + struct kobject kobj; + int hard_limit; + int reclaim_percentage; + int soft_limit; + int timeout_secs; +}; + +struct ncache_orangefs_obj { + struct kobject kobj; + int hard_limit; + int reclaim_percentage; + int soft_limit; + int timeout_msecs; +}; + +struct pc_orangefs_obj { + struct kobject kobj; + char *acache; + char *capcache; + char *ncache; +}; + +struct stats_orangefs_obj { + struct kobject kobj; + int reads; + int writes; +}; + +struct orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct acache_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct acache_orangefs_obj *acache_orangefs_obj, + struct acache_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct acache_orangefs_obj *acache_orangefs_obj, + struct acache_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct capcache_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct capcache_orangefs_obj *capcache_orangefs_obj, + struct capcache_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct capcache_orangefs_obj *capcache_orangefs_obj, + struct capcache_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct ccache_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct ccache_orangefs_obj *ccache_orangefs_obj, + struct ccache_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct ccache_orangefs_obj *ccache_orangefs_obj, + struct ccache_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct ncache_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct ncache_orangefs_obj *ncache_orangefs_obj, + struct ncache_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct ncache_orangefs_obj *ncache_orangefs_obj, + struct ncache_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct pc_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct pc_orangefs_obj *pc_orangefs_obj, + struct pc_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct pc_orangefs_obj *pc_orangefs_obj, + struct pc_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +struct stats_orangefs_attribute { + struct attribute attr; + ssize_t (*show)(struct stats_orangefs_obj *stats_orangefs_obj, + struct stats_orangefs_attribute *attr, + char *buf); + ssize_t (*store)(struct stats_orangefs_obj *stats_orangefs_obj, + struct stats_orangefs_attribute *attr, + const char *buf, + size_t count); +}; + +static ssize_t orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct orangefs_attribute *attribute; + struct orangefs_obj *orangefs_obj; + int rc; + + attribute = container_of(attr, struct orangefs_attribute, attr); + orangefs_obj = container_of(kobj, struct orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(orangefs_obj, attribute, buf); + +out: + return rc; +} + +static ssize_t orangefs_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t len) +{ + struct orangefs_attribute *attribute; + struct orangefs_obj *orangefs_obj; + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "orangefs_attr_store: start\n"); + + attribute = container_of(attr, struct orangefs_attribute, attr); + orangefs_obj = container_of(kobj, struct orangefs_obj, kobj); + + if (!attribute->store) { + rc = -EIO; + goto out; + } + + rc = attribute->store(orangefs_obj, attribute, buf, len); + +out: + return rc; +} + +static const struct sysfs_ops orangefs_sysfs_ops = { + .show = orangefs_attr_show, + .store = orangefs_attr_store, +}; + +static ssize_t acache_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct acache_orangefs_attribute *attribute; + struct acache_orangefs_obj *acache_orangefs_obj; + int rc; + + attribute = container_of(attr, struct acache_orangefs_attribute, attr); + acache_orangefs_obj = + container_of(kobj, struct acache_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(acache_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static ssize_t acache_orangefs_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t len) +{ + struct acache_orangefs_attribute *attribute; + struct acache_orangefs_obj *acache_orangefs_obj; + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "acache_orangefs_attr_store: start\n"); + + attribute = container_of(attr, struct acache_orangefs_attribute, attr); + acache_orangefs_obj = + container_of(kobj, struct acache_orangefs_obj, kobj); + + if (!attribute->store) { + rc = -EIO; + goto out; + } + + rc = attribute->store(acache_orangefs_obj, attribute, buf, len); + +out: + return rc; +} + +static const struct sysfs_ops acache_orangefs_sysfs_ops = { + .show = acache_orangefs_attr_show, + .store = acache_orangefs_attr_store, +}; + +static ssize_t capcache_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct capcache_orangefs_attribute *attribute; + struct capcache_orangefs_obj *capcache_orangefs_obj; + int rc; + + attribute = + container_of(attr, struct capcache_orangefs_attribute, attr); + capcache_orangefs_obj = + container_of(kobj, struct capcache_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(capcache_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static ssize_t capcache_orangefs_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t len) +{ + struct capcache_orangefs_attribute *attribute; + struct capcache_orangefs_obj *capcache_orangefs_obj; + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "capcache_orangefs_attr_store: start\n"); + + attribute = + container_of(attr, struct capcache_orangefs_attribute, attr); + capcache_orangefs_obj = + container_of(kobj, struct capcache_orangefs_obj, kobj); + + if (!attribute->store) { + rc = -EIO; + goto out; + } + + rc = attribute->store(capcache_orangefs_obj, attribute, buf, len); + +out: + return rc; +} + +static const struct sysfs_ops capcache_orangefs_sysfs_ops = { + .show = capcache_orangefs_attr_show, + .store = capcache_orangefs_attr_store, +}; + +static ssize_t ccache_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ccache_orangefs_attribute *attribute; + struct ccache_orangefs_obj *ccache_orangefs_obj; + int rc; + + attribute = + container_of(attr, struct ccache_orangefs_attribute, attr); + ccache_orangefs_obj = + container_of(kobj, struct ccache_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(ccache_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static ssize_t ccache_orangefs_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t len) +{ + struct ccache_orangefs_attribute *attribute; + struct ccache_orangefs_obj *ccache_orangefs_obj; + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "ccache_orangefs_attr_store: start\n"); + + attribute = + container_of(attr, struct ccache_orangefs_attribute, attr); + ccache_orangefs_obj = + container_of(kobj, struct ccache_orangefs_obj, kobj); + + if (!attribute->store) { + rc = -EIO; + goto out; + } + + rc = attribute->store(ccache_orangefs_obj, attribute, buf, len); + +out: + return rc; +} + +static const struct sysfs_ops ccache_orangefs_sysfs_ops = { + .show = ccache_orangefs_attr_show, + .store = ccache_orangefs_attr_store, +}; + +static ssize_t ncache_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct ncache_orangefs_attribute *attribute; + struct ncache_orangefs_obj *ncache_orangefs_obj; + int rc; + + attribute = container_of(attr, struct ncache_orangefs_attribute, attr); + ncache_orangefs_obj = + container_of(kobj, struct ncache_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(ncache_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static ssize_t ncache_orangefs_attr_store(struct kobject *kobj, + struct attribute *attr, + const char *buf, + size_t len) +{ + struct ncache_orangefs_attribute *attribute; + struct ncache_orangefs_obj *ncache_orangefs_obj; + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "ncache_orangefs_attr_store: start\n"); + + attribute = container_of(attr, struct ncache_orangefs_attribute, attr); + ncache_orangefs_obj = + container_of(kobj, struct ncache_orangefs_obj, kobj); + + if (!attribute->store) { + rc = -EIO; + goto out; + } + + rc = attribute->store(ncache_orangefs_obj, attribute, buf, len); + +out: + return rc; +} + +static const struct sysfs_ops ncache_orangefs_sysfs_ops = { + .show = ncache_orangefs_attr_show, + .store = ncache_orangefs_attr_store, +}; + +static ssize_t pc_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct pc_orangefs_attribute *attribute; + struct pc_orangefs_obj *pc_orangefs_obj; + int rc; + + attribute = container_of(attr, struct pc_orangefs_attribute, attr); + pc_orangefs_obj = + container_of(kobj, struct pc_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(pc_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static const struct sysfs_ops pc_orangefs_sysfs_ops = { + .show = pc_orangefs_attr_show, +}; + +static ssize_t stats_orangefs_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct stats_orangefs_attribute *attribute; + struct stats_orangefs_obj *stats_orangefs_obj; + int rc; + + attribute = container_of(attr, struct stats_orangefs_attribute, attr); + stats_orangefs_obj = + container_of(kobj, struct stats_orangefs_obj, kobj); + + if (!attribute->show) { + rc = -EIO; + goto out; + } + + rc = attribute->show(stats_orangefs_obj, attribute, buf); + +out: + return rc; +} + +static const struct sysfs_ops stats_orangefs_sysfs_ops = { + .show = stats_orangefs_attr_show, +}; + +static void orangefs_release(struct kobject *kobj) +{ + struct orangefs_obj *orangefs_obj; + + orangefs_obj = container_of(kobj, struct orangefs_obj, kobj); + kfree(orangefs_obj); +} + +static void acache_orangefs_release(struct kobject *kobj) +{ + struct acache_orangefs_obj *acache_orangefs_obj; + + acache_orangefs_obj = + container_of(kobj, struct acache_orangefs_obj, kobj); + kfree(acache_orangefs_obj); +} + +static void capcache_orangefs_release(struct kobject *kobj) +{ + struct capcache_orangefs_obj *capcache_orangefs_obj; + + capcache_orangefs_obj = + container_of(kobj, struct capcache_orangefs_obj, kobj); + kfree(capcache_orangefs_obj); +} + +static void ccache_orangefs_release(struct kobject *kobj) +{ + struct ccache_orangefs_obj *ccache_orangefs_obj; + + ccache_orangefs_obj = + container_of(kobj, struct ccache_orangefs_obj, kobj); + kfree(ccache_orangefs_obj); +} + +static void ncache_orangefs_release(struct kobject *kobj) +{ + struct ncache_orangefs_obj *ncache_orangefs_obj; + + ncache_orangefs_obj = + container_of(kobj, struct ncache_orangefs_obj, kobj); + kfree(ncache_orangefs_obj); +} + +static void pc_orangefs_release(struct kobject *kobj) +{ + struct pc_orangefs_obj *pc_orangefs_obj; + + pc_orangefs_obj = + container_of(kobj, struct pc_orangefs_obj, kobj); + kfree(pc_orangefs_obj); +} + +static void stats_orangefs_release(struct kobject *kobj) +{ + struct stats_orangefs_obj *stats_orangefs_obj; + + stats_orangefs_obj = + container_of(kobj, struct stats_orangefs_obj, kobj); + kfree(stats_orangefs_obj); +} + +static ssize_t sysfs_int_show(char *kobj_id, char *buf, void *attr) +{ + int rc = -EIO; + struct orangefs_attribute *orangefs_attr; + struct stats_orangefs_attribute *stats_orangefs_attr; + + gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", kobj_id); + + if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) { + orangefs_attr = (struct orangefs_attribute *)attr; + + if (!strcmp(orangefs_attr->attr.name, "op_timeout_secs")) { + rc = scnprintf(buf, + PAGE_SIZE, + "%d\n", + op_timeout_secs); + goto out; + } else if (!strcmp(orangefs_attr->attr.name, + "slot_timeout_secs")) { + rc = scnprintf(buf, + PAGE_SIZE, + "%d\n", + slot_timeout_secs); + goto out; + } else { + goto out; + } + + } else if (!strcmp(kobj_id, STATS_KOBJ_ID)) { + stats_orangefs_attr = (struct stats_orangefs_attribute *)attr; + + if (!strcmp(stats_orangefs_attr->attr.name, "reads")) { + rc = scnprintf(buf, + PAGE_SIZE, + "%lu\n", + g_pvfs2_stats.reads); + goto out; + } else if (!strcmp(stats_orangefs_attr->attr.name, "writes")) { + rc = scnprintf(buf, + PAGE_SIZE, + "%lu\n", + g_pvfs2_stats.writes); + goto out; + } else { + goto out; + } + } + +out: + + return rc; +} + +static ssize_t int_orangefs_show(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + char *buf) +{ + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "int_orangefs_show:start attr->attr.name:%s:\n", + attr->attr.name); + + rc = sysfs_int_show(ORANGEFS_KOBJ_ID, buf, (void *) attr); + + return rc; +} + +static ssize_t int_stats_show(struct stats_orangefs_obj *stats_orangefs_obj, + struct stats_orangefs_attribute *attr, + char *buf) +{ + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "int_stats_show:start attr->attr.name:%s:\n", + attr->attr.name); + + rc = sysfs_int_show(STATS_KOBJ_ID, buf, (void *) attr); + + return rc; +} + +static ssize_t int_store(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "int_store: start attr->attr.name:%s: buf:%s:\n", + attr->attr.name, buf); + + if (!strcmp(attr->attr.name, "op_timeout_secs")) { + rc = kstrtoint(buf, 0, &op_timeout_secs); + goto out; + } else if (!strcmp(attr->attr.name, "slot_timeout_secs")) { + rc = kstrtoint(buf, 0, &slot_timeout_secs); + goto out; + } else { + goto out; + } + +out: + if (rc) + rc = -EINVAL; + else + rc = count; + + return rc; +} + +/* + * obtain attribute values from userspace with a service operation. + */ +int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) +{ + struct pvfs2_kernel_op_s *new_op = NULL; + int rc = 0; + char *ser_op_type = NULL; + struct orangefs_attribute *orangefs_attr; + struct acache_orangefs_attribute *acache_attr; + struct capcache_orangefs_attribute *capcache_attr; + struct ccache_orangefs_attribute *ccache_attr; + struct ncache_orangefs_attribute *ncache_attr; + struct pc_orangefs_attribute *pc_attr; + __u32 op_alloc_type; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "sysfs_service_op_show: id:%s:\n", + kobj_id); + + if (strcmp(kobj_id, PC_KOBJ_ID)) + op_alloc_type = PVFS2_VFS_OP_PARAM; + else + op_alloc_type = PVFS2_VFS_OP_PERF_COUNT; + + new_op = op_alloc(op_alloc_type); + if (!new_op) { + rc = -ENOMEM; + goto out; + } + + /* Can't do a service_operation if the client is not running... */ + rc = is_daemon_in_service(); + if (rc) { + pr_info("%s: Client not running :%d:\n", + __func__, + is_daemon_in_service()); + goto out; + } + + if (strcmp(kobj_id, PC_KOBJ_ID)) + new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_GET; + + if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) { + orangefs_attr = (struct orangefs_attribute *)attr; + + if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; + else if (!strcmp(orangefs_attr->attr.name, + "perf_time_interval_secs")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; + else if (!strcmp(orangefs_attr->attr.name, + "perf_counter_reset")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_RESET; + + } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) { + acache_attr = (struct acache_orangefs_attribute *)attr; + + if (!strcmp(acache_attr->attr.name, "timeout_msecs")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; + + if (!strcmp(acache_attr->attr.name, "hard_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; + + if (!strcmp(acache_attr->attr.name, "soft_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; + + if (!strcmp(acache_attr->attr.name, "reclaim_percentage")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; + + } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) { + capcache_attr = (struct capcache_orangefs_attribute *)attr; + + if (!strcmp(capcache_attr->attr.name, "timeout_secs")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; + + if (!strcmp(capcache_attr->attr.name, "hard_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; + + if (!strcmp(capcache_attr->attr.name, "soft_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; + + if (!strcmp(capcache_attr->attr.name, "reclaim_percentage")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; + + } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) { + ccache_attr = (struct ccache_orangefs_attribute *)attr; + + if (!strcmp(ccache_attr->attr.name, "timeout_secs")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; + + if (!strcmp(ccache_attr->attr.name, "hard_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; + + if (!strcmp(ccache_attr->attr.name, "soft_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; + + if (!strcmp(ccache_attr->attr.name, "reclaim_percentage")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; + + } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) { + ncache_attr = (struct ncache_orangefs_attribute *)attr; + + if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; + + if (!strcmp(ncache_attr->attr.name, "hard_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; + + if (!strcmp(ncache_attr->attr.name, "soft_limit")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; + + if (!strcmp(ncache_attr->attr.name, "reclaim_percentage")) + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; + + } else if (!strcmp(kobj_id, PC_KOBJ_ID)) { + pc_attr = (struct pc_orangefs_attribute *)attr; + + if (!strcmp(pc_attr->attr.name, ACACHE_KOBJ_ID)) + new_op->upcall.req.perf_count.type = + PVFS2_PERF_COUNT_REQUEST_ACACHE; + + if (!strcmp(pc_attr->attr.name, CAPCACHE_KOBJ_ID)) + new_op->upcall.req.perf_count.type = + PVFS2_PERF_COUNT_REQUEST_CAPCACHE; + + if (!strcmp(pc_attr->attr.name, NCACHE_KOBJ_ID)) + new_op->upcall.req.perf_count.type = + PVFS2_PERF_COUNT_REQUEST_NCACHE; + + } else { + gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n", + kobj_id); + rc = -EINVAL; + goto out; + } + + + if (strcmp(kobj_id, PC_KOBJ_ID)) + ser_op_type = "pvfs2_param"; + else + ser_op_type = "pvfs2_perf_count"; + + /* + * The service_operation will return an errno return code on + * error, and zero on success. + */ + rc = service_operation(new_op, ser_op_type, PVFS2_OP_INTERRUPTIBLE); + +out: + if (!rc) { + if (strcmp(kobj_id, PC_KOBJ_ID)) { + rc = scnprintf(buf, + PAGE_SIZE, + "%d\n", + (int)new_op->downcall.resp.param.value); + } else { + rc = scnprintf( + buf, + PAGE_SIZE, + "%s", + new_op->downcall.resp.perf_count.buffer); + } + } + + /* + * if we got ENOMEM, then op_alloc probably failed... + */ + if (rc != -ENOMEM) + op_release(new_op); + + return rc; + +} + +static ssize_t service_orangefs_show(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(ORANGEFS_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +static ssize_t + service_acache_show(struct acache_orangefs_obj *acache_orangefs_obj, + struct acache_orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(ACACHE_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +static ssize_t service_capcache_show(struct capcache_orangefs_obj + *capcache_orangefs_obj, + struct capcache_orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(CAPCACHE_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +static ssize_t service_ccache_show(struct ccache_orangefs_obj + *ccache_orangefs_obj, + struct ccache_orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(CCACHE_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +static ssize_t + service_ncache_show(struct ncache_orangefs_obj *ncache_orangefs_obj, + struct ncache_orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(NCACHE_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +static ssize_t + service_pc_show(struct pc_orangefs_obj *pc_orangefs_obj, + struct pc_orangefs_attribute *attr, + char *buf) +{ + int rc = 0; + + rc = sysfs_service_op_show(PC_KOBJ_ID, buf, (void *)attr); + + return rc; +} + +/* + * pass attribute values back to userspace with a service operation. + * + * We have to do a memory allocation, an sscanf and a service operation. + * And we have to evaluate what the user entered, to make sure the + * value is within the range supported by the attribute. So, there's + * a lot of return code checking and mapping going on here. + * + * We want to return 1 if we think everything went OK, and + * EINVAL if not. + */ +int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) +{ + struct pvfs2_kernel_op_s *new_op = NULL; + int val = 0; + int rc = 0; + struct orangefs_attribute *orangefs_attr; + struct acache_orangefs_attribute *acache_attr; + struct capcache_orangefs_attribute *capcache_attr; + struct ccache_orangefs_attribute *ccache_attr; + struct ncache_orangefs_attribute *ncache_attr; + + gossip_debug(GOSSIP_SYSFS_DEBUG, + "sysfs_service_op_store: id:%s:\n", + kobj_id); + + new_op = op_alloc(PVFS2_VFS_OP_PARAM); + if (!new_op) { + rc = -ENOMEM; + goto out; + } + + /* Can't do a service_operation if the client is not running... */ + rc = is_daemon_in_service(); + if (rc) { + pr_info("%s: Client not running :%d:\n", + __func__, + is_daemon_in_service()); + goto out; + } + + /* + * The value we want to send back to userspace is in buf. + */ + rc = kstrtoint(buf, 0, &val); + if (rc) + goto out; + + if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) { + orangefs_attr = (struct orangefs_attribute *)attr; + + if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) { + if (val > 0) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(orangefs_attr->attr.name, + "perf_time_interval_secs")) { + if (val > 0) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(orangefs_attr->attr.name, + "perf_counter_reset")) { + if ((val == 0) || (val == 1)) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_PERF_RESET; + } else { + rc = 0; + goto out; + } + } + + } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) { + acache_attr = (struct acache_orangefs_attribute *)attr; + + if (!strcmp(acache_attr->attr.name, "hard_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(acache_attr->attr.name, "soft_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(acache_attr->attr.name, + "reclaim_percentage")) { + if ((val > -1) && (val < 101)) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(acache_attr->attr.name, "timeout_msecs")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; + } else { + rc = 0; + goto out; + } + } + + } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) { + capcache_attr = (struct capcache_orangefs_attribute *)attr; + + if (!strcmp(capcache_attr->attr.name, "hard_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(capcache_attr->attr.name, "soft_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(capcache_attr->attr.name, + "reclaim_percentage")) { + if ((val > -1) && (val < 101)) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(capcache_attr->attr.name, "timeout_secs")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; + } else { + rc = 0; + goto out; + } + } + + } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) { + ccache_attr = (struct ccache_orangefs_attribute *)attr; + + if (!strcmp(ccache_attr->attr.name, "hard_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ccache_attr->attr.name, "soft_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ccache_attr->attr.name, + "reclaim_percentage")) { + if ((val > -1) && (val < 101)) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ccache_attr->attr.name, "timeout_secs")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; + } else { + rc = 0; + goto out; + } + } + + } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) { + ncache_attr = (struct ncache_orangefs_attribute *)attr; + + if (!strcmp(ncache_attr->attr.name, "hard_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ncache_attr->attr.name, "soft_limit")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ncache_attr->attr.name, + "reclaim_percentage")) { + if ((val > -1) && (val < 101)) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; + } else { + rc = 0; + goto out; + } + } else if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) { + if (val > -1) { + new_op->upcall.req.param.op = + PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; + } else { + rc = 0; + goto out; + } + } + + } else { + gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n", + kobj_id); + rc = -EINVAL; + goto out; + } + + new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET; + + new_op->upcall.req.param.value = val; + + /* + * The service_operation will return a errno return code on + * error, and zero on success. + */ + rc = service_operation(new_op, "pvfs2_param", PVFS2_OP_INTERRUPTIBLE); + + if (rc < 0) { + gossip_err("sysfs_service_op_store: service op returned:%d:\n", + rc); + rc = 0; + } else { + rc = 1; + } + +out: + /* + * if we got ENOMEM, then op_alloc probably failed... + */ + if (rc == -ENOMEM) + rc = 0; + else + op_release(new_op); + + if (rc == 0) + rc = -EINVAL; + + return rc; +} + +static ssize_t + service_orangefs_store(struct orangefs_obj *orangefs_obj, + struct orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + rc = sysfs_service_op_store(ORANGEFS_KOBJ_ID, buf, (void *) attr); + + /* rc should have an errno value if the service_op went bad. */ + if (rc == 1) + rc = count; + + return rc; +} + +static ssize_t + service_acache_store(struct acache_orangefs_obj *acache_orangefs_obj, + struct acache_orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + rc = sysfs_service_op_store(ACACHE_KOBJ_ID, buf, (void *) attr); + + /* rc should have an errno value if the service_op went bad. */ + if (rc == 1) + rc = count; + + return rc; +} + +static ssize_t + service_capcache_store(struct capcache_orangefs_obj + *capcache_orangefs_obj, + struct capcache_orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + rc = sysfs_service_op_store(CAPCACHE_KOBJ_ID, buf, (void *) attr); + + /* rc should have an errno value if the service_op went bad. */ + if (rc == 1) + rc = count; + + return rc; +} + +static ssize_t service_ccache_store(struct ccache_orangefs_obj + *ccache_orangefs_obj, + struct ccache_orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + rc = sysfs_service_op_store(CCACHE_KOBJ_ID, buf, (void *) attr); + + /* rc should have an errno value if the service_op went bad. */ + if (rc == 1) + rc = count; + + return rc; +} + +static ssize_t + service_ncache_store(struct ncache_orangefs_obj *ncache_orangefs_obj, + struct ncache_orangefs_attribute *attr, + const char *buf, + size_t count) +{ + int rc = 0; + + rc = sysfs_service_op_store(NCACHE_KOBJ_ID, buf, (void *) attr); + + /* rc should have an errno value if the service_op went bad. */ + if (rc == 1) + rc = count; + + return rc; +} + +static struct orangefs_attribute op_timeout_secs_attribute = + __ATTR(op_timeout_secs, 0664, int_orangefs_show, int_store); + +static struct orangefs_attribute slot_timeout_secs_attribute = + __ATTR(slot_timeout_secs, 0664, int_orangefs_show, int_store); + +static struct orangefs_attribute perf_counter_reset_attribute = + __ATTR(perf_counter_reset, + 0664, + service_orangefs_show, + service_orangefs_store); + +static struct orangefs_attribute perf_history_size_attribute = + __ATTR(perf_history_size, + 0664, + service_orangefs_show, + service_orangefs_store); + +static struct orangefs_attribute perf_time_interval_secs_attribute = + __ATTR(perf_time_interval_secs, + 0664, + service_orangefs_show, + service_orangefs_store); + +static struct attribute *orangefs_default_attrs[] = { + &op_timeout_secs_attribute.attr, + &slot_timeout_secs_attribute.attr, + &perf_counter_reset_attribute.attr, + &perf_history_size_attribute.attr, + &perf_time_interval_secs_attribute.attr, + NULL, +}; + +static struct kobj_type orangefs_ktype = { + .sysfs_ops = &orangefs_sysfs_ops, + .release = orangefs_release, + .default_attrs = orangefs_default_attrs, +}; + +static struct acache_orangefs_attribute acache_hard_limit_attribute = + __ATTR(hard_limit, + 0664, + service_acache_show, + service_acache_store); + +static struct acache_orangefs_attribute acache_reclaim_percent_attribute = + __ATTR(reclaim_percentage, + 0664, + service_acache_show, + service_acache_store); + +static struct acache_orangefs_attribute acache_soft_limit_attribute = + __ATTR(soft_limit, + 0664, + service_acache_show, + service_acache_store); + +static struct acache_orangefs_attribute acache_timeout_msecs_attribute = + __ATTR(timeout_msecs, + 0664, + service_acache_show, + service_acache_store); + +static struct attribute *acache_orangefs_default_attrs[] = { + &acache_hard_limit_attribute.attr, + &acache_reclaim_percent_attribute.attr, + &acache_soft_limit_attribute.attr, + &acache_timeout_msecs_attribute.attr, + NULL, +}; + +static struct kobj_type acache_orangefs_ktype = { + .sysfs_ops = &acache_orangefs_sysfs_ops, + .release = acache_orangefs_release, + .default_attrs = acache_orangefs_default_attrs, +}; + +static struct capcache_orangefs_attribute capcache_hard_limit_attribute = + __ATTR(hard_limit, + 0664, + service_capcache_show, + service_capcache_store); + +static struct capcache_orangefs_attribute capcache_reclaim_percent_attribute = + __ATTR(reclaim_percentage, + 0664, + service_capcache_show, + service_capcache_store); + +static struct capcache_orangefs_attribute capcache_soft_limit_attribute = + __ATTR(soft_limit, + 0664, + service_capcache_show, + service_capcache_store); + +static struct capcache_orangefs_attribute capcache_timeout_secs_attribute = + __ATTR(timeout_secs, + 0664, + service_capcache_show, + service_capcache_store); + +static struct attribute *capcache_orangefs_default_attrs[] = { + &capcache_hard_limit_attribute.attr, + &capcache_reclaim_percent_attribute.attr, + &capcache_soft_limit_attribute.attr, + &capcache_timeout_secs_attribute.attr, + NULL, +}; + +static struct kobj_type capcache_orangefs_ktype = { + .sysfs_ops = &capcache_orangefs_sysfs_ops, + .release = capcache_orangefs_release, + .default_attrs = capcache_orangefs_default_attrs, +}; + +static struct ccache_orangefs_attribute ccache_hard_limit_attribute = + __ATTR(hard_limit, + 0664, + service_ccache_show, + service_ccache_store); + +static struct ccache_orangefs_attribute ccache_reclaim_percent_attribute = + __ATTR(reclaim_percentage, + 0664, + service_ccache_show, + service_ccache_store); + +static struct ccache_orangefs_attribute ccache_soft_limit_attribute = + __ATTR(soft_limit, + 0664, + service_ccache_show, + service_ccache_store); + +static struct ccache_orangefs_attribute ccache_timeout_secs_attribute = + __ATTR(timeout_secs, + 0664, + service_ccache_show, + service_ccache_store); + +static struct attribute *ccache_orangefs_default_attrs[] = { + &ccache_hard_limit_attribute.attr, + &ccache_reclaim_percent_attribute.attr, + &ccache_soft_limit_attribute.attr, + &ccache_timeout_secs_attribute.attr, + NULL, +}; + +static struct kobj_type ccache_orangefs_ktype = { + .sysfs_ops = &ccache_orangefs_sysfs_ops, + .release = ccache_orangefs_release, + .default_attrs = ccache_orangefs_default_attrs, +}; + +static struct ncache_orangefs_attribute ncache_hard_limit_attribute = + __ATTR(hard_limit, + 0664, + service_ncache_show, + service_ncache_store); + +static struct ncache_orangefs_attribute ncache_reclaim_percent_attribute = + __ATTR(reclaim_percentage, + 0664, + service_ncache_show, + service_ncache_store); + +static struct ncache_orangefs_attribute ncache_soft_limit_attribute = + __ATTR(soft_limit, + 0664, + service_ncache_show, + service_ncache_store); + +static struct ncache_orangefs_attribute ncache_timeout_msecs_attribute = + __ATTR(timeout_msecs, + 0664, + service_ncache_show, + service_ncache_store); + +static struct attribute *ncache_orangefs_default_attrs[] = { + &ncache_hard_limit_attribute.attr, + &ncache_reclaim_percent_attribute.attr, + &ncache_soft_limit_attribute.attr, + &ncache_timeout_msecs_attribute.attr, + NULL, +}; + +static struct kobj_type ncache_orangefs_ktype = { + .sysfs_ops = &ncache_orangefs_sysfs_ops, + .release = ncache_orangefs_release, + .default_attrs = ncache_orangefs_default_attrs, +}; + +static struct pc_orangefs_attribute pc_acache_attribute = + __ATTR(acache, + 0664, + service_pc_show, + NULL); + +static struct pc_orangefs_attribute pc_capcache_attribute = + __ATTR(capcache, + 0664, + service_pc_show, + NULL); + +static struct pc_orangefs_attribute pc_ncache_attribute = + __ATTR(ncache, + 0664, + service_pc_show, + NULL); + +static struct attribute *pc_orangefs_default_attrs[] = { + &pc_acache_attribute.attr, + &pc_capcache_attribute.attr, + &pc_ncache_attribute.attr, + NULL, +}; + +static struct kobj_type pc_orangefs_ktype = { + .sysfs_ops = &pc_orangefs_sysfs_ops, + .release = pc_orangefs_release, + .default_attrs = pc_orangefs_default_attrs, +}; + +static struct stats_orangefs_attribute stats_reads_attribute = + __ATTR(reads, + 0664, + int_stats_show, + NULL); + +static struct stats_orangefs_attribute stats_writes_attribute = + __ATTR(writes, + 0664, + int_stats_show, + NULL); + +static struct attribute *stats_orangefs_default_attrs[] = { + &stats_reads_attribute.attr, + &stats_writes_attribute.attr, + NULL, +}; + +static struct kobj_type stats_orangefs_ktype = { + .sysfs_ops = &stats_orangefs_sysfs_ops, + .release = stats_orangefs_release, + .default_attrs = stats_orangefs_default_attrs, +}; + +static struct orangefs_obj *orangefs_obj; +static struct acache_orangefs_obj *acache_orangefs_obj; +static struct capcache_orangefs_obj *capcache_orangefs_obj; +static struct ccache_orangefs_obj *ccache_orangefs_obj; +static struct ncache_orangefs_obj *ncache_orangefs_obj; +static struct pc_orangefs_obj *pc_orangefs_obj; +static struct stats_orangefs_obj *stats_orangefs_obj; + +int orangefs_sysfs_init(void) +{ + int rc; + + gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n"); + + /* create /sys/fs/orangefs. */ + orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL); + if (!orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&orangefs_obj->kobj, + &orangefs_ktype, + fs_kobj, + ORANGEFS_KOBJ_ID); + + if (rc) { + kobject_put(&orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/acache. */ + acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL); + if (!acache_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&acache_orangefs_obj->kobj, + &acache_orangefs_ktype, + &orangefs_obj->kobj, + ACACHE_KOBJ_ID); + + if (rc) { + kobject_put(&acache_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&acache_orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/capcache. */ + capcache_orangefs_obj = + kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL); + if (!capcache_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&capcache_orangefs_obj->kobj, + &capcache_orangefs_ktype, + &orangefs_obj->kobj, + CAPCACHE_KOBJ_ID); + if (rc) { + kobject_put(&capcache_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&capcache_orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/ccache. */ + ccache_orangefs_obj = + kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL); + if (!ccache_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&ccache_orangefs_obj->kobj, + &ccache_orangefs_ktype, + &orangefs_obj->kobj, + CCACHE_KOBJ_ID); + if (rc) { + kobject_put(&ccache_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&ccache_orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/ncache. */ + ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL); + if (!ncache_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&ncache_orangefs_obj->kobj, + &ncache_orangefs_ktype, + &orangefs_obj->kobj, + NCACHE_KOBJ_ID); + + if (rc) { + kobject_put(&ncache_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&ncache_orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/perf_counters. */ + pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL); + if (!pc_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&pc_orangefs_obj->kobj, + &pc_orangefs_ktype, + &orangefs_obj->kobj, + "perf_counters"); + + if (rc) { + kobject_put(&pc_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&pc_orangefs_obj->kobj, KOBJ_ADD); + + /* create /sys/fs/orangefs/stats. */ + stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL); + if (!stats_orangefs_obj) { + rc = -EINVAL; + goto out; + } + + rc = kobject_init_and_add(&stats_orangefs_obj->kobj, + &stats_orangefs_ktype, + &orangefs_obj->kobj, + STATS_KOBJ_ID); + + if (rc) { + kobject_put(&stats_orangefs_obj->kobj); + rc = -EINVAL; + goto out; + } + + kobject_uevent(&stats_orangefs_obj->kobj, KOBJ_ADD); +out: + return rc; +} + +void orangefs_sysfs_exit(void) +{ + gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n"); + + kobject_put(&acache_orangefs_obj->kobj); + kobject_put(&capcache_orangefs_obj->kobj); + kobject_put(&ccache_orangefs_obj->kobj); + kobject_put(&ncache_orangefs_obj->kobj); + kobject_put(&pc_orangefs_obj->kobj); + kobject_put(&stats_orangefs_obj->kobj); + + kobject_put(&orangefs_obj->kobj); +} diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c new file mode 100644 index 000000000000..107f425d2e90 --- /dev/null +++ b/fs/orangefs/pvfs2-utils.c @@ -0,0 +1,1128 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-dev-proto.h" +#include "pvfs2-bufmap.h" + +__s32 fsid_of_op(struct pvfs2_kernel_op_s *op) +{ + __s32 fsid = PVFS_FS_ID_NULL; + + if (op) { + switch (op->upcall.type) { + case PVFS2_VFS_OP_FILE_IO: + fsid = op->upcall.req.io.refn.fs_id; + break; + case PVFS2_VFS_OP_LOOKUP: + fsid = op->upcall.req.lookup.parent_refn.fs_id; + break; + case PVFS2_VFS_OP_CREATE: + fsid = op->upcall.req.create.parent_refn.fs_id; + break; + case PVFS2_VFS_OP_GETATTR: + fsid = op->upcall.req.getattr.refn.fs_id; + break; + case PVFS2_VFS_OP_REMOVE: + fsid = op->upcall.req.remove.parent_refn.fs_id; + break; + case PVFS2_VFS_OP_MKDIR: + fsid = op->upcall.req.mkdir.parent_refn.fs_id; + break; + case PVFS2_VFS_OP_READDIR: + fsid = op->upcall.req.readdir.refn.fs_id; + break; + case PVFS2_VFS_OP_SETATTR: + fsid = op->upcall.req.setattr.refn.fs_id; + break; + case PVFS2_VFS_OP_SYMLINK: + fsid = op->upcall.req.sym.parent_refn.fs_id; + break; + case PVFS2_VFS_OP_RENAME: + fsid = op->upcall.req.rename.old_parent_refn.fs_id; + break; + case PVFS2_VFS_OP_STATFS: + fsid = op->upcall.req.statfs.fs_id; + break; + case PVFS2_VFS_OP_TRUNCATE: + fsid = op->upcall.req.truncate.refn.fs_id; + break; + case PVFS2_VFS_OP_MMAP_RA_FLUSH: + fsid = op->upcall.req.ra_cache_flush.refn.fs_id; + break; + case PVFS2_VFS_OP_FS_UMOUNT: + fsid = op->upcall.req.fs_umount.fs_id; + break; + case PVFS2_VFS_OP_GETXATTR: + fsid = op->upcall.req.getxattr.refn.fs_id; + break; + case PVFS2_VFS_OP_SETXATTR: + fsid = op->upcall.req.setxattr.refn.fs_id; + break; + case PVFS2_VFS_OP_LISTXATTR: + fsid = op->upcall.req.listxattr.refn.fs_id; + break; + case PVFS2_VFS_OP_REMOVEXATTR: + fsid = op->upcall.req.removexattr.refn.fs_id; + break; + case PVFS2_VFS_OP_FSYNC: + fsid = op->upcall.req.fsync.refn.fs_id; + break; + default: + break; + } + } + return fsid; +} + +static void pvfs2_set_inode_flags(struct inode *inode, + struct PVFS_sys_attr_s *attrs) +{ + if (attrs->flags & PVFS_IMMUTABLE_FL) + inode->i_flags |= S_IMMUTABLE; + else + inode->i_flags &= ~S_IMMUTABLE; + + if (attrs->flags & PVFS_APPEND_FL) + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; + + if (attrs->flags & PVFS_NOATIME_FL) + inode->i_flags |= S_NOATIME; + else + inode->i_flags &= ~S_NOATIME; + +} + +/* NOTE: symname is ignored unless the inode is a sym link */ +static int copy_attributes_to_inode(struct inode *inode, + struct PVFS_sys_attr_s *attrs, + char *symname) +{ + int ret = -1; + int perm_mode = 0; + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + loff_t inode_size = 0; + loff_t rounded_up_size = 0; + + + /* + arbitrarily set the inode block size; FIXME: we need to + resolve the difference between the reported inode blocksize + and the PAGE_CACHE_SIZE, since our block count will always + be wrong. + + For now, we're setting the block count to be the proper + number assuming the block size is 512 bytes, and the size is + rounded up to the nearest 4K. This is apparently required + to get proper size reports from the 'du' shell utility. + + changing the inode->i_blkbits to something other than + PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that. + */ + gossip_debug(GOSSIP_UTILS_DEBUG, + "attrs->mask = %x (objtype = %s)\n", + attrs->mask, + attrs->objtype == PVFS_TYPE_METAFILE ? "file" : + attrs->objtype == PVFS_TYPE_DIRECTORY ? "directory" : + attrs->objtype == PVFS_TYPE_SYMLINK ? "symlink" : + "invalid/unknown"); + + switch (attrs->objtype) { + case PVFS_TYPE_METAFILE: + pvfs2_set_inode_flags(inode, attrs); + if (attrs->mask & PVFS_ATTR_SYS_SIZE) { + inode_size = (loff_t) attrs->size; + rounded_up_size = + (inode_size + (4096 - (inode_size % 4096))); + + pvfs2_lock_inode(inode); + inode->i_bytes = inode_size; + inode->i_blocks = + (unsigned long)(rounded_up_size / 512); + pvfs2_unlock_inode(inode); + + /* + * NOTE: make sure all the places we're called + * from have the inode->i_sem lock. We're fine + * in 99% of the cases since we're mostly + * called from a lookup. + */ + inode->i_size = inode_size; + } + break; + case PVFS_TYPE_SYMLINK: + if (symname != NULL) { + inode->i_size = (loff_t) strlen(symname); + break; + } + /*FALLTHRU*/ + default: + pvfs2_lock_inode(inode); + inode->i_bytes = PAGE_CACHE_SIZE; + inode->i_blocks = (unsigned long)(PAGE_CACHE_SIZE / 512); + pvfs2_unlock_inode(inode); + + inode->i_size = PAGE_CACHE_SIZE; + break; + } + + inode->i_uid = make_kuid(&init_user_ns, attrs->owner); + inode->i_gid = make_kgid(&init_user_ns, attrs->group); + inode->i_atime.tv_sec = (time_t) attrs->atime; + inode->i_mtime.tv_sec = (time_t) attrs->mtime; + inode->i_ctime.tv_sec = (time_t) attrs->ctime; + inode->i_atime.tv_nsec = 0; + inode->i_mtime.tv_nsec = 0; + inode->i_ctime.tv_nsec = 0; + + if (attrs->perms & PVFS_O_EXECUTE) + perm_mode |= S_IXOTH; + if (attrs->perms & PVFS_O_WRITE) + perm_mode |= S_IWOTH; + if (attrs->perms & PVFS_O_READ) + perm_mode |= S_IROTH; + + if (attrs->perms & PVFS_G_EXECUTE) + perm_mode |= S_IXGRP; + if (attrs->perms & PVFS_G_WRITE) + perm_mode |= S_IWGRP; + if (attrs->perms & PVFS_G_READ) + perm_mode |= S_IRGRP; + + if (attrs->perms & PVFS_U_EXECUTE) + perm_mode |= S_IXUSR; + if (attrs->perms & PVFS_U_WRITE) + perm_mode |= S_IWUSR; + if (attrs->perms & PVFS_U_READ) + perm_mode |= S_IRUSR; + + if (attrs->perms & PVFS_G_SGID) + perm_mode |= S_ISGID; + if (attrs->perms & PVFS_U_SUID) + perm_mode |= S_ISUID; + + inode->i_mode = perm_mode; + + if (is_root_handle(inode)) { + /* special case: mark the root inode as sticky */ + inode->i_mode |= S_ISVTX; + gossip_debug(GOSSIP_UTILS_DEBUG, + "Marking inode %pU as sticky\n", + get_khandle_from_ino(inode)); + } + + switch (attrs->objtype) { + case PVFS_TYPE_METAFILE: + inode->i_mode |= S_IFREG; + ret = 0; + break; + case PVFS_TYPE_DIRECTORY: + inode->i_mode |= S_IFDIR; + /* NOTE: we have no good way to keep nlink consistent + * for directories across clients; keep constant at 1. + * Why 1? If we go with 2, then find(1) gets confused + * and won't work properly withouth the -noleaf option + */ + set_nlink(inode, 1); + ret = 0; + break; + case PVFS_TYPE_SYMLINK: + inode->i_mode |= S_IFLNK; + + /* copy link target to inode private data */ + if (pvfs2_inode && symname) { + strncpy(pvfs2_inode->link_target, + symname, + PVFS_NAME_MAX); + gossip_debug(GOSSIP_UTILS_DEBUG, + "Copied attr link target %s\n", + pvfs2_inode->link_target); + } + gossip_debug(GOSSIP_UTILS_DEBUG, + "symlink mode %o\n", + inode->i_mode); + ret = 0; + break; + default: + gossip_err("pvfs2: copy_attributes_to_inode: got invalid attribute type %x\n", + attrs->objtype); + } + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n", + inode->i_mode, + (unsigned long)i_size_read(inode)); + + return ret; +} + +/* + * NOTE: in kernel land, we never use the sys_attr->link_target for + * anything, so don't bother copying it into the sys_attr object here. + */ +static inline int copy_attributes_from_inode(struct inode *inode, + struct PVFS_sys_attr_s *attrs, + struct iattr *iattr) +{ + umode_t tmp_mode; + + if (!iattr || !inode || !attrs) { + gossip_err("NULL iattr (%p), inode (%p), attrs (%p) " + "in copy_attributes_from_inode!\n", + iattr, + inode, + attrs); + return -EINVAL; + } + /* + * We need to be careful to only copy the attributes out of the + * iattr object that we know are valid. + */ + attrs->mask = 0; + if (iattr->ia_valid & ATTR_UID) { + attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid); + attrs->mask |= PVFS_ATTR_SYS_UID; + gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner); + } + if (iattr->ia_valid & ATTR_GID) { + attrs->group = from_kgid(current_user_ns(), iattr->ia_gid); + attrs->mask |= PVFS_ATTR_SYS_GID; + gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group); + } + + if (iattr->ia_valid & ATTR_ATIME) { + attrs->mask |= PVFS_ATTR_SYS_ATIME; + if (iattr->ia_valid & ATTR_ATIME_SET) { + attrs->atime = + pvfs2_convert_time_field((void *)&iattr->ia_atime); + attrs->mask |= PVFS_ATTR_SYS_ATIME_SET; + } + } + if (iattr->ia_valid & ATTR_MTIME) { + attrs->mask |= PVFS_ATTR_SYS_MTIME; + if (iattr->ia_valid & ATTR_MTIME_SET) { + attrs->mtime = + pvfs2_convert_time_field((void *)&iattr->ia_mtime); + attrs->mask |= PVFS_ATTR_SYS_MTIME_SET; + } + } + if (iattr->ia_valid & ATTR_CTIME) + attrs->mask |= PVFS_ATTR_SYS_CTIME; + + /* + * PVFS2 cannot set size with a setattr operation. Probably not likely + * to be requested through the VFS, but just in case, don't worry about + * ATTR_SIZE + */ + + if (iattr->ia_valid & ATTR_MODE) { + tmp_mode = iattr->ia_mode; + if (tmp_mode & (S_ISVTX)) { + if (is_root_handle(inode)) { + /* + * allow sticky bit to be set on root (since + * it shows up that way by default anyhow), + * but don't show it to the server + */ + tmp_mode -= S_ISVTX; + } else { + gossip_debug(GOSSIP_UTILS_DEBUG, + "User attempted to set sticky bit on non-root directory; returning EINVAL.\n"); + return -EINVAL; + } + } + + if (tmp_mode & (S_ISUID)) { + gossip_debug(GOSSIP_UTILS_DEBUG, + "Attempting to set setuid bit (not supported); returning EINVAL.\n"); + return -EINVAL; + } + + attrs->perms = PVFS_util_translate_mode(tmp_mode); + attrs->mask |= PVFS_ATTR_SYS_PERM; + } + + return 0; +} + +/* + * issues a pvfs2 getattr request and fills in the appropriate inode + * attributes if successful. returns 0 on success; -errno otherwise + */ +int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op; + int ret = -EINVAL; + + gossip_debug(GOSSIP_UTILS_DEBUG, + "%s: called on inode %pU\n", + __func__, + get_khandle_from_ino(inode)); + + new_op = op_alloc(PVFS2_VFS_OP_GETATTR); + if (!new_op) + return -ENOMEM; + new_op->upcall.req.getattr.refn = pvfs2_inode->refn; + new_op->upcall.req.getattr.mask = getattr_mask; + + ret = service_operation(new_op, __func__, + get_interruptible_flag(inode)); + if (ret != 0) + goto out; + + if (copy_attributes_to_inode(inode, + &new_op->downcall.resp.getattr.attributes, + new_op->downcall.resp.getattr.link_target)) { + gossip_err("%s: failed to copy attributes\n", __func__); + ret = -ENOENT; + goto out; + } + + /* + * Store blksize in pvfs2 specific part of inode structure; we are + * only going to use this to report to stat to make sure it doesn't + * perturb any inode related code paths. + */ + if (new_op->downcall.resp.getattr.attributes.objtype == + PVFS_TYPE_METAFILE) { + pvfs2_inode->blksize = + new_op->downcall.resp.getattr.attributes.blksize; + } else { + /* mimic behavior of generic_fillattr() for other types. */ + pvfs2_inode->blksize = (1 << inode->i_blkbits); + + } + +out: + gossip_debug(GOSSIP_UTILS_DEBUG, + "Getattr on handle %pU, " + "fsid %d\n (inode ct = %d) returned %d\n", + &pvfs2_inode->refn.khandle, + pvfs2_inode->refn.fs_id, + (int)atomic_read(&inode->i_count), + ret); + + op_release(new_op); + return ret; +} + +/* + * issues a pvfs2 setattr request to make sure the new attribute values + * take effect if successful. returns 0 on success; -errno otherwise + */ +int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op; + int ret; + + new_op = op_alloc(PVFS2_VFS_OP_SETATTR); + if (!new_op) + return -ENOMEM; + + new_op->upcall.req.setattr.refn = pvfs2_inode->refn; + ret = copy_attributes_from_inode(inode, + &new_op->upcall.req.setattr.attributes, + iattr); + if (ret < 0) { + op_release(new_op); + return ret; + } + + ret = service_operation(new_op, __func__, + get_interruptible_flag(inode)); + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_inode_setattr: returning %d\n", + ret); + + /* when request is serviced properly, free req op struct */ + op_release(new_op); + + /* + * successful setattr should clear the atime, mtime and + * ctime flags. + */ + if (ret == 0) { + ClearAtimeFlag(pvfs2_inode); + ClearMtimeFlag(pvfs2_inode); + ClearCtimeFlag(pvfs2_inode); + ClearModeFlag(pvfs2_inode); + } + + return ret; +} + +int pvfs2_flush_inode(struct inode *inode) +{ + /* + * If it is a dirty inode, this function gets called. + * Gather all the information that needs to be setattr'ed + * Right now, this will only be used for mode, atime, mtime + * and/or ctime. + */ + struct iattr wbattr; + int ret; + int mtime_flag; + int ctime_flag; + int atime_flag; + int mode_flag; + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + + memset(&wbattr, 0, sizeof(wbattr)); + + /* + * check inode flags up front, and clear them if they are set. This + * will prevent multiple processes from all trying to flush the same + * inode if they call close() simultaneously + */ + mtime_flag = MtimeFlag(pvfs2_inode); + ClearMtimeFlag(pvfs2_inode); + ctime_flag = CtimeFlag(pvfs2_inode); + ClearCtimeFlag(pvfs2_inode); + atime_flag = AtimeFlag(pvfs2_inode); + ClearAtimeFlag(pvfs2_inode); + mode_flag = ModeFlag(pvfs2_inode); + ClearModeFlag(pvfs2_inode); + + /* -- Lazy atime,mtime and ctime update -- + * Note: all times are dictated by server in the new scheme + * and not by the clients + * + * Also mode updates are being handled now.. + */ + + if (mtime_flag) + wbattr.ia_valid |= ATTR_MTIME; + if (ctime_flag) + wbattr.ia_valid |= ATTR_CTIME; + if (atime_flag) + wbattr.ia_valid |= ATTR_ATIME; + + if (mode_flag) { + wbattr.ia_mode = inode->i_mode; + wbattr.ia_valid |= ATTR_MODE; + } + + gossip_debug(GOSSIP_UTILS_DEBUG, + "*********** pvfs2_flush_inode: %pU " + "(ia_valid %d)\n", + get_khandle_from_ino(inode), + wbattr.ia_valid); + if (wbattr.ia_valid == 0) { + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_flush_inode skipping setattr()\n"); + return 0; + } + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_flush_inode (%pU) writing mode %o\n", + get_khandle_from_ino(inode), + inode->i_mode); + + ret = pvfs2_inode_setattr(inode, &wbattr); + + return ret; +} + +int pvfs2_unmount_sb(struct super_block *sb) +{ + int ret = -EINVAL; + struct pvfs2_kernel_op_s *new_op = NULL; + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_unmount_sb called on sb %p\n", + sb); + + new_op = op_alloc(PVFS2_VFS_OP_FS_UMOUNT); + if (!new_op) + return -ENOMEM; + new_op->upcall.req.fs_umount.id = PVFS2_SB(sb)->id; + new_op->upcall.req.fs_umount.fs_id = PVFS2_SB(sb)->fs_id; + strncpy(new_op->upcall.req.fs_umount.pvfs2_config_server, + PVFS2_SB(sb)->devname, + PVFS_MAX_SERVER_ADDR_LEN); + + gossip_debug(GOSSIP_UTILS_DEBUG, + "Attempting PVFS2 Unmount via host %s\n", + new_op->upcall.req.fs_umount.pvfs2_config_server); + + ret = service_operation(new_op, "pvfs2_fs_umount", 0); + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_unmount: got return value of %d\n", ret); + if (ret) + sb = ERR_PTR(ret); + else + PVFS2_SB(sb)->mount_pending = 1; + + op_release(new_op); + return ret; +} + +/* + * NOTE: on successful cancellation, be sure to return -EINTR, as + * that's the return value the caller expects + */ +int pvfs2_cancel_op_in_progress(__u64 tag) +{ + int ret = -EINVAL; + struct pvfs2_kernel_op_s *new_op = NULL; + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_cancel_op_in_progress called on tag %llu\n", + llu(tag)); + + new_op = op_alloc(PVFS2_VFS_OP_CANCEL); + if (!new_op) + return -ENOMEM; + new_op->upcall.req.cancel.op_tag = tag; + + gossip_debug(GOSSIP_UTILS_DEBUG, + "Attempting PVFS2 operation cancellation of tag %llu\n", + llu(new_op->upcall.req.cancel.op_tag)); + + ret = service_operation(new_op, "pvfs2_cancel", PVFS2_OP_CANCELLATION); + + gossip_debug(GOSSIP_UTILS_DEBUG, + "pvfs2_cancel_op_in_progress: got return value of %d\n", + ret); + + op_release(new_op); + return ret; +} + +void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op) +{ + if (op) { + spin_lock(&op->lock); + op->io_completed = 0; + + op->upcall.type = PVFS2_VFS_OP_INVALID; + op->downcall.type = PVFS2_VFS_OP_INVALID; + op->downcall.status = -1; + + op->op_state = OP_VFS_STATE_UNKNOWN; + op->tag = 0; + spin_unlock(&op->lock); + } +} + +void pvfs2_make_bad_inode(struct inode *inode) +{ + if (is_root_handle(inode)) { + /* + * if this occurs, the pvfs2-client-core was killed but we + * can't afford to lose the inode operations and such + * associated with the root handle in any case. + */ + gossip_debug(GOSSIP_UTILS_DEBUG, + "*** NOT making bad root inode %pU\n", + get_khandle_from_ino(inode)); + } else { + gossip_debug(GOSSIP_UTILS_DEBUG, + "*** making bad inode %pU\n", + get_khandle_from_ino(inode)); + make_bad_inode(inode); + } +} + +/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigmask */ +void mask_blocked_signals(sigset_t *orig_sigset) +{ + unsigned long sigallow = sigmask(SIGKILL); + unsigned long irqflags = 0; + struct k_sigaction *action = pvfs2_current_sigaction; + + sigallow |= ((action[SIGINT - 1].sa.sa_handler == SIG_DFL) ? + sigmask(SIGINT) : + 0); + sigallow |= ((action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) ? + sigmask(SIGQUIT) : + 0); + + spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags); + *orig_sigset = current->blocked; + siginitsetinv(¤t->blocked, sigallow & ~orig_sigset->sig[0]); + recalc_sigpending(); + spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags); +} + +/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigunmask */ +void unmask_blocked_signals(sigset_t *orig_sigset) +{ + unsigned long irqflags = 0; + + spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags); + current->blocked = *orig_sigset; + recalc_sigpending(); + spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags); +} + +__u64 pvfs2_convert_time_field(void *time_ptr) +{ + __u64 pvfs2_time; + struct timespec *tspec = (struct timespec *)time_ptr; + + pvfs2_time = (__u64) ((time_t) tspec->tv_sec); + return pvfs2_time; +} + +/* macro defined in include/pvfs2-types.h */ +DECLARE_ERRNO_MAPPING_AND_FN(); + +int pvfs2_normalize_to_errno(__s32 error_code) +{ + if (error_code > 0) { + gossip_err("pvfs2: error status receieved.\n"); + gossip_err("pvfs2: assuming error code is inverted.\n"); + error_code = -error_code; + } + + /* convert any error codes that are in pvfs2 format */ + if (IS_PVFS_NON_ERRNO_ERROR(-error_code)) { + if (PVFS_NON_ERRNO_ERROR_CODE(-error_code) == PVFS_ECANCEL) { + /* + * cancellation error codes generally correspond to + * a timeout from the client's perspective + */ + error_code = -ETIMEDOUT; + } else { + /* assume a default error code */ + gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n", + error_code); + error_code = -EINVAL; + } + } else if (IS_PVFS_ERROR(-error_code)) { + error_code = -PVFS_ERROR_TO_ERRNO(-error_code); + } + return error_code; +} + +#define NUM_MODES 11 +__s32 PVFS_util_translate_mode(int mode) +{ + int ret = 0; + int i = 0; + static int modes[NUM_MODES] = { + S_IXOTH, S_IWOTH, S_IROTH, + S_IXGRP, S_IWGRP, S_IRGRP, + S_IXUSR, S_IWUSR, S_IRUSR, + S_ISGID, S_ISUID + }; + static int pvfs2_modes[NUM_MODES] = { + PVFS_O_EXECUTE, PVFS_O_WRITE, PVFS_O_READ, + PVFS_G_EXECUTE, PVFS_G_WRITE, PVFS_G_READ, + PVFS_U_EXECUTE, PVFS_U_WRITE, PVFS_U_READ, + PVFS_G_SGID, PVFS_U_SUID + }; + + for (i = 0; i < NUM_MODES; i++) + if (mode & modes[i]) + ret |= pvfs2_modes[i]; + + return ret; +} +#undef NUM_MODES + +/* + * After obtaining a string representation of the client's debug + * keywords and their associated masks, this function is called to build an + * array of these values. + */ +int orangefs_prepare_cdm_array(char *debug_array_string) +{ + int i; + int rc = -EINVAL; + char *cds_head = NULL; + char *cds_delimiter = NULL; + int keyword_len = 0; + + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); + + /* + * figure out how many elements the cdm_array needs. + */ + for (i = 0; i < strlen(debug_array_string); i++) + if (debug_array_string[i] == '\n') + cdm_element_count++; + + if (!cdm_element_count) { + pr_info("No elements in client debug array string!\n"); + goto out; + } + + cdm_array = + kzalloc(cdm_element_count * sizeof(struct client_debug_mask), + GFP_KERNEL); + if (!cdm_array) { + pr_info("malloc failed for cdm_array!\n"); + rc = -ENOMEM; + goto out; + } + + cds_head = debug_array_string; + + for (i = 0; i < cdm_element_count; i++) { + cds_delimiter = strchr(cds_head, '\n'); + *cds_delimiter = '\0'; + + keyword_len = strcspn(cds_head, " "); + + cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL); + if (!cdm_array[i].keyword) { + rc = -ENOMEM; + goto out; + } + + sscanf(cds_head, + "%s %llx %llx", + cdm_array[i].keyword, + (unsigned long long *)&(cdm_array[i].mask1), + (unsigned long long *)&(cdm_array[i].mask2)); + + if (!strcmp(cdm_array[i].keyword, PVFS2_VERBOSE)) + client_verbose_index = i; + + if (!strcmp(cdm_array[i].keyword, PVFS2_ALL)) + client_all_index = i; + + cds_head = cds_delimiter + 1; + } + + rc = cdm_element_count; + + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc); + +out: + + return rc; + +} + +/* + * /sys/kernel/debug/orangefs/debug-help can be catted to + * see all the available kernel and client debug keywords. + * + * When the kernel boots, we have no idea what keywords the + * client supports, nor their associated masks. + * + * We pass through this function once at boot and stamp a + * boilerplate "we don't know" message for the client in the + * debug-help file. We pass through here again when the client + * starts and then we can fill out the debug-help file fully. + * + * The client might be restarted any number of times between + * reboots, we only build the debug-help file the first time. + */ +int orangefs_prepare_debugfs_help_string(int at_boot) +{ + int rc = -EINVAL; + int i; + int byte_count = 0; + char *client_title = "Client Debug Keywords:\n"; + char *kernel_title = "Kernel Debug Keywords:\n"; + + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); + + if (at_boot) { + byte_count += strlen(HELP_STRING_UNINITIALIZED); + client_title = HELP_STRING_UNINITIALIZED; + } else { + /* + * fill the client keyword/mask array and remember + * how many elements there were. + */ + cdm_element_count = + orangefs_prepare_cdm_array(client_debug_array_string); + if (cdm_element_count <= 0) + goto out; + + /* Count the bytes destined for debug_help_string. */ + byte_count += strlen(client_title); + + for (i = 0; i < cdm_element_count; i++) { + byte_count += strlen(cdm_array[i].keyword + 2); + if (byte_count >= DEBUG_HELP_STRING_SIZE) { + pr_info("%s: overflow 1!\n", __func__); + goto out; + } + } + + gossip_debug(GOSSIP_UTILS_DEBUG, + "%s: cdm_element_count:%d:\n", + __func__, + cdm_element_count); + } + + byte_count += strlen(kernel_title); + for (i = 0; i < num_kmod_keyword_mask_map; i++) { + byte_count += + strlen(s_kmod_keyword_mask_map[i].keyword + 2); + if (byte_count >= DEBUG_HELP_STRING_SIZE) { + pr_info("%s: overflow 2!\n", __func__); + goto out; + } + } + + /* build debug_help_string. */ + debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL); + if (!debug_help_string) { + rc = -ENOMEM; + goto out; + } + + strcat(debug_help_string, client_title); + + if (!at_boot) { + for (i = 0; i < cdm_element_count; i++) { + strcat(debug_help_string, "\t"); + strcat(debug_help_string, cdm_array[i].keyword); + strcat(debug_help_string, "\n"); + } + } + + strcat(debug_help_string, "\n"); + strcat(debug_help_string, kernel_title); + + for (i = 0; i < num_kmod_keyword_mask_map; i++) { + strcat(debug_help_string, "\t"); + strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword); + strcat(debug_help_string, "\n"); + } + + rc = 0; + +out: + + return rc; + +} + +/* + * kernel = type 0 + * client = type 1 + */ +void debug_mask_to_string(void *mask, int type) +{ + int i; + int len = 0; + char *debug_string; + int element_count = 0; + + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); + + if (type) { + debug_string = client_debug_string; + element_count = cdm_element_count; + } else { + debug_string = kernel_debug_string; + element_count = num_kmod_keyword_mask_map; + } + + memset(debug_string, 0, PVFS2_MAX_DEBUG_STRING_LEN); + + /* + * Some keywords, like "all" or "verbose", are amalgams of + * numerous other keywords. Make a special check for those + * before grinding through the whole mask only to find out + * later... + */ + if (check_amalgam_keyword(mask, type)) + goto out; + + /* Build the debug string. */ + for (i = 0; i < element_count; i++) + if (type) + do_c_string(mask, i); + else + do_k_string(mask, i); + + len = strlen(debug_string); + + if ((len) && (type)) + client_debug_string[len - 1] = '\0'; + else if (len) + kernel_debug_string[len - 1] = '\0'; + else if (type) + strcpy(client_debug_string, "none"); + else + strcpy(kernel_debug_string, "none"); + +out: +gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string); + + return; + +} + +void do_k_string(void *k_mask, int index) +{ + __u64 *mask = (__u64 *) k_mask; + + if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword)) + goto out; + + if (*mask & s_kmod_keyword_mask_map[index].mask_val) { + if ((strlen(kernel_debug_string) + + strlen(s_kmod_keyword_mask_map[index].keyword)) + < PVFS2_MAX_DEBUG_STRING_LEN - 1) { + strcat(kernel_debug_string, + s_kmod_keyword_mask_map[index].keyword); + strcat(kernel_debug_string, ","); + } else { + gossip_err("%s: overflow!\n", __func__); + strcpy(kernel_debug_string, PVFS2_ALL); + goto out; + } + } + +out: + + return; +} + +void do_c_string(void *c_mask, int index) +{ + struct client_debug_mask *mask = (struct client_debug_mask *) c_mask; + + if (keyword_is_amalgam(cdm_array[index].keyword)) + goto out; + + if ((mask->mask1 & cdm_array[index].mask1) || + (mask->mask2 & cdm_array[index].mask2)) { + if ((strlen(client_debug_string) + + strlen(cdm_array[index].keyword) + 1) + < PVFS2_MAX_DEBUG_STRING_LEN - 2) { + strcat(client_debug_string, + cdm_array[index].keyword); + strcat(client_debug_string, ","); + } else { + gossip_err("%s: overflow!\n", __func__); + strcpy(client_debug_string, PVFS2_ALL); + goto out; + } + } +out: + return; +} + +int keyword_is_amalgam(char *keyword) +{ + int rc = 0; + + if ((!strcmp(keyword, PVFS2_ALL)) || (!strcmp(keyword, PVFS2_VERBOSE))) + rc = 1; + + return rc; +} + +/* + * kernel = type 0 + * client = type 1 + * + * return 1 if we found an amalgam. + */ +int check_amalgam_keyword(void *mask, int type) +{ + __u64 *k_mask; + struct client_debug_mask *c_mask; + int k_all_index = num_kmod_keyword_mask_map - 1; + int rc = 0; + + if (type) { + c_mask = (struct client_debug_mask *) mask; + + if ((c_mask->mask1 == cdm_array[client_all_index].mask1) && + (c_mask->mask2 == cdm_array[client_all_index].mask2)) { + strcpy(client_debug_string, PVFS2_ALL); + rc = 1; + goto out; + } + + if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) && + (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) { + strcpy(client_debug_string, PVFS2_VERBOSE); + rc = 1; + goto out; + } + + } else { + k_mask = (__u64 *) mask; + + if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) { + strcpy(kernel_debug_string, PVFS2_ALL); + rc = 1; + goto out; + } + } + +out: + + return rc; +} + +/* + * kernel = type 0 + * client = type 1 + */ +void debug_string_to_mask(char *debug_string, void *mask, int type) +{ + char *unchecked_keyword; + int i; + char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL); + int element_count = 0; + struct client_debug_mask *c_mask; + __u64 *k_mask; + + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); + + if (type) { + c_mask = (struct client_debug_mask *)mask; + element_count = cdm_element_count; + } else { + k_mask = (__u64 *)mask; + *k_mask = 0; + element_count = num_kmod_keyword_mask_map; + } + + while ((unchecked_keyword = strsep(&strsep_fodder, ","))) + if (strlen(unchecked_keyword)) { + for (i = 0; i < element_count; i++) + if (type) + do_c_mask(i, + unchecked_keyword, + &c_mask); + else + do_k_mask(i, + unchecked_keyword, + &k_mask); + } + + kfree(strsep_fodder); +} + +void do_c_mask(int i, + char *unchecked_keyword, + struct client_debug_mask **sane_mask) +{ + + if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) { + (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1; + (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2; + } +} + +void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask) +{ + + if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword)) + **sane_mask = (**sane_mask) | + s_kmod_keyword_mask_map[i].mask_val; +} -- GitLab From 1182fca3bc00441d5b2dee2f0548a3b7f978f9e7 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:15 -0400 Subject: [PATCH 0005/5324] Orangefs: kernel client part 5 Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 558 ++++++++++++++++++++++++++++++++++++++++ fs/orangefs/symlink.c | 31 +++ fs/orangefs/waitqueue.c | 522 +++++++++++++++++++++++++++++++++++++ fs/orangefs/xattr.c | 532 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 1643 insertions(+) create mode 100644 fs/orangefs/super.c create mode 100644 fs/orangefs/symlink.c create mode 100644 fs/orangefs/waitqueue.c create mode 100644 fs/orangefs/xattr.c diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c new file mode 100644 index 000000000000..a854390fc0ea --- /dev/null +++ b/fs/orangefs/super.c @@ -0,0 +1,558 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +#include + +/* a cache for pvfs2-inode objects (i.e. pvfs2 inode private data) */ +static struct kmem_cache *pvfs2_inode_cache; + +/* list for storing pvfs2 specific superblocks in use */ +LIST_HEAD(pvfs2_superblocks); + +DEFINE_SPINLOCK(pvfs2_superblocks_lock); + +enum { + Opt_intr, + Opt_acl, + Opt_local_lock, + + Opt_err +}; + +static const match_table_t tokens = { + { Opt_acl, "acl" }, + { Opt_intr, "intr" }, + { Opt_local_lock, "local_lock" }, + { Opt_err, NULL } +}; + + +static int parse_mount_options(struct super_block *sb, char *options, + int silent) +{ + struct pvfs2_sb_info_s *pvfs2_sb = PVFS2_SB(sb); + substring_t args[MAX_OPT_ARGS]; + char *p; + + /* + * Force any potential flags that might be set from the mount + * to zero, ie, initialize to unset. + */ + sb->s_flags &= ~MS_POSIXACL; + pvfs2_sb->flags &= ~PVFS2_OPT_INTR; + pvfs2_sb->flags &= ~PVFS2_OPT_LOCAL_LOCK; + + while ((p = strsep(&options, ",")) != NULL) { + int token; + + if (!*p) + continue; + + token = match_token(p, tokens, args); + switch (token) { + case Opt_acl: + sb->s_flags |= MS_POSIXACL; + break; + case Opt_intr: + pvfs2_sb->flags |= PVFS2_OPT_INTR; + break; + case Opt_local_lock: + pvfs2_sb->flags |= PVFS2_OPT_LOCAL_LOCK; + break; + default: + goto fail; + } + } + + return 0; +fail: + if (!silent) + gossip_err("Error: mount option [%s] is not supported.\n", p); + return -EINVAL; +} + +static void pvfs2_inode_cache_ctor(void *req) +{ + struct pvfs2_inode_s *pvfs2_inode = req; + + inode_init_once(&pvfs2_inode->vfs_inode); + init_rwsem(&pvfs2_inode->xattr_sem); + + pvfs2_inode->vfs_inode.i_version = 1; +} + +static struct inode *pvfs2_alloc_inode(struct super_block *sb) +{ + struct pvfs2_inode_s *pvfs2_inode; + + pvfs2_inode = kmem_cache_alloc(pvfs2_inode_cache, + PVFS2_CACHE_ALLOC_FLAGS); + if (pvfs2_inode == NULL) { + gossip_err("Failed to allocate pvfs2_inode\n"); + return NULL; + } + + /* + * We want to clear everything except for rw_semaphore and the + * vfs_inode. + */ + memset(&pvfs2_inode->refn.khandle, 0, 16); + pvfs2_inode->refn.fs_id = PVFS_FS_ID_NULL; + pvfs2_inode->last_failed_block_index_read = 0; + memset(pvfs2_inode->link_target, 0, sizeof(pvfs2_inode->link_target)); + pvfs2_inode->pinode_flags = 0; + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_alloc_inode: allocated %p\n", + &pvfs2_inode->vfs_inode); + return &pvfs2_inode->vfs_inode; +} + +static void pvfs2_destroy_inode(struct inode *inode) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "%s: deallocated %p destroying inode %pU\n", + __func__, pvfs2_inode, get_khandle_from_ino(inode)); + + kmem_cache_free(pvfs2_inode_cache, pvfs2_inode); +} + +/* + * NOTE: information filled in here is typically reflected in the + * output of the system command 'df' +*/ +static int pvfs2_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + int ret = -ENOMEM; + struct pvfs2_kernel_op_s *new_op = NULL; + int flags = 0; + struct super_block *sb = NULL; + + sb = dentry->d_sb; + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_statfs: called on sb %p (fs_id is %d)\n", + sb, + (int)(PVFS2_SB(sb)->fs_id)); + + new_op = op_alloc(PVFS2_VFS_OP_STATFS); + if (!new_op) + return ret; + new_op->upcall.req.statfs.fs_id = PVFS2_SB(sb)->fs_id; + + if (PVFS2_SB(sb)->flags & PVFS2_OPT_INTR) + flags = PVFS2_OP_INTERRUPTIBLE; + + ret = service_operation(new_op, "pvfs2_statfs", flags); + + if (new_op->downcall.status < 0) + goto out_op_release; + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_statfs: got %ld blocks available | " + "%ld blocks total | %ld block size\n", + (long)new_op->downcall.resp.statfs.blocks_avail, + (long)new_op->downcall.resp.statfs.blocks_total, + (long)new_op->downcall.resp.statfs.block_size); + + buf->f_type = sb->s_magic; + memcpy(&buf->f_fsid, &PVFS2_SB(sb)->fs_id, sizeof(buf->f_fsid)); + buf->f_bsize = new_op->downcall.resp.statfs.block_size; + buf->f_namelen = PVFS2_NAME_LEN; + + buf->f_blocks = (sector_t) new_op->downcall.resp.statfs.blocks_total; + buf->f_bfree = (sector_t) new_op->downcall.resp.statfs.blocks_avail; + buf->f_bavail = (sector_t) new_op->downcall.resp.statfs.blocks_avail; + buf->f_files = (sector_t) new_op->downcall.resp.statfs.files_total; + buf->f_ffree = (sector_t) new_op->downcall.resp.statfs.files_avail; + buf->f_frsize = sb->s_blocksize; + +out_op_release: + op_release(new_op); + gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_statfs: returning %d\n", ret); + return ret; +} + +/* + * Remount as initiated by VFS layer. We just need to reparse the mount + * options, no need to signal pvfs2-client-core about it. + */ +static int pvfs2_remount_fs(struct super_block *sb, int *flags, char *data) +{ + gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount_fs: called\n"); + return parse_mount_options(sb, data, 1); +} + +/* + * Remount as initiated by pvfs2-client-core on restart. This is used to + * repopulate mount information left from previous pvfs2-client-core. + * + * the idea here is that given a valid superblock, we're + * re-initializing the user space client with the initial mount + * information specified when the super block was first initialized. + * this is very different than the first initialization/creation of a + * superblock. we use the special service_priority_operation to make + * sure that the mount gets ahead of any other pending operation that + * is waiting for servicing. this means that the pvfs2-client won't + * fail to start several times for all other pending operations before + * the client regains all of the mount information from us. + * NOTE: this function assumes that the request_mutex is already acquired! + */ +int pvfs2_remount(struct super_block *sb) +{ + struct pvfs2_kernel_op_s *new_op; + int ret = -EINVAL; + + gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount: called\n"); + + new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT); + if (!new_op) + return -ENOMEM; + strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server, + PVFS2_SB(sb)->devname, + PVFS_MAX_SERVER_ADDR_LEN); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "Attempting PVFS2 Remount via host %s\n", + new_op->upcall.req.fs_mount.pvfs2_config_server); + + /* + * we assume that the calling function has already acquire the + * request_mutex to prevent other operations from bypassing + * this one + */ + ret = service_operation(new_op, "pvfs2_remount", + PVFS2_OP_PRIORITY | PVFS2_OP_NO_SEMAPHORE); + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_remount: mount got return value of %d\n", + ret); + if (ret == 0) { + /* + * store the id assigned to this sb -- it's just a + * short-lived mapping that the system interface uses + * to map this superblock to a particular mount entry + */ + PVFS2_SB(sb)->id = new_op->downcall.resp.fs_mount.id; + PVFS2_SB(sb)->mount_pending = 0; + } + + op_release(new_op); + return ret; +} + +int fsid_key_table_initialize(void) +{ + return 0; +} + +void fsid_key_table_finalize(void) +{ +} + +/* Called whenever the VFS dirties the inode in response to atime updates */ +static void pvfs2_dirty_inode(struct inode *inode, int flags) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_dirty_inode: %pU\n", + get_khandle_from_ino(inode)); + SetAtimeFlag(pvfs2_inode); +} + +struct super_operations pvfs2_s_ops = { + .alloc_inode = pvfs2_alloc_inode, + .destroy_inode = pvfs2_destroy_inode, + .dirty_inode = pvfs2_dirty_inode, + .drop_inode = generic_delete_inode, + .statfs = pvfs2_statfs, + .remount_fs = pvfs2_remount_fs, + .show_options = generic_show_options, +}; + +struct dentry *pvfs2_fh_to_dentry(struct super_block *sb, + struct fid *fid, + int fh_len, + int fh_type) +{ + struct pvfs2_object_kref refn; + + if (fh_len < 5 || fh_type > 2) + return NULL; + + PVFS_khandle_from(&(refn.khandle), fid->raw, 16); + refn.fs_id = (u32) fid->raw[4]; + gossip_debug(GOSSIP_SUPER_DEBUG, + "fh_to_dentry: handle %pU, fs_id %d\n", + &refn.khandle, + refn.fs_id); + + return d_obtain_alias(pvfs2_iget(sb, &refn)); +} + +int pvfs2_encode_fh(struct inode *inode, + __u32 *fh, + int *max_len, + struct inode *parent) +{ + int len = parent ? 10 : 5; + int type = 1; + struct pvfs2_object_kref refn; + + if (*max_len < len) { + gossip_lerr("fh buffer is too small for encoding\n"); + *max_len = len; + type = 255; + goto out; + } + + refn = PVFS2_I(inode)->refn; + PVFS_khandle_to(&refn.khandle, fh, 16); + fh[4] = refn.fs_id; + + gossip_debug(GOSSIP_SUPER_DEBUG, + "Encoding fh: handle %pU, fsid %u\n", + &refn.khandle, + refn.fs_id); + + + if (parent) { + refn = PVFS2_I(parent)->refn; + PVFS_khandle_to(&refn.khandle, (char *) fh + 20, 16); + fh[9] = refn.fs_id; + + type = 2; + gossip_debug(GOSSIP_SUPER_DEBUG, + "Encoding parent: handle %pU, fsid %u\n", + &refn.khandle, + refn.fs_id); + } + *max_len = len; + +out: + return type; +} + +static struct export_operations pvfs2_export_ops = { + .encode_fh = pvfs2_encode_fh, + .fh_to_dentry = pvfs2_fh_to_dentry, +}; + +int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) +{ + int ret = -EINVAL; + struct inode *root = NULL; + struct dentry *root_dentry = NULL; + struct pvfs2_mount_sb_info_s *mount_sb_info = + (struct pvfs2_mount_sb_info_s *) data; + struct pvfs2_object_kref root_object; + + /* alloc and init our private pvfs2 sb info */ + sb->s_fs_info = + kmalloc(sizeof(struct pvfs2_sb_info_s), PVFS2_GFP_FLAGS); + if (!PVFS2_SB(sb)) + return -ENOMEM; + memset(sb->s_fs_info, 0, sizeof(struct pvfs2_sb_info_s)); + PVFS2_SB(sb)->sb = sb; + + PVFS2_SB(sb)->root_khandle = mount_sb_info->root_khandle; + PVFS2_SB(sb)->fs_id = mount_sb_info->fs_id; + PVFS2_SB(sb)->id = mount_sb_info->id; + + if (mount_sb_info->data) { + ret = parse_mount_options(sb, mount_sb_info->data, + silent); + if (ret) + return ret; + } + + /* Hang the xattr handlers off the superblock */ + sb->s_xattr = pvfs2_xattr_handlers; + sb->s_magic = PVFS2_SUPER_MAGIC; + sb->s_op = &pvfs2_s_ops; + sb->s_d_op = &pvfs2_dentry_operations; + + sb->s_blocksize = pvfs_bufmap_size_query(); + sb->s_blocksize_bits = pvfs_bufmap_shift_query(); + sb->s_maxbytes = MAX_LFS_FILESIZE; + + root_object.khandle = PVFS2_SB(sb)->root_khandle; + root_object.fs_id = PVFS2_SB(sb)->fs_id; + gossip_debug(GOSSIP_SUPER_DEBUG, + "get inode %pU, fsid %d\n", + &root_object.khandle, + root_object.fs_id); + + root = pvfs2_iget(sb, &root_object); + if (IS_ERR(root)) + return PTR_ERR(root); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "Allocated root inode [%p] with mode %x\n", + root, + root->i_mode); + + /* allocates and places root dentry in dcache */ + root_dentry = d_make_root(root); + if (!root_dentry) { + iput(root); + return -ENOMEM; + } + + sb->s_export_op = &pvfs2_export_ops; + sb->s_root = root_dentry; + return 0; +} + +struct dentry *pvfs2_mount(struct file_system_type *fst, + int flags, + const char *devname, + void *data) +{ + int ret = -EINVAL; + struct super_block *sb = ERR_PTR(-EINVAL); + struct pvfs2_kernel_op_s *new_op; + struct pvfs2_mount_sb_info_s mount_sb_info; + struct dentry *mnt_sb_d = ERR_PTR(-EINVAL); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_mount: called with devname %s\n", + devname); + + if (!devname) { + gossip_err("ERROR: device name not specified.\n"); + return ERR_PTR(-EINVAL); + } + + new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT); + if (!new_op) + return ERR_PTR(-ENOMEM); + + strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server, + devname, + PVFS_MAX_SERVER_ADDR_LEN); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "Attempting PVFS2 Mount via host %s\n", + new_op->upcall.req.fs_mount.pvfs2_config_server); + + ret = service_operation(new_op, "pvfs2_mount", 0); + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_mount: mount got return value of %d\n", ret); + if (ret) + goto free_op; + + if (new_op->downcall.resp.fs_mount.fs_id == PVFS_FS_ID_NULL) { + gossip_err("ERROR: Retrieved null fs_id\n"); + ret = -EINVAL; + goto free_op; + } + + /* fill in temporary structure passed to fill_sb method */ + mount_sb_info.data = data; + mount_sb_info.root_khandle = + new_op->downcall.resp.fs_mount.root_khandle; + mount_sb_info.fs_id = new_op->downcall.resp.fs_mount.fs_id; + mount_sb_info.id = new_op->downcall.resp.fs_mount.id; + + /* + * the mount_sb_info structure looks odd, but it's used because + * the private sb info isn't allocated until we call + * pvfs2_fill_sb, yet we have the info we need to fill it with + * here. so we store it temporarily and pass all of the info + * to fill_sb where it's properly copied out + */ + mnt_sb_d = mount_nodev(fst, + flags, + (void *)&mount_sb_info, + pvfs2_fill_sb); + if (IS_ERR(mnt_sb_d)) { + sb = ERR_CAST(mnt_sb_d); + goto free_op; + } + + sb = mnt_sb_d->d_sb; + + /* + * on successful mount, store the devname and data + * used + */ + strncpy(PVFS2_SB(sb)->devname, + devname, + PVFS_MAX_SERVER_ADDR_LEN); + + /* mount_pending must be cleared */ + PVFS2_SB(sb)->mount_pending = 0; + + /* + * finally, add this sb to our list of known pvfs2 + * sb's + */ + add_pvfs2_sb(sb); + op_release(new_op); + return mnt_sb_d; + +free_op: + gossip_err("pvfs2_mount: mount request failed with %d\n", ret); + if (ret == -EINVAL) { + gossip_err("Ensure that all pvfs2-servers have the same FS configuration files\n"); + gossip_err("Look at pvfs2-client-core log file (typically /tmp/pvfs2-client.log) for more details\n"); + } + + op_release(new_op); + + gossip_debug(GOSSIP_SUPER_DEBUG, + "pvfs2_mount: returning dentry %p\n", + mnt_sb_d); + return mnt_sb_d; +} + +void pvfs2_kill_sb(struct super_block *sb) +{ + gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_kill_sb: called\n"); + + /* + * issue the unmount to userspace to tell it to remove the + * dynamic mount info it has for this superblock + */ + pvfs2_unmount_sb(sb); + + /* remove the sb from our list of pvfs2 specific sb's */ + remove_pvfs2_sb(sb); + + /* provided sb cleanup */ + kill_anon_super(sb); + + /* free the pvfs2 superblock private data */ + kfree(PVFS2_SB(sb)); +} + +int pvfs2_inode_cache_initialize(void) +{ + pvfs2_inode_cache = kmem_cache_create("pvfs2_inode_cache", + sizeof(struct pvfs2_inode_s), + 0, + PVFS2_CACHE_CREATE_FLAGS, + pvfs2_inode_cache_ctor); + + if (!pvfs2_inode_cache) { + gossip_err("Cannot create pvfs2_inode_cache\n"); + return -ENOMEM; + } + return 0; +} + +int pvfs2_inode_cache_finalize(void) +{ + kmem_cache_destroy(pvfs2_inode_cache); + return 0; +} diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c new file mode 100644 index 000000000000..2adfceff7730 --- /dev/null +++ b/fs/orangefs/symlink.c @@ -0,0 +1,31 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +static const char *pvfs2_follow_link(struct dentry *dentry, void **cookie) +{ + char *target = PVFS2_I(dentry->d_inode)->link_target; + + gossip_debug(GOSSIP_INODE_DEBUG, + "%s: called on %s (target is %p)\n", + __func__, (char *)dentry->d_name.name, target); + + *cookie = target; + + return target; +} + +struct inode_operations pvfs2_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = pvfs2_follow_link, + .setattr = pvfs2_setattr, + .getattr = pvfs2_getattr, + .listxattr = pvfs2_listxattr, + .setxattr = generic_setxattr, +}; diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c new file mode 100644 index 000000000000..9b32286a7dc4 --- /dev/null +++ b/fs/orangefs/waitqueue.c @@ -0,0 +1,522 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * (C) 2011 Omnibond Systems + * + * Changes by Acxiom Corporation to implement generic service_operation() + * function, Copyright Acxiom Corporation, 2005. + * + * See COPYING in top-level directory. + */ + +/* + * In-kernel waitqueue operations. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" + +/* + * What we do in this function is to walk the list of operations that are + * present in the request queue and mark them as purged. + * NOTE: This is called from the device close after client-core has + * guaranteed that no new operations could appear on the list since the + * client-core is anyway going to exit. + */ +void purge_waiting_ops(void) +{ + struct pvfs2_kernel_op_s *op; + + spin_lock(&pvfs2_request_list_lock); + list_for_each_entry(op, &pvfs2_request_list, list) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2-client-core: purging op tag %llu %s\n", + llu(op->tag), + get_opname_string(op)); + spin_lock(&op->lock); + set_op_state_purged(op); + spin_unlock(&op->lock); + wake_up_interruptible(&op->waitq); + } + spin_unlock(&pvfs2_request_list_lock); +} + +/* + * submits a PVFS2 operation and waits for it to complete + * + * Note op->downcall.status will contain the status of the operation (in + * errno format), whether provided by pvfs2-client or a result of failure to + * service the operation. If the caller wishes to distinguish, then + * op->state can be checked to see if it was serviced or not. + * + * Returns contents of op->downcall.status for convenience + */ +int service_operation(struct pvfs2_kernel_op_s *op, + const char *op_name, + int flags) +{ + /* flags to modify behavior */ + sigset_t orig_sigset; + int ret = 0; + + /* irqflags and wait_entry are only used IF the client-core aborts */ + unsigned long irqflags; + + DECLARE_WAITQUEUE(wait_entry, current); + + op->upcall.tgid = current->tgid; + op->upcall.pid = current->pid; + +retry_servicing: + op->downcall.status = 0; + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2: service_operation: %s %p\n", + op_name, + op); + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2: operation posted by process: %s, pid: %i\n", + current->comm, + current->pid); + + /* mask out signals if this operation is not to be interrupted */ + if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + mask_blocked_signals(&orig_sigset); + + if (!(flags & PVFS2_OP_NO_SEMAPHORE)) { + ret = mutex_lock_interruptible(&request_mutex); + /* + * check to see if we were interrupted while waiting for + * semaphore + */ + if (ret < 0) { + if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + unmask_blocked_signals(&orig_sigset); + op->downcall.status = ret; + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2: service_operation interrupted.\n"); + return ret; + } + } + + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:About to call is_daemon_in_service().\n", + __func__); + + if (is_daemon_in_service() < 0) { + /* + * By incrementing the per-operation attempt counter, we + * directly go into the timeout logic while waiting for + * the matching downcall to be read + */ + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:client core is NOT in service(%d).\n", + __func__, + is_daemon_in_service()); + op->attempts++; + } + + /* queue up the operation */ + if (flags & PVFS2_OP_PRIORITY) { + add_priority_op_to_request_list(op); + } else { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:About to call add_op_to_request_list().\n", + __func__); + add_op_to_request_list(op); + } + + if (!(flags & PVFS2_OP_NO_SEMAPHORE)) + mutex_unlock(&request_mutex); + + /* + * If we are asked to service an asynchronous operation from + * VFS perspective, we are done. + */ + if (flags & PVFS2_OP_ASYNC) + return 0; + + if (flags & PVFS2_OP_CANCELLATION) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:" + "About to call wait_for_cancellation_downcall.\n", + __func__); + ret = wait_for_cancellation_downcall(op); + } else { + ret = wait_for_matching_downcall(op); + } + + if (ret < 0) { + /* failed to get matching downcall */ + if (ret == -ETIMEDOUT) { + gossip_err("pvfs2: %s -- wait timed out; aborting attempt.\n", + op_name); + } + op->downcall.status = ret; + } else { + /* got matching downcall; make sure status is in errno format */ + op->downcall.status = + pvfs2_normalize_to_errno(op->downcall.status); + ret = op->downcall.status; + } + + if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + unmask_blocked_signals(&orig_sigset); + + BUG_ON(ret != op->downcall.status); + /* retry if operation has not been serviced and if requested */ + if (!op_state_serviced(op) && op->downcall.status == -EAGAIN) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2: tag %llu (%s)" + " -- operation to be retried (%d attempt)\n", + llu(op->tag), + op_name, + op->attempts + 1); + + if (!op->uses_shared_memory) + /* + * this operation doesn't use the shared memory + * system + */ + goto retry_servicing; + + /* op uses shared memory */ + if (get_bufmap_init() == 0) { + /* + * This operation uses the shared memory system AND + * the system is not yet ready. This situation occurs + * when the client-core is restarted AND there were + * operations waiting to be processed or were already + * in process. + */ + gossip_debug(GOSSIP_WAIT_DEBUG, + "uses_shared_memory is true.\n"); + gossip_debug(GOSSIP_WAIT_DEBUG, + "Client core in-service status(%d).\n", + is_daemon_in_service()); + gossip_debug(GOSSIP_WAIT_DEBUG, "bufmap_init:%d.\n", + get_bufmap_init()); + gossip_debug(GOSSIP_WAIT_DEBUG, + "operation's status is 0x%0x.\n", + op->op_state); + + /* + * let process sleep for a few seconds so shared + * memory system can be initialized. + */ + spin_lock_irqsave(&op->lock, irqflags); + add_wait_queue(&pvfs2_bufmap_init_waitq, &wait_entry); + spin_unlock_irqrestore(&op->lock, irqflags); + + set_current_state(TASK_INTERRUPTIBLE); + + /* + * Wait for pvfs_bufmap_initialize() to wake me up + * within the allotted time. + */ + ret = schedule_timeout(MSECS_TO_JIFFIES + (1000 * PVFS2_BUFMAP_WAIT_TIMEOUT_SECS)); + + gossip_debug(GOSSIP_WAIT_DEBUG, + "Value returned from schedule_timeout:" + "%d.\n", + ret); + gossip_debug(GOSSIP_WAIT_DEBUG, + "Is shared memory available? (%d).\n", + get_bufmap_init()); + + spin_lock_irqsave(&op->lock, irqflags); + remove_wait_queue(&pvfs2_bufmap_init_waitq, + &wait_entry); + spin_unlock_irqrestore(&op->lock, irqflags); + + if (get_bufmap_init() == 0) { + gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted. Aborting user's request(%s).\n", + __func__, + PVFS2_BUFMAP_WAIT_TIMEOUT_SECS, + get_opname_string(op)); + return -EIO; + } + + /* + * Return to the calling function and re-populate a + * shared memory buffer. + */ + return -EAGAIN; + } + } + + gossip_debug(GOSSIP_WAIT_DEBUG, + "pvfs2: service_operation %s returning: %d for %p.\n", + op_name, + ret, + op); + return ret; +} + +void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op) +{ + /* + * handle interrupted cases depending on what state we were in when + * the interruption is detected. there is a coarse grained lock + * across the operation. + * + * NOTE: be sure not to reverse lock ordering by locking an op lock + * while holding the request_list lock. Here, we first lock the op + * and then lock the appropriate list. + */ + if (!op) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s: op is null, ignoring\n", + __func__); + return; + } + + /* + * one more sanity check, make sure it's in one of the possible states + * or don't try to cancel it + */ + if (!(op_state_waiting(op) || + op_state_in_progress(op) || + op_state_serviced(op) || + op_state_purged(op))) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s: op %p not in a valid state (%0x), " + "ignoring\n", + __func__, + op, + op->op_state); + return; + } + + spin_lock(&op->lock); + + if (op_state_waiting(op)) { + /* + * upcall hasn't been read; remove op from upcall request + * list. + */ + spin_unlock(&op->lock); + remove_op_from_request_list(op); + gossip_debug(GOSSIP_WAIT_DEBUG, + "Interrupted: Removed op %p from request_list\n", + op); + } else if (op_state_in_progress(op)) { + /* op must be removed from the in progress htable */ + spin_unlock(&op->lock); + spin_lock(&htable_ops_in_progress_lock); + list_del(&op->list); + spin_unlock(&htable_ops_in_progress_lock); + gossip_debug(GOSSIP_WAIT_DEBUG, + "Interrupted: Removed op %p" + " from htable_ops_in_progress\n", + op); + } else if (!op_state_serviced(op)) { + spin_unlock(&op->lock); + gossip_err("interrupted operation is in a weird state 0x%x\n", + op->op_state); + } +} + +/* + * sleeps on waitqueue waiting for matching downcall. + * if client-core finishes servicing, then we are good to go. + * else if client-core exits, we get woken up here, and retry with a timeout + * + * Post when this call returns to the caller, the specified op will no + * longer be on any list or htable. + * + * Returns 0 on success and -errno on failure + * Errors are: + * EAGAIN in case we want the caller to requeue and try again.. + * EINTR/EIO/ETIMEDOUT indicating we are done trying to service this + * operation since client-core seems to be exiting too often + * or if we were interrupted. + */ +int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) +{ + int ret = -EINVAL; + DECLARE_WAITQUEUE(wait_entry, current); + + spin_lock(&op->lock); + add_wait_queue(&op->waitq, &wait_entry); + spin_unlock(&op->lock); + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + spin_lock(&op->lock); + if (op_state_serviced(op)) { + spin_unlock(&op->lock); + ret = 0; + break; + } + spin_unlock(&op->lock); + + if (!signal_pending(current)) { + /* + * if this was our first attempt and client-core + * has not purged our operation, we are happy to + * simply wait + */ + spin_lock(&op->lock); + if (op->attempts == 0 && !op_state_purged(op)) { + spin_unlock(&op->lock); + schedule(); + } else { + spin_unlock(&op->lock); + /* + * subsequent attempts, we retry exactly once + * with timeouts + */ + if (!schedule_timeout(MSECS_TO_JIFFIES + (1000 * op_timeout_secs))) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "*** %s:" + " operation timed out (tag" + " %llu, %p, att %d)\n", + __func__, + llu(op->tag), + op, + op->attempts); + ret = -ETIMEDOUT; + pvfs2_clean_up_interrupted_operation + (op); + break; + } + } + spin_lock(&op->lock); + op->attempts++; + /* + * if the operation was purged in the meantime, it + * is better to requeue it afresh but ensure that + * we have not been purged repeatedly. This could + * happen if client-core crashes when an op + * is being serviced, so we requeue the op, client + * core crashes again so we requeue the op, client + * core starts, and so on... + */ + if (op_state_purged(op)) { + ret = (op->attempts < PVFS2_PURGE_RETRY_COUNT) ? + -EAGAIN : + -EIO; + spin_unlock(&op->lock); + gossip_debug(GOSSIP_WAIT_DEBUG, + "*** %s:" + " operation purged (tag " + "%llu, %p, att %d)\n", + __func__, + llu(op->tag), + op, + op->attempts); + pvfs2_clean_up_interrupted_operation(op); + break; + } + spin_unlock(&op->lock); + continue; + } + + gossip_debug(GOSSIP_WAIT_DEBUG, + "*** %s:" + " operation interrupted by a signal (tag " + "%llu, op %p)\n", + __func__, + llu(op->tag), + op); + pvfs2_clean_up_interrupted_operation(op); + ret = -EINTR; + break; + } + + set_current_state(TASK_RUNNING); + + spin_lock(&op->lock); + remove_wait_queue(&op->waitq, &wait_entry); + spin_unlock(&op->lock); + + return ret; +} + +/* + * similar to wait_for_matching_downcall(), but used in the special case + * of I/O cancellations. + * + * Note we need a special wait function because if this is called we already + * know that a signal is pending in current and need to service the + * cancellation upcall anyway. the only way to exit this is to either + * timeout or have the cancellation be serviced properly. + */ +int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op) +{ + int ret = -EINVAL; + DECLARE_WAITQUEUE(wait_entry, current); + + spin_lock(&op->lock); + add_wait_queue(&op->waitq, &wait_entry); + spin_unlock(&op->lock); + + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + spin_lock(&op->lock); + if (op_state_serviced(op)) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:op-state is SERVICED.\n", + __func__); + spin_unlock(&op->lock); + ret = 0; + break; + } + spin_unlock(&op->lock); + + if (signal_pending(current)) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:operation interrupted by a signal (tag" + " %llu, op %p)\n", + __func__, + llu(op->tag), + op); + pvfs2_clean_up_interrupted_operation(op); + ret = -EINTR; + break; + } + + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:About to call schedule_timeout.\n", + __func__); + ret = + schedule_timeout(MSECS_TO_JIFFIES(1000 * op_timeout_secs)); + + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:Value returned from schedule_timeout(%d).\n", + __func__, + ret); + if (!ret) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:*** operation timed out: %p\n", + __func__, + op); + pvfs2_clean_up_interrupted_operation(op); + ret = -ETIMEDOUT; + break; + } + + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:Breaking out of loop, regardless of value returned by schedule_timeout.\n", + __func__); + ret = -ETIMEDOUT; + break; + } + + set_current_state(TASK_RUNNING); + + spin_lock(&op->lock); + remove_wait_queue(&op->waitq, &wait_entry); + spin_unlock(&op->lock); + + gossip_debug(GOSSIP_WAIT_DEBUG, + "%s:returning ret(%d)\n", + __func__, + ret); + + return ret; +} diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c new file mode 100644 index 000000000000..2766090f5ca4 --- /dev/null +++ b/fs/orangefs/xattr.c @@ -0,0 +1,532 @@ +/* + * (C) 2001 Clemson University and The University of Chicago + * + * See COPYING in top-level directory. + */ + +/* + * Linux VFS extended attribute operations. + */ + +#include "protocol.h" +#include "pvfs2-kernel.h" +#include "pvfs2-bufmap.h" +#include +#include + + +#define SYSTEM_PVFS2_KEY "system.pvfs2." +#define SYSTEM_PVFS2_KEY_LEN 13 + +/* + * this function returns + * 0 if the key corresponding to name is not meant to be printed as part + * of a listxattr. + * 1 if the key corresponding to name is meant to be returned as part of + * a listxattr. + * The ones that start SYSTEM_PVFS2_KEY are the ones to avoid printing. + */ +static int is_reserved_key(const char *key, size_t size) +{ + + if (size < SYSTEM_PVFS2_KEY_LEN) + return 1; + + return strncmp(key, SYSTEM_PVFS2_KEY, SYSTEM_PVFS2_KEY_LEN) ? 1 : 0; +} + +static inline int convert_to_internal_xattr_flags(int setxattr_flags) +{ + int internal_flag = 0; + + if (setxattr_flags & XATTR_REPLACE) { + /* Attribute must exist! */ + internal_flag = PVFS_XATTR_REPLACE; + } else if (setxattr_flags & XATTR_CREATE) { + /* Attribute must not exist */ + internal_flag = PVFS_XATTR_CREATE; + } + return internal_flag; +} + + +/* + * Tries to get a specified key's attributes of a given + * file into a user-specified buffer. Note that the getxattr + * interface allows for the users to probe the size of an + * extended attribute by passing in a value of 0 to size. + * Thus our return value is always the size of the attribute + * unless the key does not exist for the file and/or if + * there were errors in fetching the attribute value. + */ +ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, + const char *name, void *buffer, size_t size) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op = NULL; + ssize_t ret = -ENOMEM; + ssize_t length = 0; + int fsuid; + int fsgid; + + gossip_debug(GOSSIP_XATTR_DEBUG, + "%s: prefix %s name %s, buffer_size %zd\n", + __func__, prefix, name, size); + + if (name == NULL || (size > 0 && buffer == NULL)) { + gossip_err("pvfs2_inode_getxattr: bogus NULL pointers\n"); + return -EINVAL; + } + if (size < 0 || + (strlen(name) + strlen(prefix)) >= PVFS_MAX_XATTR_NAMELEN) { + gossip_err("Invalid size (%d) or key length (%d)\n", + (int)size, + (int)(strlen(name) + strlen(prefix))); + return -EINVAL; + } + + fsuid = from_kuid(current_user_ns(), current_fsuid()); + fsgid = from_kgid(current_user_ns(), current_fsgid()); + + gossip_debug(GOSSIP_XATTR_DEBUG, + "getxattr on inode %pU, name %s " + "(uid %o, gid %o)\n", + get_khandle_from_ino(inode), + name, + fsuid, + fsgid); + + down_read(&pvfs2_inode->xattr_sem); + + new_op = op_alloc(PVFS2_VFS_OP_GETXATTR); + if (!new_op) + goto out_unlock; + + new_op->upcall.req.getxattr.refn = pvfs2_inode->refn; + ret = snprintf((char *)new_op->upcall.req.getxattr.key, + PVFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name); + + /* + * NOTE: Although keys are meant to be NULL terminated textual + * strings, I am going to explicitly pass the length just in case + * we change this later on... + */ + new_op->upcall.req.getxattr.key_sz = ret + 1; + + ret = service_operation(new_op, "pvfs2_inode_getxattr", + get_interruptible_flag(inode)); + if (ret != 0) { + if (ret == -ENOENT) { + ret = -ENODATA; + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_getxattr: inode %pU key %s" + " does not exist!\n", + get_khandle_from_ino(inode), + (char *)new_op->upcall.req.getxattr.key); + } + goto out_release_op; + } + + /* + * Length returned includes null terminator. + */ + length = new_op->downcall.resp.getxattr.val_sz; + + /* + * Just return the length of the queried attribute. + */ + if (size == 0) { + ret = length; + goto out_release_op; + } + + /* + * Check to see if key length is > provided buffer size. + */ + if (length > size) { + ret = -ERANGE; + goto out_release_op; + } + + memset(buffer, 0, size); + memcpy(buffer, new_op->downcall.resp.getxattr.val, length); + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_getxattr: inode %pU " + "key %s key_sz %d, val_len %d\n", + get_khandle_from_ino(inode), + (char *)new_op-> + upcall.req.getxattr.key, + (int)new_op-> + upcall.req.getxattr.key_sz, + (int)ret); + + ret = length; + +out_release_op: + op_release(new_op); +out_unlock: + up_read(&pvfs2_inode->xattr_sem); + return ret; +} + +static int pvfs2_inode_removexattr(struct inode *inode, + const char *prefix, + const char *name, + int flags) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op = NULL; + int ret = -ENOMEM; + + down_write(&pvfs2_inode->xattr_sem); + new_op = op_alloc(PVFS2_VFS_OP_REMOVEXATTR); + if (!new_op) + goto out_unlock; + + new_op->upcall.req.removexattr.refn = pvfs2_inode->refn; + /* + * NOTE: Although keys are meant to be NULL terminated + * textual strings, I am going to explicitly pass the + * length just in case we change this later on... + */ + ret = snprintf((char *)new_op->upcall.req.removexattr.key, + PVFS_MAX_XATTR_NAMELEN, + "%s%s", + (prefix ? prefix : ""), + name); + new_op->upcall.req.removexattr.key_sz = ret + 1; + + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_removexattr: key %s, key_sz %d\n", + (char *)new_op->upcall.req.removexattr.key, + (int)new_op->upcall.req.removexattr.key_sz); + + ret = service_operation(new_op, + "pvfs2_inode_removexattr", + get_interruptible_flag(inode)); + if (ret == -ENOENT) { + /* + * Request to replace a non-existent attribute is an error. + */ + if (flags & XATTR_REPLACE) + ret = -ENODATA; + else + ret = 0; + } + + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_removexattr: returning %d\n", ret); + + op_release(new_op); +out_unlock: + up_write(&pvfs2_inode->xattr_sem); + return ret; +} + +/* + * Tries to set an attribute for a given key on a file. + * + * Returns a -ve number on error and 0 on success. Key is text, but value + * can be binary! + */ +int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, + const char *name, const void *value, size_t size, int flags) +{ + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op; + int internal_flag = 0; + int ret = -ENOMEM; + + gossip_debug(GOSSIP_XATTR_DEBUG, + "%s: prefix %s, name %s, buffer_size %zd\n", + __func__, prefix, name, size); + + if (size < 0 || + size >= PVFS_MAX_XATTR_VALUELEN || + flags < 0) { + gossip_err("pvfs2_inode_setxattr: bogus values of size(%d), flags(%d)\n", + (int)size, + flags); + return -EINVAL; + } + + if (name == NULL || + (size > 0 && value == NULL)) { + gossip_err("pvfs2_inode_setxattr: bogus NULL pointers!\n"); + return -EINVAL; + } + + internal_flag = convert_to_internal_xattr_flags(flags); + + if (prefix) { + if (strlen(name) + strlen(prefix) >= PVFS_MAX_XATTR_NAMELEN) { + gossip_err + ("pvfs2_inode_setxattr: bogus key size (%d)\n", + (int)(strlen(name) + strlen(prefix))); + return -EINVAL; + } + } else { + if (strlen(name) >= PVFS_MAX_XATTR_NAMELEN) { + gossip_err + ("pvfs2_inode_setxattr: bogus key size (%d)\n", + (int)(strlen(name))); + return -EINVAL; + } + } + + /* This is equivalent to a removexattr */ + if (size == 0 && value == NULL) { + gossip_debug(GOSSIP_XATTR_DEBUG, + "removing xattr (%s%s)\n", + prefix, + name); + return pvfs2_inode_removexattr(inode, prefix, name, flags); + } + + gossip_debug(GOSSIP_XATTR_DEBUG, + "setxattr on inode %pU, name %s\n", + get_khandle_from_ino(inode), + name); + + down_write(&pvfs2_inode->xattr_sem); + new_op = op_alloc(PVFS2_VFS_OP_SETXATTR); + if (!new_op) + goto out_unlock; + + + new_op->upcall.req.setxattr.refn = pvfs2_inode->refn; + new_op->upcall.req.setxattr.flags = internal_flag; + /* + * NOTE: Although keys are meant to be NULL terminated textual + * strings, I am going to explicitly pass the length just in + * case we change this later on... + */ + ret = snprintf((char *)new_op->upcall.req.setxattr.keyval.key, + PVFS_MAX_XATTR_NAMELEN, + "%s%s", + prefix, name); + new_op->upcall.req.setxattr.keyval.key_sz = ret + 1; + memcpy(new_op->upcall.req.setxattr.keyval.val, value, size); + new_op->upcall.req.setxattr.keyval.val_sz = size; + + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_setxattr: key %s, key_sz %d " + " value size %zd\n", + (char *)new_op->upcall.req.setxattr.keyval.key, + (int)new_op->upcall.req.setxattr.keyval.key_sz, + size); + + ret = service_operation(new_op, + "pvfs2_inode_setxattr", + get_interruptible_flag(inode)); + + gossip_debug(GOSSIP_XATTR_DEBUG, + "pvfs2_inode_setxattr: returning %d\n", + ret); + + /* when request is serviced properly, free req op struct */ + op_release(new_op); +out_unlock: + up_write(&pvfs2_inode->xattr_sem); + return ret; +} + +/* + * Tries to get a specified object's keys into a user-specified buffer of a + * given size. Note that like the previous instances of xattr routines, this + * also allows you to pass in a NULL pointer and 0 size to probe the size for + * subsequent memory allocations. Thus our return value is always the size of + * all the keys unless there were errors in fetching the keys! + */ +ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + struct inode *inode = dentry->d_inode; + struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct pvfs2_kernel_op_s *new_op; + __u64 token = PVFS_ITERATE_START; + ssize_t ret = -ENOMEM; + ssize_t total = 0; + ssize_t length = 0; + int count_keys = 0; + int key_size; + int i = 0; + + if (size > 0 && buffer == NULL) { + gossip_err("%s: bogus NULL pointers\n", __func__); + return -EINVAL; + } + if (size < 0) { + gossip_err("Invalid size (%d)\n", (int)size); + return -EINVAL; + } + + down_read(&pvfs2_inode->xattr_sem); + new_op = op_alloc(PVFS2_VFS_OP_LISTXATTR); + if (!new_op) + goto out_unlock; + + if (buffer && size > 0) + memset(buffer, 0, size); + +try_again: + key_size = 0; + new_op->upcall.req.listxattr.refn = pvfs2_inode->refn; + new_op->upcall.req.listxattr.token = token; + new_op->upcall.req.listxattr.requested_count = + (size == 0) ? 0 : PVFS_MAX_XATTR_LISTLEN; + ret = service_operation(new_op, __func__, + get_interruptible_flag(inode)); + if (ret != 0) + goto done; + + if (size == 0) { + /* + * This is a bit of a big upper limit, but I did not want to + * spend too much time getting this correct, since users end + * up allocating memory rather than us... + */ + total = new_op->downcall.resp.listxattr.returned_count * + PVFS_MAX_XATTR_NAMELEN; + goto done; + } + + length = new_op->downcall.resp.listxattr.keylen; + if (length == 0) + goto done; + + /* + * Check to see how much can be fit in the buffer. Fit only whole keys. + */ + for (i = 0; i < new_op->downcall.resp.listxattr.returned_count; i++) { + if (total + new_op->downcall.resp.listxattr.lengths[i] > size) + goto done; + + /* + * Since many dumb programs try to setxattr() on our reserved + * xattrs this is a feeble attempt at defeating those by not + * listing them in the output of listxattr.. sigh + */ + if (is_reserved_key(new_op->downcall.resp.listxattr.key + + key_size, + new_op->downcall.resp. + listxattr.lengths[i])) { + gossip_debug(GOSSIP_XATTR_DEBUG, "Copying key %d -> %s\n", + i, new_op->downcall.resp.listxattr.key + + key_size); + memcpy(buffer + total, + new_op->downcall.resp.listxattr.key + key_size, + new_op->downcall.resp.listxattr.lengths[i]); + total += new_op->downcall.resp.listxattr.lengths[i]; + count_keys++; + } else { + gossip_debug(GOSSIP_XATTR_DEBUG, "[RESERVED] key %d -> %s\n", + i, new_op->downcall.resp.listxattr.key + + key_size); + } + key_size += new_op->downcall.resp.listxattr.lengths[i]; + } + + /* + * Since the buffer was large enough, we might have to continue + * fetching more keys! + */ + token = new_op->downcall.resp.listxattr.token; + if (token != PVFS_ITERATE_END) + goto try_again; + +done: + gossip_debug(GOSSIP_XATTR_DEBUG, "%s: returning %d" + " [size of buffer %ld] (filled in %d keys)\n", + __func__, + ret ? (int)ret : (int)total, + (long)size, + count_keys); + op_release(new_op); + if (ret == 0) + ret = total; +out_unlock: + up_read(&pvfs2_inode->xattr_sem); + return ret; +} + +int pvfs2_xattr_set_default(struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags, + int handler_flags) +{ + return pvfs2_inode_setxattr(dentry->d_inode, + PVFS2_XATTR_NAME_DEFAULT_PREFIX, + name, + buffer, + size, + flags); +} + +int pvfs2_xattr_get_default(struct dentry *dentry, + const char *name, + void *buffer, + size_t size, + int handler_flags) +{ + return pvfs2_inode_getxattr(dentry->d_inode, + PVFS2_XATTR_NAME_DEFAULT_PREFIX, + name, + buffer, + size); + +} + +static int pvfs2_xattr_set_trusted(struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags, + int handler_flags) +{ + return pvfs2_inode_setxattr(dentry->d_inode, + PVFS2_XATTR_NAME_TRUSTED_PREFIX, + name, + buffer, + size, + flags); +} + +static int pvfs2_xattr_get_trusted(struct dentry *dentry, + const char *name, + void *buffer, + size_t size, + int handler_flags) +{ + return pvfs2_inode_getxattr(dentry->d_inode, + PVFS2_XATTR_NAME_TRUSTED_PREFIX, + name, + buffer, + size); +} + +static struct xattr_handler pvfs2_xattr_trusted_handler = { + .prefix = PVFS2_XATTR_NAME_TRUSTED_PREFIX, + .get = pvfs2_xattr_get_trusted, + .set = pvfs2_xattr_set_trusted, +}; + +static struct xattr_handler pvfs2_xattr_default_handler = { + /* + * NOTE: this is set to be the empty string. + * so that all un-prefixed xattrs keys get caught + * here! + */ + .prefix = PVFS2_XATTR_NAME_DEFAULT_PREFIX, + .get = pvfs2_xattr_get_default, + .set = pvfs2_xattr_set_default, +}; + +const struct xattr_handler *pvfs2_xattr_handlers[] = { + &posix_acl_access_xattr_handler, + &posix_acl_default_xattr_handler, + &pvfs2_xattr_trusted_handler, + &pvfs2_xattr_default_handler, + NULL +}; -- GitLab From 74a552a133ab4c9673476d26edadae13f5d54408 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:16 -0400 Subject: [PATCH 0006/5324] Orangefs: kernel client part 6 Signed-off-by: Mike Marshall --- Documentation/ABI/stable/sysfs-fs-orangefs | 87 +++++++++++++ Documentation/filesystems/orangefs.txt | 137 +++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-fs-orangefs create mode 100644 Documentation/filesystems/orangefs.txt diff --git a/Documentation/ABI/stable/sysfs-fs-orangefs b/Documentation/ABI/stable/sysfs-fs-orangefs new file mode 100644 index 000000000000..affdb114bd33 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-fs-orangefs @@ -0,0 +1,87 @@ +What: /sys/fs/orangefs/perf_counters/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Counters and settings for various caches. + Read only. + + +What: /sys/fs/orangefs/perf_counter_reset +Date: June 2015 +Contact: Mike Marshall +Description: + echo a 0 or a 1 into perf_counter_reset to + reset all the counters in + /sys/fs/orangefs/perf_counters + except ones with PINT_PERF_PRESERVE set. + + +What: /sys/fs/orangefs/perf_time_interval_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Length of perf counter intervals in + seconds. + + +What: /sys/fs/orangefs/perf_history_size +Date: Jun 2015 +Contact: Mike Marshall +Description: + The perf_counters cache statistics have N, or + perf_history_size, samples. The default is + one. + + Every perf_time_interval_secs the (first) + samples are reset. + + If N is greater than one, the "current" set + of samples is reset, and the samples from the + other N-1 intervals remain available. + + +What: /sys/fs/orangefs/op_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Service operation timeout in seconds. + + +What: /sys/fs/orangefs/slot_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + "Slot" timeout in seconds. A "slot" + is an indexed buffer in the shared + memory segment used for communication + between the kernel module and userspace. + Slots are requested and waited for, + the wait times out after slot_timeout_secs. + + +What: /sys/fs/orangefs/acache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Attribute cache configurable settings. + + +What: /sys/fs/orangefs/ncache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Name cache configurable settings. + + +What: /sys/fs/orangefs/capcache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Capability cache configurable settings. + + +What: /sys/fs/orangefs/ccache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Credential cache configurable settings. diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt new file mode 100644 index 000000000000..ec9c8416427e --- /dev/null +++ b/Documentation/filesystems/orangefs.txt @@ -0,0 +1,137 @@ +ORANGEFS +======== + +OrangeFS is an LGPL userspace scale-out parallel storage system. It is ideal +for large storage problems faced by HPC, BigData, Streaming Video, +Genomics, Bioinformatics. + +Orangefs, originally called PVFS, was first developed in 1993 by +Walt Ligon and Eric Blumer as a parallel file system for Parallel +Virtual Machine (PVM) as part of a NASA grant to study the I/O patterns +of parallel programs. + +Orangefs features include: + + * Distributes file data among multiple file servers + * Supports simultaneous access by multiple clients + * Stores file data and metadata on servers using local file system + and access methods + * Userspace implementation is easy to install and maintain + * Direct MPI support + * Stateless + + +MAILING LIST +============ + +http://beowulf-underground.org/mailman/listinfo/pvfs2-users + + +DOCUMENTATION +============= + +http://www.orangefs.org/documentation/ + + +USERSPACE FILESYSTEM SOURCE +=========================== + +http://www.orangefs.org/download + +Orangefs versions prior to 2.9.3 would not be compatible with the +upstream version of the kernel client. + + +BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER +==================================================== + +When Orangefs is upstream, "--with-kernel" shouldn't be needed, but +until then the path to where the kernel with the Orangefs kernel client +patch was built is needed to ensure that pvfs2-client-core (the bridge +between kernel space and user space) will build properly. You can omit +--prefix if you don't care that things are sprinkled around in +/usr/local. + +./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel + +make + +make install + +Create an orangefs config file: +/opt/ofs/bin/pvfs2-genconfig /etc/pvfs2.conf + + for "Enter hostnames", use the hostname, don't let it default to + localhost. + +create a pvfs2tab file in /etc: +cat /etc/pvfs2tab +tcp://myhostname:3334/orangefs /mymountpoint pvfs2 defaults,noauto 0 0 + +create the mount point you specified in the tab file if needed: +mkdir /mymountpoint + +bootstrap the server: +/opt/ofs/sbin/pvfs2-server /etc/pvfs2.conf -f + +start the server: +/opt/osf/sbin/pvfs2-server /etc/pvfs2.conf + +Now the server is running. At this point you might like to +prove things are working with: + +/opt/osf/bin/pvfs2-ls /mymountpoint + +You might not want to enforce selinux, it doesn't seem to matter by +linux 3.11... + +If stuff seems to be working, turn on the client core: +/opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core + +Mount your filesystem. +mount -t pvfs2 tcp://myhostname:3334/orangefs /mymountpoint + + +OPTIONS +======= + +The following mount options are accepted: + + acl + Allow the use of Access Control Lists on files and directories. + + intr + Some operations between the kernel client and the user space + filesystem can be interruptible, such as changes in debug levels + and the setting of tunable parameters. + + local_lock + Enable posix locking from the perspective of "this" kernel. The + default file_operations lock action is to return ENOSYS. Posix + locking kicks in if the filesystem is mounted with -o local_lock. + Distributed locking is being worked on for the future. + + +DEBUGGING +========= + +If you want the debug (GOSSIP) statments in a particular +source file (inode.c for example) go to syslog: + + echo inode > /sys/kernel/debug/orangefs/kernel-debug + +No debugging (the default): + + echo none > /sys/kernel/debug/orangefs/kernel-debug + +Debugging from several source files: + + echo inode,dir > /sys/kernel/debug/orangefs/kernel-debug + +All debugging: + + echo all > /sys/kernel/debug/orangefs/kernel-debug + +Get a list of all debugging keywords: + + cat /sys/kernel/debug/orangefs/debug-help -- GitLab From 07f01962e3d37bd2c5bbcdf87f29c9fe78feb6e0 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 17 Jul 2015 10:38:17 -0400 Subject: [PATCH 0007/5324] Orangefs: kernel client part 7 Signed-off-by: Mike Marshall --- fs/Kconfig | 1 + fs/Makefile | 1 + fs/orangefs/Kconfig | 6 ++++++ fs/orangefs/Makefile | 10 ++++++++++ 4 files changed, 18 insertions(+) create mode 100644 fs/orangefs/Kconfig create mode 100644 fs/orangefs/Makefile diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f1a4e4..7d1bef1999af 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -190,6 +190,7 @@ menuconfig MISC_FILESYSTEMS if MISC_FILESYSTEMS +source "fs/orangefs/Kconfig" source "fs/adfs/Kconfig" source "fs/affs/Kconfig" source "fs/ecryptfs/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index f79cf4043e60..b4406d6f7da1 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -104,6 +104,7 @@ obj-$(CONFIG_AUTOFS4_FS) += autofs4/ obj-$(CONFIG_ADFS_FS) += adfs/ obj-$(CONFIG_FUSE_FS) += fuse/ obj-$(CONFIG_OVERLAY_FS) += overlayfs/ +obj-$(CONFIG_ORANGEFS_FS) += orangefs/ obj-$(CONFIG_UDF_FS) += udf/ obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ obj-$(CONFIG_OMFS_FS) += omfs/ diff --git a/fs/orangefs/Kconfig b/fs/orangefs/Kconfig new file mode 100644 index 000000000000..1554c02489de --- /dev/null +++ b/fs/orangefs/Kconfig @@ -0,0 +1,6 @@ +config ORANGEFS_FS + tristate "ORANGEFS (Powered by PVFS) support" + select FS_POSIX_ACL + help + Orange is a parallel file system designed for use on high end + computing (HEC) systems. diff --git a/fs/orangefs/Makefile b/fs/orangefs/Makefile new file mode 100644 index 000000000000..828b36a6916d --- /dev/null +++ b/fs/orangefs/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the ORANGEFS filesystem. +# + +obj-$(CONFIG_ORANGEFS_FS) += orangefs.o + +orangefs-objs := acl.o file.o pvfs2-cache.o pvfs2-utils.o xattr.o dcache.o \ + inode.o pvfs2-sysfs.o pvfs2-mod.o super.o devpvfs2-req.o \ + namei.o symlink.o dir.o pvfs2-bufmap.o \ + pvfs2-debugfs.o waitqueue.o -- GitLab From 2c590d5fb6987e6579a82285b742a318cc1fdb50 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 24 Jul 2015 10:37:15 -0400 Subject: [PATCH 0008/5324] Orangefs: kernel client update 1. Stephen Rothwell noticed that orangefs would not compile on powerpc... Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 17 ++++++++++++----- fs/orangefs/protocol.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index 3e450228f3dc..7e60fd047f28 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -36,7 +36,7 @@ do { \ static int hash_func(__u64 tag, int table_size) { - return tag % ((unsigned int)table_size); + return do_div(tag, (unsigned int)table_size); } static void pvfs2_devreq_add_op(struct pvfs2_kernel_op_s *op) @@ -279,7 +279,7 @@ static ssize_t pvfs2_devreq_writev(struct file *file, /* Either there is a trailer or there isn't */ if (count != notrailer_count && count != (notrailer_count + 1)) { - gossip_err("Error: Number of iov vectors is (%ld) and notrailer count is %d\n", + gossip_err("Error: Number of iov vectors is (%zu) and notrailer count is %d\n", count, notrailer_count); return -EPROTO; @@ -356,7 +356,7 @@ static ssize_t pvfs2_devreq_writev(struct file *file, "writev: trailer size %ld\n", (unsigned long)op->downcall.trailer_size); if (count != (notrailer_count + 1)) { - gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%ld)\n", (unsigned long)op->downcall.trailer_size, count); + gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)op->downcall.trailer_size, count); dev_req_release(buffer); put_op(op); return -EPROTO; @@ -908,6 +908,14 @@ static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd, return dispatch_ioctl_command(cmd, arg); } +#endif /* CONFIG_COMPAT is in .config */ + +/* + * The following two ioctl32 functions had been refactored into the above + * CONFIG_COMPAT ifdef, but that was an over simplification that was + * not noticed until we tried to compile on power pc... + */ +#if (defined(CONFIG_COMPAT) && !defined(HAVE_REGISTER_IOCTL32_CONVERSION)) || !defined(CONFIG_COMPAT) static int pvfs2_ioctl32_init(void) { return 0; @@ -917,8 +925,7 @@ static void pvfs2_ioctl32_cleanup(void) { return; } - -#endif /* CONFIG_COMPAT is in .config */ +#endif /* the assigned character device major number */ static int pvfs2_dev_major; diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 2fb3a63ae9ab..8e0c8a6158f7 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -1,6 +1,7 @@ #include #include #include +#include extern struct client_debug_mask *cdm_array; extern char *debug_help_string; -- GitLab From 84d02150dea7571dc32176e35d65eecde82631a9 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Tue, 28 Jul 2015 13:27:51 -0400 Subject: [PATCH 0009/5324] Orangefs: sooth most sparse complaints Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 2 +- fs/orangefs/file.c | 13 ++++++++----- fs/orangefs/inode.c | 2 +- fs/orangefs/protocol.h | 12 +----------- fs/orangefs/pvfs2-bufmap.c | 10 +++++++--- fs/orangefs/pvfs2-debugfs.c | 2 +- fs/orangefs/pvfs2-kernel.h | 2 +- fs/orangefs/pvfs2-mod.c | 1 - fs/orangefs/pvfs2-sysfs.c | 4 ++-- fs/orangefs/super.c | 8 ++++---- fs/orangefs/waitqueue.c | 7 +++++++ 11 files changed, 33 insertions(+), 30 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index 7e60fd047f28..13878cac49ed 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -857,7 +857,7 @@ static unsigned long translate_dev_map26(unsigned long args, long *error) */ struct PVFS_dev_map_desc __user *p = compat_alloc_user_space(sizeof(*p)); - u32 addr; + compat_uptr_t addr; *error = 0; /* get the ptr from the 32 bit user-space */ diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 8e26f9fac289..4ba1b6c48aa7 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -799,7 +799,7 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) /* * Perform a miscellaneous operation on a file. */ -long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; __u64 val = 0; @@ -885,7 +885,7 @@ static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma) * * \note Not called when each file is closed. */ -int pvfs2_file_release(struct inode *inode, struct file *file) +static int pvfs2_file_release(struct inode *inode, struct file *file) { gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_release: called on %s\n", @@ -909,7 +909,10 @@ int pvfs2_file_release(struct inode *inode, struct file *file) /* * Push all data for a specific file onto permanent storage. */ -int pvfs2_fsync(struct file *file, loff_t start, loff_t end, int datasync) +static int pvfs2_fsync(struct file *file, + loff_t start, + loff_t end, + int datasync) { int ret = -EINVAL; struct pvfs2_inode_s *pvfs2_inode = @@ -947,7 +950,7 @@ int pvfs2_fsync(struct file *file, loff_t start, loff_t end, int datasync) * Future upgrade could support SEEK_DATA and SEEK_HOLE but would * require much changes to the FS */ -loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) +static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) { int ret = -EINVAL; struct inode *inode = file->f_path.dentry->d_inode; @@ -989,7 +992,7 @@ loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) * Support local locks (locks that only this kernel knows about) * if Orangefs was mounted -o local_lock. */ -int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) +static int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) { int rc = -ENOLCK; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index feda00fcdd7d..9ff6b2985240 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -33,7 +33,7 @@ static int read_one_page(struct page *page) loff_t blockptr_offset = (((loff_t) page->index) << blockbits); bytes_read = pvfs2_inode_read(inode, - page_data, + (char __user *) page_data, blocksize, &blockptr_offset, inode->i_size); diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 8e0c8a6158f7..ca7cef9590d3 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -341,7 +341,7 @@ __s32 PINT_non_errno_mapping[] = { \ extern __s32 PINT_errno_mapping[]; \ extern __s32 PINT_non_errno_mapping[]; \ extern const char *PINT_non_errno_strerror_mapping[]; \ -__s32 PVFS_get_errno_mapping(__s32 error) \ +static __s32 PVFS_get_errno_mapping(__s32 error) \ { \ __s32 ret = error, mask = 0; \ __s32 positive = ((error > -1) ? 1 : 0); \ @@ -364,16 +364,6 @@ __s32 PVFS_get_errno_mapping(__s32 error) \ } \ return ret; \ } \ -__s32 PVFS_errno_to_error(int err) \ -{ \ - __s32 e = 0; \ - \ - for (; e < PVFS_ERRNO_MAX; ++e) \ - if (PINT_errno_mapping[e] == err) \ - return e | PVFS_ERROR_BIT; \ - \ - return err; \ -} \ DECLARE_ERRNO_MAPPING() /* permission bits */ diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index aa14c37d0216..a439163f8d7c 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -9,7 +9,7 @@ DECLARE_WAIT_QUEUE_HEAD(pvfs2_bufmap_init_waitq); -struct pvfs2_bufmap { +static struct pvfs2_bufmap { atomic_t refcnt; int desc_size; @@ -663,6 +663,7 @@ int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, int to_page_index = 0; void *to_kaddr = NULL; void *from_kaddr = NULL; + struct kvec *iv = NULL; struct iovec *copied_iovec = NULL; struct pvfs_bufmap_desc *to; unsigned int seg; @@ -708,9 +709,10 @@ int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, * buffer into the mapped buffer one page at a time though */ while (amt_copied < size) { - struct iovec *iv = &copied_iovec[seg]; int inc_to_page_index; + iv = (struct kvec *) &copied_iovec[seg]; + if (iv->iov_len < (PAGE_SIZE - to_page_offset)) { cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied); @@ -885,6 +887,7 @@ int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, int from_page_index = 0; void *from_kaddr = NULL; void *to_kaddr = NULL; + struct kvec *iv; struct iovec *copied_iovec = NULL; struct pvfs_bufmap_desc *from; unsigned int seg; @@ -930,9 +933,10 @@ int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, * but make sure that we do so one page at a time. */ while (amt_copied < size) { - struct iovec *iv = &copied_iovec[seg]; int inc_from_page_index; + iv = (struct kvec *) &copied_iovec[seg]; + if (iv->iov_len < (PAGE_SIZE - from_page_offset)) { cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied); diff --git a/fs/orangefs/pvfs2-debugfs.c b/fs/orangefs/pvfs2-debugfs.c index 8d118da9b88f..ba5bfef7a3f3 100644 --- a/fs/orangefs/pvfs2-debugfs.c +++ b/fs/orangefs/pvfs2-debugfs.c @@ -70,7 +70,7 @@ static const struct seq_operations help_debug_ops = { * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and * ORANGEFS_KMOD_DEBUG_FILE. */ -DEFINE_MUTEX(orangefs_debug_lock); +static DEFINE_MUTEX(orangefs_debug_lock); int orangefs_debug_open(struct inode *, struct file *); diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 6c787c4797d0..be30111b40d2 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -608,7 +608,7 @@ struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref); ssize_t pvfs2_inode_read(struct inode *inode, - char *buf, + char __user *buf, size_t count, loff_t *offset, loff_t readahead_size); diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c index 9cbc992731d6..69289c5d838c 100644 --- a/fs/orangefs/pvfs2-mod.c +++ b/fs/orangefs/pvfs2-mod.c @@ -47,7 +47,6 @@ struct client_debug_mask client_debug_mask = { NULL, 0, 0 }; unsigned int kernel_mask_set_mod_init; /* implicitly false */ int op_timeout_secs = PVFS2_DEFAULT_OP_TIMEOUT_SECS; int slot_timeout_secs = PVFS2_DEFAULT_SLOT_TIMEOUT_SECS; -__u32 DEBUG_LINE = 50; MODULE_LICENSE("GPL"); MODULE_AUTHOR("PVFS2 Development Team"); diff --git a/fs/orangefs/pvfs2-sysfs.c b/fs/orangefs/pvfs2-sysfs.c index 6d0e18b7239f..ea635b5e431b 100644 --- a/fs/orangefs/pvfs2-sysfs.c +++ b/fs/orangefs/pvfs2-sysfs.c @@ -750,7 +750,7 @@ static ssize_t int_store(struct orangefs_obj *orangefs_obj, /* * obtain attribute values from userspace with a service operation. */ -int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) +static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) { struct pvfs2_kernel_op_s *new_op = NULL; int rc = 0; @@ -1023,7 +1023,7 @@ static ssize_t * We want to return 1 if we think everything went OK, and * EINVAL if not. */ -int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) +static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) { struct pvfs2_kernel_op_s *new_op = NULL; int val = 0; diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index a854390fc0ea..90c7a1c9f201 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -269,7 +269,7 @@ static void pvfs2_dirty_inode(struct inode *inode, int flags) SetAtimeFlag(pvfs2_inode); } -struct super_operations pvfs2_s_ops = { +static const struct super_operations pvfs2_s_ops = { .alloc_inode = pvfs2_alloc_inode, .destroy_inode = pvfs2_destroy_inode, .dirty_inode = pvfs2_dirty_inode, @@ -279,7 +279,7 @@ struct super_operations pvfs2_s_ops = { .show_options = generic_show_options, }; -struct dentry *pvfs2_fh_to_dentry(struct super_block *sb, +static struct dentry *pvfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) @@ -299,7 +299,7 @@ struct dentry *pvfs2_fh_to_dentry(struct super_block *sb, return d_obtain_alias(pvfs2_iget(sb, &refn)); } -int pvfs2_encode_fh(struct inode *inode, +static int pvfs2_encode_fh(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent) @@ -347,7 +347,7 @@ static struct export_operations pvfs2_export_ops = { .fh_to_dentry = pvfs2_fh_to_dentry, }; -int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) +static int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) { int ret = -EINVAL; struct inode *root = NULL; diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 9b32286a7dc4..ad79e534dc8e 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -314,6 +314,13 @@ void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op) spin_unlock(&op->lock); gossip_err("interrupted operation is in a weird state 0x%x\n", op->op_state); + } else { + /* + * It is not intended for execution to flow here, + * but having this unlock here makes sparse happy. + */ + gossip_err("%s: can't get here.\n", __func__); + spin_unlock(&op->lock); } } -- GitLab From eeaa3d448c5d35ad0dc16a981aacd64139c53eee Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 29 Jul 2015 13:36:37 -0400 Subject: [PATCH 0010/5324] Orangefs: address problems found by static checker Don't check for negative rc from boolean. Don't pointlessly initialize variables, it short-circuits gcc's uninitialized variable warnings. And max_new_nr_segs can never be zero, so don't check for it. Preserve original kstrdup pointer for freeing later. Don't check for negative value in unsigned variable. Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 16 ---------------- fs/orangefs/file.c | 18 ++++++------------ fs/orangefs/pvfs2-utils.c | 4 +++- fs/orangefs/xattr.c | 6 ++---- 4 files changed, 11 insertions(+), 33 deletions(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 9b5f4bb17874..c126c0fc6e0f 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -104,7 +104,6 @@ static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap, * * \param dir_emit callback function called for each entry read. * - * \retval <0 on error * \retval 0 when directory has been completely traversed * \retval >0 if we don't call dir_emit for all entries * @@ -253,8 +252,6 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __func__, llu(pos)); ret = dir_emit(ctx, ".", 1, ino, DT_DIR); - if (ret < 0) - goto out_destroy_handle; ctx->pos++; gossip_ldebug(GOSSIP_DIR_DEBUG, "%s: ctx->pos:%lld\n", @@ -270,8 +267,6 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __func__, llu(pos)); ret = dir_emit(ctx, "..", 2, ino, DT_DIR); - if (ret < 0) - goto out_destroy_handle; ctx->pos++; gossip_ldebug(GOSSIP_DIR_DEBUG, "%s: ctx->pos:%lld\n", @@ -293,17 +288,6 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) (unsigned long)pos); ret = dir_emit(ctx, current_entry, len, current_ino, DT_UNKNOWN); - if (ret < 0) { - gossip_debug(GOSSIP_DIR_DEBUG, - "dir_emit() failed. ret:%d\n", - ret); - if (i < 2) { - gossip_err("dir_emit failed on one of the first two true PVFS directory entries.\n"); - gossip_err("Duplicate entries may appear.\n"); - } - buffer_full = 1; - break; - } ctx->pos++; gossip_ldebug(GOSSIP_DIR_DEBUG, "%s: ctx->pos:%lld\n", diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 4ba1b6c48aa7..013a07c8bdfd 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -463,12 +463,12 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, unsigned int to_free; size_t count; unsigned long seg; - unsigned long new_nr_segs = 0; - unsigned long max_new_nr_segs = 0; - unsigned long seg_count = 0; - unsigned long *seg_array = NULL; - struct iovec *iovecptr = NULL; - struct iovec *ptr = NULL; + unsigned long new_nr_segs; + unsigned long max_new_nr_segs; + unsigned long seg_count; + unsigned long *seg_array; + struct iovec *iovecptr; + struct iovec *ptr; total_count = 0; ret = -EINVAL; @@ -477,12 +477,6 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, /* Compute total and max number of segments after split */ max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count); - if (max_new_nr_segs < 0) { - gossip_lerr("%s: could not bound iovec %lu\n", - __func__, - max_new_nr_segs); - goto out; - } gossip_debug(GOSSIP_FILE_DEBUG, "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n", diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 107f425d2e90..8d4411ca118f 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -1077,6 +1077,7 @@ void debug_string_to_mask(char *debug_string, void *mask, int type) char *unchecked_keyword; int i; char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL); + char *original_pointer; int element_count = 0; struct client_debug_mask *c_mask; __u64 *k_mask; @@ -1092,6 +1093,7 @@ void debug_string_to_mask(char *debug_string, void *mask, int type) element_count = num_kmod_keyword_mask_map; } + original_pointer = strsep_fodder; while ((unchecked_keyword = strsep(&strsep_fodder, ","))) if (strlen(unchecked_keyword)) { for (i = 0; i < element_count; i++) @@ -1105,7 +1107,7 @@ void debug_string_to_mask(char *debug_string, void *mask, int type) &k_mask); } - kfree(strsep_fodder); + kfree(original_pointer); } void do_c_mask(int i, diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index 2766090f5ca4..227eaa47b1e1 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -77,10 +77,8 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, gossip_err("pvfs2_inode_getxattr: bogus NULL pointers\n"); return -EINVAL; } - if (size < 0 || - (strlen(name) + strlen(prefix)) >= PVFS_MAX_XATTR_NAMELEN) { - gossip_err("Invalid size (%d) or key length (%d)\n", - (int)size, + if ((strlen(name) + strlen(prefix)) >= PVFS_MAX_XATTR_NAMELEN) { + gossip_err("Invalid key length (%d)\n", (int)(strlen(name) + strlen(prefix))); return -EINVAL; } -- GitLab From c36316b74e0d98fdc5492104b5dd8bde697f0f81 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 30 Jul 2015 15:34:04 -0400 Subject: [PATCH 0011/5324] Orangefs: large integer implicitly truncated to unsigned type make.cross ARCH=tile doesn't like "inode->i_bytes = PAGE_CACHE_SIZE;", so cast PAGE_CACHE_SIZE to unsigned short. Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 8d4411ca118f..6eecb1861aca 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -163,7 +163,7 @@ static int copy_attributes_to_inode(struct inode *inode, /*FALLTHRU*/ default: pvfs2_lock_inode(inode); - inode->i_bytes = PAGE_CACHE_SIZE; + inode->i_bytes = (unsigned short)PAGE_CACHE_SIZE; inode->i_blocks = (unsigned long)(PAGE_CACHE_SIZE / 512); pvfs2_unlock_inode(inode); -- GitLab From f0566532fe19c7f75a3c0c908152ea0e24e6ead2 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 5 Aug 2015 13:46:28 -0400 Subject: [PATCH 0012/5324] Orangefs: use inode_set_bytes for directories Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-utils.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 6eecb1861aca..11ee073ecd19 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -162,12 +162,11 @@ static int copy_attributes_to_inode(struct inode *inode, } /*FALLTHRU*/ default: + inode->i_size = PAGE_CACHE_SIZE; + pvfs2_lock_inode(inode); - inode->i_bytes = (unsigned short)PAGE_CACHE_SIZE; - inode->i_blocks = (unsigned long)(PAGE_CACHE_SIZE / 512); + inode_set_bytes(inode, inode->i_size); pvfs2_unlock_inode(inode); - - inode->i_size = PAGE_CACHE_SIZE; break; } -- GitLab From cb987f3cbe3ced82496c802565b263844abfb0b9 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 3 Aug 2015 00:08:59 -0400 Subject: [PATCH 0013/5324] fs: orangefs: remove execute priviliges from module params This makes no sense and causes warnings on boot. Signed-off-by: Sasha Levin Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-mod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c index 69289c5d838c..d80537dadcd8 100644 --- a/fs/orangefs/pvfs2-mod.c +++ b/fs/orangefs/pvfs2-mod.c @@ -65,7 +65,7 @@ static struct file_system_type pvfs2_fs_type = { }; module_param(hash_table_size, int, 0); -module_param(module_parm_debug_mask, ulong, 0755); +module_param(module_parm_debug_mask, ulong, 0644); module_param(op_timeout_secs, int, 0); module_param(slot_timeout_secs, int, 0); -- GitLab From 81b784b11ea65c5c591f4d963daed2111a1b4280 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 1 Aug 2015 18:29:37 -0700 Subject: [PATCH 0014/5324] Orangefs: Swap order of include files spinlock_types.h requires types from linux/types.h. Including spinlock_types.h first may result in the following build errors, as seen with arm:allmodconfig. arch/arm/include/asm/spinlock_types.h:12:3: error: unknown type name 'u32' arch/arm/include/asm/spinlock_types.h:16:4: error: unknown type name 'u16' Fixes: deb4fb58ff73 ("Orangefs: kernel client part 2") Cc: Mark Brown Cc: Mike Marshall Signed-off-by: Guenter Roeck Signed-off-by: Mike Marshall --- fs/orangefs/protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index ca7cef9590d3..f571be21f66a 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -1,5 +1,5 @@ -#include #include +#include #include #include -- GitLab From 4d1c44043b26e99dd70f379cdbe80c64f43fd123 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 4 Sep 2015 10:31:16 -0400 Subject: [PATCH 0015/5324] Orangefs: use iov_iter interface replace opencoded pvfs_bufmap_copy_to_kernel_iovec, pvfs_bufmap_copy_to_user_iovec, pvfs_bufmap_copy_iovec_from_kernel, and pvfs_bufmap_copy_iovec_from_user with pvfs_bufmap_copy_to_iovec and pvfs_bufmap_copy_from_iovec, which both use the iov_iter interface. Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 77 +++--- fs/orangefs/pvfs2-bufmap.c | 474 +++---------------------------------- fs/orangefs/pvfs2-bufmap.h | 31 +-- 3 files changed, 72 insertions(+), 510 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 013a07c8bdfd..3e5fc1a2c82f 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -33,31 +33,30 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, int buffer_index, const struct iovec *vec, unsigned long nr_segs, - size_t total_size, - int from_user) + size_t total_size) { int ret = 0; + struct iov_iter iter; /* * copy data from application/kernel by pulling it out * of the iovec. */ - /* Are we copying from User Virtual Addresses? */ - if (from_user) - ret = pvfs_bufmap_copy_iovec_from_user( - bufmap, - buffer_index, - vec, - nr_segs, - total_size); - /* Are we copying from Kernel Virtual Addresses? */ - else - ret = pvfs_bufmap_copy_iovec_from_kernel( - bufmap, - buffer_index, - vec, - nr_segs, - total_size); + + + if (total_size) { + iov_iter_init(&iter, WRITE, vec, nr_segs, total_size); + ret = pvfs_bufmap_copy_from_iovec(bufmap, + &iter, + buffer_index, + total_size); + if (ret < 0) + gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", + __func__, + (long)ret); + + } + if (ret < 0) gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", __func__, @@ -76,35 +75,24 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, int buffer_index, const struct iovec *vec, int nr_segs, - size_t total_size, - int to_user) + size_t total_size) { int ret = 0; + struct iov_iter iter; + /* * copy data to application/kernel by pushing it out to * the iovec. NOTE; target buffers can be addresses or * struct page pointers. */ if (total_size) { - /* Are we copying to User Virtual Addresses? */ - if (to_user) - ret = pvfs_bufmap_copy_to_user_iovec( - bufmap, - buffer_index, - vec, - nr_segs, - total_size); - /* Are we copying to Kern Virtual Addresses? */ - else - ret = pvfs_bufmap_copy_to_kernel_iovec( - bufmap, - buffer_index, - vec, - nr_segs, - total_size); + iov_iter_init(&iter, READ, vec, nr_segs, total_size); + ret = pvfs_bufmap_copy_to_iovec(bufmap, + &iter, + buffer_index); if (ret < 0) - gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", + gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", __func__, (long)ret); } @@ -116,7 +104,7 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, */ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, loff_t *offset, struct iovec *vec, unsigned long nr_segs, - size_t total_size, loff_t readahead_size, int to_user) + size_t total_size, loff_t readahead_size) { struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; @@ -158,10 +146,9 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, new_op->upcall.req.io.offset = *offset; gossip_debug(GOSSIP_FILE_DEBUG, - "%s(%pU): copy_to_user %d nr_segs %lu, offset: %llu total_size: %zd\n", + "%s(%pU): nr_segs %lu, offset: %llu total_size: %zd\n", __func__, handle, - to_user, nr_segs, llu(*offset), total_size); @@ -174,8 +161,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, buffer_index, vec, nr_segs, - total_size, - to_user); + total_size); if (ret < 0) goto out; } @@ -239,8 +225,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, buffer_index, vec, nr_segs, - new_op->downcall.resp.io.amt_complete, - to_user); + new_op->downcall.resp.io.amt_complete); if (ret < 0) { /* * put error codes in downcall so that handle_io_error() @@ -606,7 +591,7 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, (int)*offset); ret = wait_for_direct_io(type, inode, offset, ptr, - seg_array[seg], each_count, 0, 1); + seg_array[seg], each_count, 0); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): return from wait_for_io:%d\n", __func__, @@ -699,7 +684,7 @@ ssize_t pvfs2_inode_read(struct inode *inode, llu(*offset)); ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &vec, 1, - count, readahead_size, 0); + count, readahead_size); if (ret > 0) *offset += ret; diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index a439163f8d7c..e01e220fd5d7 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -507,468 +507,60 @@ void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index) pvfs2_bufmap_unref(bufmap); } -/* - * pvfs_bufmap_copy_iovec_from_user() - * - * copies data from several user space address's in an iovec - * to a mapped buffer - * - * Note that the mapped buffer is a series of pages and therefore - * the copies have to be split by PAGE_SIZE bytes at a time. - * Note that this routine checks that summation of iov_len - * across all the elements of iov is equal to size. - * - * returns 0 on success, -errno on failure - */ -int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap, - int buffer_index, - const struct iovec *iov, - unsigned long nr_segs, - size_t size) +int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, + struct iov_iter *iter, + int buffer_index, + size_t size) { - size_t ret = 0; - size_t amt_copied = 0; - size_t cur_copy_size = 0; - unsigned int to_page_offset = 0; - unsigned int to_page_index = 0; - void *to_kaddr = NULL; - void __user *from_addr = NULL; - struct iovec *copied_iovec = NULL; struct pvfs_bufmap_desc *to; - unsigned int seg; - char *tmp_printer = NULL; - int tmp_int = 0; - - gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_copy_iovec_from_user: index %d, " - "size %zd\n", - buffer_index, - size); - - to = &bufmap->desc_array[buffer_index]; - - /* - * copy the passed in iovec so that we can change some of its fields - */ - copied_iovec = kmalloc_array(nr_segs, - sizeof(*copied_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (copied_iovec == NULL) - return -ENOMEM; - - memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); - /* - * Go through each segment in the iovec and make sure that - * the summation of iov_len matches the given size. - */ - for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) - amt_copied += copied_iovec[seg].iov_len; - if (amt_copied != size) { - gossip_err( - "pvfs2_bufmap_copy_iovec_from_user: computed total (" - "%zd) is not equal to (%zd)\n", - amt_copied, - size); - kfree(copied_iovec); - return -EINVAL; - } - - to_page_index = 0; - to_page_offset = 0; - amt_copied = 0; - seg = 0; - /* - * Go through each segment in the iovec and copy its - * buffer into the mapped buffer one page at a time though - */ - while (amt_copied < size) { - struct iovec *iv = &copied_iovec[seg]; - int inc_to_page_index; - - if (iv->iov_len < (PAGE_SIZE - to_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - from_addr = iv->iov_base; - inc_to_page_index = 0; - } else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - from_addr = iv->iov_base; - inc_to_page_index = 1; - } else { - cur_copy_size = - PVFS_util_min(PAGE_SIZE - to_page_offset, - size - amt_copied); - from_addr = iv->iov_base; - iv->iov_base += cur_copy_size; - iv->iov_len -= cur_copy_size; - inc_to_page_index = 1; - } - to_kaddr = pvfs2_kmap(to->page_array[to_page_index]); - ret = - copy_from_user(to_kaddr + to_page_offset, - from_addr, - cur_copy_size); - if (!PageReserved(to->page_array[to_page_index])) - SetPageDirty(to->page_array[to_page_index]); - - if (!tmp_printer) { - tmp_printer = (char *)(to_kaddr + to_page_offset); - tmp_int += tmp_printer[0]; - gossip_debug(GOSSIP_BUFMAP_DEBUG, - "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n", - tmp_int); - } - - pvfs2_kunmap(to->page_array[to_page_index]); - if (ret) { - gossip_err("Failed to copy data from user space\n"); - kfree(copied_iovec); - return -EFAULT; - } - - amt_copied += cur_copy_size; - if (inc_to_page_index) { - to_page_offset = 0; - to_page_index++; - } else { - to_page_offset += cur_copy_size; - } - } - kfree(copied_iovec); - return 0; -} - -/* - * pvfs_bufmap_copy_iovec_from_kernel() - * - * copies data from several kernel space address's in an iovec - * to a mapped buffer - * - * Note that the mapped buffer is a series of pages and therefore - * the copies have to be split by PAGE_SIZE bytes at a time. - * Note that this routine checks that summation of iov_len - * across all the elements of iov is equal to size. - * - * returns 0 on success, -errno on failure - */ -int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, - int buffer_index, const struct iovec *iov, - unsigned long nr_segs, size_t size) -{ - size_t amt_copied = 0; - size_t cur_copy_size = 0; - int to_page_index = 0; - void *to_kaddr = NULL; - void *from_kaddr = NULL; - struct kvec *iv = NULL; - struct iovec *copied_iovec = NULL; - struct pvfs_bufmap_desc *to; - unsigned int seg; - unsigned to_page_offset = 0; + struct page *page; + size_t copied; + int i; gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_copy_iovec_from_kernel: index %d, " - "size %zd\n", - buffer_index, - size); + "%s: buffer_index:%d: size:%lu:\n", + __func__, buffer_index, size); to = &bufmap->desc_array[buffer_index]; - /* - * copy the passed in iovec so that we can change some of its fields - */ - copied_iovec = kmalloc_array(nr_segs, - sizeof(*copied_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (copied_iovec == NULL) - return -ENOMEM; - - memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); - /* - * Go through each segment in the iovec and make sure that - * the summation of iov_len matches the given size. - */ - for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) - amt_copied += copied_iovec[seg].iov_len; - if (amt_copied != size) { - gossip_err("pvfs2_bufmap_copy_iovec_from_kernel: computed total(%zd) is not equal to (%zd)\n", - amt_copied, - size); - kfree(copied_iovec); - return -EINVAL; - } - to_page_index = 0; - amt_copied = 0; - seg = 0; - to_page_offset = 0; - /* - * Go through each segment in the iovec and copy its - * buffer into the mapped buffer one page at a time though - */ - while (amt_copied < size) { - int inc_to_page_index; - - iv = (struct kvec *) &copied_iovec[seg]; - - if (iv->iov_len < (PAGE_SIZE - to_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - from_kaddr = iv->iov_base; - inc_to_page_index = 0; - } else if (iv->iov_len == (PAGE_SIZE - to_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - from_kaddr = iv->iov_base; - inc_to_page_index = 1; - } else { - cur_copy_size = - PVFS_util_min(PAGE_SIZE - to_page_offset, - size - amt_copied); - from_kaddr = iv->iov_base; - iv->iov_base += cur_copy_size; - iv->iov_len -= cur_copy_size; - inc_to_page_index = 1; - } - to_kaddr = pvfs2_kmap(to->page_array[to_page_index]); - memcpy(to_kaddr + to_page_offset, from_kaddr, cur_copy_size); - if (!PageReserved(to->page_array[to_page_index])) - SetPageDirty(to->page_array[to_page_index]); - pvfs2_kunmap(to->page_array[to_page_index]); - amt_copied += cur_copy_size; - if (inc_to_page_index) { - to_page_offset = 0; - to_page_index++; - } else { - to_page_offset += cur_copy_size; - } - } - kfree(copied_iovec); - return 0; -} - -/* - * pvfs_bufmap_copy_to_user_iovec() - * - * copies data to several user space address's in an iovec - * from a mapped buffer - * - * returns 0 on success, -errno on failure - */ -int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap, - int buffer_index, const struct iovec *iov, - unsigned long nr_segs, size_t size) -{ - size_t ret = 0; - size_t amt_copied = 0; - size_t cur_copy_size = 0; - int from_page_index = 0; - void *from_kaddr = NULL; - void __user *to_addr = NULL; - struct iovec *copied_iovec = NULL; - struct pvfs_bufmap_desc *from; - unsigned int seg; - unsigned from_page_offset = 0; - char *tmp_printer = NULL; - int tmp_int = 0; - - gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_copy_to_user_iovec: index %d, size %zd\n", - buffer_index, - size); - - from = &bufmap->desc_array[buffer_index]; - /* - * copy the passed in iovec so that we can change some of its fields - */ - copied_iovec = kmalloc_array(nr_segs, - sizeof(*copied_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (copied_iovec == NULL) - return -ENOMEM; - - memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); - /* - * Go through each segment in the iovec and make sure that - * the summation of iov_len is greater than the given size. - */ - for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) - amt_copied += copied_iovec[seg].iov_len; - if (amt_copied < size) { - gossip_err("pvfs2_bufmap_copy_to_user_iovec: computed total (%zd) is less than (%zd)\n", - amt_copied, - size); - kfree(copied_iovec); - return -EINVAL; + for (i = 0; size; i++) { + page = to->page_array[i]; + copied = copy_page_from_iter(page, 0, PAGE_SIZE, iter); + size -= copied; + if ((copied == 0) && (size)) + break; } - from_page_index = 0; - amt_copied = 0; - seg = 0; - from_page_offset = 0; - /* - * Go through each segment in the iovec and copy from the mapper buffer, - * but make sure that we do so one page at a time. - */ - while (amt_copied < size) { - struct iovec *iv = &copied_iovec[seg]; - int inc_from_page_index; - - if (iv->iov_len < (PAGE_SIZE - from_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - to_addr = iv->iov_base; - inc_from_page_index = 0; - } else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - to_addr = iv->iov_base; - inc_from_page_index = 1; - } else { - cur_copy_size = - PVFS_util_min(PAGE_SIZE - from_page_offset, - size - amt_copied); - to_addr = iv->iov_base; - iv->iov_base += cur_copy_size; - iv->iov_len -= cur_copy_size; - inc_from_page_index = 1; - } - from_kaddr = pvfs2_kmap(from->page_array[from_page_index]); - if (!tmp_printer) { - tmp_printer = (char *)(from_kaddr + from_page_offset); - tmp_int += tmp_printer[0]; - gossip_debug(GOSSIP_BUFMAP_DEBUG, - "First character (integer value) in pvfs_bufmap_copy_to_user_iovec: %d\n", - tmp_int); - } - ret = - copy_to_user(to_addr, - from_kaddr + from_page_offset, - cur_copy_size); - pvfs2_kunmap(from->page_array[from_page_index]); - if (ret) { - gossip_err("Failed to copy data to user space\n"); - kfree(copied_iovec); - return -EFAULT; - } + return size ? -EFAULT : 0; - amt_copied += cur_copy_size; - if (inc_from_page_index) { - from_page_offset = 0; - from_page_index++; - } else { - from_page_offset += cur_copy_size; - } - } - kfree(copied_iovec); - return 0; } /* - * pvfs_bufmap_copy_to_kernel_iovec() + * Iterate through the array of pages containing the bytes from + * a file being read. * - * copies data to several kernel space address's in an iovec - * from a mapped buffer - * - * returns 0 on success, -errno on failure */ -int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, - int buffer_index, const struct iovec *iov, - unsigned long nr_segs, size_t size) +int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, + struct iov_iter *iter, + int buffer_index) { - size_t amt_copied = 0; - size_t cur_copy_size = 0; - int from_page_index = 0; - void *from_kaddr = NULL; - void *to_kaddr = NULL; - struct kvec *iv; - struct iovec *copied_iovec = NULL; struct pvfs_bufmap_desc *from; - unsigned int seg; - unsigned int from_page_offset = 0; + struct page *page; + int i; + size_t written; gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_copy_to_kernel_iovec: index %d, size %zd\n", - buffer_index, - size); + "%s: buffer_index:%d: iov_iter_count(iter):%lu:\n", + __func__, buffer_index, iov_iter_count(iter)); - from = &bufmap->desc_array[buffer_index]; - /* - * copy the passed in iovec so that we can change some of its fields - */ - copied_iovec = kmalloc_array(nr_segs, - sizeof(*copied_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (copied_iovec == NULL) - return -ENOMEM; + from = &bufmap->desc_array[buffer_index]; - memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec)); - /* - * Go through each segment in the iovec and make sure that - * the summation of iov_len is greater than the given size. - */ - for (seg = 0, amt_copied = 0; seg < nr_segs; seg++) - amt_copied += copied_iovec[seg].iov_len; - - if (amt_copied < size) { - gossip_err("pvfs2_bufmap_copy_to_kernel_iovec: computed total (%zd) is less than (%zd)\n", - amt_copied, - size); - kfree(copied_iovec); - return -EINVAL; + for (i = 0; iov_iter_count(iter); i++) { + page = from->page_array[i]; + written = copy_page_to_iter(page, 0, PAGE_SIZE, iter); + if ((written == 0) && (iov_iter_count(iter))) + break; } - from_page_index = 0; - amt_copied = 0; - seg = 0; - from_page_offset = 0; - /* - * Go through each segment in the iovec and copy from the mapper buffer, - * but make sure that we do so one page at a time. - */ - while (amt_copied < size) { - int inc_from_page_index; - - iv = (struct kvec *) &copied_iovec[seg]; - - if (iv->iov_len < (PAGE_SIZE - from_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - to_kaddr = iv->iov_base; - inc_from_page_index = 0; - } else if (iv->iov_len == (PAGE_SIZE - from_page_offset)) { - cur_copy_size = - PVFS_util_min(iv->iov_len, size - amt_copied); - seg++; - to_kaddr = iv->iov_base; - inc_from_page_index = 1; - } else { - cur_copy_size = - PVFS_util_min(PAGE_SIZE - from_page_offset, - size - amt_copied); - to_kaddr = iv->iov_base; - iv->iov_base += cur_copy_size; - iv->iov_len -= cur_copy_size; - inc_from_page_index = 1; - } - from_kaddr = pvfs2_kmap(from->page_array[from_page_index]); - memcpy(to_kaddr, from_kaddr + from_page_offset, cur_copy_size); - pvfs2_kunmap(from->page_array[from_page_index]); - amt_copied += cur_copy_size; - if (inc_from_page_index) { - from_page_offset = 0; - from_page_index++; - } else { - from_page_offset += cur_copy_size; - } - } - kfree(copied_iovec); - return 0; + return iov_iter_count(iter) ? -EFAULT : 0; } diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/pvfs2-bufmap.h index e269deafbb74..a0f84c045d73 100644 --- a/fs/orangefs/pvfs2-bufmap.h +++ b/fs/orangefs/pvfs2-bufmap.h @@ -42,29 +42,14 @@ int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index); void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index); -int pvfs_bufmap_copy_iovec_from_user(struct pvfs2_bufmap *bufmap, - int buffer_index, - const struct iovec *iov, - unsigned long nr_segs, - size_t size); - -int pvfs_bufmap_copy_iovec_from_kernel(struct pvfs2_bufmap *bufmap, - int buffer_index, - const struct iovec *iov, - unsigned long nr_segs, - size_t size); - -int pvfs_bufmap_copy_to_user_iovec(struct pvfs2_bufmap *bufmap, - int buffer_index, - const struct iovec *iov, - unsigned long nr_segs, - size_t size); - -int pvfs_bufmap_copy_to_kernel_iovec(struct pvfs2_bufmap *bufmap, - int buffer_index, - const struct iovec *iov, - unsigned long nr_segs, - size_t size); +int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, + struct iov_iter *iter, + int buffer_index, + size_t size); + +int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, + struct iov_iter *iter, + int buffer_index); size_t pvfs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk, struct iovec *iovec, -- GitLab From 88309aae3ddb62e6d02a8f1002a4f4fc41b423ad Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 23 Sep 2015 16:48:40 -0400 Subject: [PATCH 0016/5324] Orangefs: fix dir_emit code in pvfs2_readdir. Al Viro glanced at readdir and surmised that getdents would misbehave the way it was written... and sure enough. Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 131 +++++++++++++++-------------------------- fs/orangefs/protocol.h | 1 + 2 files changed, 50 insertions(+), 82 deletions(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index c126c0fc6e0f..3870e78f5ecf 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -95,26 +95,16 @@ static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap, /* * Read directory entries from an instance of an open directory. - * - * \note This routine was converted for the readdir to iterate change - * in "struct file_operations". "converted" mostly amounts to - * changing occurrences of "readdir" and "filldir" in the - * comments to "iterate" and "dir_emit". Also filldir calls - * were changed to dir_emit calls. - * - * \param dir_emit callback function called for each entry read. - * - * \retval 0 when directory has been completely traversed - * \retval >0 if we don't call dir_emit for all entries - * - * \note If the dir_emit call-back returns non-zero, then iterate should - * assume that it has had enough, and should return as well. */ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) { struct pvfs2_bufmap *bufmap = NULL; int ret = 0; int buffer_index; + /* + * ptoken supports Orangefs' distributed directory logic, added + * in 2.9.2. + */ __u64 *ptoken = file->private_data; __u64 pos = 0; ino_t ino = 0; @@ -129,11 +119,11 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) char *current_entry = NULL; long bytes_decoded; - gossip_ldebug(GOSSIP_DIR_DEBUG, - "%s: ctx->pos:%lld, token = %llu\n", - __func__, - lld(ctx->pos), - llu(*ptoken)); + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: ctx->pos:%lld, ptoken = %llu\n", + __func__, + lld(ctx->pos), + llu(*ptoken)); pos = (__u64) ctx->pos; @@ -165,16 +155,6 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __func__, &new_op->upcall.req.readdir.refn.khandle); - /* - * NOTE: the position we send to the readdir upcall is out of - * sync with ctx->pos since: - * 1. pvfs2 doesn't include the "." and ".." entries that are - * added below. - * 2. the introduction of distributed directory logic makes token no - * longer be related to f_pos and pos. Instead an independent - * variable is used inside the function and stored in the - * private_data of the file structure. - */ new_op->upcall.req.readdir.token = *ptoken; get_new_buffer_index: @@ -238,13 +218,18 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) } if (bytes_decoded != new_op->downcall.trailer_size) { - gossip_err("pvfs2_readdir: # bytes decoded (%ld) != trailer size (%ld)\n", - bytes_decoded, - (long)new_op->downcall.trailer_size); + gossip_err("pvfs2_readdir: # bytes decoded (%ld) " + "!= trailer size (%ld)\n", + bytes_decoded, + (long)new_op->downcall.trailer_size); ret = -EINVAL; goto out_destroy_handle; } + /* + * pvfs2 doesn't actually store dot and dot-dot, but + * we need to have them represented. + */ if (pos == 0) { ino = get_ino_from_khandle(dentry->d_inode); gossip_debug(GOSSIP_DIR_DEBUG, @@ -252,12 +237,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __func__, llu(pos)); ret = dir_emit(ctx, ".", 1, ino, DT_DIR); - ctx->pos++; - gossip_ldebug(GOSSIP_DIR_DEBUG, - "%s: ctx->pos:%lld\n", - __func__, - lld(ctx->pos)); - pos++; + pos += 1; } if (pos == 1) { @@ -267,62 +247,55 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __func__, llu(pos)); ret = dir_emit(ctx, "..", 2, ino, DT_DIR); - ctx->pos++; - gossip_ldebug(GOSSIP_DIR_DEBUG, - "%s: ctx->pos:%lld\n", - __func__, - lld(ctx->pos)); - pos++; + pos += 1; } - for (i = 0; i < rhandle.readdir_response.pvfs_dirent_outcount; i++) { + /* + * we stored PVFS_ITERATE_NEXT in ctx->pos last time around + * to prevent "finding" dot and dot-dot on any iteration + * other than the first. + */ + if (ctx->pos == PVFS_ITERATE_NEXT) + ctx->pos = 0; + + for (i = ctx->pos; + i < rhandle.readdir_response.pvfs_dirent_outcount; + i++) { len = rhandle.readdir_response.dirent_array[i].d_length; current_entry = rhandle.readdir_response.dirent_array[i].d_name; current_ino = pvfs2_khandle_to_ino( &(rhandle.readdir_response.dirent_array[i].khandle)); gossip_debug(GOSSIP_DIR_DEBUG, - "calling dir_emit for %s with len %d, pos %ld\n", + "calling dir_emit for %s with len %d" + ", ctx->pos %ld\n", current_entry, len, - (unsigned long)pos); + (unsigned long)ctx->pos); + /* + * type is unknown. We don't return object type + * in the dirent_array. This leaves getdents + * clueless about type. + */ ret = dir_emit(ctx, current_entry, len, current_ino, DT_UNKNOWN); + if (!ret) + break; ctx->pos++; - gossip_ldebug(GOSSIP_DIR_DEBUG, + gossip_debug(GOSSIP_DIR_DEBUG, "%s: ctx->pos:%lld\n", __func__, lld(ctx->pos)); - pos++; } - /* this means that all of the dir_emit calls succeeded */ - if (i == rhandle.readdir_response.pvfs_dirent_outcount) { - /* update token */ + /* + * we ran all the way through the last batch, set up for + * getting another batch... + */ + if (ret) { *ptoken = rhandle.readdir_response.token; - } else { - /* this means a dir_emit call failed */ - if (rhandle.readdir_response.token == PVFS_READDIR_END) { - /* - * If PVFS hit end of directory, then there - * is no way to do math on the token that it - * returned. Instead we go by ctx->pos but - * back up to account for the artificial . - * and .. entries. - */ - ctx->pos -= 3; - } else { - /* - * this means a dir_emit call failed. !!! need to set - * back to previous ctx->pos, no middle value allowed - */ - pos -= (i - 1); - ctx->pos -= (i - 1); - } - gossip_debug(GOSSIP_DIR_DEBUG, - "at least one dir_emit call failed. Setting ctx->pos to: %lld\n", - lld(ctx->pos)); + ctx->pos = PVFS_ITERATE_NEXT; } /* @@ -330,17 +303,11 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) */ if (rhandle.readdir_response.token == PVFS_READDIR_END && !buffer_full) { - gossip_debug(GOSSIP_DIR_DEBUG, "End of dir detected; setting ctx->pos to PVFS_READDIR_END.\n"); + gossip_debug(GOSSIP_DIR_DEBUG, + "End of dir detected; setting ctx->pos to PVFS_READDIR_END.\n"); ctx->pos = PVFS_READDIR_END; } - gossip_debug(GOSSIP_DIR_DEBUG, - "pos = %llu, token = %llu" - ", ctx->pos should have been %lld\n", - llu(pos), - llu(*ptoken), - lld(ctx->pos)); - out_destroy_handle: readdir_handle_dtor(bufmap, &rhandle); out_free_op: diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index f571be21f66a..cae9cc0f9d18 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -384,6 +384,7 @@ DECLARE_ERRNO_MAPPING() #define INT32_MAX (2147483647) #define PVFS_ITERATE_START (INT32_MAX - 1) #define PVFS_ITERATE_END (INT32_MAX - 2) +#define PVFS_ITERATE_NEXT (INT32_MAX - 3) #define PVFS_READDIR_START PVFS_ITERATE_START #define PVFS_READDIR_END PVFS_ITERATE_END #define PVFS_IMMUTABLE_FL FS_IMMUTABLE_FL -- GitLab From d6fe654b7b580720fee632c8d526c6a159111d50 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 24 Sep 2015 12:38:38 -0400 Subject: [PATCH 0017/5324] Orangefs: put PVFS_util_min out of its misery. Signed-off-by: Mike Marshall --- fs/orangefs/protocol.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index cae9cc0f9d18..c50c6e30f5a8 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -572,7 +572,6 @@ struct dev_mask2_info_s { }; /* pvfs2-util.h *************************************************************/ -#define PVFS_util_min(x1, x2) (((x1) > (x2)) ? (x2) : (x1)) __s32 PVFS_util_translate_mode(int mode); /* pvfs2-debug.h ************************************************************/ -- GitLab From f957ae2dec09b63b44df9ec06765cbdc52666eec Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 24 Sep 2015 12:53:05 -0400 Subject: [PATCH 0018/5324] Orangefs: choose return codes from among the expected ones. Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 2 +- fs/orangefs/namei.c | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 3e5fc1a2c82f..53e58c3f2121 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -973,7 +973,7 @@ static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) */ static int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) { - int rc = -ENOLCK; + int rc = -EINVAL; if (PVFS2_SB(filp->f_inode->i_sb)->flags & PVFS2_OPT_LOCAL_LOCK) { if (cmd == F_GETLK) { diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 747fe6a690af..05f6feadfd0d 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -243,28 +243,24 @@ static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) } /* - * pvfs2_link() is only implemented here to make sure that we return a - * reasonable error code (the kernel will return a misleading EPERM - * otherwise). PVFS2 does not support hard links. + * PVFS2 does not support hard links. */ static int pvfs2_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { - return -EOPNOTSUPP; + return -EPERM; } /* - * pvfs2_mknod() is only implemented here to make sure that we return a - * reasonable error code (the kernel will return a misleading EPERM - * otherwise). PVFS2 does not support special files such as fifos or devices. + * PVFS2 does not support special files. */ static int pvfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { - return -EOPNOTSUPP; + return -EPERM; } static int pvfs2_symlink(struct inode *dir, -- GitLab From 50e01586f4b10dc7aa534bbfcd1707586e7b32e0 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Tue, 29 Sep 2015 11:17:26 -0400 Subject: [PATCH 0019/5324] Orangefs: Don't opencode memcpy. Signed-off-by: Mike Marshall --- fs/orangefs/protocol.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index c50c6e30f5a8..cdbde64f8e39 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -70,30 +70,21 @@ static inline int PVFS_khandle_cmp(const struct pvfs2_khandle *kh1, return 0; } -/* copy a khandle to a field of arbitrary size */ static inline void PVFS_khandle_to(const struct pvfs2_khandle *kh, void *p, int size) { - int i; - unsigned char *c = p; memset(p, 0, size); + memcpy(p, kh->u, 16); - for (i = 0; i < 16 && i < size; i++) - c[i] = kh->u[i]; } -/* copy a khandle from a field of arbitrary size */ static inline void PVFS_khandle_from(struct pvfs2_khandle *kh, void *p, int size) { - int i; - unsigned char *c = p; - memset(kh, 0, 16); + memcpy(kh->u, p, 16); - for (i = 0; i < 16 && i < size; i++) - kh->u[i] = c[i]; } /* pvfs2-types.h ************************************************************/ -- GitLab From 8c3905adea92c79e32b02120c724dfd4cf84dd85 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Tue, 29 Sep 2015 12:07:46 -0400 Subject: [PATCH 0020/5324] Orangefs: update signal blocking code before Oleg sees it. Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-kernel.h | 4 ++-- fs/orangefs/pvfs2-utils.c | 41 ++++++++++++++------------------------ fs/orangefs/waitqueue.c | 6 +++--- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index be30111b40d2..299b48c37cab 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -649,9 +649,9 @@ void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op); void pvfs2_make_bad_inode(struct inode *inode); -void mask_blocked_signals(sigset_t *orig_sigset); +void block_signals(sigset_t *); -void unmask_blocked_signals(sigset_t *orig_sigset); +void set_signals(sigset_t *); int pvfs2_unmount_sb(struct super_block *sb); diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 11ee073ecd19..834e06674d0a 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -632,36 +632,25 @@ void pvfs2_make_bad_inode(struct inode *inode) } } -/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigmask */ -void mask_blocked_signals(sigset_t *orig_sigset) +/* Block all blockable signals... */ +void block_signals(sigset_t *orig_sigset) { - unsigned long sigallow = sigmask(SIGKILL); - unsigned long irqflags = 0; - struct k_sigaction *action = pvfs2_current_sigaction; - - sigallow |= ((action[SIGINT - 1].sa.sa_handler == SIG_DFL) ? - sigmask(SIGINT) : - 0); - sigallow |= ((action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) ? - sigmask(SIGQUIT) : - 0); - - spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags); - *orig_sigset = current->blocked; - siginitsetinv(¤t->blocked, sigallow & ~orig_sigset->sig[0]); - recalc_sigpending(); - spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags); + sigset_t mask; + + /* + * Initialize all entries in the signal set to the + * inverse of the given mask. + */ + siginitsetinv(&mask, sigmask(SIGKILL)); + + /* Block 'em Danno... */ + sigprocmask(SIG_BLOCK, &mask, orig_sigset); } -/* this code is based on linux/net/sunrpc/clnt.c:rpc_clnt_sigunmask */ -void unmask_blocked_signals(sigset_t *orig_sigset) +/* set the signal mask to the given template... */ +void set_signals(sigset_t *sigset) { - unsigned long irqflags = 0; - - spin_lock_irqsave(&pvfs2_current_signal_lock, irqflags); - current->blocked = *orig_sigset; - recalc_sigpending(); - spin_unlock_irqrestore(&pvfs2_current_signal_lock, irqflags); + sigprocmask(SIG_SETMASK, sigset, NULL); } __u64 pvfs2_convert_time_field(void *time_ptr) diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index ad79e534dc8e..d7b0eba043ab 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -80,7 +80,7 @@ int service_operation(struct pvfs2_kernel_op_s *op, /* mask out signals if this operation is not to be interrupted */ if (!(flags & PVFS2_OP_INTERRUPTIBLE)) - mask_blocked_signals(&orig_sigset); + block_signals(&orig_sigset); if (!(flags & PVFS2_OP_NO_SEMAPHORE)) { ret = mutex_lock_interruptible(&request_mutex); @@ -90,7 +90,7 @@ int service_operation(struct pvfs2_kernel_op_s *op, */ if (ret < 0) { if (!(flags & PVFS2_OP_INTERRUPTIBLE)) - unmask_blocked_signals(&orig_sigset); + set_signals(&orig_sigset); op->downcall.status = ret; gossip_debug(GOSSIP_WAIT_DEBUG, "pvfs2: service_operation interrupted.\n"); @@ -160,7 +160,7 @@ int service_operation(struct pvfs2_kernel_op_s *op, } if (!(flags & PVFS2_OP_INTERRUPTIBLE)) - unmask_blocked_signals(&orig_sigset); + set_signals(&orig_sigset); BUG_ON(ret != op->downcall.status); /* retry if operation has not been serviced and if requested */ -- GitLab From 1be21f865aa5a94b178bf22e749567001cf5ef9b Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Tue, 29 Sep 2015 15:26:37 -0400 Subject: [PATCH 0021/5324] Orangefs: don't use mount_nodev, use sget directly. Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 90c7a1c9f201..9dee95293599 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -422,7 +422,7 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, struct super_block *sb = ERR_PTR(-EINVAL); struct pvfs2_kernel_op_s *new_op; struct pvfs2_mount_sb_info_s mount_sb_info; - struct dentry *mnt_sb_d = ERR_PTR(-EINVAL); + struct dentry *d = ERR_PTR(-EINVAL); gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_mount: called with devname %s\n", @@ -464,23 +464,21 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, mount_sb_info.fs_id = new_op->downcall.resp.fs_mount.fs_id; mount_sb_info.id = new_op->downcall.resp.fs_mount.id; - /* - * the mount_sb_info structure looks odd, but it's used because - * the private sb info isn't allocated until we call - * pvfs2_fill_sb, yet we have the info we need to fill it with - * here. so we store it temporarily and pass all of the info - * to fill_sb where it's properly copied out - */ - mnt_sb_d = mount_nodev(fst, - flags, - (void *)&mount_sb_info, - pvfs2_fill_sb); - if (IS_ERR(mnt_sb_d)) { - sb = ERR_CAST(mnt_sb_d); + sb = sget(fst, NULL, set_anon_super, flags, NULL); + + if (IS_ERR(sb)) { + d = ERR_CAST(sb); goto free_op; } - sb = mnt_sb_d->d_sb; + ret = pvfs2_fill_sb(sb, + (void *)&mount_sb_info, + flags & MS_SILENT ? 1 : 0); + + if (ret) { + d = ERR_PTR(ret); + goto free_op; + } /* * on successful mount, store the devname and data @@ -499,7 +497,7 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, */ add_pvfs2_sb(sb); op_release(new_op); - return mnt_sb_d; + return dget(sb->s_root); free_op: gossip_err("pvfs2_mount: mount request failed with %d\n", ret); @@ -510,10 +508,7 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, op_release(new_op); - gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_mount: returning dentry %p\n", - mnt_sb_d); - return mnt_sb_d; + return d; } void pvfs2_kill_sb(struct super_block *sb) -- GitLab From 353908035f699bc6b769c4cd351c3125553d63c1 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Wed, 30 Sep 2015 13:11:54 -0400 Subject: [PATCH 0022/5324] Orangefs: Use readonly mmap since writepage is not implemented. Previously the code silently failed to update the disk. Now it will not allow writable and shared mmaps. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 53e58c3f2121..87f718163d1b 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -853,7 +853,9 @@ static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma) /* set the sequential readahead hint */ vma->vm_flags |= VM_SEQ_READ; vma->vm_flags &= ~VM_RAND_READ; - return generic_file_mmap(file, vma); + + /* Use readonly mmap since we cannot support writable maps. */ + return generic_file_readonly_mmap(file, vma); } #define mapping_nrpages(idata) ((idata)->nrpages) -- GitLab From 894ac432b48bb64fabae31fd2f373b2b8659350f Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Fri, 2 Oct 2015 12:11:19 -0400 Subject: [PATCH 0023/5324] Orangefs: Clean up error decoding. Errors from the server need to be decoded. A bunch of code was imported from the server to do this but much of it is convoluted and not even needed. The result is better but still as convoluted as required by the protocol. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/protocol.h | 286 +++++--------------------------------- fs/orangefs/pvfs2-utils.c | 58 ++++++-- 2 files changed, 80 insertions(+), 264 deletions(-) diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index cdbde64f8e39..b374c4b2009e 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -100,262 +100,40 @@ typedef __s32 PVFS_error; typedef __s64 PVFS_offset; #define PVFS2_SUPER_MAGIC 0x20030528 -#define PVFS_ERROR_BIT (1 << 30) -#define PVFS_NON_ERRNO_ERROR_BIT (1 << 29) -#define IS_PVFS_ERROR(__error) ((__error)&(PVFS_ERROR_BIT)) -#define IS_PVFS_NON_ERRNO_ERROR(__error) \ -(((__error)&(PVFS_NON_ERRNO_ERROR_BIT)) && IS_PVFS_ERROR(__error)) -#define PVFS_ERROR_TO_ERRNO(__error) PVFS_get_errno_mapping(__error) - -/* 7 bits are used for the errno mapped error codes */ -#define PVFS_ERROR_CODE(__error) \ -((__error) & (__s32)(0x7f|PVFS_ERROR_BIT)) -#define PVFS_ERROR_CLASS(__error) \ -((__error) & ~((__s32)(0x7f|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT))) -#define PVFS_NON_ERRNO_ERROR_CODE(__error) \ -((__error) & (__s32)(127|PVFS_ERROR_BIT|PVFS_NON_ERRNO_ERROR_BIT)) - -/* PVFS2 error codes, compliments of asm/errno.h */ -#define PVFS_EPERM E(1) /* Operation not permitted */ -#define PVFS_ENOENT E(2) /* No such file or directory */ -#define PVFS_EINTR E(3) /* Interrupted system call */ -#define PVFS_EIO E(4) /* I/O error */ -#define PVFS_ENXIO E(5) /* No such device or address */ -#define PVFS_EBADF E(6) /* Bad file number */ -#define PVFS_EAGAIN E(7) /* Try again */ -#define PVFS_ENOMEM E(8) /* Out of memory */ -#define PVFS_EFAULT E(9) /* Bad address */ -#define PVFS_EBUSY E(10) /* Device or resource busy */ -#define PVFS_EEXIST E(11) /* File exists */ -#define PVFS_ENODEV E(12) /* No such device */ -#define PVFS_ENOTDIR E(13) /* Not a directory */ -#define PVFS_EISDIR E(14) /* Is a directory */ -#define PVFS_EINVAL E(15) /* Invalid argument */ -#define PVFS_EMFILE E(16) /* Too many open files */ -#define PVFS_EFBIG E(17) /* File too large */ -#define PVFS_ENOSPC E(18) /* No space left on device */ -#define PVFS_EROFS E(19) /* Read-only file system */ -#define PVFS_EMLINK E(20) /* Too many links */ -#define PVFS_EPIPE E(21) /* Broken pipe */ -#define PVFS_EDEADLK E(22) /* Resource deadlock would occur */ -#define PVFS_ENAMETOOLONG E(23) /* File name too long */ -#define PVFS_ENOLCK E(24) /* No record locks available */ -#define PVFS_ENOSYS E(25) /* Function not implemented */ -#define PVFS_ENOTEMPTY E(26) /* Directory not empty */ - /* -#define PVFS_ELOOP E(27) * Too many symbolic links encountered - */ -#define PVFS_EWOULDBLOCK E(28) /* Operation would block */ -#define PVFS_ENOMSG E(29) /* No message of desired type */ -#define PVFS_EUNATCH E(30) /* Protocol driver not attached */ -#define PVFS_EBADR E(31) /* Invalid request descriptor */ -#define PVFS_EDEADLOCK E(32) -#define PVFS_ENODATA E(33) /* No data available */ -#define PVFS_ETIME E(34) /* Timer expired */ -#define PVFS_ENONET E(35) /* Machine is not on the network */ -#define PVFS_EREMOTE E(36) /* Object is remote */ -#define PVFS_ECOMM E(37) /* Communication error on send */ -#define PVFS_EPROTO E(38) /* Protocol error */ -#define PVFS_EBADMSG E(39) /* Not a data message */ - /* -#define PVFS_EOVERFLOW E(40) * Value too large for defined data - * type - */ - /* -#define PVFS_ERESTART E(41) * Interrupted system call should be - * restarted - */ -#define PVFS_EMSGSIZE E(42) /* Message too long */ -#define PVFS_EPROTOTYPE E(43) /* Protocol wrong type for socket */ -#define PVFS_ENOPROTOOPT E(44) /* Protocol not available */ -#define PVFS_EPROTONOSUPPORT E(45) /* Protocol not supported */ - /* -#define PVFS_EOPNOTSUPP E(46) * Operation not supported on transport - * endpoint - */ -#define PVFS_EADDRINUSE E(47) /* Address already in use */ -#define PVFS_EADDRNOTAVAIL E(48) /* Cannot assign requested address */ -#define PVFS_ENETDOWN E(49) /* Network is down */ -#define PVFS_ENETUNREACH E(50) /* Network is unreachable */ - /* -#define PVFS_ENETRESET E(51) * Network dropped connection because - * of reset - */ -#define PVFS_ENOBUFS E(52) /* No buffer space available */ -#define PVFS_ETIMEDOUT E(53) /* Connection timed out */ -#define PVFS_ECONNREFUSED E(54) /* Connection refused */ -#define PVFS_EHOSTDOWN E(55) /* Host is down */ -#define PVFS_EHOSTUNREACH E(56) /* No route to host */ -#define PVFS_EALREADY E(57) /* Operation already in progress */ -#define PVFS_EACCES E(58) /* Access not allowed */ -#define PVFS_ECONNRESET E(59) /* Connection reset by peer */ -#define PVFS_ERANGE E(60) /* Math out of range or buf too small */ - -/***************** non-errno/pvfs2 specific error codes *****************/ -#define PVFS_ECANCEL (1|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_EDEVINIT (2|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_EDETAIL (3|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_EHOSTNTFD (4|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_EADDRNTFD (5|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_ENORECVR (6|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_ETRYAGAIN (7|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_ENOTPVFS (8|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -#define PVFS_ESECURITY (9|(PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT)) -/* - * NOTE: PLEASE DO NOT ARBITRARILY ADD NEW ERRNO ERROR CODES! - * - * IF YOU CHOOSE TO ADD A NEW ERROR CODE (DESPITE OUR PLEA), YOU ALSO - * NEED TO INCREMENT PVFS_ERRNO MAX (BELOW) AND ADD A MAPPING TO A - * UNIX ERRNO VALUE IN THE MACROS BELOW (USED IN - * src/common/misc/errno-mapping.c and the kernel module) - */ -#define PVFS_ERRNO_MAX 61 - -#define PVFS_ERROR_BMI (1 << 7) /* BMI-specific error */ -#define PVFS_ERROR_TROVE (2 << 7) /* Trove-specific error */ -#define PVFS_ERROR_FLOW (3 << 7) -#define PVFS_ERROR_SM (4 << 7) /* state machine specific error */ -#define PVFS_ERROR_SCHED (5 << 7) -#define PVFS_ERROR_CLIENT (6 << 7) -#define PVFS_ERROR_DEV (7 << 7) /* device file interaction */ - -#define PVFS_ERROR_CLASS_BITS \ - (PVFS_ERROR_BMI | \ - PVFS_ERROR_TROVE | \ - PVFS_ERROR_FLOW | \ - PVFS_ERROR_SM | \ - PVFS_ERROR_SCHED | \ - PVFS_ERROR_CLIENT | \ - PVFS_ERROR_DEV) - -#define DECLARE_ERRNO_MAPPING() \ -__s32 PINT_errno_mapping[PVFS_ERRNO_MAX + 1] = { \ - 0, /* leave this one empty */ \ - EPERM, /* 1 */ \ - ENOENT, \ - EINTR, \ - EIO, \ - ENXIO, \ - EBADF, \ - EAGAIN, \ - ENOMEM, \ - EFAULT, \ - EBUSY, /* 10 */ \ - EEXIST, \ - ENODEV, \ - ENOTDIR, \ - EISDIR, \ - EINVAL, \ - EMFILE, \ - EFBIG, \ - ENOSPC, \ - EROFS, \ - EMLINK, /* 20 */ \ - EPIPE, \ - EDEADLK, \ - ENAMETOOLONG, \ - ENOLCK, \ - ENOSYS, \ - ENOTEMPTY, \ - ELOOP, \ - EWOULDBLOCK, \ - ENOMSG, \ - EUNATCH, /* 30 */ \ - EBADR, \ - EDEADLOCK, \ - ENODATA, \ - ETIME, \ - ENONET, \ - EREMOTE, \ - ECOMM, \ - EPROTO, \ - EBADMSG, \ - EOVERFLOW, /* 40 */ \ - ERESTART, \ - EMSGSIZE, \ - EPROTOTYPE, \ - ENOPROTOOPT, \ - EPROTONOSUPPORT, \ - EOPNOTSUPP, \ - EADDRINUSE, \ - EADDRNOTAVAIL, \ - ENETDOWN, \ - ENETUNREACH, /* 50 */ \ - ENETRESET, \ - ENOBUFS, \ - ETIMEDOUT, \ - ECONNREFUSED, \ - EHOSTDOWN, \ - EHOSTUNREACH, \ - EALREADY, \ - EACCES, \ - ECONNRESET, /* 59 */ \ - ERANGE, \ - 0 /* PVFS_ERRNO_MAX */ \ -}; \ -const char *PINT_non_errno_strerror_mapping[] = { \ - "Success", /* 0 */ \ - "Operation cancelled (possibly due to timeout)", \ - "Device initialization failed", \ - "Detailed per-server errors are available", \ - "Unknown host", \ - "No address associated with name", \ - "Unknown server error", \ - "Host name lookup failure", \ - "Path contains non-PVFS elements", \ - "Security error", \ -}; \ -__s32 PINT_non_errno_mapping[] = { \ - 0, /* leave this one empty */ \ - PVFS_ECANCEL, /* 1 */ \ - PVFS_EDEVINIT, /* 2 */ \ - PVFS_EDETAIL, /* 3 */ \ - PVFS_EHOSTNTFD, /* 4 */ \ - PVFS_EADDRNTFD, /* 5 */ \ - PVFS_ENORECVR, /* 6 */ \ - PVFS_ETRYAGAIN, /* 7 */ \ - PVFS_ENOTPVFS, /* 8 */ \ - PVFS_ESECURITY, /* 9 */ \ -} +/* PVFS2 error codes are a signed 32-bit integer. Error codes are negative, but + * the sign is stripped before decoding. */ -/* - * NOTE: PVFS_get_errno_mapping will convert a PVFS_ERROR_CODE to an - * errno value. If the error code is a pvfs2 specific error code - * (i.e. a PVFS_NON_ERRNO_ERROR_CODE), PVFS_get_errno_mapping will - * return an index into the PINT_non_errno_strerror_mapping array which - * can be used for getting the pvfs2 specific strerror message given - * the error code. if the value is not a recognized error code, the - * passed in value will be returned unchanged. - */ -#define DECLARE_ERRNO_MAPPING_AND_FN() \ -extern __s32 PINT_errno_mapping[]; \ -extern __s32 PINT_non_errno_mapping[]; \ -extern const char *PINT_non_errno_strerror_mapping[]; \ -static __s32 PVFS_get_errno_mapping(__s32 error) \ -{ \ - __s32 ret = error, mask = 0; \ - __s32 positive = ((error > -1) ? 1 : 0); \ - if (IS_PVFS_NON_ERRNO_ERROR((positive ? error : -error))) { \ - mask = (PVFS_NON_ERRNO_ERROR_BIT | \ - PVFS_ERROR_BIT | \ - PVFS_ERROR_CLASS_BITS); \ - ret = PVFS_NON_ERRNO_ERROR_CODE(((positive ? \ - error : \ - abs(error))) & \ - ~mask); \ - } \ - else if (IS_PVFS_ERROR((positive ? error : -error))) { \ - mask = (PVFS_ERROR_BIT | \ - PVFS_ERROR_CLASS_BITS); \ - ret = PINT_errno_mapping[PVFS_ERROR_CODE(((positive ? \ - error : \ - abs(error))) & \ - ~mask)]; \ - } \ - return ret; \ -} \ -DECLARE_ERRNO_MAPPING() +/* Bit 31 is not used since it is the sign. */ + +/* Bit 30 specifies that this is a PVFS2 error. A PVFS2 error is either an + * encoded errno value or a PVFS2 protocol error. */ +#define PVFS_ERROR_BIT (1 << 30) + +/* Bit 29 specifies that this is a PVFS2 protocol error and not an encoded + * errno value. */ +#define PVFS_NON_ERRNO_ERROR_BIT (1 << 29) + +/* Bits 9, 8, and 7 specify the error class, which encodes the section of + * server code the error originated in for logging purposes. It is not used + * in the kernel except to be masked out. */ +#define PVFS_ERROR_CLASS_BITS 0x380 + +/* Bits 6 - 0 are reserved for the actual error code. */ +#define PVFS_ERROR_NUMBER_BITS 0x7f + +/* Encoded errno values are decoded by PINT_errno_mapping in pvfs2-utils.c. */ + +/* Our own PVFS2 protocol error codes. */ +#define PVFS_ECANCEL (1|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_EDEVINIT (2|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_EDETAIL (3|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_EHOSTNTFD (4|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_EADDRNTFD (5|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_ENORECVR (6|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_ETRYAGAIN (7|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_ENOTPVFS (8|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +#define PVFS_ESECURITY (9|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) /* permission bits */ #define PVFS_O_EXECUTE (1 << 0) diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 834e06674d0a..086ebbb36570 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -662,20 +662,45 @@ __u64 pvfs2_convert_time_field(void *time_ptr) return pvfs2_time; } -/* macro defined in include/pvfs2-types.h */ -DECLARE_ERRNO_MAPPING_AND_FN(); +/* The following is a very dirty hack that is now a permanent part of the + * PVFS2 protocol. See protocol.h for more error definitions. */ + +/* The order matches include/pvfs2-types.h in the OrangeFS source. */ +static int PINT_errno_mapping[] = { + 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM, + EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE, + EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG, + ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH, + EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM, + EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE, + ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE, + EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS, + ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY, + EACCES, ECONNRESET, ERANGE +}; int pvfs2_normalize_to_errno(__s32 error_code) { - if (error_code > 0) { + /* Success */ + if (error_code == 0) { + return 0; + /* This shouldn't ever happen. If it does it should be fixed on the + * server. */ + } else if (error_code > 0) { gossip_err("pvfs2: error status receieved.\n"); gossip_err("pvfs2: assuming error code is inverted.\n"); error_code = -error_code; } - /* convert any error codes that are in pvfs2 format */ - if (IS_PVFS_NON_ERRNO_ERROR(-error_code)) { - if (PVFS_NON_ERRNO_ERROR_CODE(-error_code) == PVFS_ECANCEL) { + /* XXX: This is very bad since error codes from PVFS2 may not be + * suitable for return into userspace. */ + + /* Convert PVFS2 error values into errno values suitable for return + * from the kernel. */ + if ((-error_code) & PVFS_NON_ERRNO_ERROR_BIT) { + if (((-error_code) & + (PVFS_ERROR_NUMBER_BITS|PVFS_NON_ERRNO_ERROR_BIT| + PVFS_ERROR_BIT)) == PVFS_ECANCEL) { /* * cancellation error codes generally correspond to * a timeout from the client's perspective @@ -683,12 +708,25 @@ int pvfs2_normalize_to_errno(__s32 error_code) error_code = -ETIMEDOUT; } else { /* assume a default error code */ - gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n", - error_code); + gossip_err("pvfs2: warning: got error code without " + "errno equivalent: %d.\n", error_code); error_code = -EINVAL; } - } else if (IS_PVFS_ERROR(-error_code)) { - error_code = -PVFS_ERROR_TO_ERRNO(-error_code); + + /* Convert PVFS2 encoded errno values into regular errno values. */ + } else if ((-error_code) & PVFS_ERROR_BIT) { + __u32 i; + i = (-error_code) & ~(PVFS_ERROR_BIT|PVFS_ERROR_CLASS_BITS); + if (i < sizeof PINT_errno_mapping/sizeof *PINT_errno_mapping) + error_code = -PINT_errno_mapping[i]; + else + error_code = -EINVAL; + + /* Only PVFS2 protocol error codes should ever come here. Otherwise + * there is a bug somewhere. */ + } else { + gossip_err("pvfs2: pvfs2_normalize_to_errno: got error code" + "which is not from PVFS2.\n"); } return error_code; } -- GitLab From 548049495cb46348866aec1cb7721e9d00b4eb83 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Mon, 5 Oct 2015 13:44:24 -0400 Subject: [PATCH 0024/5324] Orangefs: fix some checkpatch.pl complaints that had creeped in. Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 6 +-- fs/orangefs/dir.c | 2 +- fs/orangefs/downcall.h | 2 +- fs/orangefs/file.c | 25 ++++++----- fs/orangefs/inode.c | 24 +++++------ fs/orangefs/protocol.h | 32 +++++++------- fs/orangefs/pvfs2-bufmap.c | 10 ++--- fs/orangefs/pvfs2-debug.h | 6 ++- fs/orangefs/pvfs2-kernel.h | 9 ++-- fs/orangefs/pvfs2-mod.c | 10 ++--- fs/orangefs/pvfs2-utils.c | 87 +++++++++++++++++++++----------------- 11 files changed, 111 insertions(+), 102 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index 13878cac49ed..ede842f05b62 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -476,9 +476,9 @@ static ssize_t pvfs2_devreq_writev(struct file *file, set_op_state_serviced(op); spin_unlock(&op->lock); /* - for every other operation (i.e. non-I/O), we need to - wake up the callers for downcall completion - notification + * for every other operation (i.e. non-I/O), we need to + * wake up the callers for downcall completion + * notification */ wake_up_interruptible(&op->waitq); } diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 3870e78f5ecf..daf497384501 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -289,7 +289,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) } - /* + /* * we ran all the way through the last batch, set up for * getting another batch... */ diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h index a79129f875f3..f8bea46e7c6a 100644 --- a/fs/orangefs/downcall.h +++ b/fs/orangefs/downcall.h @@ -107,7 +107,7 @@ struct pvfs2_downcall_s { __s32 status; /* currently trailer is used only by readdir */ __s64 trailer_size; - char * trailer_buf; + char *trailer_buf; union { struct pvfs2_io_response io; diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 87f718163d1b..feb1764c2f80 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -54,7 +54,6 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", __func__, (long)ret); - } if (ret < 0) @@ -199,9 +198,9 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, if (ret < 0) { handle_io_error(); /* defined in pvfs2-kernel.h */ /* - don't write an error to syslog on signaled operation - termination unless we've got debugging turned on, as - this can happen regularly (i.e. ctrl-c) + * don't write an error to syslog on signaled operation + * termination unless we've got debugging turned on, as + * this can happen regularly (i.e. ctrl-c) */ if (ret == -EINTR) gossip_debug(GOSSIP_FILE_DEBUG, @@ -245,10 +244,10 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, ret = new_op->downcall.resp.io.amt_complete; /* - tell the device file owner waiting on I/O that this read has - completed and it can return now. in this exact case, on - wakeup the daemon will free the op, so we *cannot* touch it - after this. + * tell the device file owner waiting on I/O that this read has + * completed and it can return now. in this exact case, on + * wakeup the daemon will free the op, so we *cannot* touch it + * after this. */ wake_up_daemon_for_return(new_op); new_op = NULL; @@ -875,9 +874,9 @@ static int pvfs2_file_release(struct inode *inode, struct file *file) pvfs2_flush_inode(inode); /* - remove all associated inode pages from the page cache and mmap - readahead cache (if any); this forces an expensive refresh of - data for the next caller of mmap (or 'get_block' accesses) + * remove all associated inode pages from the page cache and mmap + * readahead cache (if any); this forces an expensive refresh of + * data for the next caller of mmap (or 'get_block' accesses) */ if (file->f_path.dentry->d_inode && file->f_path.dentry->d_inode->i_mapping && @@ -960,8 +959,8 @@ static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) } gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_file_llseek: offset is %ld | origin is %d | " - "inode size is %lu\n", + "pvfs2_file_llseek: offset is %ld | origin is %d" + " | inode size is %lu\n", (long)offset, origin, (unsigned long)file->f_path.dentry->d_inode->i_size); diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 9ff6b2985240..4f7c45a44c1f 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -128,18 +128,18 @@ static int pvfs2_releasepage(struct page *page, gfp_t foo) * AIO. Modeled after NFS, they do this too. */ /* -static ssize_t pvfs2_direct_IO(int rw, - struct kiocb *iocb, - struct iov_iter *iter, - loff_t offset) -{ - gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_direct_IO: %s\n", - iocb->ki_filp->f_path.dentry->d_name.name); - - return -EINVAL; -} -*/ + * static ssize_t pvfs2_direct_IO(int rw, + * struct kiocb *iocb, + * struct iov_iter *iter, + * loff_t offset) + *{ + * gossip_debug(GOSSIP_INODE_DEBUG, + * "pvfs2_direct_IO: %s\n", + * iocb->ki_filp->f_path.dentry->d_name.name); + * + * return -EINVAL; + *} + */ struct backing_dev_info pvfs2_backing_dev_info = { .name = "pvfs2", diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index b374c4b2009e..85f611fe0536 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -101,22 +101,30 @@ typedef __s64 PVFS_offset; #define PVFS2_SUPER_MAGIC 0x20030528 -/* PVFS2 error codes are a signed 32-bit integer. Error codes are negative, but - * the sign is stripped before decoding. */ +/* + * PVFS2 error codes are a signed 32-bit integer. Error codes are negative, but + * the sign is stripped before decoding. + */ /* Bit 31 is not used since it is the sign. */ -/* Bit 30 specifies that this is a PVFS2 error. A PVFS2 error is either an - * encoded errno value or a PVFS2 protocol error. */ +/* + * Bit 30 specifies that this is a PVFS2 error. A PVFS2 error is either an + * encoded errno value or a PVFS2 protocol error. + */ #define PVFS_ERROR_BIT (1 << 30) -/* Bit 29 specifies that this is a PVFS2 protocol error and not an encoded - * errno value. */ +/* + * Bit 29 specifies that this is a PVFS2 protocol error and not an encoded + * errno value. + */ #define PVFS_NON_ERRNO_ERROR_BIT (1 << 29) -/* Bits 9, 8, and 7 specify the error class, which encodes the section of +/* + * Bits 9, 8, and 7 specify the error class, which encodes the section of * server code the error originated in for logging purposes. It is not used - * in the kernel except to be masked out. */ + * in the kernel except to be masked out. + */ #define PVFS_ERROR_CLASS_BITS 0x380 /* Bits 6 - 0 are reserved for the actual error code. */ @@ -388,14 +396,8 @@ enum { /* * version number for use in communicating between kernel space and user - * space + * space. Zero signifies the upstream version of the kernel module. */ -/* -#define PVFS_KERNEL_PROTO_VERSION \ - ((PVFS2_VERSION_MAJOR * 10000) + \ - (PVFS2_VERSION_MINOR * 100) + \ - PVFS2_VERSION_SUB) -*/ #define PVFS_KERNEL_PROTO_VERSION 0 /* diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index e01e220fd5d7..9d0392a3e824 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -508,9 +508,9 @@ void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index) } int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, - struct iov_iter *iter, - int buffer_index, - size_t size) + struct iov_iter *iter, + int buffer_index, + size_t size) { struct pvfs_bufmap_desc *to; struct page *page; @@ -553,7 +553,7 @@ int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, "%s: buffer_index:%d: iov_iter_count(iter):%lu:\n", __func__, buffer_index, iov_iter_count(iter)); - from = &bufmap->desc_array[buffer_index]; + from = &bufmap->desc_array[buffer_index]; for (i = 0; iov_iter_count(iter); i++) { page = from->page_array[i]; @@ -562,5 +562,5 @@ int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, break; } - return iov_iter_count(iter) ? -EFAULT : 0; + return iov_iter_count(iter) ? -EFAULT : 0; } diff --git a/fs/orangefs/pvfs2-debug.h b/fs/orangefs/pvfs2-debug.h index 4c27ad77fa16..fd71d6c84cf6 100644 --- a/fs/orangefs/pvfs2-debug.h +++ b/fs/orangefs/pvfs2-debug.h @@ -180,8 +180,10 @@ static struct __keyword_mask_s s_keyword_mask_map[] = { {"readdir", GOSSIP_READDIR_DEBUG}, /* Debug the mkdir operation (server only) */ {"mkdir", GOSSIP_MKDIR_DEBUG}, - /* Debug the io operation (reads and writes) - * for both the client and server */ + /* + * Debug the io operation (reads and writes) + * for both the client and server. + */ {"io", GOSSIP_IO_DEBUG}, /* Debug the server's open file descriptor cache */ {"open_cache", GOSSIP_DBPF_OPEN_CACHE_DEBUG}, diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 299b48c37cab..29b4a48b3a25 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -229,9 +229,6 @@ int keyword_is_amalgam(char *); extern char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; extern char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; extern char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN]; -/* HELLO -extern struct client_debug_mask current_client_mask; -*/ extern unsigned int kernel_mask_set_mod_init; extern int pvfs2_init_acl(struct inode *inode, struct inode *dir); @@ -431,9 +428,9 @@ struct pvfs2_stats { extern struct pvfs2_stats g_pvfs2_stats; /* - NOTE: See Documentation/filesystems/porting for information - on implementing FOO_I and properly accessing fs private data -*/ + * NOTE: See Documentation/filesystems/porting for information + * on implementing FOO_I and properly accessing fs private data + */ static inline struct pvfs2_inode_s *PVFS2_I(struct inode *inode) { return container_of(inode, struct pvfs2_inode_s, vfs_inode); diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c index d80537dadcd8..d848c90413d1 100644 --- a/fs/orangefs/pvfs2-mod.c +++ b/fs/orangefs/pvfs2-mod.c @@ -73,11 +73,11 @@ module_param(slot_timeout_secs, int, 0); struct mutex devreq_mutex; /* - blocks non-priority requests from being queued for servicing. this - could be used for protecting the request list data structure, but - for now it's only being used to stall the op addition to the request - list -*/ + * Blocks non-priority requests from being queued for servicing. This + * could be used for protecting the request list data structure, but + * for now it's only being used to stall the op addition to the request + * list + */ struct mutex request_mutex; /* hash table for storing operations waiting for matching downcall */ diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 086ebbb36570..c33e7193599c 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -111,18 +111,18 @@ static int copy_attributes_to_inode(struct inode *inode, /* - arbitrarily set the inode block size; FIXME: we need to - resolve the difference between the reported inode blocksize - and the PAGE_CACHE_SIZE, since our block count will always - be wrong. - - For now, we're setting the block count to be the proper - number assuming the block size is 512 bytes, and the size is - rounded up to the nearest 4K. This is apparently required - to get proper size reports from the 'du' shell utility. - - changing the inode->i_blkbits to something other than - PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that. + * arbitrarily set the inode block size; FIXME: we need to + * resolve the difference between the reported inode blocksize + * and the PAGE_CACHE_SIZE, since our block count will always + * be wrong. + * + * For now, we're setting the block count to be the proper + * number assuming the block size is 512 bytes, and the size is + * rounded up to the nearest 4K. This is apparently required + * to get proper size reports from the 'du' shell utility. + * + * changing the inode->i_blkbits to something other than + * PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that. */ gossip_debug(GOSSIP_UTILS_DEBUG, "attrs->mask = %x (objtype = %s)\n", @@ -662,41 +662,51 @@ __u64 pvfs2_convert_time_field(void *time_ptr) return pvfs2_time; } -/* The following is a very dirty hack that is now a permanent part of the - * PVFS2 protocol. See protocol.h for more error definitions. */ +/* + * The following is a very dirty hack that is now a permanent part of the + * PVFS2 protocol. See protocol.h for more error definitions. + */ /* The order matches include/pvfs2-types.h in the OrangeFS source. */ static int PINT_errno_mapping[] = { - 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM, - EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE, - EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG, - ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH, - EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM, - EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE, - ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE, - EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS, - ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY, - EACCES, ECONNRESET, ERANGE + 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM, + EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE, + EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG, + ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH, + EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM, + EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE, + ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE, + EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS, + ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY, + EACCES, ECONNRESET, ERANGE }; int pvfs2_normalize_to_errno(__s32 error_code) { + __u32 i; + /* Success */ if (error_code == 0) { return 0; - /* This shouldn't ever happen. If it does it should be fixed on the - * server. */ + /* + * This shouldn't ever happen. If it does it should be fixed on the + * server. + */ } else if (error_code > 0) { gossip_err("pvfs2: error status receieved.\n"); gossip_err("pvfs2: assuming error code is inverted.\n"); error_code = -error_code; } - /* XXX: This is very bad since error codes from PVFS2 may not be - * suitable for return into userspace. */ + /* + * XXX: This is very bad since error codes from PVFS2 may not be + * suitable for return into userspace. + */ - /* Convert PVFS2 error values into errno values suitable for return - * from the kernel. */ + /* + * Convert PVFS2 error values into errno values suitable for return + * from the kernel. + */ if ((-error_code) & PVFS_NON_ERRNO_ERROR_BIT) { if (((-error_code) & (PVFS_ERROR_NUMBER_BITS|PVFS_NON_ERRNO_ERROR_BIT| @@ -708,25 +718,24 @@ int pvfs2_normalize_to_errno(__s32 error_code) error_code = -ETIMEDOUT; } else { /* assume a default error code */ - gossip_err("pvfs2: warning: got error code without " - "errno equivalent: %d.\n", error_code); + gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n", error_code); error_code = -EINVAL; } /* Convert PVFS2 encoded errno values into regular errno values. */ } else if ((-error_code) & PVFS_ERROR_BIT) { - __u32 i; i = (-error_code) & ~(PVFS_ERROR_BIT|PVFS_ERROR_CLASS_BITS); - if (i < sizeof PINT_errno_mapping/sizeof *PINT_errno_mapping) + if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping)) error_code = -PINT_errno_mapping[i]; else error_code = -EINVAL; - /* Only PVFS2 protocol error codes should ever come here. Otherwise - * there is a bug somewhere. */ + /* + * Only PVFS2 protocol error codes should ever come here. Otherwise + * there is a bug somewhere. + */ } else { - gossip_err("pvfs2: pvfs2_normalize_to_errno: got error code" - "which is not from PVFS2.\n"); + gossip_err("pvfs2: pvfs2_normalize_to_errno: got error code which is not from PVFS2.\n"); } return error_code; } @@ -993,7 +1002,7 @@ void do_k_string(void *k_mask, int index) __u64 *mask = (__u64 *) k_mask; if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword)) - goto out; + goto out; if (*mask & s_kmod_keyword_mask_map[index].mask_val) { if ((strlen(kernel_debug_string) + -- GitLab From 2ae4b6b20e2004dccf80d804ae52b073377c2f5b Mon Sep 17 00:00:00 2001 From: Amitoj Kaur Chawla Date: Thu, 22 Oct 2015 04:05:00 +0530 Subject: [PATCH 0025/5324] firewire: nosy: Replace timeval with timespec64 32 bit systems using 'struct timeval' will break in the year 2038, so we replace the code appropriately. However, this driver is not broken in 2038 since we are using only the microseconds portion of the current time. This patch replaces timeval with timespec64. Signed-off-by: Amitoj Kaur Chawla Reviewed-by: Arnd Bergmann Signed-off-by: Stefan Richter --- drivers/firewire/nosy.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index 76b2d390f6ec..8a46077129ac 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -33,6 +33,7 @@ #include /* required for linux/wait.h */ #include #include +#include #include #include #include @@ -413,17 +414,18 @@ static void packet_irq_handler(struct pcilynx *lynx) { struct client *client; - u32 tcode_mask, tcode; + u32 tcode_mask, tcode, timestamp; size_t length; - struct timeval tv; + struct timespec64 ts64; /* FIXME: Also report rcv_speed. */ length = __le32_to_cpu(lynx->rcv_pcl->pcl_status) & 0x00001fff; tcode = __le32_to_cpu(lynx->rcv_buffer[1]) >> 4 & 0xf; - do_gettimeofday(&tv); - lynx->rcv_buffer[0] = (__force __le32)tv.tv_usec; + ktime_get_real_ts64(&ts64); + timestamp = ts64.tv_nsec / NSEC_PER_USEC; + lynx->rcv_buffer[0] = (__force __le32)timestamp; if (length == PHY_PACKET_SIZE) tcode_mask = 1 << TCODE_PHY_PACKET; -- GitLab From a354cf00c71390c46927335fe20b65f38a528b59 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Nov 2015 15:52:13 +0100 Subject: [PATCH 0026/5324] firewire: ohci: propagate return code from soft_reset to probe and resume software_reset() may fail - due to unresponsive chip with -EBUSY (-16), or - due to ejected or unseated card with -ENODEV (-19). Let the PCI probe and resume routines log the actual error code instead of hardwired -EBUSY. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index c2f5117fd8cb..8bf89267dc25 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2278,9 +2278,10 @@ static int ohci_enable(struct fw_card *card, u32 lps, version, irqs; int i, ret; - if (software_reset(ohci)) { + ret = software_reset(ohci); + if (ret < 0) { ohci_err(ohci, "failed to reset ohci card\n"); - return -EBUSY; + return ret; } /* -- GitLab From 5759139469899ea402c5953a8a38dd4f4c345b3c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 1 Nov 2015 15:52:51 +0100 Subject: [PATCH 0027/5324] firewire: ABI documentation: jujuutils were renamed to linux-firewire-utils Signed-off-by: Stefan Richter --- Documentation/ABI/stable/firewire-cdev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/stable/firewire-cdev b/Documentation/ABI/stable/firewire-cdev index 16d030827368..b55dd3c6aff5 100644 --- a/Documentation/ABI/stable/firewire-cdev +++ b/Documentation/ABI/stable/firewire-cdev @@ -100,4 +100,4 @@ Description: Users: libraw1394 libdc1394 - tools like jujuutils, fwhack, ... + tools like linux-firewire-utils, fwhack, ... -- GitLab From 5c278228bbfe3abb7d468ef39dffac23de15c078 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 17:43:58 -0400 Subject: [PATCH 0028/5324] orangefs: explicitly pass the size to pvfs_bufmap_copy_to_iovec() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 3 ++- fs/orangefs/pvfs2-bufmap.c | 29 +++++++++++++++-------------- fs/orangefs/pvfs2-bufmap.h | 3 ++- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index feb1764c2f80..92a0974f0743 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -89,7 +89,8 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, iov_iter_init(&iter, READ, vec, nr_segs, total_size); ret = pvfs_bufmap_copy_to_iovec(bufmap, &iter, - buffer_index); + buffer_index, + total_size); if (ret < 0) gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", __func__, diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index 9d0392a3e824..843883035214 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -542,25 +542,26 @@ int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, */ int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, struct iov_iter *iter, - int buffer_index) + int buffer_index, + size_t size) { - struct pvfs_bufmap_desc *from; - struct page *page; + struct pvfs_bufmap_desc *from = &bufmap->desc_array[buffer_index]; int i; - size_t written; gossip_debug(GOSSIP_BUFMAP_DEBUG, - "%s: buffer_index:%d: iov_iter_count(iter):%lu:\n", - __func__, buffer_index, iov_iter_count(iter)); + "%s: buffer_index:%d: size:%zu:\n", + __func__, buffer_index, size); - from = &bufmap->desc_array[buffer_index]; - for (i = 0; iov_iter_count(iter); i++) { - page = from->page_array[i]; - written = copy_page_to_iter(page, 0, PAGE_SIZE, iter); - if ((written == 0) && (iov_iter_count(iter))) - break; + for (i = 0; size; i++) { + struct page *page = from->page_array[i]; + size_t n = size; + if (n > PAGE_SIZE) + n = PAGE_SIZE; + n = copy_page_to_iter(page, 0, n, iter); + if (!n) + return -EFAULT; + size -= n; } - - return iov_iter_count(iter) ? -EFAULT : 0; + return 0; } diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/pvfs2-bufmap.h index a0f84c045d73..d1aedb52a877 100644 --- a/fs/orangefs/pvfs2-bufmap.h +++ b/fs/orangefs/pvfs2-bufmap.h @@ -49,7 +49,8 @@ int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, struct iov_iter *iter, - int buffer_index); + int buffer_index, + size_t size); size_t pvfs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk, struct iovec *iovec, -- GitLab From 34204fde4c877cb33d8ec0df09f38333f570cc84 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 17:47:44 -0400 Subject: [PATCH 0029/5324] pvfs_bufmap_copy_from_iovec(): don't rely upon size being equal to iov_iter_count(iter) Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-bufmap.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index 843883035214..dacf42bee196 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -512,26 +512,25 @@ int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, int buffer_index, size_t size) { - struct pvfs_bufmap_desc *to; - struct page *page; - size_t copied; + struct pvfs_bufmap_desc *to = &bufmap->desc_array[buffer_index]; int i; gossip_debug(GOSSIP_BUFMAP_DEBUG, - "%s: buffer_index:%d: size:%lu:\n", + "%s: buffer_index:%d: size:%zu:\n", __func__, buffer_index, size); - to = &bufmap->desc_array[buffer_index]; for (i = 0; size; i++) { - page = to->page_array[i]; - copied = copy_page_from_iter(page, 0, PAGE_SIZE, iter); - size -= copied; - if ((copied == 0) && (size)) - break; + struct page *page = to->page_array[i]; + size_t n = size; + if (n > PAGE_SIZE) + n = PAGE_SIZE; + n = copy_page_from_iter(page, 0, n, iter); + if (!n) + return -EFAULT; + size -= n; } - - return size ? -EFAULT : 0; + return 0; } -- GitLab From 5f0e3c953fd962d82e1f38aeb24f7aec9bd1ba54 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 17:52:44 -0400 Subject: [PATCH 0030/5324] orangefs: make postcopy_buffers() take iov_iter Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 92a0974f0743..c169bdda66a3 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -72,23 +72,18 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, */ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, int buffer_index, - const struct iovec *vec, - int nr_segs, + struct iov_iter *iter, size_t total_size) { int ret = 0; - - struct iov_iter iter; - /* * copy data to application/kernel by pushing it out to * the iovec. NOTE; target buffers can be addresses or * struct page pointers. */ if (total_size) { - iov_iter_init(&iter, READ, vec, nr_segs, total_size); ret = pvfs_bufmap_copy_to_iovec(bufmap, - &iter, + iter, buffer_index, total_size); if (ret < 0) @@ -221,10 +216,11 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * postcopy_buffers only pertains to reads. */ if (type == PVFS_IO_READ) { + struct iov_iter iter; + iov_iter_init(&iter, READ, vec, nr_segs, new_op->downcall.resp.io.amt_complete); ret = postcopy_buffers(bufmap, buffer_index, - vec, - nr_segs, + &iter, new_op->downcall.resp.io.amt_complete); if (ret < 0) { /* -- GitLab From a5c126a52269ce304b6da95e980e595668bf467d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 17:54:31 -0400 Subject: [PATCH 0031/5324] orangefs: make precopy_buffers() take iov_iter Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index c169bdda66a3..bd8e6f866047 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -31,13 +31,10 @@ do { \ */ static int precopy_buffers(struct pvfs2_bufmap *bufmap, int buffer_index, - const struct iovec *vec, - unsigned long nr_segs, + struct iov_iter *iter, size_t total_size) { int ret = 0; - struct iov_iter iter; - /* * copy data from application/kernel by pulling it out * of the iovec. @@ -45,9 +42,8 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, if (total_size) { - iov_iter_init(&iter, WRITE, vec, nr_segs, total_size); ret = pvfs_bufmap_copy_from_iovec(bufmap, - &iter, + iter, buffer_index, total_size); if (ret < 0) @@ -152,10 +148,11 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * precopy_buffers only pertains to writes. */ if (type == PVFS_IO_WRITE) { + struct iov_iter iter; + iov_iter_init(&iter, WRITE, vec, nr_segs, total_size); ret = precopy_buffers(bufmap, buffer_index, - vec, - nr_segs, + &iter, total_size); if (ret < 0) goto out; -- GitLab From 3c2fcfcb6858585e9df6c7832464ab28bfb5bb6b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 18:00:26 -0400 Subject: [PATCH 0032/5324] orangefs: make wait_for_direct_io() take iov_iter incidentally, insane or compromised server returning *more* than requested on read should not oops the kernel - initialize the iov_iter for read according to the iovec we've got. That's why pvfs_bufmap_copy_to_iovec() needed a separate size argument - we shouldn't abuse iov_iter_count(iter) for passing that. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index bd8e6f866047..9a439b2e8bde 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -94,7 +94,7 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, * Post and wait for the I/O upcall to finish */ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, - loff_t *offset, struct iovec *vec, unsigned long nr_segs, + loff_t *offset, struct iov_iter *iter, size_t total_size, loff_t readahead_size) { struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); @@ -137,10 +137,9 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, new_op->upcall.req.io.offset = *offset; gossip_debug(GOSSIP_FILE_DEBUG, - "%s(%pU): nr_segs %lu, offset: %llu total_size: %zd\n", + "%s(%pU): offset: %llu total_size: %zd\n", __func__, handle, - nr_segs, llu(*offset), total_size); /* @@ -148,11 +147,9 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * precopy_buffers only pertains to writes. */ if (type == PVFS_IO_WRITE) { - struct iov_iter iter; - iov_iter_init(&iter, WRITE, vec, nr_segs, total_size); ret = precopy_buffers(bufmap, buffer_index, - &iter, + iter, total_size); if (ret < 0) goto out; @@ -213,11 +210,9 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * postcopy_buffers only pertains to reads. */ if (type == PVFS_IO_READ) { - struct iov_iter iter; - iov_iter_init(&iter, READ, vec, nr_segs, new_op->downcall.resp.io.amt_complete); ret = postcopy_buffers(bufmap, buffer_index, - &iter, + iter, new_op->downcall.resp.io.amt_complete); if (ret < 0) { /* @@ -563,6 +558,7 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, #endif seg = 0; while (total_count < count) { + struct iov_iter iter; size_t each_count; size_t amt_complete; @@ -583,8 +579,11 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, handle, (int)*offset); - ret = wait_for_direct_io(type, inode, offset, ptr, - seg_array[seg], each_count, 0); + iov_iter_init(&iter, type == PVFS_IO_READ ? READ : WRITE, + ptr, seg_array[seg], each_count); + + ret = wait_for_direct_io(type, inode, offset, &iter, + each_count, 0); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): return from wait_for_io:%d\n", __func__, @@ -654,6 +653,7 @@ ssize_t pvfs2_inode_read(struct inode *inode, struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); size_t bufmap_size; struct iovec vec; + struct iov_iter iter; ssize_t ret = -EINVAL; g_pvfs2_stats.reads++; @@ -676,7 +676,8 @@ ssize_t pvfs2_inode_read(struct inode *inode, count, llu(*offset)); - ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &vec, 1, + iov_iter_init(&iter, READ, &vec, 1, count); + ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &iter, count, readahead_size); if (ret > 0) *offset += ret; -- GitLab From dc4067f671231eea971298cb44f687a30e04d0fd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 18:17:26 -0400 Subject: [PATCH 0033/5324] orangefs: don't bother with splitting iovecs copy_page_{to,from}_iter() advances it just fine *and* it has no problem with partially consumed segments. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 282 +-------------------------------------------- 1 file changed, 6 insertions(+), 276 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 9a439b2e8bde..ff7fe37f5a22 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -256,168 +256,6 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, return ret; } -/* - * The reason we need to do this is to be able to support readv and writev - * that are larger than (pvfs_bufmap_size_query()) Default is - * PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB. What that means is that we will - * create a new io vec descriptor for those memory addresses that - * go beyond the limit. Return value for this routine is negative in case - * of errors and 0 in case of success. - * - * Further, the new_nr_segs pointer is updated to hold the new value - * of number of iovecs, the new_vec pointer is updated to hold the pointer - * to the new split iovec, and the size array is an array of integers holding - * the number of iovecs that straddle pvfs_bufmap_size_query(). - * The max_new_nr_segs value is computed by the caller and returned. - * (It will be (count of all iov_len/ block_size) + 1). - */ -static int split_iovecs(unsigned long max_new_nr_segs, /* IN */ - unsigned long nr_segs, /* IN */ - const struct iovec *original_iovec, /* IN */ - unsigned long *new_nr_segs, /* OUT */ - struct iovec **new_vec, /* OUT */ - unsigned long *seg_count, /* OUT */ - unsigned long **seg_array) /* OUT */ -{ - unsigned long seg; - unsigned long count = 0; - unsigned long begin_seg; - unsigned long tmpnew_nr_segs = 0; - struct iovec *new_iovec = NULL; - struct iovec *orig_iovec; - unsigned long *sizes = NULL; - unsigned long sizes_count = 0; - - if (nr_segs <= 0 || - original_iovec == NULL || - new_nr_segs == NULL || - new_vec == NULL || - seg_count == NULL || - seg_array == NULL || - max_new_nr_segs <= 0) { - gossip_err("Invalid parameters to split_iovecs\n"); - return -EINVAL; - } - *new_nr_segs = 0; - *new_vec = NULL; - *seg_count = 0; - *seg_array = NULL; - /* copy the passed in iovec descriptor to a temp structure */ - orig_iovec = kmalloc_array(nr_segs, - sizeof(*orig_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (orig_iovec == NULL) { - gossip_err( - "split_iovecs: Could not allocate memory for %lu bytes!\n", - (unsigned long)(nr_segs * sizeof(*orig_iovec))); - return -ENOMEM; - } - new_iovec = kcalloc(max_new_nr_segs, - sizeof(*new_iovec), - PVFS2_BUFMAP_GFP_FLAGS); - if (new_iovec == NULL) { - kfree(orig_iovec); - gossip_err( - "split_iovecs: Could not allocate memory for %lu bytes!\n", - (unsigned long)(max_new_nr_segs * sizeof(*new_iovec))); - return -ENOMEM; - } - sizes = kcalloc(max_new_nr_segs, - sizeof(*sizes), - PVFS2_BUFMAP_GFP_FLAGS); - if (sizes == NULL) { - kfree(new_iovec); - kfree(orig_iovec); - gossip_err( - "split_iovecs: Could not allocate memory for %lu bytes!\n", - (unsigned long)(max_new_nr_segs * sizeof(*sizes))); - return -ENOMEM; - } - /* copy the passed in iovec to a temp structure */ - memcpy(orig_iovec, original_iovec, nr_segs * sizeof(*orig_iovec)); - begin_seg = 0; -repeat: - for (seg = begin_seg; seg < nr_segs; seg++) { - if (tmpnew_nr_segs >= max_new_nr_segs || - sizes_count >= max_new_nr_segs) { - kfree(sizes); - kfree(orig_iovec); - kfree(new_iovec); - gossip_err - ("split_iovecs: exceeded the index limit (%lu)\n", - tmpnew_nr_segs); - return -EINVAL; - } - if (count + orig_iovec[seg].iov_len < - pvfs_bufmap_size_query()) { - count += orig_iovec[seg].iov_len; - memcpy(&new_iovec[tmpnew_nr_segs], - &orig_iovec[seg], - sizeof(*new_iovec)); - tmpnew_nr_segs++; - sizes[sizes_count]++; - } else { - new_iovec[tmpnew_nr_segs].iov_base = - orig_iovec[seg].iov_base; - new_iovec[tmpnew_nr_segs].iov_len = - (pvfs_bufmap_size_query() - count); - tmpnew_nr_segs++; - sizes[sizes_count]++; - sizes_count++; - begin_seg = seg; - orig_iovec[seg].iov_base += - (pvfs_bufmap_size_query() - count); - orig_iovec[seg].iov_len -= - (pvfs_bufmap_size_query() - count); - count = 0; - break; - } - } - if (seg != nr_segs) - goto repeat; - else - sizes_count++; - - *new_nr_segs = tmpnew_nr_segs; - /* new_iovec is freed by the caller */ - *new_vec = new_iovec; - *seg_count = sizes_count; - /* seg_array is also freed by the caller */ - *seg_array = sizes; - kfree(orig_iovec); - return 0; -} - -static long bound_max_iovecs(const struct iovec *curr, unsigned long nr_segs, - ssize_t *total_count) -{ - unsigned long i; - long max_nr_iovecs; - ssize_t total; - ssize_t count; - - total = 0; - count = 0; - max_nr_iovecs = 0; - for (i = 0; i < nr_segs; i++) { - const struct iovec *iv = &curr[i]; - - count += iv->iov_len; - if (unlikely((ssize_t) (count | iv->iov_len) < 0)) - return -EINVAL; - if (total + iv->iov_len < pvfs_bufmap_size_query()) { - total += iv->iov_len; - max_nr_iovecs++; - } else { - total = - (total + iv->iov_len - pvfs_bufmap_size_query()); - max_nr_iovecs += (total / pvfs_bufmap_size_query() + 2); - } - } - *total_count = count; - return max_nr_iovecs; -} - /* * Common entry point for read/write/readv/writev * This function will dispatch it to either the direct I/O @@ -431,25 +269,10 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, struct inode *inode = file->f_mapping->host; struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; - ssize_t ret; - ssize_t total_count; - unsigned int to_free; - size_t count; - unsigned long seg; - unsigned long new_nr_segs; - unsigned long max_new_nr_segs; - unsigned long seg_count; - unsigned long *seg_array; - struct iovec *iovecptr; - struct iovec *ptr; - - total_count = 0; - ret = -EINVAL; - count = 0; - to_free = 0; - - /* Compute total and max number of segments after split */ - max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count); + struct iov_iter iter; + size_t count = iov_length(iov, nr_segs); + ssize_t total_count = 0; + ssize_t ret = -EINVAL; gossip_debug(GOSSIP_FILE_DEBUG, "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n", @@ -472,93 +295,10 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, goto out; } - /* - * if the total size of data transfer requested is greater than - * the kernel-set blocksize of PVFS2, then we split the iovecs - * such that no iovec description straddles a block size limit - */ - - gossip_debug(GOSSIP_FILE_DEBUG, - "%s: pvfs_bufmap_size:%d\n", - __func__, - pvfs_bufmap_size_query()); - - if (count > pvfs_bufmap_size_query()) { - /* - * Split up the given iovec description such that - * no iovec descriptor straddles over the block-size limitation. - * This makes us our job easier to stage the I/O. - * In addition, this function will also compute an array - * with seg_count entries that will store the number of - * segments that straddle the block-size boundaries. - */ - ret = split_iovecs(max_new_nr_segs, /* IN */ - nr_segs, /* IN */ - iov, /* IN */ - &new_nr_segs, /* OUT */ - &iovecptr, /* OUT */ - &seg_count, /* OUT */ - &seg_array); /* OUT */ - if (ret < 0) { - gossip_err("%s: Failed to split iovecs to satisfy larger than blocksize readv/writev request %zd\n", - __func__, - ret); - goto out; - } - gossip_debug(GOSSIP_FILE_DEBUG, - "%s: Splitting iovecs from %lu to %lu" - " [max_new %lu]\n", - __func__, - nr_segs, - new_nr_segs, - max_new_nr_segs); - /* We must free seg_array and iovecptr */ - to_free = 1; - } else { - new_nr_segs = nr_segs; - /* use the given iovec description */ - iovecptr = (struct iovec *)iov; - /* There is only 1 element in the seg_array */ - seg_count = 1; - /* and its value is the number of segments passed in */ - seg_array = &nr_segs; - /* We dont have to free up anything */ - to_free = 0; - } - ptr = iovecptr; + iov_iter_init(&iter, type == PVFS_IO_READ ? READ : WRITE, + iov, nr_segs, count); - gossip_debug(GOSSIP_FILE_DEBUG, - "%s(%pU) %zd@%llu\n", - __func__, - handle, - count, - llu(*offset)); - gossip_debug(GOSSIP_FILE_DEBUG, - "%s(%pU): new_nr_segs: %lu, seg_count: %lu\n", - __func__, - handle, - new_nr_segs, seg_count); - -/* PVFS2_KERNEL_DEBUG is a CFLAGS define. */ -#ifdef PVFS2_KERNEL_DEBUG - for (seg = 0; seg < new_nr_segs; seg++) - gossip_debug(GOSSIP_FILE_DEBUG, - "%s: %d) %p to %p [%d bytes]\n", - __func__, - (int)seg + 1, - iovecptr[seg].iov_base, - iovecptr[seg].iov_base + iovecptr[seg].iov_len, - (int)iovecptr[seg].iov_len); - for (seg = 0; seg < seg_count; seg++) - gossip_debug(GOSSIP_FILE_DEBUG, - "%s: %zd) %lu\n", - __func__, - seg + 1, - seg_array[seg]); -#endif - seg = 0; while (total_count < count) { - struct iov_iter iter; size_t each_count; size_t amt_complete; @@ -579,9 +319,6 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, handle, (int)*offset); - iov_iter_init(&iter, type == PVFS_IO_READ ? READ : WRITE, - ptr, seg_array[seg], each_count); - ret = wait_for_direct_io(type, inode, offset, &iter, each_count, 0); gossip_debug(GOSSIP_FILE_DEBUG, @@ -593,9 +330,6 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, if (ret < 0) goto out; - /* advance the iovec pointer */ - ptr += seg_array[seg]; - seg++; *offset += ret; total_count += ret; amt_complete = ret; @@ -617,10 +351,6 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, if (total_count > 0) ret = total_count; out: - if (to_free) { - kfree(iovecptr); - kfree(seg_array); - } if (ret > 0) { if (type == PVFS_IO_READ) { file_accessed(file); -- GitLab From 0071ed1ec663fa87a3a8ae18f6d0812db010a343 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 18:22:08 -0400 Subject: [PATCH 0034/5324] orangefs: make do_readv_writev() take iov_iter no need to build a copy of what the caller already has; what's more, we want the one given to caller properly advanced *and* we shouldn't depend upon it being an iovec-backed one. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index ff7fe37f5a22..8dae04dc9df4 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -264,13 +264,12 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * Note: File extended attributes override any mount options. */ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, - loff_t *offset, const struct iovec *iov, unsigned long nr_segs) + loff_t *offset, struct iov_iter *iter) { struct inode *inode = file->f_mapping->host; struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; - struct iov_iter iter; - size_t count = iov_length(iov, nr_segs); + size_t count = iov_iter_count(iter); ssize_t total_count = 0; ssize_t ret = -EINVAL; @@ -295,18 +294,13 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, goto out; } - iov_iter_init(&iter, type == PVFS_IO_READ ? READ : WRITE, - iov, nr_segs, count); - - while (total_count < count) { - size_t each_count; + while (iov_iter_count(iter)) { + size_t each_count = iov_iter_count(iter); size_t amt_complete; /* how much to transfer in this loop iteration */ - each_count = - (((count - total_count) > pvfs_bufmap_size_query()) ? - pvfs_bufmap_size_query() : - (count - total_count)); + if (each_count > pvfs_bufmap_size_query()) + each_count = pvfs_bufmap_size_query(); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): size of each_count(%d)\n", @@ -319,7 +313,7 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, handle, (int)*offset); - ret = wait_for_direct_io(type, inode, offset, &iter, + ret = wait_for_direct_io(type, inode, offset, iter, each_count, 0); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): return from wait_for_io:%d\n", @@ -426,7 +420,6 @@ static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) struct file *file = iocb->ki_filp; loff_t pos = *(&iocb->ki_pos); ssize_t rc = 0; - unsigned long nr_segs = iter->nr_segs; BUG_ON(iocb->private); @@ -434,11 +427,7 @@ static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) g_pvfs2_stats.reads++; - rc = do_readv_writev(PVFS_IO_READ, - file, - &pos, - iter->iov, - nr_segs); + rc = do_readv_writev(PVFS_IO_READ, file, &pos, iter); iocb->ki_pos = pos; return rc; @@ -448,7 +437,6 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; loff_t pos = *(&iocb->ki_pos); - unsigned long nr_segs = iter->nr_segs; ssize_t rc; BUG_ON(iocb->private); @@ -482,8 +470,7 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) rc = do_readv_writev(PVFS_IO_WRITE, file, &pos, - iter->iov, - nr_segs); + iter); if (rc < 0) { gossip_err("%s: do_readv_writev failed, rc:%zd:.\n", __func__, rc); -- GitLab From 74f68fce2a395a188d454a488ea167affa4d7cf5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 18:31:05 -0400 Subject: [PATCH 0035/5324] orangefs: make pvfs2_inode_read() take iov_iter ... and make the only caller use page-backed iov_iter, getting rid of kmap/kunmap *and* of the bug with attempted use of iovec-backed copy_page_to_iter() on a kernel pointer. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 12 +++--------- fs/orangefs/inode.c | 17 +++++++---------- fs/orangefs/pvfs2-kernel.h | 3 +-- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 8dae04dc9df4..78d296bb870e 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -369,22 +369,17 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, * Data may be placed either in a user or kernel buffer. */ ssize_t pvfs2_inode_read(struct inode *inode, - char __user *buf, - size_t count, + struct iov_iter *iter, loff_t *offset, loff_t readahead_size) { struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + size_t count = iov_iter_count(iter); size_t bufmap_size; - struct iovec vec; - struct iov_iter iter; ssize_t ret = -EINVAL; g_pvfs2_stats.reads++; - vec.iov_base = buf; - vec.iov_len = count; - bufmap_size = pvfs_bufmap_size_query(); if (count > bufmap_size) { gossip_debug(GOSSIP_FILE_DEBUG, @@ -400,8 +395,7 @@ ssize_t pvfs2_inode_read(struct inode *inode, count, llu(*offset)); - iov_iter_init(&iter, READ, &vec, 1, count); - ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &iter, + ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, iter, count, readahead_size); if (ret > 0) *offset += ret; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 4f7c45a44c1f..70d1c1925ea3 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -14,18 +14,20 @@ static int read_one_page(struct page *page) { - void *page_data; int ret; int max_block; ssize_t bytes_read = 0; struct inode *inode = page->mapping->host; const __u32 blocksize = PAGE_CACHE_SIZE; /* inode->i_blksize */ const __u32 blockbits = PAGE_CACHE_SHIFT; /* inode->i_blkbits */ + struct iov_iter to; + struct bio_vec bv = {.bv_page = page, .bv_len = PAGE_SIZE}; + + iov_iter_bvec(&to, ITER_BVEC | READ, &bv, 1, PAGE_SIZE); gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpage called with page %p\n", page); - page_data = pvfs2_kmap(page); max_block = ((inode->i_size / blocksize) + 1); @@ -33,16 +35,12 @@ static int read_one_page(struct page *page) loff_t blockptr_offset = (((loff_t) page->index) << blockbits); bytes_read = pvfs2_inode_read(inode, - (char __user *) page_data, - blocksize, + &to, &blockptr_offset, inode->i_size); } - /* only zero remaining unread portions of the page data */ - if (bytes_read > 0) - memset(page_data + bytes_read, 0, blocksize - bytes_read); - else - memset(page_data, 0, blocksize); + /* this will only zero remaining unread portions of the page data */ + iov_iter_zero(~0U, &to); /* takes care of potential aliasing */ flush_dcache_page(page); if (bytes_read < 0) { @@ -54,7 +52,6 @@ static int read_one_page(struct page *page) ClearPageError(page); ret = 0; } - pvfs2_kunmap(page); /* unlock the page after the ->readpage() routine completes */ unlock_page(page); return ret; diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 29b4a48b3a25..916a35513419 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -605,8 +605,7 @@ struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref); ssize_t pvfs2_inode_read(struct inode *inode, - char __user *buf, - size_t count, + struct iov_iter *iter, loff_t *offset, loff_t readahead_size); -- GitLab From a0435ca18efe3e052393c2866a755f9ca1902268 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:09:20 -0400 Subject: [PATCH 0036/5324] orangefs: kill kmap/kunmap wrappers Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-kernel.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 916a35513419..16df1d5aa879 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -185,9 +185,6 @@ struct client_debug_mask { #define PVFS2_GFP_FLAGS (GFP_KERNEL) #define PVFS2_BUFMAP_GFP_FLAGS (GFP_KERNEL) -#define pvfs2_kmap(page) kmap(page) -#define pvfs2_kunmap(page) kunmap(page) - /* pvfs2 xattr and acl related defines */ #define PVFS2_XATTR_INDEX_POSIX_ACL_ACCESS 1 #define PVFS2_XATTR_INDEX_POSIX_ACL_DEFAULT 2 -- GitLab From 16742f2d7c1004bea5222a19428196b7125a41d1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:10:00 -0400 Subject: [PATCH 0037/5324] orangefs: use get_user_pages_fast(), not get_user_pages() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-bufmap.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index dacf42bee196..c7b0f3560734 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -171,16 +171,8 @@ pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap, int offset = 0, ret, i; /* map the pages */ - down_write(¤t->mm->mmap_sem); - ret = get_user_pages(current, - current->mm, - (unsigned long)user_desc->ptr, - bufmap->page_count, - 1, - 0, - bufmap->page_array, - NULL); - up_write(¤t->mm->mmap_sem); + ret = get_user_pages_fast((unsigned long)user_desc->ptr, + bufmap->page_count, 1, bufmap->page_array); if (ret < 0) return ret; -- GitLab From b05a7851095c24ff62d5ffeb81baeffe7acd26a2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:18:00 -0400 Subject: [PATCH 0038/5324] orangefs: double iput() in case of d_make_root() failure Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 9dee95293599..833af68c2227 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -403,10 +403,8 @@ static int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) /* allocates and places root dentry in dcache */ root_dentry = d_make_root(root); - if (!root_dentry) { - iput(root); + if (!root_dentry) return -ENOMEM; - } sb->s_export_op = &pvfs2_export_ops; sb->s_root = root_dentry; -- GitLab From 5c0dbbc64b25fde6a4e29c545ac2296fc5194b3f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:22:43 -0400 Subject: [PATCH 0039/5324] orangefs: kill struct pvfs2_mount_sb_info_s The only reason for that thing used to be the API of mount_nodev() callback; since we are calling pvfs2_fill_sb() ourselves now, we don't have to shove everything into a single structure. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-kernel.h | 12 ------------ fs/orangefs/super.c | 27 +++++++++------------------ 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 16df1d5aa879..c36868be03dc 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -364,18 +364,6 @@ struct pvfs2_sb_info_s { struct list_head list; }; -/* - * a temporary structure used only for sb mount time that groups the - * mount time data provided along with a private superblock structure - * that is allocated before a 'kernel' superblock is allocated. -*/ -struct pvfs2_mount_sb_info_s { - void *data; - struct pvfs2_khandle root_khandle; - __s32 fs_id; - int id; -}; - /* * structure that holds the state of any async I/O operation issued * through the VFS. Needed especially to handle cancellation requests diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 833af68c2227..f29e7cccdfd1 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -347,13 +347,13 @@ static struct export_operations pvfs2_export_ops = { .fh_to_dentry = pvfs2_fh_to_dentry, }; -static int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) +static int pvfs2_fill_sb(struct super_block *sb, + struct pvfs2_fs_mount_response *fs_mount, + void *data, int silent) { int ret = -EINVAL; struct inode *root = NULL; struct dentry *root_dentry = NULL; - struct pvfs2_mount_sb_info_s *mount_sb_info = - (struct pvfs2_mount_sb_info_s *) data; struct pvfs2_object_kref root_object; /* alloc and init our private pvfs2 sb info */ @@ -364,13 +364,12 @@ static int pvfs2_fill_sb(struct super_block *sb, void *data, int silent) memset(sb->s_fs_info, 0, sizeof(struct pvfs2_sb_info_s)); PVFS2_SB(sb)->sb = sb; - PVFS2_SB(sb)->root_khandle = mount_sb_info->root_khandle; - PVFS2_SB(sb)->fs_id = mount_sb_info->fs_id; - PVFS2_SB(sb)->id = mount_sb_info->id; + PVFS2_SB(sb)->root_khandle = fs_mount->root_khandle; + PVFS2_SB(sb)->fs_id = fs_mount->fs_id; + PVFS2_SB(sb)->id = fs_mount->id; - if (mount_sb_info->data) { - ret = parse_mount_options(sb, mount_sb_info->data, - silent); + if (data) { + ret = parse_mount_options(sb, data, silent); if (ret) return ret; } @@ -419,7 +418,6 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, int ret = -EINVAL; struct super_block *sb = ERR_PTR(-EINVAL); struct pvfs2_kernel_op_s *new_op; - struct pvfs2_mount_sb_info_s mount_sb_info; struct dentry *d = ERR_PTR(-EINVAL); gossip_debug(GOSSIP_SUPER_DEBUG, @@ -455,13 +453,6 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, goto free_op; } - /* fill in temporary structure passed to fill_sb method */ - mount_sb_info.data = data; - mount_sb_info.root_khandle = - new_op->downcall.resp.fs_mount.root_khandle; - mount_sb_info.fs_id = new_op->downcall.resp.fs_mount.fs_id; - mount_sb_info.id = new_op->downcall.resp.fs_mount.id; - sb = sget(fst, NULL, set_anon_super, flags, NULL); if (IS_ERR(sb)) { @@ -470,7 +461,7 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, } ret = pvfs2_fill_sb(sb, - (void *)&mount_sb_info, + &new_op->downcall.resp.fs_mount, data, flags & MS_SILENT ? 1 : 0); if (ret) { -- GitLab From 75992b0fa95a667d8f436962ea6a694fe992c001 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:27:40 -0400 Subject: [PATCH 0040/5324] pvfs2_fill_sb(): use kzalloc() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index f29e7cccdfd1..45db0772a767 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -358,10 +358,9 @@ static int pvfs2_fill_sb(struct super_block *sb, /* alloc and init our private pvfs2 sb info */ sb->s_fs_info = - kmalloc(sizeof(struct pvfs2_sb_info_s), PVFS2_GFP_FLAGS); + kzalloc(sizeof(struct pvfs2_sb_info_s), PVFS2_GFP_FLAGS); if (!PVFS2_SB(sb)) return -ENOMEM; - memset(sb->s_fs_info, 0, sizeof(struct pvfs2_sb_info_s)); PVFS2_SB(sb)->sb = sb; PVFS2_SB(sb)->root_khandle = fs_mount->root_khandle; -- GitLab From aada5c5872aa3048980a0e6926efd9086dc98532 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 20:35:36 -0400 Subject: [PATCH 0041/5324] orangefs: kill pointless ->link() and ->mknod() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/namei.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 05f6feadfd0d..39f96ace0289 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -242,27 +242,6 @@ static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) return ret; } -/* - * PVFS2 does not support hard links. - */ -static int pvfs2_link(struct dentry *old_dentry, - struct inode *dir, - struct dentry *dentry) -{ - return -EPERM; -} - -/* - * PVFS2 does not support special files. - */ -static int pvfs2_mknod(struct inode *dir, - struct dentry *dentry, - umode_t mode, - dev_t rdev) -{ - return -EPERM; -} - static int pvfs2_symlink(struct inode *dir, struct dentry *dentry, const char *symname) @@ -453,12 +432,10 @@ struct inode_operations pvfs2_dir_inode_operations = { .get_acl = pvfs2_get_acl, .set_acl = pvfs2_set_acl, .create = pvfs2_create, - .link = pvfs2_link, .unlink = pvfs2_unlink, .symlink = pvfs2_symlink, .mkdir = pvfs2_mkdir, .rmdir = pvfs2_unlink, - .mknod = pvfs2_mknod, .rename = pvfs2_rename, .setattr = pvfs2_setattr, .getattr = pvfs2_getattr, -- GitLab From 5714156be232b088e24c74fe4e95cb900a8b12e0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 Oct 2015 22:02:00 -0400 Subject: [PATCH 0042/5324] orangefs: sanitize pvfs2_convert_time_field() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-kernel.h | 5 ++++- fs/orangefs/pvfs2-utils.c | 13 ++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index c36868be03dc..e96251717966 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -638,7 +638,10 @@ int pvfs2_unmount_sb(struct super_block *sb); int pvfs2_cancel_op_in_progress(__u64 tag); -__u64 pvfs2_convert_time_field(void *time_ptr); +static inline __u64 pvfs2_convert_time_field(const struct timespec *ts) +{ + return (__u64)ts->tv_sec; +} int pvfs2_normalize_to_errno(__s32 error_code); diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index c33e7193599c..1180a2480d2b 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -298,7 +298,7 @@ static inline int copy_attributes_from_inode(struct inode *inode, attrs->mask |= PVFS_ATTR_SYS_ATIME; if (iattr->ia_valid & ATTR_ATIME_SET) { attrs->atime = - pvfs2_convert_time_field((void *)&iattr->ia_atime); + pvfs2_convert_time_field(&iattr->ia_atime); attrs->mask |= PVFS_ATTR_SYS_ATIME_SET; } } @@ -306,7 +306,7 @@ static inline int copy_attributes_from_inode(struct inode *inode, attrs->mask |= PVFS_ATTR_SYS_MTIME; if (iattr->ia_valid & ATTR_MTIME_SET) { attrs->mtime = - pvfs2_convert_time_field((void *)&iattr->ia_mtime); + pvfs2_convert_time_field(&iattr->ia_mtime); attrs->mask |= PVFS_ATTR_SYS_MTIME_SET; } } @@ -653,15 +653,6 @@ void set_signals(sigset_t *sigset) sigprocmask(SIG_SETMASK, sigset, NULL); } -__u64 pvfs2_convert_time_field(void *time_ptr) -{ - __u64 pvfs2_time; - struct timespec *tspec = (struct timespec *)time_ptr; - - pvfs2_time = (__u64) ((time_t) tspec->tv_sec); - return pvfs2_time; -} - /* * The following is a very dirty hack that is now a permanent part of the * PVFS2 protocol. See protocol.h for more error definitions. -- GitLab From ef4af94edcf8fc32ab1d4141537a4eb29ff45a40 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Oct 2015 13:23:16 -0400 Subject: [PATCH 0043/5324] orangefs: switch decode_dirents() to use of kcalloc() gets rid of multiplication overflow Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index daf497384501..280755db1814 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -27,7 +27,7 @@ static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) readdir->token = rd->token; readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount; - readdir->dirent_array = kmalloc(readdir->pvfs_dirent_outcount * + readdir->dirent_array = kcalloc(readdir->pvfs_dirent_outcount, sizeof(*readdir->dirent_array), GFP_KERNEL); if (readdir->dirent_array == NULL) -- GitLab From 9be68b08719c10cc3cc9305e7b2452475a9dcacd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Oct 2015 17:43:15 -0400 Subject: [PATCH 0044/5324] orangefs: get rid of dec_string and enc_string The latter is never used, the former has one user and would be better off spelled out right there. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 15 ++++++++------- fs/orangefs/pvfs2-dev-proto.h | 16 ---------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 280755db1814..eb4c3d334088 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -23,7 +23,6 @@ static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) struct pvfs2_readdir_response_s *rd = (struct pvfs2_readdir_response_s *) ptr; char *buf = ptr; - char **pptr = &buf; readdir->token = rd->token; readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount; @@ -32,15 +31,17 @@ static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) GFP_KERNEL); if (readdir->dirent_array == NULL) return -ENOMEM; - *pptr += offsetof(struct pvfs2_readdir_response_s, dirent_array); + buf += offsetof(struct pvfs2_readdir_response_s, dirent_array); for (i = 0; i < readdir->pvfs_dirent_outcount; i++) { - dec_string(pptr, &readdir->dirent_array[i].d_name, - &readdir->dirent_array[i].d_length); + __u32 len = *(__u32 *)buf; + readdir->dirent_array[i].d_name = buf + 4; + buf += roundup8(4 + len + 1); + readdir->dirent_array[i].d_length = len; readdir->dirent_array[i].khandle = - *(struct pvfs2_khandle *) *pptr; - *pptr += 16; + *(struct pvfs2_khandle *) buf; + buf += 16; } - return (unsigned long)*pptr - (unsigned long)ptr; + return buf - ptr; } static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/pvfs2-dev-proto.h index 9c82e6e651f3..68b1bc6e57b4 100644 --- a/fs/orangefs/pvfs2-dev-proto.h +++ b/fs/orangefs/pvfs2-dev-proto.h @@ -78,22 +78,6 @@ #define roundup8(x) (((x)+7) & ~7) #endif -/* strings; decoding just points into existing character data */ -#define enc_string(pptr, pbuf) do { \ - __u32 len = strlen(*pbuf); \ - *(__u32 *) *(pptr) = (len); \ - memcpy(*(pptr)+4, *pbuf, len+1); \ - *(pptr) += roundup8(4 + len + 1); \ -} while (0) - -#define dec_string(pptr, pbuf, plen) do { \ - __u32 len = (*(__u32 *) *(pptr)); \ - *pbuf = *(pptr) + 4; \ - *(pptr) += roundup8(4 + len + 1); \ - if (plen) \ - *plen = len;\ -} while (0) - struct read_write_x { __s64 off; __s64 len; -- GitLab From ade1d48b788996e05fb9914dfb62993b1c279357 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Oct 2015 17:51:36 -0400 Subject: [PATCH 0045/5324] orangefs: don't leave uninitialized data in ->trailer_buf minimal fix; it would be better to reject such requests outright. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index ede842f05b62..7a719900235f 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -352,18 +352,20 @@ static ssize_t pvfs2_devreq_writev(struct file *file, * to reset trailer size on op errors. */ if (op->downcall.status == 0 && op->downcall.trailer_size > 0) { + __u64 trailer_size = op->downcall.trailer_size; + size_t size; gossip_debug(GOSSIP_DEV_DEBUG, "writev: trailer size %ld\n", - (unsigned long)op->downcall.trailer_size); + (unsigned long)size); if (count != (notrailer_count + 1)) { - gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)op->downcall.trailer_size, count); + gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)trailer_size, count); dev_req_release(buffer); put_op(op); return -EPROTO; } - if (iov[notrailer_count].iov_len > - op->downcall.trailer_size) { - gossip_err("writev error: trailer size (%ld) != iov_len (%ld)\n", (unsigned long)op->downcall.trailer_size, (unsigned long)iov[notrailer_count].iov_len); + size = iov[notrailer_count].iov_len; + if (size > trailer_size) { + gossip_err("writev error: trailer size (%ld) != iov_len (%zd)\n", (unsigned long)trailer_size, size); dev_req_release(buffer); put_op(op); return -EMSGSIZE; @@ -371,16 +373,14 @@ static ssize_t pvfs2_devreq_writev(struct file *file, /* Allocate a buffer large enough to hold the * trailer bytes. */ - op->downcall.trailer_buf = - vmalloc(op->downcall.trailer_size); + op->downcall.trailer_buf = vmalloc(trailer_size); if (op->downcall.trailer_buf != NULL) { gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n", op->downcall.trailer_buf); ret = copy_from_user(op->downcall.trailer_buf, iov[notrailer_count]. iov_base, - iov[notrailer_count]. - iov_len); + size); if (ret) { gossip_err("Failed to copy trailer data from user space\n"); dev_req_release(buffer); @@ -392,6 +392,8 @@ static ssize_t pvfs2_devreq_writev(struct file *file, put_op(op); return -EIO; } + memset(op->downcall.trailer_buf + size, 0, + trailer_size - size); } else { /* Change downcall status */ op->downcall.status = -ENOMEM; -- GitLab From 8092895f759ede31634d0f0fc85a74d970552c49 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 9 Oct 2015 18:11:10 -0400 Subject: [PATCH 0046/5324] orangefs: validate the response in decode_dirents() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index eb4c3d334088..3049cd61b700 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -17,13 +17,17 @@ struct readdir_handle_s { /* * decode routine needed by kmod to make sense of the shared page for readdirs. */ -static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) +static long decode_dirents(char *ptr, size_t size, + struct pvfs2_readdir_response_s *readdir) { int i; struct pvfs2_readdir_response_s *rd = (struct pvfs2_readdir_response_s *) ptr; char *buf = ptr; + if (size < offsetof(struct pvfs2_readdir_response_s, dirent_array)) + return -EINVAL; + readdir->token = rd->token; readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount; readdir->dirent_array = kcalloc(readdir->pvfs_dirent_outcount, @@ -31,21 +35,43 @@ static long decode_dirents(char *ptr, struct pvfs2_readdir_response_s *readdir) GFP_KERNEL); if (readdir->dirent_array == NULL) return -ENOMEM; + buf += offsetof(struct pvfs2_readdir_response_s, dirent_array); + size -= offsetof(struct pvfs2_readdir_response_s, dirent_array); + for (i = 0; i < readdir->pvfs_dirent_outcount; i++) { - __u32 len = *(__u32 *)buf; + __u32 len; + + if (size < 4) + goto Einval; + + len = *(__u32 *)buf; + if (len >= (unsigned)-24) + goto Einval; + readdir->dirent_array[i].d_name = buf + 4; - buf += roundup8(4 + len + 1); readdir->dirent_array[i].d_length = len; + + len = roundup8(4 + len + 1); + if (size < len + 16) + goto Einval; + size -= len + 16; + + buf += len; + readdir->dirent_array[i].khandle = *(struct pvfs2_khandle *) buf; buf += 16; } return buf - ptr; +Einval: + kfree(readdir->dirent_array); + readdir->dirent_array = NULL; + return -EINVAL; } static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, - int buffer_index) + size_t size, int buffer_index) { long ret; @@ -61,7 +87,7 @@ static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, } rhandle->buffer_index = buffer_index; rhandle->dents_buf = buf; - ret = decode_dirents(buf, &rhandle->readdir_response); + ret = decode_dirents(buf, size, &rhandle->readdir_response); if (ret < 0) { gossip_err("Could not decode readdir from buffer %ld\n", ret); rhandle->buffer_index = -1; @@ -209,6 +235,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) bytes_decoded = readdir_handle_ctor(&rhandle, new_op->downcall.trailer_buf, + new_op->downcall.trailer_size, buffer_index); if (bytes_decoded < 0) { gossip_err("pvfs2_readdir: Could not decode trailer buffer into a readdir response %d\n", -- GitLab From 3f1b6947dcfa76de0b690022dcf3ed8814744aa7 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 13 Nov 2015 13:05:11 -0500 Subject: [PATCH 0047/5324] Orangefs: set pos after generic_write_checks if we are appending, generic_write_checks would have updated pos to the end of the file... Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 78d296bb870e..78a46968a994 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -430,7 +430,7 @@ static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; - loff_t pos = *(&iocb->ki_pos); + loff_t pos; ssize_t rc; BUG_ON(iocb->private); @@ -461,6 +461,13 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) goto out; } + /* + * if we are appending, generic_write_checks would have updated + * pos to the end of the file, so we will wait till now to set + * pos... + */ + pos = *(&iocb->ki_pos); + rc = do_readv_writev(PVFS_IO_WRITE, file, &pos, -- GitLab From 6d0dd7684cc8d010ab3082db572534dffd2ad42d Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Wed, 7 Oct 2015 13:40:54 -0400 Subject: [PATCH 0048/5324] Orangefs: Remove unused #defines from signal blocking code. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/pvfs2-kernel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index e96251717966..8b7d57118f9e 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -806,8 +806,6 @@ do { \ #define pvfs2_lock_inode(inode) spin_lock(&inode->i_lock) #define pvfs2_unlock_inode(inode) spin_unlock(&inode->i_lock) -#define pvfs2_current_signal_lock current->sighand->siglock -#define pvfs2_current_sigaction current->sighand->action #define fill_default_sys_attrs(sys_attr, type, mode) \ do { \ -- GitLab From b5bbc84328556bb653412b8e9682b8fdb091866a Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 13 Nov 2015 14:39:15 -0500 Subject: [PATCH 0049/5324] Orangefs: fix gossip statement Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index 7a719900235f..dbf52ab1e569 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -356,7 +356,7 @@ static ssize_t pvfs2_devreq_writev(struct file *file, size_t size; gossip_debug(GOSSIP_DEV_DEBUG, "writev: trailer size %ld\n", - (unsigned long)size); + (unsigned long)trailer_size); if (count != (notrailer_count + 1)) { gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)trailer_size, count); dev_req_release(buffer); -- GitLab From f0ed4418d46db587eca981065ef5014332678606 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Fri, 13 Nov 2015 14:26:09 -0500 Subject: [PATCH 0050/5324] Orangefs: Remove upcall trailers which are not used. Also removes remnants of iox (readx/writex) which previously used trailers, but no longer exist. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 117 ++++++++++------------------------ fs/orangefs/downcall.h | 5 -- fs/orangefs/pvfs2-cache.c | 16 +---- fs/orangefs/pvfs2-dev-proto.h | 1 - fs/orangefs/pvfs2-kernel.h | 14 ---- fs/orangefs/upcall.h | 11 +--- 6 files changed, 36 insertions(+), 128 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index dbf52ab1e569..34e2240f1d29 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -139,20 +139,6 @@ static ssize_t pvfs2_devreq_read(struct file *file, cur_op = op; spin_lock(&cur_op->lock); list_del(&cur_op->list); - cur_op->op_linger_tmp--; - /* - * if there is a trailer, re-add it to - * the request list. - */ - if (cur_op->op_linger == 2 && - cur_op->op_linger_tmp == 1) { - if (cur_op->upcall.trailer_size <= 0 || - cur_op->upcall.trailer_buf == NULL) - gossip_err("BUG:trailer_size is %ld and trailer buf is %p\n", (long)cur_op->upcall.trailer_size, cur_op->upcall.trailer_buf); - /* re-add it to the head of the list */ - list_add(&cur_op->list, - &pvfs2_request_list); - } spin_unlock(&cur_op->lock); break; } @@ -167,11 +153,8 @@ static ssize_t pvfs2_devreq_read(struct file *file, "client-core: reading op tag %llu %s\n", llu(cur_op->tag), get_opname_string(cur_op)); if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) { - if (cur_op->op_linger == 1) - gossip_err("WARNING: Current op already queued...skipping\n"); - } else if (cur_op->op_linger == 1 || - (cur_op->op_linger == 2 && - cur_op->op_linger_tmp == 0)) { + gossip_err("WARNING: Current op already queued...skipping\n"); + } else { /* * atomically move the operation to the * htable_ops_in_progress @@ -182,71 +165,40 @@ static ssize_t pvfs2_devreq_read(struct file *file, spin_unlock(&cur_op->lock); - /* 2 cases - * a) OPs with no trailers - * b) OPs with trailers, Stage 1 - * Either way push the upcall out - */ - if (cur_op->op_linger == 1 || - (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 1)) { - len = MAX_ALIGNED_DEV_REQ_UPSIZE; - if ((size_t) len <= count) { - ret = copy_to_user(buf, - &proto_ver, - sizeof(__s32)); + /* Push the upcall out */ + len = MAX_ALIGNED_DEV_REQ_UPSIZE; + if ((size_t) len <= count) { + ret = copy_to_user(buf, + &proto_ver, + sizeof(__s32)); + if (ret == 0) { + ret = copy_to_user(buf + sizeof(__s32), + &magic, + sizeof(__s32)); + if (ret == 0) { + ret = copy_to_user(buf+2 * sizeof(__s32), + &cur_op->tag, + sizeof(__u64)); if (ret == 0) { - ret = copy_to_user(buf + sizeof(__s32), - &magic, - sizeof(__s32)); - if (ret == 0) { - ret = copy_to_user(buf+2 * sizeof(__s32), - &cur_op->tag, - sizeof(__u64)); - if (ret == 0) { - ret = copy_to_user( - buf + - 2 * - sizeof(__s32) + - sizeof(__u64), - &cur_op->upcall, - sizeof(struct pvfs2_upcall_s)); - } - } - } - - if (ret) { - gossip_err("Failed to copy data to user space\n"); - len = -EFAULT; + ret = copy_to_user( + buf + + 2 * + sizeof(__s32) + + sizeof(__u64), + &cur_op->upcall, + sizeof(struct pvfs2_upcall_s)); } - } else { - gossip_err - ("Failed to copy data to user space\n"); - len = -EIO; - } - } - /* Stage 2: Push the trailer out */ - else if (cur_op->op_linger == 2 && cur_op->op_linger_tmp == 0) { - len = cur_op->upcall.trailer_size; - if ((size_t) len <= count) { - ret = copy_to_user(buf, - cur_op->upcall.trailer_buf, - len); - if (ret) { - gossip_err("Failed to copy trailer to user space\n"); - len = -EFAULT; - } - } else { - gossip_err("Read buffer for trailer is too small (%ld as opposed to %ld)\n", - (long)count, - (long)len); - len = -EIO; } + } + + if (ret) { + gossip_err("Failed to copy data to user space\n"); + len = -EFAULT; + } } else { - gossip_err("cur_op: %p (op_linger %d), (op_linger_tmp %d), erroneous request list?\n", - cur_op, - cur_op->op_linger, - cur_op->op_linger_tmp); - len = 0; + gossip_err + ("Failed to copy data to user space\n"); + len = -EIO; } } else if (file->f_flags & O_NONBLOCK) { /* @@ -413,9 +365,8 @@ static ssize_t pvfs2_devreq_writev(struct file *file, * application reading/writing this device to return until * the buffers are done being used. */ - if ((op->upcall.type == PVFS2_VFS_OP_FILE_IO && - op->upcall.req.io.async_vfs_io == PVFS_VFS_SYNC_IO) || - op->upcall.type == PVFS2_VFS_OP_FILE_IOX) { + if (op->upcall.type == PVFS2_VFS_OP_FILE_IO && + op->upcall.req.io.async_vfs_io == PVFS_VFS_SYNC_IO) { int timed_out = 0; DECLARE_WAITQUEUE(wait_entry, current); diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h index f8bea46e7c6a..e372f446f6ba 100644 --- a/fs/orangefs/downcall.h +++ b/fs/orangefs/downcall.h @@ -19,10 +19,6 @@ struct pvfs2_io_response { __s64 amt_complete; }; -struct pvfs2_iox_response { - __s64 amt_complete; -}; - struct pvfs2_lookup_response { struct pvfs2_object_kref refn; }; @@ -111,7 +107,6 @@ struct pvfs2_downcall_s { union { struct pvfs2_io_response io; - struct pvfs2_iox_response iox; struct pvfs2_lookup_response lookup; struct pvfs2_create_response create; struct pvfs2_symlink_response sym; diff --git a/fs/orangefs/pvfs2-cache.c b/fs/orangefs/pvfs2-cache.c index 15251884ba4a..f982616a4349 100644 --- a/fs/orangefs/pvfs2-cache.c +++ b/fs/orangefs/pvfs2-cache.c @@ -103,13 +103,11 @@ char *get_opname_string(struct pvfs2_kernel_op_s *new_op) return "OP_FSYNC"; else if (type == PVFS2_VFS_OP_FSKEY) return "OP_FSKEY"; - else if (type == PVFS2_VFS_OP_FILE_IOX) - return "OP_FILE_IOX"; } return "OP_UNKNOWN?"; } -static struct pvfs2_kernel_op_s *op_alloc_common(__s32 op_linger, __s32 type) +struct pvfs2_kernel_op_s *op_alloc(__s32 type) { struct pvfs2_kernel_op_s *new_op = NULL; @@ -145,24 +143,12 @@ static struct pvfs2_kernel_op_s *op_alloc_common(__s32 op_linger, __s32 type) new_op->upcall.gid = from_kgid(current_user_ns(), current_fsgid()); - - new_op->op_linger = new_op->op_linger_tmp = op_linger; } else { gossip_err("op_alloc: kmem_cache_alloc failed!\n"); } return new_op; } -struct pvfs2_kernel_op_s *op_alloc(__s32 type) -{ - return op_alloc_common(1, type); -} - -struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type) -{ - return op_alloc_common(2, type); -} - void op_release(struct pvfs2_kernel_op_s *pvfs2_op) { if (pvfs2_op) { diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/pvfs2-dev-proto.h index 68b1bc6e57b4..71ab56df4ad7 100644 --- a/fs/orangefs/pvfs2-dev-proto.h +++ b/fs/orangefs/pvfs2-dev-proto.h @@ -41,7 +41,6 @@ #define PVFS2_VFS_OP_FSYNC 0xFF00EE01 #define PVFS2_VFS_OP_FSKEY 0xFF00EE02 #define PVFS2_VFS_OP_READDIRPLUS 0xFF00EE03 -#define PVFS2_VFS_OP_FILE_IOX 0xFF00EE04 /* * Misc constants. Please retain them as multiples of 8! diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 8b7d57118f9e..ac90b6365fd3 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -279,19 +279,6 @@ struct pvfs2_kernel_op_s { int io_completed; wait_queue_head_t io_completion_waitq; - /* - * upcalls requiring variable length trailers require that this struct - * be in the request list even after client-core does a read() on the - * device to dequeue the upcall. - * if op_linger field goes to 0, we dequeue this op off the list. - * else we let it stay. What gets passed to the read() is - * a) if op_linger field is = 1, pvfs2_kernel_op_s itself - * b) else if = 0, we pass ->upcall.trailer_buf - * We expect to have only a single upcall trailer buffer, - * so we expect callers with trailers - * to set this field to 2 and others to set it to 1. - */ - __s32 op_linger, op_linger_tmp; /* VFS aio fields */ /* used by the async I/O code to stash the pvfs2_kiocb_s structure */ @@ -507,7 +494,6 @@ static inline int match_handle(struct pvfs2_khandle resp_handle, int op_cache_initialize(void); int op_cache_finalize(void); struct pvfs2_kernel_op_s *op_alloc(__s32 type); -struct pvfs2_kernel_op_s *op_alloc_trailer(__s32 type); char *get_opname_string(struct pvfs2_kernel_op_s *new_op); void op_release(struct pvfs2_kernel_op_s *op); diff --git a/fs/orangefs/upcall.h b/fs/orangefs/upcall.h index 1e07f626aac6..0805778a8185 100644 --- a/fs/orangefs/upcall.h +++ b/fs/orangefs/upcall.h @@ -23,14 +23,6 @@ struct pvfs2_io_request_s { __s32 readahead_size; }; -struct pvfs2_iox_request_s { - __s32 buf_index; - __s32 count; - struct pvfs2_object_kref refn; - enum PVFS_io_type io_type; - __s32 __pad1; -}; - struct pvfs2_lookup_request_s { __s32 sym_follow; __s32 __pad1; @@ -218,13 +210,12 @@ struct pvfs2_upcall_s { __u32 gid; int pid; int tgid; - /* currently trailer is used only by readx/writex (iox) */ + /* Trailers unused but must be retained for protocol compatibility. */ __s64 trailer_size; char *trailer_buf; union { struct pvfs2_io_request_s io; - struct pvfs2_iox_request_s iox; struct pvfs2_lookup_request_s lookup; struct pvfs2_create_request_s create; struct pvfs2_symlink_request_s sym; -- GitLab From 24c8d0804be00da90af9efa8eb404bd7a3284ba9 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Fri, 13 Nov 2015 14:26:10 -0500 Subject: [PATCH 0051/5324] Orangefs: Clean up pvfs2_devreq_read. * Kick invalid arguments out early, so handling them does not clutter the code. * Avoid possibility of race by not releasing lock until completely done. * Do not leak ops (memory) in certain error condition. * Check for more error conditions. * Put module name in all error and debug logs. * Document behavior. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/devpvfs2-req.c | 207 +++++++++++++++++++++---------------- 1 file changed, 117 insertions(+), 90 deletions(-) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index 34e2240f1d29..e37b6479a6a1 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -104,110 +104,137 @@ static ssize_t pvfs2_devreq_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { - int ret = 0; - ssize_t len = 0; - struct pvfs2_kernel_op_s *cur_op = NULL; - static __s32 magic = PVFS2_DEVREQ_MAGIC; + struct pvfs2_kernel_op_s *op, *temp; __s32 proto_ver = PVFS_KERNEL_PROTO_VERSION; + static __s32 magic = PVFS2_DEVREQ_MAGIC; + struct pvfs2_kernel_op_s *cur_op = NULL; + unsigned long ret; + /* We do not support blocking IO. */ if (!(file->f_flags & O_NONBLOCK)) { - /* We do not support blocking reads/opens any more */ - gossip_err("pvfs2: blocking reads are not supported! (pvfs2-client-core bug)\n"); + gossip_err("orangefs: blocking reads are not supported! (pvfs2-client-core bug)\n"); return -EINVAL; - } else { - struct pvfs2_kernel_op_s *op = NULL, *temp = NULL; - /* get next op (if any) from top of list */ - spin_lock(&pvfs2_request_list_lock); - list_for_each_entry_safe(op, temp, &pvfs2_request_list, list) { - __s32 fsid = fsid_of_op(op); - /* - * Check if this op's fsid is known and needs - * remounting - */ - if (fsid != PVFS_FS_ID_NULL && - fs_mount_pending(fsid) == 1) { + } + + /* + * The client will do an ioctl to find MAX_ALIGNED_DEV_REQ_UPSIZE, then + * always read with that size buffer. + */ + if (count != MAX_ALIGNED_DEV_REQ_UPSIZE) { + gossip_err("orangefs: client-core tried to read wrong size\n"); + return -EINVAL; + } + + /* Get next op (if any) from top of list. */ + spin_lock(&pvfs2_request_list_lock); + list_for_each_entry_safe(op, temp, &pvfs2_request_list, list) { + __s32 fsid; + /* This lock is held past the end of the loop when we break. */ + spin_lock(&op->lock); + + fsid = fsid_of_op(op); + if (fsid != PVFS_FS_ID_NULL) { + int ret; + /* Skip ops whose filesystem needs to be mounted. */ + ret = fs_mount_pending(fsid); + if (ret == 1) { gossip_debug(GOSSIP_DEV_DEBUG, - "Skipping op tag %llu %s\n", - llu(op->tag), - get_opname_string(op)); + "orangefs: skipping op tag %llu %s\n", + llu(op->tag), get_opname_string(op)); + spin_unlock(&op->lock); + continue; + /* Skip ops whose filesystem we don't know about unless + * it is being mounted. */ + /* XXX: is there a better way to detect this? */ + } else if (ret == -1 && + !(op->upcall.type == PVFS2_VFS_OP_FS_MOUNT || + op->upcall.type == PVFS2_VFS_OP_GETATTR)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "orangefs: skipping op tag %llu %s\n", + llu(op->tag), get_opname_string(op)); + gossip_err( + "orangefs: ERROR: fs_mount_pending %d\n", + fsid); + spin_unlock(&op->lock); continue; - } else { - /* - * op does not belong to any particular fsid - * or already mounted.. let it through - */ - cur_op = op; - spin_lock(&cur_op->lock); - list_del(&cur_op->list); - spin_unlock(&cur_op->lock); - break; } } - spin_unlock(&pvfs2_request_list_lock); + /* + * Either this op does not pertain to a filesystem, is mounting + * a filesystem, or pertains to a mounted filesystem. Let it + * through. + */ + cur_op = op; + break; } - if (cur_op) { - spin_lock(&cur_op->lock); + /* + * At this point we either have a valid op and can continue or have not + * found an op and must ask the client to try again later. + */ + if (!cur_op) { + spin_unlock(&pvfs2_request_list_lock); + return -EAGAIN; + } - gossip_debug(GOSSIP_DEV_DEBUG, - "client-core: reading op tag %llu %s\n", - llu(cur_op->tag), get_opname_string(cur_op)); - if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) { - gossip_err("WARNING: Current op already queued...skipping\n"); - } else { - /* - * atomically move the operation to the - * htable_ops_in_progress - */ - set_op_state_inprogress(cur_op); - pvfs2_devreq_add_op(cur_op); - } + gossip_debug(GOSSIP_DEV_DEBUG, "orangefs: reading op tag %llu %s\n", + llu(cur_op->tag), get_opname_string(cur_op)); + /* + * Such an op should never be on the list in the first place. If so, we + * will abort. + */ + if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) { + gossip_err("orangefs: ERROR: Current op already queued.\n"); + list_del(&cur_op->list); spin_unlock(&cur_op->lock); - - /* Push the upcall out */ - len = MAX_ALIGNED_DEV_REQ_UPSIZE; - if ((size_t) len <= count) { - ret = copy_to_user(buf, - &proto_ver, - sizeof(__s32)); - if (ret == 0) { - ret = copy_to_user(buf + sizeof(__s32), - &magic, - sizeof(__s32)); - if (ret == 0) { - ret = copy_to_user(buf+2 * sizeof(__s32), - &cur_op->tag, - sizeof(__u64)); - if (ret == 0) { - ret = copy_to_user( - buf + - 2 * - sizeof(__s32) + - sizeof(__u64), - &cur_op->upcall, - sizeof(struct pvfs2_upcall_s)); - } - } - } - - if (ret) { - gossip_err("Failed to copy data to user space\n"); - len = -EFAULT; - } - } else { - gossip_err - ("Failed to copy data to user space\n"); - len = -EIO; - } - } else if (file->f_flags & O_NONBLOCK) { - /* - * if in non-blocking mode, return EAGAIN since no requests are - * ready yet - */ - len = -EAGAIN; + spin_unlock(&pvfs2_request_list_lock); + return -EAGAIN; } - return len; + + /* + * Set the operation to be in progress and move it between lists since + * it has been sent to the client. + */ + set_op_state_inprogress(cur_op); + + list_del(&cur_op->list); + spin_unlock(&pvfs2_request_list_lock); + pvfs2_devreq_add_op(cur_op); + spin_unlock(&cur_op->lock); + + /* Push the upcall out. */ + ret = copy_to_user(buf, &proto_ver, sizeof(__s32)); + if (ret != 0) + goto error; + ret = copy_to_user(buf+sizeof(__s32), &magic, sizeof(__s32)); + if (ret != 0) + goto error; + ret = copy_to_user(buf+2 * sizeof(__s32), &cur_op->tag, sizeof(__u64)); + if (ret != 0) + goto error; + ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall, + sizeof(struct pvfs2_upcall_s)); + if (ret != 0) + goto error; + + /* The client only asks to read one size buffer. */ + return MAX_ALIGNED_DEV_REQ_UPSIZE; +error: + /* + * We were unable to copy the op data to the client. Put the op back in + * list. If client has crashed, the op will be purged later when the + * device is released. + */ + gossip_err("orangefs: Failed to copy data to user space\n"); + spin_lock(&pvfs2_request_list_lock); + spin_lock(&cur_op->lock); + set_op_state_waiting(cur_op); + pvfs2_devreq_remove_op(cur_op->tag); + list_add(&cur_op->list, &pvfs2_request_list); + spin_unlock(&cur_op->lock); + spin_unlock(&pvfs2_request_list_lock); + return -EFAULT; } /* Function for writev() callers into the device */ -- GitLab From 555fa0fa618b846c5b38406347b7d53ace320ac6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 11 Nov 2015 16:33:39 +0000 Subject: [PATCH 0052/5324] fs: out of bounds on stack in iov_iter_advance On Wed, Nov 11, 2015 at 10:19:48AM +0000, Al Viro wrote: > I'll cook the minimal fixup for API change after I get some sleep and > send it your way, unless somebody gets there first... This should do it - switches ->ioctl() to pvfs2_inode_[gs]etxattr() and converts xattr_handler ->[gs]et() to new API. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 19 +++++++--------- fs/orangefs/pvfs2-kernel.h | 13 ----------- fs/orangefs/xattr.c | 44 +++++++++++++++++++------------------- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 78a46968a994..3a8140f289f6 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -506,11 +506,10 @@ static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) */ if (cmd == FS_IOC_GETFLAGS) { val = 0; - ret = pvfs2_xattr_get_default(file->f_path.dentry, - "user.pvfs2.meta_hint", - &val, - sizeof(val), - 0); + ret = pvfs2_inode_getxattr(file_inode(file), + PVFS2_XATTR_NAME_DEFAULT_PREFIX, + "user.pvfs2.meta_hint", + &val, sizeof(val)); if (ret < 0 && ret != -ENODATA) return ret; else if (ret == -ENODATA) @@ -540,12 +539,10 @@ static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_ioctl: FS_IOC_SETFLAGS: %llu\n", (unsigned long long)val); - ret = pvfs2_xattr_set_default(file->f_path.dentry, - "user.pvfs2.meta_hint", - &val, - sizeof(val), - 0, - 0); + ret = pvfs2_inode_setxattr(file_inode(file), + PVFS2_XATTR_NAME_DEFAULT_PREFIX, + "user.pvfs2.meta_hint", + &val, sizeof(val), 0); } return ret; diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index ac90b6365fd3..4295e263e25b 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -234,19 +234,6 @@ extern const struct xattr_handler *pvfs2_xattr_handlers[]; extern struct posix_acl *pvfs2_get_acl(struct inode *inode, int type); extern int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); -int pvfs2_xattr_set_default(struct dentry *dentry, - const char *name, - const void *buffer, - size_t size, - int flags, - int handler_flags); - -int pvfs2_xattr_get_default(struct dentry *dentry, - const char *name, - void *buffer, - size_t size, - int handler_flags); - /* * Redefine xtvec structure so that we could move helper functions out of * the define diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index 227eaa47b1e1..b683daab7425 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -447,12 +447,12 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) return ret; } -int pvfs2_xattr_set_default(struct dentry *dentry, - const char *name, - const void *buffer, - size_t size, - int flags, - int handler_flags) +static int pvfs2_xattr_set_default(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags) { return pvfs2_inode_setxattr(dentry->d_inode, PVFS2_XATTR_NAME_DEFAULT_PREFIX, @@ -462,11 +462,11 @@ int pvfs2_xattr_set_default(struct dentry *dentry, flags); } -int pvfs2_xattr_get_default(struct dentry *dentry, - const char *name, - void *buffer, - size_t size, - int handler_flags) +static int pvfs2_xattr_get_default(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + void *buffer, + size_t size) { return pvfs2_inode_getxattr(dentry->d_inode, PVFS2_XATTR_NAME_DEFAULT_PREFIX, @@ -476,12 +476,12 @@ int pvfs2_xattr_get_default(struct dentry *dentry, } -static int pvfs2_xattr_set_trusted(struct dentry *dentry, - const char *name, - const void *buffer, - size_t size, - int flags, - int handler_flags) +static int pvfs2_xattr_set_trusted(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags) { return pvfs2_inode_setxattr(dentry->d_inode, PVFS2_XATTR_NAME_TRUSTED_PREFIX, @@ -491,11 +491,11 @@ static int pvfs2_xattr_set_trusted(struct dentry *dentry, flags); } -static int pvfs2_xattr_get_trusted(struct dentry *dentry, - const char *name, - void *buffer, - size_t size, - int handler_flags) +static int pvfs2_xattr_get_trusted(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + void *buffer, + size_t size) { return pvfs2_inode_getxattr(dentry->d_inode, PVFS2_XATTR_NAME_TRUSTED_PREFIX, -- GitLab From 172f3fcb17382faafc71091868370b6765da7a43 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2015 22:12:02 +0000 Subject: [PATCH 0053/5324] ARM: l2c: tauros2: fix OF-enabled non-DT boot Signed-off-by: Russell King --- arch/arm/mm/cache-tauros2.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 1e373d268c04..95eb524ce556 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -287,16 +287,15 @@ void __init tauros2_init(unsigned int features) node = of_find_matching_node(NULL, tauros2_ids); if (!node) { pr_info("Not found marvell,tauros2-cache, disable it\n"); - return; + } else { + ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); + if (ret) { + pr_info("Not found marvell,tauros-cache-features property, " + "disable extra features\n"); + features = 0; + } else + features = f; } - - ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); - if (ret) { - pr_info("Not found marvell,tauros-cache-features property, " - "disable extra features\n"); - features = 0; - } else - features = f; #endif tauros2_internal_init(features); } -- GitLab From 1d93ba2aaacc96bef018c5c2e12840f07372a2be Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Nov 2015 22:12:26 +0000 Subject: [PATCH 0054/5324] ARM: l2c: tauros2: use descriptive definitions for register bits Use descriptive definitions for the Tauros2 register bits, and while we're here, clean up the "Tauros2: %s line fill burt8." message. Signed-off-by: Russell King --- arch/arm/mm/cache-tauros2.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 95eb524ce556..88255bea65e4 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -22,6 +22,11 @@ #include #include +/* CP15 PJ4 Control configuration register */ +#define CCR_L2C_PREFETCH_DISABLE BIT(24) +#define CCR_L2C_ECC_ENABLE BIT(23) +#define CCR_L2C_WAY7_4_DISABLE BIT(21) +#define CCR_L2C_BURST8_ENABLE BIT(20) /* * When Tauros2 is used on a CPU that supports the v7 hierarchical @@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features) u = read_extra_features(); if (features & CACHE_TAUROS2_PREFETCH_ON) - u &= ~0x01000000; + u &= ~CCR_L2C_PREFETCH_DISABLE; else - u |= 0x01000000; + u |= CCR_L2C_PREFETCH_DISABLE; pr_info("Tauros2: %s L2 prefetch.\n", (features & CACHE_TAUROS2_PREFETCH_ON) ? "Enabling" : "Disabling"); if (features & CACHE_TAUROS2_LINEFILL_BURST8) - u |= 0x00100000; + u |= CCR_L2C_BURST8_ENABLE; else - u &= ~0x00100000; - pr_info("Tauros2: %s line fill burt8.\n", + u &= ~CCR_L2C_BURST8_ENABLE; + pr_info("Tauros2: %s burst8 line fill.\n", (features & CACHE_TAUROS2_LINEFILL_BURST8) ? "Enabling" : "Disabling"); -- GitLab From 21cdb6b568435738cc0b303b2b3b82742396310c Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:30 +0000 Subject: [PATCH 0055/5324] x86/mm: Page align the '_end' symbol to avoid pfn conversion bugs Ingo noted that if we can guarantee _end is aligned to PAGE_SIZE we can automatically avoid bugs along the lines of, size = _end - _text >> PAGE_SHIFT which is missing a call to PFN_ALIGN(). The EFI mixed mode contains this bug, for example. _text is already aligned to PAGE_SIZE through the use of LOAD_PHYSICAL_ADDR, and the BSS and BRK sections are explicitly aligned in the linker script, so it makes sense to align _end to match. Reported-by: Ingo Molnar Signed-off-by: Matt Fleming Acked-by: Borislav Petkov Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-2-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 74e4bf11f562..4f1994257a18 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -325,6 +325,7 @@ SECTIONS __brk_limit = .; } + . = ALIGN(PAGE_SIZE); _end = .; STABS_DEBUG -- GitLab From edc3b9129cecd0f0857112136f5b8b1bc1d45918 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:31 +0000 Subject: [PATCH 0056/5324] x86/mm/pat: Ensure cpa->pfn only contains page frame numbers The x86 pageattr code is confused about the data that is stored in cpa->pfn, sometimes it's treated as a page frame number, sometimes it's treated as an unshifted physical address, and in one place it's treated as a pte. The result of this is that the mapping functions do not map the intended physical address. This isn't a problem in practice because most of the addresses we're mapping in the EFI code paths are already mapped in 'trampoline_pgd' and so the pageattr mapping functions don't actually do anything in this case. But when we move to using a separate page table for the EFI runtime this will be an issue. Signed-off-by: Matt Fleming Reviewed-by: Borislav Petkov Acked-by: Borislav Petkov Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-3-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 17 ++++++----------- arch/x86/platform/efi/efi_64.c | 16 ++++++++++------ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index a3137a4feed1..c70e42014101 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -905,15 +905,10 @@ static void populate_pte(struct cpa_data *cpa, pte = pte_offset_kernel(pmd, start); while (num_pages-- && start < end) { - - /* deal with the NX bit */ - if (!(pgprot_val(pgprot) & _PAGE_NX)) - cpa->pfn &= ~_PAGE_NX; - - set_pte(pte, pfn_pte(cpa->pfn >> PAGE_SHIFT, pgprot)); + set_pte(pte, pfn_pte(cpa->pfn, pgprot)); start += PAGE_SIZE; - cpa->pfn += PAGE_SIZE; + cpa->pfn++; pte++; } } @@ -969,11 +964,11 @@ static int populate_pmd(struct cpa_data *cpa, pmd = pmd_offset(pud, start); - set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE | + set_pmd(pmd, __pmd(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pmd_pgprot))); start += PMD_SIZE; - cpa->pfn += PMD_SIZE; + cpa->pfn += PMD_SIZE >> PAGE_SHIFT; cur_pages += PMD_SIZE >> PAGE_SHIFT; } @@ -1042,11 +1037,11 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, * Map everything starting from the Gb boundary, possibly with 1G pages */ while (end - start >= PUD_SIZE) { - set_pud(pud, __pud(cpa->pfn | _PAGE_PSE | + set_pud(pud, __pud(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pud_pgprot))); start += PUD_SIZE; - cpa->pfn += PUD_SIZE; + cpa->pfn += PUD_SIZE >> PAGE_SHIFT; cur_pages += PUD_SIZE >> PAGE_SHIFT; pud++; } diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a0ac0f9c307f..5aa186db59e3 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -143,7 +143,7 @@ void efi_sync_low_kernel_mappings(void) int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - unsigned long text; + unsigned long pfn, text; struct page *page; unsigned npages; pgd_t *pgd; @@ -160,7 +160,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) * and ident-map those pages containing the map before calling * phys_efi_set_virtual_address_map(). */ - if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) { + pfn = pa_memmap >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, pa_memmap, num_pages, _PAGE_NX)) { pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap); return 1; } @@ -185,8 +186,9 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) npages = (_end - _text) >> PAGE_SHIFT; text = __pa(_text); + pfn = text >> PAGE_SHIFT; - if (kernel_map_pages_in_pgd(pgd, text >> PAGE_SHIFT, text, npages, 0)) { + if (kernel_map_pages_in_pgd(pgd, pfn, text, npages, 0)) { pr_err("Failed to map kernel text 1:1\n"); return 1; } @@ -204,12 +206,14 @@ void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) static void __init __map_region(efi_memory_desc_t *md, u64 va) { pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - unsigned long pf = 0; + unsigned long flags = 0; + unsigned long pfn; if (!(md->attribute & EFI_MEMORY_WB)) - pf |= _PAGE_PCD; + flags |= _PAGE_PCD; - if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf)) + pfn = md->phys_addr >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags)) pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", md->phys_addr, va); } -- GitLab From b61a76f8850d2979550abc42d7e09154ebb8d785 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:32 +0000 Subject: [PATCH 0057/5324] x86/efi: Map RAM into the identity page table for mixed mode We are relying on the pre-existing mappings in 'trampoline_pgd' when accessing function arguments in the EFI mixed mode thunking code. Instead let's map memory explicitly so that things will continue to work when we move to a separate page table in the future. Signed-off-by: Matt Fleming Reviewed-by: Borislav Petkov Acked-by: Borislav Petkov Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-4-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi_64.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 5aa186db59e3..102976dda8c4 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -144,6 +144,7 @@ void efi_sync_low_kernel_mappings(void) int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { unsigned long pfn, text; + efi_memory_desc_t *md; struct page *page; unsigned npages; pgd_t *pgd; @@ -177,6 +178,25 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (!IS_ENABLED(CONFIG_EFI_MIXED)) return 0; + /* + * Map all of RAM so that we can access arguments in the 1:1 + * mapping when making EFI runtime calls. + */ + for_each_efi_memory_desc(&memmap, md) { + if (md->type != EFI_CONVENTIONAL_MEMORY && + md->type != EFI_LOADER_DATA && + md->type != EFI_LOADER_CODE) + continue; + + pfn = md->phys_addr >> PAGE_SHIFT; + npages = md->num_pages; + + if (kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, npages, 0)) { + pr_err("Failed to map 1:1 memory\n"); + return 1; + } + } + page = alloc_page(GFP_KERNEL|__GFP_DMA32); if (!page) panic("Unable to allocate EFI runtime stack < 4GB\n"); -- GitLab From c9f2a9a65e4855b74d92cdad688f6ee4a1a323ff Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:33 +0000 Subject: [PATCH 0058/5324] x86/efi: Hoist page table switching code into efi_call_virt() This change is a prerequisite for pending patches that switch to a dedicated EFI page table, instead of using 'trampoline_pgd' which shares PGD entries with 'swapper_pg_dir'. The pending patches make it impossible to dereference the runtime service function pointer without first switching %cr3. It's true that we now have duplicated switching code in efi_call_virt() and efi_call_phys_{prolog,epilog}() but we are sacrificing code duplication for a little more clarity and the ease of writing the page table switching code in C instead of asm. Signed-off-by: Matt Fleming Reviewed-by: Borislav Petkov Acked-by: Borislav Petkov Cc: Andrew Morton Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Jones Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Stephen Smalley Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-5-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/include/asm/efi.h | 25 +++++++++++++++++ arch/x86/platform/efi/efi_64.c | 24 ++++++++-------- arch/x86/platform/efi/efi_stub_64.S | 43 ----------------------------- 3 files changed, 36 insertions(+), 56 deletions(-) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 0010c78c4998..347eeacb06a8 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -3,6 +3,7 @@ #include #include +#include /* * We map the EFI regions needed for runtime services non-contiguously, @@ -64,6 +65,17 @@ extern u64 asmlinkage efi_call(void *fp, ...); #define efi_call_phys(f, args...) efi_call((f), args) +/* + * Scratch space used for switching the pagetable in the EFI stub + */ +struct efi_scratch { + u64 r15; + u64 prev_cr3; + pgd_t *efi_pgt; + bool use_pgd; + u64 phys_stack; +} __packed; + #define efi_call_virt(f, ...) \ ({ \ efi_status_t __s; \ @@ -71,7 +83,20 @@ extern u64 asmlinkage efi_call(void *fp, ...); efi_sync_low_kernel_mappings(); \ preempt_disable(); \ __kernel_fpu_begin(); \ + \ + if (efi_scratch.use_pgd) { \ + efi_scratch.prev_cr3 = read_cr3(); \ + write_cr3((unsigned long)efi_scratch.efi_pgt); \ + __flush_tlb_all(); \ + } \ + \ __s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \ + \ + if (efi_scratch.use_pgd) { \ + write_cr3(efi_scratch.prev_cr3); \ + __flush_tlb_all(); \ + } \ + \ __kernel_fpu_end(); \ preempt_enable(); \ __s; \ diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 102976dda8c4..b19cdac959b2 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -47,16 +47,7 @@ */ static u64 efi_va = EFI_VA_START; -/* - * Scratch space used for switching the pagetable in the EFI stub - */ -struct efi_scratch { - u64 r15; - u64 prev_cr3; - pgd_t *efi_pgt; - bool use_pgd; - u64 phys_stack; -} __packed; +struct efi_scratch efi_scratch; static void __init early_code_mapping_set_exec(int executable) { @@ -83,8 +74,11 @@ pgd_t * __init efi_call_phys_prolog(void) int pgd; int n_pgds; - if (!efi_enabled(EFI_OLD_MEMMAP)) - return NULL; + if (!efi_enabled(EFI_OLD_MEMMAP)) { + save_pgd = (pgd_t *)read_cr3(); + write_cr3((unsigned long)efi_scratch.efi_pgt); + goto out; + } early_code_mapping_set_exec(1); @@ -96,6 +90,7 @@ pgd_t * __init efi_call_phys_prolog(void) vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); } +out: __flush_tlb_all(); return save_pgd; @@ -109,8 +104,11 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) int pgd_idx; int nr_pgds; - if (!save_pgd) + if (!efi_enabled(EFI_OLD_MEMMAP)) { + write_cr3((unsigned long)save_pgd); + __flush_tlb_all(); return; + } nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 86d0f9e08dd9..32020cb8bb08 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -38,41 +38,6 @@ mov %rsi, %cr0; \ mov (%rsp), %rsp - /* stolen from gcc */ - .macro FLUSH_TLB_ALL - movq %r15, efi_scratch(%rip) - movq %r14, efi_scratch+8(%rip) - movq %cr4, %r15 - movq %r15, %r14 - andb $0x7f, %r14b - movq %r14, %cr4 - movq %r15, %cr4 - movq efi_scratch+8(%rip), %r14 - movq efi_scratch(%rip), %r15 - .endm - - .macro SWITCH_PGT - cmpb $0, efi_scratch+24(%rip) - je 1f - movq %r15, efi_scratch(%rip) # r15 - # save previous CR3 - movq %cr3, %r15 - movq %r15, efi_scratch+8(%rip) # prev_cr3 - movq efi_scratch+16(%rip), %r15 # EFI pgt - movq %r15, %cr3 - 1: - .endm - - .macro RESTORE_PGT - cmpb $0, efi_scratch+24(%rip) - je 2f - movq efi_scratch+8(%rip), %r15 - movq %r15, %cr3 - movq efi_scratch(%rip), %r15 - FLUSH_TLB_ALL - 2: - .endm - ENTRY(efi_call) SAVE_XMM mov (%rsp), %rax @@ -83,16 +48,8 @@ ENTRY(efi_call) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx - SWITCH_PGT call *%rdi - RESTORE_PGT addq $48, %rsp RESTORE_XMM ret ENDPROC(efi_call) - - .data -ENTRY(efi_scratch) - .fill 3,8,0 - .byte 0 - .quad 0 -- GitLab From 67a9108ed4313b85a9c53406d80dc1ae3f8c3e36 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:34 +0000 Subject: [PATCH 0059/5324] x86/efi: Build our own page table structures With commit e1a58320a38d ("x86/mm: Warn on W^X mappings") all users booting on 64-bit UEFI machines see the following warning, ------------[ cut here ]------------ WARNING: CPU: 7 PID: 1 at arch/x86/mm/dump_pagetables.c:225 note_page+0x5dc/0x780() x86/mm: Found insecure W+X mapping at address ffff88000005f000/0xffff88000005f000 ... x86/mm: Checked W+X mappings: FAILED, 165660 W+X pages found. ... This is caused by mapping EFI regions with RWX permissions. There isn't much we can do to restrict the permissions for these regions due to the way the firmware toolchains mix code and data, but we can at least isolate these mappings so that they do not appear in the regular kernel page tables. In commit d2f7cbe7b26a ("x86/efi: Runtime services virtual mapping") we started using 'trampoline_pgd' to map the EFI regions because there was an existing identity mapping there which we use during the SetVirtualAddressMap() call and for broken firmware that accesses those addresses. But 'trampoline_pgd' shares some PGD entries with 'swapper_pg_dir' and does not provide the isolation we require. Notably the virtual address for __START_KERNEL_map and MODULES_START are mapped by the same PGD entry so we need to be more careful when copying changes over in efi_sync_low_kernel_mappings(). This patch doesn't go the full mile, we still want to share some PGD entries with 'swapper_pg_dir'. Having completely separate page tables brings its own issues such as synchronising new mappings after memory hotplug and module loading. Sharing also keeps memory usage down. Signed-off-by: Matt Fleming Reviewed-by: Borislav Petkov Acked-by: Borislav Petkov Cc: Andrew Morton Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Jones Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Stephen Smalley Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-6-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/include/asm/efi.h | 1 + arch/x86/platform/efi/efi.c | 39 +++++--------- arch/x86/platform/efi/efi_32.c | 5 ++ arch/x86/platform/efi/efi_64.c | 97 ++++++++++++++++++++++++++++------ 4 files changed, 102 insertions(+), 40 deletions(-) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 347eeacb06a8..8fd9e637629a 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -136,6 +136,7 @@ extern void __init efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); extern void __init efi_map_region_fixed(efi_memory_desc_t *md); extern void efi_sync_low_kernel_mappings(void); +extern int __init efi_alloc_page_tables(void); extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init old_map_region(efi_memory_desc_t *md); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index ad285404ea7f..3c1f3cd7b2ba 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -869,7 +869,7 @@ static void __init kexec_enter_virtual_mode(void) * This function will switch the EFI runtime services to virtual mode. * Essentially, we look through the EFI memmap and map every region that * has the runtime attribute bit set in its memory descriptor into the - * ->trampoline_pgd page table using a top-down VA allocation scheme. + * efi_pgd page table. * * The old method which used to update that memory descriptor with the * virtual address obtained from ioremap() is still supported when the @@ -879,8 +879,8 @@ static void __init kexec_enter_virtual_mode(void) * * The new method does a pagetable switch in a preemption-safe manner * so that we're in a different address space when calling a runtime - * function. For function arguments passing we do copy the PGDs of the - * kernel page table into ->trampoline_pgd prior to each call. + * function. For function arguments passing we do copy the PUDs of the + * kernel page table into efi_pgd prior to each call. * * Specially for kexec boot, efi runtime maps in previous kernel should * be passed in via setup_data. In that case runtime ranges will be mapped @@ -895,6 +895,12 @@ static void __init __efi_enter_virtual_mode(void) efi.systab = NULL; + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_merge_regions(); new_memmap = efi_map_regions(&count, &pg_shift); if (!new_memmap) { @@ -954,28 +960,11 @@ static void __init __efi_enter_virtual_mode(void) efi_runtime_mkexec(); /* - * We mapped the descriptor array into the EFI pagetable above but we're - * not unmapping it here. Here's why: - * - * We're copying select PGDs from the kernel page table to the EFI page - * table and when we do so and make changes to those PGDs like unmapping - * stuff from them, those changes appear in the kernel page table and we - * go boom. - * - * From setup_real_mode(): - * - * ... - * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd; - * - * In this particular case, our allocation is in PGD 0 of the EFI page - * table but we've copied that PGD from PGD[272] of the EFI page table: - * - * pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272 - * - * where the direct memory mapping in kernel space is. - * - * new_memmap's VA comes from that direct mapping and thus clearing it, - * it would get cleared in the kernel page table too. + * We mapped the descriptor array into the EFI pagetable above + * but we're not unmapping it here because if we're running in + * EFI mixed mode we need all of memory to be accessible when + * we pass parameters to the EFI runtime services in the + * thunking code. * * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); */ diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index ed5b67338294..58d669bc8250 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -38,6 +38,11 @@ * say 0 - 3G. */ +int __init efi_alloc_page_tables(void) +{ + return 0; +} + void efi_sync_low_kernel_mappings(void) {} void __init efi_dump_pagetable(void) {} int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index b19cdac959b2..4897f518760f 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -40,6 +40,7 @@ #include #include #include +#include /* * We allocate runtime services regions bottom-up, starting from -4G, i.e. @@ -121,22 +122,92 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) early_code_mapping_set_exec(0); } +static pgd_t *efi_pgd; + +/* + * We need our own copy of the higher levels of the page tables + * because we want to avoid inserting EFI region mappings (EFI_VA_END + * to EFI_VA_START) into the standard kernel page tables. Everything + * else can be shared, see efi_sync_low_kernel_mappings(). + */ +int __init efi_alloc_page_tables(void) +{ + pgd_t *pgd; + pud_t *pud; + gfp_t gfp_mask; + + if (efi_enabled(EFI_OLD_MEMMAP)) + return 0; + + gfp_mask = GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO; + efi_pgd = (pgd_t *)__get_free_page(gfp_mask); + if (!efi_pgd) + return -ENOMEM; + + pgd = efi_pgd + pgd_index(EFI_VA_END); + + pud = pud_alloc_one(NULL, 0); + if (!pud) { + free_page((unsigned long)efi_pgd); + return -ENOMEM; + } + + pgd_populate(NULL, pgd, pud); + + return 0; +} + /* * Add low kernel mappings for passing arguments to EFI functions. */ void efi_sync_low_kernel_mappings(void) { - unsigned num_pgds; - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); + unsigned num_entries; + pgd_t *pgd_k, *pgd_efi; + pud_t *pud_k, *pud_efi; if (efi_enabled(EFI_OLD_MEMMAP)) return; - num_pgds = pgd_index(MODULES_END - 1) - pgd_index(PAGE_OFFSET); + /* + * We can share all PGD entries apart from the one entry that + * covers the EFI runtime mapping space. + * + * Make sure the EFI runtime region mappings are guaranteed to + * only span a single PGD entry and that the entry also maps + * other important kernel regions. + */ + BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END)); + BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) != + (EFI_VA_END & PGDIR_MASK)); + + pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET); + pgd_k = pgd_offset_k(PAGE_OFFSET); + + num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); + memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); - memcpy(pgd + pgd_index(PAGE_OFFSET), - init_mm.pgd + pgd_index(PAGE_OFFSET), - sizeof(pgd_t) * num_pgds); + /* + * We share all the PUD entries apart from those that map the + * EFI regions. Copy around them. + */ + BUILD_BUG_ON((EFI_VA_START & ~PUD_MASK) != 0); + BUILD_BUG_ON((EFI_VA_END & ~PUD_MASK) != 0); + + pgd_efi = efi_pgd + pgd_index(EFI_VA_END); + pud_efi = pud_offset(pgd_efi, 0); + + pgd_k = pgd_offset_k(EFI_VA_END); + pud_k = pud_offset(pgd_k, 0); + + num_entries = pud_index(EFI_VA_END); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); + + pud_efi = pud_offset(pgd_efi, EFI_VA_START); + pud_k = pud_offset(pgd_k, EFI_VA_START); + + num_entries = PTRS_PER_PUD - pud_index(EFI_VA_START); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); } int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) @@ -150,8 +221,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (efi_enabled(EFI_OLD_MEMMAP)) return 0; - efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd; - pgd = __va(efi_scratch.efi_pgt); + efi_scratch.efi_pgt = (pgd_t *)__pa(efi_pgd); + pgd = efi_pgd; /* * It can happen that the physical address of new_memmap lands in memory @@ -216,16 +287,14 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages); + kernel_unmap_pages_in_pgd(efi_pgd, pa_memmap, num_pages); } static void __init __map_region(efi_memory_desc_t *md, u64 va) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); unsigned long flags = 0; unsigned long pfn; + pgd_t *pgd = efi_pgd; if (!(md->attribute & EFI_MEMORY_WB)) flags |= _PAGE_PCD; @@ -334,9 +403,7 @@ void __init efi_runtime_mkexec(void) void __init efi_dump_pagetable(void) { #ifdef CONFIG_EFI_PGT_DUMP - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - ptdump_walk_pgd_level(NULL, pgd); + ptdump_walk_pgd_level(NULL, efi_pgd); #endif } -- GitLab From ff3d0a12fb2dc123e2b46e9524ebf4e08de5c59c Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 27 Nov 2015 21:09:35 +0000 Subject: [PATCH 0060/5324] Documentation/x86: Update EFI memory region description Make it clear that the EFI page tables are only available during EFI runtime calls since that subject has come up a fair numbers of times in the past. Additionally, add the EFI region start and end addresses to the table so that it's possible to see at a glance where they fall in relation to other regions. Signed-off-by: Matt Fleming Reviewed-by: Borislav Petkov Acked-by: Borislav Petkov Cc: Andrew Morton Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Jones Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sai Praneeth Prakhya Cc: Stephen Smalley Cc: Thomas Gleixner Cc: Toshi Kani Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1448658575-17029-7-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- Documentation/x86/x86_64/mm.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 05712ac83e38..c518dce7da4d 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -16,6 +16,8 @@ ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB) ... unused hole ... ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks ... unused hole ... +ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space +... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls @@ -32,11 +34,9 @@ reference. Current X86-64 implementations only support 40 bits of address space, but we support up to 46 bits. This expands into MBZ space in the page tables. -->trampoline_pgd: - -We map EFI runtime services in the aforementioned PGD in the virtual -range of 64Gb (arbitrarily set, can be raised if needed) - -0xffffffef00000000 - 0xffffffff00000000 +We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual +memory window (this size is arbitrary, it can be raised later if needed). +The mappings are not part of any other kernel PGD and are only available +during EFI runtime calls. -Andi Kleen, Jul 2004 -- GitLab From 8bb8aefd5afb54a25a002feb4ec70011812d06a0 Mon Sep 17 00:00:00 2001 From: Yi Liu Date: Tue, 24 Nov 2015 15:12:14 -0500 Subject: [PATCH 0061/5324] OrangeFS: Change almost all instances of the string PVFS2 to OrangeFS. OrangeFS was formerly known as PVFS2 and retains the name in many places. I leave the device /dev/pvfs2-req since this affects userspace. I leave the filesystem type pvfs2 since this affects userspace. Further the OrangeFS sysint library reads fstab for an entry of type pvfs2 independently of kernel mounts. I leave extended attribute keys user.pvfs2 and system.pvfs2 as the sysint library understands these. I leave references to userspace binaries still named pvfs2. I leave the filenames. Signed-off-by: Yi Liu [martin@omnibond.com: clairify above constraints and merge] Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/acl.c | 42 ++-- fs/orangefs/dcache.c | 24 +- fs/orangefs/devpvfs2-req.c | 256 +++++++++++----------- fs/orangefs/dir.c | 86 ++++---- fs/orangefs/downcall.h | 84 +++---- fs/orangefs/file.c | 208 +++++++++--------- fs/orangefs/inode.c | 176 +++++++-------- fs/orangefs/namei.c | 134 ++++++------ fs/orangefs/protocol.h | 308 +++++++++++++------------- fs/orangefs/pvfs2-bufmap.c | 168 +++++++------- fs/orangefs/pvfs2-bufmap.h | 40 ++-- fs/orangefs/pvfs2-cache.c | 122 +++++------ fs/orangefs/pvfs2-debug.h | 18 +- fs/orangefs/pvfs2-debugfs.c | 48 ++-- fs/orangefs/pvfs2-debugfs.h | 6 +- fs/orangefs/pvfs2-dev-proto.h | 68 +++--- fs/orangefs/pvfs2-kernel.h | 402 +++++++++++++++++----------------- fs/orangefs/pvfs2-mod.c | 106 ++++----- fs/orangefs/pvfs2-sysfs.c | 108 ++++----- fs/orangefs/pvfs2-utils.c | 336 ++++++++++++++-------------- fs/orangefs/super.c | 280 +++++++++++------------ fs/orangefs/symlink.c | 14 +- fs/orangefs/upcall.h | 262 +++++++++++----------- fs/orangefs/waitqueue.c | 70 +++--- fs/orangefs/xattr.c | 204 ++++++++--------- 25 files changed, 1785 insertions(+), 1785 deletions(-) diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c index e462b81a3ba1..5e27d5fcb6bf 100644 --- a/fs/orangefs/acl.c +++ b/fs/orangefs/acl.c @@ -10,7 +10,7 @@ #include #include -struct posix_acl *pvfs2_get_acl(struct inode *inode, int type) +struct posix_acl *orangefs_get_acl(struct inode *inode, int type) { struct posix_acl *acl; int ret; @@ -18,23 +18,23 @@ struct posix_acl *pvfs2_get_acl(struct inode *inode, int type) switch (type) { case ACL_TYPE_ACCESS: - key = PVFS2_XATTR_NAME_ACL_ACCESS; + key = ORANGEFS_XATTR_NAME_ACL_ACCESS; break; case ACL_TYPE_DEFAULT: - key = PVFS2_XATTR_NAME_ACL_DEFAULT; + key = ORANGEFS_XATTR_NAME_ACL_DEFAULT; break; default: - gossip_err("pvfs2_get_acl: bogus value of type %d\n", type); + gossip_err("orangefs_get_acl: bogus value of type %d\n", type); return ERR_PTR(-EINVAL); } /* * Rather than incurring a network call just to determine the exact * length of the attribute, I just allocate a max length to save on * the network call. Conceivably, we could pass NULL to - * pvfs2_inode_getxattr() to probe the length of the value, but + * orangefs_inode_getxattr() to probe the length of the value, but * I don't do that for now. */ - value = kmalloc(PVFS_MAX_XATTR_VALUELEN, GFP_KERNEL); + value = kmalloc(ORANGEFS_MAX_XATTR_VALUELEN, GFP_KERNEL); if (value == NULL) return ERR_PTR(-ENOMEM); @@ -43,11 +43,11 @@ struct posix_acl *pvfs2_get_acl(struct inode *inode, int type) get_khandle_from_ino(inode), key, type); - ret = pvfs2_inode_getxattr(inode, + ret = orangefs_inode_getxattr(inode, "", key, value, - PVFS_MAX_XATTR_VALUELEN); + ORANGEFS_MAX_XATTR_VALUELEN); /* if the key exists, convert it to an in-memory rep */ if (ret > 0) { acl = posix_acl_from_xattr(&init_user_ns, value, ret); @@ -64,9 +64,9 @@ struct posix_acl *pvfs2_get_acl(struct inode *inode, int type) return acl; } -int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); int error = 0; void *value = NULL; size_t size = 0; @@ -74,7 +74,7 @@ int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) switch (type) { case ACL_TYPE_ACCESS: - name = PVFS2_XATTR_NAME_ACL_ACCESS; + name = ORANGEFS_XATTR_NAME_ACL_ACCESS; if (acl) { umode_t mode = inode->i_mode; /* @@ -90,7 +90,7 @@ int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) } if (inode->i_mode != mode) - SetModeFlag(pvfs2_inode); + SetModeFlag(orangefs_inode); inode->i_mode = mode; mark_inode_dirty_sync(inode); if (error == 0) @@ -98,7 +98,7 @@ int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) } break; case ACL_TYPE_DEFAULT: - name = PVFS2_XATTR_NAME_ACL_DEFAULT; + name = ORANGEFS_XATTR_NAME_ACL_DEFAULT; break; default: gossip_err("%s: invalid type %d!\n", __func__, type); @@ -131,7 +131,7 @@ int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) * will xlate to a removexattr. However, we don't want removexattr * complain if attributes does not exist. */ - error = pvfs2_inode_setxattr(inode, "", name, value, size, 0); + error = orangefs_inode_setxattr(inode, "", name, value, size, 0); out: kfree(value); @@ -140,35 +140,35 @@ int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type) return error; } -int pvfs2_init_acl(struct inode *inode, struct inode *dir) +int orangefs_init_acl(struct inode *inode, struct inode *dir) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct posix_acl *default_acl, *acl; umode_t mode = inode->i_mode; int error = 0; - ClearModeFlag(pvfs2_inode); + ClearModeFlag(orangefs_inode); error = posix_acl_create(dir, &mode, &default_acl, &acl); if (error) return error; if (default_acl) { - error = pvfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); + error = orangefs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); posix_acl_release(default_acl); } if (acl) { if (!error) - error = pvfs2_set_acl(inode, acl, ACL_TYPE_ACCESS); + error = orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); } /* If mode of the inode was changed, then do a forcible ->setattr */ if (mode != inode->i_mode) { - SetModeFlag(pvfs2_inode); + SetModeFlag(orangefs_inode); inode->i_mode = mode; - pvfs2_flush_inode(inode); + orangefs_flush_inode(inode); } return error; diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index 9466b179bf24..12c916fa4c7f 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -12,27 +12,27 @@ #include "pvfs2-kernel.h" /* Returns 1 if dentry can still be trusted, else 0. */ -static int pvfs2_revalidate_lookup(struct dentry *dentry) +static int orangefs_revalidate_lookup(struct dentry *dentry) { struct dentry *parent_dentry = dget_parent(dentry); struct inode *parent_inode = parent_dentry->d_inode; - struct pvfs2_inode_s *parent = PVFS2_I(parent_inode); + struct orangefs_inode_s *parent = ORANGEFS_I(parent_inode); struct inode *inode = dentry->d_inode; - struct pvfs2_kernel_op_s *new_op; + struct orangefs_kernel_op_s *new_op; int ret = 0; int err = 0; gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__); - new_op = op_alloc(PVFS2_VFS_OP_LOOKUP); + new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); if (!new_op) goto out_put_parent; - new_op->upcall.req.lookup.sym_follow = PVFS2_LOOKUP_LINK_NO_FOLLOW; + new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; new_op->upcall.req.lookup.parent_refn = parent->refn; strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, - PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d interrupt flag [%d]\n", @@ -41,7 +41,7 @@ static int pvfs2_revalidate_lookup(struct dentry *dentry) __LINE__, get_interruptible_flag(parent_inode)); - err = service_operation(new_op, "pvfs2_lookup", + err = service_operation(new_op, "orangefs_lookup", get_interruptible_flag(parent_inode)); if (err) goto out_drop; @@ -79,7 +79,7 @@ static int pvfs2_revalidate_lookup(struct dentry *dentry) * * Should return 1 if dentry can still be trusted, else 0 */ -static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags) +static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) { struct inode *inode; int ret = 0; @@ -105,7 +105,7 @@ static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags) * exists, but is still in the expected place in the name space */ if (!is_root_handle(inode)) { - if (!pvfs2_revalidate_lookup(dentry)) + if (!orangefs_revalidate_lookup(dentry)) goto invalid_exit; } else { gossip_debug(GOSSIP_DCACHE_DEBUG, @@ -119,7 +119,7 @@ static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags) __func__, inode, get_khandle_from_ino(inode)); - ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: getattr %s (ret = %d), returning %s for dentry i_count=%d\n", __func__, @@ -137,6 +137,6 @@ static int pvfs2_d_revalidate(struct dentry *dentry, unsigned int flags) return 0; } -const struct dentry_operations pvfs2_dentry_operations = { - .d_revalidate = pvfs2_d_revalidate, +const struct dentry_operations orangefs_dentry_operations = { + .d_revalidate = orangefs_d_revalidate, }; diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devpvfs2-req.c index e37b6479a6a1..e18149f0975b 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devpvfs2-req.c @@ -22,14 +22,14 @@ static int open_access_count; #define DUMP_DEVICE_ERROR() \ do { \ gossip_err("*****************************************************\n");\ - gossip_err("PVFS2 Device Error: You cannot open the device file "); \ + gossip_err("ORANGEFS Device Error: You cannot open the device file "); \ gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \ - "are no ", PVFS2_REQDEVICE_NAME); \ + "are no ", ORANGEFS_REQDEVICE_NAME); \ gossip_err("instances of a program using this device\ncurrently " \ "running. (You must verify this!)\n"); \ gossip_err("For example, you can use the lsof program as follows:\n");\ gossip_err("'lsof | grep %s' (run this as root)\n", \ - PVFS2_REQDEVICE_NAME); \ + ORANGEFS_REQDEVICE_NAME); \ gossip_err(" open_access_count = %d\n", open_access_count); \ gossip_err("*****************************************************\n");\ } while (0) @@ -39,7 +39,7 @@ static int hash_func(__u64 tag, int table_size) return do_div(tag, (unsigned int)table_size); } -static void pvfs2_devreq_add_op(struct pvfs2_kernel_op_s *op) +static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op) { int index = hash_func(op->tag, hash_table_size); @@ -48,9 +48,9 @@ static void pvfs2_devreq_add_op(struct pvfs2_kernel_op_s *op) spin_unlock(&htable_ops_in_progress_lock); } -static struct pvfs2_kernel_op_s *pvfs2_devreq_remove_op(__u64 tag) +static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag) { - struct pvfs2_kernel_op_s *op, *next; + struct orangefs_kernel_op_s *op, *next; int index; index = hash_func(tag, hash_table_size); @@ -71,12 +71,12 @@ static struct pvfs2_kernel_op_s *pvfs2_devreq_remove_op(__u64 tag) return NULL; } -static int pvfs2_devreq_open(struct inode *inode, struct file *file) +static int orangefs_devreq_open(struct inode *inode, struct file *file) { int ret = -EINVAL; if (!(file->f_flags & O_NONBLOCK)) { - gossip_err("pvfs2: device cannot be opened in blocking mode\n"); + gossip_err("orangefs: device cannot be opened in blocking mode\n"); goto out; } ret = -EACCES; @@ -100,14 +100,14 @@ static int pvfs2_devreq_open(struct inode *inode, struct file *file) return ret; } -static ssize_t pvfs2_devreq_read(struct file *file, +static ssize_t orangefs_devreq_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { - struct pvfs2_kernel_op_s *op, *temp; - __s32 proto_ver = PVFS_KERNEL_PROTO_VERSION; - static __s32 magic = PVFS2_DEVREQ_MAGIC; - struct pvfs2_kernel_op_s *cur_op = NULL; + struct orangefs_kernel_op_s *op, *temp; + __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION; + static __s32 magic = ORANGEFS_DEVREQ_MAGIC; + struct orangefs_kernel_op_s *cur_op = NULL; unsigned long ret; /* We do not support blocking IO. */ @@ -126,14 +126,14 @@ static ssize_t pvfs2_devreq_read(struct file *file, } /* Get next op (if any) from top of list. */ - spin_lock(&pvfs2_request_list_lock); - list_for_each_entry_safe(op, temp, &pvfs2_request_list, list) { + spin_lock(&orangefs_request_list_lock); + list_for_each_entry_safe(op, temp, &orangefs_request_list, list) { __s32 fsid; /* This lock is held past the end of the loop when we break. */ spin_lock(&op->lock); fsid = fsid_of_op(op); - if (fsid != PVFS_FS_ID_NULL) { + if (fsid != ORANGEFS_FS_ID_NULL) { int ret; /* Skip ops whose filesystem needs to be mounted. */ ret = fs_mount_pending(fsid); @@ -147,8 +147,8 @@ static ssize_t pvfs2_devreq_read(struct file *file, * it is being mounted. */ /* XXX: is there a better way to detect this? */ } else if (ret == -1 && - !(op->upcall.type == PVFS2_VFS_OP_FS_MOUNT || - op->upcall.type == PVFS2_VFS_OP_GETATTR)) { + !(op->upcall.type == ORANGEFS_VFS_OP_FS_MOUNT || + op->upcall.type == ORANGEFS_VFS_OP_GETATTR)) { gossip_debug(GOSSIP_DEV_DEBUG, "orangefs: skipping op tag %llu %s\n", llu(op->tag), get_opname_string(op)); @@ -173,7 +173,7 @@ static ssize_t pvfs2_devreq_read(struct file *file, * found an op and must ask the client to try again later. */ if (!cur_op) { - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); return -EAGAIN; } @@ -188,7 +188,7 @@ static ssize_t pvfs2_devreq_read(struct file *file, gossip_err("orangefs: ERROR: Current op already queued.\n"); list_del(&cur_op->list); spin_unlock(&cur_op->lock); - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); return -EAGAIN; } @@ -199,8 +199,8 @@ static ssize_t pvfs2_devreq_read(struct file *file, set_op_state_inprogress(cur_op); list_del(&cur_op->list); - spin_unlock(&pvfs2_request_list_lock); - pvfs2_devreq_add_op(cur_op); + spin_unlock(&orangefs_request_list_lock); + orangefs_devreq_add_op(cur_op); spin_unlock(&cur_op->lock); /* Push the upcall out. */ @@ -214,7 +214,7 @@ static ssize_t pvfs2_devreq_read(struct file *file, if (ret != 0) goto error; ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall, - sizeof(struct pvfs2_upcall_s)); + sizeof(struct orangefs_upcall_s)); if (ret != 0) goto error; @@ -227,23 +227,23 @@ static ssize_t pvfs2_devreq_read(struct file *file, * device is released. */ gossip_err("orangefs: Failed to copy data to user space\n"); - spin_lock(&pvfs2_request_list_lock); + spin_lock(&orangefs_request_list_lock); spin_lock(&cur_op->lock); set_op_state_waiting(cur_op); - pvfs2_devreq_remove_op(cur_op->tag); - list_add(&cur_op->list, &pvfs2_request_list); + orangefs_devreq_remove_op(cur_op->tag); + list_add(&cur_op->list, &orangefs_request_list); spin_unlock(&cur_op->lock); - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); return -EFAULT; } /* Function for writev() callers into the device */ -static ssize_t pvfs2_devreq_writev(struct file *file, +static ssize_t orangefs_devreq_writev(struct file *file, const struct iovec *iov, size_t count, loff_t *offset) { - struct pvfs2_kernel_op_s *op = NULL; + struct orangefs_kernel_op_s *op = NULL; void *buffer = NULL; void *ptr = NULL; unsigned long i = 0; @@ -301,7 +301,7 @@ static ssize_t pvfs2_devreq_writev(struct file *file, tag = *((__u64 *) ptr); ptr += sizeof(__u64); - if (magic != PVFS2_DEVREQ_MAGIC) { + if (magic != ORANGEFS_DEVREQ_MAGIC) { gossip_err("Error: Device magic number does not match.\n"); dev_req_release(buffer); return -EPROTO; @@ -311,17 +311,17 @@ static ssize_t pvfs2_devreq_writev(struct file *file, * proto_ver = 20902 for 2.9.2 */ - op = pvfs2_devreq_remove_op(tag); + op = orangefs_devreq_remove_op(tag); if (op) { /* Increase ref count! */ get_op(op); /* cut off magic and tag from payload size */ payload_size -= (2 * sizeof(__s32) + sizeof(__u64)); - if (payload_size <= sizeof(struct pvfs2_downcall_s)) + if (payload_size <= sizeof(struct orangefs_downcall_s)) /* copy the passed in downcall into the op */ memcpy(&op->downcall, ptr, - sizeof(struct pvfs2_downcall_s)); + sizeof(struct orangefs_downcall_s)); else gossip_debug(GOSSIP_DEV_DEBUG, "writev: Ignoring %d bytes\n", @@ -392,8 +392,8 @@ static ssize_t pvfs2_devreq_writev(struct file *file, * application reading/writing this device to return until * the buffers are done being used. */ - if (op->upcall.type == PVFS2_VFS_OP_FILE_IO && - op->upcall.req.io.async_vfs_io == PVFS_VFS_SYNC_IO) { + if (op->upcall.type == ORANGEFS_VFS_OP_FILE_IO && + op->upcall.req.io.async_vfs_io == ORANGEFS_VFS_SYNC_IO) { int timed_out = 0; DECLARE_WAITQUEUE(wait_entry, current); @@ -473,10 +473,10 @@ static ssize_t pvfs2_devreq_writev(struct file *file, return total_returned_size; } -static ssize_t pvfs2_devreq_write_iter(struct kiocb *iocb, +static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, struct iov_iter *iter) { - return pvfs2_devreq_writev(iocb->ki_filp, + return orangefs_devreq_writev(iocb->ki_filp, iter->iov, iter->nr_segs, &iocb->ki_pos); @@ -486,15 +486,15 @@ static ssize_t pvfs2_devreq_write_iter(struct kiocb *iocb, static int mark_all_pending_mounts(void) { int unmounted = 1; - struct pvfs2_sb_info_s *pvfs2_sb = NULL; + struct orangefs_sb_info_s *orangefs_sb = NULL; - spin_lock(&pvfs2_superblocks_lock); - list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) { + spin_lock(&orangefs_superblocks_lock); + list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) { /* All of these file system require a remount */ - pvfs2_sb->mount_pending = 1; + orangefs_sb->mount_pending = 1; unmounted = 0; } - spin_unlock(&pvfs2_superblocks_lock); + spin_unlock(&orangefs_superblocks_lock); return unmounted; } @@ -507,16 +507,16 @@ static int mark_all_pending_mounts(void) int fs_mount_pending(__s32 fsid) { int mount_pending = -1; - struct pvfs2_sb_info_s *pvfs2_sb = NULL; + struct orangefs_sb_info_s *orangefs_sb = NULL; - spin_lock(&pvfs2_superblocks_lock); - list_for_each_entry(pvfs2_sb, &pvfs2_superblocks, list) { - if (pvfs2_sb->fs_id == fsid) { - mount_pending = pvfs2_sb->mount_pending; + spin_lock(&orangefs_superblocks_lock); + list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) { + if (orangefs_sb->fs_id == fsid) { + mount_pending = orangefs_sb->mount_pending; break; } } - spin_unlock(&pvfs2_superblocks_lock); + spin_unlock(&orangefs_superblocks_lock); return mount_pending; } @@ -525,10 +525,10 @@ int fs_mount_pending(__s32 fsid) * Using the open_access_count variable, we enforce a reference count * on this file so that it can be opened by only one process at a time. * the devreq_mutex is used to make sure all i/o has completed - * before we call pvfs_bufmap_finalize, and similar such tricky + * before we call orangefs_bufmap_finalize, and similar such tricky * situations */ -static int pvfs2_devreq_release(struct inode *inode, struct file *file) +static int orangefs_devreq_release(struct inode *inode, struct file *file) { int unmounted = 0; @@ -537,12 +537,12 @@ static int pvfs2_devreq_release(struct inode *inode, struct file *file) __func__); mutex_lock(&devreq_mutex); - pvfs_bufmap_finalize(); + orangefs_bufmap_finalize(); open_access_count--; unmounted = mark_all_pending_mounts(); - gossip_debug(GOSSIP_DEV_DEBUG, "PVFS2 Device Close: Filesystem(s) %s\n", + gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n", (unmounted ? "UNMOUNTED" : "MOUNTED")); mutex_unlock(&devreq_mutex); @@ -578,17 +578,17 @@ int is_daemon_in_service(void) static inline long check_ioctl_command(unsigned int command) { /* Check for valid ioctl codes */ - if (_IOC_TYPE(command) != PVFS_DEV_MAGIC) { + if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) { gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n", command, _IOC_TYPE(command), - PVFS_DEV_MAGIC); + ORANGEFS_DEV_MAGIC); return -EINVAL; } /* and valid ioctl commands */ - if (_IOC_NR(command) >= PVFS_DEV_MAXNR || _IOC_NR(command) <= 0) { + if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) { gossip_err("Invalid ioctl command number [%d >= %d]\n", - _IOC_NR(command), PVFS_DEV_MAXNR); + _IOC_NR(command), ORANGEFS_DEV_MAXNR); return -ENOIOCTLCMD; } return 0; @@ -596,46 +596,46 @@ static inline long check_ioctl_command(unsigned int command) static long dispatch_ioctl_command(unsigned int command, unsigned long arg) { - static __s32 magic = PVFS2_DEVREQ_MAGIC; + static __s32 magic = ORANGEFS_DEVREQ_MAGIC; static __s32 max_up_size = MAX_ALIGNED_DEV_REQ_UPSIZE; static __s32 max_down_size = MAX_ALIGNED_DEV_REQ_DOWNSIZE; - struct PVFS_dev_map_desc user_desc; + struct ORANGEFS_dev_map_desc user_desc; int ret = 0; struct dev_mask_info_s mask_info = { 0 }; struct dev_mask2_info_s mask2_info = { 0, 0 }; int upstream_kmod = 1; struct list_head *tmp = NULL; - struct pvfs2_sb_info_s *pvfs2_sb = NULL; + struct orangefs_sb_info_s *orangefs_sb = NULL; /* mtmoore: add locking here */ switch (command) { - case PVFS_DEV_GET_MAGIC: + case ORANGEFS_DEV_GET_MAGIC: return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ? -EIO : 0); - case PVFS_DEV_GET_MAX_UPSIZE: + case ORANGEFS_DEV_GET_MAX_UPSIZE: return ((put_user(max_up_size, (__s32 __user *) arg) == -EFAULT) ? -EIO : 0); - case PVFS_DEV_GET_MAX_DOWNSIZE: + case ORANGEFS_DEV_GET_MAX_DOWNSIZE: return ((put_user(max_down_size, (__s32 __user *) arg) == -EFAULT) ? -EIO : 0); - case PVFS_DEV_MAP: + case ORANGEFS_DEV_MAP: ret = copy_from_user(&user_desc, - (struct PVFS_dev_map_desc __user *) + (struct ORANGEFS_dev_map_desc __user *) arg, - sizeof(struct PVFS_dev_map_desc)); - return ret ? -EIO : pvfs_bufmap_initialize(&user_desc); - case PVFS_DEV_REMOUNT_ALL: + sizeof(struct ORANGEFS_dev_map_desc)); + return ret ? -EIO : orangefs_bufmap_initialize(&user_desc); + case ORANGEFS_DEV_REMOUNT_ALL: gossip_debug(GOSSIP_DEV_DEBUG, - "pvfs2_devreq_ioctl: got PVFS_DEV_REMOUNT_ALL\n"); + "orangefs_devreq_ioctl: got ORANGEFS_DEV_REMOUNT_ALL\n"); /* - * remount all mounted pvfs2 volumes to regain the lost + * remount all mounted orangefs volumes to regain the lost * dynamic mount tables (if any) -- NOTE: this is done * without keeping the superblock list locked due to the * upcall/downcall waiting. also, the request semaphore is @@ -647,30 +647,30 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) if (ret < 0) return ret; gossip_debug(GOSSIP_DEV_DEBUG, - "pvfs2_devreq_ioctl: priority remount in progress\n"); - list_for_each(tmp, &pvfs2_superblocks) { - pvfs2_sb = - list_entry(tmp, struct pvfs2_sb_info_s, list); - if (pvfs2_sb && (pvfs2_sb->sb)) { + "orangefs_devreq_ioctl: priority remount in progress\n"); + list_for_each(tmp, &orangefs_superblocks) { + orangefs_sb = + list_entry(tmp, struct orangefs_sb_info_s, list); + if (orangefs_sb && (orangefs_sb->sb)) { gossip_debug(GOSSIP_DEV_DEBUG, "Remounting SB %p\n", - pvfs2_sb); + orangefs_sb); - ret = pvfs2_remount(pvfs2_sb->sb); + ret = orangefs_remount(orangefs_sb->sb); if (ret) { gossip_debug(GOSSIP_DEV_DEBUG, "SB %p remount failed\n", - pvfs2_sb); + orangefs_sb); break; } } } gossip_debug(GOSSIP_DEV_DEBUG, - "pvfs2_devreq_ioctl: priority remount complete\n"); + "orangefs_devreq_ioctl: priority remount complete\n"); mutex_unlock(&request_mutex); return ret; - case PVFS_DEV_UPSTREAM: + case ORANGEFS_DEV_UPSTREAM: ret = copy_to_user((void __user *)arg, &upstream_kmod, sizeof(upstream_kmod)); @@ -680,7 +680,7 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) else return ret; - case PVFS_DEV_CLIENT_MASK: + case ORANGEFS_DEV_CLIENT_MASK: ret = copy_from_user(&mask2_info, (void __user *)arg, sizeof(struct dev_mask2_info_s)); @@ -699,13 +699,13 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) return ret; - case PVFS_DEV_CLIENT_STRING: + case ORANGEFS_DEV_CLIENT_STRING: ret = copy_from_user(&client_debug_array_string, (void __user *)arg, - PVFS2_MAX_DEBUG_STRING_LEN); + ORANGEFS_MAX_DEBUG_STRING_LEN); if (ret != 0) { pr_info("%s: " - "PVFS_DEV_CLIENT_STRING: copy_from_user failed" + "ORANGEFS_DEV_CLIENT_STRING: copy_from_user failed" "\n", __func__); return -EIO; @@ -753,13 +753,13 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) debugfs_remove(client_debug_dentry); - pvfs2_client_debug_init(); + orangefs_client_debug_init(); help_string_initialized++; return ret; - case PVFS_DEV_DEBUG: + case ORANGEFS_DEV_DEBUG: ret = copy_from_user(&mask_info, (void __user *)arg, sizeof(mask_info)); @@ -774,21 +774,21 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) * the kernel debug mask was set when the * kernel module was loaded; don't override * it if the client-core was started without - * a value for PVFS2_KMODMASK. + * a value for ORANGEFS_KMODMASK. */ return 0; } debug_mask_to_string(&mask_info.mask_value, mask_info.mask_type); gossip_debug_mask = mask_info.mask_value; - pr_info("PVFS: kernel debug mask has been modified to " + pr_info("ORANGEFS: kernel debug mask has been modified to " ":%s: :%llx:\n", kernel_debug_string, (unsigned long long)gossip_debug_mask); } else if (mask_info.mask_type == CLIENT_MASK) { debug_mask_to_string(&mask_info.mask_value, mask_info.mask_type); - pr_info("PVFS: client debug mask has been modified to" + pr_info("ORANGEFS: client debug mask has been modified to" ":%s: :%llx:\n", client_debug_string, llu(mask_info.mask_value)); @@ -805,7 +805,7 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) return -ENOIOCTLCMD; } -static long pvfs2_devreq_ioctl(struct file *file, +static long orangefs_devreq_ioctl(struct file *file, unsigned int command, unsigned long arg) { long ret; @@ -820,8 +820,8 @@ static long pvfs2_devreq_ioctl(struct file *file, #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ -/* Compat structure for the PVFS_DEV_MAP ioctl */ -struct PVFS_dev_map_desc32 { +/* Compat structure for the ORANGEFS_DEV_MAP ioctl */ +struct ORANGEFS_dev_map_desc32 { compat_uptr_t ptr; __s32 total_size; __s32 size; @@ -830,12 +830,12 @@ struct PVFS_dev_map_desc32 { static unsigned long translate_dev_map26(unsigned long args, long *error) { - struct PVFS_dev_map_desc32 __user *p32 = (void __user *)args; + struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args; /* * Depending on the architecture, allocate some space on the * user-call-stack based on our expected layout. */ - struct PVFS_dev_map_desc __user *p = + struct ORANGEFS_dev_map_desc __user *p = compat_alloc_user_space(sizeof(*p)); compat_uptr_t addr; @@ -863,7 +863,7 @@ static unsigned long translate_dev_map26(unsigned long args, long *error) * 32 bit user-space apps' ioctl handlers when kernel modules * is compiled as a 64 bit one */ -static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd, +static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long args) { long ret; @@ -873,7 +873,7 @@ static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd, ret = check_ioctl_command(cmd); if (ret < 0) return ret; - if (cmd == PVFS_DEV_MAP) { + if (cmd == ORANGEFS_DEV_MAP) { /* * convert the arguments to what we expect internally * in kernel space @@ -896,89 +896,89 @@ static long pvfs2_devreq_compat_ioctl(struct file *filp, unsigned int cmd, * not noticed until we tried to compile on power pc... */ #if (defined(CONFIG_COMPAT) && !defined(HAVE_REGISTER_IOCTL32_CONVERSION)) || !defined(CONFIG_COMPAT) -static int pvfs2_ioctl32_init(void) +static int orangefs_ioctl32_init(void) { return 0; } -static void pvfs2_ioctl32_cleanup(void) +static void orangefs_ioctl32_cleanup(void) { return; } #endif /* the assigned character device major number */ -static int pvfs2_dev_major; +static int orangefs_dev_major; /* - * Initialize pvfs2 device specific state: + * Initialize orangefs device specific state: * Must be called at module load time only */ -int pvfs2_dev_init(void) +int orangefs_dev_init(void) { int ret; /* register the ioctl32 sub-system */ - ret = pvfs2_ioctl32_init(); + ret = orangefs_ioctl32_init(); if (ret < 0) return ret; - /* register pvfs2-req device */ - pvfs2_dev_major = register_chrdev(0, - PVFS2_REQDEVICE_NAME, - &pvfs2_devreq_file_operations); - if (pvfs2_dev_major < 0) { + /* register orangefs-req device */ + orangefs_dev_major = register_chrdev(0, + ORANGEFS_REQDEVICE_NAME, + &orangefs_devreq_file_operations); + if (orangefs_dev_major < 0) { gossip_debug(GOSSIP_DEV_DEBUG, "Failed to register /dev/%s (error %d)\n", - PVFS2_REQDEVICE_NAME, pvfs2_dev_major); - pvfs2_ioctl32_cleanup(); - return pvfs2_dev_major; + ORANGEFS_REQDEVICE_NAME, orangefs_dev_major); + orangefs_ioctl32_cleanup(); + return orangefs_dev_major; } gossip_debug(GOSSIP_DEV_DEBUG, "*** /dev/%s character device registered ***\n", - PVFS2_REQDEVICE_NAME); + ORANGEFS_REQDEVICE_NAME); gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n", - PVFS2_REQDEVICE_NAME, pvfs2_dev_major); + ORANGEFS_REQDEVICE_NAME, orangefs_dev_major); return 0; } -void pvfs2_dev_cleanup(void) +void orangefs_dev_cleanup(void) { - unregister_chrdev(pvfs2_dev_major, PVFS2_REQDEVICE_NAME); + unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME); gossip_debug(GOSSIP_DEV_DEBUG, "*** /dev/%s character device unregistered ***\n", - PVFS2_REQDEVICE_NAME); + ORANGEFS_REQDEVICE_NAME); /* unregister the ioctl32 sub-system */ - pvfs2_ioctl32_cleanup(); + orangefs_ioctl32_cleanup(); } -static unsigned int pvfs2_devreq_poll(struct file *file, +static unsigned int orangefs_devreq_poll(struct file *file, struct poll_table_struct *poll_table) { int poll_revent_mask = 0; if (open_access_count == 1) { - poll_wait(file, &pvfs2_request_list_waitq, poll_table); + poll_wait(file, &orangefs_request_list_waitq, poll_table); - spin_lock(&pvfs2_request_list_lock); - if (!list_empty(&pvfs2_request_list)) + spin_lock(&orangefs_request_list_lock); + if (!list_empty(&orangefs_request_list)) poll_revent_mask |= POLL_IN; - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); } return poll_revent_mask; } -const struct file_operations pvfs2_devreq_file_operations = { +const struct file_operations orangefs_devreq_file_operations = { .owner = THIS_MODULE, - .read = pvfs2_devreq_read, - .write_iter = pvfs2_devreq_write_iter, - .open = pvfs2_devreq_open, - .release = pvfs2_devreq_release, - .unlocked_ioctl = pvfs2_devreq_ioctl, + .read = orangefs_devreq_read, + .write_iter = orangefs_devreq_write_iter, + .open = orangefs_devreq_open, + .release = orangefs_devreq_release, + .unlocked_ioctl = orangefs_devreq_ioctl, #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */ - .compat_ioctl = pvfs2_devreq_compat_ioctl, + .compat_ioctl = orangefs_devreq_compat_ioctl, #endif - .poll = pvfs2_devreq_poll + .poll = orangefs_devreq_poll }; diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 3049cd61b700..452d589b9747 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -10,7 +10,7 @@ struct readdir_handle_s { int buffer_index; - struct pvfs2_readdir_response_s readdir_response; + struct orangefs_readdir_response_s readdir_response; void *dents_buf; }; @@ -18,28 +18,28 @@ struct readdir_handle_s { * decode routine needed by kmod to make sense of the shared page for readdirs. */ static long decode_dirents(char *ptr, size_t size, - struct pvfs2_readdir_response_s *readdir) + struct orangefs_readdir_response_s *readdir) { int i; - struct pvfs2_readdir_response_s *rd = - (struct pvfs2_readdir_response_s *) ptr; + struct orangefs_readdir_response_s *rd = + (struct orangefs_readdir_response_s *) ptr; char *buf = ptr; - if (size < offsetof(struct pvfs2_readdir_response_s, dirent_array)) + if (size < offsetof(struct orangefs_readdir_response_s, dirent_array)) return -EINVAL; readdir->token = rd->token; - readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount; - readdir->dirent_array = kcalloc(readdir->pvfs_dirent_outcount, + readdir->orangefs_dirent_outcount = rd->orangefs_dirent_outcount; + readdir->dirent_array = kcalloc(readdir->orangefs_dirent_outcount, sizeof(*readdir->dirent_array), GFP_KERNEL); if (readdir->dirent_array == NULL) return -ENOMEM; - buf += offsetof(struct pvfs2_readdir_response_s, dirent_array); - size -= offsetof(struct pvfs2_readdir_response_s, dirent_array); + buf += offsetof(struct orangefs_readdir_response_s, dirent_array); + size -= offsetof(struct orangefs_readdir_response_s, dirent_array); - for (i = 0; i < readdir->pvfs_dirent_outcount; i++) { + for (i = 0; i < readdir->orangefs_dirent_outcount; i++) { __u32 len; if (size < 4) @@ -60,7 +60,7 @@ static long decode_dirents(char *ptr, size_t size, buf += len; readdir->dirent_array[i].khandle = - *(struct pvfs2_khandle *) buf; + *(struct orangefs_khandle *) buf; buf += 16; } return buf - ptr; @@ -98,7 +98,7 @@ static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, return ret; } -static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap, +static void readdir_handle_dtor(struct orangefs_bufmap *bufmap, struct readdir_handle_s *rhandle) { if (rhandle == NULL) @@ -123,9 +123,9 @@ static void readdir_handle_dtor(struct pvfs2_bufmap *bufmap, /* * Read directory entries from an instance of an open directory. */ -static int pvfs2_readdir(struct file *file, struct dir_context *ctx) +static int orangefs_readdir(struct file *file, struct dir_context *ctx) { - struct pvfs2_bufmap *bufmap = NULL; + struct orangefs_bufmap *bufmap = NULL; int ret = 0; int buffer_index; /* @@ -136,8 +136,8 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) __u64 pos = 0; ino_t ino = 0; struct dentry *dentry = file->f_path.dentry; - struct pvfs2_kernel_op_s *new_op = NULL; - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(dentry->d_inode); + struct orangefs_kernel_op_s *new_op = NULL; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode); int buffer_full = 0; struct readdir_handle_s rhandle; int i = 0; @@ -155,26 +155,26 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) pos = (__u64) ctx->pos; /* are we done? */ - if (pos == PVFS_READDIR_END) { + if (pos == ORANGEFS_READDIR_END) { gossip_debug(GOSSIP_DIR_DEBUG, "Skipping to termination path\n"); return 0; } gossip_debug(GOSSIP_DIR_DEBUG, - "pvfs2_readdir called on %s (pos=%llu)\n", + "orangefs_readdir called on %s (pos=%llu)\n", dentry->d_name.name, llu(pos)); rhandle.buffer_index = -1; rhandle.dents_buf = NULL; memset(&rhandle.readdir_response, 0, sizeof(rhandle.readdir_response)); - new_op = op_alloc(PVFS2_VFS_OP_READDIR); + new_op = op_alloc(ORANGEFS_VFS_OP_READDIR); if (!new_op) return -ENOMEM; new_op->uses_shared_memory = 1; - new_op->upcall.req.readdir.refn = pvfs2_inode->refn; + new_op->upcall.req.readdir.refn = orangefs_inode->refn; new_op->upcall.req.readdir.max_dirent_count = MAX_DIRENT_COUNT_READDIR; gossip_debug(GOSSIP_DIR_DEBUG, @@ -187,14 +187,14 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) get_new_buffer_index: ret = readdir_index_get(&bufmap, &buffer_index); if (ret < 0) { - gossip_lerr("pvfs2_readdir: readdir_index_get() failure (%d)\n", + gossip_lerr("orangefs_readdir: readdir_index_get() failure (%d)\n", ret); goto out_free_op; } new_op->upcall.req.readdir.buf_index = buffer_index; ret = service_operation(new_op, - "pvfs2_readdir", + "orangefs_readdir", get_interruptible_flag(dentry->d_inode)); gossip_debug(GOSSIP_DIR_DEBUG, @@ -238,7 +238,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) new_op->downcall.trailer_size, buffer_index); if (bytes_decoded < 0) { - gossip_err("pvfs2_readdir: Could not decode trailer buffer into a readdir response %d\n", + gossip_err("orangefs_readdir: Could not decode trailer buffer into a readdir response %d\n", ret); ret = bytes_decoded; readdir_index_put(bufmap, buffer_index); @@ -246,7 +246,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) } if (bytes_decoded != new_op->downcall.trailer_size) { - gossip_err("pvfs2_readdir: # bytes decoded (%ld) " + gossip_err("orangefs_readdir: # bytes decoded (%ld) " "!= trailer size (%ld)\n", bytes_decoded, (long)new_op->downcall.trailer_size); @@ -255,7 +255,7 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) } /* - * pvfs2 doesn't actually store dot and dot-dot, but + * orangefs doesn't actually store dot and dot-dot, but * we need to have them represented. */ if (pos == 0) { @@ -279,19 +279,19 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) } /* - * we stored PVFS_ITERATE_NEXT in ctx->pos last time around + * we stored ORANGEFS_ITERATE_NEXT in ctx->pos last time around * to prevent "finding" dot and dot-dot on any iteration * other than the first. */ - if (ctx->pos == PVFS_ITERATE_NEXT) + if (ctx->pos == ORANGEFS_ITERATE_NEXT) ctx->pos = 0; for (i = ctx->pos; - i < rhandle.readdir_response.pvfs_dirent_outcount; + i < rhandle.readdir_response.orangefs_dirent_outcount; i++) { len = rhandle.readdir_response.dirent_array[i].d_length; current_entry = rhandle.readdir_response.dirent_array[i].d_name; - current_ino = pvfs2_khandle_to_ino( + current_ino = orangefs_khandle_to_ino( &(rhandle.readdir_response.dirent_array[i].khandle)); gossip_debug(GOSSIP_DIR_DEBUG, @@ -323,28 +323,28 @@ static int pvfs2_readdir(struct file *file, struct dir_context *ctx) */ if (ret) { *ptoken = rhandle.readdir_response.token; - ctx->pos = PVFS_ITERATE_NEXT; + ctx->pos = ORANGEFS_ITERATE_NEXT; } /* * Did we hit the end of the directory? */ - if (rhandle.readdir_response.token == PVFS_READDIR_END && + if (rhandle.readdir_response.token == ORANGEFS_READDIR_END && !buffer_full) { gossip_debug(GOSSIP_DIR_DEBUG, - "End of dir detected; setting ctx->pos to PVFS_READDIR_END.\n"); - ctx->pos = PVFS_READDIR_END; + "End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n"); + ctx->pos = ORANGEFS_READDIR_END; } out_destroy_handle: readdir_handle_dtor(bufmap, &rhandle); out_free_op: op_release(new_op); - gossip_debug(GOSSIP_DIR_DEBUG, "pvfs2_readdir returning %d\n", ret); + gossip_debug(GOSSIP_DIR_DEBUG, "orangefs_readdir returning %d\n", ret); return ret; } -static int pvfs2_dir_open(struct inode *inode, struct file *file) +static int orangefs_dir_open(struct inode *inode, struct file *file) { __u64 *ptoken; @@ -353,21 +353,21 @@ static int pvfs2_dir_open(struct inode *inode, struct file *file) return -ENOMEM; ptoken = file->private_data; - *ptoken = PVFS_READDIR_START; + *ptoken = ORANGEFS_READDIR_START; return 0; } -static int pvfs2_dir_release(struct inode *inode, struct file *file) +static int orangefs_dir_release(struct inode *inode, struct file *file) { - pvfs2_flush_inode(inode); + orangefs_flush_inode(inode); kfree(file->private_data); return 0; } -/** PVFS2 implementation of VFS directory operations */ -const struct file_operations pvfs2_dir_operations = { +/** ORANGEFS implementation of VFS directory operations */ +const struct file_operations orangefs_dir_operations = { .read = generic_read_dir, - .iterate = pvfs2_readdir, - .open = pvfs2_dir_open, - .release = pvfs2_dir_release, + .iterate = orangefs_readdir, + .open = orangefs_dir_open, + .release = orangefs_dir_release, }; diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h index e372f446f6ba..72d4cac54821 100644 --- a/fs/orangefs/downcall.h +++ b/fs/orangefs/downcall.h @@ -15,42 +15,42 @@ * Sanitized the device-client core interaction * for clean 32-64 bit usage */ -struct pvfs2_io_response { +struct orangefs_io_response { __s64 amt_complete; }; -struct pvfs2_lookup_response { - struct pvfs2_object_kref refn; +struct orangefs_lookup_response { + struct orangefs_object_kref refn; }; -struct pvfs2_create_response { - struct pvfs2_object_kref refn; +struct orangefs_create_response { + struct orangefs_object_kref refn; }; -struct pvfs2_symlink_response { - struct pvfs2_object_kref refn; +struct orangefs_symlink_response { + struct orangefs_object_kref refn; }; -struct pvfs2_getattr_response { - struct PVFS_sys_attr_s attributes; - char link_target[PVFS2_NAME_LEN]; +struct orangefs_getattr_response { + struct ORANGEFS_sys_attr_s attributes; + char link_target[ORANGEFS_NAME_LEN]; }; -struct pvfs2_mkdir_response { - struct pvfs2_object_kref refn; +struct orangefs_mkdir_response { + struct orangefs_object_kref refn; }; /* * duplication of some system interface structures so that I don't have * to allocate extra memory */ -struct pvfs2_dirent { +struct orangefs_dirent { char *d_name; int d_length; - struct pvfs2_khandle khandle; + struct orangefs_khandle khandle; }; -struct pvfs2_statfs_response { +struct orangefs_statfs_response { __s64 block_size; __s64 blocks_total; __s64 blocks_avail; @@ -58,47 +58,47 @@ struct pvfs2_statfs_response { __s64 files_avail; }; -struct pvfs2_fs_mount_response { +struct orangefs_fs_mount_response { __s32 fs_id; __s32 id; - struct pvfs2_khandle root_khandle; + struct orangefs_khandle root_khandle; }; /* the getxattr response is the attribute value */ -struct pvfs2_getxattr_response { +struct orangefs_getxattr_response { __s32 val_sz; __s32 __pad1; - char val[PVFS_MAX_XATTR_VALUELEN]; + char val[ORANGEFS_MAX_XATTR_VALUELEN]; }; /* the listxattr response is an array of attribute names */ -struct pvfs2_listxattr_response { +struct orangefs_listxattr_response { __s32 returned_count; __s32 __pad1; __u64 token; - char key[PVFS_MAX_XATTR_LISTLEN * PVFS_MAX_XATTR_NAMELEN]; + char key[ORANGEFS_MAX_XATTR_LISTLEN * ORANGEFS_MAX_XATTR_NAMELEN]; __s32 keylen; __s32 __pad2; - __s32 lengths[PVFS_MAX_XATTR_LISTLEN]; + __s32 lengths[ORANGEFS_MAX_XATTR_LISTLEN]; }; -struct pvfs2_param_response { +struct orangefs_param_response { __s64 value; }; #define PERF_COUNT_BUF_SIZE 4096 -struct pvfs2_perf_count_response { +struct orangefs_perf_count_response { char buffer[PERF_COUNT_BUF_SIZE]; }; #define FS_KEY_BUF_SIZE 4096 -struct pvfs2_fs_key_response { +struct orangefs_fs_key_response { __s32 fs_keylen; __s32 __pad1; char fs_key[FS_KEY_BUF_SIZE]; }; -struct pvfs2_downcall_s { +struct orangefs_downcall_s { __s32 type; __s32 status; /* currently trailer is used only by readdir */ @@ -106,28 +106,28 @@ struct pvfs2_downcall_s { char *trailer_buf; union { - struct pvfs2_io_response io; - struct pvfs2_lookup_response lookup; - struct pvfs2_create_response create; - struct pvfs2_symlink_response sym; - struct pvfs2_getattr_response getattr; - struct pvfs2_mkdir_response mkdir; - struct pvfs2_statfs_response statfs; - struct pvfs2_fs_mount_response fs_mount; - struct pvfs2_getxattr_response getxattr; - struct pvfs2_listxattr_response listxattr; - struct pvfs2_param_response param; - struct pvfs2_perf_count_response perf_count; - struct pvfs2_fs_key_response fs_key; + struct orangefs_io_response io; + struct orangefs_lookup_response lookup; + struct orangefs_create_response create; + struct orangefs_symlink_response sym; + struct orangefs_getattr_response getattr; + struct orangefs_mkdir_response mkdir; + struct orangefs_statfs_response statfs; + struct orangefs_fs_mount_response fs_mount; + struct orangefs_getxattr_response getxattr; + struct orangefs_listxattr_response listxattr; + struct orangefs_param_response param; + struct orangefs_perf_count_response perf_count; + struct orangefs_fs_key_response fs_key; } resp; }; -struct pvfs2_readdir_response_s { +struct orangefs_readdir_response_s { __u64 token; __u64 directory_version; __u32 __pad2; - __u32 pvfs_dirent_outcount; - struct pvfs2_dirent *dirent_array; + __u32 orangefs_dirent_outcount; + struct orangefs_dirent *dirent_array; }; #endif /* __DOWNCALL_H */ diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 3a8140f289f6..ae5d8ed67ed5 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -29,7 +29,7 @@ do { \ * can futher be kernel-space or user-space addresses. * or it can pointers to struct page's */ -static int precopy_buffers(struct pvfs2_bufmap *bufmap, +static int precopy_buffers(struct orangefs_bufmap *bufmap, int buffer_index, struct iov_iter *iter, size_t total_size) @@ -42,10 +42,10 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, if (total_size) { - ret = pvfs_bufmap_copy_from_iovec(bufmap, - iter, - buffer_index, - total_size); + ret = orangefs_bufmap_copy_from_iovec(bufmap, + iter, + buffer_index, + total_size); if (ret < 0) gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n", __func__, @@ -66,7 +66,7 @@ static int precopy_buffers(struct pvfs2_bufmap *bufmap, * can futher be kernel-space or user-space addresses. * or it can pointers to struct page's */ -static int postcopy_buffers(struct pvfs2_bufmap *bufmap, +static int postcopy_buffers(struct orangefs_bufmap *bufmap, int buffer_index, struct iov_iter *iter, size_t total_size) @@ -78,10 +78,10 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, * struct page pointers. */ if (total_size) { - ret = pvfs_bufmap_copy_to_iovec(bufmap, - iter, - buffer_index, - total_size); + ret = orangefs_bufmap_copy_to_iovec(bufmap, + iter, + buffer_index, + total_size); if (ret < 0) gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n", __func__, @@ -93,34 +93,34 @@ static int postcopy_buffers(struct pvfs2_bufmap *bufmap, /* * Post and wait for the I/O upcall to finish */ -static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, +static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode, loff_t *offset, struct iov_iter *iter, size_t total_size, loff_t readahead_size) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; - struct pvfs2_bufmap *bufmap = NULL; - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_khandle *handle = &orangefs_inode->refn.khandle; + struct orangefs_bufmap *bufmap = NULL; + struct orangefs_kernel_op_s *new_op = NULL; int buffer_index = -1; ssize_t ret; - new_op = op_alloc(PVFS2_VFS_OP_FILE_IO); + new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO); if (!new_op) { ret = -ENOMEM; goto out; } /* synchronous I/O */ - new_op->upcall.req.io.async_vfs_io = PVFS_VFS_SYNC_IO; + new_op->upcall.req.io.async_vfs_io = ORANGEFS_VFS_SYNC_IO; new_op->upcall.req.io.readahead_size = readahead_size; new_op->upcall.req.io.io_type = type; - new_op->upcall.req.io.refn = pvfs2_inode->refn; + new_op->upcall.req.io.refn = orangefs_inode->refn; populate_shared_memory: /* get a shared buffer index */ - ret = pvfs_bufmap_get(&bufmap, &buffer_index); + ret = orangefs_bufmap_get(&bufmap, &buffer_index); if (ret < 0) { gossip_debug(GOSSIP_FILE_DEBUG, - "%s: pvfs_bufmap_get failure (%ld)\n", + "%s: orangefs_bufmap_get failure (%ld)\n", __func__, (long)ret); goto out; } @@ -146,7 +146,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * Stage 1: copy the buffers into client-core's address space * precopy_buffers only pertains to writes. */ - if (type == PVFS_IO_WRITE) { + if (type == ORANGEFS_IO_WRITE) { ret = precopy_buffers(bufmap, buffer_index, iter, @@ -163,14 +163,14 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, /* Stage 2: Service the I/O operation */ ret = service_operation(new_op, - type == PVFS_IO_WRITE ? + type == ORANGEFS_IO_WRITE ? "file_write" : "file_read", get_interruptible_flag(inode)); /* * If service_operation() returns -EAGAIN #and# the operation was - * purged from pvfs2_request_list or htable_ops_in_progress, then + * purged from orangefs_request_list or htable_ops_in_progress, then * we know that the client was restarted, causing the shared memory * area to be wiped clean. To restart a write operation in this * case, we must re-copy the data from the user's iovec to a NEW @@ -178,7 +178,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * a new shared memory location. */ if (ret == -EAGAIN && op_state_purged(new_op)) { - pvfs_bufmap_put(bufmap, buffer_index); + orangefs_bufmap_put(bufmap, buffer_index); gossip_debug(GOSSIP_FILE_DEBUG, "%s:going to repopulate_shared_memory.\n", __func__); @@ -199,7 +199,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, else gossip_err("%s: error in %s handle %pU, returning %zd\n", __func__, - type == PVFS_IO_READ ? + type == ORANGEFS_IO_READ ? "read from" : "write to", handle, ret); goto out; @@ -209,7 +209,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * Stage 3: Post copy buffers from client-core's address space * postcopy_buffers only pertains to reads. */ - if (type == PVFS_IO_READ) { + if (type == ORANGEFS_IO_READ) { ret = postcopy_buffers(bufmap, buffer_index, iter, @@ -243,7 +243,7 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, out: if (buffer_index >= 0) { - pvfs_bufmap_put(bufmap, buffer_index); + orangefs_bufmap_put(bufmap, buffer_index); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): PUT buffer_index %d\n", __func__, handle, buffer_index); @@ -263,12 +263,12 @@ static ssize_t wait_for_direct_io(enum PVFS_io_type type, struct inode *inode, * augmented/extended metadata attached to the file. * Note: File extended attributes override any mount options. */ -static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, +static ssize_t do_readv_writev(enum ORANGEFS_io_type type, struct file *file, loff_t *offset, struct iov_iter *iter) { struct inode *inode = file->f_mapping->host; - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_khandle *handle = &pvfs2_inode->refn.khandle; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_khandle *handle = &orangefs_inode->refn.khandle; size_t count = iov_iter_count(iter); ssize_t total_count = 0; ssize_t ret = -EINVAL; @@ -279,7 +279,7 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, handle, (int)count); - if (type == PVFS_IO_WRITE) { + if (type == ORANGEFS_IO_WRITE) { gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): proceeding with offset : %llu, " "size %d\n", @@ -299,8 +299,8 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, size_t amt_complete; /* how much to transfer in this loop iteration */ - if (each_count > pvfs_bufmap_size_query()) - each_count = pvfs_bufmap_size_query(); + if (each_count > orangefs_bufmap_size_query()) + each_count = orangefs_bufmap_size_query(); gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): size of each_count(%d)\n", @@ -346,10 +346,10 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, ret = total_count; out: if (ret > 0) { - if (type == PVFS_IO_READ) { + if (type == ORANGEFS_IO_READ) { file_accessed(file); } else { - SetMtimeFlag(pvfs2_inode); + SetMtimeFlag(orangefs_inode); inode->i_mtime = CURRENT_TIME; mark_inode_dirty_sync(inode); } @@ -368,19 +368,19 @@ static ssize_t do_readv_writev(enum PVFS_io_type type, struct file *file, * Read data from a specified offset in a file (referenced by inode). * Data may be placed either in a user or kernel buffer. */ -ssize_t pvfs2_inode_read(struct inode *inode, - struct iov_iter *iter, - loff_t *offset, - loff_t readahead_size) +ssize_t orangefs_inode_read(struct inode *inode, + struct iov_iter *iter, + loff_t *offset, + loff_t readahead_size) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); size_t count = iov_iter_count(iter); size_t bufmap_size; ssize_t ret = -EINVAL; - g_pvfs2_stats.reads++; + g_orangefs_stats.reads++; - bufmap_size = pvfs_bufmap_size_query(); + bufmap_size = orangefs_bufmap_size_query(); if (count > bufmap_size) { gossip_debug(GOSSIP_FILE_DEBUG, "%s: count is too large (%zd/%zd)!\n", @@ -391,11 +391,11 @@ ssize_t pvfs2_inode_read(struct inode *inode, gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU) %zd@%llu\n", __func__, - &pvfs2_inode->refn.khandle, + &orangefs_inode->refn.khandle, count, llu(*offset)); - ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, iter, + ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, offset, iter, count, readahead_size); if (ret > 0) *offset += ret; @@ -403,13 +403,13 @@ ssize_t pvfs2_inode_read(struct inode *inode, gossip_debug(GOSSIP_FILE_DEBUG, "%s(%pU): Value(%zd) returned.\n", __func__, - &pvfs2_inode->refn.khandle, + &orangefs_inode->refn.khandle, ret); return ret; } -static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) +static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; loff_t pos = *(&iocb->ki_pos); @@ -417,17 +417,17 @@ static ssize_t pvfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) BUG_ON(iocb->private); - gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_read_iter\n"); + gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_read_iter\n"); - g_pvfs2_stats.reads++; + g_orangefs_stats.reads++; - rc = do_readv_writev(PVFS_IO_READ, file, &pos, iter); + rc = do_readv_writev(ORANGEFS_IO_READ, file, &pos, iter); iocb->ki_pos = pos; return rc; } -static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) +static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; loff_t pos; @@ -435,23 +435,23 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) BUG_ON(iocb->private); - gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_file_write_iter\n"); + gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n"); mutex_lock(&file->f_mapping->host->i_mutex); /* Make sure generic_write_checks sees an up to date inode size. */ if (file->f_flags & O_APPEND) { - rc = pvfs2_inode_getattr(file->f_mapping->host, - PVFS_ATTR_SYS_SIZE); + rc = orangefs_inode_getattr(file->f_mapping->host, + ORANGEFS_ATTR_SYS_SIZE); if (rc) { - gossip_err("%s: pvfs2_inode_getattr failed, rc:%zd:.\n", + gossip_err("%s: orangefs_inode_getattr failed, rc:%zd:.\n", __func__, rc); goto out; } } if (file->f_pos > i_size_read(file->f_mapping->host)) - pvfs2_i_size_write(file->f_mapping->host, file->f_pos); + orangefs_i_size_write(file->f_mapping->host, file->f_pos); rc = generic_write_checks(iocb, iter); @@ -468,7 +468,7 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) */ pos = *(&iocb->ki_pos); - rc = do_readv_writev(PVFS_IO_WRITE, + rc = do_readv_writev(ORANGEFS_IO_WRITE, file, &pos, iter); @@ -479,7 +479,7 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) } iocb->ki_pos = pos; - g_pvfs2_stats.writes++; + g_orangefs_stats.writes++; out: @@ -490,14 +490,14 @@ static ssize_t pvfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) /* * Perform a miscellaneous operation on a file. */ -static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; __u64 val = 0; unsigned long uval; gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_ioctl: called with cmd %d\n", + "orangefs_ioctl: called with cmd %d\n", cmd); /* @@ -506,17 +506,17 @@ static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) */ if (cmd == FS_IOC_GETFLAGS) { val = 0; - ret = pvfs2_inode_getxattr(file_inode(file), - PVFS2_XATTR_NAME_DEFAULT_PREFIX, - "user.pvfs2.meta_hint", - &val, sizeof(val)); + ret = orangefs_inode_getxattr(file_inode(file), + ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, + "user.pvfs2.meta_hint", + &val, sizeof(val)); if (ret < 0 && ret != -ENODATA) return ret; else if (ret == -ENODATA) val = 0; uval = val; gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_ioctl: FS_IOC_GETFLAGS: %llu\n", + "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n", (unsigned long long)uval); return put_user(uval, (int __user *)arg); } else if (cmd == FS_IOC_SETFLAGS) { @@ -524,25 +524,25 @@ static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (get_user(uval, (int __user *)arg)) return -EFAULT; /* - * PVFS_MIRROR_FL is set internally when the mirroring mode + * ORANGEFS_MIRROR_FL is set internally when the mirroring mode * is turned on for a file. The user is not allowed to turn * on this bit, but the bit is present if the user first gets * the flags and then updates the flags with some new * settings. So, we ignore it in the following edit. bligon. */ - if ((uval & ~PVFS_MIRROR_FL) & + if ((uval & ~ORANGEFS_MIRROR_FL) & (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) { - gossip_err("pvfs2_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n"); + gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n"); return -EINVAL; } val = uval; gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_ioctl: FS_IOC_SETFLAGS: %llu\n", + "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n", (unsigned long long)val); - ret = pvfs2_inode_setxattr(file_inode(file), - PVFS2_XATTR_NAME_DEFAULT_PREFIX, - "user.pvfs2.meta_hint", - &val, sizeof(val), 0); + ret = orangefs_inode_setxattr(file_inode(file), + ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, + "user.pvfs2.meta_hint", + &val, sizeof(val), 0); } return ret; @@ -551,10 +551,10 @@ static long pvfs2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* * Memory map a region of a file. */ -static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma) +static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma) { gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_file_mmap: called on %s\n", + "orangefs_file_mmap: called on %s\n", (file ? (char *)file->f_path.dentry->d_name.name : (char *)"Unknown")); @@ -575,13 +575,13 @@ static int pvfs2_file_mmap(struct file *file, struct vm_area_struct *vma) * * \note Not called when each file is closed. */ -static int pvfs2_file_release(struct inode *inode, struct file *file) +static int orangefs_file_release(struct inode *inode, struct file *file) { gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_file_release: called on %s\n", + "orangefs_file_release: called on %s\n", file->f_path.dentry->d_name.name); - pvfs2_flush_inode(inode); + orangefs_flush_inode(inode); /* * remove all associated inode pages from the page cache and mmap @@ -599,35 +599,35 @@ static int pvfs2_file_release(struct inode *inode, struct file *file) /* * Push all data for a specific file onto permanent storage. */ -static int pvfs2_fsync(struct file *file, +static int orangefs_fsync(struct file *file, loff_t start, loff_t end, int datasync) { int ret = -EINVAL; - struct pvfs2_inode_s *pvfs2_inode = - PVFS2_I(file->f_path.dentry->d_inode); - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_inode_s *orangefs_inode = + ORANGEFS_I(file->f_path.dentry->d_inode); + struct orangefs_kernel_op_s *new_op = NULL; /* required call */ filemap_write_and_wait_range(file->f_mapping, start, end); - new_op = op_alloc(PVFS2_VFS_OP_FSYNC); + new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC); if (!new_op) return -ENOMEM; - new_op->upcall.req.fsync.refn = pvfs2_inode->refn; + new_op->upcall.req.fsync.refn = orangefs_inode->refn; ret = service_operation(new_op, - "pvfs2_fsync", + "orangefs_fsync", get_interruptible_flag(file->f_path.dentry->d_inode)); gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_fsync got return value of %d\n", + "orangefs_fsync got return value of %d\n", ret); op_release(new_op); - pvfs2_flush_inode(file->f_path.dentry->d_inode); + orangefs_flush_inode(file->f_path.dentry->d_inode); return ret; } @@ -640,36 +640,36 @@ static int pvfs2_fsync(struct file *file, * Future upgrade could support SEEK_DATA and SEEK_HOLE but would * require much changes to the FS */ -static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) +static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin) { int ret = -EINVAL; struct inode *inode = file->f_path.dentry->d_inode; if (!inode) { - gossip_err("pvfs2_file_llseek: invalid inode (NULL)\n"); + gossip_err("orangefs_file_llseek: invalid inode (NULL)\n"); return ret; } - if (origin == PVFS2_SEEK_END) { + if (origin == ORANGEFS_SEEK_END) { /* * revalidate the inode's file size. * NOTE: We are only interested in file size here, * so we set mask accordingly. */ - ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_SIZE); + ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_SIZE); if (ret) { gossip_debug(GOSSIP_FILE_DEBUG, "%s:%s:%d calling make bad inode\n", __FILE__, __func__, __LINE__); - pvfs2_make_bad_inode(inode); + orangefs_make_bad_inode(inode); return ret; } } gossip_debug(GOSSIP_FILE_DEBUG, - "pvfs2_file_llseek: offset is %ld | origin is %d" + "orangefs_file_llseek: offset is %ld | origin is %d" " | inode size is %lu\n", (long)offset, origin, @@ -682,11 +682,11 @@ static loff_t pvfs2_file_llseek(struct file *file, loff_t offset, int origin) * Support local locks (locks that only this kernel knows about) * if Orangefs was mounted -o local_lock. */ -static int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) +static int orangefs_lock(struct file *filp, int cmd, struct file_lock *fl) { int rc = -EINVAL; - if (PVFS2_SB(filp->f_inode->i_sb)->flags & PVFS2_OPT_LOCAL_LOCK) { + if (ORANGEFS_SB(filp->f_inode->i_sb)->flags & ORANGEFS_OPT_LOCAL_LOCK) { if (cmd == F_GETLK) { rc = 0; posix_test_lock(filp, fl); @@ -698,15 +698,15 @@ static int pvfs2_lock(struct file *filp, int cmd, struct file_lock *fl) return rc; } -/** PVFS2 implementation of VFS file operations */ -const struct file_operations pvfs2_file_operations = { - .llseek = pvfs2_file_llseek, - .read_iter = pvfs2_file_read_iter, - .write_iter = pvfs2_file_write_iter, - .lock = pvfs2_lock, - .unlocked_ioctl = pvfs2_ioctl, - .mmap = pvfs2_file_mmap, +/** ORANGEFS implementation of VFS file operations */ +const struct file_operations orangefs_file_operations = { + .llseek = orangefs_file_llseek, + .read_iter = orangefs_file_read_iter, + .write_iter = orangefs_file_write_iter, + .lock = orangefs_lock, + .unlocked_ioctl = orangefs_ioctl, + .mmap = orangefs_file_mmap, .open = generic_file_open, - .release = pvfs2_file_release, - .fsync = pvfs2_fsync, + .release = orangefs_file_release, + .fsync = orangefs_fsync, }; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 70d1c1925ea3..58e83182d3dc 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -26,7 +26,7 @@ static int read_one_page(struct page *page) iov_iter_bvec(&to, ITER_BVEC | READ, &bv, 1, PAGE_SIZE); gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_readpage called with page %p\n", + "orangefs_readpage called with page %p\n", page); max_block = ((inode->i_size / blocksize) + 1); @@ -34,10 +34,10 @@ static int read_one_page(struct page *page) if (page->index < max_block) { loff_t blockptr_offset = (((loff_t) page->index) << blockbits); - bytes_read = pvfs2_inode_read(inode, - &to, - &blockptr_offset, - inode->i_size); + bytes_read = orangefs_inode_read(inode, + &to, + &blockptr_offset, + inode->i_size); } /* this will only zero remaining unread portions of the page data */ iov_iter_zero(~0U, &to); @@ -57,12 +57,12 @@ static int read_one_page(struct page *page) return ret; } -static int pvfs2_readpage(struct file *file, struct page *page) +static int orangefs_readpage(struct file *file, struct page *page) { return read_one_page(page); } -static int pvfs2_readpages(struct file *file, +static int orangefs_readpages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) @@ -70,7 +70,7 @@ static int pvfs2_readpages(struct file *file, int page_idx; int ret; - gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_readpages called\n"); + gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_readpages called\n"); for (page_idx = 0; page_idx < nr_pages; page_idx++) { struct page *page; @@ -93,12 +93,12 @@ static int pvfs2_readpages(struct file *file, return 0; } -static void pvfs2_invalidatepage(struct page *page, +static void orangefs_invalidatepage(struct page *page, unsigned int offset, unsigned int length) { gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_invalidatepage called on page %p " + "orangefs_invalidatepage called on page %p " "(offset is %u)\n", page, offset); @@ -109,10 +109,10 @@ static void pvfs2_invalidatepage(struct page *page, } -static int pvfs2_releasepage(struct page *page, gfp_t foo) +static int orangefs_releasepage(struct page *page, gfp_t foo) { gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_releasepage called on page %p\n", + "orangefs_releasepage called on page %p\n", page); return 0; } @@ -131,32 +131,32 @@ static int pvfs2_releasepage(struct page *page, gfp_t foo) * loff_t offset) *{ * gossip_debug(GOSSIP_INODE_DEBUG, - * "pvfs2_direct_IO: %s\n", + * "orangefs_direct_IO: %s\n", * iocb->ki_filp->f_path.dentry->d_name.name); * * return -EINVAL; *} */ -struct backing_dev_info pvfs2_backing_dev_info = { - .name = "pvfs2", +struct backing_dev_info orangefs_backing_dev_info = { + .name = "orangefs", .ra_pages = 0, .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, }; -/** PVFS2 implementation of address space operations */ -const struct address_space_operations pvfs2_address_operations = { - .readpage = pvfs2_readpage, - .readpages = pvfs2_readpages, - .invalidatepage = pvfs2_invalidatepage, - .releasepage = pvfs2_releasepage, +/** ORANGEFS2 implementation of address space operations */ +const struct address_space_operations orangefs_address_operations = { + .readpage = orangefs_readpage, + .readpages = orangefs_readpages, + .invalidatepage = orangefs_invalidatepage, + .releasepage = orangefs_releasepage, /* .direct_IO = pvfs2_direct_IO */ }; -static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr) +static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op; loff_t orig_size = i_size_read(inode); int ret = -EINVAL; @@ -164,17 +164,17 @@ static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr) "%s: %pU: Handle is %pU | fs_id %d | size is %llu\n", __func__, get_khandle_from_ino(inode), - &pvfs2_inode->refn.khandle, - pvfs2_inode->refn.fs_id, + &orangefs_inode->refn.khandle, + orangefs_inode->refn.fs_id, iattr->ia_size); truncate_setsize(inode, iattr->ia_size); - new_op = op_alloc(PVFS2_VFS_OP_TRUNCATE); + new_op = op_alloc(ORANGEFS_VFS_OP_TRUNCATE); if (!new_op) return -ENOMEM; - new_op->upcall.req.truncate.refn = pvfs2_inode->refn; + new_op->upcall.req.truncate.refn = orangefs_inode->refn; new_op->upcall.req.truncate.size = (__s64) iattr->ia_size; ret = service_operation(new_op, __func__, @@ -185,7 +185,7 @@ static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr) * the status value tells us if it went through ok or not */ gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2: pvfs2_truncate got return value of %d\n", + "orangefs: orangefs_truncate got return value of %d\n", ret); op_release(new_op); @@ -216,13 +216,13 @@ static int pvfs2_setattr_size(struct inode *inode, struct iattr *iattr) /* * Change attributes of an object referenced by dentry. */ -int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr) +int orangefs_setattr(struct dentry *dentry, struct iattr *iattr) { int ret = -EINVAL; struct inode *inode = dentry->d_inode; gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_setattr: called on %s\n", + "orangefs_setattr: called on %s\n", dentry->d_name.name); ret = inode_change_ok(inode, iattr); @@ -231,7 +231,7 @@ int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr) if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size != i_size_read(inode)) { - ret = pvfs2_setattr_size(inode, iattr); + ret = orangefs_setattr_size(inode, iattr); if (ret) goto out; } @@ -239,9 +239,9 @@ int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr) setattr_copy(inode, iattr); mark_inode_dirty(inode); - ret = pvfs2_inode_setattr(inode, iattr); + ret = orangefs_inode_setattr(inode, iattr); gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_setattr: inode_setattr returned %d\n", + "orangefs_setattr: inode_setattr returned %d\n", ret); if (!ret && (iattr->ia_valid & ATTR_MODE)) @@ -249,23 +249,23 @@ int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr) ret = posix_acl_chmod(inode, inode->i_mode); out: - gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_setattr: returning %d\n", ret); + gossip_debug(GOSSIP_INODE_DEBUG, "orangefs_setattr: returning %d\n", ret); return ret; } /* * Obtain attributes of an object given a dentry */ -int pvfs2_getattr(struct vfsmount *mnt, +int orangefs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat) { int ret = -ENOENT; struct inode *inode = dentry->d_inode; - struct pvfs2_inode_s *pvfs2_inode = NULL; + struct orangefs_inode_s *orangefs_inode = NULL; gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_getattr: called on %s\n", + "orangefs_getattr: called on %s\n", dentry->d_name.name); /* @@ -273,12 +273,12 @@ int pvfs2_getattr(struct vfsmount *mnt, * fields/attributes of the inode would be refreshed. So again, we * dont have too much of a choice but refresh all the attributes. */ - ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); if (ret == 0) { generic_fillattr(inode, kstat); /* override block size reported to stat */ - pvfs2_inode = PVFS2_I(inode); - kstat->blksize = pvfs2_inode->blksize; + orangefs_inode = ORANGEFS_I(inode); + kstat->blksize = orangefs_inode->blksize; } else { /* assume an I/O error and flag inode as bad */ gossip_debug(GOSSIP_INODE_DEBUG, @@ -286,39 +286,39 @@ int pvfs2_getattr(struct vfsmount *mnt, __FILE__, __func__, __LINE__); - pvfs2_make_bad_inode(inode); + orangefs_make_bad_inode(inode); } return ret; } -/* PVFS2 implementation of VFS inode operations for files */ -struct inode_operations pvfs2_file_inode_operations = { - .get_acl = pvfs2_get_acl, - .set_acl = pvfs2_set_acl, - .setattr = pvfs2_setattr, - .getattr = pvfs2_getattr, +/* ORANGEDS2 implementation of VFS inode operations for files */ +struct inode_operations orangefs_file_inode_operations = { + .get_acl = orangefs_get_acl, + .set_acl = orangefs_set_acl, + .setattr = orangefs_setattr, + .getattr = orangefs_getattr, .setxattr = generic_setxattr, .getxattr = generic_getxattr, - .listxattr = pvfs2_listxattr, + .listxattr = orangefs_listxattr, .removexattr = generic_removexattr, }; -static int pvfs2_init_iops(struct inode *inode) +static int orangefs_init_iops(struct inode *inode) { - inode->i_mapping->a_ops = &pvfs2_address_operations; + inode->i_mapping->a_ops = &orangefs_address_operations; switch (inode->i_mode & S_IFMT) { case S_IFREG: - inode->i_op = &pvfs2_file_inode_operations; - inode->i_fop = &pvfs2_file_operations; + inode->i_op = &orangefs_file_inode_operations; + inode->i_fop = &orangefs_file_operations; inode->i_blkbits = PAGE_CACHE_SHIFT; break; case S_IFLNK: - inode->i_op = &pvfs2_symlink_inode_operations; + inode->i_op = &orangefs_symlink_inode_operations; break; case S_IFDIR: - inode->i_op = &pvfs2_dir_inode_operations; - inode->i_fop = &pvfs2_dir_operations; + inode->i_op = &orangefs_dir_inode_operations; + inode->i_fop = &orangefs_dir_operations; break; default: gossip_debug(GOSSIP_INODE_DEBUG, @@ -331,75 +331,75 @@ static int pvfs2_init_iops(struct inode *inode) } /* - * Given a PVFS2 object identifier (fsid, handle), convert it into a ino_t type + * Given a ORANGEFS object identifier (fsid, handle), convert it into a ino_t type * that will be used as a hash-index from where the handle will * be searched for in the VFS hash table of inodes. */ -static inline ino_t pvfs2_handle_hash(struct pvfs2_object_kref *ref) +static inline ino_t orangefs_handle_hash(struct orangefs_object_kref *ref) { if (!ref) return 0; - return pvfs2_khandle_to_ino(&(ref->khandle)); + return orangefs_khandle_to_ino(&(ref->khandle)); } /* * Called to set up an inode from iget5_locked. */ -static int pvfs2_set_inode(struct inode *inode, void *data) +static int orangefs_set_inode(struct inode *inode, void *data) { - struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data; - struct pvfs2_inode_s *pvfs2_inode = NULL; + struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; + struct orangefs_inode_s *orangefs_inode = NULL; /* Make sure that we have sane parameters */ if (!data || !inode) return 0; - pvfs2_inode = PVFS2_I(inode); - if (!pvfs2_inode) + orangefs_inode = ORANGEFS_I(inode); + if (!orangefs_inode) return 0; - pvfs2_inode->refn.fs_id = ref->fs_id; - pvfs2_inode->refn.khandle = ref->khandle; + orangefs_inode->refn.fs_id = ref->fs_id; + orangefs_inode->refn.khandle = ref->khandle; return 0; } /* * Called to determine if handles match. */ -static int pvfs2_test_inode(struct inode *inode, void *data) +static int orangefs_test_inode(struct inode *inode, void *data) { - struct pvfs2_object_kref *ref = (struct pvfs2_object_kref *) data; - struct pvfs2_inode_s *pvfs2_inode = NULL; + struct orangefs_object_kref *ref = (struct orangefs_object_kref *) data; + struct orangefs_inode_s *orangefs_inode = NULL; - pvfs2_inode = PVFS2_I(inode); - return (!PVFS_khandle_cmp(&(pvfs2_inode->refn.khandle), &(ref->khandle)) - && pvfs2_inode->refn.fs_id == ref->fs_id); + orangefs_inode = ORANGEFS_I(inode); + return (!ORANGEFS_khandle_cmp(&(orangefs_inode->refn.khandle), &(ref->khandle)) + && orangefs_inode->refn.fs_id == ref->fs_id); } /* - * Front-end to lookup the inode-cache maintained by the VFS using the PVFS2 + * Front-end to lookup the inode-cache maintained by the VFS using the ORANGEFS * file handle. * * @sb: the file system super block instance. - * @ref: The PVFS2 object for which we are trying to locate an inode structure. + * @ref: The ORANGEFS object for which we are trying to locate an inode structure. */ -struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref) +struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref *ref) { struct inode *inode = NULL; unsigned long hash; int error; - hash = pvfs2_handle_hash(ref); - inode = iget5_locked(sb, hash, pvfs2_test_inode, pvfs2_set_inode, ref); + hash = orangefs_handle_hash(ref); + inode = iget5_locked(sb, hash, orangefs_test_inode, orangefs_set_inode, ref); if (!inode || !(inode->i_state & I_NEW)) return inode; - error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); if (error) { iget_failed(inode); return ERR_PTR(error); } inode->i_ino = hash; /* needed for stat etc */ - pvfs2_init_iops(inode); + orangefs_init_iops(inode); unlock_new_inode(inode); gossip_debug(GOSSIP_INODE_DEBUG, @@ -415,15 +415,15 @@ struct inode *pvfs2_iget(struct super_block *sb, struct pvfs2_object_kref *ref) /* * Allocate an inode for a newly created file and insert it into the inode hash. */ -struct inode *pvfs2_new_inode(struct super_block *sb, struct inode *dir, - int mode, dev_t dev, struct pvfs2_object_kref *ref) +struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, + int mode, dev_t dev, struct orangefs_object_kref *ref) { - unsigned long hash = pvfs2_handle_hash(ref); + unsigned long hash = orangefs_handle_hash(ref); struct inode *inode; int error; gossip_debug(GOSSIP_INODE_DEBUG, - "pvfs2_get_custom_inode_common: called\n" + "orangefs_get_custom_inode_common: called\n" "(sb is %p | MAJOR(dev)=%u | MINOR(dev)=%u mode=%o)\n", sb, MAJOR(dev), @@ -434,14 +434,14 @@ struct inode *pvfs2_new_inode(struct super_block *sb, struct inode *dir, if (!inode) return NULL; - pvfs2_set_inode(inode, ref); + orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ - error = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT); + error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); if (error) goto out_iput; - pvfs2_init_iops(inode); + orangefs_init_iops(inode); inode->i_mode = mode; inode->i_uid = current_fsuid(); @@ -450,14 +450,14 @@ struct inode *pvfs2_new_inode(struct super_block *sb, struct inode *dir, inode->i_size = PAGE_CACHE_SIZE; inode->i_rdev = dev; - error = insert_inode_locked4(inode, hash, pvfs2_test_inode, ref); + error = insert_inode_locked4(inode, hash, orangefs_test_inode, ref); if (error < 0) goto out_iput; gossip_debug(GOSSIP_INODE_DEBUG, "Initializing ACL's for inode %pU\n", get_khandle_from_ino(inode)); - pvfs2_init_acl(inode, dir); + orangefs_init_acl(inode, dir); return inode; out_iput: diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 39f96ace0289..333c87c8b0f5 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -14,34 +14,34 @@ /* * Get a newly allocated inode to go with a negative dentry. */ -static int pvfs2_create(struct inode *dir, +static int orangefs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool exclusive) { - struct pvfs2_inode_s *parent = PVFS2_I(dir); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *parent = ORANGEFS_I(dir); + struct orangefs_kernel_op_s *new_op; struct inode *inode; int ret; gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); - new_op = op_alloc(PVFS2_VFS_OP_CREATE); + new_op = op_alloc(ORANGEFS_VFS_OP_CREATE); if (!new_op) return -ENOMEM; new_op->upcall.req.create.parent_refn = parent->refn; fill_default_sys_attrs(new_op->upcall.req.create.attributes, - PVFS_TYPE_METAFILE, mode); + ORANGEFS_TYPE_METAFILE, mode); strncpy(new_op->upcall.req.create.d_name, - dentry->d_name.name, PVFS2_NAME_LEN); + dentry->d_name.name, ORANGEFS_NAME_LEN); ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); gossip_debug(GOSSIP_NAME_DEBUG, - "Create Got PVFS2 handle %pU on fsid %d (ret=%d)\n", + "Create Got ORANGEFS handle %pU on fsid %d (ret=%d)\n", &new_op->downcall.resp.create.refn.khandle, new_op->downcall.resp.create.refn.fs_id, ret); @@ -52,10 +52,10 @@ static int pvfs2_create(struct inode *dir, goto out; } - inode = pvfs2_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, + inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, &new_op->downcall.resp.create.refn); if (IS_ERR(inode)) { - gossip_err("*** Failed to allocate pvfs2 file inode\n"); + gossip_err("*** Failed to allocate orangefs file inode\n"); ret = PTR_ERR(inode); goto out; } @@ -86,11 +86,11 @@ static int pvfs2_create(struct inode *dir, * Attempt to resolve an object name (dentry->d_name), parent handle, and * fsid into a handle for the object. */ -static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, +static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - struct pvfs2_inode_s *parent = PVFS2_I(dir); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *parent = ORANGEFS_I(dir); + struct orangefs_kernel_op_s *new_op; struct inode *inode; struct dentry *res; int ret = -EINVAL; @@ -106,10 +106,10 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %s\n", __func__, dentry->d_name.name); - if (dentry->d_name.len > (PVFS2_NAME_LEN - 1)) + if (dentry->d_name.len > (ORANGEFS_NAME_LEN - 1)) return ERR_PTR(-ENAMETOOLONG); - new_op = op_alloc(PVFS2_VFS_OP_LOOKUP); + new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); if (!new_op) return ERR_PTR(-ENOMEM); @@ -123,7 +123,7 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, new_op->upcall.req.lookup.parent_refn = parent->refn; strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, - PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); gossip_debug(GOSSIP_NAME_DEBUG, "%s: doing lookup on %s under %pU,%d (follow=%s)\n", @@ -132,7 +132,7 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, &new_op->upcall.req.lookup.parent_refn.khandle, new_op->upcall.req.lookup.parent_refn.fs_id, ((new_op->upcall.req.lookup.sym_follow == - PVFS2_LOOKUP_LINK_FOLLOW) ? "yes" : "no")); + ORANGEFS_LOOKUP_LINK_FOLLOW) ? "yes" : "no")); ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); @@ -158,7 +158,7 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, */ gossip_debug(GOSSIP_NAME_DEBUG, - "pvfs2_lookup: Adding *negative* dentry " + "orangefs_lookup: Adding *negative* dentry " "%p for %s\n", dentry, dentry->d_name.name); @@ -173,7 +173,7 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, goto out; } - inode = pvfs2_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); + inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); if (IS_ERR(inode)) { gossip_debug(GOSSIP_NAME_DEBUG, "error %ld from iget\n", PTR_ERR(inode)); @@ -202,11 +202,11 @@ static struct dentry *pvfs2_lookup(struct inode *dir, struct dentry *dentry, } /* return 0 on success; non-zero otherwise */ -static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) +static int orangefs_unlink(struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; - struct pvfs2_inode_s *parent = PVFS2_I(dir); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *parent = ORANGEFS_I(dir); + struct orangefs_kernel_op_s *new_op; int ret; gossip_debug(GOSSIP_NAME_DEBUG, @@ -218,15 +218,15 @@ static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) &parent->refn.khandle, parent->refn.fs_id); - new_op = op_alloc(PVFS2_VFS_OP_REMOVE); + new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE); if (!new_op) return -ENOMEM; new_op->upcall.req.remove.parent_refn = parent->refn; strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name, - PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); - ret = service_operation(new_op, "pvfs2_unlink", + ret = service_operation(new_op, "orangefs_unlink", get_interruptible_flag(inode)); /* when request is serviced properly, free req op struct */ @@ -242,12 +242,12 @@ static int pvfs2_unlink(struct inode *dir, struct dentry *dentry) return ret; } -static int pvfs2_symlink(struct inode *dir, +static int orangefs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { - struct pvfs2_inode_s *parent = PVFS2_I(dir); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *parent = ORANGEFS_I(dir); + struct orangefs_kernel_op_s *new_op; struct inode *inode; int mode = 755; int ret; @@ -257,25 +257,25 @@ static int pvfs2_symlink(struct inode *dir, if (!symname) return -EINVAL; - new_op = op_alloc(PVFS2_VFS_OP_SYMLINK); + new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK); if (!new_op) return -ENOMEM; new_op->upcall.req.sym.parent_refn = parent->refn; fill_default_sys_attrs(new_op->upcall.req.sym.attributes, - PVFS_TYPE_SYMLINK, + ORANGEFS_TYPE_SYMLINK, mode); strncpy(new_op->upcall.req.sym.entry_name, dentry->d_name.name, - PVFS2_NAME_LEN); - strncpy(new_op->upcall.req.sym.target, symname, PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); + strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_LEN); ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); gossip_debug(GOSSIP_NAME_DEBUG, - "Symlink Got PVFS2 handle %pU on fsid %d (ret=%d)\n", + "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n", &new_op->downcall.resp.sym.refn.khandle, new_op->downcall.resp.sym.refn.fs_id, ret); @@ -286,11 +286,11 @@ static int pvfs2_symlink(struct inode *dir, goto out; } - inode = pvfs2_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, + inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &new_op->downcall.resp.sym.refn); if (IS_ERR(inode)) { gossip_err - ("*** Failed to allocate pvfs2 symlink inode\n"); + ("*** Failed to allocate orangefs symlink inode\n"); ret = PTR_ERR(inode); goto out; } @@ -316,29 +316,29 @@ static int pvfs2_symlink(struct inode *dir, return ret; } -static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - struct pvfs2_inode_s *parent = PVFS2_I(dir); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *parent = ORANGEFS_I(dir); + struct orangefs_kernel_op_s *new_op; struct inode *inode; int ret; - new_op = op_alloc(PVFS2_VFS_OP_MKDIR); + new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR); if (!new_op) return -ENOMEM; new_op->upcall.req.mkdir.parent_refn = parent->refn; fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes, - PVFS_TYPE_DIRECTORY, mode); + ORANGEFS_TYPE_DIRECTORY, mode); strncpy(new_op->upcall.req.mkdir.d_name, - dentry->d_name.name, PVFS2_NAME_LEN); + dentry->d_name.name, ORANGEFS_NAME_LEN); ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); gossip_debug(GOSSIP_NAME_DEBUG, - "Mkdir Got PVFS2 handle %pU on fsid %d\n", + "Mkdir Got ORANGEFS handle %pU on fsid %d\n", &new_op->downcall.resp.mkdir.refn.khandle, new_op->downcall.resp.mkdir.refn.fs_id); @@ -349,10 +349,10 @@ static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) goto out; } - inode = pvfs2_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, + inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &new_op->downcall.resp.mkdir.refn); if (IS_ERR(inode)) { - gossip_err("*** Failed to allocate pvfs2 dir inode\n"); + gossip_err("*** Failed to allocate orangefs dir inode\n"); ret = PTR_ERR(inode); goto out; } @@ -381,42 +381,42 @@ static int pvfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) return ret; } -static int pvfs2_rename(struct inode *old_dir, +static int orangefs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { - struct pvfs2_kernel_op_s *new_op; + struct orangefs_kernel_op_s *new_op; int ret; gossip_debug(GOSSIP_NAME_DEBUG, - "pvfs2_rename: called (%s/%s => %s/%s) ct=%d\n", + "orangefs_rename: called (%s/%s => %s/%s) ct=%d\n", old_dentry->d_parent->d_name.name, old_dentry->d_name.name, new_dentry->d_parent->d_name.name, new_dentry->d_name.name, d_count(new_dentry)); - new_op = op_alloc(PVFS2_VFS_OP_RENAME); + new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); if (!new_op) return -EINVAL; - new_op->upcall.req.rename.old_parent_refn = PVFS2_I(old_dir)->refn; - new_op->upcall.req.rename.new_parent_refn = PVFS2_I(new_dir)->refn; + new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn; + new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn; strncpy(new_op->upcall.req.rename.d_old_name, old_dentry->d_name.name, - PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); strncpy(new_op->upcall.req.rename.d_new_name, new_dentry->d_name.name, - PVFS2_NAME_LEN); + ORANGEFS_NAME_LEN); ret = service_operation(new_op, - "pvfs2_rename", + "orangefs_rename", get_interruptible_flag(old_dentry->d_inode)); gossip_debug(GOSSIP_NAME_DEBUG, - "pvfs2_rename: got downcall status %d\n", + "orangefs_rename: got downcall status %d\n", ret); if (new_dentry->d_inode) @@ -426,21 +426,21 @@ static int pvfs2_rename(struct inode *old_dir, return ret; } -/* PVFS2 implementation of VFS inode operations for directories */ -struct inode_operations pvfs2_dir_inode_operations = { - .lookup = pvfs2_lookup, - .get_acl = pvfs2_get_acl, - .set_acl = pvfs2_set_acl, - .create = pvfs2_create, - .unlink = pvfs2_unlink, - .symlink = pvfs2_symlink, - .mkdir = pvfs2_mkdir, - .rmdir = pvfs2_unlink, - .rename = pvfs2_rename, - .setattr = pvfs2_setattr, - .getattr = pvfs2_getattr, +/* ORANGEFS implementation of VFS inode operations for directories */ +struct inode_operations orangefs_dir_inode_operations = { + .lookup = orangefs_lookup, + .get_acl = orangefs_get_acl, + .set_acl = orangefs_set_acl, + .create = orangefs_create, + .unlink = orangefs_unlink, + .symlink = orangefs_symlink, + .mkdir = orangefs_mkdir, + .rmdir = orangefs_unlink, + .rename = orangefs_rename, + .setattr = orangefs_setattr, + .getattr = orangefs_getattr, .setxattr = generic_setxattr, .getxattr = generic_getxattr, .removexattr = generic_removexattr, - .listxattr = pvfs2_listxattr, + .listxattr = orangefs_listxattr, }; diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 85f611fe0536..5f10ebc83e76 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -20,13 +20,13 @@ extern int cdm_element_count; #define ORANGEFS_KMOD_DEBUG_HELP_FILE "debug-help" #define ORANGEFS_KMOD_DEBUG_FILE "kernel-debug" #define ORANGEFS_CLIENT_DEBUG_FILE "client-debug" -#define PVFS2_VERBOSE "verbose" -#define PVFS2_ALL "all" +#define ORANGEFS_VERBOSE "verbose" +#define ORANGEFS_ALL "all" /* pvfs2-config.h ***********************************************************/ -#define PVFS2_VERSION_MAJOR 2 -#define PVFS2_VERSION_MINOR 9 -#define PVFS2_VERSION_SUB 0 +#define ORANGEFS_VERSION_MAJOR 2 +#define ORANGEFS_VERSION_MINOR 9 +#define ORANGEFS_VERSION_SUB 0 /* khandle stuff ***********************************************************/ @@ -38,15 +38,15 @@ extern int cdm_element_count; * The kernel module will always use the first four bytes and * the last four bytes as an inum. */ -struct pvfs2_khandle { +struct orangefs_khandle { unsigned char u[16]; } __aligned(8); /* * kernel version of an object ref. */ -struct pvfs2_object_kref { - struct pvfs2_khandle khandle; +struct orangefs_object_kref { + struct orangefs_khandle khandle; __s32 fs_id; __s32 __pad1; }; @@ -55,8 +55,8 @@ struct pvfs2_object_kref { * compare 2 khandles assumes little endian thus from large address to * small address */ -static inline int PVFS_khandle_cmp(const struct pvfs2_khandle *kh1, - const struct pvfs2_khandle *kh2) +static inline int ORANGEFS_khandle_cmp(const struct orangefs_khandle *kh1, + const struct orangefs_khandle *kh2) { int i; @@ -70,7 +70,7 @@ static inline int PVFS_khandle_cmp(const struct pvfs2_khandle *kh1, return 0; } -static inline void PVFS_khandle_to(const struct pvfs2_khandle *kh, +static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh, void *p, int size) { @@ -79,7 +79,7 @@ static inline void PVFS_khandle_to(const struct pvfs2_khandle *kh, } -static inline void PVFS_khandle_from(struct pvfs2_khandle *kh, +static inline void ORANGEFS_khandle_from(struct orangefs_khandle *kh, void *p, int size) { memset(kh, 0, 16); @@ -88,152 +88,152 @@ static inline void PVFS_khandle_from(struct pvfs2_khandle *kh, } /* pvfs2-types.h ************************************************************/ -typedef __u32 PVFS_uid; -typedef __u32 PVFS_gid; -typedef __s32 PVFS_fs_id; -typedef __u32 PVFS_permissions; -typedef __u64 PVFS_time; -typedef __s64 PVFS_size; -typedef __u64 PVFS_flags; -typedef __u64 PVFS_ds_position; -typedef __s32 PVFS_error; -typedef __s64 PVFS_offset; - -#define PVFS2_SUPER_MAGIC 0x20030528 +typedef __u32 ORANGEFS_uid; +typedef __u32 ORANGEFS_gid; +typedef __s32 ORANGEFS_fs_id; +typedef __u32 ORANGEFS_permissions; +typedef __u64 ORANGEFS_time; +typedef __s64 ORANGEFS_size; +typedef __u64 ORANGEFS_flags; +typedef __u64 ORANGEFS_ds_position; +typedef __s32 ORANGEFS_error; +typedef __s64 ORANGEFS_offset; + +#define ORANGEFS_SUPER_MAGIC 0x20030528 /* - * PVFS2 error codes are a signed 32-bit integer. Error codes are negative, but + * ORANGEFS error codes are a signed 32-bit integer. Error codes are negative, but * the sign is stripped before decoding. */ /* Bit 31 is not used since it is the sign. */ /* - * Bit 30 specifies that this is a PVFS2 error. A PVFS2 error is either an - * encoded errno value or a PVFS2 protocol error. + * Bit 30 specifies that this is a ORANGEFS error. A ORANGEFS error is either an + * encoded errno value or a ORANGEFS protocol error. */ -#define PVFS_ERROR_BIT (1 << 30) +#define ORANGEFS_ERROR_BIT (1 << 30) /* - * Bit 29 specifies that this is a PVFS2 protocol error and not an encoded + * Bit 29 specifies that this is a ORANGEFS protocol error and not an encoded * errno value. */ -#define PVFS_NON_ERRNO_ERROR_BIT (1 << 29) +#define ORANGEFS_NON_ERRNO_ERROR_BIT (1 << 29) /* * Bits 9, 8, and 7 specify the error class, which encodes the section of * server code the error originated in for logging purposes. It is not used * in the kernel except to be masked out. */ -#define PVFS_ERROR_CLASS_BITS 0x380 +#define ORANGEFS_ERROR_CLASS_BITS 0x380 /* Bits 6 - 0 are reserved for the actual error code. */ -#define PVFS_ERROR_NUMBER_BITS 0x7f +#define ORANGEFS_ERROR_NUMBER_BITS 0x7f /* Encoded errno values are decoded by PINT_errno_mapping in pvfs2-utils.c. */ -/* Our own PVFS2 protocol error codes. */ -#define PVFS_ECANCEL (1|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_EDEVINIT (2|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_EDETAIL (3|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_EHOSTNTFD (4|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_EADDRNTFD (5|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_ENORECVR (6|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_ETRYAGAIN (7|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_ENOTPVFS (8|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) -#define PVFS_ESECURITY (9|PVFS_NON_ERRNO_ERROR_BIT|PVFS_ERROR_BIT) +/* Our own ORANGEFS protocol error codes. */ +#define ORANGEFS_ECANCEL (1|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_EDEVINIT (2|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_EDETAIL (3|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_EHOSTNTFD (4|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_EADDRNTFD (5|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_ENORECVR (6|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_ETRYAGAIN (7|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_ENOTPVFS (8|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) +#define ORANGEFS_ESECURITY (9|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) /* permission bits */ -#define PVFS_O_EXECUTE (1 << 0) -#define PVFS_O_WRITE (1 << 1) -#define PVFS_O_READ (1 << 2) -#define PVFS_G_EXECUTE (1 << 3) -#define PVFS_G_WRITE (1 << 4) -#define PVFS_G_READ (1 << 5) -#define PVFS_U_EXECUTE (1 << 6) -#define PVFS_U_WRITE (1 << 7) -#define PVFS_U_READ (1 << 8) -/* no PVFS_U_VTX (sticky bit) */ -#define PVFS_G_SGID (1 << 10) -#define PVFS_U_SUID (1 << 11) +#define ORANGEFS_O_EXECUTE (1 << 0) +#define ORANGEFS_O_WRITE (1 << 1) +#define ORANGEFS_O_READ (1 << 2) +#define ORANGEFS_G_EXECUTE (1 << 3) +#define ORANGEFS_G_WRITE (1 << 4) +#define ORANGEFS_G_READ (1 << 5) +#define ORANGEFS_U_EXECUTE (1 << 6) +#define ORANGEFS_U_WRITE (1 << 7) +#define ORANGEFS_U_READ (1 << 8) +/* no ORANGEFS_U_VTX (sticky bit) */ +#define ORANGEFS_G_SGID (1 << 10) +#define ORANGEFS_U_SUID (1 << 11) /* definition taken from stdint.h */ #define INT32_MAX (2147483647) -#define PVFS_ITERATE_START (INT32_MAX - 1) -#define PVFS_ITERATE_END (INT32_MAX - 2) -#define PVFS_ITERATE_NEXT (INT32_MAX - 3) -#define PVFS_READDIR_START PVFS_ITERATE_START -#define PVFS_READDIR_END PVFS_ITERATE_END -#define PVFS_IMMUTABLE_FL FS_IMMUTABLE_FL -#define PVFS_APPEND_FL FS_APPEND_FL -#define PVFS_NOATIME_FL FS_NOATIME_FL -#define PVFS_MIRROR_FL 0x01000000ULL -#define PVFS_O_EXECUTE (1 << 0) -#define PVFS_FS_ID_NULL ((__s32)0) -#define PVFS_ATTR_SYS_UID (1 << 0) -#define PVFS_ATTR_SYS_GID (1 << 1) -#define PVFS_ATTR_SYS_PERM (1 << 2) -#define PVFS_ATTR_SYS_ATIME (1 << 3) -#define PVFS_ATTR_SYS_CTIME (1 << 4) -#define PVFS_ATTR_SYS_MTIME (1 << 5) -#define PVFS_ATTR_SYS_TYPE (1 << 6) -#define PVFS_ATTR_SYS_ATIME_SET (1 << 7) -#define PVFS_ATTR_SYS_MTIME_SET (1 << 8) -#define PVFS_ATTR_SYS_SIZE (1 << 20) -#define PVFS_ATTR_SYS_LNK_TARGET (1 << 24) -#define PVFS_ATTR_SYS_DFILE_COUNT (1 << 25) -#define PVFS_ATTR_SYS_DIRENT_COUNT (1 << 26) -#define PVFS_ATTR_SYS_BLKSIZE (1 << 28) -#define PVFS_ATTR_SYS_MIRROR_COPIES_COUNT (1 << 29) -#define PVFS_ATTR_SYS_COMMON_ALL \ - (PVFS_ATTR_SYS_UID | \ - PVFS_ATTR_SYS_GID | \ - PVFS_ATTR_SYS_PERM | \ - PVFS_ATTR_SYS_ATIME | \ - PVFS_ATTR_SYS_CTIME | \ - PVFS_ATTR_SYS_MTIME | \ - PVFS_ATTR_SYS_TYPE) - -#define PVFS_ATTR_SYS_ALL_SETABLE \ -(PVFS_ATTR_SYS_COMMON_ALL-PVFS_ATTR_SYS_TYPE) - -#define PVFS_ATTR_SYS_ALL_NOHINT \ - (PVFS_ATTR_SYS_COMMON_ALL | \ - PVFS_ATTR_SYS_SIZE | \ - PVFS_ATTR_SYS_LNK_TARGET | \ - PVFS_ATTR_SYS_DFILE_COUNT | \ - PVFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ - PVFS_ATTR_SYS_DIRENT_COUNT | \ - PVFS_ATTR_SYS_BLKSIZE) -#define PVFS_XATTR_REPLACE 0x2 -#define PVFS_XATTR_CREATE 0x1 -#define PVFS_MAX_SERVER_ADDR_LEN 256 -#define PVFS_NAME_MAX 256 +#define ORANGEFS_ITERATE_START (INT32_MAX - 1) +#define ORANGEFS_ITERATE_END (INT32_MAX - 2) +#define ORANGEFS_ITERATE_NEXT (INT32_MAX - 3) +#define ORANGEFS_READDIR_START ORANGEFS_ITERATE_START +#define ORANGEFS_READDIR_END ORANGEFS_ITERATE_END +#define ORANGEFS_IMMUTABLE_FL FS_IMMUTABLE_FL +#define ORANGEFS_APPEND_FL FS_APPEND_FL +#define ORANGEFS_NOATIME_FL FS_NOATIME_FL +#define ORANGEFS_MIRROR_FL 0x01000000ULL +#define ORANGEFS_O_EXECUTE (1 << 0) +#define ORANGEFS_FS_ID_NULL ((__s32)0) +#define ORANGEFS_ATTR_SYS_UID (1 << 0) +#define ORANGEFS_ATTR_SYS_GID (1 << 1) +#define ORANGEFS_ATTR_SYS_PERM (1 << 2) +#define ORANGEFS_ATTR_SYS_ATIME (1 << 3) +#define ORANGEFS_ATTR_SYS_CTIME (1 << 4) +#define ORANGEFS_ATTR_SYS_MTIME (1 << 5) +#define ORANGEFS_ATTR_SYS_TYPE (1 << 6) +#define ORANGEFS_ATTR_SYS_ATIME_SET (1 << 7) +#define ORANGEFS_ATTR_SYS_MTIME_SET (1 << 8) +#define ORANGEFS_ATTR_SYS_SIZE (1 << 20) +#define ORANGEFS_ATTR_SYS_LNK_TARGET (1 << 24) +#define ORANGEFS_ATTR_SYS_DFILE_COUNT (1 << 25) +#define ORANGEFS_ATTR_SYS_DIRENT_COUNT (1 << 26) +#define ORANGEFS_ATTR_SYS_BLKSIZE (1 << 28) +#define ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT (1 << 29) +#define ORANGEFS_ATTR_SYS_COMMON_ALL \ + (ORANGEFS_ATTR_SYS_UID | \ + ORANGEFS_ATTR_SYS_GID | \ + ORANGEFS_ATTR_SYS_PERM | \ + ORANGEFS_ATTR_SYS_ATIME | \ + ORANGEFS_ATTR_SYS_CTIME | \ + ORANGEFS_ATTR_SYS_MTIME | \ + ORANGEFS_ATTR_SYS_TYPE) + +#define ORANGEFS_ATTR_SYS_ALL_SETABLE \ +(ORANGEFS_ATTR_SYS_COMMON_ALL-ORANGEFS_ATTR_SYS_TYPE) + +#define ORANGEFS_ATTR_SYS_ALL_NOHINT \ + (ORANGEFS_ATTR_SYS_COMMON_ALL | \ + ORANGEFS_ATTR_SYS_SIZE | \ + ORANGEFS_ATTR_SYS_LNK_TARGET | \ + ORANGEFS_ATTR_SYS_DFILE_COUNT | \ + ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ + ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ + ORANGEFS_ATTR_SYS_BLKSIZE) +#define ORANGEFS_XATTR_REPLACE 0x2 +#define ORANGEFS_XATTR_CREATE 0x1 +#define ORANGEFS_MAX_SERVER_ADDR_LEN 256 +#define ORANGEFS_NAME_MAX 256 /* * max extended attribute name len as imposed by the VFS and exploited for the * upcall request types. * NOTE: Please retain them as multiples of 8 even if you wish to change them * This is *NECESSARY* for supporting 32 bit user-space binaries on a 64-bit * kernel. Due to implementation within DBPF, this really needs to be - * PVFS_NAME_MAX, which it was the same value as, but no reason to let it + * ORANGEFS_NAME_MAX, which it was the same value as, but no reason to let it * break if that changes in the future. */ -#define PVFS_MAX_XATTR_NAMELEN PVFS_NAME_MAX /* Not the same as +#define ORANGEFS_MAX_XATTR_NAMELEN ORANGEFS_NAME_MAX /* Not the same as * XATTR_NAME_MAX defined * by */ -#define PVFS_MAX_XATTR_VALUELEN 8192 /* Not the same as XATTR_SIZE_MAX +#define ORANGEFS_MAX_XATTR_VALUELEN 8192 /* Not the same as XATTR_SIZE_MAX * defined by */ -#define PVFS_MAX_XATTR_LISTLEN 16 /* Not the same as XATTR_LIST_MAX +#define ORANGEFS_MAX_XATTR_LISTLEN 16 /* Not the same as XATTR_LIST_MAX * defined by */ /* - * PVFS I/O operation types, used in both system and server interfaces. + * ORANGEFS I/O operation types, used in both system and server interfaces. */ -enum PVFS_io_type { - PVFS_IO_READ = 1, - PVFS_IO_WRITE = 2 +enum ORANGEFS_io_type { + ORANGEFS_IO_READ = 1, + ORANGEFS_IO_WRITE = 2 }; /* @@ -241,21 +241,21 @@ enum PVFS_io_type { * batch and low threshold sizes may need to be modified to reflect this * change. */ -enum pvfs2_ds_type { - PVFS_TYPE_NONE = 0, - PVFS_TYPE_METAFILE = (1 << 0), - PVFS_TYPE_DATAFILE = (1 << 1), - PVFS_TYPE_DIRECTORY = (1 << 2), - PVFS_TYPE_SYMLINK = (1 << 3), - PVFS_TYPE_DIRDATA = (1 << 4), - PVFS_TYPE_INTERNAL = (1 << 5) /* for the server's private use */ +enum orangefs_ds_type { + ORANGEFS_TYPE_NONE = 0, + ORANGEFS_TYPE_METAFILE = (1 << 0), + ORANGEFS_TYPE_DATAFILE = (1 << 1), + ORANGEFS_TYPE_DIRECTORY = (1 << 2), + ORANGEFS_TYPE_SYMLINK = (1 << 3), + ORANGEFS_TYPE_DIRDATA = (1 << 4), + ORANGEFS_TYPE_INTERNAL = (1 << 5) /* for the server's private use */ }; /* - * PVFS_certificate simply stores a buffer with the buffer size. + * ORANGEFS_certificate simply stores a buffer with the buffer size. * The buffer can be converted to an OpenSSL X509 struct for use. */ -struct PVFS_certificate { +struct ORANGEFS_certificate { __u32 buf_size; unsigned char *buf; }; @@ -264,7 +264,7 @@ struct PVFS_certificate { * A credential identifies a user and is signed by the client/user * private key. */ -struct PVFS_credential { +struct ORANGEFS_credential { __u32 userid; /* user id */ __u32 num_groups; /* length of group_array */ __u32 *group_array; /* groups for which the user is a member */ @@ -272,25 +272,25 @@ struct PVFS_credential { __u64 timeout; /* seconds after epoch to time out */ __u32 sig_size; /* length of the signature in bytes */ unsigned char *signature; /* digital signature */ - struct PVFS_certificate certificate; /* user certificate buffer */ + struct ORANGEFS_certificate certificate; /* user certificate buffer */ }; -#define extra_size_PVFS_credential (PVFS_REQ_LIMIT_GROUPS * \ +#define extra_size_ORANGEFS_credential (ORANGEFS_REQ_LIMIT_GROUPS * \ sizeof(__u32) + \ - PVFS_REQ_LIMIT_ISSUER + \ - PVFS_REQ_LIMIT_SIGNATURE + \ - extra_size_PVFS_certificate) + ORANGEFS_REQ_LIMIT_ISSUER + \ + ORANGEFS_REQ_LIMIT_SIGNATURE + \ + extra_size_ORANGEFS_certificate) /* This structure is used by the VFS-client interaction alone */ -struct PVFS_keyval_pair { - char key[PVFS_MAX_XATTR_NAMELEN]; +struct ORANGEFS_keyval_pair { + char key[ORANGEFS_MAX_XATTR_NAMELEN]; __s32 key_sz; /* __s32 for portable, fixed-size structures */ __s32 val_sz; - char val[PVFS_MAX_XATTR_VALUELEN]; + char val[ORANGEFS_MAX_XATTR_VALUELEN]; }; /* pvfs2-sysint.h ***********************************************************/ /* Describes attributes for a file, directory, or symlink. */ -struct PVFS_sys_attr_s { +struct ORANGEFS_sys_attr_s { __u32 owner; __u32 group; __u32 perms; @@ -323,18 +323,18 @@ struct PVFS_sys_attr_s { char *dist_params; __s64 dirent_count; - enum pvfs2_ds_type objtype; + enum orangefs_ds_type objtype; __u64 flags; __u32 mask; __s64 blksize; }; -#define PVFS2_LOOKUP_LINK_NO_FOLLOW 0 -#define PVFS2_LOOKUP_LINK_FOLLOW 1 +#define ORANGEFS_LOOKUP_LINK_NO_FOLLOW 0 +#define ORANGEFS_LOOKUP_LINK_FOLLOW 1 /* pint-dev.h ***************************************************************/ -/* parameter structure used in PVFS_DEV_DEBUG ioctl command */ +/* parameter structure used in ORANGEFS_DEV_DEBUG ioctl command */ struct dev_mask_info_s { enum { KERNEL_MASK, @@ -349,7 +349,7 @@ struct dev_mask2_info_s { }; /* pvfs2-util.h *************************************************************/ -__s32 PVFS_util_translate_mode(int mode); +__s32 ORANGEFS_util_translate_mode(int mode); /* pvfs2-debug.h ************************************************************/ #include "pvfs2-debug.h" @@ -359,9 +359,9 @@ __s32 PVFS_util_translate_mode(int mode); #define lld(x) (long long)(x) /* pint-dev-shared.h ********************************************************/ -#define PVFS_DEV_MAGIC 'k' +#define ORANGEFS_DEV_MAGIC 'k' -#define PVFS2_READDIR_DEFAULT_DESC_COUNT 5 +#define ORANGEFS_READDIR_DEFAULT_DESC_COUNT 5 #define DEV_GET_MAGIC 0x1 #define DEV_GET_MAX_UPSIZE 0x2 @@ -376,39 +376,39 @@ __s32 PVFS_util_translate_mode(int mode); /* supported ioctls, codes are with respect to user-space */ enum { - PVFS_DEV_GET_MAGIC = _IOW(PVFS_DEV_MAGIC, DEV_GET_MAGIC, __s32), - PVFS_DEV_GET_MAX_UPSIZE = - _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_UPSIZE, __s32), - PVFS_DEV_GET_MAX_DOWNSIZE = - _IOW(PVFS_DEV_MAGIC, DEV_GET_MAX_DOWNSIZE, __s32), - PVFS_DEV_MAP = _IO(PVFS_DEV_MAGIC, DEV_MAP), - PVFS_DEV_REMOUNT_ALL = _IO(PVFS_DEV_MAGIC, DEV_REMOUNT_ALL), - PVFS_DEV_DEBUG = _IOR(PVFS_DEV_MAGIC, DEV_DEBUG, __s32), - PVFS_DEV_UPSTREAM = _IOW(PVFS_DEV_MAGIC, DEV_UPSTREAM, int), - PVFS_DEV_CLIENT_MASK = _IOW(PVFS_DEV_MAGIC, + ORANGEFS_DEV_GET_MAGIC = _IOW(ORANGEFS_DEV_MAGIC, DEV_GET_MAGIC, __s32), + ORANGEFS_DEV_GET_MAX_UPSIZE = + _IOW(ORANGEFS_DEV_MAGIC, DEV_GET_MAX_UPSIZE, __s32), + ORANGEFS_DEV_GET_MAX_DOWNSIZE = + _IOW(ORANGEFS_DEV_MAGIC, DEV_GET_MAX_DOWNSIZE, __s32), + ORANGEFS_DEV_MAP = _IO(ORANGEFS_DEV_MAGIC, DEV_MAP), + ORANGEFS_DEV_REMOUNT_ALL = _IO(ORANGEFS_DEV_MAGIC, DEV_REMOUNT_ALL), + ORANGEFS_DEV_DEBUG = _IOR(ORANGEFS_DEV_MAGIC, DEV_DEBUG, __s32), + ORANGEFS_DEV_UPSTREAM = _IOW(ORANGEFS_DEV_MAGIC, DEV_UPSTREAM, int), + ORANGEFS_DEV_CLIENT_MASK = _IOW(ORANGEFS_DEV_MAGIC, DEV_CLIENT_MASK, struct dev_mask2_info_s), - PVFS_DEV_CLIENT_STRING = _IOW(PVFS_DEV_MAGIC, + ORANGEFS_DEV_CLIENT_STRING = _IOW(ORANGEFS_DEV_MAGIC, DEV_CLIENT_STRING, char *), - PVFS_DEV_MAXNR = DEV_MAX_NR, + ORANGEFS_DEV_MAXNR = DEV_MAX_NR, }; /* * version number for use in communicating between kernel space and user * space. Zero signifies the upstream version of the kernel module. */ -#define PVFS_KERNEL_PROTO_VERSION 0 +#define ORANGEFS_KERNEL_PROTO_VERSION 0 /* - * describes memory regions to map in the PVFS_DEV_MAP ioctl. + * describes memory regions to map in the ORANGEFS_DEV_MAP ioctl. * NOTE: See devpvfs2-req.c for 32 bit compat structure. * Since this structure has a variable-sized layout that is different * on 32 and 64 bit platforms, we need to normalize to a 64 bit layout * on such systems before servicing ioctl calls from user-space binaries * that may be 32 bit! */ -struct PVFS_dev_map_desc { +struct ORANGEFS_dev_map_desc { void *ptr; __s32 total_size; __s32 size; diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/pvfs2-bufmap.c index c7b0f3560734..345287e871b1 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/pvfs2-bufmap.c @@ -7,9 +7,9 @@ #include "pvfs2-kernel.h" #include "pvfs2-bufmap.h" -DECLARE_WAIT_QUEUE_HEAD(pvfs2_bufmap_init_waitq); +DECLARE_WAIT_QUEUE_HEAD(orangefs_bufmap_init_waitq); -static struct pvfs2_bufmap { +static struct orangefs_bufmap { atomic_t refcnt; int desc_size; @@ -19,21 +19,21 @@ static struct pvfs2_bufmap { int page_count; struct page **page_array; - struct pvfs_bufmap_desc *desc_array; + struct orangefs_bufmap_desc *desc_array; /* array to track usage of buffer descriptors */ int *buffer_index_array; spinlock_t buffer_index_lock; /* array to track usage of buffer descriptors for readdir */ - int readdir_index_array[PVFS2_READDIR_DEFAULT_DESC_COUNT]; + int readdir_index_array[ORANGEFS_READDIR_DEFAULT_DESC_COUNT]; spinlock_t readdir_index_lock; -} *__pvfs2_bufmap; +} *__orangefs_bufmap; -static DEFINE_SPINLOCK(pvfs2_bufmap_lock); +static DEFINE_SPINLOCK(orangefs_bufmap_lock); static void -pvfs2_bufmap_unmap(struct pvfs2_bufmap *bufmap) +orangefs_bufmap_unmap(struct orangefs_bufmap *bufmap) { int i; @@ -42,7 +42,7 @@ pvfs2_bufmap_unmap(struct pvfs2_bufmap *bufmap) } static void -pvfs2_bufmap_free(struct pvfs2_bufmap *bufmap) +orangefs_bufmap_free(struct orangefs_bufmap *bufmap) { kfree(bufmap->page_array); kfree(bufmap->desc_array); @@ -50,45 +50,45 @@ pvfs2_bufmap_free(struct pvfs2_bufmap *bufmap) kfree(bufmap); } -struct pvfs2_bufmap *pvfs2_bufmap_ref(void) +struct orangefs_bufmap *orangefs_bufmap_ref(void) { - struct pvfs2_bufmap *bufmap = NULL; + struct orangefs_bufmap *bufmap = NULL; - spin_lock(&pvfs2_bufmap_lock); - if (__pvfs2_bufmap) { - bufmap = __pvfs2_bufmap; + spin_lock(&orangefs_bufmap_lock); + if (__orangefs_bufmap) { + bufmap = __orangefs_bufmap; atomic_inc(&bufmap->refcnt); } - spin_unlock(&pvfs2_bufmap_lock); + spin_unlock(&orangefs_bufmap_lock); return bufmap; } -void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap) +void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) { - if (atomic_dec_and_lock(&bufmap->refcnt, &pvfs2_bufmap_lock)) { - __pvfs2_bufmap = NULL; - spin_unlock(&pvfs2_bufmap_lock); + if (atomic_dec_and_lock(&bufmap->refcnt, &orangefs_bufmap_lock)) { + __orangefs_bufmap = NULL; + spin_unlock(&orangefs_bufmap_lock); - pvfs2_bufmap_unmap(bufmap); - pvfs2_bufmap_free(bufmap); + orangefs_bufmap_unmap(bufmap); + orangefs_bufmap_free(bufmap); } } -inline int pvfs_bufmap_size_query(void) +inline int orangefs_bufmap_size_query(void) { - struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); int size = bufmap ? bufmap->desc_size : 0; - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); return size; } -inline int pvfs_bufmap_shift_query(void) +inline int orangefs_bufmap_shift_query(void) { - struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); int shift = bufmap ? bufmap->desc_shift : 0; - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); return shift; } @@ -105,14 +105,14 @@ static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq); */ int get_bufmap_init(void) { - return __pvfs2_bufmap ? 1 : 0; + return __orangefs_bufmap ? 1 : 0; } -static struct pvfs2_bufmap * -pvfs2_bufmap_alloc(struct PVFS_dev_map_desc *user_desc) +static struct orangefs_bufmap * +orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) { - struct pvfs2_bufmap *bufmap; + struct orangefs_bufmap *bufmap; bufmap = kzalloc(sizeof(*bufmap), GFP_KERNEL); if (!bufmap) @@ -128,17 +128,17 @@ pvfs2_bufmap_alloc(struct PVFS_dev_map_desc *user_desc) bufmap->buffer_index_array = kcalloc(bufmap->desc_count, sizeof(int), GFP_KERNEL); if (!bufmap->buffer_index_array) { - gossip_err("pvfs2: could not allocate %d buffer indices\n", + gossip_err("orangefs: could not allocate %d buffer indices\n", bufmap->desc_count); goto out_free_bufmap; } spin_lock_init(&bufmap->readdir_index_lock); bufmap->desc_array = - kcalloc(bufmap->desc_count, sizeof(struct pvfs_bufmap_desc), + kcalloc(bufmap->desc_count, sizeof(struct orangefs_bufmap_desc), GFP_KERNEL); if (!bufmap->desc_array) { - gossip_err("pvfs2: could not allocate %d descriptors\n", + gossip_err("orangefs: could not allocate %d descriptors\n", bufmap->desc_count); goto out_free_index_array; } @@ -164,8 +164,8 @@ pvfs2_bufmap_alloc(struct PVFS_dev_map_desc *user_desc) } static int -pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap, - struct PVFS_dev_map_desc *user_desc) +orangefs_bufmap_map(struct orangefs_bufmap *bufmap, + struct ORANGEFS_dev_map_desc *user_desc) { int pages_per_desc = bufmap->desc_size / PAGE_SIZE; int offset = 0, ret, i; @@ -178,7 +178,7 @@ pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap, return ret; if (ret != bufmap->page_count) { - gossip_err("pvfs2 error: asked for %d pages, only got %d.\n", + gossip_err("orangefs error: asked for %d pages, only got %d.\n", bufmap->page_count, ret); for (i = 0; i < ret; i++) { @@ -210,19 +210,19 @@ pvfs2_bufmap_map(struct pvfs2_bufmap *bufmap, } /* - * pvfs_bufmap_initialize() + * orangefs_bufmap_initialize() * * initializes the mapped buffer interface * * returns 0 on success, -errno on failure */ -int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc) +int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc) { - struct pvfs2_bufmap *bufmap; + struct orangefs_bufmap *bufmap; int ret = -EINVAL; gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_initialize: called (ptr (" + "orangefs_bufmap_initialize: called (ptr (" "%p) sz (%d) cnt(%d).\n", user_desc->ptr, user_desc->size, @@ -234,21 +234,21 @@ int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc) */ if (PAGE_ALIGN((unsigned long)user_desc->ptr) != (unsigned long)user_desc->ptr) { - gossip_err("pvfs2 error: memory alignment (front). %p\n", + gossip_err("orangefs error: memory alignment (front). %p\n", user_desc->ptr); goto out; } if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->total_size)) != (unsigned long)(user_desc->ptr + user_desc->total_size)) { - gossip_err("pvfs2 error: memory alignment (back).(%p + %d)\n", + gossip_err("orangefs error: memory alignment (back).(%p + %d)\n", user_desc->ptr, user_desc->total_size); goto out; } if (user_desc->total_size != (user_desc->size * user_desc->count)) { - gossip_err("pvfs2 error: user provided an oddly sized buffer: (%d, %d, %d)\n", + gossip_err("orangefs error: user provided an oddly sized buffer: (%d, %d, %d)\n", user_desc->total_size, user_desc->size, user_desc->count); @@ -256,33 +256,33 @@ int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc) } if ((user_desc->size % PAGE_SIZE) != 0) { - gossip_err("pvfs2 error: bufmap size not page size divisible (%d).\n", + gossip_err("orangefs error: bufmap size not page size divisible (%d).\n", user_desc->size); goto out; } ret = -ENOMEM; - bufmap = pvfs2_bufmap_alloc(user_desc); + bufmap = orangefs_bufmap_alloc(user_desc); if (!bufmap) goto out; - ret = pvfs2_bufmap_map(bufmap, user_desc); + ret = orangefs_bufmap_map(bufmap, user_desc); if (ret) goto out_free_bufmap; - spin_lock(&pvfs2_bufmap_lock); - if (__pvfs2_bufmap) { - spin_unlock(&pvfs2_bufmap_lock); - gossip_err("pvfs2: error: bufmap already initialized.\n"); + spin_lock(&orangefs_bufmap_lock); + if (__orangefs_bufmap) { + spin_unlock(&orangefs_bufmap_lock); + gossip_err("orangefs: error: bufmap already initialized.\n"); ret = -EALREADY; goto out_unmap_bufmap; } - __pvfs2_bufmap = bufmap; - spin_unlock(&pvfs2_bufmap_lock); + __orangefs_bufmap = bufmap; + spin_unlock(&orangefs_bufmap_lock); /* - * If there are operations in pvfs2_bufmap_init_waitq, wake them up. + * If there are operations in orangefs_bufmap_init_waitq, wake them up. * This scenario occurs when the client-core is restarted and I/O * requests in the in-progress or waiting tables are restarted. I/O * requests cannot be restarted until the shared memory system is @@ -291,35 +291,35 @@ int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc) * are also on a timer, so they don't wait forever just in case the * client-core doesn't come back up. */ - wake_up_interruptible(&pvfs2_bufmap_init_waitq); + wake_up_interruptible(&orangefs_bufmap_init_waitq); gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs_bufmap_initialize: exiting normally\n"); + "orangefs_bufmap_initialize: exiting normally\n"); return 0; out_unmap_bufmap: - pvfs2_bufmap_unmap(bufmap); + orangefs_bufmap_unmap(bufmap); out_free_bufmap: - pvfs2_bufmap_free(bufmap); + orangefs_bufmap_free(bufmap); out: return ret; } /* - * pvfs_bufmap_finalize() + * orangefs_bufmap_finalize() * * shuts down the mapped buffer interface and releases any resources * associated with it * * no return value */ -void pvfs_bufmap_finalize(void) +void orangefs_bufmap_finalize(void) { - gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: called\n"); - BUG_ON(!__pvfs2_bufmap); - pvfs2_bufmap_unref(__pvfs2_bufmap); + gossip_debug(GOSSIP_BUFMAP_DEBUG, "orangefs_bufmap_finalize: called\n"); + BUG_ON(!__orangefs_bufmap); + orangefs_bufmap_unref(__orangefs_bufmap); gossip_debug(GOSSIP_BUFMAP_DEBUG, - "pvfs2_bufmap_finalize: exiting normally\n"); + "orangefs_bufmap_finalize: exiting normally\n"); } struct slot_args { @@ -377,7 +377,7 @@ static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) continue; } - gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2: %s interrupted.\n", + gossip_debug(GOSSIP_BUFMAP_DEBUG, "orangefs: %s interrupted.\n", __func__); ret = -EINTR; break; @@ -406,21 +406,21 @@ static void put_back_slot(struct slot_args *slargs, int buffer_index) } /* - * pvfs_bufmap_get() + * orangefs_bufmap_get() * * gets a free mapped buffer descriptor, will sleep until one becomes * available if necessary * * returns 0 on success, -errno on failure */ -int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index) +int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index) { - struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); struct slot_args slargs; int ret; if (!bufmap) { - gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n"); + gossip_err("orangefs: please confirm that pvfs2-client daemon is running.\n"); return -EIO; } @@ -430,19 +430,19 @@ int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index) slargs.slot_wq = &bufmap_waitq; ret = wait_for_a_slot(&slargs, buffer_index); if (ret) - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); *mapp = bufmap; return ret; } /* - * pvfs_bufmap_put() + * orangefs_bufmap_put() * * returns a mapped buffer descriptor to the collection * * no return value */ -void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index) +void orangefs_bufmap_put(struct orangefs_bufmap *bufmap, int buffer_index) { struct slot_args slargs; @@ -451,7 +451,7 @@ void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index) slargs.slot_lock = &bufmap->buffer_index_lock; slargs.slot_wq = &bufmap_waitq; put_back_slot(&slargs, buffer_index); - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); } /* @@ -465,46 +465,46 @@ void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index) * * returns 0 on success, -errno on failure */ -int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index) +int readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) { - struct pvfs2_bufmap *bufmap = pvfs2_bufmap_ref(); + struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); struct slot_args slargs; int ret; if (!bufmap) { - gossip_err("pvfs2: please confirm that pvfs2-client daemon is running.\n"); + gossip_err("orangefs: please confirm that pvfs2-client daemon is running.\n"); return -EIO; } - slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT; + slargs.slot_count = ORANGEFS_READDIR_DEFAULT_DESC_COUNT; slargs.slot_array = bufmap->readdir_index_array; slargs.slot_lock = &bufmap->readdir_index_lock; slargs.slot_wq = &readdir_waitq; ret = wait_for_a_slot(&slargs, buffer_index); if (ret) - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); *mapp = bufmap; return ret; } -void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index) +void readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) { struct slot_args slargs; - slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT; + slargs.slot_count = ORANGEFS_READDIR_DEFAULT_DESC_COUNT; slargs.slot_array = bufmap->readdir_index_array; slargs.slot_lock = &bufmap->readdir_index_lock; slargs.slot_wq = &readdir_waitq; put_back_slot(&slargs, buffer_index); - pvfs2_bufmap_unref(bufmap); + orangefs_bufmap_unref(bufmap); } -int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, +int orangefs_bufmap_copy_from_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, int buffer_index, size_t size) { - struct pvfs_bufmap_desc *to = &bufmap->desc_array[buffer_index]; + struct orangefs_bufmap_desc *to = &bufmap->desc_array[buffer_index]; int i; gossip_debug(GOSSIP_BUFMAP_DEBUG, @@ -531,12 +531,12 @@ int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, * a file being read. * */ -int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, +int orangefs_bufmap_copy_to_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, int buffer_index, size_t size) { - struct pvfs_bufmap_desc *from = &bufmap->desc_array[buffer_index]; + struct orangefs_bufmap_desc *from = &bufmap->desc_array[buffer_index]; int i; gossip_debug(GOSSIP_BUFMAP_DEBUG, diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/pvfs2-bufmap.h index d1aedb52a877..91d1755c231a 100644 --- a/fs/orangefs/pvfs2-bufmap.h +++ b/fs/orangefs/pvfs2-bufmap.h @@ -4,59 +4,59 @@ * See COPYING in top-level directory. */ -#ifndef __PVFS2_BUFMAP_H -#define __PVFS2_BUFMAP_H +#ifndef __ORANGEFS_BUFMAP_H +#define __ORANGEFS_BUFMAP_H /* used to describe mapped buffers */ -struct pvfs_bufmap_desc { +struct orangefs_bufmap_desc { void *uaddr; /* user space address pointer */ struct page **page_array; /* array of mapped pages */ int array_count; /* size of above arrays */ struct list_head list_link; }; -struct pvfs2_bufmap; +struct orangefs_bufmap; -struct pvfs2_bufmap *pvfs2_bufmap_ref(void); -void pvfs2_bufmap_unref(struct pvfs2_bufmap *bufmap); +struct orangefs_bufmap *orangefs_bufmap_ref(void); +void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap); /* - * pvfs_bufmap_size_query is now an inline function because buffer + * orangefs_bufmap_size_query is now an inline function because buffer * sizes are not hardcoded */ -int pvfs_bufmap_size_query(void); +int orangefs_bufmap_size_query(void); -int pvfs_bufmap_shift_query(void); +int orangefs_bufmap_shift_query(void); -int pvfs_bufmap_initialize(struct PVFS_dev_map_desc *user_desc); +int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc); int get_bufmap_init(void); -void pvfs_bufmap_finalize(void); +void orangefs_bufmap_finalize(void); -int pvfs_bufmap_get(struct pvfs2_bufmap **mapp, int *buffer_index); +int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index); -void pvfs_bufmap_put(struct pvfs2_bufmap *bufmap, int buffer_index); +void orangefs_bufmap_put(struct orangefs_bufmap *bufmap, int buffer_index); -int readdir_index_get(struct pvfs2_bufmap **mapp, int *buffer_index); +int readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index); -void readdir_index_put(struct pvfs2_bufmap *bufmap, int buffer_index); +void readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index); -int pvfs_bufmap_copy_from_iovec(struct pvfs2_bufmap *bufmap, +int orangefs_bufmap_copy_from_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, int buffer_index, size_t size); -int pvfs_bufmap_copy_to_iovec(struct pvfs2_bufmap *bufmap, +int orangefs_bufmap_copy_to_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, int buffer_index, size_t size); -size_t pvfs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk, +size_t orangefs_bufmap_copy_to_user_task_iovec(struct task_struct *tsk, struct iovec *iovec, unsigned long nr_segs, - struct pvfs2_bufmap *bufmap, + struct orangefs_bufmap *bufmap, int buffer_index, size_t bytes_to_be_copied); -#endif /* __PVFS2_BUFMAP_H */ +#endif /* __ORANGEFS_BUFMAP_H */ diff --git a/fs/orangefs/pvfs2-cache.c b/fs/orangefs/pvfs2-cache.c index f982616a4349..a224831770f4 100644 --- a/fs/orangefs/pvfs2-cache.c +++ b/fs/orangefs/pvfs2-cache.c @@ -11,27 +11,27 @@ static __u64 next_tag_value; static DEFINE_SPINLOCK(next_tag_value_lock); -/* the pvfs2 memory caches */ +/* the orangefs memory caches */ -/* a cache for pvfs2 upcall/downcall operations */ +/* a cache for orangefs upcall/downcall operations */ static struct kmem_cache *op_cache; /* a cache for device (/dev/pvfs2-req) communication */ static struct kmem_cache *dev_req_cache; -/* a cache for pvfs2_kiocb objects (i.e pvfs2 iocb structures ) */ -static struct kmem_cache *pvfs2_kiocb_cache; +/* a cache for orangefs_kiocb objects (i.e orangefs iocb structures ) */ +static struct kmem_cache *orangefs_kiocb_cache; int op_cache_initialize(void) { - op_cache = kmem_cache_create("pvfs2_op_cache", - sizeof(struct pvfs2_kernel_op_s), + op_cache = kmem_cache_create("orangefs_op_cache", + sizeof(struct orangefs_kernel_op_s), 0, - PVFS2_CACHE_CREATE_FLAGS, + ORANGEFS_CACHE_CREATE_FLAGS, NULL); if (!op_cache) { - gossip_err("Cannot create pvfs2_op_cache\n"); + gossip_err("Cannot create orangefs_op_cache\n"); return -ENOMEM; } @@ -48,72 +48,72 @@ int op_cache_finalize(void) return 0; } -char *get_opname_string(struct pvfs2_kernel_op_s *new_op) +char *get_opname_string(struct orangefs_kernel_op_s *new_op) { if (new_op) { __s32 type = new_op->upcall.type; - if (type == PVFS2_VFS_OP_FILE_IO) + if (type == ORANGEFS_VFS_OP_FILE_IO) return "OP_FILE_IO"; - else if (type == PVFS2_VFS_OP_LOOKUP) + else if (type == ORANGEFS_VFS_OP_LOOKUP) return "OP_LOOKUP"; - else if (type == PVFS2_VFS_OP_CREATE) + else if (type == ORANGEFS_VFS_OP_CREATE) return "OP_CREATE"; - else if (type == PVFS2_VFS_OP_GETATTR) + else if (type == ORANGEFS_VFS_OP_GETATTR) return "OP_GETATTR"; - else if (type == PVFS2_VFS_OP_REMOVE) + else if (type == ORANGEFS_VFS_OP_REMOVE) return "OP_REMOVE"; - else if (type == PVFS2_VFS_OP_MKDIR) + else if (type == ORANGEFS_VFS_OP_MKDIR) return "OP_MKDIR"; - else if (type == PVFS2_VFS_OP_READDIR) + else if (type == ORANGEFS_VFS_OP_READDIR) return "OP_READDIR"; - else if (type == PVFS2_VFS_OP_READDIRPLUS) + else if (type == ORANGEFS_VFS_OP_READDIRPLUS) return "OP_READDIRPLUS"; - else if (type == PVFS2_VFS_OP_SETATTR) + else if (type == ORANGEFS_VFS_OP_SETATTR) return "OP_SETATTR"; - else if (type == PVFS2_VFS_OP_SYMLINK) + else if (type == ORANGEFS_VFS_OP_SYMLINK) return "OP_SYMLINK"; - else if (type == PVFS2_VFS_OP_RENAME) + else if (type == ORANGEFS_VFS_OP_RENAME) return "OP_RENAME"; - else if (type == PVFS2_VFS_OP_STATFS) + else if (type == ORANGEFS_VFS_OP_STATFS) return "OP_STATFS"; - else if (type == PVFS2_VFS_OP_TRUNCATE) + else if (type == ORANGEFS_VFS_OP_TRUNCATE) return "OP_TRUNCATE"; - else if (type == PVFS2_VFS_OP_MMAP_RA_FLUSH) + else if (type == ORANGEFS_VFS_OP_MMAP_RA_FLUSH) return "OP_MMAP_RA_FLUSH"; - else if (type == PVFS2_VFS_OP_FS_MOUNT) + else if (type == ORANGEFS_VFS_OP_FS_MOUNT) return "OP_FS_MOUNT"; - else if (type == PVFS2_VFS_OP_FS_UMOUNT) + else if (type == ORANGEFS_VFS_OP_FS_UMOUNT) return "OP_FS_UMOUNT"; - else if (type == PVFS2_VFS_OP_GETXATTR) + else if (type == ORANGEFS_VFS_OP_GETXATTR) return "OP_GETXATTR"; - else if (type == PVFS2_VFS_OP_SETXATTR) + else if (type == ORANGEFS_VFS_OP_SETXATTR) return "OP_SETXATTR"; - else if (type == PVFS2_VFS_OP_LISTXATTR) + else if (type == ORANGEFS_VFS_OP_LISTXATTR) return "OP_LISTXATTR"; - else if (type == PVFS2_VFS_OP_REMOVEXATTR) + else if (type == ORANGEFS_VFS_OP_REMOVEXATTR) return "OP_REMOVEXATTR"; - else if (type == PVFS2_VFS_OP_PARAM) + else if (type == ORANGEFS_VFS_OP_PARAM) return "OP_PARAM"; - else if (type == PVFS2_VFS_OP_PERF_COUNT) + else if (type == ORANGEFS_VFS_OP_PERF_COUNT) return "OP_PERF_COUNT"; - else if (type == PVFS2_VFS_OP_CANCEL) + else if (type == ORANGEFS_VFS_OP_CANCEL) return "OP_CANCEL"; - else if (type == PVFS2_VFS_OP_FSYNC) + else if (type == ORANGEFS_VFS_OP_FSYNC) return "OP_FSYNC"; - else if (type == PVFS2_VFS_OP_FSKEY) + else if (type == ORANGEFS_VFS_OP_FSKEY) return "OP_FSKEY"; } return "OP_UNKNOWN?"; } -struct pvfs2_kernel_op_s *op_alloc(__s32 type) +struct orangefs_kernel_op_s *op_alloc(__s32 type) { - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; - new_op = kmem_cache_alloc(op_cache, PVFS2_CACHE_ALLOC_FLAGS); + new_op = kmem_cache_alloc(op_cache, ORANGEFS_CACHE_ALLOC_FLAGS); if (new_op) { - memset(new_op, 0, sizeof(struct pvfs2_kernel_op_s)); + memset(new_op, 0, sizeof(struct orangefs_kernel_op_s)); INIT_LIST_HEAD(&new_op->list); spin_lock_init(&new_op->lock); @@ -122,7 +122,7 @@ struct pvfs2_kernel_op_s *op_alloc(__s32 type) init_waitqueue_head(&new_op->io_completion_waitq); atomic_set(&new_op->aio_ref_count, 0); - pvfs2_op_initialize(new_op); + orangefs_op_initialize(new_op); /* initialize the op specific tag and upcall credentials */ spin_lock(&next_tag_value_lock); @@ -149,15 +149,15 @@ struct pvfs2_kernel_op_s *op_alloc(__s32 type) return new_op; } -void op_release(struct pvfs2_kernel_op_s *pvfs2_op) +void op_release(struct orangefs_kernel_op_s *orangefs_op) { - if (pvfs2_op) { + if (orangefs_op) { gossip_debug(GOSSIP_CACHE_DEBUG, "Releasing OP (%p: %llu)\n", - pvfs2_op, - llu(pvfs2_op->tag)); - pvfs2_op_initialize(pvfs2_op); - kmem_cache_free(op_cache, pvfs2_op); + orangefs_op, + llu(orangefs_op->tag)); + orangefs_op_initialize(orangefs_op); + kmem_cache_free(op_cache, orangefs_op); } else { gossip_err("NULL pointer in op_release\n"); } @@ -165,14 +165,14 @@ void op_release(struct pvfs2_kernel_op_s *pvfs2_op) int dev_req_cache_initialize(void) { - dev_req_cache = kmem_cache_create("pvfs2_devreqcache", + dev_req_cache = kmem_cache_create("orangefs_devreqcache", MAX_ALIGNED_DEV_REQ_DOWNSIZE, 0, - PVFS2_CACHE_CREATE_FLAGS, + ORANGEFS_CACHE_CREATE_FLAGS, NULL); if (!dev_req_cache) { - gossip_err("Cannot create pvfs2_dev_req_cache\n"); + gossip_err("Cannot create orangefs_dev_req_cache\n"); return -ENOMEM; } return 0; @@ -188,7 +188,7 @@ void *dev_req_alloc(void) { void *buffer; - buffer = kmem_cache_alloc(dev_req_cache, PVFS2_CACHE_ALLOC_FLAGS); + buffer = kmem_cache_alloc(dev_req_cache, ORANGEFS_CACHE_ALLOC_FLAGS); if (buffer == NULL) gossip_err("Failed to allocate from dev_req_cache\n"); else @@ -206,14 +206,14 @@ void dev_req_release(void *buffer) int kiocb_cache_initialize(void) { - pvfs2_kiocb_cache = kmem_cache_create("pvfs2_kiocbcache", - sizeof(struct pvfs2_kiocb_s), + orangefs_kiocb_cache = kmem_cache_create("orangefs_kiocbcache", + sizeof(struct orangefs_kiocb_s), 0, - PVFS2_CACHE_CREATE_FLAGS, + ORANGEFS_CACHE_CREATE_FLAGS, NULL); - if (!pvfs2_kiocb_cache) { - gossip_err("Cannot create pvfs2_kiocb_cache!\n"); + if (!orangefs_kiocb_cache) { + gossip_err("Cannot create orangefs_kiocb_cache!\n"); return -ENOMEM; } return 0; @@ -221,26 +221,26 @@ int kiocb_cache_initialize(void) int kiocb_cache_finalize(void) { - kmem_cache_destroy(pvfs2_kiocb_cache); + kmem_cache_destroy(orangefs_kiocb_cache); return 0; } -struct pvfs2_kiocb_s *kiocb_alloc(void) +struct orangefs_kiocb_s *kiocb_alloc(void) { - struct pvfs2_kiocb_s *x = NULL; + struct orangefs_kiocb_s *x = NULL; - x = kmem_cache_alloc(pvfs2_kiocb_cache, PVFS2_CACHE_ALLOC_FLAGS); + x = kmem_cache_alloc(orangefs_kiocb_cache, ORANGEFS_CACHE_ALLOC_FLAGS); if (x == NULL) gossip_err("kiocb_alloc: kmem_cache_alloc failed!\n"); else - memset(x, 0, sizeof(struct pvfs2_kiocb_s)); + memset(x, 0, sizeof(struct orangefs_kiocb_s)); return x; } -void kiocb_release(struct pvfs2_kiocb_s *x) +void kiocb_release(struct orangefs_kiocb_s *x) { if (x) - kmem_cache_free(pvfs2_kiocb_cache, x); + kmem_cache_free(orangefs_kiocb_cache, x); else gossip_err("kiocb_release: kmem_cache_free NULL pointer!\n"); } diff --git a/fs/orangefs/pvfs2-debug.h b/fs/orangefs/pvfs2-debug.h index fd71d6c84cf6..e6b4baa5e8fb 100644 --- a/fs/orangefs/pvfs2-debug.h +++ b/fs/orangefs/pvfs2-debug.h @@ -5,12 +5,12 @@ */ /* This file just defines debugging masks to be used with the gossip - * logging utility. All debugging masks for PVFS2 are kept here to make + * logging utility. All debugging masks for ORANGEFS are kept here to make * sure we don't have collisions. */ -#ifndef __PVFS2_DEBUG_H -#define __PVFS2_DEBUG_H +#ifndef __ORANGEFS_DEBUG_H +#define __ORANGEFS_DEBUG_H #ifdef __KERNEL__ #include @@ -90,7 +90,7 @@ GOSSIP_BMI_DEBUG_MX + \ GOSSIP_BMI_DEBUG_PORTALS)) -const char *PVFS_debug_get_next_debug_keyword(int position); +const char *ORANGEFS_debug_get_next_debug_keyword(int position); #define GOSSIP_SUPER_DEBUG ((__u64)1 << 0) #define GOSSIP_INODE_DEBUG ((__u64)1 << 1) @@ -113,10 +113,10 @@ const char *PVFS_debug_get_next_debug_keyword(int position); #define GOSSIP_MAX_DEBUG (((__u64)1 << GOSSIP_MAX_NR) - 1) /*function prototypes*/ -__u64 PVFS_kmod_eventlog_to_mask(const char *event_logging); -__u64 PVFS_debug_eventlog_to_mask(const char *event_logging); -char *PVFS_debug_mask_to_eventlog(__u64 mask); -char *PVFS_kmod_mask_to_eventlog(__u64 mask); +__u64 ORANGEFS_kmod_eventlog_to_mask(const char *event_logging); +__u64 ORANGEFS_debug_eventlog_to_mask(const char *event_logging); +char *ORANGEFS_debug_mask_to_eventlog(__u64 mask); +char *ORANGEFS_kmod_mask_to_eventlog(__u64 mask); /* a private internal type */ struct __keyword_mask_s { @@ -289,4 +289,4 @@ static const int num_kmod_keyword_mask_map = (int) static const int num_keyword_mask_map = (int) (sizeof(s_keyword_mask_map) / sizeof(struct __keyword_mask_s)); -#endif /* __PVFS2_DEBUG_H */ +#endif /* __ORANGEFS_DEBUG_H */ diff --git a/fs/orangefs/pvfs2-debugfs.c b/fs/orangefs/pvfs2-debugfs.c index ba5bfef7a3f3..315dc538b723 100644 --- a/fs/orangefs/pvfs2-debugfs.c +++ b/fs/orangefs/pvfs2-debugfs.c @@ -95,7 +95,7 @@ static const struct file_operations kernel_debug_fops = { * initialize kmod debug operations, create orangefs debugfs dir and * ORANGEFS_KMOD_DEBUG_HELP_FILE. */ -int pvfs2_debugfs_init(void) +int orangefs_debugfs_init(void) { int rc = -ENOMEM; @@ -117,12 +117,12 @@ int pvfs2_debugfs_init(void) out: if (rc) - pvfs2_debugfs_cleanup(); + orangefs_debugfs_cleanup(); return rc; } -void pvfs2_debugfs_cleanup(void) +void orangefs_debugfs_cleanup(void) { debugfs_remove_recursive(debug_dir); } @@ -196,7 +196,7 @@ static int help_show(struct seq_file *m, void *v) /* * initialize the kernel-debug file. */ -int pvfs2_kernel_debug_init(void) +int orangefs_kernel_debug_init(void) { int rc = -ENOMEM; @@ -205,11 +205,11 @@ int pvfs2_kernel_debug_init(void) gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); - k_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); if (!k_buffer) goto out; - if (strlen(kernel_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) { + if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) { strcpy(k_buffer, kernel_debug_string); strcat(k_buffer, "\n"); } else { @@ -233,7 +233,7 @@ int pvfs2_kernel_debug_init(void) out: if (rc) - pvfs2_debugfs_cleanup(); + orangefs_debugfs_cleanup(); gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); return rc; @@ -242,7 +242,7 @@ int pvfs2_kernel_debug_init(void) /* * initialize the client-debug file. */ -int pvfs2_client_debug_init(void) +int orangefs_client_debug_init(void) { int rc = -ENOMEM; @@ -250,11 +250,11 @@ int pvfs2_client_debug_init(void) gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__); - c_buffer = kzalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); if (!c_buffer) goto out; - if (strlen(client_debug_string) + 1 < PVFS2_MAX_DEBUG_STRING_LEN) { + if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) { strcpy(c_buffer, client_debug_string); strcat(c_buffer, "\n"); } else { @@ -278,7 +278,7 @@ int pvfs2_client_debug_init(void) out: if (rc) - pvfs2_debugfs_cleanup(); + orangefs_debugfs_cleanup(); gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc); return rc; @@ -320,7 +320,7 @@ static ssize_t orangefs_debug_read(struct file *file, gossip_debug(GOSSIP_DEBUGFS_DEBUG, "orangefs_debug_read: start\n"); - buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + buf = kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); if (!buf) goto out; @@ -349,7 +349,7 @@ static ssize_t orangefs_debug_write(struct file *file, int rc = -EFAULT; size_t silly = 0; char *debug_string; - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; struct client_debug_mask c_mask = { NULL, 0, 0 }; gossip_debug(GOSSIP_DEBUGFS_DEBUG, @@ -360,15 +360,15 @@ static ssize_t orangefs_debug_write(struct file *file, * Thwart users who try to jamb a ridiculous number * of bytes into the debug file... */ - if (count > PVFS2_MAX_DEBUG_STRING_LEN + 1) { + if (count > ORANGEFS_MAX_DEBUG_STRING_LEN + 1) { silly = count; - count = PVFS2_MAX_DEBUG_STRING_LEN + 1; + count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1; } - buf = kmalloc(PVFS2_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + buf = kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); if (!buf) goto out; - memset(buf, 0, PVFS2_MAX_DEBUG_STRING_LEN); + memset(buf, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); if (copy_from_user(buf, ubuf, count - 1)) { gossip_debug(GOSSIP_DEBUGFS_DEBUG, @@ -407,18 +407,18 @@ static ssize_t orangefs_debug_write(struct file *file, debug_mask_to_string(&c_mask, 1); debug_string = client_debug_string; - new_op = op_alloc(PVFS2_VFS_OP_PARAM); + new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); if (!new_op) { pr_info("%s: op_alloc failed!\n", __func__); goto out; } new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES; - new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET; + ORANGEFS_PARAM_REQUEST_OP_TWO_MASK_VALUES; + new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET; memset(new_op->upcall.req.param.s_value, 0, - PVFS2_MAX_DEBUG_STRING_LEN); + ORANGEFS_MAX_DEBUG_STRING_LEN); sprintf(new_op->upcall.req.param.s_value, "%llx %llx\n", c_mask.mask1, @@ -426,8 +426,8 @@ static ssize_t orangefs_debug_write(struct file *file, /* service_operation returns 0 on success... */ rc = service_operation(new_op, - "pvfs2_param", - PVFS2_OP_INTERRUPTIBLE); + "orangefs_param", + ORANGEFS_OP_INTERRUPTIBLE); if (rc) gossip_debug(GOSSIP_DEBUGFS_DEBUG, @@ -439,7 +439,7 @@ static ssize_t orangefs_debug_write(struct file *file, } mutex_lock(&orangefs_debug_lock); - memset(file->f_inode->i_private, 0, PVFS2_MAX_DEBUG_STRING_LEN); + memset(file->f_inode->i_private, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); sprintf((char *)file->f_inode->i_private, "%s\n", debug_string); mutex_unlock(&orangefs_debug_lock); diff --git a/fs/orangefs/pvfs2-debugfs.h b/fs/orangefs/pvfs2-debugfs.h index a66b7d08c14d..e4828c0e3ef9 100644 --- a/fs/orangefs/pvfs2-debugfs.h +++ b/fs/orangefs/pvfs2-debugfs.h @@ -1,3 +1,3 @@ -int pvfs2_debugfs_init(void); -int pvfs2_kernel_debug_init(void); -void pvfs2_debugfs_cleanup(void); +int orangefs_debugfs_init(void); +int orangefs_kernel_debug_init(void); +void orangefs_debugfs_cleanup(void); diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/pvfs2-dev-proto.h index 71ab56df4ad7..dc1951dd7045 100644 --- a/fs/orangefs/pvfs2-dev-proto.h +++ b/fs/orangefs/pvfs2-dev-proto.h @@ -4,8 +4,8 @@ * See COPYING in top-level directory. */ -#ifndef _PVFS2_DEV_PROTO_H -#define _PVFS2_DEV_PROTO_H +#ifndef _ORANGEFS_DEV_PROTO_H +#define _ORANGEFS_DEV_PROTO_H /* * types and constants shared between user space and kernel space for @@ -13,46 +13,46 @@ */ /* - * valid pvfs2 kernel operation types + * valid orangefs kernel operation types */ -#define PVFS2_VFS_OP_INVALID 0xFF000000 -#define PVFS2_VFS_OP_FILE_IO 0xFF000001 -#define PVFS2_VFS_OP_LOOKUP 0xFF000002 -#define PVFS2_VFS_OP_CREATE 0xFF000003 -#define PVFS2_VFS_OP_GETATTR 0xFF000004 -#define PVFS2_VFS_OP_REMOVE 0xFF000005 -#define PVFS2_VFS_OP_MKDIR 0xFF000006 -#define PVFS2_VFS_OP_READDIR 0xFF000007 -#define PVFS2_VFS_OP_SETATTR 0xFF000008 -#define PVFS2_VFS_OP_SYMLINK 0xFF000009 -#define PVFS2_VFS_OP_RENAME 0xFF00000A -#define PVFS2_VFS_OP_STATFS 0xFF00000B -#define PVFS2_VFS_OP_TRUNCATE 0xFF00000C -#define PVFS2_VFS_OP_MMAP_RA_FLUSH 0xFF00000D -#define PVFS2_VFS_OP_FS_MOUNT 0xFF00000E -#define PVFS2_VFS_OP_FS_UMOUNT 0xFF00000F -#define PVFS2_VFS_OP_GETXATTR 0xFF000010 -#define PVFS2_VFS_OP_SETXATTR 0xFF000011 -#define PVFS2_VFS_OP_LISTXATTR 0xFF000012 -#define PVFS2_VFS_OP_REMOVEXATTR 0xFF000013 -#define PVFS2_VFS_OP_PARAM 0xFF000014 -#define PVFS2_VFS_OP_PERF_COUNT 0xFF000015 -#define PVFS2_VFS_OP_CANCEL 0xFF00EE00 -#define PVFS2_VFS_OP_FSYNC 0xFF00EE01 -#define PVFS2_VFS_OP_FSKEY 0xFF00EE02 -#define PVFS2_VFS_OP_READDIRPLUS 0xFF00EE03 +#define ORANGEFS_VFS_OP_INVALID 0xFF000000 +#define ORANGEFS_VFS_OP_FILE_IO 0xFF000001 +#define ORANGEFS_VFS_OP_LOOKUP 0xFF000002 +#define ORANGEFS_VFS_OP_CREATE 0xFF000003 +#define ORANGEFS_VFS_OP_GETATTR 0xFF000004 +#define ORANGEFS_VFS_OP_REMOVE 0xFF000005 +#define ORANGEFS_VFS_OP_MKDIR 0xFF000006 +#define ORANGEFS_VFS_OP_READDIR 0xFF000007 +#define ORANGEFS_VFS_OP_SETATTR 0xFF000008 +#define ORANGEFS_VFS_OP_SYMLINK 0xFF000009 +#define ORANGEFS_VFS_OP_RENAME 0xFF00000A +#define ORANGEFS_VFS_OP_STATFS 0xFF00000B +#define ORANGEFS_VFS_OP_TRUNCATE 0xFF00000C +#define ORANGEFS_VFS_OP_MMAP_RA_FLUSH 0xFF00000D +#define ORANGEFS_VFS_OP_FS_MOUNT 0xFF00000E +#define ORANGEFS_VFS_OP_FS_UMOUNT 0xFF00000F +#define ORANGEFS_VFS_OP_GETXATTR 0xFF000010 +#define ORANGEFS_VFS_OP_SETXATTR 0xFF000011 +#define ORANGEFS_VFS_OP_LISTXATTR 0xFF000012 +#define ORANGEFS_VFS_OP_REMOVEXATTR 0xFF000013 +#define ORANGEFS_VFS_OP_PARAM 0xFF000014 +#define ORANGEFS_VFS_OP_PERF_COUNT 0xFF000015 +#define ORANGEFS_VFS_OP_CANCEL 0xFF00EE00 +#define ORANGEFS_VFS_OP_FSYNC 0xFF00EE01 +#define ORANGEFS_VFS_OP_FSKEY 0xFF00EE02 +#define ORANGEFS_VFS_OP_READDIRPLUS 0xFF00EE03 /* * Misc constants. Please retain them as multiples of 8! * Otherwise 32-64 bit interactions will be messed up :) */ -#define PVFS2_NAME_LEN 0x00000100 -#define PVFS2_MAX_DEBUG_STRING_LEN 0x00000400 -#define PVFS2_MAX_DEBUG_ARRAY_LEN 0x00000800 +#define ORANGEFS_NAME_LEN 0x00000100 +#define ORANGEFS_MAX_DEBUG_STRING_LEN 0x00000400 +#define ORANGEFS_MAX_DEBUG_ARRAY_LEN 0x00000800 /* - * MAX_DIRENT_COUNT cannot be larger than PVFS_REQ_LIMIT_LISTATTR. - * The value of PVFS_REQ_LIMIT_LISTATTR has been changed from 113 to 60 + * MAX_DIRENT_COUNT cannot be larger than ORANGEFS_REQ_LIMIT_LISTATTR. + * The value of ORANGEFS_REQ_LIMIT_LISTATTR has been changed from 113 to 60 * to accomodate an attribute object with mirrored handles. * MAX_DIRENT_COUNT is replaced by MAX_DIRENT_COUNT_READDIR and * MAX_DIRENT_COUNT_READDIRPLUS, since readdir doesn't trigger a listattr diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/pvfs2-kernel.h index 4295e263e25b..33fcf3bccd2e 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/pvfs2-kernel.h @@ -5,18 +5,18 @@ */ /* - * The PVFS2 Linux kernel support allows PVFS2 volumes to be mounted and + * The ORANGEFS Linux kernel support allows ORANGEFS volumes to be mounted and * accessed through the Linux VFS (i.e. using standard I/O system calls). * This support is only needed on clients that wish to mount the file system. * */ /* - * Declarations and macros for the PVFS2 Linux kernel support. + * Declarations and macros for the ORANGEFS Linux kernel support. */ -#ifndef __PVFS2KERNEL_H -#define __PVFS2KERNEL_H +#ifndef __ORANGEFSKERNEL_H +#define __ORANGEFSKERNEL_H #include #include @@ -55,30 +55,30 @@ #include "pvfs2-dev-proto.h" -#ifdef PVFS2_KERNEL_DEBUG -#define PVFS2_DEFAULT_OP_TIMEOUT_SECS 10 +#ifdef ORANGEFS_KERNEL_DEBUG +#define ORANGEFS_DEFAULT_OP_TIMEOUT_SECS 10 #else -#define PVFS2_DEFAULT_OP_TIMEOUT_SECS 20 +#define ORANGEFS_DEFAULT_OP_TIMEOUT_SECS 20 #endif -#define PVFS2_BUFMAP_WAIT_TIMEOUT_SECS 30 +#define ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS 30 -#define PVFS2_DEFAULT_SLOT_TIMEOUT_SECS 900 /* 15 minutes */ +#define ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS 900 /* 15 minutes */ -#define PVFS2_REQDEVICE_NAME "pvfs2-req" +#define ORANGEFS_REQDEVICE_NAME "pvfs2-req" -#define PVFS2_DEVREQ_MAGIC 0x20030529 -#define PVFS2_LINK_MAX 0x000000FF -#define PVFS2_PURGE_RETRY_COUNT 0x00000005 -#define PVFS2_SEEK_END 0x00000002 -#define PVFS2_MAX_NUM_OPTIONS 0x00000004 -#define PVFS2_MAX_MOUNT_OPT_LEN 0x00000080 -#define PVFS2_MAX_FSKEY_LEN 64 +#define ORANGEFS_DEVREQ_MAGIC 0x20030529 +#define ORANGEFS_LINK_MAX 0x000000FF +#define ORANGEFS_PURGE_RETRY_COUNT 0x00000005 +#define ORANGEFS_SEEK_END 0x00000002 +#define ORANGEFS_MAX_NUM_OPTIONS 0x00000004 +#define ORANGEFS_MAX_MOUNT_OPT_LEN 0x00000080 +#define ORANGEFS_MAX_FSKEY_LEN 64 #define MAX_DEV_REQ_UPSIZE (2*sizeof(__s32) + \ -sizeof(__u64) + sizeof(struct pvfs2_upcall_s)) +sizeof(__u64) + sizeof(struct orangefs_upcall_s)) #define MAX_DEV_REQ_DOWNSIZE (2*sizeof(__s32) + \ -sizeof(__u64) + sizeof(struct pvfs2_downcall_s)) +sizeof(__u64) + sizeof(struct orangefs_downcall_s)) #define BITS_PER_LONG_DIV_8 (BITS_PER_LONG >> 3) @@ -104,7 +104,7 @@ sizeof(__u64) + sizeof(struct pvfs2_downcall_s)) MAX_DEV_REQ_DOWNSIZE)) /* - * valid pvfs2 kernel operation states + * valid orangefs kernel operation states * * unknown - op was just initialized * waiting - op is on request_list (upward bound) @@ -113,7 +113,7 @@ sizeof(__u64) + sizeof(struct pvfs2_downcall_s)) * purged - op has to start a timer since client-core * exited uncleanly before servicing op */ -enum pvfs2_vfs_op_states { +enum orangefs_vfs_op_states { OP_VFS_STATE_UNKNOWN = 0, OP_VFS_STATE_WAITING = 1, OP_VFS_STATE_INPROGR = 2, @@ -156,9 +156,9 @@ enum pvfs2_vfs_op_states { /* * Defines for controlling whether I/O upcalls are for async or sync operations */ -enum PVFS_async_io_type { - PVFS_VFS_SYNC_IO = 0, - PVFS_VFS_ASYNC_IO = 1, +enum ORANGEFS_async_io_type { + ORANGEFS_VFS_SYNC_IO = 0, + ORANGEFS_VFS_ASYNC_IO = 1, }; /* @@ -172,24 +172,24 @@ struct client_debug_mask { }; /* - * pvfs2 kernel memory related flags + * orangefs kernel memory related flags */ -#if ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) -#define PVFS2_CACHE_CREATE_FLAGS SLAB_RED_ZONE +#if ((defined ORANGEFS_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) +#define ORANGEFS_CACHE_CREATE_FLAGS SLAB_RED_ZONE #else -#define PVFS2_CACHE_CREATE_FLAGS 0 -#endif /* ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */ +#define ORANGEFS_CACHE_CREATE_FLAGS 0 +#endif /* ((defined ORANGEFS_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */ -#define PVFS2_CACHE_ALLOC_FLAGS (GFP_KERNEL) -#define PVFS2_GFP_FLAGS (GFP_KERNEL) -#define PVFS2_BUFMAP_GFP_FLAGS (GFP_KERNEL) +#define ORANGEFS_CACHE_ALLOC_FLAGS (GFP_KERNEL) +#define ORANGEFS_GFP_FLAGS (GFP_KERNEL) +#define ORANGEFS_BUFMAP_GFP_FLAGS (GFP_KERNEL) -/* pvfs2 xattr and acl related defines */ -#define PVFS2_XATTR_INDEX_POSIX_ACL_ACCESS 1 -#define PVFS2_XATTR_INDEX_POSIX_ACL_DEFAULT 2 -#define PVFS2_XATTR_INDEX_TRUSTED 3 -#define PVFS2_XATTR_INDEX_DEFAULT 4 +/* orangefs xattr and acl related defines */ +#define ORANGEFS_XATTR_INDEX_POSIX_ACL_ACCESS 1 +#define ORANGEFS_XATTR_INDEX_POSIX_ACL_DEFAULT 2 +#define ORANGEFS_XATTR_INDEX_TRUSTED 3 +#define ORANGEFS_XATTR_INDEX_DEFAULT 4 #if 0 #ifndef POSIX_ACL_XATTR_ACCESS @@ -200,17 +200,17 @@ struct client_debug_mask { #endif #endif -#define PVFS2_XATTR_NAME_ACL_ACCESS POSIX_ACL_XATTR_ACCESS -#define PVFS2_XATTR_NAME_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT -#define PVFS2_XATTR_NAME_TRUSTED_PREFIX "trusted." -#define PVFS2_XATTR_NAME_DEFAULT_PREFIX "" +#define ORANGEFS_XATTR_NAME_ACL_ACCESS POSIX_ACL_XATTR_ACCESS +#define ORANGEFS_XATTR_NAME_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT +#define ORANGEFS_XATTR_NAME_TRUSTED_PREFIX "trusted." +#define ORANGEFS_XATTR_NAME_DEFAULT_PREFIX "" -/* these functions are defined in pvfs2-utils.c */ +/* these functions are defined in orangefs-utils.c */ int orangefs_prepare_cdm_array(char *debug_array_string); int orangefs_prepare_debugfs_help_string(int); -/* defined in pvfs2-debugfs.c */ -int pvfs2_client_debug_init(void); +/* defined in orangefs-debugfs.c */ +int orangefs_client_debug_init(void); void debug_string_to_mask(char *, void *, int); void do_c_mask(int, char *, struct client_debug_mask **); @@ -222,17 +222,17 @@ void do_c_string(void *, int); int check_amalgam_keyword(void *, int); int keyword_is_amalgam(char *); -/*these variables are defined in pvfs2-mod.c */ -extern char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; -extern char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; -extern char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN]; +/*these variables are defined in orangefs-mod.c */ +extern char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; +extern char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; +extern char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; extern unsigned int kernel_mask_set_mod_init; -extern int pvfs2_init_acl(struct inode *inode, struct inode *dir); -extern const struct xattr_handler *pvfs2_xattr_handlers[]; +extern int orangefs_init_acl(struct inode *inode, struct inode *dir); +extern const struct xattr_handler *orangefs_xattr_handlers[]; -extern struct posix_acl *pvfs2_get_acl(struct inode *inode, int type); -extern int pvfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); +extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type); +extern int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type); /* * Redefine xtvec structure so that we could move helper functions out of @@ -244,10 +244,10 @@ struct xtvec { }; /* - * pvfs2 data structures + * orangefs data structures */ -struct pvfs2_kernel_op_s { - enum pvfs2_vfs_op_states op_state; +struct orangefs_kernel_op_s { + enum orangefs_vfs_op_states op_state; __u64 tag; /* @@ -257,8 +257,8 @@ struct pvfs2_kernel_op_s { */ int uses_shared_memory; - struct pvfs2_upcall_s upcall; - struct pvfs2_downcall_s downcall; + struct orangefs_upcall_s upcall; + struct orangefs_downcall_s downcall; wait_queue_head_t waitq; spinlock_t lock; @@ -268,7 +268,7 @@ struct pvfs2_kernel_op_s { /* VFS aio fields */ - /* used by the async I/O code to stash the pvfs2_kiocb_s structure */ + /* used by the async I/O code to stash the orangefs_kiocb_s structure */ void *priv; /* used again for the async I/O code for deallocation */ @@ -279,14 +279,14 @@ struct pvfs2_kernel_op_s { struct list_head list; }; -/* per inode private pvfs2 info */ -struct pvfs2_inode_s { - struct pvfs2_object_kref refn; - char link_target[PVFS_NAME_MAX]; +/* per inode private orangefs info */ +struct orangefs_inode_s { + struct orangefs_object_kref refn; + char link_target[ORANGEFS_NAME_MAX]; __s64 blksize; /* * Reading/Writing Extended attributes need to acquire the appropriate - * reader/writer semaphore on the pvfs2_inode_s structure. + * reader/writer semaphore on the orangefs_inode_s structure. */ struct rw_semaphore xattr_sem; @@ -299,7 +299,7 @@ struct pvfs2_inode_s { */ unsigned long pinode_flags; - /* All allocated pvfs2_inode_s objects are chained to a list */ + /* All allocated orangefs_inode_s objects are chained to a list */ struct list_head list; }; @@ -324,15 +324,15 @@ struct pvfs2_inode_s { #define SetModeFlag(pinode) set_bit(P_MODE_FLAG, &(pinode)->pinode_flags) #define ModeFlag(pinode) test_bit(P_MODE_FLAG, &(pinode)->pinode_flags) -/* per superblock private pvfs2 info */ -struct pvfs2_sb_info_s { - struct pvfs2_khandle root_khandle; +/* per superblock private orangefs info */ +struct orangefs_sb_info_s { + struct orangefs_khandle root_khandle; __s32 fs_id; int id; int flags; -#define PVFS2_OPT_INTR 0x01 -#define PVFS2_OPT_LOCAL_LOCK 0x02 - char devname[PVFS_MAX_SERVER_ADDR_LEN]; +#define ORANGEFS_OPT_INTR 0x01 +#define ORANGEFS_OPT_LOCAL_LOCK 0x02 + char devname[ORANGEFS_MAX_SERVER_ADDR_LEN]; struct super_block *sb; int mount_pending; struct list_head list; @@ -344,7 +344,7 @@ struct pvfs2_sb_info_s { * or even completion notification so that the VFS client-side daemon * can free up its vfs_request slots. */ -struct pvfs2_kiocb_s { +struct orangefs_kiocb_s { /* the pointer to the task that initiated the AIO */ struct task_struct *tsk; @@ -352,11 +352,11 @@ struct pvfs2_kiocb_s { struct kiocb *kiocb; /* buffer index that was used for the I/O */ - struct pvfs2_bufmap *bufmap; + struct orangefs_bufmap *bufmap; int buffer_index; - /* pvfs2 kernel operation type */ - struct pvfs2_kernel_op_s *op; + /* orangefs kernel operation type */ + struct orangefs_kernel_op_s *op; /* The user space buffers from/to which I/O is being staged */ struct iovec *iov; @@ -377,31 +377,31 @@ struct pvfs2_kiocb_s { int needs_cleanup; }; -struct pvfs2_stats { +struct orangefs_stats { unsigned long cache_hits; unsigned long cache_misses; unsigned long reads; unsigned long writes; }; -extern struct pvfs2_stats g_pvfs2_stats; +extern struct orangefs_stats g_orangefs_stats; /* * NOTE: See Documentation/filesystems/porting for information * on implementing FOO_I and properly accessing fs private data */ -static inline struct pvfs2_inode_s *PVFS2_I(struct inode *inode) +static inline struct orangefs_inode_s *ORANGEFS_I(struct inode *inode) { - return container_of(inode, struct pvfs2_inode_s, vfs_inode); + return container_of(inode, struct orangefs_inode_s, vfs_inode); } -static inline struct pvfs2_sb_info_s *PVFS2_SB(struct super_block *sb) +static inline struct orangefs_sb_info_s *ORANGEFS_SB(struct super_block *sb) { - return (struct pvfs2_sb_info_s *) sb->s_fs_info; + return (struct orangefs_sb_info_s *) sb->s_fs_info; } /* ino_t descends from "unsigned long", 8 bytes, 64 bits. */ -static inline ino_t pvfs2_khandle_to_ino(struct pvfs2_khandle *khandle) +static inline ino_t orangefs_khandle_to_ino(struct orangefs_khandle *khandle) { union { unsigned char u[8]; @@ -420,23 +420,23 @@ static inline ino_t pvfs2_khandle_to_ino(struct pvfs2_khandle *khandle) return ihandle.ino; } -static inline struct pvfs2_khandle *get_khandle_from_ino(struct inode *inode) +static inline struct orangefs_khandle *get_khandle_from_ino(struct inode *inode) { - return &(PVFS2_I(inode)->refn.khandle); + return &(ORANGEFS_I(inode)->refn.khandle); } static inline __s32 get_fsid_from_ino(struct inode *inode) { - return PVFS2_I(inode)->refn.fs_id; + return ORANGEFS_I(inode)->refn.fs_id; } static inline ino_t get_ino_from_khandle(struct inode *inode) { - struct pvfs2_khandle *khandle; + struct orangefs_khandle *khandle; ino_t ino; khandle = get_khandle_from_ino(inode); - ino = pvfs2_khandle_to_ino(khandle); + ino = orangefs_khandle_to_ino(khandle); return ino; } @@ -450,17 +450,17 @@ static inline int is_root_handle(struct inode *inode) gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: root handle: %pU, this handle: %pU:\n", __func__, - &PVFS2_SB(inode->i_sb)->root_khandle, + &ORANGEFS_SB(inode->i_sb)->root_khandle, get_khandle_from_ino(inode)); - if (PVFS_khandle_cmp(&(PVFS2_SB(inode->i_sb)->root_khandle), + if (ORANGEFS_khandle_cmp(&(ORANGEFS_SB(inode->i_sb)->root_khandle), get_khandle_from_ino(inode))) return 0; else return 1; } -static inline int match_handle(struct pvfs2_khandle resp_handle, +static inline int match_handle(struct orangefs_khandle resp_handle, struct inode *inode) { gossip_debug(GOSSIP_DCACHE_DEBUG, @@ -469,57 +469,57 @@ static inline int match_handle(struct pvfs2_khandle resp_handle, &resp_handle, get_khandle_from_ino(inode)); - if (PVFS_khandle_cmp(&resp_handle, get_khandle_from_ino(inode))) + if (ORANGEFS_khandle_cmp(&resp_handle, get_khandle_from_ino(inode))) return 0; else return 1; } /* - * defined in pvfs2-cache.c + * defined in orangefs-cache.c */ int op_cache_initialize(void); int op_cache_finalize(void); -struct pvfs2_kernel_op_s *op_alloc(__s32 type); -char *get_opname_string(struct pvfs2_kernel_op_s *new_op); -void op_release(struct pvfs2_kernel_op_s *op); +struct orangefs_kernel_op_s *op_alloc(__s32 type); +char *get_opname_string(struct orangefs_kernel_op_s *new_op); +void op_release(struct orangefs_kernel_op_s *op); int dev_req_cache_initialize(void); int dev_req_cache_finalize(void); void *dev_req_alloc(void); void dev_req_release(void *); -int pvfs2_inode_cache_initialize(void); -int pvfs2_inode_cache_finalize(void); +int orangefs_inode_cache_initialize(void); +int orangefs_inode_cache_finalize(void); int kiocb_cache_initialize(void); int kiocb_cache_finalize(void); -struct pvfs2_kiocb_s *kiocb_alloc(void); -void kiocb_release(struct pvfs2_kiocb_s *ptr); +struct orangefs_kiocb_s *kiocb_alloc(void); +void kiocb_release(struct orangefs_kiocb_s *ptr); /* - * defined in pvfs2-mod.c + * defined in orangefs-mod.c */ void purge_inprogress_ops(void); /* * defined in waitqueue.c */ -int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op); -int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op); -void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op); +int wait_for_matching_downcall(struct orangefs_kernel_op_s *op); +int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op); +void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op); void purge_waiting_ops(void); /* * defined in super.c */ -struct dentry *pvfs2_mount(struct file_system_type *fst, +struct dentry *orangefs_mount(struct file_system_type *fst, int flags, const char *devname, void *data); -void pvfs2_kill_sb(struct super_block *sb); -int pvfs2_remount(struct super_block *sb); +void orangefs_kill_sb(struct super_block *sb); +int orangefs_remount(struct super_block *sb); int fsid_key_table_initialize(void); void fsid_key_table_finalize(void); @@ -527,175 +527,175 @@ void fsid_key_table_finalize(void); /* * defined in inode.c */ -__u32 convert_to_pvfs2_mask(unsigned long lite_mask); -struct inode *pvfs2_new_inode(struct super_block *sb, +__u32 convert_to_orangefs_mask(unsigned long lite_mask); +struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, int mode, dev_t dev, - struct pvfs2_object_kref *ref); + struct orangefs_object_kref *ref); -int pvfs2_setattr(struct dentry *dentry, struct iattr *iattr); +int orangefs_setattr(struct dentry *dentry, struct iattr *iattr); -int pvfs2_getattr(struct vfsmount *mnt, +int orangefs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat); /* * defined in xattr.c */ -int pvfs2_setxattr(struct dentry *dentry, +int orangefs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); -ssize_t pvfs2_getxattr(struct dentry *dentry, +ssize_t orangefs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); -ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size); +ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size); /* * defined in namei.c */ -struct inode *pvfs2_iget(struct super_block *sb, - struct pvfs2_object_kref *ref); +struct inode *orangefs_iget(struct super_block *sb, + struct orangefs_object_kref *ref); -ssize_t pvfs2_inode_read(struct inode *inode, - struct iov_iter *iter, - loff_t *offset, - loff_t readahead_size); +ssize_t orangefs_inode_read(struct inode *inode, + struct iov_iter *iter, + loff_t *offset, + loff_t readahead_size); /* - * defined in devpvfs2-req.c + * defined in devorangefs-req.c */ -int pvfs2_dev_init(void); -void pvfs2_dev_cleanup(void); +int orangefs_dev_init(void); +void orangefs_dev_cleanup(void); int is_daemon_in_service(void); int fs_mount_pending(__s32 fsid); /* - * defined in pvfs2-utils.c + * defined in orangefs-utils.c */ -__s32 fsid_of_op(struct pvfs2_kernel_op_s *op); +__s32 fsid_of_op(struct orangefs_kernel_op_s *op); -int pvfs2_flush_inode(struct inode *inode); +int orangefs_flush_inode(struct inode *inode); -ssize_t pvfs2_inode_getxattr(struct inode *inode, +ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix, const char *name, void *buffer, size_t size); -int pvfs2_inode_setxattr(struct inode *inode, +int orangefs_inode_setxattr(struct inode *inode, const char *prefix, const char *name, const void *value, size_t size, int flags); -int pvfs2_inode_getattr(struct inode *inode, __u32 mask); +int orangefs_inode_getattr(struct inode *inode, __u32 mask); -int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr); +int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr); -void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op); +void orangefs_op_initialize(struct orangefs_kernel_op_s *op); -void pvfs2_make_bad_inode(struct inode *inode); +void orangefs_make_bad_inode(struct inode *inode); void block_signals(sigset_t *); void set_signals(sigset_t *); -int pvfs2_unmount_sb(struct super_block *sb); +int orangefs_unmount_sb(struct super_block *sb); -int pvfs2_cancel_op_in_progress(__u64 tag); +int orangefs_cancel_op_in_progress(__u64 tag); -static inline __u64 pvfs2_convert_time_field(const struct timespec *ts) +static inline __u64 orangefs_convert_time_field(const struct timespec *ts) { return (__u64)ts->tv_sec; } -int pvfs2_normalize_to_errno(__s32 error_code); +int orangefs_normalize_to_errno(__s32 error_code); extern struct mutex devreq_mutex; extern struct mutex request_mutex; extern int debug; extern int op_timeout_secs; extern int slot_timeout_secs; -extern struct list_head pvfs2_superblocks; -extern spinlock_t pvfs2_superblocks_lock; -extern struct list_head pvfs2_request_list; -extern spinlock_t pvfs2_request_list_lock; -extern wait_queue_head_t pvfs2_request_list_waitq; +extern struct list_head orangefs_superblocks; +extern spinlock_t orangefs_superblocks_lock; +extern struct list_head orangefs_request_list; +extern spinlock_t orangefs_request_list_lock; +extern wait_queue_head_t orangefs_request_list_waitq; extern struct list_head *htable_ops_in_progress; extern spinlock_t htable_ops_in_progress_lock; extern int hash_table_size; -extern const struct address_space_operations pvfs2_address_operations; -extern struct backing_dev_info pvfs2_backing_dev_info; -extern struct inode_operations pvfs2_file_inode_operations; -extern const struct file_operations pvfs2_file_operations; -extern struct inode_operations pvfs2_symlink_inode_operations; -extern struct inode_operations pvfs2_dir_inode_operations; -extern const struct file_operations pvfs2_dir_operations; -extern const struct dentry_operations pvfs2_dentry_operations; -extern const struct file_operations pvfs2_devreq_file_operations; +extern const struct address_space_operations orangefs_address_operations; +extern struct backing_dev_info orangefs_backing_dev_info; +extern struct inode_operations orangefs_file_inode_operations; +extern const struct file_operations orangefs_file_operations; +extern struct inode_operations orangefs_symlink_inode_operations; +extern struct inode_operations orangefs_dir_inode_operations; +extern const struct file_operations orangefs_dir_operations; +extern const struct dentry_operations orangefs_dentry_operations; +extern const struct file_operations orangefs_devreq_file_operations; -extern wait_queue_head_t pvfs2_bufmap_init_waitq; +extern wait_queue_head_t orangefs_bufmap_init_waitq; /* * misc convenience macros */ #define add_op_to_request_list(op) \ do { \ - spin_lock(&pvfs2_request_list_lock); \ + spin_lock(&orangefs_request_list_lock); \ spin_lock(&op->lock); \ set_op_state_waiting(op); \ - list_add_tail(&op->list, &pvfs2_request_list); \ - spin_unlock(&pvfs2_request_list_lock); \ + list_add_tail(&op->list, &orangefs_request_list); \ + spin_unlock(&orangefs_request_list_lock); \ spin_unlock(&op->lock); \ - wake_up_interruptible(&pvfs2_request_list_waitq); \ + wake_up_interruptible(&orangefs_request_list_waitq); \ } while (0) #define add_priority_op_to_request_list(op) \ do { \ - spin_lock(&pvfs2_request_list_lock); \ + spin_lock(&orangefs_request_list_lock); \ spin_lock(&op->lock); \ set_op_state_waiting(op); \ \ - list_add(&op->list, &pvfs2_request_list); \ - spin_unlock(&pvfs2_request_list_lock); \ + list_add(&op->list, &orangefs_request_list); \ + spin_unlock(&orangefs_request_list_lock); \ spin_unlock(&op->lock); \ - wake_up_interruptible(&pvfs2_request_list_waitq); \ + wake_up_interruptible(&orangefs_request_list_waitq); \ } while (0) #define remove_op_from_request_list(op) \ do { \ struct list_head *tmp = NULL; \ struct list_head *tmp_safe = NULL; \ - struct pvfs2_kernel_op_s *tmp_op = NULL; \ + struct orangefs_kernel_op_s *tmp_op = NULL; \ \ - spin_lock(&pvfs2_request_list_lock); \ - list_for_each_safe(tmp, tmp_safe, &pvfs2_request_list) { \ + spin_lock(&orangefs_request_list_lock); \ + list_for_each_safe(tmp, tmp_safe, &orangefs_request_list) { \ tmp_op = list_entry(tmp, \ - struct pvfs2_kernel_op_s, \ + struct orangefs_kernel_op_s, \ list); \ if (tmp_op && (tmp_op == op)) { \ list_del(&tmp_op->list); \ break; \ } \ } \ - spin_unlock(&pvfs2_request_list_lock); \ + spin_unlock(&orangefs_request_list_lock); \ } while (0) -#define PVFS2_OP_INTERRUPTIBLE 1 /* service_operation() is interruptible */ -#define PVFS2_OP_PRIORITY 2 /* service_operation() is high priority */ -#define PVFS2_OP_CANCELLATION 4 /* this is a cancellation */ -#define PVFS2_OP_NO_SEMAPHORE 8 /* don't acquire semaphore */ -#define PVFS2_OP_ASYNC 16 /* Queue it, but don't wait */ +#define ORANGEFS_OP_INTERRUPTIBLE 1 /* service_operation() is interruptible */ +#define ORANGEFS_OP_PRIORITY 2 /* service_operation() is high priority */ +#define ORANGEFS_OP_CANCELLATION 4 /* this is a cancellation */ +#define ORANGEFS_OP_NO_SEMAPHORE 8 /* don't acquire semaphore */ +#define ORANGEFS_OP_ASYNC 16 /* Queue it, but don't wait */ -int service_operation(struct pvfs2_kernel_op_s *op, +int service_operation(struct orangefs_kernel_op_s *op, const char *op_name, int flags); @@ -719,7 +719,7 @@ int service_operation(struct pvfs2_kernel_op_s *op, * sent and have handle_error * take care of this situation as well.. * - * if a pvfs2 sysint level error occured and i/o has been completed, + * if a orangefs sysint level error occured and i/o has been completed, * there is no need to cancel the operation, as the user has finished * using the bufmap page and so there is no danger in this case. in * this case, we wake up the device normally so that it may free the @@ -731,77 +731,77 @@ int service_operation(struct pvfs2_kernel_op_s *op, #define handle_io_error() \ do { \ if (!op_state_serviced(new_op)) { \ - pvfs2_cancel_op_in_progress(new_op->tag); \ + orangefs_cancel_op_in_progress(new_op->tag); \ op_release(new_op); \ } else { \ wake_up_daemon_for_return(new_op); \ } \ new_op = NULL; \ - pvfs_bufmap_put(bufmap, buffer_index); \ + orangefs_bufmap_put(bufmap, buffer_index); \ buffer_index = -1; \ } while (0) #define get_interruptible_flag(inode) \ - ((PVFS2_SB(inode->i_sb)->flags & PVFS2_OPT_INTR) ? \ - PVFS2_OP_INTERRUPTIBLE : 0) + ((ORANGEFS_SB(inode->i_sb)->flags & ORANGEFS_OPT_INTR) ? \ + ORANGEFS_OP_INTERRUPTIBLE : 0) -#define add_pvfs2_sb(sb) \ +#define add_orangefs_sb(sb) \ do { \ gossip_debug(GOSSIP_SUPER_DEBUG, \ - "Adding SB %p to pvfs2 superblocks\n", \ - PVFS2_SB(sb)); \ - spin_lock(&pvfs2_superblocks_lock); \ - list_add_tail(&PVFS2_SB(sb)->list, &pvfs2_superblocks); \ - spin_unlock(&pvfs2_superblocks_lock); \ + "Adding SB %p to orangefs superblocks\n", \ + ORANGEFS_SB(sb)); \ + spin_lock(&orangefs_superblocks_lock); \ + list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks); \ + spin_unlock(&orangefs_superblocks_lock); \ } while (0) -#define remove_pvfs2_sb(sb) \ +#define remove_orangefs_sb(sb) \ do { \ struct list_head *tmp = NULL; \ struct list_head *tmp_safe = NULL; \ - struct pvfs2_sb_info_s *pvfs2_sb = NULL; \ + struct orangefs_sb_info_s *orangefs_sb = NULL; \ \ - spin_lock(&pvfs2_superblocks_lock); \ - list_for_each_safe(tmp, tmp_safe, &pvfs2_superblocks) { \ - pvfs2_sb = list_entry(tmp, \ - struct pvfs2_sb_info_s, \ + spin_lock(&orangefs_superblocks_lock); \ + list_for_each_safe(tmp, tmp_safe, &orangefs_superblocks) { \ + orangefs_sb = list_entry(tmp, \ + struct orangefs_sb_info_s, \ list); \ - if (pvfs2_sb && (pvfs2_sb->sb == sb)) { \ + if (orangefs_sb && (orangefs_sb->sb == sb)) { \ gossip_debug(GOSSIP_SUPER_DEBUG, \ - "Removing SB %p from pvfs2 superblocks\n", \ - pvfs2_sb); \ - list_del(&pvfs2_sb->list); \ + "Removing SB %p from orangefs superblocks\n", \ + orangefs_sb); \ + list_del(&orangefs_sb->list); \ break; \ } \ } \ - spin_unlock(&pvfs2_superblocks_lock); \ + spin_unlock(&orangefs_superblocks_lock); \ } while (0) -#define pvfs2_lock_inode(inode) spin_lock(&inode->i_lock) -#define pvfs2_unlock_inode(inode) spin_unlock(&inode->i_lock) +#define orangefs_lock_inode(inode) spin_lock(&inode->i_lock) +#define orangefs_unlock_inode(inode) spin_unlock(&inode->i_lock) #define fill_default_sys_attrs(sys_attr, type, mode) \ do { \ sys_attr.owner = from_kuid(current_user_ns(), current_fsuid()); \ sys_attr.group = from_kgid(current_user_ns(), current_fsgid()); \ sys_attr.size = 0; \ - sys_attr.perms = PVFS_util_translate_mode(mode); \ + sys_attr.perms = ORANGEFS_util_translate_mode(mode); \ sys_attr.objtype = type; \ - sys_attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; \ + sys_attr.mask = ORANGEFS_ATTR_SYS_ALL_SETABLE; \ } while (0) -#define pvfs2_inode_lock(__i) mutex_lock(&(__i)->i_mutex) +#define orangefs_inode_lock(__i) mutex_lock(&(__i)->i_mutex) -#define pvfs2_inode_unlock(__i) mutex_unlock(&(__i)->i_mutex) +#define orangefs_inode_unlock(__i) mutex_unlock(&(__i)->i_mutex) -static inline void pvfs2_i_size_write(struct inode *inode, loff_t i_size) +static inline void orangefs_i_size_write(struct inode *inode, loff_t i_size) { #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) - pvfs2_inode_lock(inode); + ornagefs_inode_lock(inode); #endif i_size_write(inode, i_size); #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) - pvfs2_inode_unlock(inode); + orangefs_inode_unlock(inode); #endif } @@ -816,4 +816,4 @@ static inline unsigned int diff(struct timeval *end, struct timeval *begin) return (end->tv_sec * 1000000) + end->tv_usec; } -#endif /* __PVFS2KERNEL_H */ +#endif /* __ORANGEFSKERNEL_H */ diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/pvfs2-mod.c index d848c90413d1..d8642908a917 100644 --- a/fs/orangefs/pvfs2-mod.c +++ b/fs/orangefs/pvfs2-mod.c @@ -12,9 +12,9 @@ #include "pvfs2-debugfs.h" #include "pvfs2-sysfs.h" -/* PVFS2_VERSION is a ./configure define */ -#ifndef PVFS2_VERSION -#define PVFS2_VERSION "Unknown" +/* ORANGEFS_VERSION is a ./configure define */ +#ifndef ORANGEFS_VERSION +#define ORANGEFS_VERSION "Unknown" #endif /* @@ -25,9 +25,9 @@ struct client_debug_mask *cdm_array; int cdm_element_count; -char kernel_debug_string[PVFS2_MAX_DEBUG_STRING_LEN] = "none"; -char client_debug_string[PVFS2_MAX_DEBUG_STRING_LEN]; -char client_debug_array_string[PVFS2_MAX_DEBUG_STRING_LEN]; +char kernel_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN] = "none"; +char client_debug_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; +char client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN]; char *debug_help_string; int help_string_initialized; @@ -36,7 +36,7 @@ struct dentry *client_debug_dentry; struct dentry *debug_dir; int client_verbose_index; int client_all_index; -struct pvfs2_stats g_pvfs2_stats; +struct orangefs_stats g_orangefs_stats; /* the size of the hash tables for ops in progress */ int hash_table_size = 509; @@ -45,22 +45,22 @@ static ulong module_parm_debug_mask; __u64 gossip_debug_mask; struct client_debug_mask client_debug_mask = { NULL, 0, 0 }; unsigned int kernel_mask_set_mod_init; /* implicitly false */ -int op_timeout_secs = PVFS2_DEFAULT_OP_TIMEOUT_SECS; -int slot_timeout_secs = PVFS2_DEFAULT_SLOT_TIMEOUT_SECS; +int op_timeout_secs = ORANGEFS_DEFAULT_OP_TIMEOUT_SECS; +int slot_timeout_secs = ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS; MODULE_LICENSE("GPL"); -MODULE_AUTHOR("PVFS2 Development Team"); -MODULE_DESCRIPTION("The Linux Kernel VFS interface to PVFS2"); -MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see pvfs2-debug.h for values)"); +MODULE_AUTHOR("ORANGEFS Development Team"); +MODULE_DESCRIPTION("The Linux Kernel VFS interface to ORANGEFS"); +MODULE_PARM_DESC(module_parm_debug_mask, "debugging level (see orangefs-debug.h for values)"); MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds"); MODULE_PARM_DESC(slot_timeout_secs, "Slot timeout in seconds"); MODULE_PARM_DESC(hash_table_size, "size of hash table for operations in progress"); -static struct file_system_type pvfs2_fs_type = { +static struct file_system_type orangefs_fs_type = { .name = "pvfs2", - .mount = pvfs2_mount, - .kill_sb = pvfs2_kill_sb, + .mount = orangefs_mount, + .kill_sb = orangefs_kill_sb, .owner = THIS_MODULE, }; @@ -85,15 +85,15 @@ struct list_head *htable_ops_in_progress; DEFINE_SPINLOCK(htable_ops_in_progress_lock); /* list for queueing upcall operations */ -LIST_HEAD(pvfs2_request_list); +LIST_HEAD(orangefs_request_list); -/* used to protect the above pvfs2_request_list */ -DEFINE_SPINLOCK(pvfs2_request_list_lock); +/* used to protect the above orangefs_request_list */ +DEFINE_SPINLOCK(orangefs_request_list_lock); /* used for incoming request notification */ -DECLARE_WAIT_QUEUE_HEAD(pvfs2_request_list_waitq); +DECLARE_WAIT_QUEUE_HEAD(orangefs_request_list_waitq); -static int __init pvfs2_init(void) +static int __init orangefs_init(void) { int ret = -1; __u32 i = 0; @@ -112,7 +112,7 @@ static int __init pvfs2_init(void) /* * if the mask has a non-zero value, then indicate that the mask - * was set when the kernel module was loaded. The pvfs2 dev ioctl + * was set when the kernel module was loaded. The orangefs dev ioctl * command will look at this boolean to determine if the kernel's * debug mask should be overwritten when the client-core is started. */ @@ -120,11 +120,11 @@ static int __init pvfs2_init(void) kernel_mask_set_mod_init = true; /* print information message to the system log */ - pr_info("pvfs2: pvfs2_init called with debug mask: :%s: :%llx:\n", + pr_info("orangefs: orangefs_init called with debug mask: :%s: :%llx:\n", kernel_debug_string, (unsigned long long)gossip_debug_mask); - ret = bdi_init(&pvfs2_backing_dev_info); + ret = bdi_init(&orangefs_backing_dev_info); if (ret) return ret; @@ -144,7 +144,7 @@ static int __init pvfs2_init(void) if (ret < 0) goto cleanup_op; - ret = pvfs2_inode_cache_initialize(); + ret = orangefs_inode_cache_initialize(); if (ret < 0) goto cleanup_req; @@ -153,9 +153,9 @@ static int __init pvfs2_init(void) goto cleanup_inode; /* Initialize the pvfsdev subsystem. */ - ret = pvfs2_dev_init(); + ret = orangefs_dev_init(); if (ret < 0) { - gossip_err("pvfs2: could not initialize device subsystem %d!\n", + gossip_err("orangefs: could not initialize device subsystem %d!\n", ret); goto cleanup_kiocb; } @@ -197,17 +197,17 @@ static int __init pvfs2_init(void) if (ret) goto out; - pvfs2_debugfs_init(); - pvfs2_kernel_debug_init(); + orangefs_debugfs_init(); + orangefs_kernel_debug_init(); orangefs_sysfs_init(); - ret = register_filesystem(&pvfs2_fs_type); + ret = register_filesystem(&orangefs_fs_type); if (ret == 0) { - pr_info("pvfs2: module version %s loaded\n", PVFS2_VERSION); + pr_info("orangefs: module version %s loaded\n", ORANGEFS_VERSION); return 0; } - pvfs2_debugfs_cleanup(); + orangefs_debugfs_cleanup(); orangefs_sysfs_exit(); fsid_key_table_finalize(); @@ -215,13 +215,13 @@ static int __init pvfs2_init(void) kfree(htable_ops_in_progress); cleanup_device: - pvfs2_dev_cleanup(); + orangefs_dev_cleanup(); cleanup_kiocb: kiocb_cache_finalize(); cleanup_inode: - pvfs2_inode_cache_finalize(); + orangefs_inode_cache_finalize(); cleanup_req: dev_req_cache_finalize(); @@ -230,29 +230,29 @@ static int __init pvfs2_init(void) op_cache_finalize(); err: - bdi_destroy(&pvfs2_backing_dev_info); + bdi_destroy(&orangefs_backing_dev_info); out: return ret; } -static void __exit pvfs2_exit(void) +static void __exit orangefs_exit(void) { int i = 0; - struct pvfs2_kernel_op_s *cur_op = NULL; + struct orangefs_kernel_op_s *cur_op = NULL; - gossip_debug(GOSSIP_INIT_DEBUG, "pvfs2: pvfs2_exit called\n"); + gossip_debug(GOSSIP_INIT_DEBUG, "orangefs: orangefs_exit called\n"); - unregister_filesystem(&pvfs2_fs_type); - pvfs2_debugfs_cleanup(); + unregister_filesystem(&orangefs_fs_type); + orangefs_debugfs_cleanup(); orangefs_sysfs_exit(); fsid_key_table_finalize(); - pvfs2_dev_cleanup(); + orangefs_dev_cleanup(); /* clear out all pending upcall op requests */ - spin_lock(&pvfs2_request_list_lock); - while (!list_empty(&pvfs2_request_list)) { - cur_op = list_entry(pvfs2_request_list.next, - struct pvfs2_kernel_op_s, + spin_lock(&orangefs_request_list_lock); + while (!list_empty(&orangefs_request_list)) { + cur_op = list_entry(orangefs_request_list.next, + struct orangefs_kernel_op_s, list); list_del(&cur_op->list); gossip_debug(GOSSIP_INIT_DEBUG, @@ -260,26 +260,26 @@ static void __exit pvfs2_exit(void) cur_op->upcall.type); op_release(cur_op); } - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); for (i = 0; i < hash_table_size; i++) while (!list_empty(&htable_ops_in_progress[i])) { cur_op = list_entry(htable_ops_in_progress[i].next, - struct pvfs2_kernel_op_s, + struct orangefs_kernel_op_s, list); op_release(cur_op); } kiocb_cache_finalize(); - pvfs2_inode_cache_finalize(); + orangefs_inode_cache_finalize(); dev_req_cache_finalize(); op_cache_finalize(); kfree(htable_ops_in_progress); - bdi_destroy(&pvfs2_backing_dev_info); + bdi_destroy(&orangefs_backing_dev_info); - pr_info("pvfs2: module version %s unloaded\n", PVFS2_VERSION); + pr_info("orangefs: module version %s unloaded\n", ORANGEFS_VERSION); } /* @@ -291,8 +291,8 @@ void purge_inprogress_ops(void) int i; for (i = 0; i < hash_table_size; i++) { - struct pvfs2_kernel_op_s *op; - struct pvfs2_kernel_op_s *next; + struct orangefs_kernel_op_s *op; + struct orangefs_kernel_op_s *next; list_for_each_entry_safe(op, next, @@ -311,5 +311,5 @@ void purge_inprogress_ops(void) } } -module_init(pvfs2_init); -module_exit(pvfs2_exit); +module_init(orangefs_init); +module_exit(orangefs_exit); diff --git a/fs/orangefs/pvfs2-sysfs.c b/fs/orangefs/pvfs2-sysfs.c index ea635b5e431b..f04de2593c79 100644 --- a/fs/orangefs/pvfs2-sysfs.c +++ b/fs/orangefs/pvfs2-sysfs.c @@ -669,13 +669,13 @@ static ssize_t sysfs_int_show(char *kobj_id, char *buf, void *attr) rc = scnprintf(buf, PAGE_SIZE, "%lu\n", - g_pvfs2_stats.reads); + g_orangefs_stats.reads); goto out; } else if (!strcmp(stats_orangefs_attr->attr.name, "writes")) { rc = scnprintf(buf, PAGE_SIZE, "%lu\n", - g_pvfs2_stats.writes); + g_orangefs_stats.writes); goto out; } else { goto out; @@ -752,7 +752,7 @@ static ssize_t int_store(struct orangefs_obj *orangefs_obj, */ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) { - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; int rc = 0; char *ser_op_type = NULL; struct orangefs_attribute *orangefs_attr; @@ -768,9 +768,9 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) kobj_id); if (strcmp(kobj_id, PC_KOBJ_ID)) - op_alloc_type = PVFS2_VFS_OP_PARAM; + op_alloc_type = ORANGEFS_VFS_OP_PARAM; else - op_alloc_type = PVFS2_VFS_OP_PERF_COUNT; + op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT; new_op = op_alloc(op_alloc_type); if (!new_op) { @@ -788,113 +788,113 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) } if (strcmp(kobj_id, PC_KOBJ_ID)) - new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_GET; + new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_GET; if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) { orangefs_attr = (struct orangefs_attribute *)attr; if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; + ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; else if (!strcmp(orangefs_attr->attr.name, "perf_time_interval_secs")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; + ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; else if (!strcmp(orangefs_attr->attr.name, "perf_counter_reset")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_RESET; + ORANGEFS_PARAM_REQUEST_OP_PERF_RESET; } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) { acache_attr = (struct acache_orangefs_attribute *)attr; if (!strcmp(acache_attr->attr.name, "timeout_msecs")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; if (!strcmp(acache_attr->attr.name, "hard_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; if (!strcmp(acache_attr->attr.name, "soft_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; if (!strcmp(acache_attr->attr.name, "reclaim_percentage")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) { capcache_attr = (struct capcache_orangefs_attribute *)attr; if (!strcmp(capcache_attr->attr.name, "timeout_secs")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; if (!strcmp(capcache_attr->attr.name, "hard_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; if (!strcmp(capcache_attr->attr.name, "soft_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; if (!strcmp(capcache_attr->attr.name, "reclaim_percentage")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) { ccache_attr = (struct ccache_orangefs_attribute *)attr; if (!strcmp(ccache_attr->attr.name, "timeout_secs")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; if (!strcmp(ccache_attr->attr.name, "hard_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; if (!strcmp(ccache_attr->attr.name, "soft_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; if (!strcmp(ccache_attr->attr.name, "reclaim_percentage")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) { ncache_attr = (struct ncache_orangefs_attribute *)attr; if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; if (!strcmp(ncache_attr->attr.name, "hard_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; if (!strcmp(ncache_attr->attr.name, "soft_limit")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; if (!strcmp(ncache_attr->attr.name, "reclaim_percentage")) new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; } else if (!strcmp(kobj_id, PC_KOBJ_ID)) { pc_attr = (struct pc_orangefs_attribute *)attr; if (!strcmp(pc_attr->attr.name, ACACHE_KOBJ_ID)) new_op->upcall.req.perf_count.type = - PVFS2_PERF_COUNT_REQUEST_ACACHE; + ORANGEFS_PERF_COUNT_REQUEST_ACACHE; if (!strcmp(pc_attr->attr.name, CAPCACHE_KOBJ_ID)) new_op->upcall.req.perf_count.type = - PVFS2_PERF_COUNT_REQUEST_CAPCACHE; + ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE; if (!strcmp(pc_attr->attr.name, NCACHE_KOBJ_ID)) new_op->upcall.req.perf_count.type = - PVFS2_PERF_COUNT_REQUEST_NCACHE; + ORANGEFS_PERF_COUNT_REQUEST_NCACHE; } else { gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n", @@ -905,15 +905,15 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) if (strcmp(kobj_id, PC_KOBJ_ID)) - ser_op_type = "pvfs2_param"; + ser_op_type = "orangefs_param"; else - ser_op_type = "pvfs2_perf_count"; + ser_op_type = "orangefs_perf_count"; /* * The service_operation will return an errno return code on * error, and zero on success. */ - rc = service_operation(new_op, ser_op_type, PVFS2_OP_INTERRUPTIBLE); + rc = service_operation(new_op, ser_op_type, ORANGEFS_OP_INTERRUPTIBLE); out: if (!rc) { @@ -1025,7 +1025,7 @@ static ssize_t */ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) { - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; int val = 0; int rc = 0; struct orangefs_attribute *orangefs_attr; @@ -1038,7 +1038,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "sysfs_service_op_store: id:%s:\n", kobj_id); - new_op = op_alloc(PVFS2_VFS_OP_PARAM); + new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); if (!new_op) { rc = -ENOMEM; goto out; @@ -1066,7 +1066,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) { if (val > 0) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; + ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; } else { rc = 0; goto out; @@ -1075,7 +1075,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "perf_time_interval_secs")) { if (val > 0) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; + ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; } else { rc = 0; goto out; @@ -1084,7 +1084,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "perf_counter_reset")) { if ((val == 0) || (val == 1)) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_PERF_RESET; + ORANGEFS_PARAM_REQUEST_OP_PERF_RESET; } else { rc = 0; goto out; @@ -1097,7 +1097,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) if (!strcmp(acache_attr->attr.name, "hard_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; } else { rc = 0; goto out; @@ -1105,7 +1105,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(acache_attr->attr.name, "soft_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; } else { rc = 0; goto out; @@ -1114,7 +1114,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "reclaim_percentage")) { if ((val > -1) && (val < 101)) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; } else { rc = 0; goto out; @@ -1122,7 +1122,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(acache_attr->attr.name, "timeout_msecs")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; + ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; } else { rc = 0; goto out; @@ -1135,7 +1135,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) if (!strcmp(capcache_attr->attr.name, "hard_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; } else { rc = 0; goto out; @@ -1143,7 +1143,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(capcache_attr->attr.name, "soft_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; } else { rc = 0; goto out; @@ -1152,7 +1152,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "reclaim_percentage")) { if ((val > -1) && (val < 101)) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; } else { rc = 0; goto out; @@ -1160,7 +1160,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(capcache_attr->attr.name, "timeout_secs")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; } else { rc = 0; goto out; @@ -1173,7 +1173,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) if (!strcmp(ccache_attr->attr.name, "hard_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; } else { rc = 0; goto out; @@ -1181,7 +1181,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(ccache_attr->attr.name, "soft_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; } else { rc = 0; goto out; @@ -1190,7 +1190,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "reclaim_percentage")) { if ((val > -1) && (val < 101)) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; } else { rc = 0; goto out; @@ -1198,7 +1198,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(ccache_attr->attr.name, "timeout_secs")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; + ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; } else { rc = 0; goto out; @@ -1211,7 +1211,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) if (!strcmp(ncache_attr->attr.name, "hard_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; } else { rc = 0; goto out; @@ -1219,7 +1219,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(ncache_attr->attr.name, "soft_limit")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; } else { rc = 0; goto out; @@ -1228,7 +1228,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) "reclaim_percentage")) { if ((val > -1) && (val < 101)) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; } else { rc = 0; goto out; @@ -1236,7 +1236,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } else if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) { if (val > -1) { new_op->upcall.req.param.op = - PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; + ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; } else { rc = 0; goto out; @@ -1250,7 +1250,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) goto out; } - new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET; + new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET; new_op->upcall.req.param.value = val; @@ -1258,7 +1258,7 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) * The service_operation will return a errno return code on * error, and zero on success. */ - rc = service_operation(new_op, "pvfs2_param", PVFS2_OP_INTERRUPTIBLE); + rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE); if (rc < 0) { gossip_err("sysfs_service_op_store: service op returned:%d:\n", diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/pvfs2-utils.c index 1180a2480d2b..d132c5f712a4 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/pvfs2-utils.c @@ -8,67 +8,67 @@ #include "pvfs2-dev-proto.h" #include "pvfs2-bufmap.h" -__s32 fsid_of_op(struct pvfs2_kernel_op_s *op) +__s32 fsid_of_op(struct orangefs_kernel_op_s *op) { - __s32 fsid = PVFS_FS_ID_NULL; + __s32 fsid = ORANGEFS_FS_ID_NULL; if (op) { switch (op->upcall.type) { - case PVFS2_VFS_OP_FILE_IO: + case ORANGEFS_VFS_OP_FILE_IO: fsid = op->upcall.req.io.refn.fs_id; break; - case PVFS2_VFS_OP_LOOKUP: + case ORANGEFS_VFS_OP_LOOKUP: fsid = op->upcall.req.lookup.parent_refn.fs_id; break; - case PVFS2_VFS_OP_CREATE: + case ORANGEFS_VFS_OP_CREATE: fsid = op->upcall.req.create.parent_refn.fs_id; break; - case PVFS2_VFS_OP_GETATTR: + case ORANGEFS_VFS_OP_GETATTR: fsid = op->upcall.req.getattr.refn.fs_id; break; - case PVFS2_VFS_OP_REMOVE: + case ORANGEFS_VFS_OP_REMOVE: fsid = op->upcall.req.remove.parent_refn.fs_id; break; - case PVFS2_VFS_OP_MKDIR: + case ORANGEFS_VFS_OP_MKDIR: fsid = op->upcall.req.mkdir.parent_refn.fs_id; break; - case PVFS2_VFS_OP_READDIR: + case ORANGEFS_VFS_OP_READDIR: fsid = op->upcall.req.readdir.refn.fs_id; break; - case PVFS2_VFS_OP_SETATTR: + case ORANGEFS_VFS_OP_SETATTR: fsid = op->upcall.req.setattr.refn.fs_id; break; - case PVFS2_VFS_OP_SYMLINK: + case ORANGEFS_VFS_OP_SYMLINK: fsid = op->upcall.req.sym.parent_refn.fs_id; break; - case PVFS2_VFS_OP_RENAME: + case ORANGEFS_VFS_OP_RENAME: fsid = op->upcall.req.rename.old_parent_refn.fs_id; break; - case PVFS2_VFS_OP_STATFS: + case ORANGEFS_VFS_OP_STATFS: fsid = op->upcall.req.statfs.fs_id; break; - case PVFS2_VFS_OP_TRUNCATE: + case ORANGEFS_VFS_OP_TRUNCATE: fsid = op->upcall.req.truncate.refn.fs_id; break; - case PVFS2_VFS_OP_MMAP_RA_FLUSH: + case ORANGEFS_VFS_OP_MMAP_RA_FLUSH: fsid = op->upcall.req.ra_cache_flush.refn.fs_id; break; - case PVFS2_VFS_OP_FS_UMOUNT: + case ORANGEFS_VFS_OP_FS_UMOUNT: fsid = op->upcall.req.fs_umount.fs_id; break; - case PVFS2_VFS_OP_GETXATTR: + case ORANGEFS_VFS_OP_GETXATTR: fsid = op->upcall.req.getxattr.refn.fs_id; break; - case PVFS2_VFS_OP_SETXATTR: + case ORANGEFS_VFS_OP_SETXATTR: fsid = op->upcall.req.setxattr.refn.fs_id; break; - case PVFS2_VFS_OP_LISTXATTR: + case ORANGEFS_VFS_OP_LISTXATTR: fsid = op->upcall.req.listxattr.refn.fs_id; break; - case PVFS2_VFS_OP_REMOVEXATTR: + case ORANGEFS_VFS_OP_REMOVEXATTR: fsid = op->upcall.req.removexattr.refn.fs_id; break; - case PVFS2_VFS_OP_FSYNC: + case ORANGEFS_VFS_OP_FSYNC: fsid = op->upcall.req.fsync.refn.fs_id; break; default: @@ -78,20 +78,20 @@ __s32 fsid_of_op(struct pvfs2_kernel_op_s *op) return fsid; } -static void pvfs2_set_inode_flags(struct inode *inode, - struct PVFS_sys_attr_s *attrs) +static void orangefs_set_inode_flags(struct inode *inode, + struct ORANGEFS_sys_attr_s *attrs) { - if (attrs->flags & PVFS_IMMUTABLE_FL) + if (attrs->flags & ORANGEFS_IMMUTABLE_FL) inode->i_flags |= S_IMMUTABLE; else inode->i_flags &= ~S_IMMUTABLE; - if (attrs->flags & PVFS_APPEND_FL) + if (attrs->flags & ORANGEFS_APPEND_FL) inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; - if (attrs->flags & PVFS_NOATIME_FL) + if (attrs->flags & ORANGEFS_NOATIME_FL) inode->i_flags |= S_NOATIME; else inode->i_flags &= ~S_NOATIME; @@ -100,12 +100,12 @@ static void pvfs2_set_inode_flags(struct inode *inode, /* NOTE: symname is ignored unless the inode is a sym link */ static int copy_attributes_to_inode(struct inode *inode, - struct PVFS_sys_attr_s *attrs, + struct ORANGEFS_sys_attr_s *attrs, char *symname) { int ret = -1; int perm_mode = 0; - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); loff_t inode_size = 0; loff_t rounded_up_size = 0; @@ -127,24 +127,24 @@ static int copy_attributes_to_inode(struct inode *inode, gossip_debug(GOSSIP_UTILS_DEBUG, "attrs->mask = %x (objtype = %s)\n", attrs->mask, - attrs->objtype == PVFS_TYPE_METAFILE ? "file" : - attrs->objtype == PVFS_TYPE_DIRECTORY ? "directory" : - attrs->objtype == PVFS_TYPE_SYMLINK ? "symlink" : + attrs->objtype == ORANGEFS_TYPE_METAFILE ? "file" : + attrs->objtype == ORANGEFS_TYPE_DIRECTORY ? "directory" : + attrs->objtype == ORANGEFS_TYPE_SYMLINK ? "symlink" : "invalid/unknown"); switch (attrs->objtype) { - case PVFS_TYPE_METAFILE: - pvfs2_set_inode_flags(inode, attrs); - if (attrs->mask & PVFS_ATTR_SYS_SIZE) { + case ORANGEFS_TYPE_METAFILE: + orangefs_set_inode_flags(inode, attrs); + if (attrs->mask & ORANGEFS_ATTR_SYS_SIZE) { inode_size = (loff_t) attrs->size; rounded_up_size = (inode_size + (4096 - (inode_size % 4096))); - pvfs2_lock_inode(inode); + orangefs_lock_inode(inode); inode->i_bytes = inode_size; inode->i_blocks = (unsigned long)(rounded_up_size / 512); - pvfs2_unlock_inode(inode); + orangefs_unlock_inode(inode); /* * NOTE: make sure all the places we're called @@ -155,7 +155,7 @@ static int copy_attributes_to_inode(struct inode *inode, inode->i_size = inode_size; } break; - case PVFS_TYPE_SYMLINK: + case ORANGEFS_TYPE_SYMLINK: if (symname != NULL) { inode->i_size = (loff_t) strlen(symname); break; @@ -164,9 +164,9 @@ static int copy_attributes_to_inode(struct inode *inode, default: inode->i_size = PAGE_CACHE_SIZE; - pvfs2_lock_inode(inode); + orangefs_lock_inode(inode); inode_set_bytes(inode, inode->i_size); - pvfs2_unlock_inode(inode); + orangefs_unlock_inode(inode); break; } @@ -179,30 +179,30 @@ static int copy_attributes_to_inode(struct inode *inode, inode->i_mtime.tv_nsec = 0; inode->i_ctime.tv_nsec = 0; - if (attrs->perms & PVFS_O_EXECUTE) + if (attrs->perms & ORANGEFS_O_EXECUTE) perm_mode |= S_IXOTH; - if (attrs->perms & PVFS_O_WRITE) + if (attrs->perms & ORANGEFS_O_WRITE) perm_mode |= S_IWOTH; - if (attrs->perms & PVFS_O_READ) + if (attrs->perms & ORANGEFS_O_READ) perm_mode |= S_IROTH; - if (attrs->perms & PVFS_G_EXECUTE) + if (attrs->perms & ORANGEFS_G_EXECUTE) perm_mode |= S_IXGRP; - if (attrs->perms & PVFS_G_WRITE) + if (attrs->perms & ORANGEFS_G_WRITE) perm_mode |= S_IWGRP; - if (attrs->perms & PVFS_G_READ) + if (attrs->perms & ORANGEFS_G_READ) perm_mode |= S_IRGRP; - if (attrs->perms & PVFS_U_EXECUTE) + if (attrs->perms & ORANGEFS_U_EXECUTE) perm_mode |= S_IXUSR; - if (attrs->perms & PVFS_U_WRITE) + if (attrs->perms & ORANGEFS_U_WRITE) perm_mode |= S_IWUSR; - if (attrs->perms & PVFS_U_READ) + if (attrs->perms & ORANGEFS_U_READ) perm_mode |= S_IRUSR; - if (attrs->perms & PVFS_G_SGID) + if (attrs->perms & ORANGEFS_G_SGID) perm_mode |= S_ISGID; - if (attrs->perms & PVFS_U_SUID) + if (attrs->perms & ORANGEFS_U_SUID) perm_mode |= S_ISUID; inode->i_mode = perm_mode; @@ -216,11 +216,11 @@ static int copy_attributes_to_inode(struct inode *inode, } switch (attrs->objtype) { - case PVFS_TYPE_METAFILE: + case ORANGEFS_TYPE_METAFILE: inode->i_mode |= S_IFREG; ret = 0; break; - case PVFS_TYPE_DIRECTORY: + case ORANGEFS_TYPE_DIRECTORY: inode->i_mode |= S_IFDIR; /* NOTE: we have no good way to keep nlink consistent * for directories across clients; keep constant at 1. @@ -230,17 +230,17 @@ static int copy_attributes_to_inode(struct inode *inode, set_nlink(inode, 1); ret = 0; break; - case PVFS_TYPE_SYMLINK: + case ORANGEFS_TYPE_SYMLINK: inode->i_mode |= S_IFLNK; /* copy link target to inode private data */ - if (pvfs2_inode && symname) { - strncpy(pvfs2_inode->link_target, + if (orangefs_inode && symname) { + strncpy(orangefs_inode->link_target, symname, - PVFS_NAME_MAX); + ORANGEFS_NAME_MAX); gossip_debug(GOSSIP_UTILS_DEBUG, "Copied attr link target %s\n", - pvfs2_inode->link_target); + orangefs_inode->link_target); } gossip_debug(GOSSIP_UTILS_DEBUG, "symlink mode %o\n", @@ -248,12 +248,12 @@ static int copy_attributes_to_inode(struct inode *inode, ret = 0; break; default: - gossip_err("pvfs2: copy_attributes_to_inode: got invalid attribute type %x\n", + gossip_err("orangefs: copy_attributes_to_inode: got invalid attribute type %x\n", attrs->objtype); } gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n", + "orangefs: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n", inode->i_mode, (unsigned long)i_size_read(inode)); @@ -265,7 +265,7 @@ static int copy_attributes_to_inode(struct inode *inode, * anything, so don't bother copying it into the sys_attr object here. */ static inline int copy_attributes_from_inode(struct inode *inode, - struct PVFS_sys_attr_s *attrs, + struct ORANGEFS_sys_attr_s *attrs, struct iattr *iattr) { umode_t tmp_mode; @@ -285,36 +285,36 @@ static inline int copy_attributes_from_inode(struct inode *inode, attrs->mask = 0; if (iattr->ia_valid & ATTR_UID) { attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid); - attrs->mask |= PVFS_ATTR_SYS_UID; + attrs->mask |= ORANGEFS_ATTR_SYS_UID; gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner); } if (iattr->ia_valid & ATTR_GID) { attrs->group = from_kgid(current_user_ns(), iattr->ia_gid); - attrs->mask |= PVFS_ATTR_SYS_GID; + attrs->mask |= ORANGEFS_ATTR_SYS_GID; gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group); } if (iattr->ia_valid & ATTR_ATIME) { - attrs->mask |= PVFS_ATTR_SYS_ATIME; + attrs->mask |= ORANGEFS_ATTR_SYS_ATIME; if (iattr->ia_valid & ATTR_ATIME_SET) { attrs->atime = - pvfs2_convert_time_field(&iattr->ia_atime); - attrs->mask |= PVFS_ATTR_SYS_ATIME_SET; + orangefs_convert_time_field(&iattr->ia_atime); + attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET; } } if (iattr->ia_valid & ATTR_MTIME) { - attrs->mask |= PVFS_ATTR_SYS_MTIME; + attrs->mask |= ORANGEFS_ATTR_SYS_MTIME; if (iattr->ia_valid & ATTR_MTIME_SET) { attrs->mtime = - pvfs2_convert_time_field(&iattr->ia_mtime); - attrs->mask |= PVFS_ATTR_SYS_MTIME_SET; + orangefs_convert_time_field(&iattr->ia_mtime); + attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET; } } if (iattr->ia_valid & ATTR_CTIME) - attrs->mask |= PVFS_ATTR_SYS_CTIME; + attrs->mask |= ORANGEFS_ATTR_SYS_CTIME; /* - * PVFS2 cannot set size with a setattr operation. Probably not likely + * ORANGEFS cannot set size with a setattr operation. Probably not likely * to be requested through the VFS, but just in case, don't worry about * ATTR_SIZE */ @@ -342,21 +342,21 @@ static inline int copy_attributes_from_inode(struct inode *inode, return -EINVAL; } - attrs->perms = PVFS_util_translate_mode(tmp_mode); - attrs->mask |= PVFS_ATTR_SYS_PERM; + attrs->perms = ORANGEFS_util_translate_mode(tmp_mode); + attrs->mask |= ORANGEFS_ATTR_SYS_PERM; } return 0; } /* - * issues a pvfs2 getattr request and fills in the appropriate inode + * issues a orangefs getattr request and fills in the appropriate inode * attributes if successful. returns 0 on success; -errno otherwise */ -int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) +int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op; int ret = -EINVAL; gossip_debug(GOSSIP_UTILS_DEBUG, @@ -364,10 +364,10 @@ int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) __func__, get_khandle_from_ino(inode)); - new_op = op_alloc(PVFS2_VFS_OP_GETATTR); + new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); if (!new_op) return -ENOMEM; - new_op->upcall.req.getattr.refn = pvfs2_inode->refn; + new_op->upcall.req.getattr.refn = orangefs_inode->refn; new_op->upcall.req.getattr.mask = getattr_mask; ret = service_operation(new_op, __func__, @@ -384,17 +384,17 @@ int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) } /* - * Store blksize in pvfs2 specific part of inode structure; we are + * Store blksize in orangefs specific part of inode structure; we are * only going to use this to report to stat to make sure it doesn't * perturb any inode related code paths. */ if (new_op->downcall.resp.getattr.attributes.objtype == - PVFS_TYPE_METAFILE) { - pvfs2_inode->blksize = + ORANGEFS_TYPE_METAFILE) { + orangefs_inode->blksize = new_op->downcall.resp.getattr.attributes.blksize; } else { /* mimic behavior of generic_fillattr() for other types. */ - pvfs2_inode->blksize = (1 << inode->i_blkbits); + orangefs_inode->blksize = (1 << inode->i_blkbits); } @@ -402,8 +402,8 @@ int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) gossip_debug(GOSSIP_UTILS_DEBUG, "Getattr on handle %pU, " "fsid %d\n (inode ct = %d) returned %d\n", - &pvfs2_inode->refn.khandle, - pvfs2_inode->refn.fs_id, + &orangefs_inode->refn.khandle, + orangefs_inode->refn.fs_id, (int)atomic_read(&inode->i_count), ret); @@ -412,20 +412,20 @@ int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask) } /* - * issues a pvfs2 setattr request to make sure the new attribute values + * issues a orangefs setattr request to make sure the new attribute values * take effect if successful. returns 0 on success; -errno otherwise */ -int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr) +int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op; int ret; - new_op = op_alloc(PVFS2_VFS_OP_SETATTR); + new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR); if (!new_op) return -ENOMEM; - new_op->upcall.req.setattr.refn = pvfs2_inode->refn; + new_op->upcall.req.setattr.refn = orangefs_inode->refn; ret = copy_attributes_from_inode(inode, &new_op->upcall.req.setattr.attributes, iattr); @@ -438,7 +438,7 @@ int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr) get_interruptible_flag(inode)); gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_inode_setattr: returning %d\n", + "orangefs_inode_setattr: returning %d\n", ret); /* when request is serviced properly, free req op struct */ @@ -449,16 +449,16 @@ int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr) * ctime flags. */ if (ret == 0) { - ClearAtimeFlag(pvfs2_inode); - ClearMtimeFlag(pvfs2_inode); - ClearCtimeFlag(pvfs2_inode); - ClearModeFlag(pvfs2_inode); + ClearAtimeFlag(orangefs_inode); + ClearMtimeFlag(orangefs_inode); + ClearCtimeFlag(orangefs_inode); + ClearModeFlag(orangefs_inode); } return ret; } -int pvfs2_flush_inode(struct inode *inode) +int orangefs_flush_inode(struct inode *inode) { /* * If it is a dirty inode, this function gets called. @@ -472,7 +472,7 @@ int pvfs2_flush_inode(struct inode *inode) int ctime_flag; int atime_flag; int mode_flag; - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); memset(&wbattr, 0, sizeof(wbattr)); @@ -481,14 +481,14 @@ int pvfs2_flush_inode(struct inode *inode) * will prevent multiple processes from all trying to flush the same * inode if they call close() simultaneously */ - mtime_flag = MtimeFlag(pvfs2_inode); - ClearMtimeFlag(pvfs2_inode); - ctime_flag = CtimeFlag(pvfs2_inode); - ClearCtimeFlag(pvfs2_inode); - atime_flag = AtimeFlag(pvfs2_inode); - ClearAtimeFlag(pvfs2_inode); - mode_flag = ModeFlag(pvfs2_inode); - ClearModeFlag(pvfs2_inode); + mtime_flag = MtimeFlag(orangefs_inode); + ClearMtimeFlag(orangefs_inode); + ctime_flag = CtimeFlag(orangefs_inode); + ClearCtimeFlag(orangefs_inode); + atime_flag = AtimeFlag(orangefs_inode); + ClearAtimeFlag(orangefs_inode); + mode_flag = ModeFlag(orangefs_inode); + ClearModeFlag(orangefs_inode); /* -- Lazy atime,mtime and ctime update -- * Note: all times are dictated by server in the new scheme @@ -510,56 +510,56 @@ int pvfs2_flush_inode(struct inode *inode) } gossip_debug(GOSSIP_UTILS_DEBUG, - "*********** pvfs2_flush_inode: %pU " + "*********** orangefs_flush_inode: %pU " "(ia_valid %d)\n", get_khandle_from_ino(inode), wbattr.ia_valid); if (wbattr.ia_valid == 0) { gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_flush_inode skipping setattr()\n"); + "orangefs_flush_inode skipping setattr()\n"); return 0; } gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_flush_inode (%pU) writing mode %o\n", + "orangefs_flush_inode (%pU) writing mode %o\n", get_khandle_from_ino(inode), inode->i_mode); - ret = pvfs2_inode_setattr(inode, &wbattr); + ret = orangefs_inode_setattr(inode, &wbattr); return ret; } -int pvfs2_unmount_sb(struct super_block *sb) +int orangefs_unmount_sb(struct super_block *sb) { int ret = -EINVAL; - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_unmount_sb called on sb %p\n", + "orangefs_unmount_sb called on sb %p\n", sb); - new_op = op_alloc(PVFS2_VFS_OP_FS_UMOUNT); + new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT); if (!new_op) return -ENOMEM; - new_op->upcall.req.fs_umount.id = PVFS2_SB(sb)->id; - new_op->upcall.req.fs_umount.fs_id = PVFS2_SB(sb)->fs_id; - strncpy(new_op->upcall.req.fs_umount.pvfs2_config_server, - PVFS2_SB(sb)->devname, - PVFS_MAX_SERVER_ADDR_LEN); + new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id; + new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id; + strncpy(new_op->upcall.req.fs_umount.orangefs_config_server, + ORANGEFS_SB(sb)->devname, + ORANGEFS_MAX_SERVER_ADDR_LEN); gossip_debug(GOSSIP_UTILS_DEBUG, - "Attempting PVFS2 Unmount via host %s\n", - new_op->upcall.req.fs_umount.pvfs2_config_server); + "Attempting ORANGEFS Unmount via host %s\n", + new_op->upcall.req.fs_umount.orangefs_config_server); - ret = service_operation(new_op, "pvfs2_fs_umount", 0); + ret = service_operation(new_op, "orangefs_fs_umount", 0); gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_unmount: got return value of %d\n", ret); + "orangefs_unmount: got return value of %d\n", ret); if (ret) sb = ERR_PTR(ret); else - PVFS2_SB(sb)->mount_pending = 1; + ORANGEFS_SB(sb)->mount_pending = 1; op_release(new_op); return ret; @@ -569,42 +569,42 @@ int pvfs2_unmount_sb(struct super_block *sb) * NOTE: on successful cancellation, be sure to return -EINTR, as * that's the return value the caller expects */ -int pvfs2_cancel_op_in_progress(__u64 tag) +int orangefs_cancel_op_in_progress(__u64 tag) { int ret = -EINVAL; - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_cancel_op_in_progress called on tag %llu\n", + "orangefs_cancel_op_in_progress called on tag %llu\n", llu(tag)); - new_op = op_alloc(PVFS2_VFS_OP_CANCEL); + new_op = op_alloc(ORANGEFS_VFS_OP_CANCEL); if (!new_op) return -ENOMEM; new_op->upcall.req.cancel.op_tag = tag; gossip_debug(GOSSIP_UTILS_DEBUG, - "Attempting PVFS2 operation cancellation of tag %llu\n", + "Attempting ORANGEFS operation cancellation of tag %llu\n", llu(new_op->upcall.req.cancel.op_tag)); - ret = service_operation(new_op, "pvfs2_cancel", PVFS2_OP_CANCELLATION); + ret = service_operation(new_op, "orangefs_cancel", ORANGEFS_OP_CANCELLATION); gossip_debug(GOSSIP_UTILS_DEBUG, - "pvfs2_cancel_op_in_progress: got return value of %d\n", + "orangefs_cancel_op_in_progress: got return value of %d\n", ret); op_release(new_op); return ret; } -void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op) +void orangefs_op_initialize(struct orangefs_kernel_op_s *op) { if (op) { spin_lock(&op->lock); op->io_completed = 0; - op->upcall.type = PVFS2_VFS_OP_INVALID; - op->downcall.type = PVFS2_VFS_OP_INVALID; + op->upcall.type = ORANGEFS_VFS_OP_INVALID; + op->downcall.type = ORANGEFS_VFS_OP_INVALID; op->downcall.status = -1; op->op_state = OP_VFS_STATE_UNKNOWN; @@ -613,7 +613,7 @@ void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op) } } -void pvfs2_make_bad_inode(struct inode *inode) +void orangefs_make_bad_inode(struct inode *inode) { if (is_root_handle(inode)) { /* @@ -655,10 +655,10 @@ void set_signals(sigset_t *sigset) /* * The following is a very dirty hack that is now a permanent part of the - * PVFS2 protocol. See protocol.h for more error definitions. + * ORANGEFS protocol. See protocol.h for more error definitions. */ -/* The order matches include/pvfs2-types.h in the OrangeFS source. */ +/* The order matches include/orangefs-types.h in the OrangeFS source. */ static int PINT_errno_mapping[] = { 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM, EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE, @@ -672,7 +672,7 @@ static int PINT_errno_mapping[] = { EACCES, ECONNRESET, ERANGE }; -int pvfs2_normalize_to_errno(__s32 error_code) +int orangefs_normalize_to_errno(__s32 error_code) { __u32 i; @@ -684,24 +684,24 @@ int pvfs2_normalize_to_errno(__s32 error_code) * server. */ } else if (error_code > 0) { - gossip_err("pvfs2: error status receieved.\n"); - gossip_err("pvfs2: assuming error code is inverted.\n"); + gossip_err("orangefs: error status receieved.\n"); + gossip_err("orangefs: assuming error code is inverted.\n"); error_code = -error_code; } /* - * XXX: This is very bad since error codes from PVFS2 may not be + * XXX: This is very bad since error codes from ORANGEFS may not be * suitable for return into userspace. */ /* - * Convert PVFS2 error values into errno values suitable for return + * Convert ORANGEFS error values into errno values suitable for return * from the kernel. */ - if ((-error_code) & PVFS_NON_ERRNO_ERROR_BIT) { + if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) { if (((-error_code) & - (PVFS_ERROR_NUMBER_BITS|PVFS_NON_ERRNO_ERROR_BIT| - PVFS_ERROR_BIT)) == PVFS_ECANCEL) { + (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT| + ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) { /* * cancellation error codes generally correspond to * a timeout from the client's perspective @@ -709,30 +709,30 @@ int pvfs2_normalize_to_errno(__s32 error_code) error_code = -ETIMEDOUT; } else { /* assume a default error code */ - gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n", error_code); + gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code); error_code = -EINVAL; } - /* Convert PVFS2 encoded errno values into regular errno values. */ - } else if ((-error_code) & PVFS_ERROR_BIT) { - i = (-error_code) & ~(PVFS_ERROR_BIT|PVFS_ERROR_CLASS_BITS); + /* Convert ORANGEFS encoded errno values into regular errno values. */ + } else if ((-error_code) & ORANGEFS_ERROR_BIT) { + i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS); if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping)) error_code = -PINT_errno_mapping[i]; else error_code = -EINVAL; /* - * Only PVFS2 protocol error codes should ever come here. Otherwise + * Only ORANGEFS protocol error codes should ever come here. Otherwise * there is a bug somewhere. */ } else { - gossip_err("pvfs2: pvfs2_normalize_to_errno: got error code which is not from PVFS2.\n"); + gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n"); } return error_code; } #define NUM_MODES 11 -__s32 PVFS_util_translate_mode(int mode) +__s32 ORANGEFS_util_translate_mode(int mode) { int ret = 0; int i = 0; @@ -742,16 +742,16 @@ __s32 PVFS_util_translate_mode(int mode) S_IXUSR, S_IWUSR, S_IRUSR, S_ISGID, S_ISUID }; - static int pvfs2_modes[NUM_MODES] = { - PVFS_O_EXECUTE, PVFS_O_WRITE, PVFS_O_READ, - PVFS_G_EXECUTE, PVFS_G_WRITE, PVFS_G_READ, - PVFS_U_EXECUTE, PVFS_U_WRITE, PVFS_U_READ, - PVFS_G_SGID, PVFS_U_SUID + static int orangefs_modes[NUM_MODES] = { + ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ, + ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ, + ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ, + ORANGEFS_G_SGID, ORANGEFS_U_SUID }; for (i = 0; i < NUM_MODES; i++) if (mode & modes[i]) - ret |= pvfs2_modes[i]; + ret |= orangefs_modes[i]; return ret; } @@ -813,10 +813,10 @@ int orangefs_prepare_cdm_array(char *debug_array_string) (unsigned long long *)&(cdm_array[i].mask1), (unsigned long long *)&(cdm_array[i].mask2)); - if (!strcmp(cdm_array[i].keyword, PVFS2_VERBOSE)) + if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE)) client_verbose_index = i; - if (!strcmp(cdm_array[i].keyword, PVFS2_ALL)) + if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL)) client_all_index = i; cds_head = cds_delimiter + 1; @@ -952,7 +952,7 @@ void debug_mask_to_string(void *mask, int type) element_count = num_kmod_keyword_mask_map; } - memset(debug_string, 0, PVFS2_MAX_DEBUG_STRING_LEN); + memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); /* * Some keywords, like "all" or "verbose", are amalgams of @@ -998,13 +998,13 @@ void do_k_string(void *k_mask, int index) if (*mask & s_kmod_keyword_mask_map[index].mask_val) { if ((strlen(kernel_debug_string) + strlen(s_kmod_keyword_mask_map[index].keyword)) - < PVFS2_MAX_DEBUG_STRING_LEN - 1) { + < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) { strcat(kernel_debug_string, s_kmod_keyword_mask_map[index].keyword); strcat(kernel_debug_string, ","); } else { gossip_err("%s: overflow!\n", __func__); - strcpy(kernel_debug_string, PVFS2_ALL); + strcpy(kernel_debug_string, ORANGEFS_ALL); goto out; } } @@ -1025,13 +1025,13 @@ void do_c_string(void *c_mask, int index) (mask->mask2 & cdm_array[index].mask2)) { if ((strlen(client_debug_string) + strlen(cdm_array[index].keyword) + 1) - < PVFS2_MAX_DEBUG_STRING_LEN - 2) { + < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) { strcat(client_debug_string, cdm_array[index].keyword); strcat(client_debug_string, ","); } else { gossip_err("%s: overflow!\n", __func__); - strcpy(client_debug_string, PVFS2_ALL); + strcpy(client_debug_string, ORANGEFS_ALL); goto out; } } @@ -1043,7 +1043,7 @@ int keyword_is_amalgam(char *keyword) { int rc = 0; - if ((!strcmp(keyword, PVFS2_ALL)) || (!strcmp(keyword, PVFS2_VERBOSE))) + if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE))) rc = 1; return rc; @@ -1067,14 +1067,14 @@ int check_amalgam_keyword(void *mask, int type) if ((c_mask->mask1 == cdm_array[client_all_index].mask1) && (c_mask->mask2 == cdm_array[client_all_index].mask2)) { - strcpy(client_debug_string, PVFS2_ALL); + strcpy(client_debug_string, ORANGEFS_ALL); rc = 1; goto out; } if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) && (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) { - strcpy(client_debug_string, PVFS2_VERBOSE); + strcpy(client_debug_string, ORANGEFS_VERBOSE); rc = 1; goto out; } @@ -1083,7 +1083,7 @@ int check_amalgam_keyword(void *mask, int type) k_mask = (__u64 *) mask; if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) { - strcpy(kernel_debug_string, PVFS2_ALL); + strcpy(kernel_debug_string, ORANGEFS_ALL); rc = 1; goto out; } diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 45db0772a767..c104de1ae5de 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -10,13 +10,13 @@ #include -/* a cache for pvfs2-inode objects (i.e. pvfs2 inode private data) */ -static struct kmem_cache *pvfs2_inode_cache; +/* a cache for orangefs-inode objects (i.e. orangefs inode private data) */ +static struct kmem_cache *orangefs_inode_cache; -/* list for storing pvfs2 specific superblocks in use */ -LIST_HEAD(pvfs2_superblocks); +/* list for storing orangefs specific superblocks in use */ +LIST_HEAD(orangefs_superblocks); -DEFINE_SPINLOCK(pvfs2_superblocks_lock); +DEFINE_SPINLOCK(orangefs_superblocks_lock); enum { Opt_intr, @@ -37,7 +37,7 @@ static const match_table_t tokens = { static int parse_mount_options(struct super_block *sb, char *options, int silent) { - struct pvfs2_sb_info_s *pvfs2_sb = PVFS2_SB(sb); + struct orangefs_sb_info_s *orangefs_sb = ORANGEFS_SB(sb); substring_t args[MAX_OPT_ARGS]; char *p; @@ -46,8 +46,8 @@ static int parse_mount_options(struct super_block *sb, char *options, * to zero, ie, initialize to unset. */ sb->s_flags &= ~MS_POSIXACL; - pvfs2_sb->flags &= ~PVFS2_OPT_INTR; - pvfs2_sb->flags &= ~PVFS2_OPT_LOCAL_LOCK; + orangefs_sb->flags &= ~ORANGEFS_OPT_INTR; + orangefs_sb->flags &= ~ORANGEFS_OPT_LOCAL_LOCK; while ((p = strsep(&options, ",")) != NULL) { int token; @@ -61,10 +61,10 @@ static int parse_mount_options(struct super_block *sb, char *options, sb->s_flags |= MS_POSIXACL; break; case Opt_intr: - pvfs2_sb->flags |= PVFS2_OPT_INTR; + orangefs_sb->flags |= ORANGEFS_OPT_INTR; break; case Opt_local_lock: - pvfs2_sb->flags |= PVFS2_OPT_LOCAL_LOCK; + orangefs_sb->flags |= ORANGEFS_OPT_LOCAL_LOCK; break; default: goto fail; @@ -78,24 +78,24 @@ static int parse_mount_options(struct super_block *sb, char *options, return -EINVAL; } -static void pvfs2_inode_cache_ctor(void *req) +static void orangefs_inode_cache_ctor(void *req) { - struct pvfs2_inode_s *pvfs2_inode = req; + struct orangefs_inode_s *orangefs_inode = req; - inode_init_once(&pvfs2_inode->vfs_inode); - init_rwsem(&pvfs2_inode->xattr_sem); + inode_init_once(&orangefs_inode->vfs_inode); + init_rwsem(&orangefs_inode->xattr_sem); - pvfs2_inode->vfs_inode.i_version = 1; + orangefs_inode->vfs_inode.i_version = 1; } -static struct inode *pvfs2_alloc_inode(struct super_block *sb) +static struct inode *orangefs_alloc_inode(struct super_block *sb) { - struct pvfs2_inode_s *pvfs2_inode; + struct orangefs_inode_s *orangefs_inode; - pvfs2_inode = kmem_cache_alloc(pvfs2_inode_cache, - PVFS2_CACHE_ALLOC_FLAGS); - if (pvfs2_inode == NULL) { - gossip_err("Failed to allocate pvfs2_inode\n"); + orangefs_inode = kmem_cache_alloc(orangefs_inode_cache, + ORANGEFS_CACHE_ALLOC_FLAGS); + if (orangefs_inode == NULL) { + gossip_err("Failed to allocate orangefs_inode\n"); return NULL; } @@ -103,71 +103,71 @@ static struct inode *pvfs2_alloc_inode(struct super_block *sb) * We want to clear everything except for rw_semaphore and the * vfs_inode. */ - memset(&pvfs2_inode->refn.khandle, 0, 16); - pvfs2_inode->refn.fs_id = PVFS_FS_ID_NULL; - pvfs2_inode->last_failed_block_index_read = 0; - memset(pvfs2_inode->link_target, 0, sizeof(pvfs2_inode->link_target)); - pvfs2_inode->pinode_flags = 0; + memset(&orangefs_inode->refn.khandle, 0, 16); + orangefs_inode->refn.fs_id = ORANGEFS_FS_ID_NULL; + orangefs_inode->last_failed_block_index_read = 0; + memset(orangefs_inode->link_target, 0, sizeof(orangefs_inode->link_target)); + orangefs_inode->pinode_flags = 0; gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_alloc_inode: allocated %p\n", - &pvfs2_inode->vfs_inode); - return &pvfs2_inode->vfs_inode; + "orangefs_alloc_inode: allocated %p\n", + &orangefs_inode->vfs_inode); + return &orangefs_inode->vfs_inode; } -static void pvfs2_destroy_inode(struct inode *inode) +static void orangefs_destroy_inode(struct inode *inode) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); gossip_debug(GOSSIP_SUPER_DEBUG, "%s: deallocated %p destroying inode %pU\n", - __func__, pvfs2_inode, get_khandle_from_ino(inode)); + __func__, orangefs_inode, get_khandle_from_ino(inode)); - kmem_cache_free(pvfs2_inode_cache, pvfs2_inode); + kmem_cache_free(orangefs_inode_cache, orangefs_inode); } /* * NOTE: information filled in here is typically reflected in the * output of the system command 'df' */ -static int pvfs2_statfs(struct dentry *dentry, struct kstatfs *buf) +static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf) { int ret = -ENOMEM; - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_kernel_op_s *new_op = NULL; int flags = 0; struct super_block *sb = NULL; sb = dentry->d_sb; gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_statfs: called on sb %p (fs_id is %d)\n", + "orangefs_statfs: called on sb %p (fs_id is %d)\n", sb, - (int)(PVFS2_SB(sb)->fs_id)); + (int)(ORANGEFS_SB(sb)->fs_id)); - new_op = op_alloc(PVFS2_VFS_OP_STATFS); + new_op = op_alloc(ORANGEFS_VFS_OP_STATFS); if (!new_op) return ret; - new_op->upcall.req.statfs.fs_id = PVFS2_SB(sb)->fs_id; + new_op->upcall.req.statfs.fs_id = ORANGEFS_SB(sb)->fs_id; - if (PVFS2_SB(sb)->flags & PVFS2_OPT_INTR) - flags = PVFS2_OP_INTERRUPTIBLE; + if (ORANGEFS_SB(sb)->flags & ORANGEFS_OPT_INTR) + flags = ORANGEFS_OP_INTERRUPTIBLE; - ret = service_operation(new_op, "pvfs2_statfs", flags); + ret = service_operation(new_op, "orangefs_statfs", flags); if (new_op->downcall.status < 0) goto out_op_release; gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_statfs: got %ld blocks available | " + "orangefs_statfs: got %ld blocks available | " "%ld blocks total | %ld block size\n", (long)new_op->downcall.resp.statfs.blocks_avail, (long)new_op->downcall.resp.statfs.blocks_total, (long)new_op->downcall.resp.statfs.block_size); buf->f_type = sb->s_magic; - memcpy(&buf->f_fsid, &PVFS2_SB(sb)->fs_id, sizeof(buf->f_fsid)); + memcpy(&buf->f_fsid, &ORANGEFS_SB(sb)->fs_id, sizeof(buf->f_fsid)); buf->f_bsize = new_op->downcall.resp.statfs.block_size; - buf->f_namelen = PVFS2_NAME_LEN; + buf->f_namelen = ORANGEFS_NAME_LEN; buf->f_blocks = (sector_t) new_op->downcall.resp.statfs.blocks_total; buf->f_bfree = (sector_t) new_op->downcall.resp.statfs.blocks_avail; @@ -178,7 +178,7 @@ static int pvfs2_statfs(struct dentry *dentry, struct kstatfs *buf) out_op_release: op_release(new_op); - gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_statfs: returning %d\n", ret); + gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_statfs: returning %d\n", ret); return ret; } @@ -186,9 +186,9 @@ static int pvfs2_statfs(struct dentry *dentry, struct kstatfs *buf) * Remount as initiated by VFS layer. We just need to reparse the mount * options, no need to signal pvfs2-client-core about it. */ -static int pvfs2_remount_fs(struct super_block *sb, int *flags, char *data) +static int orangefs_remount_fs(struct super_block *sb, int *flags, char *data) { - gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount_fs: called\n"); + gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_remount_fs: called\n"); return parse_mount_options(sb, data, 1); } @@ -207,33 +207,33 @@ static int pvfs2_remount_fs(struct super_block *sb, int *flags, char *data) * the client regains all of the mount information from us. * NOTE: this function assumes that the request_mutex is already acquired! */ -int pvfs2_remount(struct super_block *sb) +int orangefs_remount(struct super_block *sb) { - struct pvfs2_kernel_op_s *new_op; + struct orangefs_kernel_op_s *new_op; int ret = -EINVAL; - gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_remount: called\n"); + gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_remount: called\n"); - new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT); + new_op = op_alloc(ORANGEFS_VFS_OP_FS_MOUNT); if (!new_op) return -ENOMEM; - strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server, - PVFS2_SB(sb)->devname, - PVFS_MAX_SERVER_ADDR_LEN); + strncpy(new_op->upcall.req.fs_mount.orangefs_config_server, + ORANGEFS_SB(sb)->devname, + ORANGEFS_MAX_SERVER_ADDR_LEN); gossip_debug(GOSSIP_SUPER_DEBUG, - "Attempting PVFS2 Remount via host %s\n", - new_op->upcall.req.fs_mount.pvfs2_config_server); + "Attempting ORANGEFS Remount via host %s\n", + new_op->upcall.req.fs_mount.orangefs_config_server); /* * we assume that the calling function has already acquire the * request_mutex to prevent other operations from bypassing * this one */ - ret = service_operation(new_op, "pvfs2_remount", - PVFS2_OP_PRIORITY | PVFS2_OP_NO_SEMAPHORE); + ret = service_operation(new_op, "orangefs_remount", + ORANGEFS_OP_PRIORITY | ORANGEFS_OP_NO_SEMAPHORE); gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_remount: mount got return value of %d\n", + "orangefs_remount: mount got return value of %d\n", ret); if (ret == 0) { /* @@ -241,8 +241,8 @@ int pvfs2_remount(struct super_block *sb) * short-lived mapping that the system interface uses * to map this superblock to a particular mount entry */ - PVFS2_SB(sb)->id = new_op->downcall.resp.fs_mount.id; - PVFS2_SB(sb)->mount_pending = 0; + ORANGEFS_SB(sb)->id = new_op->downcall.resp.fs_mount.id; + ORANGEFS_SB(sb)->mount_pending = 0; } op_release(new_op); @@ -259,54 +259,54 @@ void fsid_key_table_finalize(void) } /* Called whenever the VFS dirties the inode in response to atime updates */ -static void pvfs2_dirty_inode(struct inode *inode, int flags) +static void orangefs_dirty_inode(struct inode *inode, int flags) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_dirty_inode: %pU\n", + "orangefs_dirty_inode: %pU\n", get_khandle_from_ino(inode)); - SetAtimeFlag(pvfs2_inode); + SetAtimeFlag(orangefs_inode); } -static const struct super_operations pvfs2_s_ops = { - .alloc_inode = pvfs2_alloc_inode, - .destroy_inode = pvfs2_destroy_inode, - .dirty_inode = pvfs2_dirty_inode, +static const struct super_operations orangefs_s_ops = { + .alloc_inode = orangefs_alloc_inode, + .destroy_inode = orangefs_destroy_inode, + .dirty_inode = orangefs_dirty_inode, .drop_inode = generic_delete_inode, - .statfs = pvfs2_statfs, - .remount_fs = pvfs2_remount_fs, + .statfs = orangefs_statfs, + .remount_fs = orangefs_remount_fs, .show_options = generic_show_options, }; -static struct dentry *pvfs2_fh_to_dentry(struct super_block *sb, +static struct dentry *orangefs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { - struct pvfs2_object_kref refn; + struct orangefs_object_kref refn; if (fh_len < 5 || fh_type > 2) return NULL; - PVFS_khandle_from(&(refn.khandle), fid->raw, 16); + ORANGEFS_khandle_from(&(refn.khandle), fid->raw, 16); refn.fs_id = (u32) fid->raw[4]; gossip_debug(GOSSIP_SUPER_DEBUG, "fh_to_dentry: handle %pU, fs_id %d\n", &refn.khandle, refn.fs_id); - return d_obtain_alias(pvfs2_iget(sb, &refn)); + return d_obtain_alias(orangefs_iget(sb, &refn)); } -static int pvfs2_encode_fh(struct inode *inode, +static int orangefs_encode_fh(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent) { int len = parent ? 10 : 5; int type = 1; - struct pvfs2_object_kref refn; + struct orangefs_object_kref refn; if (*max_len < len) { gossip_lerr("fh buffer is too small for encoding\n"); @@ -315,8 +315,8 @@ static int pvfs2_encode_fh(struct inode *inode, goto out; } - refn = PVFS2_I(inode)->refn; - PVFS_khandle_to(&refn.khandle, fh, 16); + refn = ORANGEFS_I(inode)->refn; + ORANGEFS_khandle_to(&refn.khandle, fh, 16); fh[4] = refn.fs_id; gossip_debug(GOSSIP_SUPER_DEBUG, @@ -326,8 +326,8 @@ static int pvfs2_encode_fh(struct inode *inode, if (parent) { - refn = PVFS2_I(parent)->refn; - PVFS_khandle_to(&refn.khandle, (char *) fh + 20, 16); + refn = ORANGEFS_I(parent)->refn; + ORANGEFS_khandle_to(&refn.khandle, (char *) fh + 20, 16); fh[9] = refn.fs_id; type = 2; @@ -342,30 +342,30 @@ static int pvfs2_encode_fh(struct inode *inode, return type; } -static struct export_operations pvfs2_export_ops = { - .encode_fh = pvfs2_encode_fh, - .fh_to_dentry = pvfs2_fh_to_dentry, +static struct export_operations orangefs_export_ops = { + .encode_fh = orangefs_encode_fh, + .fh_to_dentry = orangefs_fh_to_dentry, }; -static int pvfs2_fill_sb(struct super_block *sb, - struct pvfs2_fs_mount_response *fs_mount, +static int orangefs_fill_sb(struct super_block *sb, + struct orangefs_fs_mount_response *fs_mount, void *data, int silent) { int ret = -EINVAL; struct inode *root = NULL; struct dentry *root_dentry = NULL; - struct pvfs2_object_kref root_object; + struct orangefs_object_kref root_object; - /* alloc and init our private pvfs2 sb info */ + /* alloc and init our private orangefs sb info */ sb->s_fs_info = - kzalloc(sizeof(struct pvfs2_sb_info_s), PVFS2_GFP_FLAGS); - if (!PVFS2_SB(sb)) + kzalloc(sizeof(struct orangefs_sb_info_s), ORANGEFS_GFP_FLAGS); + if (!ORANGEFS_SB(sb)) return -ENOMEM; - PVFS2_SB(sb)->sb = sb; + ORANGEFS_SB(sb)->sb = sb; - PVFS2_SB(sb)->root_khandle = fs_mount->root_khandle; - PVFS2_SB(sb)->fs_id = fs_mount->fs_id; - PVFS2_SB(sb)->id = fs_mount->id; + ORANGEFS_SB(sb)->root_khandle = fs_mount->root_khandle; + ORANGEFS_SB(sb)->fs_id = fs_mount->fs_id; + ORANGEFS_SB(sb)->id = fs_mount->id; if (data) { ret = parse_mount_options(sb, data, silent); @@ -374,23 +374,23 @@ static int pvfs2_fill_sb(struct super_block *sb, } /* Hang the xattr handlers off the superblock */ - sb->s_xattr = pvfs2_xattr_handlers; - sb->s_magic = PVFS2_SUPER_MAGIC; - sb->s_op = &pvfs2_s_ops; - sb->s_d_op = &pvfs2_dentry_operations; + sb->s_xattr = orangefs_xattr_handlers; + sb->s_magic = ORANGEFS_SUPER_MAGIC; + sb->s_op = &orangefs_s_ops; + sb->s_d_op = &orangefs_dentry_operations; - sb->s_blocksize = pvfs_bufmap_size_query(); - sb->s_blocksize_bits = pvfs_bufmap_shift_query(); + sb->s_blocksize = orangefs_bufmap_size_query(); + sb->s_blocksize_bits = orangefs_bufmap_shift_query(); sb->s_maxbytes = MAX_LFS_FILESIZE; - root_object.khandle = PVFS2_SB(sb)->root_khandle; - root_object.fs_id = PVFS2_SB(sb)->fs_id; + root_object.khandle = ORANGEFS_SB(sb)->root_khandle; + root_object.fs_id = ORANGEFS_SB(sb)->fs_id; gossip_debug(GOSSIP_SUPER_DEBUG, "get inode %pU, fsid %d\n", &root_object.khandle, root_object.fs_id); - root = pvfs2_iget(sb, &root_object); + root = orangefs_iget(sb, &root_object); if (IS_ERR(root)) return PTR_ERR(root); @@ -404,23 +404,23 @@ static int pvfs2_fill_sb(struct super_block *sb, if (!root_dentry) return -ENOMEM; - sb->s_export_op = &pvfs2_export_ops; + sb->s_export_op = &orangefs_export_ops; sb->s_root = root_dentry; return 0; } -struct dentry *pvfs2_mount(struct file_system_type *fst, +struct dentry *orangefs_mount(struct file_system_type *fst, int flags, const char *devname, void *data) { int ret = -EINVAL; struct super_block *sb = ERR_PTR(-EINVAL); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_kernel_op_s *new_op; struct dentry *d = ERR_PTR(-EINVAL); gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_mount: called with devname %s\n", + "orangefs_mount: called with devname %s\n", devname); if (!devname) { @@ -428,25 +428,25 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, return ERR_PTR(-EINVAL); } - new_op = op_alloc(PVFS2_VFS_OP_FS_MOUNT); + new_op = op_alloc(ORANGEFS_VFS_OP_FS_MOUNT); if (!new_op) return ERR_PTR(-ENOMEM); - strncpy(new_op->upcall.req.fs_mount.pvfs2_config_server, + strncpy(new_op->upcall.req.fs_mount.orangefs_config_server, devname, - PVFS_MAX_SERVER_ADDR_LEN); + ORANGEFS_MAX_SERVER_ADDR_LEN); gossip_debug(GOSSIP_SUPER_DEBUG, - "Attempting PVFS2 Mount via host %s\n", - new_op->upcall.req.fs_mount.pvfs2_config_server); + "Attempting ORANGEFS Mount via host %s\n", + new_op->upcall.req.fs_mount.orangefs_config_server); - ret = service_operation(new_op, "pvfs2_mount", 0); + ret = service_operation(new_op, "orangefs_mount", 0); gossip_debug(GOSSIP_SUPER_DEBUG, - "pvfs2_mount: mount got return value of %d\n", ret); + "orangefs_mount: mount got return value of %d\n", ret); if (ret) goto free_op; - if (new_op->downcall.resp.fs_mount.fs_id == PVFS_FS_ID_NULL) { + if (new_op->downcall.resp.fs_mount.fs_id == ORANGEFS_FS_ID_NULL) { gossip_err("ERROR: Retrieved null fs_id\n"); ret = -EINVAL; goto free_op; @@ -459,7 +459,7 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, goto free_op; } - ret = pvfs2_fill_sb(sb, + ret = orangefs_fill_sb(sb, &new_op->downcall.resp.fs_mount, data, flags & MS_SILENT ? 1 : 0); @@ -472,25 +472,25 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, * on successful mount, store the devname and data * used */ - strncpy(PVFS2_SB(sb)->devname, + strncpy(ORANGEFS_SB(sb)->devname, devname, - PVFS_MAX_SERVER_ADDR_LEN); + ORANGEFS_MAX_SERVER_ADDR_LEN); /* mount_pending must be cleared */ - PVFS2_SB(sb)->mount_pending = 0; + ORANGEFS_SB(sb)->mount_pending = 0; /* - * finally, add this sb to our list of known pvfs2 + * finally, add this sb to our list of known orangefs * sb's */ - add_pvfs2_sb(sb); + add_orangefs_sb(sb); op_release(new_op); return dget(sb->s_root); free_op: - gossip_err("pvfs2_mount: mount request failed with %d\n", ret); + gossip_err("orangefs_mount: mount request failed with %d\n", ret); if (ret == -EINVAL) { - gossip_err("Ensure that all pvfs2-servers have the same FS configuration files\n"); + gossip_err("Ensure that all orangefs-servers have the same FS configuration files\n"); gossip_err("Look at pvfs2-client-core log file (typically /tmp/pvfs2-client.log) for more details\n"); } @@ -499,43 +499,43 @@ struct dentry *pvfs2_mount(struct file_system_type *fst, return d; } -void pvfs2_kill_sb(struct super_block *sb) +void orangefs_kill_sb(struct super_block *sb) { - gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_kill_sb: called\n"); + gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_kill_sb: called\n"); /* * issue the unmount to userspace to tell it to remove the * dynamic mount info it has for this superblock */ - pvfs2_unmount_sb(sb); + orangefs_unmount_sb(sb); - /* remove the sb from our list of pvfs2 specific sb's */ - remove_pvfs2_sb(sb); + /* remove the sb from our list of orangefs specific sb's */ + remove_orangefs_sb(sb); /* provided sb cleanup */ kill_anon_super(sb); - /* free the pvfs2 superblock private data */ - kfree(PVFS2_SB(sb)); + /* free the orangefs superblock private data */ + kfree(ORANGEFS_SB(sb)); } -int pvfs2_inode_cache_initialize(void) +int orangefs_inode_cache_initialize(void) { - pvfs2_inode_cache = kmem_cache_create("pvfs2_inode_cache", - sizeof(struct pvfs2_inode_s), + orangefs_inode_cache = kmem_cache_create("orangefs_inode_cache", + sizeof(struct orangefs_inode_s), 0, - PVFS2_CACHE_CREATE_FLAGS, - pvfs2_inode_cache_ctor); + ORANGEFS_CACHE_CREATE_FLAGS, + orangefs_inode_cache_ctor); - if (!pvfs2_inode_cache) { - gossip_err("Cannot create pvfs2_inode_cache\n"); + if (!orangefs_inode_cache) { + gossip_err("Cannot create orangefs_inode_cache\n"); return -ENOMEM; } return 0; } -int pvfs2_inode_cache_finalize(void) +int orangefs_inode_cache_finalize(void) { - kmem_cache_destroy(pvfs2_inode_cache); + kmem_cache_destroy(orangefs_inode_cache); return 0; } diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c index 2adfceff7730..321f626b190b 100644 --- a/fs/orangefs/symlink.c +++ b/fs/orangefs/symlink.c @@ -8,9 +8,9 @@ #include "pvfs2-kernel.h" #include "pvfs2-bufmap.h" -static const char *pvfs2_follow_link(struct dentry *dentry, void **cookie) +static const char *orangefs_follow_link(struct dentry *dentry, void **cookie) { - char *target = PVFS2_I(dentry->d_inode)->link_target; + char *target = ORANGEFS_I(dentry->d_inode)->link_target; gossip_debug(GOSSIP_INODE_DEBUG, "%s: called on %s (target is %p)\n", @@ -21,11 +21,11 @@ static const char *pvfs2_follow_link(struct dentry *dentry, void **cookie) return target; } -struct inode_operations pvfs2_symlink_inode_operations = { +struct inode_operations orangefs_symlink_inode_operations = { .readlink = generic_readlink, - .follow_link = pvfs2_follow_link, - .setattr = pvfs2_setattr, - .getattr = pvfs2_getattr, - .listxattr = pvfs2_listxattr, + .follow_link = orangefs_follow_link, + .setattr = orangefs_setattr, + .getattr = orangefs_getattr, + .listxattr = orangefs_listxattr, .setxattr = generic_setxattr, }; diff --git a/fs/orangefs/upcall.h b/fs/orangefs/upcall.h index 0805778a8185..781cbc38523a 100644 --- a/fs/orangefs/upcall.h +++ b/fs/orangefs/upcall.h @@ -12,68 +12,68 @@ * 32-64 bit interaction issues between * client-core and device */ -struct pvfs2_io_request_s { +struct orangefs_io_request_s { __s32 async_vfs_io; __s32 buf_index; __s32 count; __s32 __pad1; __s64 offset; - struct pvfs2_object_kref refn; - enum PVFS_io_type io_type; + struct orangefs_object_kref refn; + enum ORANGEFS_io_type io_type; __s32 readahead_size; }; -struct pvfs2_lookup_request_s { +struct orangefs_lookup_request_s { __s32 sym_follow; __s32 __pad1; - struct pvfs2_object_kref parent_refn; - char d_name[PVFS2_NAME_LEN]; + struct orangefs_object_kref parent_refn; + char d_name[ORANGEFS_NAME_LEN]; }; -struct pvfs2_create_request_s { - struct pvfs2_object_kref parent_refn; - struct PVFS_sys_attr_s attributes; - char d_name[PVFS2_NAME_LEN]; +struct orangefs_create_request_s { + struct orangefs_object_kref parent_refn; + struct ORANGEFS_sys_attr_s attributes; + char d_name[ORANGEFS_NAME_LEN]; }; -struct pvfs2_symlink_request_s { - struct pvfs2_object_kref parent_refn; - struct PVFS_sys_attr_s attributes; - char entry_name[PVFS2_NAME_LEN]; - char target[PVFS2_NAME_LEN]; +struct orangefs_symlink_request_s { + struct orangefs_object_kref parent_refn; + struct ORANGEFS_sys_attr_s attributes; + char entry_name[ORANGEFS_NAME_LEN]; + char target[ORANGEFS_NAME_LEN]; }; -struct pvfs2_getattr_request_s { - struct pvfs2_object_kref refn; +struct orangefs_getattr_request_s { + struct orangefs_object_kref refn; __u32 mask; __u32 __pad1; }; -struct pvfs2_setattr_request_s { - struct pvfs2_object_kref refn; - struct PVFS_sys_attr_s attributes; +struct orangefs_setattr_request_s { + struct orangefs_object_kref refn; + struct ORANGEFS_sys_attr_s attributes; }; -struct pvfs2_remove_request_s { - struct pvfs2_object_kref parent_refn; - char d_name[PVFS2_NAME_LEN]; +struct orangefs_remove_request_s { + struct orangefs_object_kref parent_refn; + char d_name[ORANGEFS_NAME_LEN]; }; -struct pvfs2_mkdir_request_s { - struct pvfs2_object_kref parent_refn; - struct PVFS_sys_attr_s attributes; - char d_name[PVFS2_NAME_LEN]; +struct orangefs_mkdir_request_s { + struct orangefs_object_kref parent_refn; + struct ORANGEFS_sys_attr_s attributes; + char d_name[ORANGEFS_NAME_LEN]; }; -struct pvfs2_readdir_request_s { - struct pvfs2_object_kref refn; +struct orangefs_readdir_request_s { + struct orangefs_object_kref refn; __u64 token; __s32 max_dirent_count; __s32 buf_index; }; -struct pvfs2_readdirplus_request_s { - struct pvfs2_object_kref refn; +struct orangefs_readdirplus_request_s { + struct orangefs_object_kref refn; __u64 token; __s32 max_dirent_count; __u32 mask; @@ -81,130 +81,130 @@ struct pvfs2_readdirplus_request_s { __s32 __pad1; }; -struct pvfs2_rename_request_s { - struct pvfs2_object_kref old_parent_refn; - struct pvfs2_object_kref new_parent_refn; - char d_old_name[PVFS2_NAME_LEN]; - char d_new_name[PVFS2_NAME_LEN]; +struct orangefs_rename_request_s { + struct orangefs_object_kref old_parent_refn; + struct orangefs_object_kref new_parent_refn; + char d_old_name[ORANGEFS_NAME_LEN]; + char d_new_name[ORANGEFS_NAME_LEN]; }; -struct pvfs2_statfs_request_s { +struct orangefs_statfs_request_s { __s32 fs_id; __s32 __pad1; }; -struct pvfs2_truncate_request_s { - struct pvfs2_object_kref refn; +struct orangefs_truncate_request_s { + struct orangefs_object_kref refn; __s64 size; }; -struct pvfs2_mmap_ra_cache_flush_request_s { - struct pvfs2_object_kref refn; +struct orangefs_mmap_ra_cache_flush_request_s { + struct orangefs_object_kref refn; }; -struct pvfs2_fs_mount_request_s { - char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN]; +struct orangefs_fs_mount_request_s { + char orangefs_config_server[ORANGEFS_MAX_SERVER_ADDR_LEN]; }; -struct pvfs2_fs_umount_request_s { +struct orangefs_fs_umount_request_s { __s32 id; __s32 fs_id; - char pvfs2_config_server[PVFS_MAX_SERVER_ADDR_LEN]; + char orangefs_config_server[ORANGEFS_MAX_SERVER_ADDR_LEN]; }; -struct pvfs2_getxattr_request_s { - struct pvfs2_object_kref refn; +struct orangefs_getxattr_request_s { + struct orangefs_object_kref refn; __s32 key_sz; __s32 __pad1; - char key[PVFS_MAX_XATTR_NAMELEN]; + char key[ORANGEFS_MAX_XATTR_NAMELEN]; }; -struct pvfs2_setxattr_request_s { - struct pvfs2_object_kref refn; - struct PVFS_keyval_pair keyval; +struct orangefs_setxattr_request_s { + struct orangefs_object_kref refn; + struct ORANGEFS_keyval_pair keyval; __s32 flags; __s32 __pad1; }; -struct pvfs2_listxattr_request_s { - struct pvfs2_object_kref refn; +struct orangefs_listxattr_request_s { + struct orangefs_object_kref refn; __s32 requested_count; __s32 __pad1; __u64 token; }; -struct pvfs2_removexattr_request_s { - struct pvfs2_object_kref refn; +struct orangefs_removexattr_request_s { + struct orangefs_object_kref refn; __s32 key_sz; __s32 __pad1; - char key[PVFS_MAX_XATTR_NAMELEN]; + char key[ORANGEFS_MAX_XATTR_NAMELEN]; }; -struct pvfs2_op_cancel_s { +struct orangefs_op_cancel_s { __u64 op_tag; }; -struct pvfs2_fsync_request_s { - struct pvfs2_object_kref refn; -}; - -enum pvfs2_param_request_type { - PVFS2_PARAM_REQUEST_SET = 1, - PVFS2_PARAM_REQUEST_GET = 2 -}; - -enum pvfs2_param_request_op { - PVFS2_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS = 1, - PVFS2_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT = 2, - PVFS2_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT = 3, - PVFS2_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE = 4, - PVFS2_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS = 5, - PVFS2_PARAM_REQUEST_OP_PERF_HISTORY_SIZE = 6, - PVFS2_PARAM_REQUEST_OP_PERF_RESET = 7, - PVFS2_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS = 8, - PVFS2_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT = 9, - PVFS2_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT = 10, - PVFS2_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE = 11, - PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_TIMEOUT_MSECS = 12, - PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_HARD_LIMIT = 13, - PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_SOFT_LIMIT = 14, - PVFS2_PARAM_REQUEST_OP_STATIC_ACACHE_RECLAIM_PERCENTAGE = 15, - PVFS2_PARAM_REQUEST_OP_CLIENT_DEBUG = 16, - PVFS2_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS = 17, - PVFS2_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT = 18, - PVFS2_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT = 19, - PVFS2_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE = 20, - PVFS2_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS = 21, - PVFS2_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT = 22, - PVFS2_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT = 23, - PVFS2_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE = 24, - PVFS2_PARAM_REQUEST_OP_TWO_MASK_VALUES = 25, -}; - -struct pvfs2_param_request_s { - enum pvfs2_param_request_type type; - enum pvfs2_param_request_op op; +struct orangefs_fsync_request_s { + struct orangefs_object_kref refn; +}; + +enum orangefs_param_request_type { + ORANGEFS_PARAM_REQUEST_SET = 1, + ORANGEFS_PARAM_REQUEST_GET = 2 +}; + +enum orangefs_param_request_op { + ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS = 1, + ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT = 2, + ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT = 3, + ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE = 4, + ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS = 5, + ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE = 6, + ORANGEFS_PARAM_REQUEST_OP_PERF_RESET = 7, + ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS = 8, + ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT = 9, + ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT = 10, + ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE = 11, + ORANGEFS_PARAM_REQUEST_OP_STATIC_ACACHE_TIMEOUT_MSECS = 12, + ORANGEFS_PARAM_REQUEST_OP_STATIC_ACACHE_HARD_LIMIT = 13, + ORANGEFS_PARAM_REQUEST_OP_STATIC_ACACHE_SOFT_LIMIT = 14, + ORANGEFS_PARAM_REQUEST_OP_STATIC_ACACHE_RECLAIM_PERCENTAGE = 15, + ORANGEFS_PARAM_REQUEST_OP_CLIENT_DEBUG = 16, + ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS = 17, + ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT = 18, + ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT = 19, + ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE = 20, + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS = 21, + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT = 22, + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT = 23, + ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE = 24, + ORANGEFS_PARAM_REQUEST_OP_TWO_MASK_VALUES = 25, +}; + +struct orangefs_param_request_s { + enum orangefs_param_request_type type; + enum orangefs_param_request_op op; __s64 value; - char s_value[PVFS2_MAX_DEBUG_STRING_LEN]; + char s_value[ORANGEFS_MAX_DEBUG_STRING_LEN]; }; -enum pvfs2_perf_count_request_type { - PVFS2_PERF_COUNT_REQUEST_ACACHE = 1, - PVFS2_PERF_COUNT_REQUEST_NCACHE = 2, - PVFS2_PERF_COUNT_REQUEST_CAPCACHE = 3, +enum orangefs_perf_count_request_type { + ORANGEFS_PERF_COUNT_REQUEST_ACACHE = 1, + ORANGEFS_PERF_COUNT_REQUEST_NCACHE = 2, + ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE = 3, }; -struct pvfs2_perf_count_request_s { - enum pvfs2_perf_count_request_type type; +struct orangefs_perf_count_request_s { + enum orangefs_perf_count_request_type type; __s32 __pad1; }; -struct pvfs2_fs_key_request_s { +struct orangefs_fs_key_request_s { __s32 fsid; __s32 __pad1; }; -struct pvfs2_upcall_s { +struct orangefs_upcall_s { __s32 type; __u32 uid; __u32 gid; @@ -215,31 +215,31 @@ struct pvfs2_upcall_s { char *trailer_buf; union { - struct pvfs2_io_request_s io; - struct pvfs2_lookup_request_s lookup; - struct pvfs2_create_request_s create; - struct pvfs2_symlink_request_s sym; - struct pvfs2_getattr_request_s getattr; - struct pvfs2_setattr_request_s setattr; - struct pvfs2_remove_request_s remove; - struct pvfs2_mkdir_request_s mkdir; - struct pvfs2_readdir_request_s readdir; - struct pvfs2_readdirplus_request_s readdirplus; - struct pvfs2_rename_request_s rename; - struct pvfs2_statfs_request_s statfs; - struct pvfs2_truncate_request_s truncate; - struct pvfs2_mmap_ra_cache_flush_request_s ra_cache_flush; - struct pvfs2_fs_mount_request_s fs_mount; - struct pvfs2_fs_umount_request_s fs_umount; - struct pvfs2_getxattr_request_s getxattr; - struct pvfs2_setxattr_request_s setxattr; - struct pvfs2_listxattr_request_s listxattr; - struct pvfs2_removexattr_request_s removexattr; - struct pvfs2_op_cancel_s cancel; - struct pvfs2_fsync_request_s fsync; - struct pvfs2_param_request_s param; - struct pvfs2_perf_count_request_s perf_count; - struct pvfs2_fs_key_request_s fs_key; + struct orangefs_io_request_s io; + struct orangefs_lookup_request_s lookup; + struct orangefs_create_request_s create; + struct orangefs_symlink_request_s sym; + struct orangefs_getattr_request_s getattr; + struct orangefs_setattr_request_s setattr; + struct orangefs_remove_request_s remove; + struct orangefs_mkdir_request_s mkdir; + struct orangefs_readdir_request_s readdir; + struct orangefs_readdirplus_request_s readdirplus; + struct orangefs_rename_request_s rename; + struct orangefs_statfs_request_s statfs; + struct orangefs_truncate_request_s truncate; + struct orangefs_mmap_ra_cache_flush_request_s ra_cache_flush; + struct orangefs_fs_mount_request_s fs_mount; + struct orangefs_fs_umount_request_s fs_umount; + struct orangefs_getxattr_request_s getxattr; + struct orangefs_setxattr_request_s setxattr; + struct orangefs_listxattr_request_s listxattr; + struct orangefs_removexattr_request_s removexattr; + struct orangefs_op_cancel_s cancel; + struct orangefs_fsync_request_s fsync; + struct orangefs_param_request_s param; + struct orangefs_perf_count_request_s perf_count; + struct orangefs_fs_key_request_s fs_key; } req; }; diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index d7b0eba043ab..cfc8dc59c4eb 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -25,10 +25,10 @@ */ void purge_waiting_ops(void) { - struct pvfs2_kernel_op_s *op; + struct orangefs_kernel_op_s *op; - spin_lock(&pvfs2_request_list_lock); - list_for_each_entry(op, &pvfs2_request_list, list) { + spin_lock(&orangefs_request_list_lock); + list_for_each_entry(op, &orangefs_request_list, list) { gossip_debug(GOSSIP_WAIT_DEBUG, "pvfs2-client-core: purging op tag %llu %s\n", llu(op->tag), @@ -38,11 +38,11 @@ void purge_waiting_ops(void) spin_unlock(&op->lock); wake_up_interruptible(&op->waitq); } - spin_unlock(&pvfs2_request_list_lock); + spin_unlock(&orangefs_request_list_lock); } /* - * submits a PVFS2 operation and waits for it to complete + * submits a ORANGEFS operation and waits for it to complete * * Note op->downcall.status will contain the status of the operation (in * errno format), whether provided by pvfs2-client or a result of failure to @@ -51,7 +51,7 @@ void purge_waiting_ops(void) * * Returns contents of op->downcall.status for convenience */ -int service_operation(struct pvfs2_kernel_op_s *op, +int service_operation(struct orangefs_kernel_op_s *op, const char *op_name, int flags) { @@ -70,30 +70,30 @@ int service_operation(struct pvfs2_kernel_op_s *op, retry_servicing: op->downcall.status = 0; gossip_debug(GOSSIP_WAIT_DEBUG, - "pvfs2: service_operation: %s %p\n", + "orangefs: service_operation: %s %p\n", op_name, op); gossip_debug(GOSSIP_WAIT_DEBUG, - "pvfs2: operation posted by process: %s, pid: %i\n", + "orangefs: operation posted by process: %s, pid: %i\n", current->comm, current->pid); /* mask out signals if this operation is not to be interrupted */ - if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) block_signals(&orig_sigset); - if (!(flags & PVFS2_OP_NO_SEMAPHORE)) { + if (!(flags & ORANGEFS_OP_NO_SEMAPHORE)) { ret = mutex_lock_interruptible(&request_mutex); /* * check to see if we were interrupted while waiting for * semaphore */ if (ret < 0) { - if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) set_signals(&orig_sigset); op->downcall.status = ret; gossip_debug(GOSSIP_WAIT_DEBUG, - "pvfs2: service_operation interrupted.\n"); + "orangefs: service_operation interrupted.\n"); return ret; } } @@ -116,7 +116,7 @@ int service_operation(struct pvfs2_kernel_op_s *op, } /* queue up the operation */ - if (flags & PVFS2_OP_PRIORITY) { + if (flags & ORANGEFS_OP_PRIORITY) { add_priority_op_to_request_list(op); } else { gossip_debug(GOSSIP_WAIT_DEBUG, @@ -125,17 +125,17 @@ int service_operation(struct pvfs2_kernel_op_s *op, add_op_to_request_list(op); } - if (!(flags & PVFS2_OP_NO_SEMAPHORE)) + if (!(flags & ORANGEFS_OP_NO_SEMAPHORE)) mutex_unlock(&request_mutex); /* * If we are asked to service an asynchronous operation from * VFS perspective, we are done. */ - if (flags & PVFS2_OP_ASYNC) + if (flags & ORANGEFS_OP_ASYNC) return 0; - if (flags & PVFS2_OP_CANCELLATION) { + if (flags & ORANGEFS_OP_CANCELLATION) { gossip_debug(GOSSIP_WAIT_DEBUG, "%s:" "About to call wait_for_cancellation_downcall.\n", @@ -148,25 +148,25 @@ int service_operation(struct pvfs2_kernel_op_s *op, if (ret < 0) { /* failed to get matching downcall */ if (ret == -ETIMEDOUT) { - gossip_err("pvfs2: %s -- wait timed out; aborting attempt.\n", + gossip_err("orangefs: %s -- wait timed out; aborting attempt.\n", op_name); } op->downcall.status = ret; } else { /* got matching downcall; make sure status is in errno format */ op->downcall.status = - pvfs2_normalize_to_errno(op->downcall.status); + orangefs_normalize_to_errno(op->downcall.status); ret = op->downcall.status; } - if (!(flags & PVFS2_OP_INTERRUPTIBLE)) + if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) set_signals(&orig_sigset); BUG_ON(ret != op->downcall.status); /* retry if operation has not been serviced and if requested */ if (!op_state_serviced(op) && op->downcall.status == -EAGAIN) { gossip_debug(GOSSIP_WAIT_DEBUG, - "pvfs2: tag %llu (%s)" + "orangefs: tag %llu (%s)" " -- operation to be retried (%d attempt)\n", llu(op->tag), op_name, @@ -204,17 +204,17 @@ int service_operation(struct pvfs2_kernel_op_s *op, * memory system can be initialized. */ spin_lock_irqsave(&op->lock, irqflags); - add_wait_queue(&pvfs2_bufmap_init_waitq, &wait_entry); + add_wait_queue(&orangefs_bufmap_init_waitq, &wait_entry); spin_unlock_irqrestore(&op->lock, irqflags); set_current_state(TASK_INTERRUPTIBLE); /* - * Wait for pvfs_bufmap_initialize() to wake me up + * Wait for orangefs_bufmap_initialize() to wake me up * within the allotted time. */ ret = schedule_timeout(MSECS_TO_JIFFIES - (1000 * PVFS2_BUFMAP_WAIT_TIMEOUT_SECS)); + (1000 * ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS)); gossip_debug(GOSSIP_WAIT_DEBUG, "Value returned from schedule_timeout:" @@ -225,14 +225,14 @@ int service_operation(struct pvfs2_kernel_op_s *op, get_bufmap_init()); spin_lock_irqsave(&op->lock, irqflags); - remove_wait_queue(&pvfs2_bufmap_init_waitq, + remove_wait_queue(&orangefs_bufmap_init_waitq, &wait_entry); spin_unlock_irqrestore(&op->lock, irqflags); if (get_bufmap_init() == 0) { gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted. Aborting user's request(%s).\n", __func__, - PVFS2_BUFMAP_WAIT_TIMEOUT_SECS, + ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS, get_opname_string(op)); return -EIO; } @@ -246,14 +246,14 @@ int service_operation(struct pvfs2_kernel_op_s *op, } gossip_debug(GOSSIP_WAIT_DEBUG, - "pvfs2: service_operation %s returning: %d for %p.\n", + "orangefs: service_operation %s returning: %d for %p.\n", op_name, ret, op); return ret; } -void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op) +void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) { /* * handle interrupted cases depending on what state we were in when @@ -339,7 +339,7 @@ void pvfs2_clean_up_interrupted_operation(struct pvfs2_kernel_op_s *op) * operation since client-core seems to be exiting too often * or if we were interrupted. */ -int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) +int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; DECLARE_WAITQUEUE(wait_entry, current); @@ -386,7 +386,7 @@ int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) op, op->attempts); ret = -ETIMEDOUT; - pvfs2_clean_up_interrupted_operation + orangefs_clean_up_interrupted_operation (op); break; } @@ -403,7 +403,7 @@ int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) * core starts, and so on... */ if (op_state_purged(op)) { - ret = (op->attempts < PVFS2_PURGE_RETRY_COUNT) ? + ret = (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ? -EAGAIN : -EIO; spin_unlock(&op->lock); @@ -415,7 +415,7 @@ int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) llu(op->tag), op, op->attempts); - pvfs2_clean_up_interrupted_operation(op); + orangefs_clean_up_interrupted_operation(op); break; } spin_unlock(&op->lock); @@ -429,7 +429,7 @@ int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) __func__, llu(op->tag), op); - pvfs2_clean_up_interrupted_operation(op); + orangefs_clean_up_interrupted_operation(op); ret = -EINTR; break; } @@ -452,7 +452,7 @@ int wait_for_matching_downcall(struct pvfs2_kernel_op_s *op) * cancellation upcall anyway. the only way to exit this is to either * timeout or have the cancellation be serviced properly. */ -int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op) +int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; DECLARE_WAITQUEUE(wait_entry, current); @@ -482,7 +482,7 @@ int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op) __func__, llu(op->tag), op); - pvfs2_clean_up_interrupted_operation(op); + orangefs_clean_up_interrupted_operation(op); ret = -EINTR; break; } @@ -502,7 +502,7 @@ int wait_for_cancellation_downcall(struct pvfs2_kernel_op_s *op) "%s:*** operation timed out: %p\n", __func__, op); - pvfs2_clean_up_interrupted_operation(op); + orangefs_clean_up_interrupted_operation(op); ret = -ETIMEDOUT; break; } diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index b683daab7425..aeb3c3083591 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -15,8 +15,8 @@ #include -#define SYSTEM_PVFS2_KEY "system.pvfs2." -#define SYSTEM_PVFS2_KEY_LEN 13 +#define SYSTEM_ORANGEFS_KEY "system.pvfs2." +#define SYSTEM_ORANGEFS_KEY_LEN 13 /* * this function returns @@ -24,15 +24,15 @@ * of a listxattr. * 1 if the key corresponding to name is meant to be returned as part of * a listxattr. - * The ones that start SYSTEM_PVFS2_KEY are the ones to avoid printing. + * The ones that start SYSTEM_ORANGEFS_KEY are the ones to avoid printing. */ static int is_reserved_key(const char *key, size_t size) { - if (size < SYSTEM_PVFS2_KEY_LEN) + if (size < SYSTEM_ORANGEFS_KEY_LEN) return 1; - return strncmp(key, SYSTEM_PVFS2_KEY, SYSTEM_PVFS2_KEY_LEN) ? 1 : 0; + return strncmp(key, SYSTEM_ORANGEFS_KEY, SYSTEM_ORANGEFS_KEY_LEN) ? 1 : 0; } static inline int convert_to_internal_xattr_flags(int setxattr_flags) @@ -41,10 +41,10 @@ static inline int convert_to_internal_xattr_flags(int setxattr_flags) if (setxattr_flags & XATTR_REPLACE) { /* Attribute must exist! */ - internal_flag = PVFS_XATTR_REPLACE; + internal_flag = ORANGEFS_XATTR_REPLACE; } else if (setxattr_flags & XATTR_CREATE) { /* Attribute must not exist */ - internal_flag = PVFS_XATTR_CREATE; + internal_flag = ORANGEFS_XATTR_CREATE; } return internal_flag; } @@ -59,11 +59,11 @@ static inline int convert_to_internal_xattr_flags(int setxattr_flags) * unless the key does not exist for the file and/or if * there were errors in fetching the attribute value. */ -ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, +ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix, const char *name, void *buffer, size_t size) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op = NULL; ssize_t ret = -ENOMEM; ssize_t length = 0; int fsuid; @@ -74,10 +74,10 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, __func__, prefix, name, size); if (name == NULL || (size > 0 && buffer == NULL)) { - gossip_err("pvfs2_inode_getxattr: bogus NULL pointers\n"); + gossip_err("orangefs_inode_getxattr: bogus NULL pointers\n"); return -EINVAL; } - if ((strlen(name) + strlen(prefix)) >= PVFS_MAX_XATTR_NAMELEN) { + if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) { gossip_err("Invalid key length (%d)\n", (int)(strlen(name) + strlen(prefix))); return -EINVAL; @@ -94,15 +94,15 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, fsuid, fsgid); - down_read(&pvfs2_inode->xattr_sem); + down_read(&orangefs_inode->xattr_sem); - new_op = op_alloc(PVFS2_VFS_OP_GETXATTR); + new_op = op_alloc(ORANGEFS_VFS_OP_GETXATTR); if (!new_op) goto out_unlock; - new_op->upcall.req.getxattr.refn = pvfs2_inode->refn; + new_op->upcall.req.getxattr.refn = orangefs_inode->refn; ret = snprintf((char *)new_op->upcall.req.getxattr.key, - PVFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name); + ORANGEFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name); /* * NOTE: Although keys are meant to be NULL terminated textual @@ -111,13 +111,13 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, */ new_op->upcall.req.getxattr.key_sz = ret + 1; - ret = service_operation(new_op, "pvfs2_inode_getxattr", + ret = service_operation(new_op, "orangefs_inode_getxattr", get_interruptible_flag(inode)); if (ret != 0) { if (ret == -ENOENT) { ret = -ENODATA; gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_getxattr: inode %pU key %s" + "orangefs_inode_getxattr: inode %pU key %s" " does not exist!\n", get_khandle_from_ino(inode), (char *)new_op->upcall.req.getxattr.key); @@ -149,7 +149,7 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, memset(buffer, 0, size); memcpy(buffer, new_op->downcall.resp.getxattr.val, length); gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_getxattr: inode %pU " + "orangefs_inode_getxattr: inode %pU " "key %s key_sz %d, val_len %d\n", get_khandle_from_ino(inode), (char *)new_op-> @@ -163,44 +163,44 @@ ssize_t pvfs2_inode_getxattr(struct inode *inode, const char *prefix, out_release_op: op_release(new_op); out_unlock: - up_read(&pvfs2_inode->xattr_sem); + up_read(&orangefs_inode->xattr_sem); return ret; } -static int pvfs2_inode_removexattr(struct inode *inode, +static int orangefs_inode_removexattr(struct inode *inode, const char *prefix, const char *name, int flags) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op = NULL; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op = NULL; int ret = -ENOMEM; - down_write(&pvfs2_inode->xattr_sem); - new_op = op_alloc(PVFS2_VFS_OP_REMOVEXATTR); + down_write(&orangefs_inode->xattr_sem); + new_op = op_alloc(ORANGEFS_VFS_OP_REMOVEXATTR); if (!new_op) goto out_unlock; - new_op->upcall.req.removexattr.refn = pvfs2_inode->refn; + new_op->upcall.req.removexattr.refn = orangefs_inode->refn; /* * NOTE: Although keys are meant to be NULL terminated * textual strings, I am going to explicitly pass the * length just in case we change this later on... */ ret = snprintf((char *)new_op->upcall.req.removexattr.key, - PVFS_MAX_XATTR_NAMELEN, + ORANGEFS_MAX_XATTR_NAMELEN, "%s%s", (prefix ? prefix : ""), name); new_op->upcall.req.removexattr.key_sz = ret + 1; gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_removexattr: key %s, key_sz %d\n", + "orangefs_inode_removexattr: key %s, key_sz %d\n", (char *)new_op->upcall.req.removexattr.key, (int)new_op->upcall.req.removexattr.key_sz); ret = service_operation(new_op, - "pvfs2_inode_removexattr", + "orangefs_inode_removexattr", get_interruptible_flag(inode)); if (ret == -ENOENT) { /* @@ -213,11 +213,11 @@ static int pvfs2_inode_removexattr(struct inode *inode, } gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_removexattr: returning %d\n", ret); + "orangefs_inode_removexattr: returning %d\n", ret); op_release(new_op); out_unlock: - up_write(&pvfs2_inode->xattr_sem); + up_write(&orangefs_inode->xattr_sem); return ret; } @@ -227,11 +227,11 @@ static int pvfs2_inode_removexattr(struct inode *inode, * Returns a -ve number on error and 0 on success. Key is text, but value * can be binary! */ -int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, +int orangefs_inode_setxattr(struct inode *inode, const char *prefix, const char *name, const void *value, size_t size, int flags) { - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op; int internal_flag = 0; int ret = -ENOMEM; @@ -240,9 +240,9 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, __func__, prefix, name, size); if (size < 0 || - size >= PVFS_MAX_XATTR_VALUELEN || + size >= ORANGEFS_MAX_XATTR_VALUELEN || flags < 0) { - gossip_err("pvfs2_inode_setxattr: bogus values of size(%d), flags(%d)\n", + gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n", (int)size, flags); return -EINVAL; @@ -250,23 +250,23 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, if (name == NULL || (size > 0 && value == NULL)) { - gossip_err("pvfs2_inode_setxattr: bogus NULL pointers!\n"); + gossip_err("orangefs_inode_setxattr: bogus NULL pointers!\n"); return -EINVAL; } internal_flag = convert_to_internal_xattr_flags(flags); if (prefix) { - if (strlen(name) + strlen(prefix) >= PVFS_MAX_XATTR_NAMELEN) { + if (strlen(name) + strlen(prefix) >= ORANGEFS_MAX_XATTR_NAMELEN) { gossip_err - ("pvfs2_inode_setxattr: bogus key size (%d)\n", + ("orangefs_inode_setxattr: bogus key size (%d)\n", (int)(strlen(name) + strlen(prefix))); return -EINVAL; } } else { - if (strlen(name) >= PVFS_MAX_XATTR_NAMELEN) { + if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { gossip_err - ("pvfs2_inode_setxattr: bogus key size (%d)\n", + ("orangefs_inode_setxattr: bogus key size (%d)\n", (int)(strlen(name))); return -EINVAL; } @@ -278,7 +278,7 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, "removing xattr (%s%s)\n", prefix, name); - return pvfs2_inode_removexattr(inode, prefix, name, flags); + return orangefs_inode_removexattr(inode, prefix, name, flags); } gossip_debug(GOSSIP_XATTR_DEBUG, @@ -286,13 +286,13 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, get_khandle_from_ino(inode), name); - down_write(&pvfs2_inode->xattr_sem); - new_op = op_alloc(PVFS2_VFS_OP_SETXATTR); + down_write(&orangefs_inode->xattr_sem); + new_op = op_alloc(ORANGEFS_VFS_OP_SETXATTR); if (!new_op) goto out_unlock; - new_op->upcall.req.setxattr.refn = pvfs2_inode->refn; + new_op->upcall.req.setxattr.refn = orangefs_inode->refn; new_op->upcall.req.setxattr.flags = internal_flag; /* * NOTE: Although keys are meant to be NULL terminated textual @@ -300,7 +300,7 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, * case we change this later on... */ ret = snprintf((char *)new_op->upcall.req.setxattr.keyval.key, - PVFS_MAX_XATTR_NAMELEN, + ORANGEFS_MAX_XATTR_NAMELEN, "%s%s", prefix, name); new_op->upcall.req.setxattr.keyval.key_sz = ret + 1; @@ -308,24 +308,24 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, new_op->upcall.req.setxattr.keyval.val_sz = size; gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_setxattr: key %s, key_sz %d " + "orangefs_inode_setxattr: key %s, key_sz %d " " value size %zd\n", (char *)new_op->upcall.req.setxattr.keyval.key, (int)new_op->upcall.req.setxattr.keyval.key_sz, size); ret = service_operation(new_op, - "pvfs2_inode_setxattr", + "orangefs_inode_setxattr", get_interruptible_flag(inode)); gossip_debug(GOSSIP_XATTR_DEBUG, - "pvfs2_inode_setxattr: returning %d\n", + "orangefs_inode_setxattr: returning %d\n", ret); /* when request is serviced properly, free req op struct */ op_release(new_op); out_unlock: - up_write(&pvfs2_inode->xattr_sem); + up_write(&orangefs_inode->xattr_sem); return ret; } @@ -336,12 +336,12 @@ int pvfs2_inode_setxattr(struct inode *inode, const char *prefix, * subsequent memory allocations. Thus our return value is always the size of * all the keys unless there were errors in fetching the keys! */ -ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) +ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) { struct inode *inode = dentry->d_inode; - struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode); - struct pvfs2_kernel_op_s *new_op; - __u64 token = PVFS_ITERATE_START; + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + struct orangefs_kernel_op_s *new_op; + __u64 token = ORANGEFS_ITERATE_START; ssize_t ret = -ENOMEM; ssize_t total = 0; ssize_t length = 0; @@ -358,8 +358,8 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) return -EINVAL; } - down_read(&pvfs2_inode->xattr_sem); - new_op = op_alloc(PVFS2_VFS_OP_LISTXATTR); + down_read(&orangefs_inode->xattr_sem); + new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR); if (!new_op) goto out_unlock; @@ -368,10 +368,10 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) try_again: key_size = 0; - new_op->upcall.req.listxattr.refn = pvfs2_inode->refn; + new_op->upcall.req.listxattr.refn = orangefs_inode->refn; new_op->upcall.req.listxattr.token = token; new_op->upcall.req.listxattr.requested_count = - (size == 0) ? 0 : PVFS_MAX_XATTR_LISTLEN; + (size == 0) ? 0 : ORANGEFS_MAX_XATTR_LISTLEN; ret = service_operation(new_op, __func__, get_interruptible_flag(inode)); if (ret != 0) @@ -384,7 +384,7 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) * up allocating memory rather than us... */ total = new_op->downcall.resp.listxattr.returned_count * - PVFS_MAX_XATTR_NAMELEN; + ORANGEFS_MAX_XATTR_NAMELEN; goto done; } @@ -429,7 +429,7 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) * fetching more keys! */ token = new_op->downcall.resp.listxattr.token; - if (token != PVFS_ITERATE_END) + if (token != ORANGEFS_ITERATE_END) goto try_again; done: @@ -443,88 +443,88 @@ ssize_t pvfs2_listxattr(struct dentry *dentry, char *buffer, size_t size) if (ret == 0) ret = total; out_unlock: - up_read(&pvfs2_inode->xattr_sem); + up_read(&orangefs_inode->xattr_sem); return ret; } -static int pvfs2_xattr_set_default(const struct xattr_handler *handler, - struct dentry *dentry, - const char *name, - const void *buffer, - size_t size, - int flags) +static int orangefs_xattr_set_default(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags) { - return pvfs2_inode_setxattr(dentry->d_inode, - PVFS2_XATTR_NAME_DEFAULT_PREFIX, + return orangefs_inode_setxattr(dentry->d_inode, + ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, name, buffer, size, flags); } -static int pvfs2_xattr_get_default(const struct xattr_handler *handler, - struct dentry *dentry, - const char *name, - void *buffer, - size_t size) +static int orangefs_xattr_get_default(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + void *buffer, + size_t size) { - return pvfs2_inode_getxattr(dentry->d_inode, - PVFS2_XATTR_NAME_DEFAULT_PREFIX, + return orangefs_inode_getxattr(dentry->d_inode, + ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, name, buffer, size); } -static int pvfs2_xattr_set_trusted(const struct xattr_handler *handler, - struct dentry *dentry, - const char *name, - const void *buffer, - size_t size, - int flags) +static int orangefs_xattr_set_trusted(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + const void *buffer, + size_t size, + int flags) { - return pvfs2_inode_setxattr(dentry->d_inode, - PVFS2_XATTR_NAME_TRUSTED_PREFIX, + return orangefs_inode_setxattr(dentry->d_inode, + ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, name, buffer, size, flags); } -static int pvfs2_xattr_get_trusted(const struct xattr_handler *handler, - struct dentry *dentry, - const char *name, - void *buffer, - size_t size) +static int orangefs_xattr_get_trusted(const struct xattr_handler *handler, + struct dentry *dentry, + const char *name, + void *buffer, + size_t size) { - return pvfs2_inode_getxattr(dentry->d_inode, - PVFS2_XATTR_NAME_TRUSTED_PREFIX, + return orangefs_inode_getxattr(dentry->d_inode, + ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, name, buffer, size); } -static struct xattr_handler pvfs2_xattr_trusted_handler = { - .prefix = PVFS2_XATTR_NAME_TRUSTED_PREFIX, - .get = pvfs2_xattr_get_trusted, - .set = pvfs2_xattr_set_trusted, +static struct xattr_handler orangefs_xattr_trusted_handler = { + .prefix = ORANGEFS_XATTR_NAME_TRUSTED_PREFIX, + .get = orangefs_xattr_get_trusted, + .set = orangefs_xattr_set_trusted, }; -static struct xattr_handler pvfs2_xattr_default_handler = { +static struct xattr_handler orangefs_xattr_default_handler = { /* * NOTE: this is set to be the empty string. * so that all un-prefixed xattrs keys get caught * here! */ - .prefix = PVFS2_XATTR_NAME_DEFAULT_PREFIX, - .get = pvfs2_xattr_get_default, - .set = pvfs2_xattr_set_default, + .prefix = ORANGEFS_XATTR_NAME_DEFAULT_PREFIX, + .get = orangefs_xattr_get_default, + .set = orangefs_xattr_set_default, }; -const struct xattr_handler *pvfs2_xattr_handlers[] = { +const struct xattr_handler *orangefs_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, - &pvfs2_xattr_trusted_handler, - &pvfs2_xattr_default_handler, + &orangefs_xattr_trusted_handler, + &orangefs_xattr_default_handler, NULL }; -- GitLab From 575e946125f70c41c2042f10172842c5cab9a09a Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 4 Dec 2015 12:56:14 -0500 Subject: [PATCH 0062/5324] Orangefs: change pvfs2 filenames to orangefs Also changed references within source files that referred to header files whose names had changed. Signed-off-by: Mike Marshall --- Makefile | 2 +- fs/orangefs/Makefile | 8 ++++---- fs/orangefs/acl.c | 4 ++-- fs/orangefs/dcache.c | 2 +- fs/orangefs/{devpvfs2-req.c => devorangefs-req.c} | 6 +++--- fs/orangefs/dir.c | 4 ++-- fs/orangefs/file.c | 6 +++--- fs/orangefs/inode.c | 8 ++++---- fs/orangefs/namei.c | 2 +- fs/orangefs/{pvfs2-bufmap.c => orangefs-bufmap.c} | 4 ++-- fs/orangefs/{pvfs2-bufmap.h => orangefs-bufmap.h} | 0 fs/orangefs/{pvfs2-cache.c => orangefs-cache.c} | 2 +- fs/orangefs/{pvfs2-debug.h => orangefs-debug.h} | 0 fs/orangefs/{pvfs2-debugfs.c => orangefs-debugfs.c} | 4 ++-- fs/orangefs/{pvfs2-debugfs.h => orangefs-debugfs.h} | 0 fs/orangefs/{pvfs2-dev-proto.h => orangefs-dev-proto.h} | 0 fs/orangefs/{pvfs2-kernel.h => orangefs-kernel.h} | 2 +- fs/orangefs/{pvfs2-mod.c => orangefs-mod.c} | 8 ++++---- fs/orangefs/{pvfs2-sysfs.c => orangefs-sysfs.c} | 4 ++-- fs/orangefs/{pvfs2-sysfs.h => orangefs-sysfs.h} | 0 fs/orangefs/{pvfs2-utils.c => orangefs-utils.c} | 6 +++--- fs/orangefs/protocol.h | 6 +++--- fs/orangefs/super.c | 4 ++-- fs/orangefs/symlink.c | 4 ++-- fs/orangefs/waitqueue.c | 4 ++-- fs/orangefs/xattr.c | 4 ++-- 26 files changed, 47 insertions(+), 47 deletions(-) rename fs/orangefs/{devpvfs2-req.c => devorangefs-req.c} (99%) rename fs/orangefs/{pvfs2-bufmap.c => orangefs-bufmap.c} (99%) rename fs/orangefs/{pvfs2-bufmap.h => orangefs-bufmap.h} (100%) rename fs/orangefs/{pvfs2-cache.c => orangefs-cache.c} (99%) rename fs/orangefs/{pvfs2-debug.h => orangefs-debug.h} (100%) rename fs/orangefs/{pvfs2-debugfs.c => orangefs-debugfs.c} (99%) rename fs/orangefs/{pvfs2-debugfs.h => orangefs-debugfs.h} (100%) rename fs/orangefs/{pvfs2-dev-proto.h => orangefs-dev-proto.h} (100%) rename fs/orangefs/{pvfs2-kernel.h => orangefs-kernel.h} (99%) rename fs/orangefs/{pvfs2-mod.c => orangefs-mod.c} (98%) rename fs/orangefs/{pvfs2-sysfs.c => orangefs-sysfs.c} (99%) rename fs/orangefs/{pvfs2-sysfs.h => orangefs-sysfs.h} (100%) rename fs/orangefs/{pvfs2-utils.c => orangefs-utils.c} (99%) diff --git a/Makefile b/Makefile index 3a0234f50f36..aca4a73ad069 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc1-o NAME = Blurry Fish Butt # *DOCUMENTATION* diff --git a/fs/orangefs/Makefile b/fs/orangefs/Makefile index 828b36a6916d..a9d6a968fe6d 100644 --- a/fs/orangefs/Makefile +++ b/fs/orangefs/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_ORANGEFS_FS) += orangefs.o -orangefs-objs := acl.o file.o pvfs2-cache.o pvfs2-utils.o xattr.o dcache.o \ - inode.o pvfs2-sysfs.o pvfs2-mod.o super.o devpvfs2-req.o \ - namei.o symlink.o dir.o pvfs2-bufmap.o \ - pvfs2-debugfs.o waitqueue.o +orangefs-objs := acl.o file.o orangefs-cache.o orangefs-utils.o xattr.o \ + dcache.o inode.o orangefs-sysfs.o orangefs-mod.o super.o \ + devorangefs-req.o namei.o symlink.o dir.o orangefs-bufmap.o \ + orangefs-debugfs.o waitqueue.o diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c index 5e27d5fcb6bf..03f89dbb2512 100644 --- a/fs/orangefs/acl.c +++ b/fs/orangefs/acl.c @@ -5,8 +5,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" #include #include diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index 12c916fa4c7f..5dd9841df64e 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -9,7 +9,7 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" +#include "orangefs-kernel.h" /* Returns 1 if dentry can still be trusted, else 0. */ static int orangefs_revalidate_lookup(struct dentry *dentry) diff --git a/fs/orangefs/devpvfs2-req.c b/fs/orangefs/devorangefs-req.c similarity index 99% rename from fs/orangefs/devpvfs2-req.c rename to fs/orangefs/devorangefs-req.c index e18149f0975b..e74938d575d6 100644 --- a/fs/orangefs/devpvfs2-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -8,9 +8,9 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-dev-proto.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-dev-proto.h" +#include "orangefs-bufmap.h" #include #include diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 452d589b9747..c043894fc2bd 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -5,8 +5,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" struct readdir_handle_s { int buffer_index; diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index ae5d8ed67ed5..171013ae0036 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -9,8 +9,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" #include #include @@ -186,7 +186,7 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod } if (ret < 0) { - handle_io_error(); /* defined in pvfs2-kernel.h */ + handle_io_error(); /* * don't write an error to syslog on signaled operation * termination unless we've got debugging turned on, as diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 58e83182d3dc..4724c92b61ac 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -9,8 +9,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" static int read_one_page(struct page *page) { @@ -125,7 +125,7 @@ static int orangefs_releasepage(struct page *page, gfp_t foo) * AIO. Modeled after NFS, they do this too. */ /* - * static ssize_t pvfs2_direct_IO(int rw, + * static ssize_t orangefs_direct_IO(int rw, * struct kiocb *iocb, * struct iov_iter *iter, * loff_t offset) @@ -150,7 +150,7 @@ const struct address_space_operations orangefs_address_operations = { .readpages = orangefs_readpages, .invalidatepage = orangefs_invalidatepage, .releasepage = orangefs_releasepage, -/* .direct_IO = pvfs2_direct_IO */ +/* .direct_IO = orangefs_direct_IO */ }; static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 333c87c8b0f5..63aa1e7fbdb6 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -9,7 +9,7 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" +#include "orangefs-kernel.h" /* * Get a newly allocated inode to go with a negative dentry. diff --git a/fs/orangefs/pvfs2-bufmap.c b/fs/orangefs/orangefs-bufmap.c similarity index 99% rename from fs/orangefs/pvfs2-bufmap.c rename to fs/orangefs/orangefs-bufmap.c index 345287e871b1..c5368d852ee2 100644 --- a/fs/orangefs/pvfs2-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -4,8 +4,8 @@ * See COPYING in top-level directory. */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" DECLARE_WAIT_QUEUE_HEAD(orangefs_bufmap_init_waitq); diff --git a/fs/orangefs/pvfs2-bufmap.h b/fs/orangefs/orangefs-bufmap.h similarity index 100% rename from fs/orangefs/pvfs2-bufmap.h rename to fs/orangefs/orangefs-bufmap.h diff --git a/fs/orangefs/pvfs2-cache.c b/fs/orangefs/orangefs-cache.c similarity index 99% rename from fs/orangefs/pvfs2-cache.c rename to fs/orangefs/orangefs-cache.c index a224831770f4..57e270246e3d 100644 --- a/fs/orangefs/pvfs2-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -5,7 +5,7 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" +#include "orangefs-kernel.h" /* tags assigned to kernel upcall operations */ static __u64 next_tag_value; diff --git a/fs/orangefs/pvfs2-debug.h b/fs/orangefs/orangefs-debug.h similarity index 100% rename from fs/orangefs/pvfs2-debug.h rename to fs/orangefs/orangefs-debug.h diff --git a/fs/orangefs/pvfs2-debugfs.c b/fs/orangefs/orangefs-debugfs.c similarity index 99% rename from fs/orangefs/pvfs2-debugfs.c rename to fs/orangefs/orangefs-debugfs.c index 315dc538b723..7319f1a2ecb8 100644 --- a/fs/orangefs/pvfs2-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -39,9 +39,9 @@ #include -#include "pvfs2-debugfs.h" +#include "orangefs-debugfs.h" #include "protocol.h" -#include "pvfs2-kernel.h" +#include "orangefs-kernel.h" static int orangefs_debug_disabled = 1; diff --git a/fs/orangefs/pvfs2-debugfs.h b/fs/orangefs/orangefs-debugfs.h similarity index 100% rename from fs/orangefs/pvfs2-debugfs.h rename to fs/orangefs/orangefs-debugfs.h diff --git a/fs/orangefs/pvfs2-dev-proto.h b/fs/orangefs/orangefs-dev-proto.h similarity index 100% rename from fs/orangefs/pvfs2-dev-proto.h rename to fs/orangefs/orangefs-dev-proto.h diff --git a/fs/orangefs/pvfs2-kernel.h b/fs/orangefs/orangefs-kernel.h similarity index 99% rename from fs/orangefs/pvfs2-kernel.h rename to fs/orangefs/orangefs-kernel.h index 33fcf3bccd2e..840872389fc5 100644 --- a/fs/orangefs/pvfs2-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -53,7 +53,7 @@ #include -#include "pvfs2-dev-proto.h" +#include "orangefs-dev-proto.h" #ifdef ORANGEFS_KERNEL_DEBUG #define ORANGEFS_DEFAULT_OP_TIMEOUT_SECS 10 diff --git a/fs/orangefs/pvfs2-mod.c b/fs/orangefs/orangefs-mod.c similarity index 98% rename from fs/orangefs/pvfs2-mod.c rename to fs/orangefs/orangefs-mod.c index d8642908a917..fa2fca6dca7c 100644 --- a/fs/orangefs/pvfs2-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -8,9 +8,9 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-debugfs.h" -#include "pvfs2-sysfs.h" +#include "orangefs-kernel.h" +#include "orangefs-debugfs.h" +#include "orangefs-sysfs.h" /* ORANGEFS_VERSION is a ./configure define */ #ifndef ORANGEFS_VERSION @@ -152,7 +152,7 @@ static int __init orangefs_init(void) if (ret < 0) goto cleanup_inode; - /* Initialize the pvfsdev subsystem. */ + /* Initialize the orangefsdev subsystem. */ ret = orangefs_dev_init(); if (ret < 0) { gossip_err("orangefs: could not initialize device subsystem %d!\n", diff --git a/fs/orangefs/pvfs2-sysfs.c b/fs/orangefs/orangefs-sysfs.c similarity index 99% rename from fs/orangefs/pvfs2-sysfs.c rename to fs/orangefs/orangefs-sysfs.c index f04de2593c79..3d360383ea22 100644 --- a/fs/orangefs/pvfs2-sysfs.c +++ b/fs/orangefs/orangefs-sysfs.c @@ -99,8 +99,8 @@ #include #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-sysfs.h" +#include "orangefs-kernel.h" +#include "orangefs-sysfs.h" #define ORANGEFS_KOBJ_ID "orangefs" #define ACACHE_KOBJ_ID "acache" diff --git a/fs/orangefs/pvfs2-sysfs.h b/fs/orangefs/orangefs-sysfs.h similarity index 100% rename from fs/orangefs/pvfs2-sysfs.h rename to fs/orangefs/orangefs-sysfs.h diff --git a/fs/orangefs/pvfs2-utils.c b/fs/orangefs/orangefs-utils.c similarity index 99% rename from fs/orangefs/pvfs2-utils.c rename to fs/orangefs/orangefs-utils.c index d132c5f712a4..fa2a46521b7a 100644 --- a/fs/orangefs/pvfs2-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -4,9 +4,9 @@ * See COPYING in top-level directory. */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-dev-proto.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-dev-proto.h" +#include "orangefs-bufmap.h" __s32 fsid_of_op(struct orangefs_kernel_op_s *op) { diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 5f10ebc83e76..03bbe7505a35 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -130,7 +130,7 @@ typedef __s64 ORANGEFS_offset; /* Bits 6 - 0 are reserved for the actual error code. */ #define ORANGEFS_ERROR_NUMBER_BITS 0x7f -/* Encoded errno values are decoded by PINT_errno_mapping in pvfs2-utils.c. */ +/* Encoded errno values decoded by PINT_errno_mapping in orangefs-utils.c. */ /* Our own ORANGEFS protocol error codes. */ #define ORANGEFS_ECANCEL (1|ORANGEFS_NON_ERRNO_ERROR_BIT|ORANGEFS_ERROR_BIT) @@ -352,7 +352,7 @@ struct dev_mask2_info_s { __s32 ORANGEFS_util_translate_mode(int mode); /* pvfs2-debug.h ************************************************************/ -#include "pvfs2-debug.h" +#include "orangefs-debug.h" /* pvfs2-internal.h *********************************************************/ #define llu(x) (unsigned long long)(x) @@ -402,7 +402,7 @@ enum { /* * describes memory regions to map in the ORANGEFS_DEV_MAP ioctl. - * NOTE: See devpvfs2-req.c for 32 bit compat structure. + * NOTE: See devorangefs-req.c for 32 bit compat structure. * Since this structure has a variable-sized layout that is different * on 32 and 64 bit platforms, we need to normalize to a 64 bit layout * on such systems before servicing ioctl calls from user-space binaries diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index c104de1ae5de..52bc522ea21c 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -5,8 +5,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" #include diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c index 321f626b190b..1b3ae63463dc 100644 --- a/fs/orangefs/symlink.c +++ b/fs/orangefs/symlink.c @@ -5,8 +5,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" static const char *orangefs_follow_link(struct dentry *dentry, void **cookie) { diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index cfc8dc59c4eb..c731cbdd5fbd 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -13,8 +13,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" /* * What we do in this function is to walk the list of operations that are diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index aeb3c3083591..0e4e01602738 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -9,8 +9,8 @@ */ #include "protocol.h" -#include "pvfs2-kernel.h" -#include "pvfs2-bufmap.h" +#include "orangefs-kernel.h" +#include "orangefs-bufmap.h" #include #include -- GitLab From e91f1c804328ae4d46d6509791af27bfe70d917d Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 4 Dec 2015 13:06:55 -0500 Subject: [PATCH 0063/5324] Orangefs: don't expose internal details of pathname resolution to userspace. Signed-off-by: Mike Marshall --- fs/orangefs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 63aa1e7fbdb6..9f82eb377857 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -113,7 +113,7 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, if (!new_op) return ERR_PTR(-ENOMEM); - new_op->upcall.req.lookup.sym_follow = flags & LOOKUP_FOLLOW; + new_op->upcall.req.lookup.sym_follow = PVFS2_LOOKUP_LINK_NO_FOLLOW; gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", __FILE__, -- GitLab From 7cec28e91d15ae6d145d8a4ef6cc5ed7c08e70bd Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 11 Dec 2015 10:46:22 -0500 Subject: [PATCH 0064/5324] Orangefs: don't keep checking stuff in on Friday afternoon. Signed-off-by: Mike Marshall --- fs/orangefs/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 9f82eb377857..50bc45d02009 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -113,7 +113,7 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, if (!new_op) return ERR_PTR(-ENOMEM); - new_op->upcall.req.lookup.sym_follow = PVFS2_LOOKUP_LINK_NO_FOLLOW; + new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", __FILE__, -- GitLab From b5e376ea8b20d5d0b48871d2c05916d69da4e604 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 11 Dec 2015 10:50:42 -0500 Subject: [PATCH 0065/5324] Orangefs: improve comments Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-bufmap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index c5368d852ee2..f7cd18a2a73b 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -499,6 +499,10 @@ void readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) orangefs_bufmap_unref(bufmap); } +/* + * we've been handed an iovec, we need to copy it to + * the shared memory descriptor at "buffer_index". + */ int orangefs_bufmap_copy_from_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, int buffer_index, @@ -527,9 +531,8 @@ int orangefs_bufmap_copy_from_iovec(struct orangefs_bufmap *bufmap, } /* - * Iterate through the array of pages containing the bytes from - * a file being read. - * + * we've been handed an iovec, we need to fill it from + * the shared memory descriptor at "buffer_index". */ int orangefs_bufmap_copy_to_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, -- GitLab From b4cf67a2ba1a58dbd2a967c3d877b807fef83b25 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 11 Dec 2015 11:00:12 -0500 Subject: [PATCH 0066/5324] Orangef: remove overlooked old-style userspace debug parts Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-debug.h | 202 +---------------------------------- 1 file changed, 1 insertion(+), 201 deletions(-) diff --git a/fs/orangefs/orangefs-debug.h b/fs/orangefs/orangefs-debug.h index e6b4baa5e8fb..387db17cde2b 100644 --- a/fs/orangefs/orangefs-debug.h +++ b/fs/orangefs/orangefs-debug.h @@ -18,79 +18,7 @@ #include #endif -#define GOSSIP_NO_DEBUG (__u64)0 -#define GOSSIP_BMI_DEBUG_TCP ((__u64)1 << 0) -#define GOSSIP_BMI_DEBUG_CONTROL ((__u64)1 << 1) -#define GOSSIP_BMI_DEBUG_OFFSETS ((__u64)1 << 2) -#define GOSSIP_BMI_DEBUG_GM ((__u64)1 << 3) -#define GOSSIP_JOB_DEBUG ((__u64)1 << 4) -#define GOSSIP_SERVER_DEBUG ((__u64)1 << 5) -#define GOSSIP_STO_DEBUG_CTRL ((__u64)1 << 6) -#define GOSSIP_STO_DEBUG_DEFAULT ((__u64)1 << 7) -#define GOSSIP_FLOW_DEBUG ((__u64)1 << 8) -#define GOSSIP_BMI_DEBUG_GM_MEM ((__u64)1 << 9) -#define GOSSIP_REQUEST_DEBUG ((__u64)1 << 10) -#define GOSSIP_FLOW_PROTO_DEBUG ((__u64)1 << 11) -#define GOSSIP_NCACHE_DEBUG ((__u64)1 << 12) -#define GOSSIP_CLIENT_DEBUG ((__u64)1 << 13) -#define GOSSIP_REQ_SCHED_DEBUG ((__u64)1 << 14) -#define GOSSIP_ACACHE_DEBUG ((__u64)1 << 15) -#define GOSSIP_TROVE_DEBUG ((__u64)1 << 16) -#define GOSSIP_TROVE_OP_DEBUG ((__u64)1 << 17) -#define GOSSIP_DIST_DEBUG ((__u64)1 << 18) -#define GOSSIP_BMI_DEBUG_IB ((__u64)1 << 19) -#define GOSSIP_DBPF_ATTRCACHE_DEBUG ((__u64)1 << 20) -#define GOSSIP_MMAP_RCACHE_DEBUG ((__u64)1 << 21) -#define GOSSIP_LOOKUP_DEBUG ((__u64)1 << 22) -#define GOSSIP_REMOVE_DEBUG ((__u64)1 << 23) -#define GOSSIP_GETATTR_DEBUG ((__u64)1 << 24) -#define GOSSIP_READDIR_DEBUG ((__u64)1 << 25) -#define GOSSIP_IO_DEBUG ((__u64)1 << 26) -#define GOSSIP_DBPF_OPEN_CACHE_DEBUG ((__u64)1 << 27) -#define GOSSIP_PERMISSIONS_DEBUG ((__u64)1 << 28) -#define GOSSIP_CANCEL_DEBUG ((__u64)1 << 29) -#define GOSSIP_MSGPAIR_DEBUG ((__u64)1 << 30) -#define GOSSIP_CLIENTCORE_DEBUG ((__u64)1 << 31) -#define GOSSIP_CLIENTCORE_TIMING_DEBUG ((__u64)1 << 32) -#define GOSSIP_SETATTR_DEBUG ((__u64)1 << 33) -#define GOSSIP_MKDIR_DEBUG ((__u64)1 << 34) -#define GOSSIP_VARSTRIP_DEBUG ((__u64)1 << 35) -#define GOSSIP_GETEATTR_DEBUG ((__u64)1 << 36) -#define GOSSIP_SETEATTR_DEBUG ((__u64)1 << 37) -#define GOSSIP_ENDECODE_DEBUG ((__u64)1 << 38) -#define GOSSIP_DELEATTR_DEBUG ((__u64)1 << 39) -#define GOSSIP_ACCESS_DEBUG ((__u64)1 << 40) -#define GOSSIP_ACCESS_DETAIL_DEBUG ((__u64)1 << 41) -#define GOSSIP_LISTEATTR_DEBUG ((__u64)1 << 42) -#define GOSSIP_PERFCOUNTER_DEBUG ((__u64)1 << 43) -#define GOSSIP_STATE_MACHINE_DEBUG ((__u64)1 << 44) -#define GOSSIP_DBPF_KEYVAL_DEBUG ((__u64)1 << 45) -#define GOSSIP_LISTATTR_DEBUG ((__u64)1 << 46) -#define GOSSIP_DBPF_COALESCE_DEBUG ((__u64)1 << 47) -#define GOSSIP_ACCESS_HOSTNAMES ((__u64)1 << 48) -#define GOSSIP_FSCK_DEBUG ((__u64)1 << 49) -#define GOSSIP_BMI_DEBUG_MX ((__u64)1 << 50) -#define GOSSIP_BSTREAM_DEBUG ((__u64)1 << 51) -#define GOSSIP_BMI_DEBUG_PORTALS ((__u64)1 << 52) -#define GOSSIP_USER_DEV_DEBUG ((__u64)1 << 53) -#define GOSSIP_DIRECTIO_DEBUG ((__u64)1 << 54) -#define GOSSIP_MGMT_DEBUG ((__u64)1 << 55) -#define GOSSIP_MIRROR_DEBUG ((__u64)1 << 56) -#define GOSSIP_WIN_CLIENT_DEBUG ((__u64)1 << 57) -#define GOSSIP_SECURITY_DEBUG ((__u64)1 << 58) -#define GOSSIP_USRINT_DEBUG ((__u64)1 << 59) -#define GOSSIP_RCACHE_DEBUG ((__u64)1 << 60) -#define GOSSIP_SECCACHE_DEBUG ((__u64)1 << 61) - -#define GOSSIP_BMI_DEBUG_ALL ((__u64) (GOSSIP_BMI_DEBUG_TCP + \ - GOSSIP_BMI_DEBUG_CONTROL + \ - GOSSIP_BMI_DEBUG_GM + \ - GOSSIP_BMI_DEBUG_OFFSETS + \ - GOSSIP_BMI_DEBUG_IB + \ - GOSSIP_BMI_DEBUG_MX + \ - GOSSIP_BMI_DEBUG_PORTALS)) - -const char *ORANGEFS_debug_get_next_debug_keyword(int position); +#define GOSSIP_NO_DEBUG (__u64)0 #define GOSSIP_SUPER_DEBUG ((__u64)1 << 0) #define GOSSIP_INODE_DEBUG ((__u64)1 << 1) @@ -124,131 +52,6 @@ struct __keyword_mask_s { __u64 mask_val; }; -#define __DEBUG_ALL ((__u64) -1) - -/* map all config keywords to pvfs2 debug masks here */ -static struct __keyword_mask_s s_keyword_mask_map[] = { - /* Log trove debugging info. Same as 'trove'. */ - {"storage", GOSSIP_TROVE_DEBUG}, - /* Log trove debugging info. Same as 'storage'. */ - {"trove", GOSSIP_TROVE_DEBUG}, - /* Log trove operations. */ - {"trove_op", GOSSIP_TROVE_OP_DEBUG}, - /* Log network debug info. */ - {"network", GOSSIP_BMI_DEBUG_ALL}, - /* Log server info, including new operations. */ - {"server", GOSSIP_SERVER_DEBUG}, - /* Log client sysint info. This is only useful for the client. */ - {"client", GOSSIP_CLIENT_DEBUG}, - /* Debug the varstrip distribution */ - {"varstrip", GOSSIP_VARSTRIP_DEBUG}, - /* Log job info */ - {"job", GOSSIP_JOB_DEBUG}, - /* Debug PINT_process_request calls. EXTREMELY verbose! */ - {"request", GOSSIP_REQUEST_DEBUG}, - /* Log request scheduler events */ - {"reqsched", GOSSIP_REQ_SCHED_DEBUG}, - /* Log the flow protocol events, including flowproto_multiqueue */ - {"flowproto", GOSSIP_FLOW_PROTO_DEBUG}, - /* Log flow calls */ - {"flow", GOSSIP_FLOW_DEBUG}, - /* Debug the client name cache. Only useful on the client. */ - {"ncache", GOSSIP_NCACHE_DEBUG}, - /* Debug read-ahead cache events. Only useful on the client. */ - {"mmaprcache", GOSSIP_MMAP_RCACHE_DEBUG}, - /* Debug the attribute cache. Only useful on the client. */ - {"acache", GOSSIP_ACACHE_DEBUG}, - /* Log/Debug distribution calls */ - {"distribution", GOSSIP_DIST_DEBUG}, - /* Debug the server-side dbpf attribute cache */ - {"dbpfattrcache", GOSSIP_DBPF_ATTRCACHE_DEBUG}, - /* Debug the client lookup state machine. */ - {"lookup", GOSSIP_LOOKUP_DEBUG}, - /* Debug the client remove state macine. */ - {"remove", GOSSIP_REMOVE_DEBUG}, - /* Debug the server getattr state machine. */ - {"getattr", GOSSIP_GETATTR_DEBUG}, - /* Debug the server setattr state machine. */ - {"setattr", GOSSIP_SETATTR_DEBUG}, - /* vectored getattr server state machine */ - {"listattr", GOSSIP_LISTATTR_DEBUG}, - /* Debug the client and server get ext attributes SM. */ - {"geteattr", GOSSIP_GETEATTR_DEBUG}, - /* Debug the client and server set ext attributes SM. */ - {"seteattr", GOSSIP_SETEATTR_DEBUG}, - /* Debug the readdir operation (client and server) */ - {"readdir", GOSSIP_READDIR_DEBUG}, - /* Debug the mkdir operation (server only) */ - {"mkdir", GOSSIP_MKDIR_DEBUG}, - /* - * Debug the io operation (reads and writes) - * for both the client and server. - */ - {"io", GOSSIP_IO_DEBUG}, - /* Debug the server's open file descriptor cache */ - {"open_cache", GOSSIP_DBPF_OPEN_CACHE_DEBUG}, - /* Debug permissions checking on the server */ - {"permissions", GOSSIP_PERMISSIONS_DEBUG}, - /* Debug the cancel operation */ - {"cancel", GOSSIP_CANCEL_DEBUG}, - /* Debug the msgpair state machine */ - {"msgpair", GOSSIP_MSGPAIR_DEBUG}, - /* Debug the client core app */ - {"clientcore", GOSSIP_CLIENTCORE_DEBUG}, - /* Debug the client timing state machines (job timeout, etc.) */ - {"clientcore_timing", GOSSIP_CLIENTCORE_TIMING_DEBUG}, - /* network encoding */ - {"endecode", GOSSIP_ENDECODE_DEBUG}, - /* Show server file (metadata) accesses (both modify and read-only). */ - {"access", GOSSIP_ACCESS_DEBUG}, - /* Show more detailed server file accesses */ - {"access_detail", GOSSIP_ACCESS_DETAIL_DEBUG}, - /* Debug the listeattr operation */ - {"listeattr", GOSSIP_LISTEATTR_DEBUG}, - /* Debug the state machine management code */ - {"sm", GOSSIP_STATE_MACHINE_DEBUG}, - /* Debug the metadata dbpf keyval functions */ - {"keyval", GOSSIP_DBPF_KEYVAL_DEBUG}, - /* Debug the metadata sync coalescing code */ - {"coalesce", GOSSIP_DBPF_COALESCE_DEBUG}, - /* Display the hostnames instead of IP addrs in debug output */ - {"access_hostnames", GOSSIP_ACCESS_HOSTNAMES}, - /* Show the client device events */ - {"user_dev", GOSSIP_USER_DEV_DEBUG}, - /* Debug the fsck tool */ - {"fsck", GOSSIP_FSCK_DEBUG}, - /* Debug the bstream code */ - {"bstream", GOSSIP_BSTREAM_DEBUG}, - /* Debug trove in direct io mode */ - {"directio", GOSSIP_DIRECTIO_DEBUG}, - /* Debug direct io thread management */ - {"mgmt", GOSSIP_MGMT_DEBUG}, - /* Debug mirroring process */ - {"mirror", GOSSIP_MIRROR_DEBUG}, - /* Windows client */ - {"win_client", GOSSIP_WIN_CLIENT_DEBUG}, - /* Debug robust security code */ - {"security", GOSSIP_SECURITY_DEBUG}, - /* Capability Cache */ - {"seccache", GOSSIP_SECCACHE_DEBUG}, - /* Client User Interface */ - {"usrint", GOSSIP_USRINT_DEBUG}, - /* rcache */ - {"rcache", GOSSIP_RCACHE_DEBUG}, - /* Everything except the periodic events. Useful for debugging */ - {"verbose", - (__DEBUG_ALL & - ~(GOSSIP_PERFCOUNTER_DEBUG | GOSSIP_STATE_MACHINE_DEBUG | - GOSSIP_ENDECODE_DEBUG | GOSSIP_USER_DEV_DEBUG)) - }, - /* No debug output */ - {"none", GOSSIP_NO_DEBUG}, - /* Everything */ - {"all", __DEBUG_ALL} -}; - -#undef __DEBUG_ALL - /* * Map all kmod keywords to kmod debug masks here. Keep this * structure "packed": @@ -286,7 +89,4 @@ static struct __keyword_mask_s s_kmod_keyword_mask_map[] = { static const int num_kmod_keyword_mask_map = (int) (sizeof(s_kmod_keyword_mask_map) / sizeof(struct __keyword_mask_s)); -static const int num_keyword_mask_map = (int) - (sizeof(s_keyword_mask_map) / sizeof(struct __keyword_mask_s)); - #endif /* __ORANGEFS_DEBUG_H */ -- GitLab From 7f83773ced2f9f41dec5e6eb3eb4a7ef23ca1d75 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 20 Nov 2015 11:30:17 +0100 Subject: [PATCH 0067/5324] efi/esrt: Don't preformat name kobject_init_and_add takes a format string+args, so there's no reason to do this formatting in advance. Signed-off-by: Rasmus Villemoes Cc: Peter Jones Signed-off-by: Matt Fleming --- drivers/firmware/efi/esrt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index 22c5285f7705..75feb3f5829b 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -167,14 +167,11 @@ static struct kset *esrt_kset; static int esre_create_sysfs_entry(void *esre, int entry_num) { struct esre_entry *entry; - char name[20]; entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; - sprintf(name, "entry%d", entry_num); - entry->kobj.kset = esrt_kset; if (esrt->fw_resource_version == 1) { @@ -182,7 +179,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) entry->esre.esre1 = esre; rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL, - "%s", name); + "entry%d", entry_num); if (rc) { kfree(entry); return rc; -- GitLab From 3bb9eee61c64d8cd64814e582cf5d72095554473 Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 30 Nov 2015 09:36:54 -0500 Subject: [PATCH 0068/5324] doc: efi-stub.txt: Fix arm64 paths Update documented paths for arm64 files to match current tree. Signed-off-by: Alan Ott Cc: Roy Franz Cc: Jonathan Corbet Cc: Ard Biesheuvel Cc: Leif Lindholm Signed-off-by: Matt Fleming --- Documentation/efi-stub.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt index 7747024d3bb7..e15746988261 100644 --- a/Documentation/efi-stub.txt +++ b/Documentation/efi-stub.txt @@ -10,12 +10,12 @@ arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c, respectively. For ARM the EFI stub is implemented in arch/arm/boot/compressed/efi-header.S and arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared -between architectures is in drivers/firmware/efi/efi-stub-helper.c. +between architectures is in drivers/firmware/efi/libstub. For arm64, there is no compressed kernel support, so the Image itself masquerades as a PE/COFF image and the EFI stub is linked into the kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S -and arch/arm64/kernel/efi-stub.c. +and drivers/firmware/efi/libstub/arm64-stub.c. By using the EFI boot stub it's possible to boot a Linux kernel without the use of a conventional EFI boot loader, such as grub or -- GitLab From 26d7f65fbd22168c33d2350f3e7e3021f5761256 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 25 Oct 2015 10:26:35 +0000 Subject: [PATCH 0069/5324] x86/efi: Preface all print statements with efi* tag The pr_*() calls in the x86 EFI code may or may not include a subsystem tag, which makes it difficult to grep the kernel log for all relevant EFI messages and leads users to miss important information. Recently, a bug reporter provided all the EFI print messages from the kernel log when trying to diagnose an issue but missed the following statement because it wasn't prefixed with anything indicating it was related to EFI, pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap); Cc: Borislav Petkov Reviewed-by: Josh Triplett Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi-bgrt.c | 3 +++ arch/x86/platform/efi/efi_64.c | 2 ++ arch/x86/platform/efi/quirks.c | 4 +++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index ea48449b2e63..9a52b5c4438f 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -10,6 +10,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a0ac0f9c307f..d347e854a5e4 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 1c7380da65ff..6452070f3025 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include @@ -256,7 +258,7 @@ void __init efi_apply_memmap_quirks(void) * services. */ if (!efi_runtime_supported()) { - pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + pr_info("Setup done, disabling due to 32/64-bit mismatch\n"); efi_unmap_memmap(); } -- GitLab From 50a0cb565246f20d59cdb161778531e4b19d35ac Mon Sep 17 00:00:00 2001 From: Sai Praneeth Date: Wed, 9 Dec 2015 15:41:08 -0800 Subject: [PATCH 0070/5324] x86/efi-bgrt: Fix kernel panic when mapping BGRT data Starting with this commit 35eb8b81edd4 ("x86/efi: Build our own page table structures") efi regions have a separate page directory called "efi_pgd". In order to access any efi region we have to first shift %cr3 to this page table. In the bgrt code we are trying to copy bgrt_header and image, but these regions fall under "EFI_BOOT_SERVICES_DATA" and to access these regions we have to shift %cr3 to efi_pgd and not doing so will cause page fault as shown below. [ 0.251599] Last level dTLB entries: 4KB 64, 2MB 0, 4MB 0, 1GB 4 [ 0.259126] Freeing SMP alternatives memory: 32K (ffffffff8230e000 - ffffffff82316000) [ 0.271803] BUG: unable to handle kernel paging request at fffffffefce35002 [ 0.279740] IP: [] efi_bgrt_init+0x144/0x1fd [ 0.286383] PGD 300f067 PUD 0 [ 0.289879] Oops: 0000 [#1] SMP [ 0.293566] Modules linked in: [ 0.297039] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc1-eywa-eywa-built-in-47041+ #2 [ 0.306619] Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.R00.B104.B01.1511110114 11/11/2015 [ 0.320925] task: ffffffff820134c0 ti: ffffffff82000000 task.ti: ffffffff82000000 [ 0.329420] RIP: 0010:[] [] efi_bgrt_init+0x144/0x1fd [ 0.338821] RSP: 0000:ffffffff82003f18 EFLAGS: 00010246 [ 0.344852] RAX: fffffffefce35000 RBX: fffffffefce35000 RCX: fffffffefce2b000 [ 0.352952] RDX: 000000008a82b000 RSI: ffffffff8235bb80 RDI: 000000008a835000 [ 0.361050] RBP: ffffffff82003f30 R08: 000000008a865000 R09: ffffffffff202850 [ 0.369149] R10: ffffffff811ad62f R11: 0000000000000000 R12: 0000000000000000 [ 0.377248] R13: ffff88016dbaea40 R14: ffffffff822622c0 R15: ffffffff82003fb0 [ 0.385348] FS: 0000000000000000(0000) GS:ffff88016d800000(0000) knlGS:0000000000000000 [ 0.394533] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.401054] CR2: fffffffefce35002 CR3: 000000000300c000 CR4: 00000000003406f0 [ 0.409153] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 0.417252] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 0.425350] Stack: [ 0.427638] ffffffffffffffff ffffffff82256900 ffff88016dbaea40 ffffffff82003f40 [ 0.436086] ffffffff821bbce0 ffffffff82003f88 ffffffff8219c0c2 0000000000000000 [ 0.444533] ffffffff8219ba4a ffffffff822622c0 0000000000083000 00000000ffffffff [ 0.452978] Call Trace: [ 0.455763] [] efi_late_init+0x9/0xb [ 0.461697] [] start_kernel+0x463/0x47f [ 0.467928] [] ? set_init_arg+0x55/0x55 [ 0.474159] [] ? early_idt_handler_array+0x120/0x120 [ 0.481669] [] x86_64_start_reservations+0x2a/0x2c [ 0.488982] [] x86_64_start_kernel+0x13d/0x14c [ 0.495897] Code: 00 41 b4 01 48 8b 78 28 e8 09 36 01 00 48 85 c0 48 89 c3 75 13 48 c7 c7 f8 ac d3 81 31 c0 e8 d7 3b fb fe e9 b5 00 00 00 45 84 e4 <44> 8b 6b 02 74 0d be 06 00 00 00 48 89 df e8 ae 34 0$ [ 0.518151] RIP [] efi_bgrt_init+0x144/0x1fd [ 0.524888] RSP [ 0.528851] CR2: fffffffefce35002 [ 0.532615] ---[ end trace 7b06521e6ebf2aea ]--- [ 0.537852] Kernel panic - not syncing: Attempted to kill the idle task! As said above one way to fix this bug is to shift %cr3 to efi_pgd but we are not doing that way because it leaks inner details of how we switch to EFI page tables into a new call site and it also adds duplicate code. Instead, we remove the call to efi_lookup_mapped_addr() and always perform early_mem*() instead of early_io*() because we want to remap RAM regions and not I/O regions. We also delete efi_lookup_mapped_addr() because we are no longer using it. Signed-off-by: Sai Praneeth Prakhya Reported-by: Wendy Wang Cc: Borislav Petkov Cc: Josh Triplett Cc: Ricardo Neri Cc: Ravi Shankar Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi-bgrt.c | 39 ++++++++++++-------------------- drivers/firmware/efi/efi.c | 32 -------------------------- 2 files changed, 14 insertions(+), 57 deletions(-) diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index 9a52b5c4438f..bf51f4c02562 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -31,8 +31,7 @@ struct bmp_header { void __init efi_bgrt_init(void) { acpi_status status; - void __iomem *image; - bool ioremapped = false; + void *image; struct bmp_header bmp_header; if (acpi_disabled) @@ -73,20 +72,14 @@ void __init efi_bgrt_init(void) return; } - image = efi_lookup_mapped_addr(bgrt_tab->image_address); + image = early_memremap(bgrt_tab->image_address, sizeof(bmp_header)); if (!image) { - image = early_ioremap(bgrt_tab->image_address, - sizeof(bmp_header)); - ioremapped = true; - if (!image) { - pr_err("Ignoring BGRT: failed to map image header memory\n"); - return; - } + pr_err("Ignoring BGRT: failed to map image header memory\n"); + return; } - memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); - if (ioremapped) - early_iounmap(image, sizeof(bmp_header)); + memcpy(&bmp_header, image, sizeof(bmp_header)); + early_memunmap(image, sizeof(bmp_header)); bgrt_image_size = bmp_header.size; bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); @@ -96,18 +89,14 @@ void __init efi_bgrt_init(void) return; } - if (ioremapped) { - image = early_ioremap(bgrt_tab->image_address, - bmp_header.size); - if (!image) { - pr_err("Ignoring BGRT: failed to map image memory\n"); - kfree(bgrt_image); - bgrt_image = NULL; - return; - } + image = early_memremap(bgrt_tab->image_address, bmp_header.size); + if (!image) { + pr_err("Ignoring BGRT: failed to map image memory\n"); + kfree(bgrt_image); + bgrt_image = NULL; + return; } - memcpy_fromio(bgrt_image, image, bgrt_image_size); - if (ioremapped) - early_iounmap(image, bmp_header.size); + memcpy(bgrt_image, image, bgrt_image_size); + early_memunmap(image, bmp_header.size); } diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 027ca212179f..e9c458ba9353 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -324,38 +324,6 @@ u64 __init efi_mem_desc_end(efi_memory_desc_t *md) return end; } -/* - * We can't ioremap data in EFI boot services RAM, because we've already mapped - * it as RAM. So, look it up in the existing EFI memory map instead. Only - * callable after efi_enter_virtual_mode and before efi_free_boot_services. - */ -void __iomem *efi_lookup_mapped_addr(u64 phys_addr) -{ - struct efi_memory_map *map; - void *p; - map = efi.memmap; - if (!map) - return NULL; - if (WARN_ON(!map->map)) - return NULL; - for (p = map->map; p < map->map_end; p += map->desc_size) { - efi_memory_desc_t *md = p; - u64 size = md->num_pages << EFI_PAGE_SHIFT; - u64 end = md->phys_addr + size; - if (!(md->attribute & EFI_MEMORY_RUNTIME) && - md->type != EFI_BOOT_SERVICES_CODE && - md->type != EFI_BOOT_SERVICES_DATA) - continue; - if (!md->virt_addr) - continue; - if (phys_addr >= md->phys_addr && phys_addr < end) { - phys_addr += md->virt_addr - md->phys_addr; - return (__force void __iomem *)(unsigned long)phys_addr; - } - } - return NULL; -} - static __initdata efi_config_table_type_t common_tables[] = { {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, -- GitLab From 97f100277cfdcd268f0cf3d83bb6e4d1a345bc80 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 11 Dec 2015 16:45:03 -0500 Subject: [PATCH 0071/5324] Orangefs: de-uglify orangefs_devreq_writev, and devorangefs-req.c in general AV dislikes many parts of orangefs_devreq_writev. Besides making orangefs_devreq_writev more easily readable and better commented, this patch makes an effort to address some of the problems: > The 5th is quietly ignored unless trailer_size is positive and > status is zero. If trailer_size > 0 && status == 0, you verify that > the length of the 5th segment is no more than trailer_size and copy > it to vmalloc'ed buffer. Without bothering to zero the rest of that > buffer out. It was just wrong to allow a 5th segment that is not exactly equal to trailer_size. Now that that's fixed, there's nothing to zero out in the vmalloced buffer - it is exactly the right size to hold the 5th segment. > Another API bogosity: when the 5th segment is present, successful writev() > returns the sum of sizes of the first 4. Added size of 5th segment to writev return... > if concatenation of the first 4 segments is longer than > 16 + sizeof(struct pvfs2_downcall_s) by no more than sizeof(long) => whine > and proceed with garbage. If 4th segment isn't exactly sizeof(struct pvfs2_downcall_s), whine and fail. > if the 32bit value 4 bytes into op->downcall is zero and 64bit > value following it is non-zero, the latter is interpreted as the size of > trailer data. The latter is what userspace claimed was the length of the trailer data. The kernel module now compares it to the trailer iovec's iov_len as a sanity check. > if there's no trailer, the 5th segment (if present) is completely ignored. Whine and fail if there should be no trailer, yet a 5th segment is present. > if vmalloc fails, act as if status (32bit at offset 5 into > op->downcall) had been -ENOMEM and don't look at the 5th segment at all. whine and fail with -ENOMEM. Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 265 +++++++++++++++++++++------------- 1 file changed, 166 insertions(+), 99 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index e74938d575d6..b182b025db86 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -76,11 +76,12 @@ static int orangefs_devreq_open(struct inode *inode, struct file *file) int ret = -EINVAL; if (!(file->f_flags & O_NONBLOCK)) { - gossip_err("orangefs: device cannot be opened in blocking mode\n"); + gossip_err("%s: device cannot be opened in blocking mode\n", + __func__); goto out; } ret = -EACCES; - gossip_debug(GOSSIP_DEV_DEBUG, "pvfs2-client-core: opening device\n"); + gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n"); mutex_lock(&devreq_mutex); if (open_access_count == 0) { @@ -100,6 +101,7 @@ static int orangefs_devreq_open(struct inode *inode, struct file *file) return ret; } +/* Function for read() callers into the device */ static ssize_t orangefs_devreq_read(struct file *file, char __user *buf, size_t count, loff_t *offset) @@ -112,7 +114,8 @@ static ssize_t orangefs_devreq_read(struct file *file, /* We do not support blocking IO. */ if (!(file->f_flags & O_NONBLOCK)) { - gossip_err("orangefs: blocking reads are not supported! (pvfs2-client-core bug)\n"); + gossip_err("%s: blocking read from client-core.\n", + __func__); return -EINVAL; } @@ -143,12 +146,16 @@ static ssize_t orangefs_devreq_read(struct file *file, llu(op->tag), get_opname_string(op)); spin_unlock(&op->lock); continue; - /* Skip ops whose filesystem we don't know about unless - * it is being mounted. */ + /* + * Skip ops whose filesystem we don't know about unless + * it is being mounted. + */ /* XXX: is there a better way to detect this? */ } else if (ret == -1 && - !(op->upcall.type == ORANGEFS_VFS_OP_FS_MOUNT || - op->upcall.type == ORANGEFS_VFS_OP_GETATTR)) { + !(op->upcall.type == + ORANGEFS_VFS_OP_FS_MOUNT || + op->upcall.type == + ORANGEFS_VFS_OP_GETATTR)) { gossip_debug(GOSSIP_DEV_DEBUG, "orangefs: skipping op tag %llu %s\n", llu(op->tag), get_opname_string(op)); @@ -237,7 +244,11 @@ static ssize_t orangefs_devreq_read(struct file *file, return -EFAULT; } -/* Function for writev() callers into the device */ +/* + * Function for writev() callers into the device. Readdir related + * operations have an extra iovec containing info about objects + * contained in directories. + */ static ssize_t orangefs_devreq_writev(struct file *file, const struct iovec *iov, size_t count, @@ -247,27 +258,43 @@ static ssize_t orangefs_devreq_writev(struct file *file, void *buffer = NULL; void *ptr = NULL; unsigned long i = 0; - static int max_downsize = MAX_ALIGNED_DEV_REQ_DOWNSIZE; - int ret = 0, num_remaining = max_downsize; - int notrailer_count = 4; /* num elements in iovec without trailer */ + int num_remaining = MAX_ALIGNED_DEV_REQ_DOWNSIZE; + int ret = 0; + /* num elements in iovec without trailer */ + int notrailer_count = 4; + /* + * If there's a trailer, its iov index will be equal to + * notrailer_count. + */ + int trailer_index = notrailer_count; int payload_size = 0; + int returned_downcall_size = 0; __s32 magic = 0; __s32 proto_ver = 0; __u64 tag = 0; ssize_t total_returned_size = 0; - /* Either there is a trailer or there isn't */ + /* + * There will always be at least notrailer_count iovecs, and + * when there's a trailer, one more than notrailer_count. Check + * count's sanity. + */ if (count != notrailer_count && count != (notrailer_count + 1)) { - gossip_err("Error: Number of iov vectors is (%zu) and notrailer count is %d\n", + gossip_err("%s: count:%zu: notrailer_count :%d:\n", + __func__, count, notrailer_count); return -EPROTO; } + + + /* Copy the non-trailer iovec data into a device request buffer. */ buffer = dev_req_alloc(); - if (!buffer) + if (!buffer) { + gossip_err("%s: dev_req_alloc failed.\n", __func__); return -ENOMEM; + } ptr = buffer; - for (i = 0; i < notrailer_count; i++) { if (iov[i].iov_len > num_remaining) { gossip_err @@ -292,7 +319,7 @@ static ssize_t orangefs_devreq_writev(struct file *file, * make it 8 bytes big, or use get_unaligned when asigning. */ ptr = buffer; - proto_ver = *((__s32 *) ptr); + proto_ver = *((__s32 *) ptr); /* unused */ ptr += sizeof(__s32); magic = *((__s32 *) ptr); @@ -307,82 +334,114 @@ static ssize_t orangefs_devreq_writev(struct file *file, return -EPROTO; } - /* - * proto_ver = 20902 for 2.9.2 - */ - op = orangefs_devreq_remove_op(tag); if (op) { /* Increase ref count! */ get_op(op); - /* cut off magic and tag from payload size */ - payload_size -= (2 * sizeof(__s32) + sizeof(__u64)); - if (payload_size <= sizeof(struct orangefs_downcall_s)) - /* copy the passed in downcall into the op */ + + /* calculate the size of the returned downcall. */ + returned_downcall_size = + payload_size - (2 * sizeof(__s32) + sizeof(__u64)); + + /* copy the passed in downcall into the op */ + if (returned_downcall_size == + sizeof(struct orangefs_downcall_s)) { memcpy(&op->downcall, ptr, sizeof(struct orangefs_downcall_s)); - else - gossip_debug(GOSSIP_DEV_DEBUG, - "writev: Ignoring %d bytes\n", - payload_size); + } else { + gossip_err("%s: returned downcall size:%d: \n", + __func__, + returned_downcall_size); + dev_req_release(buffer); + put_op(op); + return -EMSGSIZE; + } + + /* Don't tolerate an unexpected trailer iovec. */ + if ((op->downcall.trailer_size == 0) && + (count != notrailer_count)) { + gossip_err("%s: unexpected trailer iovec.\n", + __func__); + dev_req_release(buffer); + put_op(op); + return -EPROTO; + } + + /* Don't consider the trailer if there's a bad status. */ + if (op->downcall.status != 0) + goto no_trailer; + + /* get the trailer if there is one. */ + if (op->downcall.trailer_size == 0) + goto no_trailer; + + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: op->downcall.trailer_size %lld\n", + __func__, + op->downcall.trailer_size); - /* Do not allocate needlessly if client-core forgets - * to reset trailer size on op errors. + /* + * Bail if we think think there should be a trailer, but + * there's no iovec for it. */ - if (op->downcall.status == 0 && op->downcall.trailer_size > 0) { - __u64 trailer_size = op->downcall.trailer_size; - size_t size; - gossip_debug(GOSSIP_DEV_DEBUG, - "writev: trailer size %ld\n", - (unsigned long)trailer_size); - if (count != (notrailer_count + 1)) { - gossip_err("Error: trailer size (%ld) is non-zero, no trailer elements though? (%zu)\n", (unsigned long)trailer_size, count); - dev_req_release(buffer); - put_op(op); - return -EPROTO; - } - size = iov[notrailer_count].iov_len; - if (size > trailer_size) { - gossip_err("writev error: trailer size (%ld) != iov_len (%zd)\n", (unsigned long)trailer_size, size); + if (count != (notrailer_count + 1)) { + gossip_err("%s: trailer_size:%lld: count:%zu:\n", + __func__, + op->downcall.trailer_size, + count); + dev_req_release(buffer); + put_op(op); + return -EPROTO; + } + + /* Verify that trailer_size is accurate. */ + if (op->downcall.trailer_size != iov[trailer_index].iov_len) { + gossip_err("%s: trailer_size:%lld: != iov_len:%zd:\n", + __func__, + op->downcall.trailer_size, + iov[trailer_index].iov_len); + dev_req_release(buffer); + put_op(op); + return -EMSGSIZE; + } + + total_returned_size += iov[trailer_index].iov_len; + + /* + * Allocate a buffer, copy the trailer bytes into it and + * attach it to the downcall. + */ + op->downcall.trailer_buf = vmalloc(iov[trailer_index].iov_len); + if (op->downcall.trailer_buf != NULL) { + gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n", + op->downcall.trailer_buf); + ret = copy_from_user(op->downcall.trailer_buf, + iov[trailer_index].iov_base, + iov[trailer_index].iov_len); + if (ret) { + gossip_err("%s: Failed to copy trailer.\n", + __func__); dev_req_release(buffer); - put_op(op); - return -EMSGSIZE; - } - /* Allocate a buffer large enough to hold the - * trailer bytes. - */ - op->downcall.trailer_buf = vmalloc(trailer_size); - if (op->downcall.trailer_buf != NULL) { - gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n", + gossip_debug(GOSSIP_DEV_DEBUG, + "vfree: %p\n", op->downcall.trailer_buf); - ret = copy_from_user(op->downcall.trailer_buf, - iov[notrailer_count]. - iov_base, - size); - if (ret) { - gossip_err("Failed to copy trailer data from user space\n"); - dev_req_release(buffer); - gossip_debug(GOSSIP_DEV_DEBUG, - "vfree: %p\n", - op->downcall.trailer_buf); - vfree(op->downcall.trailer_buf); - op->downcall.trailer_buf = NULL; - put_op(op); - return -EIO; - } - memset(op->downcall.trailer_buf + size, 0, - trailer_size - size); - } else { - /* Change downcall status */ - op->downcall.status = -ENOMEM; - gossip_err("writev: could not vmalloc for trailer!\n"); + vfree(op->downcall.trailer_buf); + op->downcall.trailer_buf = NULL; + put_op(op); + return -EIO; } + } else { + /* Change downcall status */ + gossip_err("writev: could not vmalloc for trailer!\n"); + dev_req_release(buffer); + put_op(op); + return -ENOMEM; } - /* if this operation is an I/O operation and if it was - * initiated on behalf of a *synchronous* VFS I/O operation, - * only then we need to wait +no_trailer: + + /* if this operation is an I/O operation we need to wait * for all data to be copied before we can return to avoid * buffer corruption and races that can pull the buffers * out from under us. @@ -392,12 +451,12 @@ static ssize_t orangefs_devreq_writev(struct file *file, * application reading/writing this device to return until * the buffers are done being used. */ - if (op->upcall.type == ORANGEFS_VFS_OP_FILE_IO && - op->upcall.req.io.async_vfs_io == ORANGEFS_VFS_SYNC_IO) { + if (op->upcall.type == ORANGEFS_VFS_OP_FILE_IO) { int timed_out = 0; DECLARE_WAITQUEUE(wait_entry, current); - /* tell the vfs op waiting on a waitqueue + /* + * tell the vfs op waiting on a waitqueue * that this op is done */ spin_lock(&op->lock); @@ -423,14 +482,18 @@ static ssize_t orangefs_devreq_writev(struct file *file, MSECS_TO_JIFFIES(1000 * op_timeout_secs); if (!schedule_timeout(timeout)) { - gossip_debug(GOSSIP_DEV_DEBUG, "*** I/O wait time is up\n"); + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: timed out.\n", + __func__); timed_out = 1; break; } continue; } - gossip_debug(GOSSIP_DEV_DEBUG, "*** signal on I/O wait -- aborting\n"); + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: signal on I/O wait, aborting\n", + __func__); break; } @@ -468,6 +531,7 @@ static ssize_t orangefs_devreq_writev(struct file *file, "WARNING: No one's waiting for tag %llu\n", llu(tag)); } + /* put_op? */ dev_req_release(buffer); return total_returned_size; @@ -632,7 +696,8 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) return ret ? -EIO : orangefs_bufmap_initialize(&user_desc); case ORANGEFS_DEV_REMOUNT_ALL: gossip_debug(GOSSIP_DEV_DEBUG, - "orangefs_devreq_ioctl: got ORANGEFS_DEV_REMOUNT_ALL\n"); + "%s: got ORANGEFS_DEV_REMOUNT_ALL\n", + __func__); /* * remount all mounted orangefs volumes to regain the lost @@ -647,13 +712,17 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) if (ret < 0) return ret; gossip_debug(GOSSIP_DEV_DEBUG, - "orangefs_devreq_ioctl: priority remount in progress\n"); + "%s: priority remount in progress\n", + __func__); list_for_each(tmp, &orangefs_superblocks) { orangefs_sb = - list_entry(tmp, struct orangefs_sb_info_s, list); + list_entry(tmp, + struct orangefs_sb_info_s, + list); if (orangefs_sb && (orangefs_sb->sb)) { gossip_debug(GOSSIP_DEV_DEBUG, - "Remounting SB %p\n", + "%s: Remounting SB %p\n", + __func__, orangefs_sb); ret = orangefs_remount(orangefs_sb->sb); @@ -661,12 +730,13 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) gossip_debug(GOSSIP_DEV_DEBUG, "SB %p remount failed\n", orangefs_sb); - break; + break; } } } gossip_debug(GOSSIP_DEV_DEBUG, - "orangefs_devreq_ioctl: priority remount complete\n"); + "%s: priority remount complete\n", + __func__); mutex_unlock(&request_mutex); return ret; @@ -704,15 +774,12 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) (void __user *)arg, ORANGEFS_MAX_DEBUG_STRING_LEN); if (ret != 0) { - pr_info("%s: " - "ORANGEFS_DEV_CLIENT_STRING: copy_from_user failed" - "\n", + pr_info("%s: CLIENT_STRING: copy_from_user failed\n", __func__); return -EIO; } - pr_info("%s: client debug array string has been been received." - "\n", + pr_info("%s: client debug array string has been received.\n", __func__); if (!help_string_initialized) { @@ -722,9 +789,7 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) /* build a proper debug help string */ if (orangefs_prepare_debugfs_help_string(0)) { - gossip_err("%s: " - "prepare_debugfs_help_string failed" - "\n", + gossip_err("%s: no debug help string \n", __func__); return -EIO; } @@ -781,15 +846,17 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) debug_mask_to_string(&mask_info.mask_value, mask_info.mask_type); gossip_debug_mask = mask_info.mask_value; - pr_info("ORANGEFS: kernel debug mask has been modified to " + pr_info("%s: kernel debug mask has been modified to " ":%s: :%llx:\n", + __func__, kernel_debug_string, (unsigned long long)gossip_debug_mask); } else if (mask_info.mask_type == CLIENT_MASK) { debug_mask_to_string(&mask_info.mask_value, mask_info.mask_type); - pr_info("ORANGEFS: client debug mask has been modified to" + pr_info("%s: client debug mask has been modified to" ":%s: :%llx:\n", + __func__, client_debug_string, llu(mask_info.mask_value)); } else { -- GitLab From ce6c414e17be602a84b1b34915468f8301ed14a0 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Mon, 14 Dec 2015 14:54:46 -0500 Subject: [PATCH 0072/5324] Orangefs: Don't wait the old-fashioned way. Get rid of add_wait_queue, set_current_state, etc, and use the wait_event() model. Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 17 ++++++++-------- fs/orangefs/orangefs-bufmap.c | 15 +++++++------- fs/orangefs/waitqueue.c | 37 +++++++++++------------------------ 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index b182b025db86..dc2e2ce7e943 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -432,7 +432,6 @@ static ssize_t orangefs_devreq_writev(struct file *file, return -EIO; } } else { - /* Change downcall status */ gossip_err("writev: could not vmalloc for trailer!\n"); dev_req_release(buffer); put_op(op); @@ -453,7 +452,7 @@ static ssize_t orangefs_devreq_writev(struct file *file, */ if (op->upcall.type == ORANGEFS_VFS_OP_FILE_IO) { int timed_out = 0; - DECLARE_WAITQUEUE(wait_entry, current); + DEFINE_WAIT(wait_entry); /* * tell the vfs op waiting on a waitqueue @@ -463,14 +462,14 @@ static ssize_t orangefs_devreq_writev(struct file *file, set_op_state_serviced(op); spin_unlock(&op->lock); - add_wait_queue_exclusive(&op->io_completion_waitq, - &wait_entry); wake_up_interruptible(&op->waitq); while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock(&op->lock); + prepare_to_wait_exclusive( + &op->io_completion_waitq, + &wait_entry, + TASK_INTERRUPTIBLE); if (op->io_completed) { spin_unlock(&op->lock); break; @@ -497,9 +496,9 @@ static ssize_t orangefs_devreq_writev(struct file *file, break; } - set_current_state(TASK_RUNNING); - remove_wait_queue(&op->io_completion_waitq, - &wait_entry); + spin_lock(&op->lock); + finish_wait(&op->io_completion_waitq, &wait_entry); + spin_unlock(&op->lock); /* NOTE: for I/O operations we handle releasing the op * object except in the case of timeout. the reason we diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index f7cd18a2a73b..863c6fc8e192 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -333,19 +333,17 @@ static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) { int ret = -1; int i = 0; - DECLARE_WAITQUEUE(my_wait, current); - - - add_wait_queue_exclusive(slargs->slot_wq, &my_wait); + DEFINE_WAIT(wait_entry); while (1) { - set_current_state(TASK_INTERRUPTIBLE); - /* * check for available desc, slot_lock is the appropriate * index_lock */ spin_lock(slargs->slot_lock); + prepare_to_wait_exclusive(slargs->slot_wq, + &wait_entry, + TASK_INTERRUPTIBLE); for (i = 0; i < slargs->slot_count; i++) if (slargs->slot_array[i] == 0) { slargs->slot_array[i] = 1; @@ -383,8 +381,9 @@ static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) break; } - set_current_state(TASK_RUNNING); - remove_wait_queue(slargs->slot_wq, &my_wait); + spin_lock(slargs->slot_lock); + finish_wait(slargs->slot_wq, &wait_entry); + spin_unlock(slargs->slot_lock); return ret; } diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index c731cbdd5fbd..856a4b48fe23 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -62,7 +62,7 @@ int service_operation(struct orangefs_kernel_op_s *op, /* irqflags and wait_entry are only used IF the client-core aborts */ unsigned long irqflags; - DECLARE_WAITQUEUE(wait_entry, current); + DEFINE_WAIT(wait_entry); op->upcall.tgid = current->tgid; op->upcall.pid = current->pid; @@ -204,11 +204,11 @@ int service_operation(struct orangefs_kernel_op_s *op, * memory system can be initialized. */ spin_lock_irqsave(&op->lock, irqflags); - add_wait_queue(&orangefs_bufmap_init_waitq, &wait_entry); + prepare_to_wait(&orangefs_bufmap_init_waitq, + &wait_entry, + TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&op->lock, irqflags); - set_current_state(TASK_INTERRUPTIBLE); - /* * Wait for orangefs_bufmap_initialize() to wake me up * within the allotted time. @@ -225,8 +225,7 @@ int service_operation(struct orangefs_kernel_op_s *op, get_bufmap_init()); spin_lock_irqsave(&op->lock, irqflags); - remove_wait_queue(&orangefs_bufmap_init_waitq, - &wait_entry); + finish_wait(&orangefs_bufmap_init_waitq, &wait_entry); spin_unlock_irqrestore(&op->lock, irqflags); if (get_bufmap_init() == 0) { @@ -342,16 +341,11 @@ void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; - DECLARE_WAITQUEUE(wait_entry, current); - - spin_lock(&op->lock); - add_wait_queue(&op->waitq, &wait_entry); - spin_unlock(&op->lock); + DEFINE_WAIT(wait_entry); while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock(&op->lock); + prepare_to_wait(&op->waitq, &wait_entry, TASK_INTERRUPTIBLE); if (op_state_serviced(op)) { spin_unlock(&op->lock); ret = 0; @@ -434,10 +428,8 @@ int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) break; } - set_current_state(TASK_RUNNING); - spin_lock(&op->lock); - remove_wait_queue(&op->waitq, &wait_entry); + finish_wait(&op->waitq, &wait_entry); spin_unlock(&op->lock); return ret; @@ -455,16 +447,11 @@ int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; - DECLARE_WAITQUEUE(wait_entry, current); - - spin_lock(&op->lock); - add_wait_queue(&op->waitq, &wait_entry); - spin_unlock(&op->lock); + DEFINE_WAIT(wait_entry); while (1) { - set_current_state(TASK_INTERRUPTIBLE); - spin_lock(&op->lock); + prepare_to_wait(&op->waitq, &wait_entry, TASK_INTERRUPTIBLE); if (op_state_serviced(op)) { gossip_debug(GOSSIP_WAIT_DEBUG, "%s:op-state is SERVICED.\n", @@ -514,10 +501,8 @@ int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) break; } - set_current_state(TASK_RUNNING); - spin_lock(&op->lock); - remove_wait_queue(&op->waitq, &wait_entry); + finish_wait(&op->waitq, &wait_entry); spin_unlock(&op->lock); gossip_debug(GOSSIP_WAIT_DEBUG, -- GitLab From 90d26aa80861afaee992228d8f0e57cbd06c8d87 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Mon, 14 Dec 2015 15:26:38 -0500 Subject: [PATCH 0073/5324] Orangefs: do not finalize bufmap if it was never initialized. Found by the infant Orangefs fuzzer... Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index dc2e2ce7e943..4d7ab7cb08f7 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -600,7 +600,8 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) __func__); mutex_lock(&devreq_mutex); - orangefs_bufmap_finalize(); + if (get_bufmap_init()) + orangefs_bufmap_finalize(); open_access_count--; @@ -692,7 +693,13 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) (struct ORANGEFS_dev_map_desc __user *) arg, sizeof(struct ORANGEFS_dev_map_desc)); - return ret ? -EIO : orangefs_bufmap_initialize(&user_desc); + if (get_bufmap_init()) { + return -EINVAL; + } else { + return ret ? + -EIO : + orangefs_bufmap_initialize(&user_desc); + } case ORANGEFS_DEV_REMOUNT_ALL: gossip_debug(GOSSIP_DEV_DEBUG, "%s: got ORANGEFS_DEV_REMOUNT_ALL\n", -- GitLab From a762ae6dc5a615f18b5f0fe54a0b8551e02e19d0 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 15 Dec 2015 14:22:06 -0500 Subject: [PATCH 0074/5324] orangefs: Remove ``aligned'' upcall and downcall length macros. There was previously MAX_ALIGNED_DEV_REQ_(UP|DOWN)SIZE macros which evaluated to MAX_DEV_REQ_(UP|DOWN)SIZE+8. As it is unclear what this is for, other than creating a situation where we accept more data than we can parse, it is removed. Signed-off-by: Mike Marshall Signed-off-by: Martin Brandenburg --- fs/orangefs/devorangefs-req.c | 12 ++++++------ fs/orangefs/orangefs-cache.c | 4 ++-- fs/orangefs/orangefs-kernel.h | 18 ------------------ 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 4d7ab7cb08f7..5a9c53eb115f 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -120,10 +120,10 @@ static ssize_t orangefs_devreq_read(struct file *file, } /* - * The client will do an ioctl to find MAX_ALIGNED_DEV_REQ_UPSIZE, then + * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then * always read with that size buffer. */ - if (count != MAX_ALIGNED_DEV_REQ_UPSIZE) { + if (count != MAX_DEV_REQ_UPSIZE) { gossip_err("orangefs: client-core tried to read wrong size\n"); return -EINVAL; } @@ -226,7 +226,7 @@ static ssize_t orangefs_devreq_read(struct file *file, goto error; /* The client only asks to read one size buffer. */ - return MAX_ALIGNED_DEV_REQ_UPSIZE; + return MAX_DEV_REQ_UPSIZE; error: /* * We were unable to copy the op data to the client. Put the op back in @@ -258,7 +258,7 @@ static ssize_t orangefs_devreq_writev(struct file *file, void *buffer = NULL; void *ptr = NULL; unsigned long i = 0; - int num_remaining = MAX_ALIGNED_DEV_REQ_DOWNSIZE; + int num_remaining = MAX_DEV_REQ_DOWNSIZE; int ret = 0; /* num elements in iovec without trailer */ int notrailer_count = 4; @@ -661,8 +661,8 @@ static inline long check_ioctl_command(unsigned int command) static long dispatch_ioctl_command(unsigned int command, unsigned long arg) { static __s32 magic = ORANGEFS_DEVREQ_MAGIC; - static __s32 max_up_size = MAX_ALIGNED_DEV_REQ_UPSIZE; - static __s32 max_down_size = MAX_ALIGNED_DEV_REQ_DOWNSIZE; + static __s32 max_up_size = MAX_DEV_REQ_UPSIZE; + static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE; struct ORANGEFS_dev_map_desc user_desc; int ret = 0; struct dev_mask_info_s mask_info = { 0 }; diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index 57e270246e3d..b40f5d74aa97 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -166,7 +166,7 @@ void op_release(struct orangefs_kernel_op_s *orangefs_op) int dev_req_cache_initialize(void) { dev_req_cache = kmem_cache_create("orangefs_devreqcache", - MAX_ALIGNED_DEV_REQ_DOWNSIZE, + MAX_DEV_REQ_DOWNSIZE, 0, ORANGEFS_CACHE_CREATE_FLAGS, NULL); @@ -192,7 +192,7 @@ void *dev_req_alloc(void) if (buffer == NULL) gossip_err("Failed to allocate from dev_req_cache\n"); else - memset(buffer, 0, sizeof(MAX_ALIGNED_DEV_REQ_DOWNSIZE)); + memset(buffer, 0, sizeof(MAX_DEV_REQ_DOWNSIZE)); return buffer; } diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 840872389fc5..c337a52eb639 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -80,29 +80,11 @@ sizeof(__u64) + sizeof(struct orangefs_upcall_s)) #define MAX_DEV_REQ_DOWNSIZE (2*sizeof(__s32) + \ sizeof(__u64) + sizeof(struct orangefs_downcall_s)) -#define BITS_PER_LONG_DIV_8 (BITS_PER_LONG >> 3) - /* borrowed from irda.h */ #ifndef MSECS_TO_JIFFIES #define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) #endif -#define MAX_ALIGNED_DEV_REQ_UPSIZE \ - (MAX_DEV_REQ_UPSIZE + \ - ((((MAX_DEV_REQ_UPSIZE / \ - (BITS_PER_LONG_DIV_8)) * \ - (BITS_PER_LONG_DIV_8)) + \ - (BITS_PER_LONG_DIV_8)) - \ - MAX_DEV_REQ_UPSIZE)) - -#define MAX_ALIGNED_DEV_REQ_DOWNSIZE \ - (MAX_DEV_REQ_DOWNSIZE + \ - ((((MAX_DEV_REQ_DOWNSIZE / \ - (BITS_PER_LONG_DIV_8)) * \ - (BITS_PER_LONG_DIV_8)) + \ - (BITS_PER_LONG_DIV_8)) - \ - MAX_DEV_REQ_DOWNSIZE)) - /* * valid orangefs kernel operation states * -- GitLab From bf89f584329c79909ea01c99aeac59ec20b3f524 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 15 Dec 2015 14:45:12 -0500 Subject: [PATCH 0075/5324] orangefs: Change visibility of several bufmap helpers to static. Signed-off-by: Mike Marshall Signed-off-by: Martin Brandenburg --- fs/orangefs/orangefs-bufmap.c | 12 ++++++++++-- fs/orangefs/orangefs-bufmap.h | 11 ----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 863c6fc8e192..bf8470060c74 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -9,6 +9,14 @@ DECLARE_WAIT_QUEUE_HEAD(orangefs_bufmap_init_waitq); +/* used to describe mapped buffers */ +struct orangefs_bufmap_desc { + void *uaddr; /* user space address pointer */ + struct page **page_array; /* array of mapped pages */ + int array_count; /* size of above arrays */ + struct list_head list_link; +}; + static struct orangefs_bufmap { atomic_t refcnt; @@ -50,7 +58,7 @@ orangefs_bufmap_free(struct orangefs_bufmap *bufmap) kfree(bufmap); } -struct orangefs_bufmap *orangefs_bufmap_ref(void) +static struct orangefs_bufmap *orangefs_bufmap_ref(void) { struct orangefs_bufmap *bufmap = NULL; @@ -63,7 +71,7 @@ struct orangefs_bufmap *orangefs_bufmap_ref(void) return bufmap; } -void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) +static void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) { if (atomic_dec_and_lock(&bufmap->refcnt, &orangefs_bufmap_lock)) { __orangefs_bufmap = NULL; diff --git a/fs/orangefs/orangefs-bufmap.h b/fs/orangefs/orangefs-bufmap.h index 91d1755c231a..f652b464b340 100644 --- a/fs/orangefs/orangefs-bufmap.h +++ b/fs/orangefs/orangefs-bufmap.h @@ -7,19 +7,8 @@ #ifndef __ORANGEFS_BUFMAP_H #define __ORANGEFS_BUFMAP_H -/* used to describe mapped buffers */ -struct orangefs_bufmap_desc { - void *uaddr; /* user space address pointer */ - struct page **page_array; /* array of mapped pages */ - int array_count; /* size of above arrays */ - struct list_head list_link; -}; - struct orangefs_bufmap; -struct orangefs_bufmap *orangefs_bufmap_ref(void); -void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap); - /* * orangefs_bufmap_size_query is now an inline function because buffer * sizes are not hardcoded -- GitLab From 765a75b34a9d72aca875d85d4dc40945afd2939e Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 15 Dec 2015 14:48:17 -0500 Subject: [PATCH 0076/5324] orangefs: Remove useless inline qualifier from bufmap functions. All callers were outside of the file these functions were declared in, so nothing was ever inlined anyway. Further this happens before I/O and any speedup by not having to do a call will be dwarfed by the time it takes to talk to the server. Signed-off-by: Mike Marshall Signed-off-by: Martin Brandenburg --- fs/orangefs/orangefs-bufmap.c | 4 ++-- fs/orangefs/orangefs-bufmap.h | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index bf8470060c74..cf3ffb57334b 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -82,7 +82,7 @@ static void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) } } -inline int orangefs_bufmap_size_query(void) +int orangefs_bufmap_size_query(void) { struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); int size = bufmap ? bufmap->desc_size : 0; @@ -91,7 +91,7 @@ inline int orangefs_bufmap_size_query(void) return size; } -inline int orangefs_bufmap_shift_query(void) +int orangefs_bufmap_shift_query(void) { struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); int shift = bufmap ? bufmap->desc_shift : 0; diff --git a/fs/orangefs/orangefs-bufmap.h b/fs/orangefs/orangefs-bufmap.h index f652b464b340..112ec33a1b86 100644 --- a/fs/orangefs/orangefs-bufmap.h +++ b/fs/orangefs/orangefs-bufmap.h @@ -9,10 +9,6 @@ struct orangefs_bufmap; -/* - * orangefs_bufmap_size_query is now an inline function because buffer - * sizes are not hardcoded - */ int orangefs_bufmap_size_query(void); int orangefs_bufmap_shift_query(void); -- GitLab From b09d10df5a39b17ec12ecc0dc230a4d71c8a9996 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Tue, 15 Dec 2015 14:54:27 -0500 Subject: [PATCH 0077/5324] orangefs: Do not unref if there is no bufmap. Signed-off-by: Mike Marshall Signed-off-by: Martin Brandenburg --- fs/orangefs/orangefs-bufmap.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index cf3ffb57334b..888aa28136ee 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -82,21 +82,32 @@ static void orangefs_bufmap_unref(struct orangefs_bufmap *bufmap) } } +/* + * XXX: Can the size and shift change while the caller gives up the + * XXX: lock between calling this and doing something useful? + */ + int orangefs_bufmap_size_query(void) { - struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); - int size = bufmap ? bufmap->desc_size : 0; - - orangefs_bufmap_unref(bufmap); + struct orangefs_bufmap *bufmap; + int size = 0; + bufmap = orangefs_bufmap_ref(); + if (bufmap) { + size = bufmap->desc_size; + orangefs_bufmap_unref(bufmap); + } return size; } int orangefs_bufmap_shift_query(void) { - struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); - int shift = bufmap ? bufmap->desc_shift : 0; - - orangefs_bufmap_unref(bufmap); + struct orangefs_bufmap *bufmap; + int shift = 0; + bufmap = orangefs_bufmap_ref(); + if (bufmap) { + shift = bufmap->desc_shift; + orangefs_bufmap_unref(bufmap); + } return shift; } -- GitLab From fef8b67ce6cab8e031285642b841acf5355d6788 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 17 Dec 2015 14:31:24 -0500 Subject: [PATCH 0078/5324] Orangefs: don't use deprecated xattr defines. Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index c337a52eb639..0b7ba0496aa3 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -173,17 +173,8 @@ struct client_debug_mask { #define ORANGEFS_XATTR_INDEX_TRUSTED 3 #define ORANGEFS_XATTR_INDEX_DEFAULT 4 -#if 0 -#ifndef POSIX_ACL_XATTR_ACCESS -#define POSIX_ACL_XATTR_ACCESS "system.posix_acl_access" -#endif -#ifndef POSIX_ACL_XATTR_DEFAULT -#define POSIX_ACL_XATTR_DEFAULT "system.posix_acl_default" -#endif -#endif - -#define ORANGEFS_XATTR_NAME_ACL_ACCESS POSIX_ACL_XATTR_ACCESS -#define ORANGEFS_XATTR_NAME_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT +#define ORANGEFS_XATTR_NAME_ACL_ACCESS XATTR_NAME_POSIX_ACL_ACCESS +#define ORANGEFS_XATTR_NAME_ACL_DEFAULT XATTR_NAME_POSIX_ACL_DEFAULT #define ORANGEFS_XATTR_NAME_TRUSTED_PREFIX "trusted." #define ORANGEFS_XATTR_NAME_DEFAULT_PREFIX "" -- GitLab From 62441fa53bccc69fe344e6b20be0680cca0fbc15 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 17 Dec 2015 16:11:40 -0500 Subject: [PATCH 0079/5324] Orangefs: validate resp.listxattr.returned_count Signed-off-by: Mike Marshall --- fs/orangefs/xattr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index 0e4e01602738..8e9ccf971486 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -348,6 +348,7 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) int count_keys = 0; int key_size; int i = 0; + int returned_count = 0; if (size > 0 && buffer == NULL) { gossip_err("%s: bogus NULL pointers\n", __func__); @@ -392,10 +393,19 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) if (length == 0) goto done; + returned_count = new_op->downcall.resp.listxattr.returned_count; + if (returned_count < 0 || + returned_count >= ORANGEFS_MAX_XATTR_LISTLEN) { + gossip_err("%s: impossible value for returned_count:%d:\n", + __func__, + returned_count); + goto done; + } + /* * Check to see how much can be fit in the buffer. Fit only whole keys. */ - for (i = 0; i < new_op->downcall.resp.listxattr.returned_count; i++) { + for (i = 0; i < returned_count; i++) { if (total + new_op->downcall.resp.listxattr.lengths[i] > size) goto done; -- GitLab From 06e668ac91c93eb10bd21dfcc8891493722db29a Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 16 Dec 2015 19:18:37 +0200 Subject: [PATCH 0080/5324] drm/i915: Apply broader WaRsDisableCoarsePowerGating for guc also commit 344df9809f45 ("drm/i915/skl: Disable coarse power gating up until F0") failed to take into account that the same workaround is used in guc when forcewake is sampled. Wrap the condition check inside a macro and use it in both places to fix the guc side scope. Cc: Dave Gordon Cc: Sagar Arun Kamble Reviewed-by: Sagar Arun Kamble Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450286318-6854-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/i915_guc_submission.c | 6 ++---- drivers/gpu/drm/i915/intel_pm.c | 4 +--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f0f75d7c0d94..9b82c4532893 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2576,6 +2576,11 @@ struct drm_i915_cmd_table { /* Early gen2 have a totally busted CS tlb and require pinned batches. */ #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) + +/* WaRsDisableCoarsePowerGating:skl,bxt */ +#define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \ + ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && \ + IS_SKL_REVID(dev, 0, SKL_REVID_F0))) /* * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts * even when in MSI mode. This results in spurious interrupt warnings if the diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 05aa7e61cbe0..9cc3b8474dae 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -158,10 +158,8 @@ static int host2guc_sample_forcewake(struct intel_guc *guc, data[0] = HOST2GUC_ACTION_SAMPLE_FORCEWAKE; /* WaRsDisableCoarsePowerGating:skl,bxt */ - if (!intel_enable_rc6(dev_priv->dev) || - IS_BXT_REVID(dev, 0, BXT_REVID_A1) || - (IS_SKL_GT3(dev) && IS_SKL_REVID(dev, 0, SKL_REVID_E0)) || - (IS_SKL_GT4(dev) && IS_SKL_REVID(dev, 0, SKL_REVID_E0))) + if (!intel_enable_rc6(dev) || + NEEDS_WaRsDisableCoarsePowerGating(dev)) data[1] = 0; else /* bit 0 and 1 are for Render and Media domain separately */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 8d0d6f59a72b..02fe081878ad 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4713,9 +4713,7 @@ static void gen9_enable_rc6(struct drm_device *dev) * 3b: Enable Coarse Power Gating only when RC6 is enabled. * WaRsDisableCoarsePowerGating:skl,bxt - Render/Media PG need to be disabled with RC6. */ - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || - ((IS_SKL_GT3(dev) || IS_SKL_GT4(dev)) && - IS_SKL_REVID(dev, 0, SKL_REVID_F0))) + if (NEEDS_WaRsDisableCoarsePowerGating(dev)) I915_WRITE(GEN9_PG_ENABLE, 0); else I915_WRITE(GEN9_PG_ENABLE, (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? -- GitLab From c140330b5e6b5bc2262ffb2f50bfeea06a482699 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 18 Nov 2015 15:19:39 +0000 Subject: [PATCH 0081/5324] drm/i915: Move Braswell stop_machine GGTT insertion workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was a silent conflict between commit 0a878716265e9af9f697264dc2e858fcc060d833 Author: Daniel Vetter Date: Thu Oct 15 14:23:01 2015 +0200 drm/i915: restore ggtt double-bind avoidance and commit 5bab6f60cb4d1417ad7c599166bcfec87529c1a2 Author: Chris Wilson Date: Fri Oct 23 18:43:32 2015 +0100 drm/i915: Serialise updates to GGTT with access through GGTT on Braswell thankfully caught by the extra WARN safegaurd in 0a878716. Since we now override the GGTT insert_pages callback when installing the aliasing ppgtt, we assert that the callback is the original ggtt routine. However, on Braswell we now use a different insertion routine to serialise access through the GGTT with updating the PTE and hence the conflict. To avoid the conflict, move the custom insertion routine for Braswell down a level. Reported-by: Ville Syrjälä Cc: Ville Syrjälä Cc: Michel Thierry Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1447859979-20107-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Ville Syrjälä Tested-by: Ville Syrjälä Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 50 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 52bc6c3dfe04..56f4f2e58d53 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2384,6 +2384,32 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm, assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); } +struct insert_entries { + struct i915_address_space *vm; + struct sg_table *st; + uint64_t start; + enum i915_cache_level level; + u32 flags; +}; + +static int gen8_ggtt_insert_entries__cb(void *_arg) +{ + struct insert_entries *arg = _arg; + gen8_ggtt_insert_entries(arg->vm, arg->st, + arg->start, arg->level, arg->flags); + return 0; +} + +static void gen8_ggtt_insert_entries__BKL(struct i915_address_space *vm, + struct sg_table *st, + uint64_t start, + enum i915_cache_level level, + u32 flags) +{ + struct insert_entries arg = { vm, st, start, level, flags }; + stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL); +} + /* * Binds an object into the global gtt with the specified cache level. The object * will be accessible to the GPU via commands whose operands reference offsets @@ -2560,26 +2586,6 @@ static int ggtt_bind_vma(struct i915_vma *vma, return 0; } -struct ggtt_bind_vma__cb { - struct i915_vma *vma; - enum i915_cache_level cache_level; - u32 flags; -}; - -static int ggtt_bind_vma__cb(void *_arg) -{ - struct ggtt_bind_vma__cb *arg = _arg; - return ggtt_bind_vma(arg->vma, arg->cache_level, arg->flags); -} - -static int ggtt_bind_vma__BKL(struct i915_vma *vma, - enum i915_cache_level cache_level, - u32 flags) -{ - struct ggtt_bind_vma__cb arg = { vma, cache_level, flags }; - return stop_machine(ggtt_bind_vma__cb, &arg, NULL); -} - static int aliasing_gtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags) @@ -3048,8 +3054,8 @@ static int gen8_gmch_probe(struct drm_device *dev, dev_priv->gtt.base.bind_vma = ggtt_bind_vma; dev_priv->gtt.base.unbind_vma = ggtt_unbind_vma; - if (IS_CHERRYVIEW(dev)) - dev_priv->gtt.base.bind_vma = ggtt_bind_vma__BKL; + if (IS_CHERRYVIEW(dev_priv)) + dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries__BKL; return ret; } -- GitLab From 61fb3980dd396880ffba48523b1e27579868b82b Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Tue, 15 Dec 2015 12:40:30 +0800 Subject: [PATCH 0082/5324] drm/i915: Correct max delay for HDMI hotplug live status checking The total delay of HDMI hotplug detecting with 30ms have already been split into a resolution of 3 retries of 10ms each, for the worst cases. But it still suffered from only waiting 10ms at most in intel_hdmi_detect(). This patch corrects it by reading hotplug status with 4 times at most for 30ms delay. v2: - straight up to loop execution for more clear in code readability - mdelay will replace with msleep by Daniel's new patch drm/i915: mdelay(10) considered harmful - suggest to re-evaluate try times for being compatible to old HDMI monitor Reviewed-by: Cooper Chiou Tested-by: Gary Wang Cc: Jani Nikula Cc: Daniel Vetter Cc: Gavin Hindman Cc: Sonika Jindal Cc: Shashank Sharma Signed-off-by: Gary Wang [danvet: fixup conflict with s/mdelay/msleep/ patch.] Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_hdmi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 478e31fda067..79ebce2f68b1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1385,17 +1385,18 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct drm_i915_private *dev_priv = to_i915(connector->dev); bool live_status = false; - unsigned int retry = 3; + unsigned int try; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - while (!live_status && --retry) { + for (try = 0; !live_status && try < 4; try++) { + if (try) + msleep(10); live_status = intel_digital_port_connected(dev_priv, hdmi_to_dig_port(intel_hdmi)); - msleep(10); } if (!live_status) -- GitLab From 1a5a9ce70f088d1c7e8e3b2c8f92cac876d8f9df Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 17 Dec 2015 09:49:57 -0800 Subject: [PATCH 0083/5324] drm/i915: Limit VF cache invalidate workaround usage to gen9 It is unclear if this is even required on BXT. v2: Make sure to set the default value to false. Uncertain how my compiler doesn't complain with v1. Cc: Imre Deak Signed-off-by: Ben Widawsky Link: http://patchwork.freedesktop.org/patch/msgid/1450374597-7021-1-git-send-email-benjamin.widawsky@intel.com Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3aa614731d7e..ca5c0e8a3bf5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1698,7 +1698,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, struct intel_ringbuffer *ringbuf = request->ringbuf; struct intel_engine_cs *ring = ringbuf->ring; u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; - bool vf_flush_wa; + bool vf_flush_wa = false; u32 flags = 0; int ret; @@ -1719,14 +1719,14 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; flags |= PIPE_CONTROL_QW_WRITE; flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; - } - /* - * On GEN9+ Before VF_CACHE_INVALIDATE we need to emit a NULL pipe - * control. - */ - vf_flush_wa = INTEL_INFO(ring->dev)->gen >= 9 && - flags & PIPE_CONTROL_VF_CACHE_INVALIDATE; + /* + * On GEN9: before VF_CACHE_INVALIDATE we need to emit a NULL + * pipe control. + */ + if (IS_GEN9(ring->dev)) + vf_flush_wa = true; + } ret = intel_logical_ring_begin(request, vf_flush_wa ? 12 : 6); if (ret) -- GitLab From c838d719d62592e8cb519ffbdd36311e44e9cb53 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Dec 2015 13:08:15 +0200 Subject: [PATCH 0084/5324] drm/i915: Decouple struct i915_params i915 into i915_params.h Otherwise usage in the i915 debug macros yields problems due to i915_drv.h <-> i915_trace.h <-> intel_drv.h include loops. v2: - Document not-so-obvious need for linux/cache.h (Chris) Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1450436898-20408-2-git-send-email-joonas.lahtinen@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 40 +----------------- drivers/gpu/drm/i915/i915_params.c | 1 + drivers/gpu/drm/i915/i915_params.h | 68 ++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_params.h diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9b82c4532893..89788dead96a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -34,6 +34,7 @@ #include #include +#include "i915_params.h" #include "i915_reg.h" #include "intel_bios.h" #include "intel_ringbuffer.h" @@ -2670,44 +2671,7 @@ extern int i915_max_ioctl; extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state); extern int i915_resume_switcheroo(struct drm_device *dev); -/* i915_params.c */ -struct i915_params { - int modeset; - int panel_ignore_lid; - int semaphores; - int lvds_channel_mode; - int panel_use_ssc; - int vbt_sdvo_panel_type; - int enable_rc6; - int enable_dc; - int enable_fbc; - int enable_ppgtt; - int enable_execlists; - int enable_psr; - unsigned int preliminary_hw_support; - int disable_power_well; - int enable_ips; - int invert_brightness; - int enable_cmd_parser; - /* leave bools at the end to not create holes */ - bool enable_hangcheck; - bool fastboot; - bool prefault_disable; - bool load_detect_test; - bool reset; - bool disable_display; - bool disable_vtd_wa; - bool enable_guc_submission; - int guc_log_level; - int use_mmio_flip; - int mmio_debug; - bool verbose_state_checks; - bool nuclear_pageflip; - int edp_vswing; -}; -extern struct i915_params i915 __read_mostly; - - /* i915_dma.c */ +/* i915_dma.c */ extern int i915_driver_load(struct drm_device *, unsigned long flags); extern int i915_driver_unload(struct drm_device *); extern int i915_driver_open(struct drm_device *dev, struct drm_file *file); diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 835d6099c769..8d90c256520a 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -22,6 +22,7 @@ * IN THE SOFTWARE. */ +#include "i915_params.h" #include "i915_drv.h" struct i915_params i915 __read_mostly = { diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h new file mode 100644 index 000000000000..353951c13049 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_params.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2015 Intel Corporation + * + * 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. + * + */ + +#ifndef _I915_PARAMS_H_ +#define _I915_PARAMS_H_ + +#include /* for __read_mostly */ + +struct i915_params { + int modeset; + int panel_ignore_lid; + int semaphores; + int lvds_channel_mode; + int panel_use_ssc; + int vbt_sdvo_panel_type; + int enable_rc6; + int enable_dc; + int enable_fbc; + int enable_ppgtt; + int enable_execlists; + int enable_psr; + unsigned int preliminary_hw_support; + int disable_power_well; + int enable_ips; + int invert_brightness; + int enable_cmd_parser; + /* leave bools at the end to not create holes */ + bool enable_hangcheck; + bool fastboot; + bool prefault_disable; + bool load_detect_test; + bool reset; + bool disable_display; + bool disable_vtd_wa; + bool enable_guc_submission; + int guc_log_level; + int use_mmio_flip; + int mmio_debug; + bool verbose_state_checks; + bool nuclear_pageflip; + int edp_vswing; +}; + +extern struct i915_params i915 __read_mostly; + +#endif + -- GitLab From 482bfe5cc707b5bf5fb40d76377110fac125adee Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Dec 2015 13:08:16 +0200 Subject: [PATCH 0085/5324] drm/i915: Reorder i915_params struct. Move all the bool variables to the end as per the comment. Reviewed-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1450436898-20408-3-git-send-email-joonas.lahtinen@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_params.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 353951c13049..529929073120 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -45,6 +45,10 @@ struct i915_params { int enable_ips; int invert_brightness; int enable_cmd_parser; + int guc_log_level; + int use_mmio_flip; + int mmio_debug; + int edp_vswing; /* leave bools at the end to not create holes */ bool enable_hangcheck; bool fastboot; @@ -54,12 +58,8 @@ struct i915_params { bool disable_display; bool disable_vtd_wa; bool enable_guc_submission; - int guc_log_level; - int use_mmio_flip; - int mmio_debug; bool verbose_state_checks; bool nuclear_pageflip; - int edp_vswing; }; extern struct i915_params i915 __read_mostly; -- GitLab From b29ec92c4f5e6d45d8bae8194e664427a01c6687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 18 Dec 2015 19:24:39 +0200 Subject: [PATCH 0086/5324] drm/i915: Workaround CHV pipe C cursor fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out CHV pipe C was glued on somewhat poorly, and there's something wrong with the cursor. If the cursor straddles the left screen edge, and is then moved away from the edge or disabled, the pipe will often underrun. If enough underruns are triggered quickly enough the pipe will fall over and die (it just scans out a solid color and reports a constant underrun). We need to turn the disp2d power well off and on again to recover the pipe. None of that is very nice for the user, so let's just refuse to place the cursor in the compromised position. The ddx appears to fall back to swcursor when the ioctl returns an error, so theoretically there's no loss of functionality for the user (discounting swcursor bugs). I suppose most cursors images actually have the hotspot not exactly at 0,0 so under typical conditions the fallback will in fact kick in as soon as the cursor touches the left edge of the screen. Any atomic compositor should anyway be prepared to fall back to GPU composition when things don't work out, so there should be no problem with those. Other things that I tried to solve this include flipping all display related clock gating knobs I could find, increasing the minimum gtt alignment all the way up to 512k. I also tried to see if there are more specific screen coordinates that hit the bug, but the findings were somewhat inconclusive. Sometimes the failures happen almost across the whole left edge, sometimes more at the very top and around the bottom half. I wasn't able to find any real pattern to these variations, so it seems our only choice is to just refuse to straddle the left screen edge at all. Cc: stable@vger.kernel.org Cc: Jason Plum Testcase: igt/kms_chv_cursor_fail Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826 Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 11af6f52b3e4..7d01b986a012 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14059,6 +14059,7 @@ intel_check_cursor_plane(struct drm_plane *plane, struct drm_crtc *crtc = crtc_state->base.crtc; struct drm_framebuffer *fb = state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); + enum pipe pipe = to_intel_plane(plane)->pipe; unsigned stride; int ret; @@ -14092,6 +14093,22 @@ intel_check_cursor_plane(struct drm_plane *plane, return -EINVAL; } + /* + * There's something wrong with the cursor on CHV pipe C. + * If it straddles the left edge of the screen then + * moving it away from the edge or disabling it often + * results in a pipe underrun, and often that can lead to + * dead pipe (constant underrun reported, and it scans + * out just a solid color). To recover from that, the + * display power well must be turned off and on again. + * Refuse the put the cursor into that compromised position. + */ + if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C && + state->visible && state->base.crtc_x < 0) { + DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n"); + return -EINVAL; + } + return 0; } -- GitLab From 4601b933c9dcb6802e3289d62bcdb52ea32425d6 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 19 Dec 2015 15:40:39 +0100 Subject: [PATCH 0087/5324] drm/i915: Remove obsolete code from intelfb_alloc() Clean up after 0c82312f3f15 ("drm/i915: Pin the ifbdev for the info->system_base GGTT mmapping"): At each of the remaining "goto out" in intelfb_alloc(), fb can only be either an ERR_PTR or NULL, so the call to drm_framebuffer_unreference() is now obsolete. Cc: Daniel Vetter Cc: Chris Wilson Signed-off-by: Lukas Wunner Link: http://patchwork.freedesktop.org/patch/msgid/56756c41.c306c20a.d0602.1830SMTPIN_ADDED_MISSING@mx.google.com Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_fbdev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index bea75cafc623..09840f4380f9 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -119,7 +119,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, { struct intel_fbdev *ifbdev = container_of(helper, struct intel_fbdev, helper); - struct drm_framebuffer *fb = NULL; + struct drm_framebuffer *fb; struct drm_device *dev = helper->dev; struct drm_i915_private *dev_priv = to_i915(dev); struct drm_mode_fb_cmd2 mode_cmd = {}; @@ -171,8 +171,6 @@ static int intelfb_alloc(struct drm_fb_helper *helper, out: mutex_unlock(&dev->struct_mutex); - if (!IS_ERR_OR_NULL(fb)) - drm_framebuffer_unreference(fb); return ret; } -- GitLab From 32753cb863af32eadc63330a6b9eaa481f83d341 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Dec 2015 14:27:26 +0200 Subject: [PATCH 0088/5324] drm/i915: Simplify _STATE_ debug macros Take advantage of WARN return value to simplify the flow. Cc: Rob Clark Reviewed-by: Chris Wilson Reported-by: Chris Wilson Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1450441647-23924-2-git-send-email-joonas.lahtinen@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 89788dead96a..e0782b0fed73 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -88,23 +88,18 @@ */ #define I915_STATE_WARN(condition, format...) ({ \ int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) { \ - if (i915.verbose_state_checks) \ - WARN(1, format); \ - else \ + if (unlikely(__ret_warn_on)) \ + if (!WARN(i915.verbose_state_checks, format)) \ DRM_ERROR(format); \ - } \ unlikely(__ret_warn_on); \ }) #define I915_STATE_WARN_ON(condition) ({ \ int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) { \ - if (i915.verbose_state_checks) \ - WARN(1, "WARN_ON(" #condition ")\n"); \ - else \ + if (unlikely(__ret_warn_on)) \ + if (!WARN(i915.verbose_state_checks, \ + "WARN_ON(" #condition ")\n")) \ DRM_ERROR("WARN_ON(" #condition ")\n"); \ - } \ unlikely(__ret_warn_on); \ }) -- GitLab From 152b22627c67c6e5f29ad6ec939ac7e6f52e6c7d Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Fri, 18 Dec 2015 14:27:27 +0200 Subject: [PATCH 0089/5324] drm/i915: Compile-time concatenate WARN_ON macro strings Using __stringify(x) instead of #x adds support for macros as a parameter and compile-time concatenation reduces the runtime overhead. Slightly increases the .text size but should not matter. v2: - Define I915_STATE_WARN_ON though I915_STATE_WARN (Bikeshed inspiration by Chris) v3: - More specific commit message v4: - Do not directly pass arbitary string as format, instead guard with "%s" (Dave) Cc: Rob Clark Cc: Dave Gordon Reviewed-by: Chris Wilson (v3) Acked-by: Daniel Vetter Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1450441647-23924-3-git-send-email-joonas.lahtinen@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e0782b0fed73..1d8279c220b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -70,11 +70,11 @@ BUILD_BUG_ON(__i915_warn_cond); \ WARN(__i915_warn_cond, "WARN_ON(" #x ")"); }) #else -#define WARN_ON(x) WARN((x), "WARN_ON(%s)", #x ) +#define WARN_ON(x) WARN((x), "%s", "WARN_ON(" __stringify(x) ")") #endif #undef WARN_ON_ONCE -#define WARN_ON_ONCE(x) WARN_ONCE((x), "WARN_ON_ONCE(%s)", #x ) +#define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")") #define MISSING_CASE(x) WARN(1, "Missing switch case (%lu) in %s\n", \ (long) (x), __func__); @@ -94,14 +94,8 @@ unlikely(__ret_warn_on); \ }) -#define I915_STATE_WARN_ON(condition) ({ \ - int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) \ - if (!WARN(i915.verbose_state_checks, \ - "WARN_ON(" #condition ")\n")) \ - DRM_ERROR("WARN_ON(" #condition ")\n"); \ - unlikely(__ret_warn_on); \ -}) +#define I915_STATE_WARN_ON(x) \ + I915_STATE_WARN((x), "%s", "WARN_ON(" __stringify(x) ")") static inline const char *yesno(bool v) { -- GitLab From 0bff4858653312a10c83709e0009c3adb87e6f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 10 Dec 2015 18:22:31 +0200 Subject: [PATCH 0090/5324] drm/i915: Unbreak check_digital_port_conflicts() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atomic changes broke check_digital_port_conflicts(). It needs to look at the global situation instead of just trying to find a conflict within the current atomic state. This bug made my HSW explode spectacularly after I had split the DDI encoders into separate DP and HDMI encoders. With the fix, things seem much more solid. I hope holding the connection_mutex is enough protection that we can actually walk the connectors even if they're not part of the current atomic state... v2: Regenerate the patch so that it actually applies (Jani) Cc: stable@vger.kernel.org Cc: Ander Conselvan de Oliveira Fixes: 5448a00d3f06 ("drm/i915: Don't use staged config in check_digital_port_conflicts()") Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1449764551-12466-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7d01b986a012..f1598f765e3a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12270,18 +12270,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, static bool check_digital_port_conflicts(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; - struct intel_encoder *encoder; struct drm_connector *connector; - struct drm_connector_state *connector_state; unsigned int used_ports = 0; - int i; /* * Walk the connector list instead of the encoder * list to detect the problem on ddi platforms * where there's just one encoder per digital port. */ - for_each_connector_in_state(state, connector, connector_state, i) { + drm_for_each_connector(connector, dev) { + struct drm_connector_state *connector_state; + struct intel_encoder *encoder; + + connector_state = drm_atomic_get_existing_connector_state(state, connector); + if (!connector_state) + connector_state = connector->state; + if (!connector_state->best_encoder) continue; -- GitLab From dd97950a4cb7218fac38570e2e12c57a2cfd8312 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:52 +0200 Subject: [PATCH 0091/5324] drm/i915/bios: add proper documentation for the Video BIOS Table (VBT) Add an overview and documentation for the VBT/BDB header structures. Acked-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/3d826d4600688ca3518713776ab5bd8a8fc9f20f.1450702954.git.jani.nikula@intel.com --- Documentation/DocBook/gpu.tmpl | 6 +++++ drivers/gpu/drm/i915/intel_bios.c | 24 ++++++++++++++++++- drivers/gpu/drm/i915/intel_bios.h | 38 +++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 03f01e76add7..0061f22d126d 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -4108,6 +4108,12 @@ int num_ioctls; !Pdrivers/gpu/drm/i915/intel_csr.c csr support for dmc !Idrivers/gpu/drm/i915/intel_csr.c + + Video BIOS Table (VBT) +!Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT) +!Idrivers/gpu/drm/i915/intel_bios.c +!Idrivers/gpu/drm/i915/intel_bios.h + diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index eba3e0f87181..b6ccba13779e 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -31,6 +31,28 @@ #include "i915_drv.h" #include "intel_bios.h" +/** + * DOC: Video BIOS Table (VBT) + * + * The Video BIOS Table, or VBT, provides platform and board specific + * configuration information to the driver that is not discoverable or available + * through other means. The configuration is mostly related to display + * hardware. The VBT is available via the ACPI OpRegion or, on older systems, in + * the PCI ROM. + * + * The VBT consists of a VBT Header (defined as &struct vbt_header), a BDB + * Header (&struct bdb_header), and a number of BIOS Data Blocks (BDB) that + * contain the actual configuration information. The VBT Header, and thus the + * VBT, begins with "$VBT" signature. The VBT Header contains the offset of the + * BDB Header. The data blocks are concatenated after the BDB Header. The data + * blocks have a 1-byte Block ID, 2-byte Block Size, and Block Size bytes of + * data. (Block 53, the MIPI Sequence Block is an exception.) + * + * The driver parses the VBT during load. The relevant information is stored in + * driver private data for ease of use, and the actual VBT is not read after + * that. + */ + #define SLAVE_ADDR1 0x70 #define SLAVE_ADDR2 0x72 @@ -1285,7 +1307,7 @@ static const struct vbt_header *find_vbt(void __iomem *bios, size_t size) /** * intel_bios_init - find VBT and initialize settings from the BIOS - * @dev: DRM device + * @dev_priv: i915 device instance * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 54eac1003a1e..2dc46a98c332 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -28,22 +28,40 @@ #ifndef _I830_BIOS_H_ #define _I830_BIOS_H_ +/** + * struct vbt_header - VBT Header structure + * @signature: VBT signature, always starts with "$VBT" + * @version: Version of this structure + * @header_size: Size of this structure + * @vbt_size: Size of VBT (VBT Header, BDB Header and data blocks) + * @vbt_checksum: Checksum + * @reserved0: Reserved + * @bdb_offset: Offset of &struct bdb_header from beginning of VBT + * @aim_offset: Offsets of add-in data blocks from beginning of VBT + */ struct vbt_header { - u8 signature[20]; /**< Always starts with 'VBT$' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 vbt_size; /**< in bytes */ + u8 signature[20]; + u16 version; + u16 header_size; + u16 vbt_size; u8 vbt_checksum; u8 reserved0; - u32 bdb_offset; /**< from beginning of VBT */ - u32 aim_offset[4]; /**< from beginning of VBT */ + u32 bdb_offset; + u32 aim_offset[4]; } __packed; +/** + * struct bdb_header - BDB Header structure + * @signature: BDB signature "BIOS_DATA_BLOCK" + * @version: Version of the data block definitions + * @header_size: Size of this structure + * @bdb_size: Size of BDB (BDB Header and data blocks) + */ struct bdb_header { - u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 bdb_size; /**< in bytes */ + u8 signature[16]; + u16 version; + u16 header_size; + u16 bdb_size; } __packed; /* strictly speaking, this is a "skip" block, but it has interesting info */ -- GitLab From bf8a0af0cc9f9de9e54aefd1afd8c23b91809e41 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 24 Nov 2015 11:29:02 +0100 Subject: [PATCH 0092/5324] drm/i915/skl: Do not allow scaling when crtc is disabled. This fixes a warning when the crtc is turned off. In that case fb will be NULL, and crtc_clock will be 0. Because the crtc is no longer active this is not a bug, and shouldn't trigger the WARN_ON. Also remove handling a null crtc_state, with all transitional helpers gone this can no longer happen. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1448360945-5723-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f1598f765e3a..9928ca4027be 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13850,7 +13850,7 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state struct drm_i915_private *dev_priv; int crtc_clock, cdclk; - if (!intel_crtc || !crtc_state) + if (!intel_crtc || !crtc_state->base.enable) return DRM_PLANE_HELPER_NO_SCALING; dev = intel_crtc->base.dev; -- GitLab From 565602d7501a3e83580289d7d6da9b15838cfbe3 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 10 Dec 2015 12:33:57 +0100 Subject: [PATCH 0093/5324] drm/i915: Do not acquire crtc state to check clock during modeset, v4. Parallel modesets are still not allowed, but this will allow updating a different crtc during a modeset if the clock is not changed. Additionally when all pipes are DPMS off the cdclk will be lowered to the minimum allowed. Changes since v1: - Add dev_priv->active_crtcs for tracking which crtcs are active. - Rename min_cdclk to min_pixclk and move to dev_priv. - Add a active_crtcs mask which is updated atomically. - Add intel_atomic_state->modeset which is set on modesets. - Commit new pixclk/active_crtcs right after state swap. Changes since v2: - Make the changes related to max_pixel_rate calculations more readable. Changes since v3: - Add cherryview and missing WARN_ON to readout. Signed-off-by: Maarten Lankhorst Reviewed-by: Mika Kahola --- drivers/gpu/drm/i915/i915_drv.h | 5 + drivers/gpu/drm/i915/intel_atomic.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 143 +++++++++++++++++++-------- drivers/gpu/drm/i915/intel_drv.h | 7 +- 4 files changed, 116 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1d8279c220b4..73da52a20c82 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1819,8 +1819,13 @@ struct drm_i915_private { struct intel_pipe_crc pipe_crc[I915_MAX_PIPES]; #endif + /* dpll and cdclk state is protected by connection_mutex */ int num_shared_dpll; struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; + + unsigned int active_crtcs; + unsigned int min_pixclk[I915_MAX_PIPES]; + int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; struct i915_workarounds workarounds; diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index d0b1c9afa35e..4625f8a9ba12 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -308,5 +308,5 @@ void intel_atomic_state_clear(struct drm_atomic_state *s) { struct intel_atomic_state *state = to_intel_atomic_state(s); drm_atomic_state_default_clear(&state->base); - state->dpll_set = false; + state->dpll_set = state->modeset = false; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9928ca4027be..83320695a716 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6063,22 +6063,31 @@ static int broxton_calc_cdclk(struct drm_i915_private *dev_priv, static int intel_mode_max_pixclk(struct drm_device *dev, struct drm_atomic_state *state) { - struct intel_crtc *intel_crtc; - struct intel_crtc_state *crtc_state; - int max_pixclk = 0; + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + unsigned max_pixclk = 0, i; + enum pipe pipe; - for_each_intel_crtc(dev, intel_crtc) { - crtc_state = intel_atomic_get_crtc_state(state, intel_crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); + memcpy(intel_state->min_pixclk, dev_priv->min_pixclk, + sizeof(intel_state->min_pixclk)); - if (!crtc_state->base.enable) - continue; + for_each_crtc_in_state(state, crtc, crtc_state, i) { + int pixclk = 0; + + if (crtc_state->enable) + pixclk = crtc_state->adjusted_mode.crtc_clock; - max_pixclk = max(max_pixclk, - crtc_state->base.adjusted_mode.crtc_clock); + intel_state->min_pixclk[i] = pixclk; } + if (!intel_state->active_crtcs) + return 0; + + for_each_pipe(dev_priv, pipe) + max_pixclk = max(intel_state->min_pixclk[pipe], max_pixclk); + return max_pixclk; } @@ -6383,6 +6392,9 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) for_each_power_domain(domain, domains) intel_display_power_put(dev_priv, domain); intel_crtc->enabled_power_domains = 0; + + dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe); + dev_priv->min_pixclk[intel_crtc->pipe] = 0; } /* @@ -9679,29 +9691,41 @@ static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state) /* compute the max rate for new configuration */ static int ilk_max_pixel_rate(struct drm_atomic_state *state) { - struct intel_crtc *intel_crtc; + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct drm_i915_private *dev_priv = state->dev->dev_private; + struct drm_crtc *crtc; + struct drm_crtc_state *cstate; struct intel_crtc_state *crtc_state; - int max_pixel_rate = 0; + unsigned max_pixel_rate = 0, i; + enum pipe pipe; - for_each_intel_crtc(state->dev, intel_crtc) { - int pixel_rate; + memcpy(intel_state->min_pixclk, dev_priv->min_pixclk, + sizeof(intel_state->min_pixclk)); - crtc_state = intel_atomic_get_crtc_state(state, intel_crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); + for_each_crtc_in_state(state, crtc, cstate, i) { + int pixel_rate; - if (!crtc_state->base.enable) + crtc_state = to_intel_crtc_state(cstate); + if (!crtc_state->base.enable) { + intel_state->min_pixclk[i] = 0; continue; + } pixel_rate = ilk_pipe_pixel_rate(crtc_state); /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ - if (IS_BROADWELL(state->dev) && crtc_state->ips_enabled) + if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95); - max_pixel_rate = max(max_pixel_rate, pixel_rate); + intel_state->min_pixclk[i] = pixel_rate; } + if (!intel_state->active_crtcs) + return 0; + + for_each_pipe(dev_priv, pipe) + max_pixel_rate = max(intel_state->min_pixclk[pipe], max_pixel_rate); + return max_pixel_rate; } @@ -13208,15 +13232,27 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state) static int intel_modeset_checks(struct drm_atomic_state *state) { - struct drm_device *dev = state->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct drm_i915_private *dev_priv = state->dev->dev_private; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int ret = 0, i; if (!check_digital_port_conflicts(state)) { DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n"); return -EINVAL; } + intel_state->modeset = true; + intel_state->active_crtcs = dev_priv->active_crtcs; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (crtc_state->active) + intel_state->active_crtcs |= 1 << i; + else + intel_state->active_crtcs &= ~(1 << i); + } + /* * See if the config requires any additional preparation, e.g. * to adjust global state with pipes off. We need to do this @@ -13240,7 +13276,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state) intel_modeset_clear_plls(state); - if (IS_HASWELL(dev)) + if (IS_HASWELL(dev_priv)) return haswell_mode_set_planes_workaround(state); return 0; @@ -13458,12 +13494,12 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool async) { + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; - int ret = 0; - int i; - bool any_ms = false; + int ret = 0, i; + bool hw_check = intel_state->modeset; ret = intel_atomic_prepare_commit(dev, state, async); if (ret) { @@ -13474,13 +13510,18 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_helper_swap_state(dev, state); dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; + if (intel_state->modeset) { + memcpy(dev_priv->min_pixclk, intel_state->min_pixclk, + sizeof(intel_state->min_pixclk)); + dev_priv->active_crtcs = intel_state->active_crtcs; + } + for_each_crtc_in_state(state, crtc, crtc_state, i) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); if (!needs_modeset(crtc->state)) continue; - any_ms = true; intel_pre_plane_update(intel_crtc); if (crtc_state->active) { @@ -13505,7 +13546,7 @@ static int intel_atomic_commit(struct drm_device *dev, * update the the output configuration. */ intel_modeset_update_crtc_state(state); - if (any_ms) { + if (intel_state->modeset) { intel_shared_dpll_commit(state); drm_atomic_helper_update_legacy_modeset_state(state->dev, state); @@ -13532,7 +13573,7 @@ static int intel_atomic_commit(struct drm_device *dev, put_domains = modeset_get_crtc_power_domains(crtc); /* make sure intel_modeset_check_state runs */ - any_ms = true; + hw_check = true; } if (!modeset) @@ -13559,7 +13600,7 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_helper_cleanup_planes(dev, state); mutex_unlock(&dev->struct_mutex); - if (any_ms) + if (hw_check) intel_modeset_check_state(dev, state); drm_atomic_state_free(state); @@ -15591,16 +15632,40 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) struct intel_connector *connector; int i; + dev_priv->active_crtcs = 0; + for_each_intel_crtc(dev, crtc) { - __drm_atomic_helper_crtc_destroy_state(&crtc->base, crtc->base.state); - memset(crtc->config, 0, sizeof(*crtc->config)); - crtc->config->base.crtc = &crtc->base; + struct intel_crtc_state *crtc_state = crtc->config; + int pixclk = 0; - crtc->active = dev_priv->display.get_pipe_config(crtc, - crtc->config); + __drm_atomic_helper_crtc_destroy_state(&crtc->base, &crtc_state->base); + memset(crtc_state, 0, sizeof(*crtc_state)); + crtc_state->base.crtc = &crtc->base; - crtc->base.state->active = crtc->active; - crtc->base.enabled = crtc->active; + crtc_state->base.active = crtc_state->base.enable = + dev_priv->display.get_pipe_config(crtc, crtc_state); + + crtc->base.enabled = crtc_state->base.enable; + crtc->active = crtc_state->base.active; + + if (crtc_state->base.active) { + dev_priv->active_crtcs |= 1 << crtc->pipe; + + if (IS_BROADWELL(dev_priv)) { + pixclk = ilk_pipe_pixel_rate(crtc_state); + + /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ + if (crtc_state->ips_enabled) + pixclk = DIV_ROUND_UP(pixclk * 100, 95); + } else if (IS_VALLEYVIEW(dev_priv) || + IS_CHERRYVIEW(dev_priv) || + IS_BROXTON(dev_priv)) + pixclk = crtc_state->base.adjusted_mode.crtc_clock; + else + WARN_ON(dev_priv->display.modeset_calc_cdclk); + } + + dev_priv->min_pixclk[crtc->pipe] = pixclk; readout_plane_state(crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d523ebb2f89d..9b051e908845 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -246,7 +246,12 @@ struct intel_atomic_state { struct drm_atomic_state base; unsigned int cdclk; - bool dpll_set; + + bool dpll_set, modeset; + + unsigned int active_crtcs; + unsigned int min_pixclk[I915_MAX_PIPES]; + struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; struct intel_wm_config wm_config; }; -- GitLab From 1a617b77658e0ab1cb58a9412c5a02f862bd4fcd Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 3 Dec 2015 14:31:06 +0100 Subject: [PATCH 0094/5324] drm/i915: Keep track of the cdclk as if all crtc's were active. On skylake when calculating plane visibility with the crtc in dpms off mode the real cdclk may be different from what it would be if the crtc was active. This may result in a WARN_ON(cdclk < crtc_clock) from skl_max_scale. The fix is to keep a atomic_cdclk that would be true if all crtc's were active. This is required to get the same calculations done correctly regardless of dpms mode. Signed-off-by: Maarten Lankhorst Reviewed-by: Mika Kahola Link: http://patchwork.freedesktop.org/patch/msgid/1447945645-32005-12-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 55 +++++++++++++++++++--------- drivers/gpu/drm/i915/intel_drv.h | 6 +++ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 73da52a20c82..cf7e0fce01ac 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1774,7 +1774,7 @@ struct drm_i915_private { unsigned int fsb_freq, mem_freq, is_ddr3; unsigned int skl_boot_cdclk; - unsigned int cdclk_freq, max_cdclk_freq; + unsigned int cdclk_freq, max_cdclk_freq, atomic_cdclk_freq; unsigned int max_dotclk_freq; unsigned int hpll_freq; unsigned int czclk_freq; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 83320695a716..30cd48ea61e8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5370,6 +5370,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv, static void modeset_update_crtc_power_domains(struct drm_atomic_state *state) { + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_device *dev = state->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long put_domains[I915_MAX_PIPES] = {}; @@ -5383,13 +5384,9 @@ static void modeset_update_crtc_power_domains(struct drm_atomic_state *state) modeset_get_crtc_power_domains(crtc); } - if (dev_priv->display.modeset_commit_cdclk) { - unsigned int cdclk = to_intel_atomic_state(state)->cdclk; - - if (cdclk != dev_priv->cdclk_freq && - !WARN_ON(!state->allow_modeset)) - dev_priv->display.modeset_commit_cdclk(state); - } + if (dev_priv->display.modeset_commit_cdclk && + intel_state->dev_cdclk != dev_priv->cdclk_freq) + dev_priv->display.modeset_commit_cdclk(state); for (i = 0; i < I915_MAX_PIPES; i++) if (put_domains[i]) @@ -6096,13 +6093,18 @@ static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state) struct drm_device *dev = state->dev; struct drm_i915_private *dev_priv = dev->dev_private; int max_pixclk = intel_mode_max_pixclk(dev, state); + struct intel_atomic_state *intel_state = + to_intel_atomic_state(state); if (max_pixclk < 0) return max_pixclk; - to_intel_atomic_state(state)->cdclk = + intel_state->cdclk = intel_state->dev_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk); + if (!intel_state->active_crtcs) + intel_state->dev_cdclk = valleyview_calc_cdclk(dev_priv, 0); + return 0; } @@ -6111,13 +6113,18 @@ static int broxton_modeset_calc_cdclk(struct drm_atomic_state *state) struct drm_device *dev = state->dev; struct drm_i915_private *dev_priv = dev->dev_private; int max_pixclk = intel_mode_max_pixclk(dev, state); + struct intel_atomic_state *intel_state = + to_intel_atomic_state(state); if (max_pixclk < 0) return max_pixclk; - to_intel_atomic_state(state)->cdclk = + intel_state->cdclk = intel_state->dev_cdclk = broxton_calc_cdclk(dev_priv, max_pixclk); + if (!intel_state->active_crtcs) + intel_state->dev_cdclk = broxton_calc_cdclk(dev_priv, 0); + return 0; } @@ -6160,8 +6167,10 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) static void valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; - unsigned int req_cdclk = to_intel_atomic_state(old_state)->cdclk; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_atomic_state *old_intel_state = + to_intel_atomic_state(old_state); + unsigned req_cdclk = old_intel_state->dev_cdclk; /* * FIXME: We can end up here with all power domains off, yet @@ -9683,7 +9692,9 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv) static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; - unsigned int req_cdclk = to_intel_atomic_state(old_state)->cdclk; + struct intel_atomic_state *old_intel_state = + to_intel_atomic_state(old_state); + unsigned int req_cdclk = old_intel_state->dev_cdclk; broxton_set_cdclk(dev, req_cdclk); } @@ -9809,6 +9820,7 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk) static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state) { struct drm_i915_private *dev_priv = to_i915(state->dev); + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); int max_pixclk = ilk_max_pixel_rate(state); int cdclk; @@ -9831,7 +9843,9 @@ static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state) return -EINVAL; } - to_intel_atomic_state(state)->cdclk = cdclk; + intel_state->cdclk = intel_state->dev_cdclk = cdclk; + if (!intel_state->active_crtcs) + intel_state->dev_cdclk = 337500; return 0; } @@ -9839,7 +9853,9 @@ static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state) static void broadwell_modeset_commit_cdclk(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; - unsigned int req_cdclk = to_intel_atomic_state(old_state)->cdclk; + struct intel_atomic_state *old_intel_state = + to_intel_atomic_state(old_state); + unsigned req_cdclk = old_intel_state->dev_cdclk; broadwell_set_cdclk(dev, req_cdclk); } @@ -13261,18 +13277,15 @@ static int intel_modeset_checks(struct drm_atomic_state *state) * adjusted_mode bits in the crtc directly. */ if (dev_priv->display.modeset_calc_cdclk) { - unsigned int cdclk; - ret = dev_priv->display.modeset_calc_cdclk(state); - cdclk = to_intel_atomic_state(state)->cdclk; - if (!ret && cdclk != dev_priv->cdclk_freq) + if (!ret && intel_state->dev_cdclk != dev_priv->cdclk_freq) ret = intel_modeset_all_pipes(state); if (ret < 0) return ret; } else - to_intel_atomic_state(state)->cdclk = dev_priv->cdclk_freq; + to_intel_atomic_state(state)->cdclk = dev_priv->atomic_cdclk_freq; intel_modeset_clear_plls(state); @@ -13514,6 +13527,7 @@ static int intel_atomic_commit(struct drm_device *dev, memcpy(dev_priv->min_pixclk, intel_state->min_pixclk, sizeof(intel_state->min_pixclk)); dev_priv->active_crtcs = intel_state->active_crtcs; + dev_priv->atomic_cdclk_freq = intel_state->cdclk; } for_each_crtc_in_state(state, crtc, crtc_state, i) { @@ -15235,7 +15249,12 @@ static void i915_disable_vga(struct drm_device *dev) void intel_modeset_init_hw(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + intel_update_cdclk(dev); + + dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; + intel_prepare_ddi(dev); intel_init_clock_gating(dev); intel_enable_gt_powersave(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9b051e908845..0438b575e1fa 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -247,6 +247,12 @@ struct intel_atomic_state { unsigned int cdclk; + /* + * Calculated device cdclk, can be different from cdclk + * only when all crtc's are DPMS off. + */ + unsigned int dev_cdclk; + bool dpll_set, modeset; unsigned int active_crtcs; -- GitLab From 35c08f43462206efb999ebc2478443e8d611161d Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 3 Dec 2015 14:31:07 +0100 Subject: [PATCH 0095/5324] drm/i915: Calculate visibility in check_plane correctly regardless of dpms. When the crtc is configured but not active we currently clip to (0,0)x(0,0). This results in differences in calculations depending on dpms setting. When the crtc is enabled but not active run check_plane as if it were on, but afterwards set plane_state->visible = false for the checks. Signed-off-by: Maarten Lankhorst Reviewed-by: Mika Kahola Link: http://patchwork.freedesktop.org/patch/msgid/1447945645-32005-13-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic_plane.c | 4 ++-- drivers/gpu/drm/i915/intel_display.c | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index c6bb0fc1edfb..856c3118bb87 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -152,9 +152,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane, intel_state->clip.x1 = 0; intel_state->clip.y1 = 0; intel_state->clip.x2 = - crtc_state->base.active ? crtc_state->pipe_src_w : 0; + crtc_state->base.enable ? crtc_state->pipe_src_w : 0; intel_state->clip.y2 = - crtc_state->base.active ? crtc_state->pipe_src_h : 0; + crtc_state->base.enable ? crtc_state->pipe_src_h : 0; if (state->fb && intel_rotation_90_or_270(state->rotation)) { if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 30cd48ea61e8..eea2cd26ba17 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11873,8 +11873,13 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, if (!was_crtc_enabled && WARN_ON(was_visible)) was_visible = false; - if (!is_crtc_enabled && WARN_ON(visible)) - visible = false; + /* + * Visibility is calculated as if the crtc was on, but + * after scaler setup everything depends on it being off + * when the crtc isn't active. + */ + if (!is_crtc_enabled) + to_intel_plane_state(plane_state)->visible = visible = false; if (!was_visible && !visible) return 0; -- GitLab From f8d03ea0053b23de42c828d559016eabe0b91523 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Wed, 23 Dec 2015 16:11:35 +0800 Subject: [PATCH 0096/5324] drm/i915: increase the tries for HDMI hotplug live status checking The total delay of HDMI hotplug detecting with 30ms is sometimes not enoughtfor HDMI live status up with specific HDMI monitors in BSW platform. After doing experiments for following monitors, it needs 80ms at least for those worst cases. Lenovo L246 1xwA (4 failed, necessary hot-plug delay: 58/40/60/40ms) Philips HH2AP (9 failed, necessary hot-plug delay: 80/50/50/60/46/40/58/58/39ms) BENQ ET-0035-N (6 failed, necessary hot-plug delay: 60/50/50/80/80/40ms) DELL U2713HM (2 failed, necessary hot-plug delay: 58/59ms) HP HP-LP2475w (5 failed, necessary hot-plug delay: 70/50/40/60/40ms) It looks like 70-80 ms is BSW platform needs in some bad cases of the monitors at this end (8 times delay at most). Keep less than 100ms for HDCP pulse HPD low (with at least 100ms) to respond a plug out. Reviewed-by: Cooper Chiou Tested-by: Gary Wang Cc: Gavin Hindman Cc: Sonika Jindal Cc: Shashank Sharma Cc: Shobhit Kumar Signed-off-by: Gary Wang Link: http://patchwork.freedesktop.org/patch/msgid/1450858295-12804-1-git-send-email-gary.c.wang@intel.com Tested-by: Shobhit Kumar Cc: drm-intel-fixes@lists.freedesktop.org Fixes: 237ed86c693d ("drm/i915: Check live status before reading edid") Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 drivers/gpu/drm/i915/intel_hdmi.c diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c old mode 100644 new mode 100755 index 79ebce2f68b1..054aa7613390 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1392,7 +1392,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - for (try = 0; !live_status && try < 4; try++) { + for (try = 0; !live_status && try < 9; try++) { if (try) msleep(10); live_status = intel_digital_port_connected(dev_priv, -- GitLab From dde58ca4367a216d51c4e034f1f0195e5923c934 Mon Sep 17 00:00:00 2001 From: Nicholas Mc Guire Date: Tue, 22 Dec 2015 17:13:50 +0100 Subject: [PATCH 0097/5324] Orangefs: use kzalloc for kmalloc + memset 0 This is an API consolidation only. The use of kmalloc + memset to 0 should be equivalent to kzalloc in this case. Signed-off-by: Nicholas Mc Guire Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 7319f1a2ecb8..9eb7972ae10d 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -365,10 +365,9 @@ static ssize_t orangefs_debug_write(struct file *file, count = ORANGEFS_MAX_DEBUG_STRING_LEN + 1; } - buf = kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); + buf = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL); if (!buf) goto out; - memset(buf, 0, ORANGEFS_MAX_DEBUG_STRING_LEN); if (copy_from_user(buf, ubuf, count - 1)) { gossip_debug(GOSSIP_DEBUGFS_DEBUG, -- GitLab From eb57bcc2718a9fb5eaea80e0d76e53afac6ae2ec Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 21 Dec 2015 14:49:29 +0100 Subject: [PATCH 0098/5324] orangefs: fix typo in ornagefs_inode_lock Orangefs fails to build on 32-bit SMP configurations due to a simple misspelling, this does the obvious fix. Signed-off-by: Arnd Bergmann Fixes: 575e946125f7 ("Orangefs: change pvfs2 filenames to orangefs") Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 0b7ba0496aa3..fe8284045a40 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -770,7 +770,7 @@ do { \ static inline void orangefs_i_size_write(struct inode *inode, loff_t i_size) { #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) - ornagefs_inode_lock(inode); + orangefs_inode_lock(inode); #endif i_size_write(inode, i_size); #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) -- GitLab From 4f20854bf7363cc28d4088f2fa954f1a63b5efce Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Mon, 28 Dec 2015 11:01:51 -0500 Subject: [PATCH 0099/5324] Orangefs: don't change EXTRAVERSION Stephen Rothwell taught me how to use CONFIG_LOCALVERSION_AUTO so now I can quit putting random things in EXTRAVERSION for my own use and then forgetting to take them out... Signed-off-by: Mike Marshall --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index aca4a73ad069..3a0234f50f36 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc1-o +EXTRAVERSION = -rc1 NAME = Blurry Fish Butt # *DOCUMENTATION* -- GitLab From eba51190f3c6ffcb685fc100a4234095b0146150 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 29 Dec 2015 14:20:43 -0800 Subject: [PATCH 0100/5324] drm/i915: Fix whitespace (trivial) Signed-off-by: Ben Widawsky Link: http://patchwork.freedesktop.org/patch/msgid/1451427643-7266-1-git-send-email-benjamin.widawsky@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lrc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ca5c0e8a3bf5..973487a73be1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -538,8 +538,8 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) WARN(1, "Preemption without Lite Restore\n"); } - if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) || - (status & GEN8_CTX_STATUS_ELEMENT_SWITCH)) { + if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) || + (status & GEN8_CTX_STATUS_ELEMENT_SWITCH)) { if (execlists_check_remove_request(ring, status_id)) submit_contexts++; } -- GitLab From f987f4c28a0f9a1dee44ca33a29080859b70f24b Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 30 Dec 2015 13:04:28 -0500 Subject: [PATCH 0101/5324] Orangefs: don't trigger copy_attributes_to_inode from d_revalidate. Signed-off-by: Mike Marshall --- fs/orangefs/dcache.c | 50 +++++++++++++------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index 5dd9841df64e..0419981f773e 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -77,7 +77,7 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) /* * Verify that dentry is valid. * - * Should return 1 if dentry can still be trusted, else 0 + * Should return 1 if dentry can still be trusted, else 0. */ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) { @@ -92,49 +92,27 @@ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) /* find inode from dentry */ if (!dentry->d_inode) { - gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n", + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: negative dentry.\n", __func__); - goto invalid_exit; + goto out; } gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: inode valid.\n", __func__); inode = dentry->d_inode; - /* - * first perform a lookup to make sure that the object not only - * exists, but is still in the expected place in the name space - */ - if (!is_root_handle(inode)) { - if (!orangefs_revalidate_lookup(dentry)) - goto invalid_exit; - } else { - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s: root handle, lookup skipped.\n", - __func__); + /* skip root handle lookups. */ + if (is_root_handle(inode)) { + ret = 1; + goto out; } - /* now perform getattr */ - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s: doing getattr: inode: %p, handle: %pU\n", - __func__, - inode, - get_khandle_from_ino(inode)); - ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s: getattr %s (ret = %d), returning %s for dentry i_count=%d\n", - __func__, - (ret == 0 ? "succeeded" : "failed"), - ret, - (ret == 0 ? "valid" : "INVALID"), - atomic_read(&inode->i_count)); - if (ret != 0) - goto invalid_exit; - - /* dentry is valid! */ - return 1; - -invalid_exit: - return 0; + /* lookup the object. */ + if (orangefs_revalidate_lookup(dentry)) + ret = 1; + +out: + return ret; } const struct dentry_operations orangefs_dentry_operations = { -- GitLab From 62ab420f7458feb4ef1fa2ef094ee00af9844253 Mon Sep 17 00:00:00 2001 From: Insu Yun Date: Wed, 30 Dec 2015 10:59:29 -0500 Subject: [PATCH 0102/5324] i915: correctly handling failed allocation Since devm_kzalloc can be failed, it needs to be checked if not, NULL dereference could be happened. Signed-off-by: Insu Yun Link: http://patchwork.freedesktop.org/patch/msgid/1451491169-35068-1-git-send-email-wuninsu@gmail.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index a5e99ac305da..aa1f7bc8f4d0 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -666,6 +666,8 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) /* This is cheating a bit with the cleanup. */ vbt_panel = devm_kzalloc(dev->dev, sizeof(*vbt_panel), GFP_KERNEL); + if (!vbt_panel) + return NULL; vbt_panel->intel_dsi = intel_dsi; drm_panel_init(&vbt_panel->panel); -- GitLab From acaca36dd94d1bfe381a7425984991a06ba58f53 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 1 Jan 2016 10:01:52 +0100 Subject: [PATCH 0103/5324] OrangeFS: constify export_operations structures This export_operations structure is never modified, so declare it as const. Most other structures of this type are already const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index 52bc522ea21c..bee67b37d805 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -342,7 +342,7 @@ static int orangefs_encode_fh(struct inode *inode, return type; } -static struct export_operations orangefs_export_ops = { +static const struct export_operations orangefs_export_ops = { .encode_fh = orangefs_encode_fh, .fh_to_dentry = orangefs_fh_to_dentry, }; -- GitLab From c146c0b87f7cef247744a649f8c1d794d18bfcb7 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 2 Jan 2016 23:04:47 +0100 Subject: [PATCH 0104/5324] orangefs: Don't pollute global namespace Prefix public functions with "orangefs_" do don't pollute the global namespace. This fixes a build issue on UML which also has block_signals(). Signed-off-by: Richard Weinberger Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 4 ++-- fs/orangefs/orangefs-utils.c | 4 ++-- fs/orangefs/waitqueue.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index fe8284045a40..0c7a9cf9b8ef 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -576,9 +576,9 @@ void orangefs_op_initialize(struct orangefs_kernel_op_s *op); void orangefs_make_bad_inode(struct inode *inode); -void block_signals(sigset_t *); +void orangefs_block_signals(sigset_t *); -void set_signals(sigset_t *); +void orangefs_set_signals(sigset_t *); int orangefs_unmount_sb(struct super_block *sb); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index fa2a46521b7a..f21233201ce3 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -633,7 +633,7 @@ void orangefs_make_bad_inode(struct inode *inode) } /* Block all blockable signals... */ -void block_signals(sigset_t *orig_sigset) +void orangefs_block_signals(sigset_t *orig_sigset) { sigset_t mask; @@ -648,7 +648,7 @@ void block_signals(sigset_t *orig_sigset) } /* set the signal mask to the given template... */ -void set_signals(sigset_t *sigset) +void orangefs_set_signals(sigset_t *sigset) { sigprocmask(SIG_SETMASK, sigset, NULL); } diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 856a4b48fe23..e1415e3882ba 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -80,7 +80,7 @@ int service_operation(struct orangefs_kernel_op_s *op, /* mask out signals if this operation is not to be interrupted */ if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) - block_signals(&orig_sigset); + orangefs_block_signals(&orig_sigset); if (!(flags & ORANGEFS_OP_NO_SEMAPHORE)) { ret = mutex_lock_interruptible(&request_mutex); @@ -90,7 +90,7 @@ int service_operation(struct orangefs_kernel_op_s *op, */ if (ret < 0) { if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) - set_signals(&orig_sigset); + orangefs_set_signals(&orig_sigset); op->downcall.status = ret; gossip_debug(GOSSIP_WAIT_DEBUG, "orangefs: service_operation interrupted.\n"); @@ -160,7 +160,7 @@ int service_operation(struct orangefs_kernel_op_s *op, } if (!(flags & ORANGEFS_OP_INTERRUPTIBLE)) - set_signals(&orig_sigset); + orangefs_set_signals(&orig_sigset); BUG_ON(ret != op->downcall.status); /* retry if operation has not been serviced and if requested */ -- GitLab From 7d2214858f137ff5fe20d0fdc2823c12b4b54f46 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Mon, 4 Jan 2016 15:05:28 -0500 Subject: [PATCH 0105/5324] orangefs: Fix some more global namespace pollution. This only changes the names of things, so there is no functional change. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 4 ++-- fs/orangefs/dir.c | 23 ++++++++++++++--------- fs/orangefs/orangefs-bufmap.c | 10 +++++----- fs/orangefs/orangefs-bufmap.h | 6 +++--- fs/orangefs/orangefs-dev-proto.h | 32 +++++--------------------------- fs/orangefs/waitqueue.c | 8 ++++---- 6 files changed, 33 insertions(+), 50 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 5a9c53eb115f..e3bb15e344ed 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -600,7 +600,7 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) __func__); mutex_lock(&devreq_mutex); - if (get_bufmap_init()) + if (orangefs_get_bufmap_init()) orangefs_bufmap_finalize(); open_access_count--; @@ -693,7 +693,7 @@ static long dispatch_ioctl_command(unsigned int command, unsigned long arg) (struct ORANGEFS_dev_map_desc __user *) arg, sizeof(struct ORANGEFS_dev_map_desc)); - if (get_bufmap_init()) { + if (orangefs_get_bufmap_init()) { return -EINVAL; } else { return ret ? diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index c043894fc2bd..58558e37fb8a 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -52,7 +52,11 @@ static long decode_dirents(char *ptr, size_t size, readdir->dirent_array[i].d_name = buf + 4; readdir->dirent_array[i].d_length = len; - len = roundup8(4 + len + 1); + /* + * Round 4 + len + 1, which is the encoded size plus the string + * plus the null terminator to the nearest eight byte boundry. + */ + len = ((4 + len + 1) + 7) & ~7; if (size < len + 16) goto Einval; size -= len + 16; @@ -109,7 +113,7 @@ static void readdir_handle_dtor(struct orangefs_bufmap *bufmap, rhandle->readdir_response.dirent_array = NULL; if (rhandle->buffer_index >= 0) { - readdir_index_put(bufmap, rhandle->buffer_index); + orangefs_readdir_index_put(bufmap, rhandle->buffer_index); rhandle->buffer_index = -1; } if (rhandle->dents_buf) { @@ -175,7 +179,8 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) new_op->uses_shared_memory = 1; new_op->upcall.req.readdir.refn = orangefs_inode->refn; - new_op->upcall.req.readdir.max_dirent_count = MAX_DIRENT_COUNT_READDIR; + new_op->upcall.req.readdir.max_dirent_count = + ORANGEFS_MAX_DIRENT_COUNT_READDIR; gossip_debug(GOSSIP_DIR_DEBUG, "%s: upcall.req.readdir.refn.khandle: %pU\n", @@ -185,9 +190,9 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) new_op->upcall.req.readdir.token = *ptoken; get_new_buffer_index: - ret = readdir_index_get(&bufmap, &buffer_index); + ret = orangefs_readdir_index_get(&bufmap, &buffer_index); if (ret < 0) { - gossip_lerr("orangefs_readdir: readdir_index_get() failure (%d)\n", + gossip_lerr("orangefs_readdir: orangefs_readdir_index_get() failure (%d)\n", ret); goto out_free_op; } @@ -211,14 +216,14 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) gossip_debug(GOSSIP_DIR_DEBUG, "%s: Getting new buffer_index for retry of readdir..\n", __func__); - readdir_index_put(bufmap, buffer_index); + orangefs_readdir_index_put(bufmap, buffer_index); goto get_new_buffer_index; } if (ret == -EIO && op_state_purged(new_op)) { gossip_err("%s: Client is down. Aborting readdir call.\n", __func__); - readdir_index_put(bufmap, buffer_index); + orangefs_readdir_index_put(bufmap, buffer_index); goto out_free_op; } @@ -226,7 +231,7 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) gossip_debug(GOSSIP_DIR_DEBUG, "Readdir request failed. Status:%d\n", new_op->downcall.status); - readdir_index_put(bufmap, buffer_index); + orangefs_readdir_index_put(bufmap, buffer_index); if (ret >= 0) ret = new_op->downcall.status; goto out_free_op; @@ -241,7 +246,7 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) gossip_err("orangefs_readdir: Could not decode trailer buffer into a readdir response %d\n", ret); ret = bytes_decoded; - readdir_index_put(bufmap, buffer_index); + orangefs_readdir_index_put(bufmap, buffer_index); goto out_free_op; } diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 888aa28136ee..15baecb8094d 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -115,14 +115,14 @@ static DECLARE_WAIT_QUEUE_HEAD(bufmap_waitq); static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq); /* - * get_bufmap_init + * orangefs_get_bufmap_init * * If bufmap_init is 1, then the shared memory system, including the * buffer_index_array, is available. Otherwise, it is not. * * returns the value of bufmap_init */ -int get_bufmap_init(void) +int orangefs_get_bufmap_init(void) { return __orangefs_bufmap ? 1 : 0; } @@ -473,7 +473,7 @@ void orangefs_bufmap_put(struct orangefs_bufmap *bufmap, int buffer_index) } /* - * readdir_index_get() + * orangefs_readdir_index_get() * * gets a free descriptor, will sleep until one becomes * available if necessary. @@ -483,7 +483,7 @@ void orangefs_bufmap_put(struct orangefs_bufmap *bufmap, int buffer_index) * * returns 0 on success, -errno on failure */ -int readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) +int orangefs_readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) { struct orangefs_bufmap *bufmap = orangefs_bufmap_ref(); struct slot_args slargs; @@ -505,7 +505,7 @@ int readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index) return ret; } -void readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) +void orangefs_readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index) { struct slot_args slargs; diff --git a/fs/orangefs/orangefs-bufmap.h b/fs/orangefs/orangefs-bufmap.h index 112ec33a1b86..dff55e2857c5 100644 --- a/fs/orangefs/orangefs-bufmap.h +++ b/fs/orangefs/orangefs-bufmap.h @@ -15,7 +15,7 @@ int orangefs_bufmap_shift_query(void); int orangefs_bufmap_initialize(struct ORANGEFS_dev_map_desc *user_desc); -int get_bufmap_init(void); +int orangefs_get_bufmap_init(void); void orangefs_bufmap_finalize(void); @@ -23,9 +23,9 @@ int orangefs_bufmap_get(struct orangefs_bufmap **mapp, int *buffer_index); void orangefs_bufmap_put(struct orangefs_bufmap *bufmap, int buffer_index); -int readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index); +int orangefs_readdir_index_get(struct orangefs_bufmap **mapp, int *buffer_index); -void readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index); +void orangefs_readdir_index_put(struct orangefs_bufmap *bufmap, int buffer_index); int orangefs_bufmap_copy_from_iovec(struct orangefs_bufmap *bufmap, struct iov_iter *iter, diff --git a/fs/orangefs/orangefs-dev-proto.h b/fs/orangefs/orangefs-dev-proto.h index dc1951dd7045..5a8725a88eac 100644 --- a/fs/orangefs/orangefs-dev-proto.h +++ b/fs/orangefs/orangefs-dev-proto.h @@ -51,35 +51,13 @@ #define ORANGEFS_MAX_DEBUG_ARRAY_LEN 0x00000800 /* - * MAX_DIRENT_COUNT cannot be larger than ORANGEFS_REQ_LIMIT_LISTATTR. - * The value of ORANGEFS_REQ_LIMIT_LISTATTR has been changed from 113 to 60 - * to accomodate an attribute object with mirrored handles. - * MAX_DIRENT_COUNT is replaced by MAX_DIRENT_COUNT_READDIR and - * MAX_DIRENT_COUNT_READDIRPLUS, since readdir doesn't trigger a listattr - * but readdirplus might. -*/ -#define MAX_DIRENT_COUNT_READDIR 0x00000060 -#define MAX_DIRENT_COUNT_READDIRPLUS 0x0000003C + * The maximum number of directory entries in a single request is 96. + * XXX: Why can this not be higher. The client-side code can handle up to 512. + * XXX: What happens if we expect more than the client can return? + */ +#define ORANGEFS_MAX_DIRENT_COUNT_READDIR 96 #include "upcall.h" #include "downcall.h" -/* - * These macros differ from proto macros in that they don't do any - * byte-swappings and are used to ensure that kernel-clientcore interactions - * don't cause any unaligned accesses etc on 64 bit machines - */ -#ifndef roundup4 -#define roundup4(x) (((x)+3) & ~3) -#endif - -#ifndef roundup8 -#define roundup8(x) (((x)+7) & ~7) -#endif - -struct read_write_x { - __s64 off; - __s64 len; -}; - #endif diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index e1415e3882ba..751c3c640a52 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -180,7 +180,7 @@ int service_operation(struct orangefs_kernel_op_s *op, goto retry_servicing; /* op uses shared memory */ - if (get_bufmap_init() == 0) { + if (orangefs_get_bufmap_init() == 0) { /* * This operation uses the shared memory system AND * the system is not yet ready. This situation occurs @@ -194,7 +194,7 @@ int service_operation(struct orangefs_kernel_op_s *op, "Client core in-service status(%d).\n", is_daemon_in_service()); gossip_debug(GOSSIP_WAIT_DEBUG, "bufmap_init:%d.\n", - get_bufmap_init()); + orangefs_get_bufmap_init()); gossip_debug(GOSSIP_WAIT_DEBUG, "operation's status is 0x%0x.\n", op->op_state); @@ -222,13 +222,13 @@ int service_operation(struct orangefs_kernel_op_s *op, ret); gossip_debug(GOSSIP_WAIT_DEBUG, "Is shared memory available? (%d).\n", - get_bufmap_init()); + orangefs_get_bufmap_init()); spin_lock_irqsave(&op->lock, irqflags); finish_wait(&orangefs_bufmap_init_waitq, &wait_entry); spin_unlock_irqrestore(&op->lock, irqflags); - if (get_bufmap_init() == 0) { + if (orangefs_get_bufmap_init() == 0) { gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted. Aborting user's request(%s).\n", __func__, ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS, -- GitLab From 85096169860199f506ae18acd222d1d870f1ee96 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Mon, 4 Jan 2016 16:38:00 -0500 Subject: [PATCH 0106/5324] Orangefs: add orangefs to MAINTAINERS Signed-off-by: Mike Marshall --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e9caa4b28828..4848bd58b478 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7953,6 +7953,14 @@ S: Supported F: fs/overlayfs/ F: Documentation/filesystems/overlayfs.txt +ORANGEFS FILESYSTEM +M: Mike Marshall +L: pvfs2-developers@beowulf-underground.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux.git +S: Supported +F: fs/orangefs/ +F: Documentation/filesystems/orangefs.txt + P54 WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org -- GitLab From 934acce3c069a3d8b14085957248444145d9ec1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Winiarski?= Date: Tue, 29 Dec 2015 18:24:52 +0100 Subject: [PATCH 0107/5324] drm/i915: Avoid writing relocs with addresses in non-canonical form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to PRM, some parts of HW require the addresses to be in a canonical form, where bits [63:48] == [47]. Let's convert addresses to canonical form prior to relocating and return converted offsets to userspace. We also need to make sure that userspace is using addresses in canonical form in case of softpin. v2: Whitespace fixup, gen8_canonical_addr description (Chris, Ville) v3: Rebase on top of softpin, fix a hole in relocate_entry, s/expect/require (Chris) v4: Handle softpin in validate_exec_list (Chris) v5: Convert back to canonical form at copy_to_user time (Chris) v6: Don't use struct exec_object2 in place of exec_object v7: Use sign_extend64 for converting to canonical form (Joonas), reject non-canonical and non-page-aligned offset for softpin (Chris) v8: Convert back to non-canonical form in a function, split the test for EXEC_OBJECT_PINNED (Chris) v9: s/canonial/canonical, drop accidental double newline (Chris) Cc: Chris Wilson Cc: Michel Thierry Cc: Ville Syrjälä Signed-off-by: Michał Winiarski Link: http://patchwork.freedesktop.org/patch/msgid/1451409892-13708-1-git-send-email-michal.winiarski@intel.com Testcase: igt/gem_bad_reloc/negative-reloc-blt Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92699 Cc: drm-intel-fixes@lists.freedesktop.org Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 52 ++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5d01ea680dc1..dccb517361b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -249,6 +249,31 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) obj->cache_level != I915_CACHE_NONE); } +/* Used to convert any address to canonical form. + * Starting from gen8, some commands (e.g. STATE_BASE_ADDRESS, + * MI_LOAD_REGISTER_MEM and others, see Broadwell PRM Vol2a) require the + * addresses to be in a canonical form: + * "GraphicsAddress[63:48] are ignored by the HW and assumed to be in correct + * canonical form [63:48] == [47]." + */ +#define GEN8_HIGH_ADDRESS_BIT 47 +static inline uint64_t gen8_canonical_addr(uint64_t address) +{ + return sign_extend64(address, GEN8_HIGH_ADDRESS_BIT); +} + +static inline uint64_t gen8_noncanonical_addr(uint64_t address) +{ + return address & ((1ULL << (GEN8_HIGH_ADDRESS_BIT + 1)) - 1); +} + +static inline uint64_t +relocation_target(struct drm_i915_gem_relocation_entry *reloc, + uint64_t target_offset) +{ + return gen8_canonical_addr((int)reloc->delta + target_offset); +} + static int relocate_entry_cpu(struct drm_i915_gem_object *obj, struct drm_i915_gem_relocation_entry *reloc, @@ -256,7 +281,7 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; uint32_t page_offset = offset_in_page(reloc->offset); - uint64_t delta = reloc->delta + target_offset; + uint64_t delta = relocation_target(reloc, target_offset); char *vaddr; int ret; @@ -292,7 +317,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - uint64_t delta = reloc->delta + target_offset; + uint64_t delta = relocation_target(reloc, target_offset); uint64_t offset; void __iomem *reloc_page; int ret; @@ -347,7 +372,7 @@ relocate_entry_clflush(struct drm_i915_gem_object *obj, { struct drm_device *dev = obj->base.dev; uint32_t page_offset = offset_in_page(reloc->offset); - uint64_t delta = (int)reloc->delta + target_offset; + uint64_t delta = relocation_target(reloc, target_offset); char *vaddr; int ret; @@ -395,7 +420,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, target_i915_obj = target_vma->obj; target_obj = &target_vma->obj->base; - target_offset = target_vma->node.start; + target_offset = gen8_canonical_addr(target_vma->node.start); /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and * pipe_control writes because the gpu doesn't properly redirect them @@ -994,6 +1019,21 @@ validate_exec_list(struct drm_device *dev, if (exec[i].flags & invalid_flags) return -EINVAL; + /* Offset can be used as input (EXEC_OBJECT_PINNED), reject + * any non-page-aligned or non-canonical addresses. + */ + if (exec[i].flags & EXEC_OBJECT_PINNED) { + if (exec[i].offset != + gen8_canonical_addr(exec[i].offset & PAGE_MASK)) + return -EINVAL; + + /* From drm_mm perspective address space is continuous, + * so from this point we're always using non-canonical + * form internally. + */ + exec[i].offset = gen8_noncanonical_addr(exec[i].offset); + } + if (exec[i].alignment && !is_power_of_2(exec[i].alignment)) return -EINVAL; @@ -1687,6 +1727,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, /* Copy the new buffer offsets back to the user's exec list. */ for (i = 0; i < args->buffer_count; i++) { + exec2_list[i].offset = + gen8_canonical_addr(exec2_list[i].offset); ret = __copy_to_user(&user_exec_list[i].offset, &exec2_list[i].offset, sizeof(user_exec_list[i].offset)); @@ -1752,6 +1794,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, int i; for (i = 0; i < args->buffer_count; i++) { + exec2_list[i].offset = + gen8_canonical_addr(exec2_list[i].offset); ret = __copy_to_user(&user_exec_list[i].offset, &exec2_list[i].offset, sizeof(user_exec_list[i].offset)); -- GitLab From fb0fec501f08a0a83af7a2b25888ec8cebab53b0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2015 15:58:53 +0000 Subject: [PATCH 0108/5324] mm: Export nr_swap_pages Some modules, like i915.ko, use swappable objects and may try to swap them out under memory pressure (via the shrinker). Before doing so, they want to check using get_nr_swap_pages() to see if any swap space is available as otherwise they will waste time purging the object from the device without recovering any memory for the system. This requires the nr_swap_pages counter to be exported to the modules. Signed-off-by: Chris Wilson Cc: "Goel, Akash" Cc: Johannes Weiner Cc: linux-mm@kvack.org Link: http://patchwork.freedesktop.org/patch/msgid/1449244734-25733-1-git-send-email-chris@chris-wilson.co.uk Acked-by: Andrew Morton Acked-by: Johannes Weiner Signed-off-by: Daniel Vetter --- mm/swapfile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/swapfile.c b/mm/swapfile.c index 58877312cf6b..2d259fdb2347 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -48,6 +48,12 @@ static sector_t map_swap_entry(swp_entry_t, struct block_device**); DEFINE_SPINLOCK(swap_lock); static unsigned int nr_swapfiles; atomic_long_t nr_swap_pages; +/* + * Some modules use swappable objects and may try to swap them out under + * memory pressure (via the shrinker). Before doing so, they may wish to + * check to see if any swap space is available. + */ +EXPORT_SYMBOL_GPL(nr_swap_pages); /* protected with swap_lock. reading in vm_swap_full() doesn't need lock */ long total_swap_pages; static int least_priority; -- GitLab From c1a415e261aad096b3458ba9157fefd123aa7cbf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Dec 2015 15:58:54 +0000 Subject: [PATCH 0109/5324] drm/i915: Disable shrinker for non-swapped backed objects If the system has no available swap pages, we cannot make forward progress in the shrinker by releasing active pages, only by releasing purgeable pages which are immediately reaped. Take total_swap_pages into account when counting up available objects to be shrunk and subsequently shrinking them. By doing so, we avoid unbinding objects that cannot be shrunk and so wasting CPU cycles flushing those objects from the GPU to the system and then immediately back again (as they will more than likely be reused shortly after). Based on a patch by Akash Goel. v2: frontswap registers extra swap pages available for the system, so it is already include in the count of available swap pages. v3: Use get_nr_swap_pages() to query the currently available amount of swap space. This should also stop us from shrinking the GPU buffers if we ever run out of swap space. Though at that point, we would expect the oom-notifier to be running and failing miserably... Reported-by: Akash Goel Signed-off-by: Chris Wilson Cc: linux-mm@kvack.org Cc: Akash Goel Cc: sourab.gupta@intel.com Link: http://patchwork.freedesktop.org/patch/msgid/1449244734-25733-2-git-send-email-chris@chris-wilson.co.uk Acked-by: Johannes Weiner Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 60 +++++++++++++++++------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index f7df54a8ee2b..16da9c1422cc 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -47,6 +47,46 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) #endif } +static int num_vma_bound(struct drm_i915_gem_object *obj) +{ + struct i915_vma *vma; + int count = 0; + + list_for_each_entry(vma, &obj->vma_list, vma_link) { + if (drm_mm_node_allocated(&vma->node)) + count++; + if (vma->pin_count) + count++; + } + + return count; +} + +static bool swap_available(void) +{ + return get_nr_swap_pages() > 0; +} + +static bool can_release_pages(struct drm_i915_gem_object *obj) +{ + /* Only report true if by unbinding the object and putting its pages + * we can actually make forward progress towards freeing physical + * pages. + * + * If the pages are pinned for any other reason than being bound + * to the GPU, simply unbinding from the GPU is not going to succeed + * in releasing our pin count on the pages themselves. + */ + if (obj->pages_pin_count != num_vma_bound(obj)) + return false; + + /* We can only return physical pages to the system if we can either + * discard the contents (because the user has marked them as being + * purgeable) or if we can move their contents out to swap. + */ + return swap_available() || obj->madv == I915_MADV_DONTNEED; +} + /** * i915_gem_shrink - Shrink buffer object caches * @dev_priv: i915 device @@ -129,6 +169,9 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, if ((flags & I915_SHRINK_ACTIVE) == 0 && obj->active) continue; + if (!can_release_pages(obj)) + continue; + drm_gem_object_reference(&obj->base); /* For the unbound phase, this should be a no-op! */ @@ -188,21 +231,6 @@ static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) return true; } -static int num_vma_bound(struct drm_i915_gem_object *obj) -{ - struct i915_vma *vma; - int count = 0; - - list_for_each_entry(vma, &obj->vma_list, vma_link) { - if (drm_mm_node_allocated(&vma->node)) - count++; - if (vma->pin_count) - count++; - } - - return count; -} - static unsigned long i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { @@ -222,7 +250,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) count += obj->base.size >> PAGE_SHIFT; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { - if (!obj->active && obj->pages_pin_count == num_vma_bound(obj)) + if (!obj->active && can_release_pages(obj)) count += obj->base.size >> PAGE_SHIFT; } -- GitLab From a7e02199ae430c0b41ee2b3079ccbbaff2393baf Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Wed, 16 Dec 2015 11:45:55 -0800 Subject: [PATCH 0110/5324] drm/i915/guc: Move GuC wq_check_space to alloc_request_extras Split GuC work queue space checking from submission and move it to ring_alloc_request_extras. The reason is that failure in later i915_add_request() won't be handled. In the case timeout happens, driver can return early in order to handle the error. v1: Move wq_reserve_space to ring_reserve_space v2: Move wq_reserve_space to alloc_request_extras (Chris Wilson) v3: The work queue head pointer is cached by driver now. So we can quickly return if space is available. s/reserve/check/g (Dave Gordon) v4: Update cached wq head after ring doorbell; check wq space before ring doorbell in case unexpected error happens; call wq space check only when GuC submission is enabled. (Dave Gordon) Signed-off-by: Alex Dai Link: http://patchwork.freedesktop.org/patch/msgid/1450295155-10050-1-git-send-email-yu.dai@intel.com Reviewed-by: Dave Gordon Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_guc_submission.c | 39 +++++++++++++--------- drivers/gpu/drm/i915/intel_guc.h | 2 ++ drivers/gpu/drm/i915/intel_lrc.c | 13 ++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 9cc3b8474dae..8b00f4619b1e 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -244,6 +244,9 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) db_exc.cookie = 1; } + /* Finally, update the cached copy of the GuC's WQ head */ + gc->wq_head = desc->head; + kunmap_atomic(base); return ret; } @@ -469,28 +472,30 @@ static void guc_fini_ctx_desc(struct intel_guc *guc, sizeof(desc) * client->ctx_index); } -/* Get valid workqueue item and return it back to offset */ -static int guc_get_workqueue_space(struct i915_guc_client *gc, u32 *offset) +int i915_guc_wq_check_space(struct i915_guc_client *gc) { struct guc_process_desc *desc; void *base; u32 size = sizeof(struct guc_wq_item); int ret = -ETIMEDOUT, timeout_counter = 200; + if (!gc) + return 0; + + /* Quickly return if wq space is available since last time we cache the + * head position. */ + if (CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size) >= size) + return 0; + base = kmap_atomic(i915_gem_object_get_page(gc->client_obj, 0)); desc = base + gc->proc_desc_offset; while (timeout_counter-- > 0) { - if (CIRC_SPACE(gc->wq_tail, desc->head, gc->wq_size) >= size) { - *offset = gc->wq_tail; + gc->wq_head = desc->head; - /* advance the tail for next workqueue item */ - gc->wq_tail += size; - gc->wq_tail &= gc->wq_size - 1; - - /* this will break the loop */ - timeout_counter = 0; + if (CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size) >= size) { ret = 0; + break; } if (timeout_counter) @@ -508,12 +513,16 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc, enum intel_ring_id ring_id = rq->ring->id; struct guc_wq_item *wqi; void *base; - u32 tail, wq_len, wq_off = 0; - int ret; + u32 tail, wq_len, wq_off, space; + + space = CIRC_SPACE(gc->wq_tail, gc->wq_head, gc->wq_size); + if (WARN_ON(space < sizeof(struct guc_wq_item))) + return -ENOSPC; /* shouldn't happen */ - ret = guc_get_workqueue_space(gc, &wq_off); - if (ret) - return ret; + /* postincrement WQ tail for next time */ + wq_off = gc->wq_tail; + gc->wq_tail += sizeof(struct guc_wq_item); + gc->wq_tail &= gc->wq_size - 1; /* For now workqueue item is 4 DWs; workqueue buffer is 2 pages. So we * should not have the case where structure wqi is across page, neither diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 822952235dcf..e8612c9afbc9 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -43,6 +43,7 @@ struct i915_guc_client { uint32_t wq_offset; uint32_t wq_size; uint32_t wq_tail; + uint32_t wq_head; /* GuC submission statistics & status */ uint64_t submissions[I915_NUM_RINGS]; @@ -122,5 +123,6 @@ int i915_guc_submit(struct i915_guc_client *client, struct drm_i915_gem_request *rq); void i915_guc_submission_disable(struct drm_device *dev); void i915_guc_submission_fini(struct drm_device *dev); +int i915_guc_wq_check_space(struct i915_guc_client *client); #endif diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 973487a73be1..e09505827394 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -670,6 +670,19 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request return ret; } + if (i915.enable_guc_submission) { + /* + * Check that the GuC has space for the request before + * going any further, as the i915_add_request() call + * later on mustn't fail ... + */ + struct intel_guc *guc = &request->i915->guc; + + ret = i915_guc_wq_check_space(guc->execbuf_client); + if (ret) + return ret; + } + return 0; } -- GitLab From 95a66f7e711d091ea277fcde2d1dd11e6b8e9468 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Fri, 18 Dec 2015 12:00:08 -0800 Subject: [PATCH 0111/5324] drm/i915/guc: Expose (intel)_lr_context_size() The GuC code needs to know the size of a logical context, so we expose get_lr_context_size(), renaming it intel_lr_context__size() to fit the naming conventions for nonstatic functions. For: VIZ-2021 Signed-off-by: Dave Gordon Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-2-git-send-email-yu.dai@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 4 ++-- drivers/gpu/drm/i915/intel_lrc.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e09505827394..808515cef607 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2399,7 +2399,7 @@ void intel_lr_context_free(struct intel_context *ctx) } } -static uint32_t get_lr_context_size(struct intel_engine_cs *ring) +uint32_t intel_lr_context_size(struct intel_engine_cs *ring) { int ret = 0; @@ -2467,7 +2467,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx, WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); WARN_ON(ctx->engine[ring->id].state); - context_size = round_up(get_lr_context_size(ring), 4096); + context_size = round_up(intel_lr_context_size(ring), 4096); /* One extra page as the sharing data between driver and GuC */ context_size += PAGE_SIZE * LRC_PPHWSP_PN; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 0b821b91723a..ae90f86a2849 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -84,6 +84,7 @@ static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer *ringbuf, #define LRC_STATE_PN (LRC_PPHWSP_PN + 1) void intel_lr_context_free(struct intel_context *ctx); +uint32_t intel_lr_context_size(struct intel_engine_cs *ring); int intel_lr_context_deferred_alloc(struct intel_context *ctx, struct intel_engine_cs *ring); void intel_lr_context_unpin(struct drm_i915_gem_request *req); -- GitLab From 68371a954ca4581a6468835f63d6f82783471591 Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Fri, 18 Dec 2015 12:00:09 -0800 Subject: [PATCH 0112/5324] drm/i915/guc: Add GuC ADS (Addition Data Structure) - allocation The GuC firmware uses this for various purposes. The ADS itself is a chunk of memory created by driver to share with GuC. Its members are usually addresses telling where GuC to access them, including things like scheduler policies, register list that will be saved and restored during reset etc. This is the first patch of a series to enable GuC ADS. For now, we only create the ADS obj whilst keep it disabled. v1: remove dead code checking return of kmap_atomic (Chris Wilson) v2: use kmap instead of the atomic version of it. Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-3-git-send-email-yu.dai@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_guc_reg.h | 1 + drivers/gpu/drm/i915/i915_guc_submission.c | 45 ++++++++++++++++++++++ drivers/gpu/drm/i915/intel_guc.h | 2 + drivers/gpu/drm/i915/intel_guc_fwif.h | 31 ++++++++++++++- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h index 685c7991e24f..e4ba5822289b 100644 --- a/drivers/gpu/drm/i915/i915_guc_reg.h +++ b/drivers/gpu/drm/i915/i915_guc_reg.h @@ -40,6 +40,7 @@ #define GS_MIA_CORE_STATE (1 << GS_MIA_SHIFT) #define SOFT_SCRATCH(n) _MMIO(0xc180 + (n) * 4) +#define SOFT_SCRATCH_COUNT 16 #define UOS_RSA_SCRATCH(i) _MMIO(0xc200 + (i) * 4) #define UOS_RSA_SCRATCH_MAX_COUNT 64 diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 8b00f4619b1e..7e6c5272e734 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -839,6 +839,46 @@ static void guc_create_log(struct intel_guc *guc) guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; } +static void guc_create_ads(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + struct drm_i915_gem_object *obj; + struct guc_ads *ads; + struct intel_engine_cs *ring; + struct page *page; + u32 size, i; + + /* The ads obj includes the struct itself and buffers passed to GuC */ + size = sizeof(struct guc_ads); + + obj = guc->ads_obj; + if (!obj) { + obj = gem_allocate_guc_obj(dev_priv->dev, PAGE_ALIGN(size)); + if (!obj) + return; + + guc->ads_obj = obj; + } + + page = i915_gem_object_get_page(obj, 0); + ads = kmap(page); + + /* + * The GuC requires a "Golden Context" when it reinitialises + * engines after a reset. Here we use the Render ring default + * context, which must already exist and be pinned in the GGTT, + * so its address won't change after we've told the GuC where + * to find it. + */ + ring = &dev_priv->ring[RCS]; + ads->golden_context_lrca = ring->status_page.gfx_addr; + + for_each_ring(ring, dev_priv, i) + ads->eng_state_size[i] = intel_lr_context_size(ring); + + kunmap(page); +} + /* * Set up the memory resources to be shared with the GuC. At this point, * we require just one object that can be mapped through the GGTT. @@ -865,6 +905,8 @@ int i915_guc_submission_init(struct drm_device *dev) guc_create_log(guc); + guc_create_ads(guc); + return 0; } @@ -903,6 +945,9 @@ void i915_guc_submission_fini(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc *guc = &dev_priv->guc; + gem_release_guc_obj(dev_priv->guc.ads_obj); + guc->ads_obj = NULL; + gem_release_guc_obj(dev_priv->guc.log_obj); guc->log_obj = NULL; diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index e8612c9afbc9..045b1491ff7a 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -89,6 +89,8 @@ struct intel_guc { uint32_t log_flags; struct drm_i915_gem_object *log_obj; + struct drm_i915_gem_object *ads_obj; + struct drm_i915_gem_object *ctx_pool_obj; struct ida ctx_ids; diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 40b2ea572e16..bc9829eaabb3 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -81,11 +81,14 @@ #define GUC_CTL_CTXINFO 0 #define GUC_CTL_CTXNUM_IN16_SHIFT 0 #define GUC_CTL_BASE_ADDR_SHIFT 12 + #define GUC_CTL_ARAT_HIGH 1 #define GUC_CTL_ARAT_LOW 2 + #define GUC_CTL_DEVICE_INFO 3 #define GUC_CTL_GTTYPE_SHIFT 0 #define GUC_CTL_COREFAMILY_SHIFT 7 + #define GUC_CTL_LOG_PARAMS 4 #define GUC_LOG_VALID (1 << 0) #define GUC_LOG_NOTIFY_ON_HALF_FULL (1 << 1) @@ -97,9 +100,12 @@ #define GUC_LOG_ISR_PAGES 3 #define GUC_LOG_ISR_SHIFT 9 #define GUC_LOG_BUF_ADDR_SHIFT 12 + #define GUC_CTL_PAGE_FAULT_CONTROL 5 + #define GUC_CTL_WA 6 #define GUC_CTL_WA_UK_BY_DRIVER (1 << 3) + #define GUC_CTL_FEATURE 7 #define GUC_CTL_VCS2_ENABLED (1 << 0) #define GUC_CTL_KERNEL_SUBMISSIONS (1 << 1) @@ -109,6 +115,7 @@ #define GUC_CTL_PREEMPTION_LOG (1 << 5) #define GUC_CTL_ENABLE_SLPC (1 << 7) #define GUC_CTL_RESET_ON_PREMPT_FAILURE (1 << 8) + #define GUC_CTL_DEBUG 8 #define GUC_LOG_VERBOSITY_SHIFT 0 #define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT) @@ -118,9 +125,19 @@ /* Verbosity range-check limits, without the shift */ #define GUC_LOG_VERBOSITY_MIN 0 #define GUC_LOG_VERBOSITY_MAX 3 +#define GUC_LOG_VERBOSITY_MASK 0x0000000f +#define GUC_LOG_DESTINATION_MASK (3 << 4) +#define GUC_LOG_DISABLED (1 << 6) +#define GUC_PROFILE_ENABLED (1 << 7) +#define GUC_WQ_TRACK_ENABLED (1 << 8) +#define GUC_ADS_ENABLED (1 << 9) +#define GUC_DEBUG_RESERVED (1 << 10) +#define GUC_ADS_ADDR_SHIFT 11 +#define GUC_ADS_ADDR_MASK 0xfffff800 + #define GUC_CTL_RSRVD 9 -#define GUC_CTL_MAX_DWORDS (GUC_CTL_RSRVD + 1) +#define GUC_CTL_MAX_DWORDS (SOFT_SCRATCH_COUNT - 2) /* [1..14] */ /** * DOC: GuC Firmware Layout @@ -299,6 +316,18 @@ struct guc_context_desc { #define GUC_POWER_D2 3 #define GUC_POWER_D3 4 +/* GuC Additional Data Struct */ + +struct guc_ads { + u32 reg_state_addr; + u32 reg_state_buffer; + u32 golden_context_lrca; + u32 scheduler_policies; + u32 reserved0[3]; + u32 eng_state_size[I915_NUM_RINGS]; + u32 reserved2[4]; +} __packed; + /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ enum host2guc_action { HOST2GUC_ACTION_DEFAULT = 0x0, -- GitLab From 463704d07f4cb0767714a67eaaf1ee47eef36fd8 Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Fri, 18 Dec 2015 12:00:10 -0800 Subject: [PATCH 0113/5324] drm/i915/guc: Add GuC ADS - scheduler policies GuC supports different scheduling policies for its four internal queues. Currently these have been set to the same default values as KMD_NORMAL queue. Particularly POLICY_MAX_NUM_WI is set to 15 to match GuC internal maximum submit queue numbers to avoid an out-of-space problem. This value indicates max number of work items allowed to be queued for one DPC process. A smaller value will let GuC schedule more frequently while a larger number may increase chances to optimize cmds (such as collapse cmds from same lrc) with risks that keeps CS idle. v1: tidy up code Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-4-git-send-email-yu.dai@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_guc_submission.c | 32 ++++++++++++++- drivers/gpu/drm/i915/intel_guc_fwif.h | 45 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 7e6c5272e734..1eb8db8d1feb 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -839,17 +839,40 @@ static void guc_create_log(struct intel_guc *guc) guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; } +static void init_guc_policies(struct guc_policies *policies) +{ + struct guc_policy *policy; + u32 p, i; + + policies->dpc_promote_time = 500000; + policies->max_num_work_items = POLICY_MAX_NUM_WI; + + for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) { + for (i = 0; i < I915_NUM_RINGS; i++) { + policy = &policies->policy[p][i]; + + policy->execution_quantum = 1000000; + policy->preemption_time = 500000; + policy->fault_time = 250000; + policy->policy_flags = 0; + } + } + + policies->is_valid = 1; +} + static void guc_create_ads(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); struct drm_i915_gem_object *obj; struct guc_ads *ads; + struct guc_policies *policies; struct intel_engine_cs *ring; struct page *page; u32 size, i; /* The ads obj includes the struct itself and buffers passed to GuC */ - size = sizeof(struct guc_ads); + size = sizeof(struct guc_ads) + sizeof(struct guc_policies); obj = guc->ads_obj; if (!obj) { @@ -876,6 +899,13 @@ static void guc_create_ads(struct intel_guc *guc) for_each_ring(ring, dev_priv, i) ads->eng_state_size[i] = intel_lr_context_size(ring); + /* GuC scheduling policies */ + policies = (void *)ads + sizeof(struct guc_ads); + init_guc_policies(policies); + + ads->scheduler_policies = i915_gem_obj_ggtt_offset(obj) + + sizeof(struct guc_ads); + kunmap(page); } diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index bc9829eaabb3..1ce5f5ba3147 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -39,6 +39,7 @@ #define GUC_CTX_PRIORITY_HIGH 1 #define GUC_CTX_PRIORITY_KMD_NORMAL 2 #define GUC_CTX_PRIORITY_NORMAL 3 +#define GUC_CTX_PRIORITY_NUM 4 #define GUC_MAX_GPU_CONTEXTS 1024 #define GUC_INVALID_CTX_ID GUC_MAX_GPU_CONTEXTS @@ -316,6 +317,50 @@ struct guc_context_desc { #define GUC_POWER_D2 3 #define GUC_POWER_D3 4 +/* Scheduling policy settings */ + +/* Reset engine upon preempt failure */ +#define POLICY_RESET_ENGINE (1<<0) +/* Preempt to idle on quantum expiry */ +#define POLICY_PREEMPT_TO_IDLE (1<<1) + +#define POLICY_MAX_NUM_WI 15 + +struct guc_policy { + /* Time for one workload to execute. (in micro seconds) */ + u32 execution_quantum; + u32 reserved1; + + /* Time to wait for a preemption request to completed before issuing a + * reset. (in micro seconds). */ + u32 preemption_time; + + /* How much time to allow to run after the first fault is observed. + * Then preempt afterwards. (in micro seconds) */ + u32 fault_time; + + u32 policy_flags; + u32 reserved[2]; +} __packed; + +struct guc_policies { + struct guc_policy policy[GUC_CTX_PRIORITY_NUM][I915_NUM_RINGS]; + + /* In micro seconds. How much time to allow before DPC processing is + * called back via interrupt (to prevent DPC queue drain starving). + * Typically 1000s of micro seconds (example only, not granularity). */ + u32 dpc_promote_time; + + /* Must be set to take these new values. */ + u32 is_valid; + + /* Max number of WIs to process per call. A large value may keep CS + * idle. */ + u32 max_num_work_items; + + u32 reserved[19]; +} __packed; + /* GuC Additional Data Struct */ struct guc_ads { -- GitLab From 5c148e044e55304073de3cc2b41c80b1a780687f Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Fri, 18 Dec 2015 12:00:11 -0800 Subject: [PATCH 0114/5324] drm/i915/guc: Add GuC ADS - MMIO reg state GuC needs to know which registers and how they will be saved and restored during event such as engine reset or power state changes. For now only the base address of reg state is initialized. The detail register table probably will be setup in future GuC TDR or Preemption patch series. Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-5-git-send-email-yu.dai@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_guc_submission.c | 22 ++++++++++++- drivers/gpu/drm/i915/intel_guc_fwif.h | 37 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 1eb8db8d1feb..9c244247c13e 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -867,12 +867,15 @@ static void guc_create_ads(struct intel_guc *guc) struct drm_i915_gem_object *obj; struct guc_ads *ads; struct guc_policies *policies; + struct guc_mmio_reg_state *reg_state; struct intel_engine_cs *ring; struct page *page; u32 size, i; /* The ads obj includes the struct itself and buffers passed to GuC */ - size = sizeof(struct guc_ads) + sizeof(struct guc_policies); + size = sizeof(struct guc_ads) + sizeof(struct guc_policies) + + sizeof(struct guc_mmio_reg_state) + + GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE; obj = guc->ads_obj; if (!obj) { @@ -906,6 +909,23 @@ static void guc_create_ads(struct intel_guc *guc) ads->scheduler_policies = i915_gem_obj_ggtt_offset(obj) + sizeof(struct guc_ads); + /* MMIO reg state */ + reg_state = (void *)policies + sizeof(struct guc_policies); + + for (i = 0; i < I915_NUM_RINGS; i++) { + reg_state->mmio_white_list[i].mmio_start = + dev_priv->ring[i].mmio_base + GUC_MMIO_WHITE_LIST_START; + + /* Nothing to be saved or restored for now. */ + reg_state->mmio_white_list[i].count = 0; + } + + ads->reg_state_addr = ads->scheduler_policies + + sizeof(struct guc_policies); + + ads->reg_state_buffer = ads->reg_state_addr + + sizeof(struct guc_mmio_reg_state); + kunmap(page); } diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 1ce5f5ba3147..b4632f0bf7b2 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -361,6 +361,43 @@ struct guc_policies { u32 reserved[19]; } __packed; +/* GuC MMIO reg state struct */ + +#define GUC_REGSET_FLAGS_NONE 0x0 +#define GUC_REGSET_POWERCYCLE 0x1 +#define GUC_REGSET_MASKED 0x2 +#define GUC_REGSET_ENGINERESET 0x4 +#define GUC_REGSET_SAVE_DEFAULT_VALUE 0x8 +#define GUC_REGSET_SAVE_CURRENT_VALUE 0x10 + +#define GUC_REGSET_MAX_REGISTERS 20 +#define GUC_MMIO_WHITE_LIST_START 0x24d0 +#define GUC_MMIO_WHITE_LIST_MAX 12 +#define GUC_S3_SAVE_SPACE_PAGES 10 + +struct guc_mmio_regset { + struct __packed { + u32 offset; + u32 value; + u32 flags; + } registers[GUC_REGSET_MAX_REGISTERS]; + + u32 values_valid; + u32 number_of_registers; +} __packed; + +struct guc_mmio_reg_state { + struct guc_mmio_regset global_reg; + struct guc_mmio_regset engine_reg[I915_NUM_RINGS]; + + /* MMIO registers that are set as non privileged */ + struct __packed { + u32 mmio_start; + u32 offsets[GUC_MMIO_WHITE_LIST_MAX]; + u32 count; + } mmio_white_list[I915_NUM_RINGS]; +} __packed; + /* GuC Additional Data Struct */ struct guc_ads { -- GitLab From b6a5cd7ea246b68240d49ef78cc339ef8595c10c Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Fri, 18 Dec 2015 12:00:12 -0800 Subject: [PATCH 0115/5324] drm/i915/guc: Add GuC ADS - enabling ADS Set ADS enabling flag during GuC init. Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-6-git-send-email-yu.dai@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_guc_loader.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 550921f2ef7d..d20788ffd341 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -165,6 +165,13 @@ static void set_guc_init_params(struct drm_i915_private *dev_priv) i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; } + if (guc->ads_obj) { + u32 ads = (u32)i915_gem_obj_ggtt_offset(guc->ads_obj) + >> PAGE_SHIFT; + params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; + params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED; + } + /* If GuC submission is enabled, set up additional parameters here */ if (i915.enable_guc_submission) { u32 pgs = i915_gem_obj_ggtt_offset(dev_priv->guc.ctx_pool_obj); -- GitLab From 513485fd10b17bd6870379ef9fff397419f20798 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:53 +0200 Subject: [PATCH 0116/5324] drm/i915/bios: fix header define name for intel_bios.h Just for OCD. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/730e41760133dbaa1e3ab1b91631ada18676810c.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 2dc46a98c332..21c162e01189 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -25,8 +25,8 @@ * */ -#ifndef _I830_BIOS_H_ -#define _I830_BIOS_H_ +#ifndef _INTEL_BIOS_H_ +#define _INTEL_BIOS_H_ /** * struct vbt_header - VBT Header structure @@ -983,4 +983,4 @@ enum mipi_gpio_pin_index { MIPI_GPIO_MAX }; -#endif /* _I830_BIOS_H_ */ +#endif /* _INTEL_BIOS_H_ */ -- GitLab From 0f8689f5bb569d2ff19f5248b2d3940ad6d35504 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:54 +0200 Subject: [PATCH 0117/5324] drm/i915/bios: split the MIPI DSI VBT block parsing to two There's two blocks to parse, have one function per block. The existing one cuts neatly into two. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/6c9598e2b4d07e8d264617cdfe8b6527a74261f7.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b6ccba13779e..5ea6087c40c1 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -765,16 +765,12 @@ static u8 *goto_next_sequence(u8 *data, int *size) } static void -parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) +parse_mipi_config(struct drm_i915_private *dev_priv, + const struct bdb_header *bdb) { const struct bdb_mipi_config *start; - const struct bdb_mipi_sequence *sequence; const struct mipi_config *config; const struct mipi_pps_data *pps; - u8 *data; - const u8 *seq_data; - int i, panel_id, seq_size; - u16 block_size; /* parse MIPI blocks only if LFP type is MIPI */ if (!dev_priv->vbt.has_mipi) @@ -820,8 +816,22 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) /* We have mandatory mipi config blocks. Initialize as generic panel */ dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; +} + +static void +parse_mipi_sequence(struct drm_i915_private *dev_priv, + const struct bdb_header *bdb) +{ + const struct bdb_mipi_sequence *sequence; + const u8 *seq_data; + u8 *data; + u16 block_size; + int i, panel_id, seq_size; + + /* Only our generic panel driver uses the sequence block. */ + if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) + return; - /* Check if we have sequence block as well */ sequence = find_section(bdb, BDB_MIPI_SEQUENCE); if (!sequence) { DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n"); @@ -1359,7 +1369,8 @@ intel_bios_init(struct drm_i915_private *dev_priv) parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); parse_psr(dev_priv, bdb); - parse_mipi(dev_priv, bdb); + parse_mipi_config(dev_priv, bdb); + parse_mipi_sequence(dev_priv, bdb); parse_ddi_ports(dev_priv, bdb); if (bios) -- GitLab From 08c0888b28d75cf4ee9ca0bbe1a2c55ddef87423 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:55 +0200 Subject: [PATCH 0118/5324] drm/i915/bios: have get_blocksize() support MIPI sequence block v3+ Have get_blocksize() support the special case of MIPI sequence block v3+ which has a separate field for size. Provide and use abstractions for getting the blocksize given a pointer to the block "envelope", i.e. pointer to the block id, and given a pointer to the block payload data. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/e935bd5e119a83dd91214c47e6cd4f6ce8b2a17e.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 5ea6087c40c1..961ae7f6d075 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -58,6 +58,22 @@ static int panel_type; +/* Get BDB block size given a pointer to Block ID. */ +static u32 _get_blocksize(const u8 *block_base) +{ + /* The MIPI Sequence Block v3+ has a separate size field. */ + if (*block_base == BDB_MIPI_SEQUENCE && *(block_base + 3) >= 3) + return *((const u32 *)(block_base + 4)); + else + return *((const u16 *)(block_base + 1)); +} + +/* Get BDB block size give a pointer to data after Block ID and Block Size. */ +static u32 get_blocksize(const void *block_data) +{ + return _get_blocksize(block_data - 3); +} + static const void * find_section(const void *_bdb, int section_id) { @@ -74,14 +90,8 @@ find_section(const void *_bdb, int section_id) /* walk the sections looking for section_id */ while (index + 3 < total) { current_id = *(base + index); - index++; - - current_size = *((const u16 *)(base + index)); - index += 2; - - /* The MIPI Sequence Block v3+ has a separate size field. */ - if (current_id == BDB_MIPI_SEQUENCE && *(base + index) >= 3) - current_size = *((const u32 *)(base + index + 1)); + current_size = _get_blocksize(base + index); + index += 3; if (index + current_size > total) return NULL; @@ -95,16 +105,6 @@ find_section(const void *_bdb, int section_id) return NULL; } -static u16 -get_blocksize(const void *p) -{ - u16 *block_ptr, block_size; - - block_ptr = (u16 *)((char *)p - 2); - block_size = *block_ptr; - return block_size; -} - static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, const struct lvds_dvo_timing *dvo_timing) -- GitLab From 5db72099e8ec26a480420fc8b9326902a1a4ef69 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 5 Jan 2016 15:50:51 +0200 Subject: [PATCH 0119/5324] drm/i915/bios: abstract finding the panel sequence block Make the whole thing easier to read. While at it, make the parsing more robust, and ensure we don't read past buffer being parsed. v2: improve commit message (Daniel) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452001851-8967-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 76 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 961ae7f6d075..422ba76700e3 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -697,7 +697,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; } -static u8 *goto_next_sequence(u8 *data, int *size) +static u8 *goto_next_sequence(u8 *data, u16 *size) { u16 len; int tmp = *size; @@ -818,15 +818,52 @@ parse_mipi_config(struct drm_i915_private *dev_priv, dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; } +/* Find the sequence block and size for the given panel. */ +static const u8 * +find_panel_sequence_block(const struct bdb_mipi_sequence *sequence, + u16 panel_id, u16 *seq_size) +{ + u32 total = get_blocksize(sequence); + const u8 *data = &sequence->data[0]; + u8 current_id; + u16 current_size; + int index = 0; + int i; + + for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index + 3 < total; i++) { + current_id = *(data + index); + index++; + + current_size = *((const u16 *)(data + index)); + index += 2; + + if (index + current_size > total) { + DRM_ERROR("Invalid sequence block\n"); + return NULL; + } + + if (current_id == panel_id) { + *seq_size = current_size; + return data + index; + } + + index += current_size; + } + + DRM_ERROR("Sequence block detected but no valid configuration\n"); + + return NULL; +} + static void parse_mipi_sequence(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) { const struct bdb_mipi_sequence *sequence; const u8 *seq_data; + u16 seq_size; u8 *data; u16 block_size; - int i, panel_id, seq_size; /* Only our generic panel driver uses the sequence block. */ if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) @@ -853,40 +890,11 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, */ dev_priv->vbt.dsi.seq_version = sequence->version; - seq_data = &sequence->data[0]; - - /* - * sequence block is variable length and hence we need to parse and - * get the sequence data for specific panel id - */ - for (i = 0; i < MAX_MIPI_CONFIGURATIONS; i++) { - panel_id = *seq_data; - seq_size = *((u16 *) (seq_data + 1)); - if (panel_id == panel_type) - break; - - /* skip the sequence including seq header of 3 bytes */ - seq_data = seq_data + 3 + seq_size; - if ((seq_data - &sequence->data[0]) > block_size) { - DRM_ERROR("Sequence start is beyond sequence block size, corrupted sequence block\n"); - return; - } - } - - if (i == MAX_MIPI_CONFIGURATIONS) { - DRM_ERROR("Sequence block detected but no valid configuration\n"); + seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size); + if (!seq_data) return; - } - - /* check if found sequence is completely within the sequence block - * just being paranoid */ - if (seq_size > block_size) { - DRM_ERROR("Corrupted sequence/size, bailing out\n"); - return; - } - /* skip the panel id(1 byte) and seq size(2 bytes) */ - dev_priv->vbt.dsi.data = kmemdup(seq_data + 3, seq_size, GFP_KERNEL); + dev_priv->vbt.dsi.data = kmemdup(seq_data, seq_size, GFP_KERNEL); if (!dev_priv->vbt.dsi.data) return; -- GitLab From 8d3ed2f3139792d9900602aa5f790032baa0a22a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:57 +0200 Subject: [PATCH 0120/5324] drm/i915/bios: rewrite sequence block parsing Make everything a bit more readable and clear. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/e8f2a62d78d90981a6b49fdf9ab3594f60a46033.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_bios.c | 158 ++++++++++-------------------- drivers/gpu/drm/i915/intel_bios.h | 4 +- 3 files changed, 57 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cf7e0fce01ac..c6dd4db29cea 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1477,7 +1477,7 @@ struct intel_vbt_data { u8 seq_version; u32 size; u8 *data; - u8 *sequence[MIPI_SEQ_MAX]; + const u8 *sequence[MIPI_SEQ_MAX]; } dsi; int crt_ddc_pin; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 422ba76700e3..71c739e33101 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -697,73 +697,6 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time; } -static u8 *goto_next_sequence(u8 *data, u16 *size) -{ - u16 len; - int tmp = *size; - - if (--tmp < 0) - return NULL; - - /* goto first element */ - data++; - while (1) { - switch (*data) { - case MIPI_SEQ_ELEM_SEND_PKT: - /* - * skip by this element payload size - * skip elem id, command flag and data type - */ - tmp -= 5; - if (tmp < 0) - return NULL; - - data += 3; - len = *((u16 *)data); - - tmp -= len; - if (tmp < 0) - return NULL; - - /* skip by len */ - data = data + 2 + len; - break; - case MIPI_SEQ_ELEM_DELAY: - /* skip by elem id, and delay is 4 bytes */ - tmp -= 5; - if (tmp < 0) - return NULL; - - data += 5; - break; - case MIPI_SEQ_ELEM_GPIO: - tmp -= 3; - if (tmp < 0) - return NULL; - - data += 3; - break; - default: - DRM_ERROR("Unknown element\n"); - return NULL; - } - - /* end of sequence ? */ - if (*data == 0) - break; - } - - /* goto next sequence or end of block byte */ - if (--tmp < 0) - return NULL; - - data++; - - /* update amount of data left for the sequence block to be parsed */ - *size = tmp; - return data; -} - static void parse_mipi_config(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) @@ -855,6 +788,39 @@ find_panel_sequence_block(const struct bdb_mipi_sequence *sequence, return NULL; } +static int goto_next_sequence(const u8 *data, int index, int total) +{ + u16 len; + + /* Skip Sequence Byte. */ + for (index = index + 1; index < total; index += len) { + u8 operation_byte = *(data + index); + index++; + + switch (operation_byte) { + case MIPI_SEQ_ELEM_END: + return index; + case MIPI_SEQ_ELEM_SEND_PKT: + if (index + 4 > total) + return 0; + + len = *((const u16 *)(data + index + 2)) + 4; + break; + case MIPI_SEQ_ELEM_DELAY: + len = 4; + break; + case MIPI_SEQ_ELEM_GPIO: + len = 2; + break; + default: + DRM_ERROR("Unknown operation byte\n"); + return 0; + } + } + + return 0; +} + static void parse_mipi_sequence(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) @@ -863,7 +829,7 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, const u8 *seq_data; u16 seq_size; u8 *data; - u16 block_size; + int index = 0; /* Only our generic panel driver uses the sequence block. */ if (dev_priv->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) @@ -883,59 +849,43 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, DRM_DEBUG_DRIVER("Found MIPI sequence block\n"); - block_size = get_blocksize(sequence); - - /* - * parse the sequence block for individual sequences - */ - dev_priv->vbt.dsi.seq_version = sequence->version; - seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size); if (!seq_data) return; - dev_priv->vbt.dsi.data = kmemdup(seq_data, seq_size, GFP_KERNEL); - if (!dev_priv->vbt.dsi.data) + data = kmemdup(seq_data, seq_size, GFP_KERNEL); + if (!data) return; - /* - * loop into the sequence data and split into multiple sequneces - * There are only 5 types of sequences as of now - */ - data = dev_priv->vbt.dsi.data; - dev_priv->vbt.dsi.size = seq_size; + /* Parse the sequences, store pointers to each sequence. */ + for (;;) { + u8 seq_id = *(data + index); + if (seq_id == MIPI_SEQ_END) + break; - /* two consecutive 0x00 indicate end of all sequences */ - while (1) { - int seq_id = *data; - if (MIPI_SEQ_MAX > seq_id && seq_id > MIPI_SEQ_UNDEFINED) { - dev_priv->vbt.dsi.sequence[seq_id] = data; - DRM_DEBUG_DRIVER("Found mipi sequence - %d\n", seq_id); - } else { - DRM_ERROR("undefined sequence\n"); + if (seq_id >= MIPI_SEQ_MAX) { + DRM_ERROR("Unknown sequence %u\n", seq_id); goto err; } - /* partial parsing to skip elements */ - data = goto_next_sequence(data, &seq_size); + dev_priv->vbt.dsi.sequence[seq_id] = data + index; - if (data == NULL) { - DRM_ERROR("Sequence elements going beyond block itself. Sequence block parsing failed\n"); + index = goto_next_sequence(data, index, seq_size); + if (!index) { + DRM_ERROR("Invalid sequence %u\n", seq_id); goto err; } - - if (*data == 0) - break; /* end of sequence reached */ } - DRM_DEBUG_DRIVER("MIPI related vbt parsing complete\n"); + dev_priv->vbt.dsi.data = data; + dev_priv->vbt.dsi.size = seq_size; + dev_priv->vbt.dsi.seq_version = sequence->version; + + DRM_DEBUG_DRIVER("MIPI related VBT parsing complete\n"); return; -err: - kfree(dev_priv->vbt.dsi.data); - dev_priv->vbt.dsi.data = NULL; - /* error during parsing so set all pointers to null - * because of partial parsing */ +err: + kfree(data); memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence)); } diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 21c162e01189..4e87df16e7b3 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -954,7 +954,7 @@ struct bdb_mipi_sequence { /* MIPI Sequnece Block definitions */ enum mipi_seq { - MIPI_SEQ_UNDEFINED = 0, + MIPI_SEQ_END = 0, MIPI_SEQ_ASSERT_RESET, MIPI_SEQ_INIT_OTP, MIPI_SEQ_DISPLAY_ON, @@ -964,7 +964,7 @@ enum mipi_seq { }; enum mipi_seq_element { - MIPI_SEQ_ELEM_UNDEFINED = 0, + MIPI_SEQ_ELEM_END = 0, MIPI_SEQ_ELEM_SEND_PKT, MIPI_SEQ_ELEM_DELAY, MIPI_SEQ_ELEM_GPIO, -- GitLab From 5cda0d20f949a111758b897c33f249f097f01727 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:58 +0200 Subject: [PATCH 0121/5324] drm/i915/dsi: be defensive about out of bounds sequence id Untie the VBT based generic panel driver from the VBT parsing, so that the two don't have to be updated in lockstep. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/7a6e3e7c4404c0e4dbcf003acd8737a6ecbe218f.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index aa1f7bc8f4d0..c6aea69230e8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -246,14 +246,21 @@ static const fn_mipi_elem_exec exec_elem[] = { */ static const char * const seq_name[] = { - "UNDEFINED", - "MIPI_SEQ_ASSERT_RESET", - "MIPI_SEQ_INIT_OTP", - "MIPI_SEQ_DISPLAY_ON", - "MIPI_SEQ_DISPLAY_OFF", - "MIPI_SEQ_DEASSERT_RESET" + [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET", + [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP", + [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON", + [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF", + [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET", }; +static const char *sequence_name(enum mipi_seq seq_id) +{ + if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id]) + return seq_name[seq_id]; + else + return "(unknown)"; +} + static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) { fn_mipi_elem_exec mipi_elem_exec; @@ -262,7 +269,8 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) if (!data) return; - DRM_DEBUG_DRIVER("Starting MIPI sequence - %s\n", seq_name[*data]); + DRM_DEBUG_DRIVER("Starting MIPI sequence %u - %s\n", + *data, sequence_name(*data)); /* go to the first element of the sequence */ data++; -- GitLab From 28c72840a787559851aa8d70a18bb5ac41b73b53 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:10:59 +0200 Subject: [PATCH 0122/5324] drm/i915/dsi: be defensive about out of bounds operation byte Untie the VBT based generic panel driver from the VBT parsing, so that the two don't have to be updated in lockstep. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/01c71ac89a9db8bc7b8ae0fb05c50a5fae362dc4.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index c6aea69230e8..9bd920809697 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -232,11 +232,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi, const u8 *data); static const fn_mipi_elem_exec exec_elem[] = { - NULL, /* reserved */ - mipi_exec_send_packet, - mipi_exec_delay, - mipi_exec_gpio, - NULL, /* status read; later */ + [MIPI_SEQ_ELEM_SEND_PKT] = mipi_exec_send_packet, + [MIPI_SEQ_ELEM_DELAY] = mipi_exec_delay, + [MIPI_SEQ_ELEM_GPIO] = mipi_exec_gpio, }; /* @@ -264,7 +262,6 @@ static const char *sequence_name(enum mipi_seq seq_id) static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) { fn_mipi_elem_exec mipi_elem_exec; - int index; if (!data) return; @@ -277,15 +274,14 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) /* parse each byte till we reach end of sequence byte - 0x00 */ while (1) { - index = *data; - mipi_elem_exec = exec_elem[index]; - if (!mipi_elem_exec) { - DRM_ERROR("Unsupported MIPI element, skipping sequence execution\n"); + u8 operation_byte = *data++; + if (operation_byte >= ARRAY_SIZE(exec_elem) || + !exec_elem[operation_byte]) { + DRM_ERROR("Unsupported MIPI operation byte %u\n", + operation_byte); return; } - - /* goto element payload */ - data++; + mipi_elem_exec = exec_elem[operation_byte]; /* execute the element specific rotines */ data = mipi_elem_exec(intel_dsi, data); -- GitLab From c5d46ee20675379105bfd1ce422fe50169106e62 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Tue, 5 Jan 2016 12:21:33 +0000 Subject: [PATCH 0123/5324] drm/i915: add kerneldoc for intel_lr_context_size() This function was recently renamed & exposed, so now it gets documented Signed-off-by: Dave Gordon Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1451996493-16079-1-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 808515cef607..8096c6a79424 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2399,6 +2399,20 @@ void intel_lr_context_free(struct intel_context *ctx) } } +/** + * intel_lr_context_size() - return the size of the context for an engine + * @ring: which engine to find the context size for + * + * Each engine may require a different amount of space for a context image, + * so when allocating (or copying) an image, this function can be used to + * find the right size for the specific engine. + * + * Return: size (in bytes) of an engine-specific context image + * + * Note: this size includes the HWSP, which is part of the context image + * in LRC mode, but does not include the "shared data page" used with + * GuC submission. The caller should account for this if using the GuC. + */ uint32_t intel_lr_context_size(struct intel_engine_cs *ring) { int ret = 0; -- GitLab From c5236470feb59e357ce4d5fa58d26f0fbe432e54 Mon Sep 17 00:00:00 2001 From: Ankitprasad Sharma Date: Tue, 22 Dec 2015 11:50:44 +0530 Subject: [PATCH 0124/5324] drm/i915: Allow use of get_dma_address for stolen backed objects i915_gem_object_get_dma_address function is used to retrieve the dma address of a particular page so as to map it in a given GTT entry for CPU access. This function would be used for stolen backed objects also for tasks like pwrite, clearing of the pages etc. So the obj->get_page.sg needs to be initialized for the stolen objects also. Signed-off-by: Ankitprasad Sharma Link: http://patchwork.freedesktop.org/patch/msgid/1450765253-32104-2-git-send-email-ankitprasad.r.sharma@intel.com Reviewed-by: Tvrtko Ursulin Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_stolen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 3476877fc0d6..c384dc9c8a63 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -569,6 +569,9 @@ _i915_gem_object_create_stolen(struct drm_device *dev, if (obj->pages == NULL) goto cleanup; + obj->get_page.sg = obj->pages->sgl; + obj->get_page.last = 0; + i915_gem_object_pin_pages(obj); obj->stolen = stolen; -- GitLab From becd9ca2de656ccd8d02c434742388aead336147 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 5 Jan 2016 17:54:07 +0100 Subject: [PATCH 0125/5324] drm/i915: Tune down rpm wakelock debug checks They're causing massive amounts of dmesg noise and hence CI noise all over the place. Enabling them for a bit was good enough to refresh our task list of what's still needed to enable rpm by default. To make sure we're not forgetting to make this noisy again add a FIXME comment. Fixes: da5827c36607 ("drm/i915: add assert_rpm_wakelock_held helper") Cc: Imre Deak Cc: drm-intel-fixes@lists.freedesktop.org Cc: Chris Wilson Acked-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452012847-4737-1-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0438b575e1fa..a3b2025da563 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1453,8 +1453,10 @@ static inline void assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) { assert_rpm_device_not_suspended(dev_priv); - WARN_ONCE(!atomic_read(&dev_priv->pm.wakeref_count), - "RPM wakelock ref not held during HW access"); + /* FIXME: Needs to be converted back to WARN_ONCE, but currently causes + * too much noise. */ + if (!atomic_read(&dev_priv->pm.wakeref_count)) + DRM_DEBUG_DRIVER("RPM wakelock ref not held during HW access"); } static inline int -- GitLab From 42f1cae8c079bcceb3cff079fddc3ff8852c788f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Nov 2015 13:28:55 +0000 Subject: [PATCH 0126/5324] drm/i915: Restore inhibiting the load of the default context Following a GPU reset, we may leave the context in a poorly defined state, and reloading from that context will leave the GPU flummoxed. For secondary contexts, this will lead to that context being banned - but currently it is also causing the default context to become banned, leading to turmoil in the shared state. This is a regression from commit 6702cf16e0ba8b0129f5aa1b6609d4e9c70bc13b [v4.1] Author: Ben Widawsky Date: Mon Mar 16 16:00:58 2015 +0000 drm/i915: Initialize all contexts which quietly introduced the removal of the MI_RESTORE_INHIBIT on the default context. v2: Mark the global default context as uninitialized on GPU reset so that the context-local workarounds are reloaded upon re-enabling. Signed-off-by: Chris Wilson Cc: Michel Thierry Cc: Mika Kuoppala Cc: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1448630935-27377-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala Cc: stable@vger.kernel.org [danvet: This seems to fix a gpu hand on after the first resume, resulting in any future suspend operation failing with -EIO because the gpu seems to be in a funky state. Somehow this patch fixes that.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 900ffd044db8..c25083c78ba7 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -347,6 +347,10 @@ void i915_gem_context_reset(struct drm_device *dev) i915_gem_context_unreference(lctx); ring->last_context = NULL; } + + /* Force the GPU state to be reinitialised on enabling */ + if (ring->default_context) + ring->default_context->legacy_hw_ctx.initialized = false; } } @@ -715,7 +719,7 @@ static int do_switch(struct drm_i915_gem_request *req) if (ret) goto unpin_out; - if (!to->legacy_hw_ctx.initialized) { + if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) { hw_flags |= MI_RESTORE_INHIBIT; /* NB: If we inhibit the restore, the context is not allowed to * die because future work may end up depending on valid address -- GitLab From 0a8d8a8667c7e66f4fa2498be18d47f8b296b430 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 3 Dec 2015 11:37:38 -0800 Subject: [PATCH 0127/5324] drm/i915: Setup clipped src/dest coordinates during FB reconstruction (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plane state objects contain two copies of src/dest coordinates: the original (requested by userspace) coordinates in the base drm_plane_state object, and a second, clipped copy (i.e., what we actually want to program to the hardware) in intel_plane_state. We've only been setting up the former set of values during boot time FB reconstruction, but we should really be initializing both. Note that the code here probably still needs some more work since we make a lot of assumptions about how the BIOS programmed the hardware that may not always be true, especially on gen9+; e.g., * Primary plane might not be positioned at 0,0 * Primary plane could have been rotated by the BIOS * Primary plane might be scaled * The BIOS fb might be a single "extended mode" FB that spans multiple displays. * ...etc... v2: Reword/expand commit message description of assumptions we make Signed-off-by: Matt Roper Reviewed-by(v1): Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1449171462-30763-4-git-send-email-matthew.d.roper@intel.com Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eea2cd26ba17..c1a3969f3d4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2598,6 +2598,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, struct drm_plane_state *plane_state = primary->state; struct drm_crtc_state *crtc_state = intel_crtc->base.state; struct intel_plane *intel_plane = to_intel_plane(primary); + struct intel_plane_state *intel_state = + to_intel_plane_state(plane_state); struct drm_framebuffer *fb; if (!plane_config->fb) @@ -2659,6 +2661,15 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, plane_state->crtc_w = fb->width; plane_state->crtc_h = fb->height; + intel_state->src.x1 = plane_state->src_x; + intel_state->src.y1 = plane_state->src_y; + intel_state->src.x2 = plane_state->src_x + plane_state->src_w; + intel_state->src.y2 = plane_state->src_y + plane_state->src_h; + intel_state->dst.x1 = plane_state->crtc_x; + intel_state->dst.y1 = plane_state->crtc_y; + intel_state->dst.x2 = plane_state->crtc_x + plane_state->crtc_w; + intel_state->dst.y2 = plane_state->crtc_y + plane_state->crtc_h; + obj = intel_fb_obj(fb); if (obj->tiling_mode != I915_TILING_NONE) dev_priv->preserve_bios_swizzle = true; -- GitLab From ee91a15972cc70efa4d17b4bbdb61ff314528110 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 3 Dec 2015 11:37:39 -0800 Subject: [PATCH 0128/5324] drm/i915: Convert hsw_compute_linetime_wm to use in-flight state When watermark calculation was moved up to the atomic check phase, the code was updated to calculate based on in-flight atomic state rather than already-committed state. However the hsw_compute_linetime_wm() didn't get updated and continued to pull values out of the currently-committed CRTC state. On platforms that call this function (HSW/BDW only), this will cause problems when we go to enable the CRTC since we'll pull the current mode (off) rather than the mode we're calculating for and wind up with a divide by zero error. This was an oversight in commit: commit a28170f3389f4e42db95e595b0d86384a79de696 Author: Matt Roper Date: Thu Sep 24 15:53:16 2015 -0700 drm/i915: Calculate ILK-style watermarks during atomic check (v3) Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1449171462-30763-5-git-send-email-matthew.d.roper@intel.com Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 02fe081878ad..0f22d11937b4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1998,14 +1998,19 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, } static uint32_t -hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc) +hsw_compute_linetime_wm(struct drm_device *dev, + struct intel_crtc_state *cstate) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; + const struct drm_display_mode *adjusted_mode = + &cstate->base.adjusted_mode; u32 linetime, ips_linetime; - if (!intel_crtc->active) + if (!cstate->base.active) + return 0; + if (WARN_ON(adjusted_mode->crtc_clock == 0)) + return 0; + if (WARN_ON(dev_priv->cdclk_freq == 0)) return 0; /* The WM are computed with base on how long it takes to fill a single @@ -2313,8 +2318,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, pristate, sprstate, curstate, &pipe_wm->wm[0]); if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - pipe_wm->linetime = hsw_compute_linetime_wm(dev, - &intel_crtc->base); + pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); /* LP0 watermarks always use 1/2 DDB partitioning */ ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); -- GitLab From 151268821e6f08956b28b6ff90fae187a5b230b8 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 3 Dec 2015 11:37:40 -0800 Subject: [PATCH 0129/5324] drm/i915: Add extra paranoia to ILK watermark calculations Our low-level watermark calculation functions don't get called when the CRTC is disabled or the relevant plane is invisible, so they should never see a zero htotal or zero bpp. However add some checks to ensure this is true so that we don't wind up dividing by zero if we make a mistake elsewhere in the driver (which the atomic watermark series has revealed we might be). References: http://lists.freedesktop.org/archives/intel-gfx/2015-October/077370.html Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1449171462-30763-6-git-send-email-matthew.d.roper@intel.com Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_pm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0f22d11937b4..f9cbd2e81f54 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1672,6 +1672,9 @@ uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config) if (pipe_h < pfit_h) pipe_h = pfit_h; + if (WARN_ON(!pfit_w || !pfit_h)) + return pixel_rate; + pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h, pfit_w * pfit_h); } @@ -1703,6 +1706,8 @@ static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, if (WARN(latency == 0, "Latency value missing\n")) return UINT_MAX; + if (WARN_ON(!pipe_htotal)) + return UINT_MAX; ret = (latency * pixel_rate) / (pipe_htotal * 10000); ret = (ret + 1) * horiz_pixels * bytes_per_pixel; @@ -1713,6 +1718,17 @@ static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, uint8_t bytes_per_pixel) { + /* + * Neither of these should be possible since this function shouldn't be + * called if the CRTC is off or the plane is invisible. But let's be + * extra paranoid to avoid a potential divide-by-zero if we screw up + * elsewhere in the driver. + */ + if (WARN_ON(!bytes_per_pixel)) + return 0; + if (WARN_ON(!horiz_pixels)) + return 0; + return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; } -- GitLab From d93c037246104e403436ffe339bcb832185d0627 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 3 Dec 2015 11:37:41 -0800 Subject: [PATCH 0130/5324] drm/i915: Sanitize watermarks after hardware state readout (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although we can do a good job of reading out hardware state, the graphics firmware may have programmed the watermarks in a creative way that doesn't match how i915 would have chosen to program them. We shouldn't trust the firmware's watermark programming, but should rather re-calculate how we think WM's should be programmed and then shove those values into the hardware. We can do this pretty easily by creating a dummy top-level state, running it through the check process to calculate all the values, and then just programming the watermarks for each CRTC. v2: Move watermark sanitization after our BIOS fb reconstruction; the watermark calculations that we do here need to look at pstate->fb, which isn't setup yet in intel_modeset_setup_hw_state(), even though we have an enabled & visible plane. v3: - Don't move 'active = optimal' watermark assignment; we just undo that change in the next patch anyway. (Ville) - Move atomic helper locking fix to separate patch. (Maarten) v4: - Grab connection_mutex before calling atomic helper to duplicate state. The connector loop inside the helper will throw a WARN if we don't hold something to protect the connector list (and the helper itself doesn't try to lock the list). - Make failure to calculate watermarks for inherited state a WARN() since it probably indicates a serious problem in either our state readout code or our watermark code for this platform. Cc: Maarten Lankhorst Cc: Ville Syrjälä Signed-off-by: Matt Roper Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 79 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_pm.c | 10 ++-- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c6dd4db29cea..bde9c764b415 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,6 +623,7 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct intel_crtc *crtc, struct drm_atomic_state *state); + void (*program_watermarks)(struct intel_crtc_state *cstate); void (*update_wm)(struct drm_crtc *crtc); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c1a3969f3d4c..043adfa65203 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15276,6 +15276,78 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_enable_gt_powersave(dev); } +/* + * Calculate what we think the watermarks should be for the state we've read + * out of the hardware and then immediately program those watermarks so that + * we ensure the hardware settings match our internal state. + * + * We can calculate what we think WM's should be by creating a duplicate of the + * current state (which was constructed during hardware readout) and running it + * through the atomic check code to calculate new watermark values in the + * state object. + */ +static void sanitize_watermarks(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_atomic_state *state; + struct drm_crtc *crtc; + struct drm_crtc_state *cstate; + struct drm_modeset_acquire_ctx ctx; + int ret; + int i; + + /* Only supported on platforms that use atomic watermark design */ + if (!dev_priv->display.program_watermarks) + return; + + /* + * We need to hold connection_mutex before calling duplicate_state so + * that the connector loop is protected. + */ + drm_modeset_acquire_init(&ctx, 0); +retry: + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry; + } else if (WARN_ON(ret)) { + return; + } + + state = drm_atomic_helper_duplicate_state(dev, &ctx); + if (WARN_ON(IS_ERR(state))) + return; + + ret = intel_atomic_check(dev, state); + if (ret) { + /* + * If we fail here, it means that the hardware appears to be + * programmed in a way that shouldn't be possible, given our + * understanding of watermark requirements. This might mean a + * mistake in the hardware readout code or a mistake in the + * watermark calculations for a given platform. Raise a WARN + * so that this is noticeable. + * + * If this actually happens, we'll have to just leave the + * BIOS-programmed watermarks untouched and hope for the best. + */ + WARN(true, "Could not determine valid watermarks for inherited state\n"); + return; + } + + /* Write calculated watermark values back */ + to_i915(dev)->wm.config = to_intel_atomic_state(state)->wm_config; + for_each_crtc_in_state(state, crtc, cstate, i) { + struct intel_crtc_state *cs = to_intel_crtc_state(cstate); + + dev_priv->display.program_watermarks(cs); + } + + drm_atomic_state_free(state); + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + void intel_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -15396,6 +15468,13 @@ void intel_modeset_init(struct drm_device *dev) */ intel_find_initial_plane_obj(crtc, &plane_config); } + + /* + * Make sure hardware watermarks really match the state we read out. + * Note that we need to do this after reconstructing the BIOS fb's + * since the watermark calculation done here will use pstate->fb. + */ + sanitize_watermarks(dev); } static void intel_enable_pipe_a(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f9cbd2e81f54..db3ca41ce16b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3617,9 +3617,11 @@ static void skl_update_wm(struct drm_crtc *crtc) dev_priv->wm.skl_hw = *results; } -static void ilk_program_watermarks(struct drm_i915_private *dev_priv) +static void ilk_program_watermarks(struct intel_crtc_state *cstate) { - struct drm_device *dev = dev_priv->dev; + struct drm_crtc *crtc = cstate->base.crtc; + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config *config = &dev_priv->wm.config; @@ -3650,7 +3652,6 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) static void ilk_update_wm(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); @@ -3670,7 +3671,7 @@ static void ilk_update_wm(struct drm_crtc *crtc) intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; - ilk_program_watermarks(dev_priv); + ilk_program_watermarks(cstate); } static void skl_pipe_wm_active_state(uint32_t val, @@ -7000,6 +7001,7 @@ void intel_init_pm(struct drm_device *dev) dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; + dev_priv->display.program_watermarks = ilk_program_watermarks; } else { DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); -- GitLab From 31d10b5701964ed8806193807279ee7b4235e491 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 6 Jan 2016 13:54:43 +0100 Subject: [PATCH 0131/5324] drm/i915: Allow fuzzy matching in intel_compare_link_m_n This prevents a unnecessary modeset on a dell XPS 13 (2016). N is always a power of 2, which means that for fuzzy matching we should compare for inequality on the n values, then do fuzzy matching on the m values. Signed-off-by: Maarten Lankhorst Tested-by: Kenneth Graunke Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/568D0E93.304@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 043adfa65203..ab0b406ee8ca 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12577,19 +12577,22 @@ intel_compare_m_n(unsigned int m, unsigned int n, BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX); - if (m > m2) { - while (m > m2) { + if (n > n2) { + while (n > n2) { m2 <<= 1; n2 <<= 1; } - } else if (m < m2) { - while (m < m2) { + } else if (n < n2) { + while (n < n2) { m <<= 1; n <<= 1; } } - return m == m2 && n == n2; + if (n != n2) + return false; + + return intel_fuzzy_clock_check(m, m2); } static bool -- GitLab From e2c90dd7e11e3025b46719a79fb4bb1e7a5cef9f Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 21 Dec 2015 14:12:52 +0000 Subject: [PATCH 0132/5324] x86/efi-bgrt: Replace early_memremap() with memremap() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Môshe reported the following warning triggered on his machine since commit 50a0cb565246 ("x86/efi-bgrt: Fix kernel panic when mapping BGRT data"), [ 0.026936] ------------[ cut here ]------------ [ 0.026941] WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:137 __early_ioremap+0x102/0x1bb() [ 0.026941] Modules linked in: [ 0.026944] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc1 #2 [ 0.026945] Hardware name: Dell Inc. XPS 13 9343/09K8G1, BIOS A05 07/14/2015 [ 0.026946] 0000000000000000 900f03d5a116524d ffffffff81c03e60 ffffffff813a3fff [ 0.026948] 0000000000000000 ffffffff81c03e98 ffffffff810a0852 00000000d7b76000 [ 0.026949] 0000000000000000 0000000000000001 0000000000000001 000000000000017c [ 0.026951] Call Trace: [ 0.026955] [] dump_stack+0x44/0x55 [ 0.026958] [] warn_slowpath_common+0x82/0xc0 [ 0.026959] [] warn_slowpath_null+0x1a/0x20 [ 0.026961] [] __early_ioremap+0x102/0x1bb [ 0.026962] [] early_memremap+0x13/0x15 [ 0.026964] [] efi_bgrt_init+0x162/0x1ad [ 0.026966] [] efi_late_init+0x9/0xb [ 0.026968] [] start_kernel+0x46f/0x49f [ 0.026970] [] ? early_idt_handler_array+0x120/0x120 [ 0.026972] [] x86_64_start_reservations+0x2a/0x2c [ 0.026974] [] x86_64_start_kernel+0x14a/0x16d [ 0.026977] ---[ end trace f9b3812eb8e24c58 ]--- [ 0.026978] efi_bgrt: Ignoring BGRT: failed to map image memory early_memremap() has an upper limit on the size of mapping it can handle which is ~200KB. Clearly the BGRT image on Môshe's machine is much larger than that. There's actually no reason to restrict ourselves to using the early_* version of memremap() - the ACPI BGRT driver is invoked late enough in boot that we can use the standard version, with the benefit that the late version allows mappings of arbitrary size. Reported-by: Môshe van der Sterre Tested-by: Môshe van der Sterre Signed-off-by: Matt Fleming Cc: Josh Triplett Cc: Sai Praneeth Prakhya Cc: Borislav Petkov Link: http://lkml.kernel.org/r/1450707172-12561-1-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Thomas Gleixner --- arch/x86/platform/efi/efi-bgrt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index bf51f4c02562..b0970661870a 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -72,14 +72,14 @@ void __init efi_bgrt_init(void) return; } - image = early_memremap(bgrt_tab->image_address, sizeof(bmp_header)); + image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB); if (!image) { pr_err("Ignoring BGRT: failed to map image header memory\n"); return; } memcpy(&bmp_header, image, sizeof(bmp_header)); - early_memunmap(image, sizeof(bmp_header)); + memunmap(image); bgrt_image_size = bmp_header.size; bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); @@ -89,7 +89,7 @@ void __init efi_bgrt_init(void) return; } - image = early_memremap(bgrt_tab->image_address, bmp_header.size); + image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB); if (!image) { pr_err("Ignoring BGRT: failed to map image memory\n"); kfree(bgrt_image); @@ -98,5 +98,5 @@ void __init efi_bgrt_init(void) } memcpy(bgrt_image, image, bgrt_image_size); - early_memunmap(image, bmp_header.size); + memunmap(image); } -- GitLab From 2dfb0b816d224379efc534764388745c474abeb4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 7 Jan 2016 10:29:10 +0200 Subject: [PATCH 0133/5324] drm/i915: shut up gen8+ SDE irq dmesg noise, again We still keep getting [ 4.249930] [drm:gen8_irq_handler [i915]] *ERROR* The master control interrupt lied (SDE)! This reverts commit 820da7ae46332fa709b171eb7ba57cbd023fa6df Author: Jani Nikula Date: Wed Nov 25 16:47:23 2015 +0200 Revert "drm/i915: shut up gen8+ SDE irq dmesg noise" which in itself is a revert, so this is just doing commit 97e5ed1111dcc5300a0f59a55248cd243937a8ab Author: Daniel Vetter Date: Fri Oct 23 10:56:12 2015 +0200 drm/i915: shut up gen8+ SDE irq dmesg noise all over again. I'll stop pretending I understand what's going on like I did when I thought I'd fixed this for good in commit 6a39d7c986be4fd18eb019e9cdbf774ec36c9f77 Author: Jani Nikula Date: Wed Nov 25 16:47:22 2015 +0200 drm/i915: fix the SDE irq dmesg warnings properly Reported-by: Chris Wilson Reference: http://mid.gmane.org/20151213124945.GA5715@nuc-i3427.alporthouse.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92084 Cc: drm-intel-fixes@lists.freedesktop.org Fixes: 820da7ae4633 ("Revert "drm/i915: shut up gen8+ SDE irq dmesg noise"") Acked-by: Chris Wilson Acked-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452155350-14658-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3f8c753997ba..fa8afa7860ae 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2414,9 +2414,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) spt_irq_handler(dev, pch_iir); else cpt_irq_handler(dev, pch_iir); - } else - DRM_ERROR("The master control interrupt lied (SDE)!\n"); - + } else { + /* + * Like on previous PCH there seems to be something + * fishy going on with forwarding PCH interrupts. + */ + DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n"); + } } I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); -- GitLab From 396e33ae204f52abebec9e578f44c749305500f4 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Wed, 6 Jan 2016 11:34:30 -0800 Subject: [PATCH 0134/5324] drm/i915: Add two-stage ILK-style watermark programming (v10) In addition to calculating final watermarks, let's also pre-calculate a set of intermediate watermark values at atomic check time. These intermediate watermarks are a combination of the watermarks for the old state and the new state; they should satisfy the requirements of both states which means they can be programmed immediately when we commit the atomic state (without waiting for a vblank). Once the vblank does happen, we can then re-program watermarks to the more optimal final value. v2: Significant rebasing/rewriting. v3: - Move 'need_postvbl_update' flag to CRTC state (Daniel) - Don't forget to check intermediate watermark values for validity (Maarten) - Don't due async watermark optimization; just do it at the end of the atomic transaction, after waiting for vblanks. We do want it to be async eventually, but adding that now will cause more trouble for Maarten's in-progress work. (Maarten) - Don't allocate space in crtc_state for intermediate watermarks on platforms that don't need it (gen9+). - Move WaCxSRDisabledForSpriteScaling:ivb into intel_begin_crtc_commit now that ilk_update_wm is gone. v4: - Add a wm_mutex to cover updates to intel_crtc->active and the need_postvbl_update flag. Since we don't have async yet it isn't terribly important yet, but might as well add it now. - Change interface to program watermarks. Platforms will now expose .initial_watermarks() and .optimize_watermarks() functions to do watermark programming. These should lock wm_mutex, copy the appropriate state values into intel_crtc->active, and then call the internal program watermarks function. v5: - Skip intermediate watermark calculation/check during initial hardware readout since we don't trust the existing HW values (and don't have valid values of our own yet). - Don't try to call .optimize_watermarks() on platforms that don't have atomic watermarks yet. (Maarten) v6: - Rebase v7: - Further rebase v8: - A few minor indentation and line length fixes v9: - Yet another rebase since Maarten's patches reworked a bunch of the code (wm_pre, wm_post, etc.) that this was previously based on. v10: - Move wm_mutex to dev_priv to protect against racing commits against disjoint CRTC sets. (Maarten) - Drop unnecessary clearing of cstate->wm.need_postvbl_update (Maarten) Cc: Maarten Lankhorst Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1452108870-24204-1-git-send-email-matthew.d.roper@intel.com Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/i915/i915_dma.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 13 ++- drivers/gpu/drm/i915/intel_atomic.c | 1 + drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 28 ++++- drivers/gpu/drm/i915/intel_pm.c | 162 +++++++++++++++++++-------- 6 files changed, 241 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 988a3806512a..44a896ce32e6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -893,6 +893,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->sb_lock); mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); + mutex_init(&dev_priv->wm.wm_mutex); intel_pm_setup(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bde9c764b415..61b9d910b912 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -623,7 +623,11 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct intel_crtc *crtc, struct drm_atomic_state *state); - void (*program_watermarks)(struct intel_crtc_state *cstate); + int (*compute_intermediate_wm)(struct drm_device *dev, + struct intel_crtc *intel_crtc, + struct intel_crtc_state *newstate); + void (*initial_watermarks)(struct intel_crtc_state *cstate); + void (*optimize_watermarks)(struct intel_crtc_state *cstate); void (*update_wm)(struct drm_crtc *crtc); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); @@ -1927,6 +1931,13 @@ struct drm_i915_private { }; uint8_t max_level; + + /* + * Should be held around atomic WM register writing; also + * protects * intel_crtc->wm.active and + * cstate->wm.need_postvbl_update. + */ + struct mutex wm_mutex; } wm; struct i915_runtime_pm pm; diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 4625f8a9ba12..9682d94af710 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -97,6 +97,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->disable_lp_wm = false; crtc_state->disable_cxsr = false; crtc_state->wm_changed = false; + crtc_state->wm.need_postvbl_update = false; return &crtc_state->base; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ab0b406ee8ca..24b3503f94be 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4858,7 +4858,42 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) intel_set_memory_cxsr(dev_priv, false); } - if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed) + /* + * IVB workaround: must disable low power watermarks for at least + * one frame before enabling scaling. LP watermarks can be re-enabled + * when scaling is disabled. + * + * WaCxSRDisabledForSpriteScaling:ivb + */ + if (pipe_config->disable_lp_wm) { + ilk_disable_lp_wm(dev); + intel_wait_for_vblank(dev, crtc->pipe); + } + + /* + * If we're doing a modeset, we're done. No need to do any pre-vblank + * watermark programming here. + */ + if (needs_modeset(&pipe_config->base)) + return; + + /* + * For platforms that support atomic watermarks, program the + * 'intermediate' watermarks immediately. On pre-gen9 platforms, these + * will be the intermediate values that are safe for both pre- and + * post- vblank; when vblank happens, the 'active' values will be set + * to the final 'target' values and we'll do this again to get the + * optimal watermarks. For gen9+ platforms, the values we program here + * will be the final target values which will get automatically latched + * at vblank time; no further programming will be necessary. + * + * If a platform hasn't been transitioned to atomic watermarks yet, + * we'll continue to update watermarks the old way, if flags tell + * us to. + */ + if (dev_priv->display.initial_watermarks != NULL) + dev_priv->display.initial_watermarks(pipe_config); + else if (pipe_config->wm_changed) intel_update_watermarks(&crtc->base); } @@ -11918,6 +11953,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, pipe_config->wm_changed = true; } + /* Pre-gen9 platforms need two-step watermark updates */ + if (pipe_config->wm_changed && INTEL_INFO(dev)->gen < 9 && + dev_priv->display.optimize_watermarks) + to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true; + if (visible || was_visible) intel_crtc->atomic.fb_bits |= to_intel_plane(plane)->frontbuffer_bit; @@ -12074,8 +12114,29 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ret = 0; if (dev_priv->display.compute_pipe_wm) { ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); - if (ret) + if (ret) { + DRM_DEBUG_KMS("Target pipe watermarks are invalid\n"); + return ret; + } + } + + if (dev_priv->display.compute_intermediate_wm && + !to_intel_atomic_state(state)->skip_intermediate_wm) { + if (WARN_ON(!dev_priv->display.compute_pipe_wm)) + return 0; + + /* + * Calculate 'intermediate' watermarks that satisfy both the + * old state and the new state. We can program these + * immediately. + */ + ret = dev_priv->display.compute_intermediate_wm(crtc->dev, + intel_crtc, + pipe_config); + if (ret) { + DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n"); return ret; + } } if (INTEL_INFO(dev)->gen >= 9) { @@ -13530,6 +13591,7 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; + struct intel_crtc_state *intel_cstate; int ret = 0, i; bool hw_check = intel_state->modeset; @@ -13629,6 +13691,20 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_helper_wait_for_vblanks(dev, state); + /* + * Now that the vblank has passed, we can go ahead and program the + * optimal watermarks on platforms that need two-step watermark + * programming. + * + * TODO: Move this (and other cleanup) to an async worker eventually. + */ + for_each_crtc_in_state(state, crtc, crtc_state, i) { + intel_cstate = to_intel_crtc_state(crtc->state); + + if (dev_priv->display.optimize_watermarks) + dev_priv->display.optimize_watermarks(intel_cstate); + } + mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); mutex_unlock(&dev->struct_mutex); @@ -15300,7 +15376,7 @@ static void sanitize_watermarks(struct drm_device *dev) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.program_watermarks) + if (!dev_priv->display.optimize_watermarks) return; /* @@ -15321,6 +15397,13 @@ static void sanitize_watermarks(struct drm_device *dev) if (WARN_ON(IS_ERR(state))) return; + /* + * Hardware readout is the only time we don't want to calculate + * intermediate watermarks (since we don't trust the current + * watermarks). + */ + to_intel_atomic_state(state)->skip_intermediate_wm = true; + ret = intel_atomic_check(dev, state); if (ret) { /* @@ -15343,7 +15426,8 @@ static void sanitize_watermarks(struct drm_device *dev) for_each_crtc_in_state(state, crtc, cstate, i) { struct intel_crtc_state *cs = to_intel_crtc_state(cstate); - dev_priv->display.program_watermarks(cs); + cs->wm.need_postvbl_update = true; + dev_priv->display.optimize_watermarks(cs); } drm_atomic_state_free(state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a3b2025da563..b7a33f6cbbbc 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -260,6 +260,12 @@ struct intel_atomic_state { struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; struct intel_wm_config wm_config; + + /* + * Current watermarks can't be trusted during hardware readout, so + * don't bother calculating intermediate watermarks. + */ + bool skip_intermediate_wm; }; struct intel_plane_state { @@ -507,13 +513,29 @@ struct intel_crtc_state { struct { /* - * optimal watermarks, programmed post-vblank when this state - * is committed + * Optimal watermarks, programmed post-vblank when this state + * is committed. */ union { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } optimal; + + /* + * Intermediate watermarks; these can be programmed immediately + * since they satisfy both the current configuration we're + * switching away from and the new configuration we're switching + * to. + */ + struct intel_pipe_wm intermediate; + + /* + * Platforms with two-step watermark programming will need to + * update watermark programming post-vblank to switch from the + * safe intermediate watermarks to the optimal final + * watermarks. + */ + bool need_postvbl_update; } wm; }; @@ -600,6 +622,7 @@ struct intel_crtc { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } active; + /* allow CxSR on this pipe */ bool cxsr_allowed; } wm; @@ -1566,6 +1589,7 @@ void skl_wm_get_hw_state(struct drm_device *dev); void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, struct skl_ddb_allocation *ddb /* out */); uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); +bool ilk_disable_lp_wm(struct drm_device *dev); /* intel_sdvo.c */ bool intel_sdvo_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index db3ca41ce16b..9df9e9a22f3c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2273,6 +2273,29 @@ static void skl_setup_wm_latency(struct drm_device *dev) intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); } +static bool ilk_validate_pipe_wm(struct drm_device *dev, + struct intel_pipe_wm *pipe_wm) +{ + /* LP0 watermark maximums depend on this pipe alone */ + const struct intel_wm_config config = { + .num_pipes_active = 1, + .sprites_enabled = pipe_wm->sprites_enabled, + .sprites_scaled = pipe_wm->sprites_scaled, + }; + struct ilk_wm_maximums max; + + /* LP0 watermarks always use 1/2 DDB partitioning */ + ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); + + /* At least LP0 must be valid */ + if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) { + DRM_DEBUG_KMS("LP0 watermark invalid\n"); + return false; + } + + return true; +} + /* Compute new watermarks for the pipe */ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct drm_atomic_state *state) @@ -2287,10 +2310,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct intel_plane_state *sprstate = NULL; struct intel_plane_state *curstate = NULL; int level, max_level = ilk_wm_max_level(dev); - /* LP0 watermark maximums depend on this pipe alone */ - struct intel_wm_config config = { - .num_pipes_active = 1, - }; struct ilk_wm_maximums max; cstate = intel_atomic_get_crtc_state(state, intel_crtc); @@ -2313,21 +2332,18 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, curstate = to_intel_plane_state(ps); } - config.sprites_enabled = sprstate->visible; - config.sprites_scaled = sprstate->visible && + pipe_wm->pipe_enabled = cstate->base.active; + pipe_wm->sprites_enabled = sprstate->visible; + pipe_wm->sprites_scaled = sprstate->visible && (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); - pipe_wm->pipe_enabled = cstate->base.active; - pipe_wm->sprites_enabled = config.sprites_enabled; - pipe_wm->sprites_scaled = config.sprites_scaled; - /* ILK/SNB: LP2+ watermarks only w/o sprites */ if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) max_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ - if (config.sprites_scaled) + if (pipe_wm->sprites_scaled) max_level = 0; ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, @@ -2336,12 +2352,8 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, if (IS_HASWELL(dev) || IS_BROADWELL(dev)) pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); - /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); - - /* At least LP0 must be valid */ - if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) - return -EINVAL; + if (!ilk_validate_pipe_wm(dev, pipe_wm)) + return false; ilk_compute_wm_reg_maximums(dev, 1, &max); @@ -2365,6 +2377,59 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, return 0; } +/* + * Build a set of 'intermediate' watermark values that satisfy both the old + * state and the new state. These can be programmed to the hardware + * immediately. + */ +static int ilk_compute_intermediate_wm(struct drm_device *dev, + struct intel_crtc *intel_crtc, + struct intel_crtc_state *newstate) +{ + struct intel_pipe_wm *a = &newstate->wm.intermediate; + struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk; + int level, max_level = ilk_wm_max_level(dev); + + /* + * Start with the final, target watermarks, then combine with the + * currently active watermarks to get values that are safe both before + * and after the vblank. + */ + *a = newstate->wm.optimal.ilk; + a->pipe_enabled |= b->pipe_enabled; + a->sprites_enabled |= b->sprites_enabled; + a->sprites_scaled |= b->sprites_scaled; + + for (level = 0; level <= max_level; level++) { + struct intel_wm_level *a_wm = &a->wm[level]; + const struct intel_wm_level *b_wm = &b->wm[level]; + + a_wm->enable &= b_wm->enable; + a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val); + a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val); + a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val); + a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val); + } + + /* + * We need to make sure that these merged watermark values are + * actually a valid configuration themselves. If they're not, + * there's no safe way to transition from the old state to + * the new state, so we need to fail the atomic transaction. + */ + if (!ilk_validate_pipe_wm(dev, a)) + return -EINVAL; + + /* + * If our intermediate WM are identical to the final WM, then we can + * omit the post-vblank programming; only update if it's different. + */ + if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) != 0) + newstate->wm.need_postvbl_update = false; + + return 0; +} + /* * Merge the watermarks from all active pipes for a specific level. */ @@ -2377,9 +2442,7 @@ static void ilk_merge_wm_level(struct drm_device *dev, ret_wm->enable = true; for_each_intel_crtc(dev, intel_crtc) { - const struct intel_crtc_state *cstate = - to_intel_crtc_state(intel_crtc->base.state); - const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; + const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; if (!active->pipe_enabled) @@ -2527,15 +2590,14 @@ static void ilk_compute_wm_results(struct drm_device *dev, /* LP0 register values */ for_each_intel_crtc(dev, intel_crtc) { - const struct intel_crtc_state *cstate = - to_intel_crtc_state(intel_crtc->base.state); enum pipe pipe = intel_crtc->pipe; - const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0]; + const struct intel_wm_level *r = + &intel_crtc->wm.active.ilk.wm[0]; if (WARN_ON(!r->enable)) continue; - results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime; + results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime; results->wm_pipe[pipe] = (r->pri_val << WM0_PIPE_PLANE_SHIFT) | @@ -2742,7 +2804,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, dev_priv->wm.hw = *results; } -static bool ilk_disable_lp_wm(struct drm_device *dev) +bool ilk_disable_lp_wm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3617,11 +3679,9 @@ static void skl_update_wm(struct drm_crtc *crtc) dev_priv->wm.skl_hw = *results; } -static void ilk_program_watermarks(struct intel_crtc_state *cstate) +static void ilk_program_watermarks(struct drm_i915_private *dev_priv) { - struct drm_crtc *crtc = cstate->base.crtc; - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_device *dev = dev_priv->dev; struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config *config = &dev_priv->wm.config; @@ -3650,28 +3710,28 @@ static void ilk_program_watermarks(struct intel_crtc_state *cstate) ilk_write_wm_values(dev_priv, &results); } -static void ilk_update_wm(struct drm_crtc *crtc) +static void ilk_initial_watermarks(struct intel_crtc_state *cstate) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); - - WARN_ON(cstate->base.active != intel_crtc->active); + struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); - /* - * IVB workaround: must disable low power watermarks for at least - * one frame before enabling scaling. LP watermarks can be re-enabled - * when scaling is disabled. - * - * WaCxSRDisabledForSpriteScaling:ivb - */ - if (cstate->disable_lp_wm) { - ilk_disable_lp_wm(crtc->dev); - intel_wait_for_vblank(crtc->dev, intel_crtc->pipe); - } + mutex_lock(&dev_priv->wm.wm_mutex); + intel_crtc->wm.active.ilk = cstate->wm.intermediate; + ilk_program_watermarks(dev_priv); + mutex_unlock(&dev_priv->wm.wm_mutex); +} - intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; +static void ilk_optimize_watermarks(struct intel_crtc_state *cstate) +{ + struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); + struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); - ilk_program_watermarks(cstate); + mutex_lock(&dev_priv->wm.wm_mutex); + if (cstate->wm.need_postvbl_update) { + intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; + ilk_program_watermarks(dev_priv); + } + mutex_unlock(&dev_priv->wm.wm_mutex); } static void skl_pipe_wm_active_state(uint32_t val, @@ -6999,9 +7059,13 @@ void intel_init_pm(struct drm_device *dev) dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { - dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; - dev_priv->display.program_watermarks = ilk_program_watermarks; + dev_priv->display.compute_intermediate_wm = + ilk_compute_intermediate_wm; + dev_priv->display.initial_watermarks = + ilk_initial_watermarks; + dev_priv->display.optimize_watermarks = + ilk_optimize_watermarks; } else { DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); -- GitLab From 2fde13910c8c3cf04011bf867d45de447be6d525 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:06 +0100 Subject: [PATCH 0135/5324] drm/i915: Use passed plane state for sprite planes, v4. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't use plane->state directly, use the pointer from commit_plane. Changes since v1: - Fix uses of plane->state->rotation and color key to use the passed state too. - Only pass crtc_state and plane_state to update_plane. Changes since v2: - Rebased. Changes since v3: - Small whitespace changes and only assign 1 variable per line. - Constify plane_state and crtc_state. (vsyrjala) Signed-off-by: Maarten Lankhorst Cc: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_drv.h | 10 +-- drivers/gpu/drm/i915/intel_sprite.c | 124 +++++++++++++++------------- 2 files changed, 71 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b7a33f6cbbbc..6f3850beccd9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -681,16 +681,12 @@ struct intel_plane { /* * NOTE: Do not place new plane state fields here (e.g., when adding * new plane properties). New runtime state should now be placed in - * the intel_plane_state structure and accessed via drm_plane->state. + * the intel_plane_state structure and accessed via plane_state. */ void (*update_plane)(struct drm_plane *plane, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h); + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state); void (*disable_plane)(struct drm_plane *plane, struct drm_crtc *crtc); int (*check_plane)(struct drm_plane *plane, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index f8bf6222fe48..4f9ebc117a34 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -178,28 +178,33 @@ void intel_pipe_update_end(struct intel_crtc *crtc) } static void -skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) +skl_update_plane(struct drm_plane *drm_plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { struct drm_device *dev = drm_plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(drm_plane); + struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); const int pipe = intel_plane->pipe; const int plane = intel_plane->plane + 1; u32 plane_ctl, stride_div, stride; - const struct drm_intel_sprite_colorkey *key = - &to_intel_plane_state(drm_plane->state)->ckey; + const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 surf_addr; u32 tile_height, plane_offset, plane_size; unsigned int rotation; int x_offset, y_offset; - struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config; - int scaler_id; + int crtc_x = plane_state->dst.x1; + int crtc_y = plane_state->dst.y1; + uint32_t crtc_w = drm_rect_width(&plane_state->dst); + uint32_t crtc_h = drm_rect_height(&plane_state->dst); + uint32_t x = plane_state->src.x1 >> 16; + uint32_t y = plane_state->src.y1 >> 16; + uint32_t src_w = drm_rect_width(&plane_state->src) >> 16; + uint32_t src_h = drm_rect_height(&plane_state->src) >> 16; + const struct intel_scaler *scaler = + &crtc_state->scaler_state.scalers[plane_state->scaler_id]; plane_ctl = PLANE_CTL_ENABLE | PLANE_CTL_PIPE_GAMMA_ENABLE | @@ -208,14 +213,12 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, plane_ctl |= skl_plane_ctl_format(fb->pixel_format); plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); - rotation = drm_plane->state->rotation; + rotation = plane_state->base.rotation; plane_ctl |= skl_plane_ctl_rotation(rotation); stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], fb->pixel_format); - scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id; - /* Sizes are 0 based */ src_w--; src_h--; @@ -256,13 +259,13 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, I915_WRITE(PLANE_SIZE(pipe, plane), plane_size); /* program plane scaler */ - if (scaler_id >= 0) { + if (plane_state->scaler_id >= 0) { uint32_t ps_ctrl = 0; + int scaler_id = plane_state->scaler_id; DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane, PS_PLANE_SEL(plane)); - ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) | - crtc_state->scaler_state.scalers[scaler_id].mode; + ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) | scaler->mode; I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0); I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); @@ -334,24 +337,29 @@ chv_update_csc(struct intel_plane *intel_plane, uint32_t format) } static void -vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) +vlv_update_plane(struct drm_plane *dplane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { struct drm_device *dev = dplane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(dplane); + struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int pipe = intel_plane->pipe; int plane = intel_plane->plane; u32 sprctl; unsigned long sprsurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - const struct drm_intel_sprite_colorkey *key = - &to_intel_plane_state(dplane->state)->ckey; + const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; + int crtc_x = plane_state->dst.x1; + int crtc_y = plane_state->dst.y1; + uint32_t crtc_w = drm_rect_width(&plane_state->dst); + uint32_t crtc_h = drm_rect_height(&plane_state->dst); + uint32_t x = plane_state->src.x1 >> 16; + uint32_t y = plane_state->src.y1 >> 16; + uint32_t src_w = drm_rect_width(&plane_state->src) >> 16; + uint32_t src_h = drm_rect_height(&plane_state->src) >> 16; sprctl = SP_ENABLE; @@ -421,7 +429,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, fb->pitches[0]); linear_offset -= sprsurf_offset; - if (dplane->state->rotation == BIT(DRM_ROTATE_180)) { + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { sprctl |= SP_ROTATE_180; x += src_w; @@ -474,23 +482,28 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) } static void -ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) +ivb_update_plane(struct drm_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); + struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); enum pipe pipe = intel_plane->pipe; u32 sprctl, sprscale = 0; unsigned long sprsurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - const struct drm_intel_sprite_colorkey *key = - &to_intel_plane_state(plane->state)->ckey; + const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; + int crtc_x = plane_state->dst.x1; + int crtc_y = plane_state->dst.y1; + uint32_t crtc_w = drm_rect_width(&plane_state->dst); + uint32_t crtc_h = drm_rect_height(&plane_state->dst); + uint32_t x = plane_state->src.x1 >> 16; + uint32_t y = plane_state->src.y1 >> 16; + uint32_t src_w = drm_rect_width(&plane_state->src) >> 16; + uint32_t src_h = drm_rect_height(&plane_state->src) >> 16; sprctl = SPRITE_ENABLE; @@ -550,7 +563,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, pixel_size, fb->pitches[0]); linear_offset -= sprsurf_offset; - if (plane->state->rotation == BIT(DRM_ROTATE_180)) { + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { sprctl |= SPRITE_ROTATE_180; /* HSW and BDW does this automagically in hardware */ @@ -612,23 +625,28 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) } static void -ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) +ilk_update_plane(struct drm_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane *intel_plane = to_intel_plane(plane); + struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int pipe = intel_plane->pipe; unsigned long dvssurf_offset, linear_offset; u32 dvscntr, dvsscale; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - const struct drm_intel_sprite_colorkey *key = - &to_intel_plane_state(plane->state)->ckey; + const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; + int crtc_x = plane_state->dst.x1; + int crtc_y = plane_state->dst.y1; + uint32_t crtc_w = drm_rect_width(&plane_state->dst); + uint32_t crtc_h = drm_rect_height(&plane_state->dst); + uint32_t x = plane_state->src.x1 >> 16; + uint32_t y = plane_state->src.y1 >> 16; + uint32_t src_w = drm_rect_width(&plane_state->src) >> 16; + uint32_t src_h = drm_rect_height(&plane_state->src) >> 16; dvscntr = DVS_ENABLE; @@ -684,7 +702,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, pixel_size, fb->pitches[0]); linear_offset -= dvssurf_offset; - if (plane->state->rotation == BIT(DRM_ROTATE_180)) { + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { dvscntr |= DVS_ROTATE_180; x += src_w; @@ -917,23 +935,17 @@ static void intel_commit_sprite_plane(struct drm_plane *plane, struct intel_plane_state *state) { - struct drm_crtc *crtc = state->base.crtc; struct intel_plane *intel_plane = to_intel_plane(plane); - struct drm_framebuffer *fb = state->base.fb; - - crtc = crtc ? crtc : plane->crtc; if (state->visible) { - intel_plane->update_plane(plane, crtc, fb, - state->dst.x1, state->dst.y1, - drm_rect_width(&state->dst), - drm_rect_height(&state->dst), - state->src.x1 >> 16, - state->src.y1 >> 16, - drm_rect_width(&state->src) >> 16, - drm_rect_height(&state->src) >> 16); + struct intel_crtc_state *crtc_state = + to_intel_crtc(state->base.crtc)->config; + + intel_plane->update_plane(plane, crtc_state, state); } else { - intel_plane->disable_plane(plane, crtc); + struct drm_crtc *crtc = state->base.crtc; + + intel_plane->disable_plane(plane, crtc ?: plane->crtc); } } -- GitLab From a758e68458258f0d8664bdf8fa833bddfdabbed6 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:07 +0100 Subject: [PATCH 0136/5324] drm/i915: Do not use commit_plane for sprite planes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use update_plane and disable_plane directly. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-3-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_atomic_plane.c | 12 +++++++++++- drivers/gpu/drm/i915/intel_sprite.c | 19 ------------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 856c3118bb87..969aa410deaa 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -194,8 +194,18 @@ static void intel_plane_atomic_update(struct drm_plane *plane, struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane_state *intel_state = to_intel_plane_state(plane->state); + struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; + struct drm_crtc_state *crtc_state = + drm_atomic_get_existing_crtc_state(old_state->state, crtc); - intel_plane->commit_plane(plane, intel_state); + if (intel_plane->commit_plane) + intel_plane->commit_plane(plane, intel_state); + else if (intel_state->visible) + intel_plane->update_plane(plane, + to_intel_crtc_state(crtc_state), + intel_state); + else + intel_plane->disable_plane(plane, crtc); } const struct drm_plane_helper_funcs intel_plane_helper_funcs = { diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4f9ebc117a34..73dfb38886b9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -931,24 +931,6 @@ intel_check_sprite_plane(struct drm_plane *plane, return 0; } -static void -intel_commit_sprite_plane(struct drm_plane *plane, - struct intel_plane_state *state) -{ - struct intel_plane *intel_plane = to_intel_plane(plane); - - if (state->visible) { - struct intel_crtc_state *crtc_state = - to_intel_crtc(state->base.crtc)->config; - - intel_plane->update_plane(plane, crtc_state, state); - } else { - struct drm_crtc *crtc = state->base.crtc; - - intel_plane->disable_plane(plane, crtc ?: plane->crtc); - } -} - int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -1130,7 +1112,6 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) intel_plane->plane = plane; intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane); intel_plane->check_plane = intel_check_sprite_plane; - intel_plane->commit_plane = intel_commit_sprite_plane; possible_crtcs = (1 << pipe); ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, &intel_plane_funcs, -- GitLab From edd62601dd6a08e5f25cb84033e7fd9371032a13 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:08 +0100 Subject: [PATCH 0137/5324] drm/i915: Remove some visibility checks from intel_crtc_update_cursor. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is duplicated with intel_check_cursor_plane, and with all non-atomic paths removed this should be dead code. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 24b3503f94be..4fe0c4d02fda 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -85,8 +85,6 @@ static const uint32_t intel_cursor_formats[] = { DRM_FORMAT_ARGB8888, }; -static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); - static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config); static void ironlake_pch_clock_get(struct intel_crtc *crtc, @@ -10237,25 +10235,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, base = intel_crtc->cursor_addr; - if (x >= intel_crtc->config->pipe_src_w) - on = false; - - if (y >= intel_crtc->config->pipe_src_h) - on = false; - if (x < 0) { - if (x + cursor_state->crtc_w <= 0) - on = false; - pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; x = -x; } pos |= x << CURSOR_X_SHIFT; if (y < 0) { - if (y + cursor_state->crtc_h <= 0) - on = false; - pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; y = -y; } -- GitLab From f28580214407d1adeb08ad8dd0af059bf6220a51 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:09 +0100 Subject: [PATCH 0138/5324] drm/i915: Make disable_cursor_plane similar to commit_cursor_plane. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update cursor_addr when disable_plane is called. This is required to make commit_cursor_plane take a crtc_state and a plane_state. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-5-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4fe0c4d02fda..0483c2429a9d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14256,6 +14256,9 @@ static void intel_disable_cursor_plane(struct drm_plane *plane, struct drm_crtc *crtc) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + intel_crtc->cursor_addr = 0; intel_crtc_update_cursor(crtc, false); } -- GitLab From 55a08b3f2bb0d69ba486c5d88602647fa6649de9 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:10 +0100 Subject: [PATCH 0139/5324] drm/i915: Use the plane state for cursor updates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor planes grab the state from plane->state instead of the state that was passed. The only updates are atomic now, so use the plane_state that's passed in. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-6-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++-------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0483c2429a9d..07715f985da1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10112,16 +10112,17 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, return true; } -static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on) +static void i845_update_cursor(struct drm_crtc *crtc, u32 base, + const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t cntl = 0, size = 0; - if (on) { - unsigned int width = intel_crtc->base.cursor->state->crtc_w; - unsigned int height = intel_crtc->base.cursor->state->crtc_h; + if (plane_state && plane_state->visible) { + unsigned int width = plane_state->base.crtc_w; + unsigned int height = plane_state->base.crtc_h; unsigned int stride = roundup_pow_of_two(width) * 4; switch (stride) { @@ -10174,7 +10175,8 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on) } } -static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on) +static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, + const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -10182,9 +10184,9 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on) int pipe = intel_crtc->pipe; uint32_t cntl = 0; - if (on) { + if (plane_state && plane_state->visible) { cntl = MCURSOR_GAMMA_ENABLE; - switch (intel_crtc->base.cursor->state->crtc_w) { + switch (plane_state->base.crtc_w) { case 64: cntl |= CURSOR_MODE_64_ARGB_AX; break; @@ -10195,17 +10197,17 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on) cntl |= CURSOR_MODE_256_ARGB_AX; break; default: - MISSING_CASE(intel_crtc->base.cursor->state->crtc_w); + MISSING_CASE(plane_state->base.crtc_w); return; } cntl |= pipe << 28; /* Connect to correct pipe */ if (HAS_DDI(dev)) cntl |= CURSOR_PIPE_CSC_ENABLE; - } - if (crtc->cursor->state->rotation == BIT(DRM_ROTATE_180)) - cntl |= CURSOR_ROTATE_180; + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) + cntl |= CURSOR_ROTATE_180; + } if (intel_crtc->cursor_cntl != cntl) { I915_WRITE(CURCNTR(pipe), cntl); @@ -10222,44 +10224,45 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, bool on) /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ static void intel_crtc_update_cursor(struct drm_crtc *crtc, - bool on) + const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; - struct drm_plane_state *cursor_state = crtc->cursor->state; - int x = cursor_state->crtc_x; - int y = cursor_state->crtc_y; - u32 base = 0, pos = 0; + u32 base = intel_crtc->cursor_addr; + u32 pos = 0; - base = intel_crtc->cursor_addr; + if (plane_state) { + int x = plane_state->base.crtc_x; + int y = plane_state->base.crtc_y; - if (x < 0) { - pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; - } - pos |= x << CURSOR_X_SHIFT; + if (x < 0) { + pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; + x = -x; + } + pos |= x << CURSOR_X_SHIFT; - if (y < 0) { - pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; - y = -y; + if (y < 0) { + pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; + y = -y; + } + pos |= y << CURSOR_Y_SHIFT; + + /* ILK+ do this automagically */ + if (HAS_GMCH_DISPLAY(dev) && + plane_state->base.rotation == BIT(DRM_ROTATE_180)) { + base += (plane_state->base.crtc_h * + plane_state->base.crtc_w - 1) * 4; + } } - pos |= y << CURSOR_Y_SHIFT; I915_WRITE(CURPOS(pipe), pos); - /* ILK+ do this automagically */ - if (HAS_GMCH_DISPLAY(dev) && - crtc->cursor->state->rotation == BIT(DRM_ROTATE_180)) { - base += (cursor_state->crtc_h * - cursor_state->crtc_w - 1) * 4; - } - if (IS_845G(dev) || IS_I865G(dev)) - i845_update_cursor(crtc, base, on); + i845_update_cursor(crtc, base, plane_state); else - i9xx_update_cursor(crtc, base, on); + i9xx_update_cursor(crtc, base, plane_state); } static bool cursor_size_ok(struct drm_device *dev, @@ -14259,22 +14262,20 @@ intel_disable_cursor_plane(struct drm_plane *plane, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); intel_crtc->cursor_addr = 0; - intel_crtc_update_cursor(crtc, false); + intel_crtc_update_cursor(crtc, NULL); } static void -intel_commit_cursor_plane(struct drm_plane *plane, - struct intel_plane_state *state) +intel_update_cursor_plane(struct drm_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *state) { - struct drm_crtc *crtc = state->base.crtc; + struct drm_crtc *crtc = crtc_state->base.crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = plane->dev; - struct intel_crtc *intel_crtc; struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb); uint32_t addr; - crtc = crtc ? crtc : plane->crtc; - intel_crtc = to_intel_crtc(crtc); - if (!obj) addr = 0; else if (!INTEL_INFO(dev)->cursor_needs_physical) @@ -14283,8 +14284,7 @@ intel_commit_cursor_plane(struct drm_plane *plane, addr = obj->phys_handle->busaddr; intel_crtc->cursor_addr = addr; - - intel_crtc_update_cursor(crtc, state->visible); + intel_crtc_update_cursor(crtc, state); } static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, @@ -14310,7 +14310,7 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, cursor->plane = pipe; cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe); cursor->check_plane = intel_check_cursor_plane; - cursor->commit_plane = intel_commit_cursor_plane; + cursor->update_plane = intel_update_cursor_plane; cursor->disable_plane = intel_disable_cursor_plane; drm_universal_plane_init(dev, &cursor->base, 0, -- GitLab From a8d201af68506b375b701d0d8dbe8487034256f2 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:11 +0100 Subject: [PATCH 0140/5324] drm/i915: Use plane state for primary plane updates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass in the atomic states to allow for proper updates. This removes uses of intel_crtc->config and direct access to plane->state. This breaks the last bit of kgdboc, but that appears to be dead code. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-7-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_drv.h | 3 - drivers/gpu/drm/i915/intel_display.c | 248 +++++++++++---------------- 2 files changed, 103 insertions(+), 148 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 61b9d910b912..8cf655c6fc03 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -652,9 +652,6 @@ struct drm_i915_display_funcs { struct drm_i915_gem_object *obj, struct drm_i915_gem_request *req, uint32_t flags); - void (*update_primary_plane)(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y); void (*hpd_irq_setup)(struct drm_device *dev); /* clock updates for mode set */ /* cursor updates */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 07715f985da1..738d0dca47a8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2679,36 +2679,23 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit; } -static void i9xx_update_primary_plane(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y) +static void i9xx_update_primary_plane(struct drm_plane *primary, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = primary->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_plane *primary = crtc->primary; - bool visible = to_intel_plane_state(primary->state)->visible; - struct drm_i915_gem_object *obj; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); int plane = intel_crtc->plane; unsigned long linear_offset; + int x = plane_state->src.x1 >> 16; + int y = plane_state->src.y1 >> 16; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); int pixel_size; - if (!visible || !fb) { - I915_WRITE(reg, 0); - if (INTEL_INFO(dev)->gen >= 4) - I915_WRITE(DSPSURF(plane), 0); - else - I915_WRITE(DSPADDR(plane), 0); - POSTING_READ(reg); - return; - } - - obj = intel_fb_obj(fb); - if (WARN_ON(obj == NULL)) - return; - pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -2723,13 +2710,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, * which should always be the user's requested size. */ I915_WRITE(DSPSIZE(plane), - ((intel_crtc->config->pipe_src_h - 1) << 16) | - (intel_crtc->config->pipe_src_w - 1)); + ((crtc_state->pipe_src_h - 1) << 16) | + (crtc_state->pipe_src_w - 1)); I915_WRITE(DSPPOS(plane), 0); } else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) { I915_WRITE(PRIMSIZE(plane), - ((intel_crtc->config->pipe_src_h - 1) << 16) | - (intel_crtc->config->pipe_src_w - 1)); + ((crtc_state->pipe_src_h - 1) << 16) | + (crtc_state->pipe_src_w - 1)); I915_WRITE(PRIMPOS(plane), 0); I915_WRITE(PRIMCNSTALPHA(plane), 0); } @@ -2780,17 +2767,17 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, intel_crtc->dspaddr_offset = linear_offset; } - if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) { + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { dspcntr |= DISPPLANE_ROTATE_180; - x += (intel_crtc->config->pipe_src_w - 1); - y += (intel_crtc->config->pipe_src_h - 1); + x += (crtc_state->pipe_src_w - 1); + y += (crtc_state->pipe_src_h - 1); /* Finding the last pixel of the last line of the display data and adding to linear_offset*/ linear_offset += - (intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] + - (intel_crtc->config->pipe_src_w - 1) * pixel_size; + (crtc_state->pipe_src_h - 1) * fb->pitches[0] + + (crtc_state->pipe_src_w - 1) * pixel_size; } intel_crtc->adjusted_x = x; @@ -2809,37 +2796,40 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, POSTING_READ(reg); } -static void ironlake_update_primary_plane(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y) +static void i9xx_disable_primary_plane(struct drm_plane *primary, + struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_plane *primary = crtc->primary; - bool visible = to_intel_plane_state(primary->state)->visible; - struct drm_i915_gem_object *obj; int plane = intel_crtc->plane; - unsigned long linear_offset; - u32 dspcntr; - i915_reg_t reg = DSPCNTR(plane); - int pixel_size; - if (!visible || !fb) { - I915_WRITE(reg, 0); + I915_WRITE(DSPCNTR(plane), 0); + if (INTEL_INFO(dev_priv)->gen >= 4) I915_WRITE(DSPSURF(plane), 0); - POSTING_READ(reg); - return; - } - - obj = intel_fb_obj(fb); - if (WARN_ON(obj == NULL)) - return; + else + I915_WRITE(DSPADDR(plane), 0); + POSTING_READ(DSPCNTR(plane)); +} - pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); +static void ironlake_update_primary_plane(struct drm_plane *primary, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) +{ + struct drm_device *dev = primary->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + int plane = intel_crtc->plane; + unsigned long linear_offset; + u32 dspcntr; + i915_reg_t reg = DSPCNTR(plane); + int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int x = plane_state->src.x1 >> 16; + int y = plane_state->src.y1 >> 16; dspcntr = DISPPLANE_GAMMA_ENABLE; - dspcntr |= DISPLAY_PLANE_ENABLE; if (IS_HASWELL(dev) || IS_BROADWELL(dev)) @@ -2881,18 +2871,18 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, pixel_size, fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; - if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) { + if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { dspcntr |= DISPPLANE_ROTATE_180; if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { - x += (intel_crtc->config->pipe_src_w - 1); - y += (intel_crtc->config->pipe_src_h - 1); + x += (crtc_state->pipe_src_w - 1); + y += (crtc_state->pipe_src_h - 1); /* Finding the last pixel of the last line of the display data and adding to linear_offset*/ linear_offset += - (intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] + - (intel_crtc->config->pipe_src_w - 1) * pixel_size; + (crtc_state->pipe_src_h - 1) * fb->pitches[0] + + (crtc_state->pipe_src_w - 1) * pixel_size; } } @@ -3083,36 +3073,30 @@ u32 skl_plane_ctl_rotation(unsigned int rotation) return 0; } -static void skylake_update_primary_plane(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y) +static void skylake_update_primary_plane(struct drm_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_plane *plane = crtc->primary; - bool visible = to_intel_plane_state(plane->state)->visible; - struct drm_i915_gem_object *obj; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_framebuffer *fb = plane_state->base.fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); int pipe = intel_crtc->pipe; u32 plane_ctl, stride_div, stride; u32 tile_height, plane_offset, plane_size; - unsigned int rotation; + unsigned int rotation = plane_state->base.rotation; int x_offset, y_offset; u32 surf_addr; - struct intel_crtc_state *crtc_state = intel_crtc->config; - struct intel_plane_state *plane_state; - int src_x = 0, src_y = 0, src_w = 0, src_h = 0; - int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0; - int scaler_id = -1; - - plane_state = to_intel_plane_state(plane->state); - - if (!visible || !fb) { - I915_WRITE(PLANE_CTL(pipe, 0), 0); - I915_WRITE(PLANE_SURF(pipe, 0), 0); - POSTING_READ(PLANE_CTL(pipe, 0)); - return; - } + int scaler_id = plane_state->scaler_id; + int src_x = plane_state->src.x1 >> 16; + int src_y = plane_state->src.y1 >> 16; + int src_w = drm_rect_width(&plane_state->src) >> 16; + int src_h = drm_rect_height(&plane_state->src) >> 16; + int dst_x = plane_state->dst.x1; + int dst_y = plane_state->dst.y1; + int dst_w = drm_rect_width(&plane_state->dst); + int dst_h = drm_rect_height(&plane_state->dst); plane_ctl = PLANE_CTL_ENABLE | PLANE_CTL_PIPE_GAMMA_ENABLE | @@ -3121,41 +3105,26 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, plane_ctl |= skl_plane_ctl_format(fb->pixel_format); plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; - - rotation = plane->state->rotation; plane_ctl |= skl_plane_ctl_rotation(rotation); - obj = intel_fb_obj(fb); stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], fb->pixel_format); surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0); WARN_ON(drm_rect_width(&plane_state->src) == 0); - scaler_id = plane_state->scaler_id; - src_x = plane_state->src.x1 >> 16; - src_y = plane_state->src.y1 >> 16; - src_w = drm_rect_width(&plane_state->src) >> 16; - src_h = drm_rect_height(&plane_state->src) >> 16; - dst_x = plane_state->dst.x1; - dst_y = plane_state->dst.y1; - dst_w = drm_rect_width(&plane_state->dst); - dst_h = drm_rect_height(&plane_state->dst); - - WARN_ON(x != src_x || y != src_y); - if (intel_rotation_90_or_270(rotation)) { /* stride = Surface height in tiles */ tile_height = intel_tile_height(dev, fb->pixel_format, fb->modifier[0], 0); stride = DIV_ROUND_UP(fb->height, tile_height); - x_offset = stride * tile_height - y - src_h; - y_offset = x; + x_offset = stride * tile_height - src_y - src_h; + y_offset = src_x; plane_size = (src_w - 1) << 16 | (src_h - 1); } else { stride = fb->pitches[0] / stride_div; - x_offset = x; - y_offset = y; + x_offset = src_x; + y_offset = src_y; plane_size = (src_h - 1) << 16 | (src_w - 1); } plane_offset = y_offset << 16 | x_offset; @@ -3188,20 +3157,30 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, POSTING_READ(PLANE_SURF(pipe, 0)); } -/* Assume fb object is pinned & idle & fenced and just update base pointers */ -static int -intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) +static void skylake_disable_primary_plane(struct drm_plane *primary, + struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = to_intel_crtc(crtc)->pipe; if (dev_priv->fbc.deactivate) dev_priv->fbc.deactivate(dev_priv); - dev_priv->display.update_primary_plane(crtc, fb, x, y); + I915_WRITE(PLANE_CTL(pipe, 0), 0); + I915_WRITE(PLANE_SURF(pipe, 0), 0); + POSTING_READ(PLANE_SURF(pipe, 0)); +} - return 0; +/* Assume fb object is pinned & idle & fenced and just update base pointers */ +static int +intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, + int x, int y, enum mode_set_atomic state) +{ + /* Support for kgdboc is disabled, this needs a major rework. */ + DRM_ERROR("legacy panic handler not supported any more.\n"); + + return -ENODEV; } static void intel_complete_page_flips(struct drm_device *dev) @@ -3228,8 +3207,10 @@ static void intel_update_primary_planes(struct drm_device *dev) drm_modeset_lock_crtc(crtc, &plane->base); plane_state = to_intel_plane_state(plane->base.state); - if (crtc->state->active && plane_state->base.fb) - plane->commit_plane(&plane->base, plane_state); + if (plane_state->visible) + plane->update_plane(&plane->base, + to_intel_crtc_state(crtc->state), + plane_state); drm_modeset_unlock_crtc(crtc); } @@ -14037,32 +14018,6 @@ intel_check_primary_plane(struct drm_plane *plane, &state->visible); } -static void -intel_commit_primary_plane(struct drm_plane *plane, - struct intel_plane_state *state) -{ - struct drm_crtc *crtc = state->base.crtc; - struct drm_framebuffer *fb = state->base.fb; - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - crtc = crtc ? crtc : plane->crtc; - - dev_priv->display.update_primary_plane(crtc, fb, - state->src.x1 >> 16, - state->src.y1 >> 16); -} - -static void -intel_disable_primary_plane(struct drm_plane *plane, - struct drm_crtc *crtc) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->display.update_primary_plane(crtc, NULL, 0, 0); -} - static void intel_begin_crtc_commit(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { @@ -14147,20 +14102,33 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, primary->plane = pipe; primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe); primary->check_plane = intel_check_primary_plane; - primary->commit_plane = intel_commit_primary_plane; - primary->disable_plane = intel_disable_primary_plane; if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4) primary->plane = !pipe; if (INTEL_INFO(dev)->gen >= 9) { intel_primary_formats = skl_primary_formats; num_formats = ARRAY_SIZE(skl_primary_formats); + + primary->update_plane = skylake_update_primary_plane; + primary->disable_plane = skylake_disable_primary_plane; + } else if (HAS_PCH_SPLIT(dev)) { + intel_primary_formats = i965_primary_formats; + num_formats = ARRAY_SIZE(i965_primary_formats); + + primary->update_plane = ironlake_update_primary_plane; + primary->disable_plane = i9xx_disable_primary_plane; } else if (INTEL_INFO(dev)->gen >= 4) { intel_primary_formats = i965_primary_formats; num_formats = ARRAY_SIZE(i965_primary_formats); + + primary->update_plane = i9xx_update_primary_plane; + primary->disable_plane = i9xx_disable_primary_plane; } else { intel_primary_formats = i8xx_primary_formats; num_formats = ARRAY_SIZE(i8xx_primary_formats); + + primary->update_plane = i9xx_update_primary_plane; + primary->disable_plane = i9xx_disable_primary_plane; } drm_universal_plane_init(dev, &primary->base, 0, @@ -14988,8 +14956,6 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - dev_priv->display.update_primary_plane = - skylake_update_primary_plane; } else if (HAS_DDI(dev)) { dev_priv->display.get_pipe_config = haswell_get_pipe_config; dev_priv->display.get_initial_plane_config = @@ -14998,8 +14964,6 @@ static void intel_init_display(struct drm_device *dev) haswell_crtc_compute_clock; dev_priv->display.crtc_enable = haswell_crtc_enable; dev_priv->display.crtc_disable = haswell_crtc_disable; - dev_priv->display.update_primary_plane = - ironlake_update_primary_plane; } else if (HAS_PCH_SPLIT(dev)) { dev_priv->display.get_pipe_config = ironlake_get_pipe_config; dev_priv->display.get_initial_plane_config = @@ -15008,8 +14972,6 @@ static void intel_init_display(struct drm_device *dev) ironlake_crtc_compute_clock; dev_priv->display.crtc_enable = ironlake_crtc_enable; dev_priv->display.crtc_disable = ironlake_crtc_disable; - dev_priv->display.update_primary_plane = - ironlake_update_primary_plane; } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = @@ -15017,8 +14979,6 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_enable = valleyview_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; - dev_priv->display.update_primary_plane = - i9xx_update_primary_plane; } else { dev_priv->display.get_pipe_config = i9xx_get_pipe_config; dev_priv->display.get_initial_plane_config = @@ -15026,8 +14986,6 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_enable = i9xx_crtc_enable; dev_priv->display.crtc_disable = i9xx_crtc_disable; - dev_priv->display.update_primary_plane = - i9xx_update_primary_plane; } /* Returns the core display clock speed */ -- GitLab From c03242b1317694e50e2c781026bb7bee8dfcc2bb Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 11:54:12 +0100 Subject: [PATCH 0141/5324] drm/i915: Remove commit_plane function pointer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With sprites, cursors and primary planes taking the atomic state this is now unused. It's removed in a separate commit to allow a revert. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452164052-21752-8-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_atomic_plane.c | 4 +--- drivers/gpu/drm/i915/intel_drv.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 969aa410deaa..e0b851a0004a 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -198,9 +198,7 @@ static void intel_plane_atomic_update(struct drm_plane *plane, struct drm_crtc_state *crtc_state = drm_atomic_get_existing_crtc_state(old_state->state, crtc); - if (intel_plane->commit_plane) - intel_plane->commit_plane(plane, intel_state); - else if (intel_state->visible) + if (intel_state->visible) intel_plane->update_plane(plane, to_intel_crtc_state(crtc_state), intel_state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6f3850beccd9..bdfe4035e074 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -692,8 +692,6 @@ struct intel_plane { int (*check_plane)(struct drm_plane *plane, struct intel_crtc_state *crtc_state, struct intel_plane_state *state); - void (*commit_plane)(struct drm_plane *plane, - struct intel_plane_state *state); }; struct intel_watermark_params { -- GitLab From 16fbc291cb87c7defcd13ad715d3e4af0d523e43 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 6 Jan 2016 12:08:36 +0000 Subject: [PATCH 0142/5324] drm/i915/kbl: Enable PW1 and Misc I/O power wells My kbl stopped working because of this. Fixes regression from commit 2f693e28b8df69f67beced5e18bb2b91c2bfcec2 Author: Damien Lespiau Date: Wed Nov 4 19:24:12 2015 +0200 drm/i915: Make turning on/off PW1 and Misc I/O part of the init/fini sequences Cc: Damien Lespiau Cc: Paulo Zanoni Cc: Patrik Jakobsson Cc: Imre Deak Signed-off-by: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1452082116-16770-1-git-send-email-michel.thierry@intel.com Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_runtime_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index ddbdbffe829a..4b44e6862a27 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1851,7 +1851,7 @@ void skl_pw1_misc_io_init(struct drm_i915_private *dev_priv) { struct i915_power_well *well; - if (!IS_SKYLAKE(dev_priv)) + if (!(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))) return; well = lookup_power_well(dev_priv, SKL_DISP_PW_1); @@ -1865,7 +1865,7 @@ void skl_pw1_misc_io_fini(struct drm_i915_private *dev_priv) { struct i915_power_well *well; - if (!IS_SKYLAKE(dev_priv)) + if (!(IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))) return; well = lookup_power_well(dev_priv, SKL_DISP_PW_1); -- GitLab From 5590a5f0af78c73c94de8c63ca580bff31b97c1e Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 5 Jan 2016 10:30:05 -0800 Subject: [PATCH 0143/5324] drm/i915: Cleanup some of the CSB handling I think this patch is a worthwhile cleanup even if it might look only marginally useful. It gets more useful in upcoming patches and for handling of future GEN platforms. The only non-mechanical part of this is the removal of the extra & operation on the ring->next_context_status_buffer. This is safe because right above this, we already did a modulus operation. Signed-off-by: Ben Widawsky Link: http://patchwork.freedesktop.org/patch/msgid/1452018609-10142-2-git-send-email-benjamin.widawsky@intel.com Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +++--- drivers/gpu/drm/i915/intel_lrc.c | 15 +++++++++------ drivers/gpu/drm/i915/intel_lrc.h | 18 ++++++++++++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0fc38bb7276c..3b05bd189eab 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2092,13 +2092,13 @@ static int i915_execlists(struct seq_file *m, void *data) seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer); read_pointer = ring->next_context_status_buffer; - write_pointer = status_pointer & 0x07; + write_pointer = GEN8_CSB_WRITE_PTR(status_pointer); if (read_pointer > write_pointer) - write_pointer += 6; + write_pointer += GEN8_CSB_ENTRIES; seq_printf(m, "\tRead pointer: 0x%08X, write pointer 0x%08X\n", read_pointer, write_pointer); - for (i = 0; i < 6; i++) { + for (i = 0; i < GEN8_CSB_ENTRIES; i++) { status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, i)); ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, i)); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8096c6a79424..7fb2035b71eb 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -516,7 +516,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); read_pointer = ring->next_context_status_buffer; - write_pointer = status_pointer & GEN8_CSB_PTR_MASK; + write_pointer = GEN8_CSB_WRITE_PTR(status_pointer); if (read_pointer > write_pointer) write_pointer += GEN8_CSB_ENTRIES; @@ -559,10 +559,11 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) WARN(submit_contexts > 2, "More than two context complete events?\n"); ring->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; + /* Update the read pointer to the old write pointer. Manual ringbuffer + * management ftw */ I915_WRITE(RING_CONTEXT_STATUS_PTR(ring), - _MASKED_FIELD(GEN8_CSB_PTR_MASK << 8, - ((u32)ring->next_context_status_buffer & - GEN8_CSB_PTR_MASK) << 8)); + _MASKED_FIELD(GEN8_CSB_READ_PTR_MASK, + ring->next_context_status_buffer << 8)); } static int execlists_context_queue(struct drm_i915_gem_request *request) @@ -1506,9 +1507,11 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) * | Suspend-to-idle (freeze) | Suspend-to-RAM (mem) | * BDW | CSB regs not reset | CSB regs reset | * CHT | CSB regs not reset | CSB regs not reset | + * SKL | ? | ? | + * BXT | ? | ? | */ - next_context_status_buffer_hw = (I915_READ(RING_CONTEXT_STATUS_PTR(ring)) - & GEN8_CSB_PTR_MASK); + next_context_status_buffer_hw = + GEN8_CSB_WRITE_PTR(I915_READ(RING_CONTEXT_STATUS_PTR(ring))); /* * When the CSB registers are reset (also after power-up / gpu reset), diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index ae90f86a2849..de41ad6cd63d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -25,8 +25,6 @@ #define _INTEL_LRC_H_ #define GEN8_LR_CONTEXT_ALIGN 4096 -#define GEN8_CSB_ENTRIES 6 -#define GEN8_CSB_PTR_MASK 0x07 /* Execlists regs */ #define RING_ELSP(ring) _MMIO((ring)->mmio_base + 0x230) @@ -40,6 +38,22 @@ #define RING_CONTEXT_STATUS_BUF_HI(ring, i) _MMIO((ring)->mmio_base + 0x370 + (i) * 8 + 4) #define RING_CONTEXT_STATUS_PTR(ring) _MMIO((ring)->mmio_base + 0x3a0) +/* The docs specify that the write pointer wraps around after 5h, "After status + * is written out to the last available status QW at offset 5h, this pointer + * wraps to 0." + * + * Therefore, one must infer than even though there are 3 bits available, 6 and + * 7 appear to be * reserved. + */ +#define GEN8_CSB_ENTRIES 6 +#define GEN8_CSB_PTR_MASK 0x7 +#define GEN8_CSB_READ_PTR_MASK (GEN8_CSB_PTR_MASK << 8) +#define GEN8_CSB_WRITE_PTR_MASK (GEN8_CSB_PTR_MASK << 0) +#define GEN8_CSB_WRITE_PTR(csb_status) \ + (((csb_status) & GEN8_CSB_WRITE_PTR_MASK) >> 0) +#define GEN8_CSB_READ_PTR(csb_status) \ + (((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8) + /* Logical Rings */ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request); int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request); -- GitLab From f764a8b146547b643d40b90a304ff99389edf352 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 5 Jan 2016 10:30:06 -0800 Subject: [PATCH 0144/5324] drm/i915: Change WARN to ERROR in CSB count There is no point in emitting a WARN since the backtrace will always be the same. Errors have actually become easier to spot given the large number of WARNs which exist today in modesetting paths. Signed-off-by: Ben Widawsky Reviewed-by: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1452018609-10142-3-git-send-email-benjamin.widawsky@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7fb2035b71eb..14affaa2a0ba 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -556,7 +556,9 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) spin_unlock(&ring->execlist_lock); - WARN(submit_contexts > 2, "More than two context complete events?\n"); + if (unlikely(submit_contexts > 2)) + DRM_ERROR("More than two context complete events?\n"); + ring->next_context_status_buffer = write_pointer % GEN8_CSB_ENTRIES; /* Update the read pointer to the old write pointer. Manual ringbuffer -- GitLab From 91a4103206e3386aa3ea53b25d23f52913353e3a Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 5 Jan 2016 10:30:07 -0800 Subject: [PATCH 0145/5324] drm/i915: Extract CSB status read This is a useful thing to have around as a function because the mechanism may change in the future. There is a net increase in LOC here, and it will continue to be the case on GEN8 and GEN9 - but future GENs may have an alternate mechanism for doing this. Signed-off-by: Ben Widawsky Reviewed-by: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1452018609-10142-4-git-send-email-benjamin.widawsky@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 14affaa2a0ba..23839ff04e27 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -496,6 +496,19 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, return false; } +static void get_context_status(struct intel_engine_cs *ring, + u8 read_pointer, + u32 *status, u32 *context_id) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + + if (WARN_ON(read_pointer >= GEN8_CSB_ENTRIES)) + return; + + *status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer)); + *context_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, read_pointer)); +} + /** * intel_lrc_irq_handler() - handle Context Switch interrupts * @ring: Engine Command Streamer to handle. @@ -523,9 +536,9 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) spin_lock(&ring->execlist_lock); while (read_pointer < write_pointer) { - read_pointer++; - status = I915_READ(RING_CONTEXT_STATUS_BUF_LO(ring, read_pointer % GEN8_CSB_ENTRIES)); - status_id = I915_READ(RING_CONTEXT_STATUS_BUF_HI(ring, read_pointer % GEN8_CSB_ENTRIES)); + + get_context_status(ring, ++read_pointer % GEN8_CSB_ENTRIES, + &status, &status_id); if (status & GEN8_CTX_STATUS_IDLE_ACTIVE) continue; -- GitLab From 07c519134417d92c2e1a536e2b66d4ffff4b3be0 Mon Sep 17 00:00:00 2001 From: Lyude Date: Thu, 7 Jan 2016 10:43:28 -0500 Subject: [PATCH 0146/5324] drm/i915: intel_hpd_init(): Fix suspend/resume reprobing This fixes reprobing of display connectors on resume. After some talking with danvet on IRC, I learned that calling drm_helper_hpd_irq_event() does actually trigger a full reprobe of each connector's status. It turns out this is the actual reason reprobing on resume hasn't been working (this was observed on a T440s): - We call hpd_init() - We check each connector for a couple of things before marking connector->polled with DRM_CONNECTOR_POLL_HPD, one of which is an active encoder. Of course, a disconnected port won't have an active encoder, so we don't add the flag to any of the connectors. - We call drm_helper_hpd_irq_event() - drm_helper_irq_event() checks each connector for the DRM_CONNECTOR_POLL_HPD flag. The only one that has it is eDP-1, so we skip reprobing each connector except that one. In addition, we also now avoid setting connector->polled to DRM_CONNECTOR_POLL_HPD for MST connectors, since their reprobing is handled by the mst helpers. This is probably what was originally intended to happen here. Changes since V1: * Use the explanation of the issue as the commit message instead * Change the title of the commit, since this does more then just stop a check for an encoder now * Add "Fixes" line for the patch that introduced this regression * Don't enable DRM_CONNECTOR_POLL_HPD for mst connectors Changes since V2: * Put patch changelog above Signed-off-by * Follow Daniel Vetter's suggestion for making the code here a bit more legible Fixes: 0e32b39ceed6 ("drm/i915: add DP 1.2 MST support (v0.7)") Cc: stable@vger.kernel.org Signed-off-by: Lyude Link: http://patchwork.freedesktop.org/patch/msgid/1452181408-14777-1-git-send-email-cpaul@redhat.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_hotplug.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index a294a3cbaea1..bee673005d48 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -468,9 +468,14 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) list_for_each_entry(connector, &mode_config->connector_list, head) { struct intel_connector *intel_connector = to_intel_connector(connector); connector->polled = intel_connector->polled; - if (connector->encoder && !connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) - connector->polled = DRM_CONNECTOR_POLL_HPD; + + /* MST has a dynamic intel_connector->encoder and it's reprobing + * is all handled by the MST helpers. */ if (intel_connector->mst_port) + continue; + + if (!connector->polled && I915_HAS_HOTPLUG(dev) && + intel_connector->encoder->hpd_pin > HPD_NONE) connector->polled = DRM_CONNECTOR_POLL_HPD; } -- GitLab From 2e78416e763261fa8187429b7ea053d369fa7f79 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 5 Jan 2016 11:11:27 -0800 Subject: [PATCH 0147/5324] drm/i915: Update Skylake DDI translation table for HDMI. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When debuging an intermittent corrupted screen I suspected on DDI translation table and checked we are out of date with the spec. I'm not sure this will fix my bug yet, but it is always good to follow the spec. v2: Ville caught a switched i-boost value. Thanks! Cc: Ville Syrjälä Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452021087-21673-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5c0801895aa7..7961fcc2adda 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -226,26 +226,26 @@ static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { { 0x00000018, 0x000000A1, 0x0 }, { 0x00000018, 0x00000098, 0x0 }, { 0x00004013, 0x00000088, 0x0 }, - { 0x00006012, 0x00000087, 0x0 }, + { 0x80006012, 0x000000CD, 0x1 }, { 0x00000018, 0x000000DF, 0x0 }, - { 0x00003015, 0x00000087, 0x0 }, /* Default */ - { 0x00003015, 0x000000C7, 0x0 }, - { 0x00000018, 0x000000C7, 0x0 }, + { 0x80003015, 0x000000CD, 0x1 }, /* Default */ + { 0x80003015, 0x000000C0, 0x1 }, + { 0x80000018, 0x000000C0, 0x1 }, }; /* Skylake Y */ static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = { { 0x00000018, 0x000000A1, 0x0 }, { 0x00005012, 0x000000DF, 0x0 }, - { 0x00007011, 0x00000084, 0x0 }, + { 0x80007011, 0x000000CB, 0x3 }, { 0x00000018, 0x000000A4, 0x0 }, { 0x00000018, 0x0000009D, 0x0 }, { 0x00004013, 0x00000080, 0x0 }, - { 0x00006013, 0x000000C7, 0x0 }, + { 0x80006013, 0x000000C0, 0x3 }, { 0x00000018, 0x0000008A, 0x0 }, - { 0x00003015, 0x000000C7, 0x0 }, /* Default */ - { 0x80003015, 0x000000C7, 0x7 }, /* Uses I_boost level 0x7 */ - { 0x00000018, 0x000000C7, 0x0 }, + { 0x80003015, 0x000000C0, 0x3 }, /* Default */ + { 0x80003015, 0x000000C0, 0x3 }, + { 0x80000018, 0x000000C0, 0x3 }, }; struct bxt_ddi_buf_trans { -- GitLab From 63ebce1fe883c26a1838c81795adc6134b5a386b Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 5 Jan 2016 07:58:31 -0800 Subject: [PATCH 0148/5324] drm/i915: Update Skylake DDI translation table for DP. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reviewing DDI translation table I noticed few changes we haven't incorporated yet and it is always good to follow latest spec. Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452009511-15064-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 7961fcc2adda..f271f7c0e9ac 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -145,7 +145,7 @@ static const struct ddi_buf_trans skl_ddi_translations_dp[] = { static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = { { 0x0000201B, 0x000000A2, 0x0 }, { 0x00005012, 0x00000088, 0x0 }, - { 0x00007011, 0x00000087, 0x0 }, + { 0x80007011, 0x000000CD, 0x0 }, { 0x80009010, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ { 0x0000201B, 0x0000009D, 0x0 }, { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ @@ -158,7 +158,7 @@ static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = { static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = { { 0x00000018, 0x000000A2, 0x0 }, { 0x00005012, 0x00000088, 0x0 }, - { 0x00007011, 0x00000087, 0x0 }, + { 0x80007011, 0x000000CD, 0x0 }, { 0x80009010, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ { 0x00000018, 0x0000009D, 0x0 }, { 0x80005012, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ -- GitLab From d7097cffdbc06e7d1c71bfc53151160237241f48 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 5 Jan 2016 11:18:55 -0800 Subject: [PATCH 0149/5324] drm/i915: Cleaning up DDI translation tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changes. That state the obvious and just duplicate the place we need to change whenever the table is updated. So let's clean it. Cc: Ville Syrjälä Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452021535-22641-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f271f7c0e9ac..612400fab559 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -133,12 +133,12 @@ static const struct ddi_buf_trans skl_ddi_translations_dp[] = { { 0x00002016, 0x000000A0, 0x0 }, { 0x00005012, 0x0000009B, 0x0 }, { 0x00007011, 0x00000088, 0x0 }, - { 0x80009010, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80009010, 0x000000C0, 0x1 }, { 0x00002016, 0x0000009B, 0x0 }, { 0x00005012, 0x00000088, 0x0 }, - { 0x80007011, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80007011, 0x000000C0, 0x1 }, { 0x00002016, 0x000000DF, 0x0 }, - { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80005012, 0x000000C0, 0x1 }, }; /* Skylake U */ @@ -146,12 +146,12 @@ static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = { { 0x0000201B, 0x000000A2, 0x0 }, { 0x00005012, 0x00000088, 0x0 }, { 0x80007011, 0x000000CD, 0x0 }, - { 0x80009010, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80009010, 0x000000C0, 0x1 }, { 0x0000201B, 0x0000009D, 0x0 }, - { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ - { 0x80007011, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80005012, 0x000000C0, 0x1 }, + { 0x80007011, 0x000000C0, 0x1 }, { 0x00002016, 0x00000088, 0x0 }, - { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */ + { 0x80005012, 0x000000C0, 0x1 }, }; /* Skylake Y */ @@ -159,12 +159,12 @@ static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = { { 0x00000018, 0x000000A2, 0x0 }, { 0x00005012, 0x00000088, 0x0 }, { 0x80007011, 0x000000CD, 0x0 }, - { 0x80009010, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ + { 0x80009010, 0x000000C0, 0x3 }, { 0x00000018, 0x0000009D, 0x0 }, - { 0x80005012, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ - { 0x80007011, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ + { 0x80005012, 0x000000C0, 0x3 }, + { 0x80007011, 0x000000C0, 0x3 }, { 0x00000018, 0x00000088, 0x0 }, - { 0x80005012, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */ + { 0x80005012, 0x000000C0, 0x3 }, }; /* -- GitLab From 61642ff03523995918c452ef41adf0795d54d909 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 1 Dec 2015 17:56:12 +0200 Subject: [PATCH 0150/5324] drm/i915: Inspect subunit states on hangcheck If head seems stuck and engine in question is rcs, inspect subunit state transitions from undone to done, before deciding that this really is a hang instead of limited progress. Only account the transitions of subunits from undone to done once, to prevent unstable subunit states to keep us falsely active. As this adds one extra steps to hangcheck heuristics, before hang is declared, it adds 1500ms to to detect hang for render ring to a total of 7500ms. We could sample the subunit states on first head stuck condition but decide not to do so only in order to mimic old behaviour. This way the check order of promotion from seqno > atchd > instdone is consistently done. v2: Deal with unstable done states (Arun) Clear instdone progress on head and seqno movement (Chris) Report raw and accumulated instdone's in in debugfs (Chris) Return HANGCHECK_ACTIVE on undone->done References: https://bugs.freedesktop.org/show_bug.cgi?id=93029 Cc: Chris Wilson Cc: Dave Gordon Cc: Daniel Vetter Cc: Arun Siluvery Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1448985372-19535-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 20 +++++++- drivers/gpu/drm/i915/i915_irq.c | 62 +++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3b05bd189eab..e3377abc0d4d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1331,7 +1331,8 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) struct intel_engine_cs *ring; u64 acthd[I915_NUM_RINGS]; u32 seqno[I915_NUM_RINGS]; - int i; + u32 instdone[I915_NUM_INSTDONE_REG]; + int i, j; if (!i915.enable_hangcheck) { seq_printf(m, "Hangcheck disabled\n"); @@ -1345,6 +1346,8 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) acthd[i] = intel_ring_get_active_head(ring); } + i915_get_extra_instdone(dev, instdone); + intel_runtime_pm_put(dev_priv); if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) { @@ -1365,6 +1368,21 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) (long long)ring->hangcheck.max_acthd); seq_printf(m, "\tscore = %d\n", ring->hangcheck.score); seq_printf(m, "\taction = %d\n", ring->hangcheck.action); + + if (ring->id == RCS) { + seq_puts(m, "\tinstdone read ="); + + for (j = 0; j < I915_NUM_INSTDONE_REG; j++) + seq_printf(m, " 0x%08x", instdone[j]); + + seq_puts(m, "\n\tinstdone accu ="); + + for (j = 0; j < I915_NUM_INSTDONE_REG; j++) + seq_printf(m, " 0x%08x", + ring->hangcheck.instdone[j]); + + seq_puts(m, "\n"); + } } return 0; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fa8afa7860ae..b775decf9d27 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2949,14 +2949,44 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) ring->hangcheck.deadlock = 0; } -static enum intel_ring_hangcheck_action -ring_stuck(struct intel_engine_cs *ring, u64 acthd) +static bool subunits_stuck(struct intel_engine_cs *ring) { - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 tmp; + u32 instdone[I915_NUM_INSTDONE_REG]; + bool stuck; + int i; + + if (ring->id != RCS) + return true; + + i915_get_extra_instdone(ring->dev, instdone); + /* There might be unstable subunit states even when + * actual head is not moving. Filter out the unstable ones by + * accumulating the undone -> done transitions and only + * consider those as progress. + */ + stuck = true; + for (i = 0; i < I915_NUM_INSTDONE_REG; i++) { + const u32 tmp = instdone[i] | ring->hangcheck.instdone[i]; + + if (tmp != ring->hangcheck.instdone[i]) + stuck = false; + + ring->hangcheck.instdone[i] |= tmp; + } + + return stuck; +} + +static enum intel_ring_hangcheck_action +head_stuck(struct intel_engine_cs *ring, u64 acthd) +{ if (acthd != ring->hangcheck.acthd) { + + /* Clear subunit states on head movement */ + memset(ring->hangcheck.instdone, 0, + sizeof(ring->hangcheck.instdone)); + if (acthd > ring->hangcheck.max_acthd) { ring->hangcheck.max_acthd = acthd; return HANGCHECK_ACTIVE; @@ -2965,6 +2995,24 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd) return HANGCHECK_ACTIVE_LOOP; } + if (!subunits_stuck(ring)) + return HANGCHECK_ACTIVE; + + return HANGCHECK_HUNG; +} + +static enum intel_ring_hangcheck_action +ring_stuck(struct intel_engine_cs *ring, u64 acthd) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_ring_hangcheck_action ha; + u32 tmp; + + ha = head_stuck(ring, acthd); + if (ha != HANGCHECK_HUNG) + return ha; + if (IS_GEN2(dev)) return HANGCHECK_HUNG; @@ -3106,7 +3154,11 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (ring->hangcheck.score > 0) ring->hangcheck.score--; + /* Clear head and subunit states on seqno movement */ ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0; + + memset(ring->hangcheck.instdone, 0, + sizeof(ring->hangcheck.instdone)); } ring->hangcheck.seqno = seqno; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 49574ffe54bc..7349d9258191 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -93,6 +93,7 @@ struct intel_ring_hangcheck { int score; enum intel_ring_hangcheck_action action; int deadlock; + u32 instdone[I915_NUM_INSTDONE_REG]; }; struct intel_ringbuffer { -- GitLab From 8a47eb198d6e59e5d2509324287d0d913b2d5af1 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 15 Dec 2015 19:24:47 +0200 Subject: [PATCH 0151/5324] drm/i915: Consolidate unclaimed mmio detection Access the unclaimed reg detection register through one helper which also does cleanup. Note that we now access the register only if the platform has the actual non claimed access bit. This prevents reading the register with gens that doesn't have the register or the unclaimed bit, when debug_mmio > 0. Note that we post after clearing the bit. This makes sure that the next unclaimed write access would get detected also if it happened right after clearing, and not fold into the previous detection. v2: s/unclaimed_reg_access/check_for_unclaimed_mmio (Chris) debug log on unclaimed detection on uncore init (Joonas) v3: remove posting read (Ville) Cc: Joonas Lahtinen Cc: Chris Wilson Cc: Paulo Zanoni Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450200287-24080-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 35 +++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 277e60ae0e47..358cb9cb219e 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -327,13 +327,31 @@ static void intel_uncore_ellc_detect(struct drm_device *dev) } } +static bool +check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) +{ + u32 dbg; + + if (!HAS_FPGA_DBG_UNCLAIMED(dev_priv)) + return false; + + dbg = __raw_i915_read32(dev_priv, FPGA_DBG); + if (likely(!(dbg & FPGA_DBG_RM_NOCLAIM))) + return false; + + __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + + return true; +} + static void __intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) { struct drm_i915_private *dev_priv = dev->dev_private; - if (HAS_FPGA_DBG_UNCLAIMED(dev)) - __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); + /* clear out unclaimed reg detection bit */ + if (check_for_unclaimed_mmio(dev_priv)) + DRM_DEBUG("unclaimed mmio detected on uncore init, clearing\n"); /* clear out old GT FIFO errors */ if (IS_GEN6(dev) || IS_GEN7(dev)) @@ -594,10 +612,9 @@ hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, if (!i915.mmio_debug) return; - if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { + if (check_for_unclaimed_mmio(dev_priv)) { WARN(1, "Unclaimed register detected %s %s register 0x%x\n", when, op, i915_mmio_reg_offset(reg)); - __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); i915.mmio_debug--; /* Only report the first N failures */ } } @@ -610,11 +627,10 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) if (i915.mmio_debug || !mmio_debug_once) return; - if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { + if (check_for_unclaimed_mmio(dev_priv)) { DRM_DEBUG("Unclaimed register detected, " "enabling oneshot unclaimed register reporting. " "Please use i915.mmio_debug=N for more information.\n"); - __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); i915.mmio_debug = mmio_debug_once--; } } @@ -1582,11 +1598,6 @@ bool intel_has_gpu_reset(struct drm_device *dev) void intel_uncore_check_errors(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; - - if (HAS_FPGA_DBG_UNCLAIMED(dev) && - (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) { + if (check_for_unclaimed_mmio(to_i915(dev))) DRM_ERROR("Unclaimed register before interrupt\n"); - __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); - } } -- GitLab From fc97618bf373b496858eca463e5154085835ae41 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 15 Dec 2015 16:25:07 +0200 Subject: [PATCH 0152/5324] drm/i915: Introduce intel_uncore_unclaimed_mmio Currently interrupt code is the only place checking for the unclaimed register access prior to actual register macros using the same functionality. Rename the function and make it return bool so that the possible error message context is clear in the caller side. The motivation is to allow usage of unclaimed detection on arbitrary places. v2: rebase, s/access/mmio, s/dev/dev_priv Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450189512-30360-2-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_irq.c | 3 ++- drivers/gpu/drm/i915/intel_uncore.c | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8cf655c6fc03..aa32e8872a95 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2717,7 +2717,7 @@ extern void intel_uncore_sanitize(struct drm_device *dev); extern void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake); extern void intel_uncore_init(struct drm_device *dev); -extern void intel_uncore_check_errors(struct drm_device *dev); +extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b775decf9d27..e7e44a972905 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2190,7 +2190,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) /* We get interrupts on unclaimed registers, so check for this before we * do any I915_{READ,WRITE}. */ - intel_uncore_check_errors(dev); + if (intel_uncore_unclaimed_mmio(dev_priv)) + DRM_ERROR("Unclaimed register before interrupt\n"); /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 358cb9cb219e..7ab5916f90dd 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1596,8 +1596,7 @@ bool intel_has_gpu_reset(struct drm_device *dev) return intel_get_gpu_reset(dev) != NULL; } -void intel_uncore_check_errors(struct drm_device *dev) +bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv) { - if (check_for_unclaimed_mmio(to_i915(dev))) - DRM_ERROR("Unclaimed register before interrupt\n"); + return check_for_unclaimed_mmio(dev_priv); } -- GitLab From 55ec45c2ced1a4b1e7cd2e7e306101f328958760 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 15 Dec 2015 16:25:08 +0200 Subject: [PATCH 0153/5324] drm/i915: Detect and clear unclaimed access on resume If something, the usual suspect being bios, access hw behind our back, don't let it slide into situation where normal register access will detect this and spit out a warn on into dmesg. On some bdw bioses this happens during igt/bat run always and as there is not much we can do about it, its better just to detect and flush this explicitly on resume and only print a debug message. v2: use DRM_DEBUG_DRIVER (Chris) v3: s/access/mmio, s/prior/prior to, s/dev/dev_priv Testcase: igt/pm_rpm/basic-rte Cc: Chris Wilson Cc: Paulo Zanoni Cc: Daniel Vetter Reviewed-by: Chris Wilson [Mika: fixed merge conflict] Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450189512-30360-3-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3ac616d7363b..288fec7691dc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1501,6 +1501,10 @@ static int intel_runtime_suspend(struct device *device) enable_rpm_wakeref_asserts(dev_priv); WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); + + if (intel_uncore_unclaimed_mmio(dev_priv)) + DRM_ERROR("Unclaimed access detected prior to suspending\n"); + dev_priv->pm.suspended = true; /* @@ -1549,6 +1553,8 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv->pm.suspended = false; + if (intel_uncore_unclaimed_mmio(dev_priv)) + DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n"); intel_guc_resume(dev); -- GitLab From 7571494004d88249bcee2a20fa74cb50753676fe Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 16 Dec 2015 09:26:48 +0200 Subject: [PATCH 0154/5324] drm/i915: Do one shot unclaimed mmio detection less frequently We have done unclaimed register access check in normal (mmio_debug=0) mode once per write. This adds probability of finding the exact sequence where we did the bad access, but also adds burden to each write. As we have mmio_debug available for more fine grained analysis, give up accuracy of detecting correct spot at the first occurrence by doing the one shot detection and arming of mmio_debug in hangcheck and in modeset. This removes the write path performance burden. v2: Remove gratuitous DRM_DEBUG and return value, comments (Chris) Cc: Chris Wilson Cc: Paulo Zanoni Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450250808-14864-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_irq.c | 11 +++++---- drivers/gpu/drm/i915/intel_display.c | 13 ++++++++++ drivers/gpu/drm/i915/intel_uncore.c | 37 ++++++++++++++-------------- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aa32e8872a95..6ef03eea3518 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -718,6 +718,8 @@ struct intel_uncore { i915_reg_t reg_post; u32 val_reset; } fw_domain[FW_DOMAIN_ID_COUNT]; + + int unclaimed_mmio_check; }; /* Iterate over initialised fw domains */ @@ -2718,6 +2720,7 @@ extern void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake); extern void intel_uncore_init(struct drm_device *dev); extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv); +extern void intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e7e44a972905..f04d799153ca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2188,11 +2188,6 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - /* We get interrupts on unclaimed registers, so check for this before we - * do any I915_{READ,WRITE}. */ - if (intel_uncore_unclaimed_mmio(dev_priv)) - DRM_ERROR("Unclaimed register before interrupt\n"); - /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); @@ -3081,6 +3076,12 @@ static void i915_hangcheck_elapsed(struct work_struct *work) */ DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); + /* As enabling the GPU requires fairly extensive mmio access, + * periodically arm the mmio checker to see if we are triggering + * any invalid access. + */ + intel_uncore_arm_unclaimed_mmio_detection(dev_priv); + for_each_ring(ring, dev_priv, i) { u64 acthd; u32 seqno; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 738d0dca47a8..3edf22ad7673 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13684,6 +13684,19 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_state_free(state); + /* As one of the primary mmio accessors, KMS has a high likelihood + * of triggering bugs in unclaimed access. After we finish + * modesetting, see if an error has been flagged, and if so + * enable debugging for the next modeset - and hope we catch + * the culprit. + * + * XXX note that we assume display power is on at this point. + * This might hold true now but we need to add pm helper to check + * unclaimed only when the hardware is on, as atomic commits + * can happen also when the device is completely off. + */ + intel_uncore_arm_unclaimed_mmio_detection(dev_priv); + return 0; } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 7ab5916f90dd..c7af339a6366 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -619,22 +619,6 @@ hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, } } -static void -hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) -{ - static bool mmio_debug_once = true; - - if (i915.mmio_debug || !mmio_debug_once) - return; - - if (check_for_unclaimed_mmio(dev_priv)) { - DRM_DEBUG("Unclaimed register detected, " - "enabling oneshot unclaimed register reporting. " - "Please use i915.mmio_debug=N for more information.\n"); - i915.mmio_debug = mmio_debug_once--; - } -} - #define GEN2_READ_HEADER(x) \ u##x val = 0; \ assert_rpm_wakelock_held(dev_priv); @@ -914,7 +898,6 @@ hsw_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool t gen6_gt_check_fifodbg(dev_priv); \ } \ hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ - hsw_unclaimed_reg_detect(dev_priv); \ GEN6_WRITE_FOOTER; \ } @@ -949,7 +932,6 @@ gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool __force_wake_get(dev_priv, FORCEWAKE_RENDER); \ __raw_i915_write##x(dev_priv, reg, val); \ hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ - hsw_unclaimed_reg_detect(dev_priv); \ GEN6_WRITE_FOOTER; \ } @@ -1019,7 +1001,6 @@ gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \ __force_wake_get(dev_priv, fw_engine); \ __raw_i915_write##x(dev_priv, reg, val); \ hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ - hsw_unclaimed_reg_detect(dev_priv); \ GEN6_WRITE_FOOTER; \ } @@ -1239,6 +1220,8 @@ void intel_uncore_init(struct drm_device *dev) intel_uncore_fw_domains_init(dev); __intel_uncore_early_sanitize(dev, false); + dev_priv->uncore.unclaimed_mmio_check = 1; + switch (INTEL_INFO(dev)->gen) { default: case 9: @@ -1600,3 +1583,19 @@ bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv) { return check_for_unclaimed_mmio(dev_priv); } + +void +intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) +{ + if (unlikely(i915.mmio_debug || + dev_priv->uncore.unclaimed_mmio_check <= 0)) + return; + + if (unlikely(intel_uncore_unclaimed_mmio(dev_priv))) { + DRM_DEBUG("Unclaimed register detected, " + "enabling oneshot unclaimed register reporting. " + "Please use i915.mmio_debug=N for more information.\n"); + i915.mmio_debug++; + dev_priv->uncore.unclaimed_mmio_check--; + } +} -- GitLab From 4bd0a25d9be2963a15e16126022214e88580103f Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 15 Dec 2015 16:25:10 +0200 Subject: [PATCH 0155/5324] drm/i915: Streamline unclaimed reg debug trace Remove char* assignments and add branching hint and also constify the parameters. This results in a 35 bytes shorter fast path, so author boldly assumes it helps without doing in-depth assembly analysis. v2: use WARN's branching (Chris), commit name (Joonas) Cc: Joonas Lahtinen Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450189512-30360-5-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c7af339a6366..bd0933cefe5d 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -604,19 +604,19 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) static void hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, - i915_reg_t reg, bool read, bool before) + const i915_reg_t reg, + const bool read, + const bool before) { - const char *op = read ? "reading" : "writing to"; - const char *when = before ? "before" : "after"; - - if (!i915.mmio_debug) + if (likely(!i915.mmio_debug)) return; - if (check_for_unclaimed_mmio(dev_priv)) { - WARN(1, "Unclaimed register detected %s %s register 0x%x\n", - when, op, i915_mmio_reg_offset(reg)); + if (WARN(check_for_unclaimed_mmio(dev_priv), + "Unclaimed register detected %s %s register 0x%x\n", + before ? "before" : "after", + read ? "reading" : "writing to", + i915_mmio_reg_offset(reg))) i915.mmio_debug--; /* Only report the first N failures */ - } } #define GEN2_READ_HEADER(x) \ -- GitLab From 8ac3e1bb76cc2e1585be3a5fa7551480e69487c8 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 15 Dec 2015 19:45:42 +0200 Subject: [PATCH 0156/5324] drm/i915: Add non claimed mmio checking for vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Imre mentioned that chv might also have capability to track unclaimed mmio accesses. Ville added that both chv and vlv has this capability and he had already made this way back [1]. Mimic what Ville's patch does but adapt on top of less frequent mmio accesses by omitting checking always on reg writes. This patch is untested as of now. v2: overflow handling and posting omitted (Ville) References: [1] http://lists.freedesktop.org/archives/intel-gfx/2013-May/027599.html Cc: Imre Deak Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1450201542-22918-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 +++++ drivers/gpu/drm/i915/intel_uncore.c | 31 +++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7510d508e373..556a458d669e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1711,6 +1711,11 @@ enum skl_disp_power_wells { #define FPGA_DBG _MMIO(0x42300) #define FPGA_DBG_RM_NOCLAIM (1<<31) +#define CLAIM_ER _MMIO(VLV_DISPLAY_BASE + 0x2028) +#define CLAIM_ER_CLR (1 << 31) +#define CLAIM_ER_OVERFLOW (1 << 16) +#define CLAIM_ER_CTR_MASK 0xffff + #define DERRMR _MMIO(0x44050) /* Note that HBLANK events are reserved on bdw+ */ #define DERRMR_PIPEA_SCANLINE (1<<0) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index bd0933cefe5d..d0973e08e7eb 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -328,13 +328,10 @@ static void intel_uncore_ellc_detect(struct drm_device *dev) } static bool -check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) +fpga_check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) { u32 dbg; - if (!HAS_FPGA_DBG_UNCLAIMED(dev_priv)) - return false; - dbg = __raw_i915_read32(dev_priv, FPGA_DBG); if (likely(!(dbg & FPGA_DBG_RM_NOCLAIM))) return false; @@ -344,6 +341,32 @@ check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) return true; } +static bool +vlv_check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) +{ + u32 cer; + + cer = __raw_i915_read32(dev_priv, CLAIM_ER); + if (likely(!(cer & (CLAIM_ER_OVERFLOW | CLAIM_ER_CTR_MASK)))) + return false; + + __raw_i915_write32(dev_priv, CLAIM_ER, CLAIM_ER_CLR); + + return true; +} + +static bool +check_for_unclaimed_mmio(struct drm_i915_private *dev_priv) +{ + if (HAS_FPGA_DBG_UNCLAIMED(dev_priv)) + return fpga_check_for_unclaimed_mmio(dev_priv); + + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + return vlv_check_for_unclaimed_mmio(dev_priv); + + return false; +} + static void __intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) { -- GitLab From d7d85d85c8b60e74df5129f147de29bc21228421 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Jan 2016 12:45:39 +0200 Subject: [PATCH 0157/5324] drm/i915/dsi: abstract get pclk platform differences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hide away the platform differences in intel_dsi_get_pckl() within intel_dsi_pll.c. No functional changes. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452249940-2605-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 9 ++------- drivers/gpu/drm/i915/intel_dsi.h | 3 +-- drivers/gpu/drm/i915/intel_dsi_pll.c | 12 ++++++++++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 4ab168dd36bf..328cd58cb5fe 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -702,7 +702,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, static void intel_dsi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - u32 pclk = 0; + u32 pclk; DRM_DEBUG_KMS("\n"); pipe_config->has_dsi_encoder = true; @@ -713,12 +713,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, */ pipe_config->dpll_hw_state.dpll_md = 0; - if (IS_BROXTON(encoder->base.dev)) - pclk = bxt_get_dsi_pclk(encoder, pipe_config->pipe_bpp); - else if (IS_VALLEYVIEW(encoder->base.dev) || - IS_CHERRYVIEW(encoder->base.dev)) - pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp); - + pclk = intel_dsi_get_pclk(encoder, pipe_config->pipe_bpp); if (!pclk) return; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 02551ff228c2..de7be7f3fb42 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -126,8 +126,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder) extern void intel_enable_dsi_pll(struct intel_encoder *encoder); extern void intel_disable_dsi_pll(struct intel_encoder *encoder); -extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); -extern u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp); +extern u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp); extern void intel_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index fbd2b51810ca..4c5bb7dd95a2 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -322,7 +322,7 @@ static void assert_bpp_mismatch(int pixel_format, int pipe_bpp) bpp, pipe_bpp); } -u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) +static u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); @@ -384,7 +384,7 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) return pclk; } -u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) +static u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp) { u32 pclk; u32 dsi_clk; @@ -419,6 +419,14 @@ u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) return pclk; } +u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp) +{ + if (IS_BROXTON(encoder->base.dev)) + return bxt_dsi_get_pclk(encoder, pipe_bpp); + else + return vlv_dsi_get_pclk(encoder, pipe_bpp); +} + static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) { u32 temp; -- GitLab From b5c0bbc4fe1acf7843639597ecdea59bc0037e9e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Jan 2016 12:45:40 +0200 Subject: [PATCH 0158/5324] drm/i915/dsi: remove unused dsi_rr_formula() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dsi_rr_formula() function has been unused for almost two years, since commit 44d4c6eebb2ef04f698c292bb6eda5f2e80c663b Author: Shobhit Kumar Date: Tue Dec 10 12:14:56 2013 +0530 drm/i915: Compute dsi_clk from pixel clock citing the reason as pixel clock based calculation being recommended in the MIPI host controller documentation. Remove the dead code, we can always bring it back if it's needed. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452249940-2605-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_pll.c | 81 ---------------------------- 1 file changed, 81 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 4c5bb7dd95a2..bb5e95a1a453 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -30,14 +30,6 @@ #include "i915_drv.h" #include "intel_dsi.h" -#define DSI_HSS_PACKET_SIZE 4 -#define DSI_HSE_PACKET_SIZE 4 -#define DSI_HSA_PACKET_EXTRA_SIZE 6 -#define DSI_HBP_PACKET_EXTRA_SIZE 6 -#define DSI_HACTIVE_PACKET_EXTRA_SIZE 6 -#define DSI_HFP_PACKET_EXTRA_SIZE 6 -#define DSI_EOTP_PACKET_SIZE 4 - static int dsi_pixel_format_bpp(int pixel_format) { int bpp; @@ -71,77 +63,6 @@ static const u32 lfsr_converts[] = { 71, 35, 273, 136, 324, 418, 465, 488, 500, 506 /* 91 - 100 */ }; -#ifdef DSI_CLK_FROM_RR - -static u32 dsi_rr_formula(const struct drm_display_mode *mode, - int pixel_format, int video_mode_format, - int lane_count, bool eotp) -{ - u32 bpp; - u32 hactive, vactive, hfp, hsync, hbp, vfp, vsync, vbp; - u32 hsync_bytes, hbp_bytes, hactive_bytes, hfp_bytes; - u32 bytes_per_line, bytes_per_frame; - u32 num_frames; - u32 bytes_per_x_frames, bytes_per_x_frames_x_lanes; - u32 dsi_bit_clock_hz; - u32 dsi_clk; - - bpp = dsi_pixel_format_bpp(pixel_format); - - hactive = mode->hdisplay; - vactive = mode->vdisplay; - hfp = mode->hsync_start - mode->hdisplay; - hsync = mode->hsync_end - mode->hsync_start; - hbp = mode->htotal - mode->hsync_end; - - vfp = mode->vsync_start - mode->vdisplay; - vsync = mode->vsync_end - mode->vsync_start; - vbp = mode->vtotal - mode->vsync_end; - - hsync_bytes = DIV_ROUND_UP(hsync * bpp, 8); - hbp_bytes = DIV_ROUND_UP(hbp * bpp, 8); - hactive_bytes = DIV_ROUND_UP(hactive * bpp, 8); - hfp_bytes = DIV_ROUND_UP(hfp * bpp, 8); - - bytes_per_line = DSI_HSS_PACKET_SIZE + hsync_bytes + - DSI_HSA_PACKET_EXTRA_SIZE + DSI_HSE_PACKET_SIZE + - hbp_bytes + DSI_HBP_PACKET_EXTRA_SIZE + - hactive_bytes + DSI_HACTIVE_PACKET_EXTRA_SIZE + - hfp_bytes + DSI_HFP_PACKET_EXTRA_SIZE; - - /* - * XXX: Need to accurately calculate LP to HS transition timeout and add - * it to bytes_per_line/bytes_per_frame. - */ - - if (eotp && video_mode_format == VIDEO_MODE_BURST) - bytes_per_line += DSI_EOTP_PACKET_SIZE; - - bytes_per_frame = vsync * bytes_per_line + vbp * bytes_per_line + - vactive * bytes_per_line + vfp * bytes_per_line; - - if (eotp && - (video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE || - video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS)) - bytes_per_frame += DSI_EOTP_PACKET_SIZE; - - num_frames = drm_mode_vrefresh(mode); - bytes_per_x_frames = num_frames * bytes_per_frame; - - bytes_per_x_frames_x_lanes = bytes_per_x_frames / lane_count; - - /* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */ - dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8; - dsi_clk = dsi_bit_clock_hz / 1000; - - if (eotp && video_mode_format == VIDEO_MODE_BURST) - dsi_clk *= 2; - - return dsi_clk; -} - -#else - /* Get DSI clock from pixel clock */ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) { @@ -155,8 +76,6 @@ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) return dsi_clk_khz; } -#endif - static int dsi_calc_mnp(struct drm_i915_private *dev_priv, struct dsi_mnp *dsi_mnp, int target_dsi_clk) { -- GitLab From 8d7a1c4a579c4ecfe360044c24dc1fbf97096752 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 7 Jan 2016 16:49:39 -0800 Subject: [PATCH 0159/5324] drm/i915/kbl: Adding missing IS_KABYLAKE checks. When adding IS_KABYLAKE definition I didn't included the DC states related because I was planing to include them with the patch that fixes DMC firmware loading, but I forgot them. Meanwhile this runtime pm code changed a lot for Skylake. Well, I didn't expect that this would crash the machine and I just noticed now that Sarah warned me our driver wasn't working. Thanks Sarah. Michel had found the main error first and his fix had better details on the history and got merged already: commit 16fbc291cb87c7defcd13ad715d3e4af0d523e43 Author: Michel Thierry Date: Wed Jan 6 12:08:36 2016 +0000 drm/i915/kbl: Enable PW1 and Misc I/O power wells This one is a follow-up adding the other remaining missing pieces. v2: Rebased on top of Michel's patch as explained above. Cc: Sarah Sharp Signed-off-by: Rodrigo Vivi Reviewed-by: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1452214179-22361-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 5 +++-- drivers/gpu/drm/i915/intel_runtime_pm.c | 15 ++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 9bb63a85997a..3f2850029c17 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -278,7 +278,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, csr->version = css_header->version; - if (IS_SKYLAKE(dev) && csr->version < SKL_CSR_VERSION_REQUIRED) { + if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && + csr->version < SKL_CSR_VERSION_REQUIRED) { DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," " please upgrade to v%u.%u or later" " [https://01.org/linuxgraphics/intel-linux-graphics-firmwares].\n", @@ -421,7 +422,7 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) if (!HAS_CSR(dev_priv)) return; - if (IS_SKYLAKE(dev_priv)) + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) csr->fw_path = I915_CSR_SKL; else if (IS_BROXTON(dev_priv)) csr->fw_path = I915_CSR_BXT; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 4b44e6862a27..89a7dd83e91f 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -532,7 +532,8 @@ static void assert_can_enable_dc5(struct drm_i915_private *dev_priv) bool pg2_enabled = intel_display_power_well_is_enabled(dev_priv, SKL_DISP_PW_2); - WARN_ONCE(!IS_SKYLAKE(dev), "Platform doesn't support DC5.\n"); + WARN_ONCE(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev), + "Platform doesn't support DC5.\n"); WARN_ONCE(!HAS_RUNTIME_PM(dev), "Runtime PM not enabled.\n"); WARN_ONCE(pg2_enabled, "PG2 not disabled to enable DC5.\n"); @@ -568,7 +569,8 @@ static void assert_can_enable_dc6(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; - WARN_ONCE(!IS_SKYLAKE(dev), "Platform doesn't support DC6.\n"); + WARN_ONCE(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev), + "Platform doesn't support DC6.\n"); WARN_ONCE(!HAS_RUNTIME_PM(dev), "Runtime PM not enabled.\n"); WARN_ONCE(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE, "Backlight is not disabled.\n"); @@ -595,7 +597,8 @@ static void gen9_disable_dc5_dc6(struct drm_i915_private *dev_priv) { assert_can_disable_dc5(dev_priv); - if (IS_SKYLAKE(dev_priv) && i915.enable_dc != 0 && i915.enable_dc != 1) + if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && + i915.enable_dc != 0 && i915.enable_dc != 1) assert_can_disable_dc6(dev_priv); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -783,7 +786,8 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - if (IS_SKYLAKE(dev_priv) && i915.enable_dc != 0 && i915.enable_dc != 1) + if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && + i915.enable_dc != 0 && i915.enable_dc != 1) skl_enable_dc6(dev_priv); else gen9_enable_dc5(dev_priv); @@ -795,7 +799,8 @@ static void gen9_dc_off_power_well_sync_hw(struct drm_i915_private *dev_priv, if (power_well->count > 0) { gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); } else { - if (IS_SKYLAKE(dev_priv) && i915.enable_dc != 0 && + if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && + i915.enable_dc != 0 && i915.enable_dc != 1) gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); else -- GitLab From cd7feaaad68edd12959843ccee9ecfcf05ecdbfe Mon Sep 17 00:00:00 2001 From: "Boyer, Wayne" Date: Wed, 6 Jan 2016 17:15:29 -0800 Subject: [PATCH 0160/5324] drm/i915: Don't warn if the workaround list is empty part 2. Extend the same reasoning as in the patch listed below. It's not an error for the workaround list to be empty if no workarounds are needed. commit 02235808b61cd9382d224b0df263193006dd9913 Author: Francisco Jerez Date: Wed Oct 7 14:44:01 2015 +0300 drm/i915: Don't warn if the workaround list is empty. Signed-off-by: Wayne Boyer Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1452129330-3484-2-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 23839ff04e27..f7fac5f3b5ce 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1116,7 +1116,7 @@ static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) struct drm_i915_private *dev_priv = dev->dev_private; struct i915_workarounds *w = &dev_priv->workarounds; - if (WARN_ON_ONCE(w->count == 0)) + if (w->count == 0) return 0; ring->gpu_caches_dirty = true; -- GitLab From db1a6aa2afa50803fbd801631bb9756eeff96dbe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 00:04:02 +0100 Subject: [PATCH 0161/5324] drm/i915: Update DRIVER_DATE to 20160111 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6ef03eea3518..747d2d84a18c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -59,7 +59,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20151218" +#define DRIVER_DATE "20160111" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ -- GitLab From bcf8be279c79df6a8a17d9c3e1f9bc926444a87c Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 8 Dec 2015 15:52:56 +0100 Subject: [PATCH 0162/5324] drm/i915: Widen return value for reservation_object_wait_timeout_rcu to long. This fixes a spurious warning from an integer overflow on 64-bits systems. The function may return MAX_SCHEDULE_TIMEOUT which gets truncated to -1. Explicitly handling this by casting to lret fixes it. Signed-off-by: Maarten Lankhorst Reported-and-tested-by: Joseph Yasi Tested-by: Andreas Reis Reviewed-by: Daniel Vetter Cc: drm-intel-fixes@lists.freedesktop.org Fixes: 3c28ff22f6e20c ("i915: wait for fence in prepare_plane_fb") Link: http://patchwork.freedesktop.org/patch/msgid/5666EEC8.2000403@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3edf22ad7673..259f2ca57447 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13902,13 +13902,15 @@ intel_prepare_plane_fb(struct drm_plane *plane, /* For framebuffer backed by dmabuf, wait for fence */ if (obj && obj->base.dma_buf) { - ret = reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv, - false, true, - MAX_SCHEDULE_TIMEOUT); - if (ret == -ERESTARTSYS) - return ret; + long lret; + + lret = reservation_object_wait_timeout_rcu(obj->base.dma_buf->resv, + false, true, + MAX_SCHEDULE_TIMEOUT); + if (lret == -ERESTARTSYS) + return lret; - WARN_ON(ret < 0); + WARN(lret < 0, "waiting returns %li\n", lret); } if (!obj) { -- GitLab From e462919413547dcfe84e785380d0f47f1359878a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 27 Nov 2015 16:26:41 +0300 Subject: [PATCH 0163/5324] xtensa: make fake NMI configurable Do not always use fake NMI when safe, provide Kconfig option instead. Print a warning if fake NMI is chosen in unsafe configuration, but allow it, because it may work if the user knows that interrupts with priorities at or above PMM IRQ are not used. Add a check to NMI handler that BUGs if any of these IRQs fire. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 16 ++++++++++++++++ arch/xtensa/include/asm/processor.h | 12 +++++------- arch/xtensa/kernel/traps.c | 27 +++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 82044f732323..128e63d3a632 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -139,6 +139,22 @@ config XTENSA_VARIANT_HAVE_PERF_EVENTS If unsure, say N. +config XTENSA_FAKE_NMI + bool "Treat PMM IRQ as NMI" + depends on XTENSA_VARIANT_HAVE_PERF_EVENTS + default n + help + If PMM IRQ is the only IRQ at EXCM level it is safe to + treat it as NMI, which improves accuracy of profiling. + + If there are other interrupts at or above PMM IRQ priority level + but not above the EXCM level, PMM IRQ still may be treated as NMI, + but only if these IRQs are not used. There will be a build warning + saying that this is not safe, and a bugcheck if one of these IRQs + actually fire. + + If unsure, say N. + config XTENSA_UNALIGNED_USER bool "Unaligned memory access in use space" help diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 83e2e4bc01ba..744ecf0dc3a4 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -78,22 +78,20 @@ #define XTENSA_INTLEVEL_MASK(level) _XTENSA_INTLEVEL_MASK(level) #define _XTENSA_INTLEVEL_MASK(level) (XCHAL_INTLEVEL##level##_MASK) -#define IS_POW2(v) (((v) & ((v) - 1)) == 0) +#define XTENSA_INTLEVEL_ANDBELOW_MASK(l) _XTENSA_INTLEVEL_ANDBELOW_MASK(l) +#define _XTENSA_INTLEVEL_ANDBELOW_MASK(l) (XCHAL_INTLEVEL##l##_ANDBELOW_MASK) #define PROFILING_INTLEVEL XTENSA_INT_LEVEL(XCHAL_PROFILING_INTERRUPT) /* LOCKLEVEL defines the interrupt level that masks all * general-purpose interrupts. */ -#if defined(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) && \ - defined(XCHAL_PROFILING_INTERRUPT) && \ - PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ - XCHAL_EXCM_LEVEL > 1 && \ - IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL)) -#define LOCKLEVEL (XCHAL_EXCM_LEVEL - 1) +#if defined(CONFIG_XTENSA_FAKE_NMI) && defined(XCHAL_PROFILING_INTERRUPT) +#define LOCKLEVEL (PROFILING_INTLEVEL - 1) #else #define LOCKLEVEL XCHAL_EXCM_LEVEL #endif + #define TOPLEVEL XCHAL_EXCM_LEVEL #define XTENSA_FAKE_NMI (LOCKLEVEL < TOPLEVEL) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 42d441f7898b..be0cae8082c7 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -205,6 +205,32 @@ extern void do_IRQ(int, struct pt_regs *); #if XTENSA_FAKE_NMI +#define IS_POW2(v) (((v) & ((v) - 1)) == 0) + +#if !(PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ + IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL))) +#warning "Fake NMI is requested for PMM, but there are other IRQs at or above its level." +#warning "Fake NMI will be used, but there will be a bugcheck if one of those IRQs fire." + +static inline void check_valid_nmi(void) +{ + unsigned intread = get_sr(interrupt); + unsigned intenable = get_sr(intenable); + + BUG_ON(intread & intenable & + ~(XTENSA_INTLEVEL_ANDBELOW_MASK(PROFILING_INTLEVEL) ^ + XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL) ^ + BIT(XCHAL_PROFILING_INTERRUPT))); +} + +#else + +static inline void check_valid_nmi(void) +{ +} + +#endif + irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id); DEFINE_PER_CPU(unsigned long, nmi_count); @@ -219,6 +245,7 @@ void do_nmi(struct pt_regs *regs) old_regs = set_irq_regs(regs); nmi_enter(); ++*this_cpu_ptr(&nmi_count); + check_valid_nmi(); xtensa_pmu_irq_handler(0, NULL); nmi_exit(); set_irq_regs(old_regs); -- GitLab From 7d2022198999bd75d2c0367c9dc5a5a16b96d04f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 21 Dec 2015 14:12:08 +0300 Subject: [PATCH 0164/5324] xtensa: use XTENSA_INT_LEVEL macro in asm/timex.h Signed-off-by: Max Filippov --- arch/xtensa/include/asm/timex.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h index ca929e6a38b5..f9b389d4e973 100644 --- a/arch/xtensa/include/asm/timex.h +++ b/arch/xtensa/include/asm/timex.h @@ -12,19 +12,16 @@ #include #include -#define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL -#define INTLEVEL(x) _INTLEVEL(x) - #if XCHAL_NUM_TIMERS > 0 && \ - INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 0 # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT #elif XCHAL_NUM_TIMERS > 1 && \ - INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 1 # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT #elif XCHAL_NUM_TIMERS > 2 && \ - INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 2 # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT #else -- GitLab From 5bb8def55dc562d81ec582368b4f27c8d432fbd5 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 10 Dec 2015 17:05:27 -0800 Subject: [PATCH 0165/5324] xtensa: support ioremap for memory outside KIO region Map physical memory outside KIO region into the vmalloc area. Unmap it with vunmap. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/io.h | 16 +++++++-- arch/xtensa/mm/Makefile | 2 +- arch/xtensa/mm/ioremap.c | 68 ++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 arch/xtensa/mm/ioremap.c diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 74fed0b4e2c2..c38e5a732d86 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -25,9 +25,12 @@ #ifdef CONFIG_MMU +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size); +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size); +void xtensa_iounmap(volatile void __iomem *addr); + /* * Return the virtual address for the specified bus memory. - * Note that we currently don't support any address outside the KIO segment. */ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size) @@ -36,7 +39,7 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR); else - BUG(); + return xtensa_ioremap_nocache(offset, size); } static inline void __iomem *ioremap_cache(unsigned long offset, @@ -46,7 +49,7 @@ static inline void __iomem *ioremap_cache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR); else - BUG(); + return xtensa_ioremap_cache(offset, size); } #define ioremap_cache ioremap_cache @@ -60,6 +63,13 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { + unsigned long va = (unsigned long) addr; + + if (!(va >= XCHAL_KIO_CACHED_VADDR && + va - XCHAL_KIO_CACHED_VADDR < XCHAL_KIO_SIZE) && + !(va >= XCHAL_KIO_BYPASS_VADDR && + va - XCHAL_KIO_BYPASS_VADDR < XCHAL_KIO_SIZE)) + xtensa_iounmap(addr); } #define virt_to_bus virt_to_phys diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index e601e2fbe8e6..0b3d296a016a 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile @@ -3,5 +3,5 @@ # obj-y := init.o misc.o -obj-$(CONFIG_MMU) += cache.o fault.o mmu.o tlb.o +obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/arch/xtensa/mm/ioremap.c b/arch/xtensa/mm/ioremap.c new file mode 100644 index 000000000000..d89c3c5fd962 --- /dev/null +++ b/arch/xtensa/mm/ioremap.c @@ -0,0 +1,68 @@ +/* + * ioremap implementation. + * + * Copyright (C) 2015 Cadence Design Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size, + pgprot_t prot) +{ + unsigned long offset = paddr & ~PAGE_MASK; + unsigned long pfn = __phys_to_pfn(paddr); + struct vm_struct *area; + unsigned long vaddr; + int err; + + paddr &= PAGE_MASK; + + WARN_ON(pfn_valid(pfn)); + + size = PAGE_ALIGN(offset + size); + + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + + vaddr = (unsigned long)area->addr; + area->phys_addr = paddr; + + err = ioremap_page_range(vaddr, vaddr + size, paddr, prot); + + if (err) { + vunmap((void *)vaddr); + return NULL; + } + + flush_cache_vmap(vaddr, vaddr + size); + return (void __iomem *)(offset + vaddr); +} + +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL)); +} +EXPORT_SYMBOL(xtensa_ioremap_nocache); + +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, PAGE_KERNEL); +} +EXPORT_SYMBOL(xtensa_ioremap_cache); + +void xtensa_iounmap(volatile void __iomem *io_addr) +{ + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); + + vunmap(addr); +} +EXPORT_SYMBOL(xtensa_iounmap); -- GitLab From 9c053501b950cf4dcea3dbbcd42da65e376acce6 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 8 Jan 2016 15:51:19 +0200 Subject: [PATCH 0166/5324] drm/i915: Enable mmio_debug for vlv/chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With commit 8ac3e1bb76cc ("drm/i915: Add non claimed mmio checking for vlv/chv") we now have chv/vlv support in place for detecting unclaimed access. Also the perf hit of extra mmio read is now only suffered if mmio_debug is set. This allows us to stuff the macro for unclaimed reg detection inside a generic gen6 register access, as now all gens using these macros uses also unclaimed debugs, the one exception being snb. We gain more clean and generic macros and only downside is that snb will suffer one branch perf hit without upside. Note that the hsw write path debug register check now happens before fifo check, but this should not make any real difference. As vlv/chv use the generic gen6 access macros, the consequence is that they gain the mmio_debug feature. Cc: Ville Syrjälä Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452261080-6979-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d0973e08e7eb..0b47bc891dc7 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -626,14 +626,11 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) } static void -hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, - const i915_reg_t reg, - const bool read, - const bool before) +__unclaimed_reg_debug(struct drm_i915_private *dev_priv, + const i915_reg_t reg, + const bool read, + const bool before) { - if (likely(!i915.mmio_debug)) - return; - if (WARN(check_for_unclaimed_mmio(dev_priv), "Unclaimed register detected %s %s register 0x%x\n", before ? "before" : "after", @@ -642,6 +639,18 @@ hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, i915.mmio_debug--; /* Only report the first N failures */ } +static inline void +unclaimed_reg_debug(struct drm_i915_private *dev_priv, + const i915_reg_t reg, + const bool read, + const bool before) +{ + if (likely(!i915.mmio_debug)) + return; + + __unclaimed_reg_debug(dev_priv, reg, read, before); +} + #define GEN2_READ_HEADER(x) \ u##x val = 0; \ assert_rpm_wakelock_held(dev_priv); @@ -687,9 +696,11 @@ __gen2_read(64) unsigned long irqflags; \ u##x val = 0; \ assert_rpm_wakelock_held(dev_priv); \ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ + unclaimed_reg_debug(dev_priv, reg, true, true) #define GEN6_READ_FOOTER \ + unclaimed_reg_debug(dev_priv, reg, true, false); \ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \ return val @@ -722,11 +733,9 @@ static inline void __force_wake_get(struct drm_i915_private *dev_priv, static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ GEN6_READ_HEADER(x); \ - hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ if (NEEDS_FORCE_WAKE(offset)) \ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \ val = __raw_i915_read##x(dev_priv, reg); \ - hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \ GEN6_READ_FOOTER; \ } @@ -774,7 +783,6 @@ static u##x \ gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ enum forcewake_domains fw_engine; \ GEN6_READ_HEADER(x); \ - hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ if (!SKL_NEEDS_FORCE_WAKE(offset)) \ fw_engine = 0; \ else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \ @@ -788,7 +796,6 @@ gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ if (fw_engine) \ __force_wake_get(dev_priv, fw_engine); \ val = __raw_i915_read##x(dev_priv, reg); \ - hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \ GEN6_READ_FOOTER; \ } @@ -887,9 +894,11 @@ __gen2_write(64) unsigned long irqflags; \ trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ assert_rpm_wakelock_held(dev_priv); \ - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags) + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); \ + unclaimed_reg_debug(dev_priv, reg, false, true) #define GEN6_WRITE_FOOTER \ + unclaimed_reg_debug(dev_priv, reg, false, false); \ spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags) #define __gen6_write(x) \ @@ -915,12 +924,10 @@ hsw_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool t if (NEEDS_FORCE_WAKE(offset)) { \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ } \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ __raw_i915_write##x(dev_priv, reg, val); \ if (unlikely(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ GEN6_WRITE_FOOTER; \ } @@ -950,11 +957,9 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, static void \ gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \ GEN6_WRITE_HEADER; \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(dev_priv, reg)) \ __force_wake_get(dev_priv, FORCEWAKE_RENDER); \ __raw_i915_write##x(dev_priv, reg, val); \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ GEN6_WRITE_FOOTER; \ } @@ -1008,7 +1013,6 @@ gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \ bool trace) { \ enum forcewake_domains fw_engine; \ GEN6_WRITE_HEADER; \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ if (!SKL_NEEDS_FORCE_WAKE(offset) || \ is_gen9_shadowed(dev_priv, reg)) \ fw_engine = 0; \ @@ -1023,7 +1027,6 @@ gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \ if (fw_engine) \ __force_wake_get(dev_priv, fw_engine); \ __raw_i915_write##x(dev_priv, reg, val); \ - hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ GEN6_WRITE_FOOTER; \ } -- GitLab From bc3b9346cd47148db8601fb425a4949902c475ec Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 8 Jan 2016 15:51:20 +0200 Subject: [PATCH 0167/5324] drm/i915: Arm the unclaimed mmio debugs on suspend path If we go into suspend with unclaimed access detected, it would be nice to catch that access on a next suspend path. So instead of just notifying about it, arm the unclaimed mmio checks on suspend side. We want to keep the asymmetry on resume, as if it was on resume path, it was not driver that is responsible so no point in arming mmio debugs. Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452261080-6979-2-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 288fec7691dc..9de993d5fed2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1502,7 +1502,7 @@ static int intel_runtime_suspend(struct device *device) enable_rpm_wakeref_asserts(dev_priv); WARN_ON_ONCE(atomic_read(&dev_priv->pm.wakeref_count)); - if (intel_uncore_unclaimed_mmio(dev_priv)) + if (intel_uncore_arm_unclaimed_mmio_detection(dev_priv)) DRM_ERROR("Unclaimed access detected prior to suspending\n"); dev_priv->pm.suspended = true; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 747d2d84a18c..104bd1809936 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2720,7 +2720,7 @@ extern void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake); extern void intel_uncore_init(struct drm_device *dev); extern bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv); -extern void intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv); +extern bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0b47bc891dc7..c3c13dc929cb 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1610,12 +1610,12 @@ bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv) return check_for_unclaimed_mmio(dev_priv); } -void +bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) { if (unlikely(i915.mmio_debug || dev_priv->uncore.unclaimed_mmio_check <= 0)) - return; + return false; if (unlikely(intel_uncore_unclaimed_mmio(dev_priv))) { DRM_DEBUG("Unclaimed register detected, " @@ -1623,5 +1623,8 @@ intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv) "Please use i915.mmio_debug=N for more information.\n"); i915.mmio_debug++; dev_priv->uncore.unclaimed_mmio_check--; + return true; } + + return false; } -- GitLab From f4d64936afb414fd5af3ac301919407273fb74a4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:11:00 +0200 Subject: [PATCH 0168/5324] drm/i915/bios: interpret the i2c element MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add parsing of the i2c element, defined in MIPI sequence block v2. Drop the status operation byte while at it, that does not exist. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/d8a2998977feee2f5b5ad609aaca787adfb41479.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 5 +++++ drivers/gpu/drm/i915/intel_bios.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 71c739e33101..69040a73c09a 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -812,6 +812,11 @@ static int goto_next_sequence(const u8 *data, int index, int total) case MIPI_SEQ_ELEM_GPIO: len = 2; break; + case MIPI_SEQ_ELEM_I2C: + if (index + 7 > total) + return 0; + len = *(data + index + 6) + 7; + break; default: DRM_ERROR("Unknown operation byte\n"); return 0; diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 4e87df16e7b3..411b33794536 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -968,7 +968,7 @@ enum mipi_seq_element { MIPI_SEQ_ELEM_SEND_PKT, MIPI_SEQ_ELEM_DELAY, MIPI_SEQ_ELEM_GPIO, - MIPI_SEQ_ELEM_STATUS, + MIPI_SEQ_ELEM_I2C, /* sequence block v2+ */ MIPI_SEQ_ELEM_MAX }; -- GitLab From e534f7a2f795081817e95dee0a92bf0293b7a878 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:11:01 +0200 Subject: [PATCH 0169/5324] drm/i915/bios: add sequences for MIPI sequence block v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly parse the new sequences added in MIPI sequence block v2. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/cc1551bdfc4392d02413b78179f3a65c786c75ab.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 411b33794536..6146f1b0cf48 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -960,6 +960,9 @@ enum mipi_seq { MIPI_SEQ_DISPLAY_ON, MIPI_SEQ_DISPLAY_OFF, MIPI_SEQ_DEASSERT_RESET, + MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */ + MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */ + MIPI_SEQ_TEAR_ON, /* sequence block v2+ */ MIPI_SEQ_MAX }; -- GitLab From 29bbdcb0e3a1602cf81f4afdf86fe127d3833b3f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 11 Jan 2016 15:29:08 +0200 Subject: [PATCH 0170/5324] drm/i915: skip the i2c element in the generic VBT DSI driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't choke on unknown elements when we do know how to skip them. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452518948-16469-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 9bd920809697..b98cec635676 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -229,12 +229,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) return data; } +static const u8 *mipi_exec_i2c_skip(struct intel_dsi *intel_dsi, const u8 *data) +{ + return data + *(data + 6) + 7; +} + typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi, const u8 *data); static const fn_mipi_elem_exec exec_elem[] = { [MIPI_SEQ_ELEM_SEND_PKT] = mipi_exec_send_packet, [MIPI_SEQ_ELEM_DELAY] = mipi_exec_delay, [MIPI_SEQ_ELEM_GPIO] = mipi_exec_gpio, + [MIPI_SEQ_ELEM_I2C] = mipi_exec_i2c_skip, }; /* -- GitLab From 4b42dfbbd8e5f0cd8b7a3f16d719046d363f6b57 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:11:03 +0200 Subject: [PATCH 0171/5324] drm/i915/bios: add defines for v3 sequence block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New sequences, new operations within sequences. Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/96335b9fb875f79882d694360bff060251bd2f17.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 6146f1b0cf48..350d4e0f75a4 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -963,6 +963,9 @@ enum mipi_seq { MIPI_SEQ_BACKLIGHT_ON, /* sequence block v2+ */ MIPI_SEQ_BACKLIGHT_OFF, /* sequence block v2+ */ MIPI_SEQ_TEAR_ON, /* sequence block v2+ */ + MIPI_SEQ_TEAR_OFF, /* sequence block v3+ */ + MIPI_SEQ_POWER_ON, /* sequence block v3+ */ + MIPI_SEQ_POWER_OFF, /* sequence block v3+ */ MIPI_SEQ_MAX }; @@ -972,6 +975,8 @@ enum mipi_seq_element { MIPI_SEQ_ELEM_DELAY, MIPI_SEQ_ELEM_GPIO, MIPI_SEQ_ELEM_I2C, /* sequence block v2+ */ + MIPI_SEQ_ELEM_SPI, /* sequence block v3+ */ + MIPI_SEQ_ELEM_PMIC, /* sequence block v3+ */ MIPI_SEQ_ELEM_MAX }; -- GitLab From 2a33d93486f247924e46b5402b8ffb43d1b9b38c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 11 Jan 2016 15:15:02 +0200 Subject: [PATCH 0172/5324] drm/i915/bios: add support for MIPI sequence block v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The changes since the sequence block v2 are: * The whole MIPI bios data block has a separate 32-bit size field since v3, stored after the version. This facilitates big sequences. * The size of the panel specific sequence blocks has grown to 32 bits. This facilitates big sequences. * The elements within sequences now have an 8-bit size field following the operation byte. This facilitates skipping unknown new operation bytes, i.e. forward compatibility. v2 (of the patch): use DRM_ERROR for unknown operation byte v3 (of the patch): even more bounds checking (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452518102-3154-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 96 +++++++++++++++++++--- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 9 ++ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 69040a73c09a..15ba52bd2538 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -754,21 +754,33 @@ parse_mipi_config(struct drm_i915_private *dev_priv, /* Find the sequence block and size for the given panel. */ static const u8 * find_panel_sequence_block(const struct bdb_mipi_sequence *sequence, - u16 panel_id, u16 *seq_size) + u16 panel_id, u32 *seq_size) { u32 total = get_blocksize(sequence); const u8 *data = &sequence->data[0]; u8 current_id; - u16 current_size; + u32 current_size; + int header_size = sequence->version >= 3 ? 5 : 3; int index = 0; int i; - for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index + 3 < total; i++) { + /* skip new block size */ + if (sequence->version >= 3) + data += 4; + + for (i = 0; i < MAX_MIPI_CONFIGURATIONS && index < total; i++) { + if (index + header_size > total) { + DRM_ERROR("Invalid sequence block (header)\n"); + return NULL; + } + current_id = *(data + index); - index++; + if (sequence->version >= 3) + current_size = *((const u32 *)(data + index + 1)); + else + current_size = *((const u16 *)(data + index + 1)); - current_size = *((const u16 *)(data + index)); - index += 2; + index += header_size; if (index + current_size > total) { DRM_ERROR("Invalid sequence block\n"); @@ -826,13 +838,71 @@ static int goto_next_sequence(const u8 *data, int index, int total) return 0; } +static int goto_next_sequence_v3(const u8 *data, int index, int total) +{ + int seq_end; + u16 len; + + /* + * Could skip sequence based on Size of Sequence alone, but also do some + * checking on the structure. + */ + if (total < 5) { + DRM_ERROR("Too small sequence size\n"); + return 0; + } + + seq_end = index + *((const u32 *)(data + 1)); + if (seq_end > total) { + DRM_ERROR("Invalid sequence size\n"); + return 0; + } + + /* Skip Sequence Byte and Size of Sequence. */ + for (index = index + 5; index < total; index += len) { + u8 operation_byte = *(data + index); + index++; + + if (operation_byte == MIPI_SEQ_ELEM_END) { + if (index != seq_end) { + DRM_ERROR("Invalid element structure\n"); + return 0; + } + return index; + } + + len = *(data + index); + index++; + + /* + * FIXME: Would be nice to check elements like for v1/v2 in + * goto_next_sequence() above. + */ + switch (operation_byte) { + case MIPI_SEQ_ELEM_SEND_PKT: + case MIPI_SEQ_ELEM_DELAY: + case MIPI_SEQ_ELEM_GPIO: + case MIPI_SEQ_ELEM_I2C: + case MIPI_SEQ_ELEM_SPI: + case MIPI_SEQ_ELEM_PMIC: + break; + default: + DRM_ERROR("Unknown operation byte %u\n", + operation_byte); + break; + } + } + + return 0; +} + static void parse_mipi_sequence(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) { const struct bdb_mipi_sequence *sequence; const u8 *seq_data; - u16 seq_size; + u32 seq_size; u8 *data; int index = 0; @@ -847,12 +917,13 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, } /* Fail gracefully for forward incompatible sequence block. */ - if (sequence->version >= 3) { - DRM_ERROR("Unable to parse MIPI Sequence Block v3+\n"); + if (sequence->version >= 4) { + DRM_ERROR("Unable to parse MIPI Sequence Block v%u\n", + sequence->version); return; } - DRM_DEBUG_DRIVER("Found MIPI sequence block\n"); + DRM_DEBUG_DRIVER("Found MIPI sequence block v%u\n", sequence->version); seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size); if (!seq_data) @@ -875,7 +946,10 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv, dev_priv->vbt.dsi.sequence[seq_id] = data + index; - index = goto_next_sequence(data, index, seq_size); + if (sequence->version >= 3) + index = goto_next_sequence_v3(data, index, seq_size); + else + index = goto_next_sequence(data, index, seq_size); if (!index) { DRM_ERROR("Invalid sequence %u\n", seq_id); goto err; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index b98cec635676..a7d22ebef3fa 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -267,6 +267,7 @@ static const char *sequence_name(enum mipi_seq seq_id) static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) { + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); fn_mipi_elem_exec mipi_elem_exec; if (!data) @@ -278,6 +279,10 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) /* go to the first element of the sequence */ data++; + /* Skip Size of Sequence. */ + if (dev_priv->vbt.dsi.seq_version >= 3) + data += 4; + /* parse each byte till we reach end of sequence byte - 0x00 */ while (1) { u8 operation_byte = *data++; @@ -289,6 +294,10 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) } mipi_elem_exec = exec_elem[operation_byte]; + /* Skip Size of Operation. */ + if (dev_priv->vbt.dsi.seq_version >= 3) + data++; + /* execute the element specific rotines */ data = mipi_elem_exec(intel_dsi, data); -- GitLab From 407957827935bc951a706c09b0a395480c087748 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 5 Jan 2016 17:06:48 +0200 Subject: [PATCH 0173/5324] drm/i915/dsi: skip unknown elements for sequence block v3+ The sequence block has sizes of elements after the operation byte since sequence block v3. Use it to skip elements we don't support yet. v2: remove redundant exec_elem[operation_byte] check (Daniel) Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452006408-27688-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 42 ++++++++++++---------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index a7d22ebef3fa..92d5972ec715 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -283,31 +283,35 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) if (dev_priv->vbt.dsi.seq_version >= 3) data += 4; - /* parse each byte till we reach end of sequence byte - 0x00 */ while (1) { u8 operation_byte = *data++; - if (operation_byte >= ARRAY_SIZE(exec_elem) || - !exec_elem[operation_byte]) { + u8 operation_size = 0; + + if (operation_byte == MIPI_SEQ_ELEM_END) + break; + + if (operation_byte < ARRAY_SIZE(exec_elem)) + mipi_elem_exec = exec_elem[operation_byte]; + else + mipi_elem_exec = NULL; + + /* Size of Operation. */ + if (dev_priv->vbt.dsi.seq_version >= 3) + operation_size = *data++; + + if (mipi_elem_exec) { + data = mipi_elem_exec(intel_dsi, data); + } else if (operation_size) { + /* We have size, skip. */ + DRM_DEBUG_KMS("Unsupported MIPI operation byte %u\n", + operation_byte); + data += operation_size; + } else { + /* No size, can't skip without parsing. */ DRM_ERROR("Unsupported MIPI operation byte %u\n", operation_byte); return; } - mipi_elem_exec = exec_elem[operation_byte]; - - /* Skip Size of Operation. */ - if (dev_priv->vbt.dsi.seq_version >= 3) - data++; - - /* execute the element specific rotines */ - data = mipi_elem_exec(intel_dsi, data); - - /* - * After processing the element, data should point to - * next element or end of sequence - * check if have we reached end of sequence - */ - if (*data == 0x00) - break; } } -- GitLab From c67fed8534139fcf5f0184cd4dea062f631d0d6f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Dec 2015 15:11:06 +0200 Subject: [PATCH 0174/5324] drm/i915/dsi: reduce tedious repetition Make it a bit tidier and safer. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/cab24a84811ddbae72d8c3a5f59d29f57b1d3aad.1450702954.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 62 ++++++++-------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 92d5972ec715..66d0b73725df 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -265,18 +265,30 @@ static const char *sequence_name(enum mipi_seq seq_id) return "(unknown)"; } -static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) +static void generic_exec_sequence(struct drm_panel *panel, enum mipi_seq seq_id) { + struct vbt_panel *vbt_panel = to_vbt_panel(panel); + struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + const u8 *data; fn_mipi_elem_exec mipi_elem_exec; - if (!data) + if (WARN_ON(seq_id >= ARRAY_SIZE(dev_priv->vbt.dsi.sequence))) return; - DRM_DEBUG_DRIVER("Starting MIPI sequence %u - %s\n", - *data, sequence_name(*data)); + data = dev_priv->vbt.dsi.sequence[seq_id]; + if (!data) { + DRM_DEBUG_KMS("MIPI sequence %d - %s not available\n", + seq_id, sequence_name(seq_id)); + return; + } - /* go to the first element of the sequence */ + WARN_ON(*data != seq_id); + + DRM_DEBUG_KMS("Starting MIPI sequence %d - %s\n", + seq_id, sequence_name(seq_id)); + + /* Skip Sequence Byte. */ data++; /* Skip Size of Sequence. */ @@ -317,59 +329,29 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) static int vbt_panel_prepare(struct drm_panel *panel) { - struct vbt_panel *vbt_panel = to_vbt_panel(panel); - struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const u8 *sequence; - - sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET]; - generic_exec_sequence(intel_dsi, sequence); - - sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; - generic_exec_sequence(intel_dsi, sequence); + generic_exec_sequence(panel, MIPI_SEQ_ASSERT_RESET); + generic_exec_sequence(panel, MIPI_SEQ_INIT_OTP); return 0; } static int vbt_panel_unprepare(struct drm_panel *panel) { - struct vbt_panel *vbt_panel = to_vbt_panel(panel); - struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const u8 *sequence; - - sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]; - generic_exec_sequence(intel_dsi, sequence); + generic_exec_sequence(panel, MIPI_SEQ_DEASSERT_RESET); return 0; } static int vbt_panel_enable(struct drm_panel *panel) { - struct vbt_panel *vbt_panel = to_vbt_panel(panel); - struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const u8 *sequence; - - sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]; - generic_exec_sequence(intel_dsi, sequence); + generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_ON); return 0; } static int vbt_panel_disable(struct drm_panel *panel) { - struct vbt_panel *vbt_panel = to_vbt_panel(panel); - struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const u8 *sequence; - - sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_OFF]; - generic_exec_sequence(intel_dsi, sequence); + generic_exec_sequence(panel, MIPI_SEQ_DISPLAY_OFF); return 0; } -- GitLab From bc95ce7f397232f8d0cacec94aa426b90e87d024 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 5 Jan 2016 17:08:17 +0200 Subject: [PATCH 0175/5324] drm/i915/dsi: add debug printing of the new sequence block names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452006497-28517-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 66d0b73725df..1d43e6f37fc1 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -255,6 +255,12 @@ static const char * const seq_name[] = { [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON", [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF", [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET", + [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON", + [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF", + [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON", + [MIPI_SEQ_TEAR_OFF] = "MIPI_SEQ_TEAR_OFF", + [MIPI_SEQ_POWER_ON] = "MIPI_SEQ_POWER_ON", + [MIPI_SEQ_POWER_OFF] = "MIPI_SEQ_POWER_OFF", }; static const char *sequence_name(enum mipi_seq seq_id) -- GitLab From 7eb08a25a4104ec6b2dfd78939606cff44a394e1 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 11 Jan 2016 14:08:35 +0000 Subject: [PATCH 0176/5324] drm/i915/bdw+: Replace list_del+list_add_tail with list_move_tail Same effect for slightly less source code and resulting binary. Signed-off-by: Tvrtko Ursulin Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452521321-4032-2-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f7fac5f3b5ce..ab344e0b878c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -431,9 +431,8 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) /* Same ctx: ignore first request, as second request * will update tail past first request's workload */ cursor->elsp_submitted = req0->elsp_submitted; - list_del(&req0->execlist_link); - list_add_tail(&req0->execlist_link, - &ring->execlist_retired_req_list); + list_move_tail(&req0->execlist_link, + &ring->execlist_retired_req_list); req0 = cursor; } else { req1 = cursor; @@ -485,9 +484,8 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, "Never submitted head request\n"); if (--head_req->elsp_submitted <= 0) { - list_del(&head_req->execlist_link); - list_add_tail(&head_req->execlist_link, - &ring->execlist_retired_req_list); + list_move_tail(&head_req->execlist_link, + &ring->execlist_retired_req_list); return true; } } @@ -608,9 +606,8 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) if (request->ctx == tail_req->ctx) { WARN(tail_req->elsp_submitted != 0, "More than 2 already-submitted reqs queued\n"); - list_del(&tail_req->execlist_link); - list_add_tail(&tail_req->execlist_link, - &ring->execlist_retired_req_list); + list_move_tail(&tail_req->execlist_link, + &ring->execlist_retired_req_list); } } -- GitLab From d919161b67b1ed4a374dae685840a601bbeb1347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:36 +0200 Subject: [PATCH 0177/5324] drm/i915: Pass the correct encoder to intel_ddi_clk_select() with MST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're supposed to pass the primary DP encoder to intel_ddi_clk_select(), not the fake MST encoder. Do so. There's no real bug here though, since intel_ddi_clk_select() only checks if the encoder type is EDP (which it isn't for either the primary DP encoder or the fake MST encoder), and it gets the DDI port via intel_ddi_get_encoder_port() (which knows how to do the fake->primary->port dance itself). Fixes: e404ba8 ("drm/i915: Setup DDI clk for MST on SKL") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1449597590-6971-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp_mst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 8b608c2cd070..5cb168dc2f0c 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -184,7 +184,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) intel_mst->port = found->port; if (intel_dp->active_mst_links == 0) { - intel_ddi_clk_select(encoder, intel_crtc->config); + intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config); intel_dp_set_link_params(intel_dp, intel_crtc->config); -- GitLab From 10e7bec38bbda47653b46d4e1257876124824a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:37 +0200 Subject: [PATCH 0178/5324] drm/i915: Check max number of lanes when registering DDI ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DDI A and E share some of the lanes, so check that we have enough lanes for the purpose we need before registering the encoders. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1449597590-6971-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 612400fab559..a69db463557f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3282,6 +3282,33 @@ void intel_ddi_init(struct drm_device *dev, enum port port) struct intel_encoder *intel_encoder; struct drm_encoder *encoder; bool init_hdmi, init_dp; + int max_lanes; + + if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) { + switch (port) { + case PORT_A: + max_lanes = 4; + break; + case PORT_E: + max_lanes = 0; + break; + default: + max_lanes = 4; + break; + } + } else { + switch (port) { + case PORT_A: + max_lanes = 2; + break; + case PORT_E: + max_lanes = 2; + break; + default: + max_lanes = 4; + break; + } + } init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi || dev_priv->vbt.ddi_port_info[port].supports_hdmi); @@ -3292,6 +3319,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port) return; } + if (WARN(max_lanes == 0, + "No lanes for port %c\n", port_name(port))) + return; + + if (WARN(init_hdmi && max_lanes < 4, + "Not enough lanes (%d) for HDMI on port %c\n", + max_lanes, port_name(port))) + init_hdmi = false; + intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); if (!intel_dig_port) return; -- GitLab From ccb1a8319015d31a51e8206b66ab3aaea07417ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:38 +0200 Subject: [PATCH 0179/5324] drm/i915: Store max lane count in intel_digital_port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than having open coded checks for the DDI A/E configuration, just store the max supported lane count in intel_digital_port. We had an open coded check for DDI A, but not for DDI E. So we may have been vilating the DDI E max lane count. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 10 +--------- drivers/gpu/drm/i915/intel_dp.c | 13 +++++++------ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 6 ++++++ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a69db463557f..1e9d292d4037 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3319,15 +3319,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) return; } - if (WARN(max_lanes == 0, - "No lanes for port %c\n", port_name(port))) - return; - - if (WARN(init_hdmi && max_lanes < 4, - "Not enough lanes (%d) for HDMI on port %c\n", - max_lanes, port_name(port))) - init_hdmi = false; - intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL); if (!intel_dig_port) return; @@ -3351,6 +3342,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); + intel_dig_port->max_lanes = max_lanes; /* * Bspec says that DDI_A_4_LANES is the only supported configuration diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5332eb7657e1..9e02dd789b86 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -157,14 +157,9 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; u8 source_max, sink_max; - source_max = 4; - if (HAS_DDI(dev) && intel_dig_port->port == PORT_A && - (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0) - source_max = 2; - + source_max = intel_dig_port->max_lanes; sink_max = drm_dp_max_lane_count(intel_dp->dpcd); return min(source_max, sink_max); @@ -5839,6 +5834,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, enum port port = intel_dig_port->port; int type, ret; + if (WARN(intel_dig_port->max_lanes < 1, + "Not enough lanes (%d) for DP on port %c\n", + intel_dig_port->max_lanes, port_name(port))) + return false; + intel_dp->pps_pipe = INVALID_PIPE; /* intel_dp vfuncs */ @@ -6037,6 +6037,7 @@ intel_dp_init(struct drm_device *dev, intel_dig_port->port = port; dev_priv->dig_port_map[port] = intel_encoder; intel_dig_port->dp.output_reg = output_reg; + intel_dig_port->max_lanes = 4; intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; if (IS_CHERRYVIEW(dev)) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bdfe4035e074..32de7e478f8f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -845,6 +845,7 @@ struct intel_digital_port { struct intel_hdmi hdmi; enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool); bool release_cl2_override; + uint8_t max_lanes; /* for communication with audio component; protected by av_mutex */ const struct drm_connector *audio_connector; }; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 054aa7613390..d4ed7aa9927e 100755 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2033,6 +2033,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, enum port port = intel_dig_port->port; uint8_t alternate_ddc_pin; + if (WARN(intel_dig_port->max_lanes < 4, + "Not enough lanes (%d) for HDMI on port %c\n", + intel_dig_port->max_lanes, port_name(port))) + return; + drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); @@ -2218,6 +2223,7 @@ void intel_hdmi_init(struct drm_device *dev, dev_priv->dig_port_map[port] = intel_encoder; intel_dig_port->hdmi.hdmi_reg = hdmi_reg; intel_dig_port->dp.output_reg = INVALID_MMIO_REG; + intel_dig_port->max_lanes = 4; intel_hdmi_init_connector(intel_dig_port, intel_connector); } -- GitLab From acee29988e9a22a343728c36954d2ea6f9c0c970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:39 +0200 Subject: [PATCH 0180/5324] drm/i915: Remove pointless 'ddi_translations' local variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit skl_get_buf_trans_*() don't need the 'ddi_translations' local variable since all they with is assign and return. Just return the right thing directly and get rid of the local variable. v2: Resolve conflicts due to KBL Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter (v1) --- drivers/gpu/drm/i915/intel_ddi.c | 44 ++++++++++++-------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1e9d292d4037..b8b4a3103cf1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -348,75 +348,63 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port) return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg); } -static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev, - int *n_entries) +static const struct ddi_buf_trans * +skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries) { - const struct ddi_buf_trans *ddi_translations; - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { - ddi_translations = skl_y_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp); + return skl_y_ddi_translations_dp; } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { - ddi_translations = skl_u_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp); + return skl_u_ddi_translations_dp; } else { - ddi_translations = skl_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_ddi_translations_dp); + return skl_ddi_translations_dp; } - - return ddi_translations; } -static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev, - int *n_entries) +static const struct ddi_buf_trans * +skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries) { struct drm_i915_private *dev_priv = dev->dev_private; - const struct ddi_buf_trans *ddi_translations; if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { if (dev_priv->edp_low_vswing) { - ddi_translations = skl_y_ddi_translations_edp; *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp); + return skl_y_ddi_translations_edp; } else { - ddi_translations = skl_y_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp); + return skl_y_ddi_translations_dp; } } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { if (dev_priv->edp_low_vswing) { - ddi_translations = skl_u_ddi_translations_edp; *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp); + return skl_u_ddi_translations_edp; } else { - ddi_translations = skl_u_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp); + return skl_u_ddi_translations_dp; } } else { if (dev_priv->edp_low_vswing) { - ddi_translations = skl_ddi_translations_edp; *n_entries = ARRAY_SIZE(skl_ddi_translations_edp); + return skl_ddi_translations_edp; } else { - ddi_translations = skl_ddi_translations_dp; *n_entries = ARRAY_SIZE(skl_ddi_translations_dp); + return skl_ddi_translations_dp; } } - - return ddi_translations; } static const struct ddi_buf_trans * -skl_get_buf_trans_hdmi(struct drm_device *dev, - int *n_entries) +skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries) { - const struct ddi_buf_trans *ddi_translations; - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { - ddi_translations = skl_y_ddi_translations_hdmi; *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi); + return skl_y_ddi_translations_hdmi; } else { - ddi_translations = skl_ddi_translations_hdmi; *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); + return skl_ddi_translations_hdmi; } - - return ddi_translations; } /* -- GitLab From cd1101cb271ba6b7cd407ca750a038d89df357a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:40 +0200 Subject: [PATCH 0181/5324] drm/i915: Eliminate duplicated skl_get_buf_trans_dp() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit skl_get_buf_trans_edp() effectively contains another copy of skl_get_buf_trans_dp(). Remove the duplication and just call skl_get_buf_trans_dp() from skl_get_buf_trans_edp(). v2: Resolve conflicts due to KBL Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter (v1) --- drivers/gpu/drm/i915/intel_ddi.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b8b4a3103cf1..9f8b28faa8e2 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -368,31 +368,20 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { - if (dev_priv->edp_low_vswing) { + if (dev_priv->edp_low_vswing) { + if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp); return skl_y_ddi_translations_edp; - } else { - *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp); - return skl_y_ddi_translations_dp; - } - } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { - if (dev_priv->edp_low_vswing) { + } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp); return skl_u_ddi_translations_edp; } else { - *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp); - return skl_u_ddi_translations_dp; - } - } else { - if (dev_priv->edp_low_vswing) { *n_entries = ARRAY_SIZE(skl_ddi_translations_edp); return skl_ddi_translations_edp; - } else { - *n_entries = ARRAY_SIZE(skl_ddi_translations_dp); - return skl_ddi_translations_dp; } } + + return skl_get_buf_trans_dp(dev, n_entries); } static const struct ddi_buf_trans * -- GitLab From 78ab0baea270af82a33c142f7f12bca4cdff6728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:41 +0200 Subject: [PATCH 0182/5324] drm/i915: Pass around dev_priv for ddi buffer programming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the ddi buffer programming code a bit more neat by passing around dev_priv instead of dev. v2: Resolve conflicts due to KBL Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter (v1) --- drivers/gpu/drm/i915/intel_ddi.c | 79 +++++++++++++++----------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9f8b28faa8e2..c47146473471 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -301,8 +301,8 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = { { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */ }; -static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, - enum port port, int type); +static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, + u32 level, enum port port, int type); static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, struct intel_digital_port **dig_port, @@ -349,12 +349,12 @@ intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port) } static const struct ddi_buf_trans * -skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries) +skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) { - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { + if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp); return skl_y_ddi_translations_dp; - } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { + } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) { *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp); return skl_u_ddi_translations_dp; } else { @@ -364,15 +364,13 @@ skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries) } static const struct ddi_buf_trans * -skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries) +skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) { - struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->edp_low_vswing) { - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { + if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp); return skl_y_ddi_translations_edp; - } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) { + } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) { *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp); return skl_u_ddi_translations_edp; } else { @@ -381,13 +379,13 @@ skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries) } } - return skl_get_buf_trans_dp(dev, n_entries); + return skl_get_buf_trans_dp(dev_priv, n_entries); } static const struct ddi_buf_trans * -skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries) +skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) { - if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) { + if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) { *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi); return skl_y_ddi_translations_hdmi; } else { @@ -403,10 +401,9 @@ skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries) * in either FDI or DP modes only, as HDMI connections will work with both * of those */ -static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, - bool supports_hdmi) +static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, + enum port port, bool supports_hdmi) { - struct drm_i915_private *dev_priv = dev->dev_private; u32 iboost_bit = 0; int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, size; @@ -417,28 +414,28 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, const struct ddi_buf_trans *ddi_translations_hdmi; const struct ddi_buf_trans *ddi_translations; - if (IS_BROXTON(dev)) { + if (IS_BROXTON(dev_priv)) { if (!supports_hdmi) return; /* Vswing programming for HDMI */ - bxt_ddi_vswing_sequence(dev, hdmi_level, port, + bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port, INTEL_OUTPUT_HDMI); return; - } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { + } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { ddi_translations_fdi = NULL; ddi_translations_dp = - skl_get_buf_trans_dp(dev, &n_dp_entries); + skl_get_buf_trans_dp(dev_priv, &n_dp_entries); ddi_translations_edp = - skl_get_buf_trans_edp(dev, &n_edp_entries); + skl_get_buf_trans_edp(dev_priv, &n_edp_entries); ddi_translations_hdmi = - skl_get_buf_trans_hdmi(dev, &n_hdmi_entries); + skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); hdmi_default_entry = 8; /* If we're boosting the current, set bit 31 of trans1 */ if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || dev_priv->vbt.ddi_port_info[port].dp_boost_level) iboost_bit = 1<<31; - } else if (IS_BROADWELL(dev)) { + } else if (IS_BROADWELL(dev_priv)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_edp = bdw_ddi_translations_edp; @@ -447,7 +444,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); hdmi_default_entry = 7; - } else if (IS_HASWELL(dev)) { + } else if (IS_HASWELL(dev_priv)) { ddi_translations_fdi = hsw_ddi_translations_fdi; ddi_translations_dp = hsw_ddi_translations_dp; ddi_translations_edp = hsw_ddi_translations_dp; @@ -478,7 +475,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, size = n_dp_entries; break; case PORT_D: - if (intel_dp_is_edp(dev, PORT_D)) { + if (intel_dp_is_edp(dev_priv->dev, PORT_D)) { ddi_translations = ddi_translations_edp; size = n_edp_entries; } else { @@ -545,7 +542,7 @@ void intel_prepare_ddi(struct drm_device *dev) supports_hdmi = intel_dig_port && intel_dig_port_supports_hdmi(intel_dig_port); - intel_prepare_ddi_buffers(dev, port, supports_hdmi); + intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi); visited[port] = true; } } @@ -2062,10 +2059,9 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) TRANS_CLK_SEL_DISABLED); } -static void skl_ddi_set_iboost(struct drm_device *dev, u32 level, - enum port port, int type) +static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv, + u32 level, enum port port, int type) { - struct drm_i915_private *dev_priv = dev->dev_private; const struct ddi_buf_trans *ddi_translations; uint8_t iboost; uint8_t dp_iboost, hdmi_iboost; @@ -2080,21 +2076,21 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level, if (dp_iboost) { iboost = dp_iboost; } else { - ddi_translations = skl_get_buf_trans_dp(dev, &n_entries); + ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries); iboost = ddi_translations[level].i_boost; } } else if (type == INTEL_OUTPUT_EDP) { if (dp_iboost) { iboost = dp_iboost; } else { - ddi_translations = skl_get_buf_trans_edp(dev, &n_entries); + ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries); iboost = ddi_translations[level].i_boost; } } else if (type == INTEL_OUTPUT_HDMI) { if (hdmi_iboost) { iboost = hdmi_iboost; } else { - ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries); + ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries); iboost = ddi_translations[level].i_boost; } } else { @@ -2119,10 +2115,9 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level, I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg); } -static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, - enum port port, int type) +static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, + u32 level, enum port port, int type) { - struct drm_i915_private *dev_priv = dev->dev_private; const struct bxt_ddi_buf_trans *ddi_translations; u32 n_entries, i; uint32_t val; @@ -2237,7 +2232,7 @@ static uint32_t translate_signal_level(int signal_levels) uint32_t ddi_signal_levels(struct intel_dp *intel_dp) { struct intel_digital_port *dport = dp_to_dig_port(intel_dp); - struct drm_device *dev = dport->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); struct intel_encoder *encoder = &dport->base; uint8_t train_set = intel_dp->train_set[0]; int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | @@ -2247,10 +2242,10 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) level = translate_signal_level(signal_levels); - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) - skl_ddi_set_iboost(dev, level, port, encoder->type); - else if (IS_BROXTON(dev)) - bxt_ddi_vswing_sequence(dev, level, port, encoder->type); + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) + skl_ddi_set_iboost(dev_priv, level, port, encoder->type); + else if (IS_BROXTON(dev_priv)) + bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type); return DDI_BUF_TRANS_SELECT(level); } @@ -2333,8 +2328,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) if (IS_BROXTON(dev)) { hdmi_level = dev_priv->vbt. ddi_port_info[port].hdmi_level_shift; - bxt_ddi_vswing_sequence(dev, hdmi_level, port, - INTEL_OUTPUT_HDMI); + bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port, + INTEL_OUTPUT_HDMI); } intel_hdmi->set_infoframes(encoder, crtc->config->has_hdmi_sink, -- GitLab From 10afa0b65fe21cac67e8b19e8b98bde39befc525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:43 +0200 Subject: [PATCH 0183/5324] drm/i915: Reject >9 ddi translation entried if port != A/E on SKL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only DDI A and E support 10 translation entries in DP mode. For the other ports the tenth entry is reserved for HDMI. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1449597590-6971-9-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index c47146473471..3edb10a4f0b4 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -435,6 +435,10 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || dev_priv->vbt.ddi_port_info[port].dp_boost_level) iboost_bit = 1<<31; + + if (WARN_ON(port != PORT_A && + port != PORT_E && n_edp_entries > 9)) + n_edp_entries = 9; } else if (IS_BROADWELL(dev_priv)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; @@ -2084,6 +2088,11 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv, iboost = dp_iboost; } else { ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries); + + if (WARN_ON(port != PORT_A && + port != PORT_E && n_entries > 9)) + n_entries = 9; + iboost = ddi_translations[level].i_boost; } } else if (type == INTEL_OUTPUT_HDMI) { -- GitLab From 6a7e4f99897f31708ff9ea01875d9ff112bebe90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 8 Dec 2015 19:59:44 +0200 Subject: [PATCH 0184/5324] drm/i915: Kill intel_prepare_ddi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the ddi buffer translation programming to occur from the encoder .pre_enable() hook, for just the ddi port we are enabling. Previously we used to reprogram the translations for all ddi ports during init and during power well enabling. v2: s/intel_prepare_ddi_buffers/intel_prepare_ddi_buffer/ (Daniel) Resolve conflicts due to dev_priv->atomic_cdclk_freq Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 1 - drivers/gpu/drm/i915/intel_ddi.c | 99 +++++++------------------ drivers/gpu/drm/i915/intel_display.c | 3 - drivers/gpu/drm/i915/intel_dp_mst.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 12 --- 6 files changed, 31 insertions(+), 88 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9de993d5fed2..f17a2b0c2493 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1077,7 +1077,6 @@ static int bxt_resume_prepare(struct drm_i915_private *dev_priv) */ broxton_init_cdclk(dev); broxton_ddi_phy_init(dev); - intel_prepare_ddi(dev); return 0; } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3edb10a4f0b4..2ed64725470a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -342,12 +342,6 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) return port; } -static bool -intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port) -{ - return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg); -} - static const struct ddi_buf_trans * skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries) { @@ -401,28 +395,34 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) * in either FDI or DP modes only, as HDMI connections will work with both * of those */ -static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, - enum port port, bool supports_hdmi) +void intel_prepare_ddi_buffer(struct intel_encoder *encoder) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 iboost_bit = 0; int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, size; - int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; + int hdmi_level; + enum port port; const struct ddi_buf_trans *ddi_translations_fdi; const struct ddi_buf_trans *ddi_translations_dp; const struct ddi_buf_trans *ddi_translations_edp; const struct ddi_buf_trans *ddi_translations_hdmi; const struct ddi_buf_trans *ddi_translations; + port = intel_ddi_get_encoder_port(encoder); + hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; + if (IS_BROXTON(dev_priv)) { - if (!supports_hdmi) + if (encoder->type != INTEL_OUTPUT_HDMI) return; /* Vswing programming for HDMI */ bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port, INTEL_OUTPUT_HDMI); return; - } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { + } + + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { ddi_translations_fdi = NULL; ddi_translations_dp = skl_get_buf_trans_dp(dev_priv, &n_dp_entries); @@ -468,30 +468,18 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, hdmi_default_entry = 7; } - switch (port) { - case PORT_A: + switch (encoder->type) { + case INTEL_OUTPUT_EDP: ddi_translations = ddi_translations_edp; size = n_edp_entries; break; - case PORT_B: - case PORT_C: + case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_HDMI: ddi_translations = ddi_translations_dp; size = n_dp_entries; break; - case PORT_D: - if (intel_dp_is_edp(dev_priv->dev, PORT_D)) { - ddi_translations = ddi_translations_edp; - size = n_edp_entries; - } else { - ddi_translations = ddi_translations_dp; - size = n_dp_entries; - } - break; - case PORT_E: - if (ddi_translations_fdi) - ddi_translations = ddi_translations_fdi; - else - ddi_translations = ddi_translations_dp; + case INTEL_OUTPUT_ANALOG: + ddi_translations = ddi_translations_fdi; size = n_dp_entries; break; default: @@ -505,7 +493,7 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, ddi_translations[i].trans2); } - if (!supports_hdmi) + if (encoder->type != INTEL_OUTPUT_HDMI) return; /* Choose a good default if VBT is badly populated */ @@ -520,37 +508,6 @@ static void intel_prepare_ddi_buffers(struct drm_i915_private *dev_priv, ddi_translations_hdmi[hdmi_level].trans2); } -/* Program DDI buffers translations for DP. By default, program ports A-D in DP - * mode and port E for FDI. - */ -void intel_prepare_ddi(struct drm_device *dev) -{ - struct intel_encoder *intel_encoder; - bool visited[I915_MAX_PORTS] = { 0, }; - - if (!HAS_DDI(dev)) - return; - - for_each_intel_encoder(dev, intel_encoder) { - struct intel_digital_port *intel_dig_port; - enum port port; - bool supports_hdmi; - - if (intel_encoder->type == INTEL_OUTPUT_DSI) - continue; - - ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port); - if (visited[port]) - continue; - - supports_hdmi = intel_dig_port && - intel_dig_port_supports_hdmi(intel_dig_port); - - intel_prepare_ddi_buffers(to_i915(dev), port, supports_hdmi); - visited[port] = true; - } -} - static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, enum port port) { @@ -579,8 +536,14 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_encoder *encoder; u32 temp, i, rx_ctl_val; + for_each_encoder_on_crtc(dev, crtc, encoder) { + WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); + intel_prepare_ddi_buffer(encoder); + } + /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the * mode set "sequence for CRT port" document: * - TP1 to TP2 time with the default value @@ -2306,12 +2269,12 @@ void intel_ddi_clk_select(struct intel_encoder *encoder, static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; - int hdmi_level; + + intel_prepare_ddi_buffer(intel_encoder); if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -2329,17 +2292,11 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); - if (port != PORT_A || INTEL_INFO(dev)->gen >= 9) + if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9) intel_dp_stop_link_train(intel_dp); } else if (type == INTEL_OUTPUT_HDMI) { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - if (IS_BROXTON(dev)) { - hdmi_level = dev_priv->vbt. - ddi_port_info[port].hdmi_level_shift; - bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port, - INTEL_OUTPUT_HDMI); - } intel_hdmi->set_infoframes(encoder, crtc->config->has_hdmi_sink, &crtc->config->base.adjusted_mode); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 259f2ca57447..20e99a0c5536 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9710,8 +9710,6 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv) val |= PCH_LP_PARTITION_LEVEL_DISABLE; I915_WRITE(SOUTH_DSPCLK_GATE_D, val); } - - intel_prepare_ddi(dev); } static void broxton_modeset_commit_cdclk(struct drm_atomic_state *old_state) @@ -15312,7 +15310,6 @@ void intel_modeset_init_hw(struct drm_device *dev) dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq; - intel_prepare_ddi(dev); intel_init_clock_gating(dev); intel_enable_gt_powersave(dev); } diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 5cb168dc2f0c..6f4762dc5a94 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -184,6 +184,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) intel_mst->port = found->port; if (intel_dp->active_mst_links == 0) { + intel_prepare_ddi_buffer(&intel_dig_port->base); + intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config); intel_dp_set_link_params(intel_dp, intel_crtc->config); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 32de7e478f8f..e27954d2edad 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1025,7 +1025,7 @@ void intel_crt_init(struct drm_device *dev); /* intel_ddi.c */ void intel_ddi_clk_select(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config); -void intel_prepare_ddi(struct drm_device *dev); +void intel_prepare_ddi_buffer(struct intel_encoder *encoder); void hsw_fdi_link_train(struct drm_crtc *crtc); void intel_ddi_init(struct drm_device *dev, enum port port); enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 89a7dd83e91f..bbca527184d0 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -626,7 +626,6 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv) static void skl_set_power_well(struct drm_i915_private *dev_priv, struct i915_power_well *power_well, bool enable) { - struct drm_device *dev = dev_priv->dev; uint32_t tmp, fuse_status; uint32_t req_mask, state_mask; bool is_enabled, enable_requested, check_fuse_status = false; @@ -670,17 +669,6 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, !I915_READ(HSW_PWR_WELL_BIOS), "Invalid for power well status to be enabled, unless done by the BIOS, \ when request is to disable!\n"); - if (power_well->data == SKL_DISP_PW_2) { - /* - * DDI buffer programming unnecessary during - * driver-load/resume as it's already done - * during modeset initialization then. It's - * also invalid here as encoder list is still - * uninitialized. - */ - if (!dev_priv->power_domains.initializing) - intel_prepare_ddi(dev); - } I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); } -- GitLab From 7d3fdfff23852fe458a0d0979a3555fe60f1e563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 11 Jan 2016 20:48:32 +0200 Subject: [PATCH 0185/5324] drm/i915: Cleanup phys status page too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore the lost phys status page cleanup. Fixes the following splat with DMA_API_DEBUG=y: WARNING: CPU: 0 PID: 21615 at ../lib/dma-debug.c:974 dma_debug_device_change+0x190/0x1f0() pci 0000:00:02.0: DMA-API: device driver has pending DMA allocations while released from device [count=1] One of leaked entries details: [device address=0x0000000023163000] [size=4096 bytes] [mapped with DMA_BIDIRECTIONAL] [mapped as coherent] Modules linked in: i915(-) i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm sha256_generic hmac drbg ctr ccm sch_fq_codel binfmt_misc joydev mousedev arc4 ath5k iTCO_wdt mac80211 smsc_ircc2 ath snd_intel8x0m snd_intel8x0 snd_ac97_codec ac97_bus psmouse snd_pcm input_leds i2c_i801 pcspkr snd_timer cfg80211 snd soundcore i2c_core ehci_pci firewire_ohci ehci_hcd firewire_core lpc_ich 8139too rfkill crc_itu_t mfd_core mii usbcore rng_core intel_agp intel_gtt usb_common agpgart irda crc_ccitt fujitsu_laptop led_class parport_pc video parport evdev backlight CPU: 0 PID: 21615 Comm: rmmod Tainted: G U 4.4.0-rc4-mgm-ovl+ #4 Hardware name: FUJITSU SIEMENS LIFEBOOK S6120/FJNB16C, BIOS Version 1.26 05/10/2004 e31a3de0 e31a3de0 e31a3d9c c128d4bd e31a3dd0 c1045a0c c15e00c4 e31a3dfc 0000546f c15dfad2 000003ce c12b3740 000003ce c12b3740 00000000 00000001 f61fb8a0 e31a3de8 c1045a83 00000009 e31a3de0 c15e00c4 e31a3dfc e31a3e4c Call Trace: [] dump_stack+0x16/0x19 [] warn_slowpath_common+0x8c/0xd0 [] ? dma_debug_device_change+0x190/0x1f0 [] ? dma_debug_device_change+0x190/0x1f0 [] warn_slowpath_fmt+0x33/0x40 [] dma_debug_device_change+0x190/0x1f0 [] notifier_call_chain+0x59/0x70 [] __blocking_notifier_call_chain+0x3f/0x80 [] blocking_notifier_call_chain+0x1f/0x30 [] __device_release_driver+0xc3/0xf0 [] driver_detach+0x97/0xa0 [] bus_remove_driver+0x40/0x90 [] driver_unregister+0x28/0x60 [] ? trace_hardirqs_on_caller+0x12c/0x1d0 [] pci_unregister_driver+0x18/0x80 [] drm_pci_exit+0x87/0xb0 [drm] [] i915_exit+0x1b/0x1ee [i915] [] SyS_delete_module+0x14c/0x210 [] ? trace_hardirqs_on_caller+0x12c/0x1d0 [] ? ____fput+0xd/0x10 [] do_fast_syscall_32+0xa4/0x450 [] sysenter_past_esp+0x3b/0x5d ---[ end trace c2ecbc77760f10a0 ]--- Mapped at: [] debug_dma_alloc_coherent+0x33/0x90 [] drm_pci_alloc+0x18c/0x1e0 [drm] [] intel_init_ring_buffer+0x2af/0x490 [i915] [] intel_init_render_ring_buffer+0x130/0x750 [i915] [] i915_gem_init_rings+0x1e/0x110 [i915] v2: s/BUG_ON/WARN_ON/ since dim doens't like the former anymore Cc: Chris Wilson Fixes: 5c6c600 ("drm/i915: Remove DRI1 ring accessors and API") Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson (v1) Link: http://patchwork.freedesktop.org/patch/msgid/1452538112-5331-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 339701d7a9a5..d9e0b400294d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1899,6 +1899,17 @@ i915_dispatch_execbuffer(struct drm_i915_gem_request *req, return 0; } +static void cleanup_phys_status_page(struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ring->dev); + + if (!dev_priv->status_page_dmah) + return; + + drm_pci_free(ring->dev, dev_priv->status_page_dmah); + ring->status_page.page_addr = NULL; +} + static void cleanup_status_page(struct intel_engine_cs *ring) { struct drm_i915_gem_object *obj; @@ -1915,9 +1926,9 @@ static void cleanup_status_page(struct intel_engine_cs *ring) static int init_status_page(struct intel_engine_cs *ring) { - struct drm_i915_gem_object *obj; + struct drm_i915_gem_object *obj = ring->status_page.obj; - if ((obj = ring->status_page.obj) == NULL) { + if (obj == NULL) { unsigned flags; int ret; @@ -2162,7 +2173,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, if (ret) goto error; } else { - BUG_ON(ring->id != RCS); + WARN_ON(ring->id != RCS); ret = init_phys_status_page(ring); if (ret) goto error; @@ -2208,7 +2219,12 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) if (ring->cleanup) ring->cleanup(ring); - cleanup_status_page(ring); + if (I915_NEED_GFX_HWS(ring->dev)) { + cleanup_status_page(ring); + } else { + WARN_ON(ring->id != RCS); + cleanup_phys_status_page(ring); + } i915_cmd_parser_fini_ring(ring); i915_gem_batch_pool_fini(&ring->batch_pool); -- GitLab From b7792d8b54cc0e66b94d625d70761d086cad1dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 14 Dec 2015 18:23:43 +0200 Subject: [PATCH 0186/5324] drm/i915: Wait for pipe to start before sampling vblank timestamps on gen2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use the vblank timestamps to generate the vblank frame counter value on gen2. That means we need the pipe scanout position to be accurate when we call drm_crtc_vblank_on(), otherwise the frame counter guesstimate may jump when the pipe actually start. What I observed on my 85x is that the DSL initially reads 0, and when the pipe actually starts DSL jumps to vblank_start. On gen2 DSL==0 means actually vtotal-1 (see update_scanline_offset()), so if we initially get vtotal-1, and then very quickly vblank_start (or thereabouts), the scanout position will appear to jump backwards by approximately one vblank length. Which means the frame counter guesstimate will also jump backwards. That's no good, so let's make sure the pipe has started before we call drm_crtc_vblank_on(). Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1450110229-30450-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 20e99a0c5536..9c87d5784f1a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2151,6 +2151,17 @@ static void intel_enable_pipe(struct intel_crtc *crtc) I915_WRITE(reg, val | PIPECONF_ENABLE); POSTING_READ(reg); + + /* + * Until the pipe starts DSL will read as 0, which would cause + * an apparent vblank timestamp jump, which messes up also the + * frame count when it's derived from the timestamps. So let's + * wait for the pipe to start properly before we call + * drm_crtc_vblank_on() + */ + if (dev->max_vblank_count == 0 && + wait_for(intel_get_crtc_scanline(crtc) != crtc->scanline_offset, 50)) + DRM_ERROR("pipe %c didn't start\n", pipe_name(pipe)); } /** -- GitLab From 52b69c849ab4a343e696a0e45d557550f15450a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 14 Dec 2015 18:23:46 +0200 Subject: [PATCH 0187/5324] drm/i915: Allow 27 bytes child_dev for VBT <109 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My 85x has VBT version 108 which has a child dev size of 27 bytes. Let's allow that without printing an error. We still want to reject the actual parsin since for that we need the child device size to be at least 33 bytes. So we should still check for that, but let's make it print a debug message only instead of an error. While at it, toss in a BUILD_BUG_ON() to verify our struct old_child_dev_config is in fact 33 bytes. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1450110229-30450-8-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_bios.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 15ba52bd2538..1de16f21121a 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1157,7 +1157,10 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); return; } - if (bdb->version < 195) { + if (bdb->version < 109) { + expected_size = 27; + } else if (bdb->version < 195) { + BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); expected_size = sizeof(struct old_child_dev_config); } else if (bdb->version == 195) { expected_size = 37; @@ -1170,18 +1173,18 @@ parse_device_mapping(struct drm_i915_private *dev_priv, bdb->version, expected_size); } - /* The legacy sized child device config is the minimum we need. */ - if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) { - DRM_ERROR("Child device config size %u is too small.\n", - p_defs->child_dev_size); - return; - } - /* Flag an error for unexpected size, but continue anyway. */ if (p_defs->child_dev_size != expected_size) DRM_ERROR("Unexpected child device config size %u (expected %u for VBT version %u)\n", p_defs->child_dev_size, expected_size, bdb->version); + /* The legacy sized child device config is the minimum we need. */ + if (p_defs->child_dev_size < sizeof(struct old_child_dev_config)) { + DRM_DEBUG_KMS("Child device config size %u is too small.\n", + p_defs->child_dev_size); + return; + } + /* get the block size of general definitions */ block_size = get_blocksize(p_defs); /* get the number of child device */ -- GitLab From 7244f309b0fc6508ec585e723ae92057f5bd5855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 14 Dec 2015 18:23:47 +0200 Subject: [PATCH 0188/5324] drm/i915: Expect child dev size of 22 bytes for VBT < 106 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My 830 has VBT version 105 with child device size of 22 bytes. Let's assume that's correct and adjust our expectations. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1450110229-30450-9-git-send-email-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/intel_bios.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 1de16f21121a..12e2f8b8bf9c 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1157,7 +1157,9 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); return; } - if (bdb->version < 109) { + if (bdb->version < 106) { + expected_size = 22; + } else if (bdb->version < 109) { expected_size = 27; } else if (bdb->version < 195) { BUILD_BUG_ON(sizeof(struct old_child_dev_config) != 33); -- GitLab From 9d611c033beeeb8ea914184675058a3c82933f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 14 Dec 2015 18:23:49 +0200 Subject: [PATCH 0189/5324] drm/i915: Use MI_BATCH_BUFFER_START on 830/845 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MI_BATCH_BUFFER is nasty since it requires that userspace pass in the correct batch length. Let's switch to using MI_BATCH_BUFFER_START instead (like we do on other platforms). Then we don't have to specify the batch length at all, and the CS will instead execute until it sees the MI_BATCH_BUFFER_END. We still need the batch length since we do the CS TLB workaround and copy the batch into the permanently pinned scratch object and execute it from there. But for this we can simply use the batch object length when the user hasn't specified the actual batch length. So specifying the batch length becomes just a way to optimize the batch copy a little bit. We lost batch_len from a bunch of igts (including the quiesce batch) so without this igt is utterly broken on 830/845. Also some igts such as gem_cpu_reloc never specified the batch_len and so didn't work. With MI_BATCH_BUFFER_START we don't have to fix up igt every time someone forgets that 830/845 exist. Cc: Chris Wilson Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1450110229-30450-11-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index dccb517361b3..d469c4779ff5 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1309,6 +1309,9 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, exec_start = params->batch_obj_vm_offset + params->args_batch_start_offset; + if (exec_len == 0) + exec_len = params->batch_obj->base.size; + ret = ring->dispatch_execbuffer(params->request, exec_start, exec_len, params->dispatch_flags); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d9e0b400294d..4060acf0601a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1865,15 +1865,13 @@ i830_dispatch_execbuffer(struct drm_i915_gem_request *req, offset = cs_offset; } - ret = intel_ring_begin(req, 4); + ret = intel_ring_begin(req, 2); if (ret) return ret; - intel_ring_emit(ring, MI_BATCH_BUFFER); + intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT); intel_ring_emit(ring, offset | (dispatch_flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); - intel_ring_emit(ring, offset + len - 8); - intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); return 0; -- GitLab From ceccad59100e2b8fa6b2ba38351ba5e730324f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 17:28:16 +0200 Subject: [PATCH 0190/5324] drm/i915: Only complain about n_edp_entries with eDP ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 10afa0b65fe2 ("drm/i915: Reject >9 ddi translation entried if port != A/E on SKL") added sanity checks to make sure we don't end up with too many ddi translation values for eDP ports, but it actually failed to check if the port is eDP. We still look up the edp translations for non-eDP ports, but don't use them, so we shouldn't be complaining about them either. Fixes: 10afa0b65fe2 ("drm/i915: Reject >9 ddi translation entried if port != A/E on SKL") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452612496-9201-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 2ed64725470a..25d9e5ccdebd 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -436,8 +436,9 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) dev_priv->vbt.ddi_port_info[port].dp_boost_level) iboost_bit = 1<<31; - if (WARN_ON(port != PORT_A && - port != PORT_E && n_edp_entries > 9)) + if (WARN_ON(encoder->type == INTEL_OUTPUT_EDP && + port != PORT_A && port != PORT_E && + n_edp_entries > 9)) n_edp_entries = 9; } else if (IS_BROADWELL(dev_priv)) { ddi_translations_fdi = bdw_ddi_translations_fdi; -- GitLab From 0cd1262de7b7509bbbcd650a9918e8895dee6d73 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 12 Jan 2016 07:13:37 -0800 Subject: [PATCH 0191/5324] drm/i915: Handle error paths during watermark sanitization properly (v3) sanitize_watermarks() does not properly handle errors returned by drm_atomic_helper_duplicate_state(). Make failures drop locks before returning. We also change the lock of connection_mutex to a drm_modeset_lock_all_ctx() to make sure any EDEADLK's are handled earlier. v2: Change call to lock connetion_mutex with a call to drm_modeset_lock_all_ctx(). This ensures that any lock contention is handled earlier and drm_atomic_helper_duplicate_state() won't return EDEADLK. (Maarten) v3: Drop locks properly in more error paths. (Maarten) Cc: Daniel Vetter Cc: Maarten Lankhorst Signed-off-by: Matt Roper Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1452611617-32144-1-git-send-email-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/intel_display.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9c87d5784f1a..3b79981735c8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15355,17 +15355,17 @@ static void sanitize_watermarks(struct drm_device *dev) */ drm_modeset_acquire_init(&ctx, 0); retry: - ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); + ret = drm_modeset_lock_all_ctx(dev, &ctx); if (ret == -EDEADLK) { drm_modeset_backoff(&ctx); goto retry; } else if (WARN_ON(ret)) { - return; + goto fail; } state = drm_atomic_helper_duplicate_state(dev, &ctx); if (WARN_ON(IS_ERR(state))) - return; + goto fail; /* * Hardware readout is the only time we don't want to calculate @@ -15388,7 +15388,7 @@ static void sanitize_watermarks(struct drm_device *dev) * BIOS-programmed watermarks untouched and hope for the best. */ WARN(true, "Could not determine valid watermarks for inherited state\n"); - return; + goto fail; } /* Write calculated watermark values back */ @@ -15401,6 +15401,7 @@ static void sanitize_watermarks(struct drm_device *dev) } drm_atomic_state_free(state); +fail: drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); } -- GitLab From 1892faa9ec5d51b07d646cbd5597cd30e049aa51 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Mon, 11 Jan 2016 11:39:27 +0000 Subject: [PATCH 0192/5324] drm/i915/gen9: Set PIN_ZONE_4G end to 4GB - 1 page Kernel and userspace are able to handle 4GB (1<<32) address space range, but "A32 Stateless Model" is not. According to documentation, A32 accesses are based on General State Base Address and bound checking is in place. Because size field (instruction State Base Address) limitation, it is not possible to address full 4GB memory region. A32 Stateless Model is used by some libraries and without this patch, the last page of 4GB address space is not accessible in 32bit processes. Reported-by: Artur Harasimiuk Signed-off-by: Michel Thierry Link: http://patchwork.freedesktop.org/patch/msgid/1452512367-23614-1-git-send-email-michel.thierry@intel.com Cc: drm-intel-fixes@lists.freedesktop.org Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d8efc9dfbc48..2c24ff394b2a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3484,7 +3484,7 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, if (flags & PIN_MAPPABLE) end = min_t(u64, end, dev_priv->gtt.mappable_end); if (flags & PIN_ZONE_4G) - end = min_t(u64, end, (1ULL << 32)); + end = min_t(u64, end, (1ULL << 32) - PAGE_SIZE); if (alignment == 0) alignment = flags & PIN_MAPPABLE ? fence_alignment : -- GitLab From e32192e1ae9884200ee340e7c839bf24f4f1f928 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 12 Jan 2016 16:04:06 +0000 Subject: [PATCH 0193/5324] drm/i915/gen8: Tidy display interrupt processing One bugfix and a few tidy-ups: * Pipe fault logging was broken on Gen9+. * Removed some unnecessary local variables. * Removed unnecessary initializers. * Decreased pipe iir block indentation level. * Grouped variable initialization close to use sites. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452614647-13973-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 131 ++++++++++++++++---------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f04d799153ca..7972ceee6096 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2268,11 +2268,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_i915_private *dev_priv = dev->dev_private; - u32 master_ctl; + u32 master_ctl, iir; irqreturn_t ret = IRQ_NONE; - uint32_t tmp = 0; enum pipe pipe; - u32 aux_mask = GEN8_AUX_CHANNEL_A; if (!intel_irqs_enabled(dev_priv)) return IRQ_NONE; @@ -2280,10 +2278,6 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ disable_rpm_wakeref_asserts(dev_priv); - if (INTEL_INFO(dev_priv)->gen >= 9) - aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | - GEN9_AUX_CHANNEL_D; - master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; if (!master_ctl) @@ -2296,11 +2290,11 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) ret = gen8_gt_irq_handler(dev_priv, master_ctl); if (master_ctl & GEN8_DE_MISC_IRQ) { - tmp = I915_READ(GEN8_DE_MISC_IIR); - if (tmp) { - I915_WRITE(GEN8_DE_MISC_IIR, tmp); + iir = I915_READ(GEN8_DE_MISC_IIR); + if (iir) { + I915_WRITE(GEN8_DE_MISC_IIR, iir); ret = IRQ_HANDLED; - if (tmp & GEN8_DE_MISC_GSE) + if (iir & GEN8_DE_MISC_GSE) intel_opregion_asle_intr(dev); else DRM_ERROR("Unexpected DE Misc interrupt\n"); @@ -2310,33 +2304,40 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) } if (master_ctl & GEN8_DE_PORT_IRQ) { - tmp = I915_READ(GEN8_DE_PORT_IIR); - if (tmp) { + iir = I915_READ(GEN8_DE_PORT_IIR); + if (iir) { + u32 tmp_mask; bool found = false; - u32 hotplug_trigger = 0; - - if (IS_BROXTON(dev_priv)) - hotplug_trigger = tmp & BXT_DE_PORT_HOTPLUG_MASK; - else if (IS_BROADWELL(dev_priv)) - hotplug_trigger = tmp & GEN8_PORT_DP_A_HOTPLUG; - I915_WRITE(GEN8_DE_PORT_IIR, tmp); + I915_WRITE(GEN8_DE_PORT_IIR, iir); ret = IRQ_HANDLED; - if (tmp & aux_mask) { + tmp_mask = GEN8_AUX_CHANNEL_A; + if (INTEL_INFO(dev_priv)->gen >= 9) + tmp_mask |= GEN9_AUX_CHANNEL_B | + GEN9_AUX_CHANNEL_C | + GEN9_AUX_CHANNEL_D; + + if (iir & tmp_mask) { dp_aux_irq_handler(dev); found = true; } - if (hotplug_trigger) { - if (IS_BROXTON(dev)) - bxt_hpd_irq_handler(dev, hotplug_trigger, hpd_bxt); - else - ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_bdw); - found = true; + if (IS_BROXTON(dev_priv)) { + tmp_mask = iir & BXT_DE_PORT_HOTPLUG_MASK; + if (tmp_mask) { + bxt_hpd_irq_handler(dev, tmp_mask, hpd_bxt); + found = true; + } + } else if (IS_BROADWELL(dev_priv)) { + tmp_mask = iir & GEN8_PORT_DP_A_HOTPLUG; + if (tmp_mask) { + ilk_hpd_irq_handler(dev, tmp_mask, hpd_bdw); + found = true; + } } - if (IS_BROXTON(dev) && (tmp & BXT_DE_PORT_GMBUS)) { + if (IS_BROXTON(dev) && (iir & BXT_DE_PORT_GMBUS)) { gmbus_irq_handler(dev); found = true; } @@ -2349,49 +2350,51 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) } for_each_pipe(dev_priv, pipe) { - uint32_t pipe_iir, flip_done = 0, fault_errors = 0; + u32 flip_done, fault_errors; if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) continue; - pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); - if (pipe_iir) { - ret = IRQ_HANDLED; - I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); + iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); + if (!iir) { + DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); + continue; + } - if (pipe_iir & GEN8_PIPE_VBLANK && - intel_pipe_handle_vblank(dev, pipe)) - intel_check_page_flip(dev, pipe); + ret = IRQ_HANDLED; + I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir); - if (INTEL_INFO(dev_priv)->gen >= 9) - flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE; - else - flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE; + if (iir & GEN8_PIPE_VBLANK && + intel_pipe_handle_vblank(dev, pipe)) + intel_check_page_flip(dev, pipe); - if (flip_done) { - intel_prepare_page_flip(dev, pipe); - intel_finish_page_flip_plane(dev, pipe); - } + flip_done = iir; + if (INTEL_INFO(dev_priv)->gen >= 9) + flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE; + else + flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE; - if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) - hsw_pipe_crc_irq_handler(dev, pipe); + if (flip_done) { + intel_prepare_page_flip(dev, pipe); + intel_finish_page_flip_plane(dev, pipe); + } - if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) - intel_cpu_fifo_underrun_irq_handler(dev_priv, - pipe); + if (iir & GEN8_PIPE_CDCLK_CRC_DONE) + hsw_pipe_crc_irq_handler(dev, pipe); + if (iir & GEN8_PIPE_FIFO_UNDERRUN) + intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); - if (INTEL_INFO(dev_priv)->gen >= 9) - fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS; - else - fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS; + fault_errors = iir; + if (INTEL_INFO(dev_priv)->gen >= 9) + fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; + else + fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; - if (fault_errors) - DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", - pipe_name(pipe), - pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS); - } else - DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); + if (fault_errors) + DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", + pipe_name(pipe), + fault_errors); } if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) && @@ -2401,15 +2404,15 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) * scheme also closed the SDE interrupt handling race we've seen * on older pch-split platforms. But this needs testing. */ - u32 pch_iir = I915_READ(SDEIIR); - if (pch_iir) { - I915_WRITE(SDEIIR, pch_iir); + iir = I915_READ(SDEIIR); + if (iir) { + I915_WRITE(SDEIIR, iir); ret = IRQ_HANDLED; if (HAS_PCH_SPT(dev_priv)) - spt_irq_handler(dev, pch_iir); + spt_irq_handler(dev, iir); else - cpt_irq_handler(dev, pch_iir); + cpt_irq_handler(dev, iir); } else { /* * Like on previous PCH there seems to be something -- GitLab From f11a0f46a2c32207a47322610ae4b214b5bab23e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 12 Jan 2016 16:04:07 +0000 Subject: [PATCH 0194/5324] drm/i915/gen8: Factor out display interrupt handling Tidy quite long interrupt service routine by factoring out the display part. This simplifies the exit path a little bit, makes the code a bit more readable, and potentialy makes code reuse in the future easier. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452614647-13973-2-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 53 +++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7972ceee6096..25a89373df63 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2264,31 +2264,14 @@ static void bxt_hpd_irq_handler(struct drm_device *dev, u32 hotplug_trigger, intel_hpd_irq_handler(dev, pin_mask, long_mask); } -static irqreturn_t gen8_irq_handler(int irq, void *arg) +static irqreturn_t +gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) { - struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 master_ctl, iir; + struct drm_device *dev = dev_priv->dev; irqreturn_t ret = IRQ_NONE; + u32 iir; enum pipe pipe; - if (!intel_irqs_enabled(dev_priv)) - return IRQ_NONE; - - /* IRQs are synced during runtime_suspend, we don't require a wakeref */ - disable_rpm_wakeref_asserts(dev_priv); - - master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); - master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; - if (!master_ctl) - goto out; - - I915_WRITE_FW(GEN8_MASTER_IRQ, 0); - - /* Find, clear, then process each source of interrupt */ - - ret = gen8_gt_irq_handler(dev_priv, master_ctl); - if (master_ctl & GEN8_DE_MISC_IRQ) { iir = I915_READ(GEN8_DE_MISC_IIR); if (iir) { @@ -2422,10 +2405,36 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) } } + return ret; +} + +static irqreturn_t gen8_irq_handler(int irq, void *arg) +{ + struct drm_device *dev = arg; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 master_ctl; + irqreturn_t ret; + + if (!intel_irqs_enabled(dev_priv)) + return IRQ_NONE; + + master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); + master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; + if (!master_ctl) + return IRQ_NONE; + + I915_WRITE_FW(GEN8_MASTER_IRQ, 0); + + /* IRQs are synced during runtime_suspend, we don't require a wakeref */ + disable_rpm_wakeref_asserts(dev_priv); + + /* Find, clear, then process each source of interrupt */ + ret = gen8_gt_irq_handler(dev_priv, master_ctl); + ret |= gen8_de_irq_handler(dev_priv, master_ctl); + I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); POSTING_READ_FW(GEN8_MASTER_IRQ); -out: enable_rpm_wakeref_asserts(dev_priv); return ret; -- GitLab From c9cacf9349ae4ce516627dac931766bfe98df793 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 12 Jan 2016 17:32:34 +0000 Subject: [PATCH 0195/5324] drm/i915: Extract vfunc setup from logical ring initializers Majority of them was duplicated code and only render ring currently overrides some of them. We can save some lines of code and also take away the confusion on why bsd2 did not do the seqno coherency workaround. (VCS2 ring does not exist on platforms where workaround is needed but that was not documented in the code.) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452619956-27014-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 88 +++++++++++--------------------- 1 file changed, 29 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ab344e0b878c..e29cf1c73745 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1942,7 +1942,28 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) ring->dev = NULL; } -static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) +static void +logical_ring_default_vfuncs(struct drm_device *dev, + struct intel_engine_cs *ring) +{ + /* Default vfuncs which can be overriden by each engine. */ + ring->init_hw = gen8_init_common_ring; + ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; + if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { + ring->get_seqno = bxt_a_get_seqno; + ring->set_seqno = bxt_a_set_seqno; + } else { + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; + } +} + +static int +logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) { int ret; @@ -2003,24 +2024,16 @@ static int logical_render_ring_init(struct drm_device *dev) if (HAS_L3_DPF(dev)) ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + logical_ring_default_vfuncs(dev, ring); + + /* Override some for render ring. */ if (INTEL_INFO(dev)->gen >= 9) ring->init_hw = gen9_init_render_ring; else ring->init_hw = gen8_init_render_ring; ring->init_context = gen8_init_rcs_context; ring->cleanup = intel_fini_pipe_control; - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ring->get_seqno = bxt_a_get_seqno; - ring->set_seqno = bxt_a_set_seqno; - } else { - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; - } - ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush_render; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; ring->dev = dev; @@ -2060,19 +2073,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - ring->init_hw = gen8_init_common_ring; - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ring->get_seqno = bxt_a_get_seqno; - ring->set_seqno = bxt_a_set_seqno; - } else { - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; - } - ring->emit_request = gen8_emit_request; - ring->emit_flush = gen8_emit_flush; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; + logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); } @@ -2090,14 +2091,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - ring->init_hw = gen8_init_common_ring; - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; - ring->emit_request = gen8_emit_request; - ring->emit_flush = gen8_emit_flush; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; + logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); } @@ -2115,19 +2109,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - ring->init_hw = gen8_init_common_ring; - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ring->get_seqno = bxt_a_get_seqno; - ring->set_seqno = bxt_a_set_seqno; - } else { - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; - } - ring->emit_request = gen8_emit_request; - ring->emit_flush = gen8_emit_flush; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; + logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); } @@ -2145,19 +2127,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - ring->init_hw = gen8_init_common_ring; - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { - ring->get_seqno = bxt_a_get_seqno; - ring->set_seqno = bxt_a_set_seqno; - } else { - ring->get_seqno = gen8_get_seqno; - ring->set_seqno = gen8_set_seqno; - } - ring->emit_request = gen8_emit_request; - ring->emit_flush = gen8_emit_flush; - ring->irq_get = gen8_logical_ring_get_irq; - ring->irq_put = gen8_logical_ring_put_irq; - ring->emit_bb_start = gen8_emit_bb_start; + logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); } -- GitLab From d9f3af96c2426bbe5b71b8875ee0ce3a01065c33 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 12 Jan 2016 17:32:35 +0000 Subject: [PATCH 0196/5324] drm/i915: Compact logical ring interrupt initialization Identically to vfuncs interrupt mask initialization can also be compacted for more readable code. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452619956-27014-2-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 33 +++++++++++++------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e29cf1c73745..4a6ba0a4aa3d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1962,6 +1962,13 @@ logical_ring_default_vfuncs(struct drm_device *dev, } } +static inline void +logical_ring_default_irqs(struct intel_engine_cs *ring, unsigned shift) +{ + ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; + ring->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; +} + static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) { @@ -2017,10 +2024,8 @@ static int logical_render_ring_init(struct drm_device *dev) ring->name = "render ring"; ring->id = RCS; ring->mmio_base = RENDER_RING_BASE; - ring->irq_enable_mask = - GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT; - ring->irq_keep_mask = - GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT; + + logical_ring_default_irqs(ring, GEN8_RCS_IRQ_SHIFT); if (HAS_L3_DPF(dev)) ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; @@ -2068,11 +2073,8 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->name = "bsd ring"; ring->id = VCS; ring->mmio_base = GEN6_BSD_RING_BASE; - ring->irq_enable_mask = - GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - ring->irq_keep_mask = - GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; + logical_ring_default_irqs(ring, GEN8_VCS1_IRQ_SHIFT); logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); @@ -2086,11 +2088,8 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->name = "bds2 ring"; ring->id = VCS2; ring->mmio_base = GEN8_BSD2_RING_BASE; - ring->irq_enable_mask = - GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - ring->irq_keep_mask = - GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; + logical_ring_default_irqs(ring, GEN8_VCS2_IRQ_SHIFT); logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); @@ -2104,11 +2103,8 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->name = "blitter ring"; ring->id = BCS; ring->mmio_base = BLT_RING_BASE; - ring->irq_enable_mask = - GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - ring->irq_keep_mask = - GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + logical_ring_default_irqs(ring, GEN8_BCS_IRQ_SHIFT); logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); @@ -2122,11 +2118,8 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->name = "video enhancement ring"; ring->id = VECS; ring->mmio_base = VEBOX_RING_BASE; - ring->irq_enable_mask = - GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - ring->irq_keep_mask = - GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT; + logical_ring_default_irqs(ring, GEN8_VECS_IRQ_SHIFT); logical_ring_default_vfuncs(dev, ring); return logical_ring_init(dev, ring); -- GitLab From ec8a9776cc5c98decbc905c9fa4a885564b7a7c3 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 12 Jan 2016 17:32:36 +0000 Subject: [PATCH 0197/5324] drm/i915: Fix bsd2 ring name Chris Wilson noticed the "bds2" typo. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452619956-27014-3-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4a6ba0a4aa3d..5027699c5291 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2085,7 +2085,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; - ring->name = "bds2 ring"; + ring->name = "bsd2 ring"; ring->id = VCS2; ring->mmio_base = GEN8_BSD2_RING_BASE; -- GitLab From 657fb5fbadb3ef286ababaf6809d5594767d8063 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 13 Jan 2016 22:48:40 +0800 Subject: [PATCH 0198/5324] drm/i915: use kobj_to_dev() Use kobj_to_dev() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/f5db8b56cd177972c901d01aa87ba763735438a9.1452696179.git.geliangtang@163.com --- drivers/gpu/drm/i915/i915_sysfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 37e3f0ddf8e0..c6188dddb341 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -164,7 +164,7 @@ i915_l3_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct drm_minor *dminor = dev_to_drm_minor(dev); struct drm_device *drm_dev = dminor->dev; struct drm_i915_private *dev_priv = drm_dev->dev_private; @@ -200,7 +200,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct drm_minor *dminor = dev_to_drm_minor(dev); struct drm_device *drm_dev = dminor->dev; struct drm_i915_private *dev_priv = drm_dev->dev_private; @@ -521,7 +521,7 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj, loff_t off, size_t count) { - struct device *kdev = container_of(kobj, struct device, kobj); + struct device *kdev = kobj_to_dev(kobj); struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; struct i915_error_state_file_priv error_priv; @@ -556,7 +556,7 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { - struct device *kdev = container_of(kobj, struct device, kobj); + struct device *kdev = kobj_to_dev(kobj); struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; int ret; -- GitLab From b3ae4755f561cffd23192cd1fb9648649aa7405e Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 11:18:12 -0500 Subject: [PATCH 0199/5324] Orangefs: implement .write_iter Until now, orangefs_devreq_write_iter has just been a wrapper for the old-fashioned orangefs_devreq_writev... linux would call .write_iter with "struct kiocb *iocb" and "struct iov_iter *iter" and .write_iter would just: return pvfs2_devreq_writev(iocb->ki_filp, iter->iov, iter->nr_segs, &iocb->ki_pos); Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 462 +++++++++++++++------------------- 1 file changed, 199 insertions(+), 263 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index e3bb15e344ed..0f01d3edfc2b 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -245,304 +245,240 @@ static ssize_t orangefs_devreq_read(struct file *file, } /* - * Function for writev() callers into the device. Readdir related - * operations have an extra iovec containing info about objects - * contained in directories. + * Function for writev() callers into the device. + * + * Userspace should have written: + * - __u32 version + * - __u32 magic + * - __u64 tag + * - struct orangefs_downcall_s + * - trailer buffer (in the case of READDIR operations) */ -static ssize_t orangefs_devreq_writev(struct file *file, - const struct iovec *iov, - size_t count, - loff_t *offset) +static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, + struct iov_iter *iter) { + ssize_t ret; struct orangefs_kernel_op_s *op = NULL; - void *buffer = NULL; - void *ptr = NULL; - unsigned long i = 0; - int num_remaining = MAX_DEV_REQ_DOWNSIZE; - int ret = 0; - /* num elements in iovec without trailer */ - int notrailer_count = 4; - /* - * If there's a trailer, its iov index will be equal to - * notrailer_count. - */ - int trailer_index = notrailer_count; - int payload_size = 0; - int returned_downcall_size = 0; - __s32 magic = 0; - __s32 proto_ver = 0; - __u64 tag = 0; - ssize_t total_returned_size = 0; + struct { + __u32 version; + __u32 magic; + __u64 tag; + } head; + int total = ret = iov_iter_count(iter); + int n; + int downcall_size = sizeof(struct orangefs_downcall_s); + int head_size = sizeof(head); + + gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n", + __func__, + total, + ret); - /* - * There will always be at least notrailer_count iovecs, and - * when there's a trailer, one more than notrailer_count. Check - * count's sanity. - */ - if (count != notrailer_count && count != (notrailer_count + 1)) { - gossip_err("%s: count:%zu: notrailer_count :%d:\n", - __func__, - count, - notrailer_count); - return -EPROTO; + if (total < MAX_DEV_REQ_DOWNSIZE) { + gossip_err("%s: total:%d: must be at least:%lu:\n", + __func__, + total, + MAX_DEV_REQ_DOWNSIZE); + ret = -EFAULT; + goto out; } - - - /* Copy the non-trailer iovec data into a device request buffer. */ - buffer = dev_req_alloc(); - if (!buffer) { - gossip_err("%s: dev_req_alloc failed.\n", __func__); - return -ENOMEM; + + n = copy_from_iter(&head, head_size, iter); + if (n < head_size) { + gossip_err("%s: failed to copy head.\n", __func__); + ret = -EFAULT; + goto out; } - ptr = buffer; - for (i = 0; i < notrailer_count; i++) { - if (iov[i].iov_len > num_remaining) { - gossip_err - ("writev error: Freeing buffer and returning\n"); - dev_req_release(buffer); - return -EMSGSIZE; - } - ret = copy_from_user(ptr, iov[i].iov_base, iov[i].iov_len); - if (ret) { - gossip_err("Failed to copy data from user space\n"); - dev_req_release(buffer); - return -EIO; - } - num_remaining -= iov[i].iov_len; - ptr += iov[i].iov_len; - payload_size += iov[i].iov_len; + + if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) { + gossip_err("%s: userspace claims version" + "%d, minimum version required: %d.\n", + __func__, + head.version, + ORANGEFS_MINIMUM_USERSPACE_VERSION); + ret = -EPROTO; + goto out; } - total_returned_size = payload_size; - /* these elements are currently 8 byte aligned (8 bytes for (version + - * magic) 8 bytes for tag). If you add another element, either - * make it 8 bytes big, or use get_unaligned when asigning. - */ - ptr = buffer; - proto_ver = *((__s32 *) ptr); /* unused */ - ptr += sizeof(__s32); + if (head.magic != ORANGEFS_DEVREQ_MAGIC) { + gossip_err("Error: Device magic number does not match.\n"); + ret = -EPROTO; + goto out; + } - magic = *((__s32 *) ptr); - ptr += sizeof(__s32); + op = orangefs_devreq_remove_op(head.tag); + if (!op) { + gossip_err("WARNING: No one's waiting for tag %llu\n", + llu(head.tag)); + goto out; + } - tag = *((__u64 *) ptr); - ptr += sizeof(__u64); + get_op(op); /* increase ref count. */ - if (magic != ORANGEFS_DEVREQ_MAGIC) { - gossip_err("Error: Device magic number does not match.\n"); - dev_req_release(buffer); - return -EPROTO; + n = copy_from_iter(&op->downcall, downcall_size, iter); + if (n != downcall_size) { + gossip_err("%s: failed to copy downcall.\n", __func__); + put_op(op); + ret = -EFAULT; + goto out; } - op = orangefs_devreq_remove_op(tag); - if (op) { - /* Increase ref count! */ - get_op(op); - - /* calculate the size of the returned downcall. */ - returned_downcall_size = - payload_size - (2 * sizeof(__s32) + sizeof(__u64)); - - /* copy the passed in downcall into the op */ - if (returned_downcall_size == - sizeof(struct orangefs_downcall_s)) { - memcpy(&op->downcall, - ptr, - sizeof(struct orangefs_downcall_s)); - } else { - gossip_err("%s: returned downcall size:%d: \n", - __func__, - returned_downcall_size); - dev_req_release(buffer); - put_op(op); - return -EMSGSIZE; - } + if (op->downcall.status) + goto wakeup; - /* Don't tolerate an unexpected trailer iovec. */ - if ((op->downcall.trailer_size == 0) && - (count != notrailer_count)) { - gossip_err("%s: unexpected trailer iovec.\n", - __func__); - dev_req_release(buffer); - put_op(op); - return -EPROTO; - } + /* + * We've successfully peeled off the head and the downcall. + * Something has gone awry if total doesn't equal the + * sum of head_size, downcall_size and trailer_size. + */ + if ((head_size + downcall_size + op->downcall.trailer_size) != total) { + gossip_err("%s: funky write, head_size:%d" + ": downcall_size:%d: trailer_size:%lld" + ": total size:%d:\n", + __func__, + head_size, + downcall_size, + op->downcall.trailer_size, + total); + put_op(op); + ret = -EFAULT; + goto out; + } - /* Don't consider the trailer if there's a bad status. */ - if (op->downcall.status != 0) - goto no_trailer; + /* Only READDIR operations should have trailers. */ + if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) && + (op->downcall.trailer_size != 0)) { + gossip_err("%s: %x operation with trailer.", + __func__, + op->downcall.type); + put_op(op); + ret = -EFAULT; + goto out; + } - /* get the trailer if there is one. */ - if (op->downcall.trailer_size == 0) - goto no_trailer; + /* READDIR operations should always have trailers. */ + if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) && + (op->downcall.trailer_size == 0)) { + gossip_err("%s: %x operation with no trailer.", + __func__, + op->downcall.type); + put_op(op); + ret = -EFAULT; + goto out; + } - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: op->downcall.trailer_size %lld\n", - __func__, - op->downcall.trailer_size); + if (op->downcall.type != ORANGEFS_VFS_OP_READDIR) + goto wakeup; - /* - * Bail if we think think there should be a trailer, but - * there's no iovec for it. - */ - if (count != (notrailer_count + 1)) { - gossip_err("%s: trailer_size:%lld: count:%zu:\n", - __func__, - op->downcall.trailer_size, - count); - dev_req_release(buffer); - put_op(op); - return -EPROTO; - } + op->downcall.trailer_buf = + vmalloc(op->downcall.trailer_size); + if (op->downcall.trailer_buf == NULL) { + gossip_err("%s: failed trailer vmalloc.\n", + __func__); + put_op(op); + ret = -ENOMEM; + goto out; + } + memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size); + n = copy_from_iter(op->downcall.trailer_buf, + op->downcall.trailer_size, + iter); + if (n != op->downcall.trailer_size) { + gossip_err("%s: failed to copy trailer.\n", __func__); + vfree(op->downcall.trailer_buf); + put_op(op); + ret = -EFAULT; + goto out; + } - /* Verify that trailer_size is accurate. */ - if (op->downcall.trailer_size != iov[trailer_index].iov_len) { - gossip_err("%s: trailer_size:%lld: != iov_len:%zd:\n", - __func__, - op->downcall.trailer_size, - iov[trailer_index].iov_len); - dev_req_release(buffer); - put_op(op); - return -EMSGSIZE; - } +wakeup: - total_returned_size += iov[trailer_index].iov_len; + /* + * If this operation is an I/O operation we need to wait + * for all data to be copied before we can return to avoid + * buffer corruption and races that can pull the buffers + * out from under us. + * + * Essentially we're synchronizing with other parts of the + * vfs implicitly by not allowing the user space + * application reading/writing this device to return until + * the buffers are done being used. + */ + if (op->downcall.type == ORANGEFS_VFS_OP_FILE_IO) { + int timed_out = 0; + DEFINE_WAIT(wait_entry); /* - * Allocate a buffer, copy the trailer bytes into it and - * attach it to the downcall. + * tell the vfs op waiting on a waitqueue + * that this op is done */ - op->downcall.trailer_buf = vmalloc(iov[trailer_index].iov_len); - if (op->downcall.trailer_buf != NULL) { - gossip_debug(GOSSIP_DEV_DEBUG, "vmalloc: %p\n", - op->downcall.trailer_buf); - ret = copy_from_user(op->downcall.trailer_buf, - iov[trailer_index].iov_base, - iov[trailer_index].iov_len); - if (ret) { - gossip_err("%s: Failed to copy trailer.\n", - __func__); - dev_req_release(buffer); - gossip_debug(GOSSIP_DEV_DEBUG, - "vfree: %p\n", - op->downcall.trailer_buf); - vfree(op->downcall.trailer_buf); - op->downcall.trailer_buf = NULL; - put_op(op); - return -EIO; - } - } else { - gossip_err("writev: could not vmalloc for trailer!\n"); - dev_req_release(buffer); - put_op(op); - return -ENOMEM; - } + spin_lock(&op->lock); + set_op_state_serviced(op); + spin_unlock(&op->lock); -no_trailer: - - /* if this operation is an I/O operation we need to wait - * for all data to be copied before we can return to avoid - * buffer corruption and races that can pull the buffers - * out from under us. - * - * Essentially we're synchronizing with other parts of the - * vfs implicitly by not allowing the user space - * application reading/writing this device to return until - * the buffers are done being used. - */ - if (op->upcall.type == ORANGEFS_VFS_OP_FILE_IO) { - int timed_out = 0; - DEFINE_WAIT(wait_entry); + wake_up_interruptible(&op->waitq); - /* - * tell the vfs op waiting on a waitqueue - * that this op is done - */ + while (1) { spin_lock(&op->lock); - set_op_state_serviced(op); - spin_unlock(&op->lock); - - wake_up_interruptible(&op->waitq); - - while (1) { - spin_lock(&op->lock); - prepare_to_wait_exclusive( - &op->io_completion_waitq, - &wait_entry, - TASK_INTERRUPTIBLE); - if (op->io_completed) { - spin_unlock(&op->lock); - break; - } + prepare_to_wait_exclusive( + &op->io_completion_waitq, + &wait_entry, + TASK_INTERRUPTIBLE); + if (op->io_completed) { spin_unlock(&op->lock); - - if (!signal_pending(current)) { - int timeout = - MSECS_TO_JIFFIES(1000 * - op_timeout_secs); - if (!schedule_timeout(timeout)) { - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: timed out.\n", - __func__); - timed_out = 1; - break; - } - continue; - } - - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: signal on I/O wait, aborting\n", - __func__); break; } - - spin_lock(&op->lock); - finish_wait(&op->io_completion_waitq, &wait_entry); spin_unlock(&op->lock); - /* NOTE: for I/O operations we handle releasing the op - * object except in the case of timeout. the reason we - * can't free the op in timeout cases is that the op - * service logic in the vfs retries operations using - * the same op ptr, thus it can't be freed. - */ - if (!timed_out) - op_release(op); - } else { + if (!signal_pending(current)) { + int timeout = + MSECS_TO_JIFFIES(1000 * + op_timeout_secs); + if (!schedule_timeout(timeout)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: timed out.\n", + __func__); + timed_out = 1; + break; + } + continue; + } - /* - * tell the vfs op waiting on a waitqueue that - * this op is done - */ - spin_lock(&op->lock); - set_op_state_serviced(op); - spin_unlock(&op->lock); - /* - * for every other operation (i.e. non-I/O), we need to - * wake up the callers for downcall completion - * notification - */ - wake_up_interruptible(&op->waitq); + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: signal on I/O wait, aborting\n", + __func__); + break; } + + spin_lock(&op->lock); + finish_wait(&op->io_completion_waitq, &wait_entry); + spin_unlock(&op->lock); + + /* NOTE: for I/O operations we handle releasing the op + * object except in the case of timeout. the reason we + * can't free the op in timeout cases is that the op + * service logic in the vfs retries operations using + * the same op ptr, thus it can't be freed. + */ + if (!timed_out) + op_release(op); } else { - /* ignore downcalls that we're not interested in */ - gossip_debug(GOSSIP_DEV_DEBUG, - "WARNING: No one's waiting for tag %llu\n", - llu(tag)); + /* + * tell the vfs op waiting on a waitqueue that + * this op is done + */ + spin_lock(&op->lock); + set_op_state_serviced(op); + spin_unlock(&op->lock); + /* + * for every other operation (i.e. non-I/O), we need to + * wake up the callers for downcall completion + * notification + */ + wake_up_interruptible(&op->waitq); } - /* put_op? */ - dev_req_release(buffer); - - return total_returned_size; -} - -static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, - struct iov_iter *iter) -{ - return orangefs_devreq_writev(iocb->ki_filp, - iter->iov, - iter->nr_segs, - &iocb->ki_pos); +out: + return ret; } /* Returns whether any FS are still pending remounted */ -- GitLab From c817e266e408538290af06b95f07f6ee2b7d507a Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 11:29:05 -0500 Subject: [PATCH 0200/5324] Orangefs: rename orangefs_kernel_op_s.aio_ref_count to just ref_count. The op structure's ref_count member hasn't got anything to do with asynchronous I/O. Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-cache.c | 2 +- fs/orangefs/orangefs-kernel.h | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index b40f5d74aa97..dd4335ff8c10 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -120,7 +120,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) init_waitqueue_head(&new_op->waitq); init_waitqueue_head(&new_op->io_completion_waitq); - atomic_set(&new_op->aio_ref_count, 0); + atomic_set(&new_op->ref_count, 0); orangefs_op_initialize(new_op); diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 0c7a9cf9b8ef..1c87e0bbdfe8 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -115,7 +115,7 @@ enum orangefs_vfs_op_states { #define get_op(op) \ do { \ - atomic_inc(&(op)->aio_ref_count); \ + atomic_inc(&(op)->ref_count); \ gossip_debug(GOSSIP_DEV_DEBUG, \ "(get) Alloced OP (%p:%llu)\n", \ op, \ @@ -124,7 +124,7 @@ enum orangefs_vfs_op_states { #define put_op(op) \ do { \ - if (atomic_sub_and_test(1, &(op)->aio_ref_count) == 1) { \ + if (atomic_sub_and_test(1, &(op)->ref_count) == 1) { \ gossip_debug(GOSSIP_DEV_DEBUG, \ "(put) Releasing OP (%p:%llu)\n", \ op, \ @@ -133,7 +133,7 @@ enum orangefs_vfs_op_states { } \ } while (0) -#define op_wait(op) (atomic_read(&(op)->aio_ref_count) <= 2 ? 0 : 1) +#define op_wait(op) (atomic_read(&(op)->ref_count) <= 2 ? 0 : 1) /* * Defines for controlling whether I/O upcalls are for async or sync operations @@ -239,14 +239,13 @@ struct orangefs_kernel_op_s { int io_completed; wait_queue_head_t io_completion_waitq; + atomic_t ref_count; + /* VFS aio fields */ /* used by the async I/O code to stash the orangefs_kiocb_s structure */ void *priv; - /* used again for the async I/O code for deallocation */ - atomic_t aio_ref_count; - int attempts; struct list_head list; -- GitLab From 4c27b327b8c286cd3091e5d9ff1650573601140b Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 11:34:59 -0500 Subject: [PATCH 0201/5324] Orangefs: change ORANGEFS_VERSION from "Unknown" to "upstream" Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-mod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index fa2fca6dca7c..cac52a9175db 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -14,7 +14,7 @@ /* ORANGEFS_VERSION is a ./configure define */ #ifndef ORANGEFS_VERSION -#define ORANGEFS_VERSION "Unknown" +#define ORANGEFS_VERSION "upstream" #endif /* -- GitLab From 569dbfc6b3a0e71118bc81f5f0fb56c3d1b88c54 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 11:36:25 -0500 Subject: [PATCH 0202/5324] Orangefs: define a minimum compatible userspace version. Signed-off-by: Mike Marshall --- fs/orangefs/protocol.h | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 03bbe7505a35..56dd65abb908 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -399,6 +399,7 @@ enum { * space. Zero signifies the upstream version of the kernel module. */ #define ORANGEFS_KERNEL_PROTO_VERSION 0 +#define ORANGEFS_MINIMUM_USERSPACE_VERSION 20904 /* * describes memory regions to map in the ORANGEFS_DEV_MAP ioctl. -- GitLab From be57366e14d8341f5d2b589d5b59151895afe210 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 11:38:14 -0500 Subject: [PATCH 0203/5324] Orangefs: make .statfs gossip_debug more complete. Signed-off-by: Mike Marshall --- fs/orangefs/super.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index bee67b37d805..a32981239ea6 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -158,11 +158,15 @@ static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf) goto out_op_release; gossip_debug(GOSSIP_SUPER_DEBUG, - "orangefs_statfs: got %ld blocks available | " - "%ld blocks total | %ld block size\n", + "%s: got %ld blocks available | " + "%ld blocks total | %ld block size | " + "%ld files total | %ld files avail\n", + __func__, (long)new_op->downcall.resp.statfs.blocks_avail, (long)new_op->downcall.resp.statfs.blocks_total, - (long)new_op->downcall.resp.statfs.block_size); + (long)new_op->downcall.resp.statfs.block_size, + (long)new_op->downcall.resp.statfs.files_total, + (long)new_op->downcall.resp.statfs.files_avail); buf->f_type = sb->s_magic; memcpy(&buf->f_fsid, &ORANGEFS_SB(sb)->fs_id, sizeof(buf->f_fsid)); -- GitLab From b5c653384f84b0ccb97e9cf942b6e8ed759221bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:31 +0200 Subject: [PATCH 0204/5324] drm/i915: Pass modifier instead of tiling_mode to gen4_compute_page_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for handling more than X tiling, pass the fb modifier to gen4_compute_page_offset() instead of the obj->tiling_mode. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-2-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++------ drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_sprite.c | 21 ++++++++++----------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3b79981735c8..e39c724aca89 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2449,11 +2449,11 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, * is assumed to be a power-of-two. */ unsigned long intel_gen4_compute_page_offset(struct drm_i915_private *dev_priv, int *x, int *y, - unsigned int tiling_mode, + uint64_t fb_modifier, unsigned int cpp, unsigned int pitch) { - if (tiling_mode != I915_TILING_NONE) { + if (fb_modifier != DRM_FORMAT_MOD_NONE) { unsigned int tile_rows, tiles; tile_rows = *y / 8; @@ -2769,8 +2769,8 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (INTEL_INFO(dev)->gen >= 4) { intel_crtc->dspaddr_offset = - intel_gen4_compute_page_offset(dev_priv, - &x, &y, obj->tiling_mode, + intel_gen4_compute_page_offset(dev_priv, &x, &y, + fb->modifier[0], pixel_size, fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; @@ -2877,8 +2877,8 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, linear_offset = y * fb->pitches[0] + x * pixel_size; intel_crtc->dspaddr_offset = - intel_gen4_compute_page_offset(dev_priv, - &x, &y, obj->tiling_mode, + intel_gen4_compute_page_offset(dev_priv, &x, &y, + fb->modifier[0], pixel_size, fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e27954d2edad..015538287171 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1198,8 +1198,8 @@ void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) unsigned long intel_gen4_compute_page_offset(struct drm_i915_private *dev_priv, int *x, int *y, - unsigned int tiling_mode, - unsigned int bpp, + uint64_t fb_modifier, + unsigned int cpp, unsigned int pitch); void intel_prepare_reset(struct drm_device *dev); void intel_finish_reset(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 73dfb38886b9..3c596c9f0305 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -422,9 +422,8 @@ vlv_update_plane(struct drm_plane *dplane, crtc_h--; linear_offset = y * fb->pitches[0] + x * pixel_size; - sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, - &x, &y, - obj->tiling_mode, + sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, + fb->modifier[0], pixel_size, fb->pitches[0]); linear_offset -= sprsurf_offset; @@ -557,10 +556,10 @@ ivb_update_plane(struct drm_plane *plane, sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * pixel_size; - sprsurf_offset = - intel_gen4_compute_page_offset(dev_priv, - &x, &y, obj->tiling_mode, - pixel_size, fb->pitches[0]); + sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= sprsurf_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { @@ -696,10 +695,10 @@ ilk_update_plane(struct drm_plane *plane, dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * pixel_size; - dvssurf_offset = - intel_gen4_compute_page_offset(dev_priv, - &x, &y, obj->tiling_mode, - pixel_size, fb->pitches[0]); + dvssurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= dvssurf_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { -- GitLab From 7b49f94839660a82f1f40ee95cfe70245b4444d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:32 +0200 Subject: [PATCH 0205/5324] drm/i915: Factor out intel_tile_width() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the tile width calculations from intel_fb_stride_alignment() into a new function intel_tile_width(). Also take the opportunity to pass aroun dev_priv instead of dev to intel_fb_stride_alignment(). v2: Reorder argumnents to be more consistent with other functions Change intel_fb_stride_alignment() to accept dev_priv instead of dev v3: Deal with Y tilling (Daniel) Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-3-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 85 +++++++++++++++++----------- drivers/gpu/drm/i915/intel_drv.h | 4 +- drivers/gpu/drm/i915/intel_sprite.c | 2 +- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e39c724aca89..d86e47a9cf6f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2223,6 +2223,43 @@ static bool need_vtd_wa(struct drm_device *dev) return false; } +static unsigned int intel_tile_width(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, unsigned int cpp) +{ + switch (fb_modifier) { + case DRM_FORMAT_MOD_NONE: + return cpp; + case I915_FORMAT_MOD_X_TILED: + if (IS_GEN2(dev_priv)) + return 128; + else + return 512; + case I915_FORMAT_MOD_Y_TILED: + if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv)) + return 128; + else + return 512; + case I915_FORMAT_MOD_Yf_TILED: + switch (cpp) { + case 1: + return 64; + case 2: + case 4: + return 128; + case 8: + case 16: + return 256; + default: + MISSING_CASE(cpp); + return cpp; + } + break; + default: + MISSING_CASE(fb_modifier); + return cpp; + } +} + unsigned int intel_tile_height(struct drm_device *dev, uint32_t pixel_format, uint64_t fb_format_modifier, unsigned int plane) @@ -2914,37 +2951,15 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, POSTING_READ(reg); } -u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier, - uint32_t pixel_format) +u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, uint32_t pixel_format) { - u32 bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8; - - /* - * The stride is either expressed as a multiple of 64 bytes - * chunks for linear buffers or in number of tiles for tiled - * buffers. - */ - switch (fb_modifier) { - case DRM_FORMAT_MOD_NONE: - return 64; - case I915_FORMAT_MOD_X_TILED: - if (INTEL_INFO(dev)->gen == 2) - return 128; - return 512; - case I915_FORMAT_MOD_Y_TILED: - /* No need to check for old gens and Y tiling since this is - * about the display engine and those will be blocked before - * we get here. - */ - return 128; - case I915_FORMAT_MOD_Yf_TILED: - if (bits_per_pixel == 8) - return 64; - else - return 128; - default: - MISSING_CASE(fb_modifier); + if (fb_modifier == DRM_FORMAT_MOD_NONE) { return 64; + } else { + int cpp = drm_format_plane_cpp(pixel_format, 0); + + return intel_tile_width(dev_priv, fb_modifier, cpp); } } @@ -3118,7 +3133,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane, plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; plane_ctl |= skl_plane_ctl_rotation(rotation); - stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], + stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0], fb->pixel_format); surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj, 0); @@ -9305,7 +9320,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, fb->width = ((val >> 0) & 0x1fff) + 1; val = I915_READ(PLANE_STRIDE(pipe, 0)); - stride_mult = intel_fb_stride_alignment(dev, fb->modifier[0], + stride_mult = intel_fb_stride_alignment(dev_priv, fb->modifier[0], fb->pixel_format); fb->pitches[0] = (val & 0x3ff) * stride_mult; @@ -11391,8 +11406,8 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, stride = DIV_ROUND_UP(fb->height, tile_height); } else { stride = fb->pitches[0] / - intel_fb_stride_alignment(dev, fb->modifier[0], - fb->pixel_format); + intel_fb_stride_alignment(dev_priv, fb->modifier[0], + fb->pixel_format); } /* @@ -14776,6 +14791,7 @@ static int intel_framebuffer_init(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_i915_gem_object *obj) { + struct drm_i915_private *dev_priv = to_i915(dev); unsigned int aligned_height; int ret; u32 pitch_limit, stride_alignment; @@ -14817,7 +14833,8 @@ static int intel_framebuffer_init(struct drm_device *dev, return -EINVAL; } - stride_alignment = intel_fb_stride_alignment(dev, mode_cmd->modifier[0], + stride_alignment = intel_fb_stride_alignment(dev_priv, + mode_cmd->modifier[0], mode_cmd->pixel_format); if (mode_cmd->pitches[0] & (stride_alignment - 1)) { DRM_DEBUG("pitch (%d) must be at least %u byte aligned\n", diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 015538287171..9a8075b785ac 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1070,8 +1070,8 @@ unsigned int intel_fb_align_height(struct drm_device *dev, uint64_t fb_format_modifier); void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire, enum fb_op_origin origin); -u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier, - uint32_t pixel_format); +u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, uint32_t pixel_format); /* intel_audio.c */ void intel_init_audio(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 3c596c9f0305..766c33ad0309 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -216,7 +216,7 @@ skl_update_plane(struct drm_plane *drm_plane, rotation = plane_state->base.rotation; plane_ctl |= skl_plane_ctl_rotation(rotation); - stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], + stride_div = intel_fb_stride_alignment(dev_priv, fb->modifier[0], fb->pixel_format); /* Sizes are 0 based */ -- GitLab From 832be82f87c2bf711d8d7aaeb59da925b4573f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:33 +0200 Subject: [PATCH 0206/5324] drm/i915: Redo intel_tile_height() as intel_tile_size() / intel_tile_width() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I find more usual to think about tile widths than heights, so changing the intel_tile_height() to calculate the tile height as tile_size/tile_width is easier than the opposite to the poor brain. v2: Reorder arguments for consistency Constify dev_priv arguments Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-4-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 89 +++++++++------------------- drivers/gpu/drm/i915/intel_drv.h | 5 +- drivers/gpu/drm/i915/intel_sprite.c | 5 +- 3 files changed, 34 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d86e47a9cf6f..9c20c2ee742f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2223,6 +2223,11 @@ static bool need_vtd_wa(struct drm_device *dev) return false; } +static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv) +{ + return IS_GEN2(dev_priv) ? 2048 : 4096; +} + static unsigned int intel_tile_width(const struct drm_i915_private *dev_priv, uint64_t fb_modifier, unsigned int cpp) { @@ -2260,67 +2265,34 @@ static unsigned int intel_tile_width(const struct drm_i915_private *dev_priv, } } -unsigned int -intel_tile_height(struct drm_device *dev, uint32_t pixel_format, - uint64_t fb_format_modifier, unsigned int plane) +unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, unsigned int cpp) { - unsigned int tile_height; - uint32_t pixel_bytes; - - switch (fb_format_modifier) { - case DRM_FORMAT_MOD_NONE: - tile_height = 1; - break; - case I915_FORMAT_MOD_X_TILED: - tile_height = IS_GEN2(dev) ? 16 : 8; - break; - case I915_FORMAT_MOD_Y_TILED: - tile_height = 32; - break; - case I915_FORMAT_MOD_Yf_TILED: - pixel_bytes = drm_format_plane_cpp(pixel_format, plane); - switch (pixel_bytes) { - default: - case 1: - tile_height = 64; - break; - case 2: - case 4: - tile_height = 32; - break; - case 8: - tile_height = 16; - break; - case 16: - WARN_ONCE(1, - "128-bit pixels are not supported for display!"); - tile_height = 16; - break; - } - break; - default: - MISSING_CASE(fb_format_modifier); - tile_height = 1; - break; - } - - return tile_height; + if (fb_modifier == DRM_FORMAT_MOD_NONE) + return 1; + else + return intel_tile_size(dev_priv) / + intel_tile_width(dev_priv, fb_modifier, cpp); } unsigned int intel_fb_align_height(struct drm_device *dev, unsigned int height, - uint32_t pixel_format, uint64_t fb_format_modifier) + uint32_t pixel_format, uint64_t fb_modifier) { - return ALIGN(height, intel_tile_height(dev, pixel_format, - fb_format_modifier, 0)); + unsigned int cpp = drm_format_plane_cpp(pixel_format, 0); + unsigned int tile_height = intel_tile_height(to_i915(dev), fb_modifier, cpp); + + return ALIGN(height, tile_height); } static void intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, const struct drm_plane_state *plane_state) { + struct drm_i915_private *dev_priv = to_i915(fb->dev); struct intel_rotation_info *info = &view->params.rotation_info; unsigned int tile_height, tile_pitch; + unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0); *view = i915_ggtt_view_normal; @@ -2338,22 +2310,19 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, info->uv_offset = fb->offsets[1]; info->fb_modifier = fb->modifier[0]; - tile_height = intel_tile_height(fb->dev, fb->pixel_format, - fb->modifier[0], 0); + tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp); tile_pitch = PAGE_SIZE / tile_height; info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_pitch); info->height_pages = DIV_ROUND_UP(fb->height, tile_height); info->size = info->width_pages * info->height_pages * PAGE_SIZE; if (info->pixel_format == DRM_FORMAT_NV12) { - tile_height = intel_tile_height(fb->dev, fb->pixel_format, - fb->modifier[0], 1); + cpp = drm_format_plane_cpp(fb->pixel_format, 1); + tile_height = intel_tile_height(dev_priv, fb->modifier[1], cpp); tile_pitch = PAGE_SIZE / tile_height; - info->width_pages_uv = DIV_ROUND_UP(fb->pitches[0], tile_pitch); - info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, - tile_height); - info->size_uv = info->width_pages_uv * info->height_pages_uv * - PAGE_SIZE; + info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_pitch); + info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height); + info->size_uv = info->width_pages_uv * info->height_pages_uv * PAGE_SIZE; } } @@ -3140,9 +3109,10 @@ static void skylake_update_primary_plane(struct drm_plane *plane, WARN_ON(drm_rect_width(&plane_state->src) == 0); if (intel_rotation_90_or_270(rotation)) { + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); + /* stride = Surface height in tiles */ - tile_height = intel_tile_height(dev, fb->pixel_format, - fb->modifier[0], 0); + tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp); stride = DIV_ROUND_UP(fb->height, tile_height); x_offset = stride * tile_height - src_y - src_h; y_offset = src_x; @@ -11401,8 +11371,7 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, */ if (intel_rotation_90_or_270(rotation)) { /* stride = Surface height in tiles */ - tile_height = intel_tile_height(dev, fb->pixel_format, - fb->modifier[0], 0); + tile_height = intel_tile_height(dev_priv, fb->modifier[0], 0); stride = DIV_ROUND_UP(fb->height, tile_height); } else { stride = fb->pitches[0] / diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9a8075b785ac..6aaaa8d3b81a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1155,9 +1155,8 @@ int intel_plane_atomic_set_property(struct drm_plane *plane, int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state); -unsigned int -intel_tile_height(struct drm_device *dev, uint32_t pixel_format, - uint64_t fb_format_modifier, unsigned int plane); +unsigned int intel_tile_height(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier, unsigned int cpp); static inline bool intel_rotation_90_or_270(unsigned int rotation) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 766c33ad0309..64083d720a00 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -239,9 +239,10 @@ skl_update_plane(struct drm_plane *drm_plane, surf_addr = intel_plane_obj_offset(intel_plane, obj, 0); if (intel_rotation_90_or_270(rotation)) { + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); + /* stride: Surface height in tiles */ - tile_height = intel_tile_height(dev, fb->pixel_format, - fb->modifier[0], 0); + tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp); stride = DIV_ROUND_UP(fb->height, tile_height); plane_size = (src_w << 16) | src_h; x_offset = stride * tile_height - y - (src_h + 1); -- GitLab From d9b3288ecf2fe33b46335d2c93bc5ae50d486d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:34 +0200 Subject: [PATCH 0207/5324] drm/i915: change intel_fill_fb_ggtt_view() to use the real tile size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the actual tile size as to compute stuff in intel_fill_fb_ggtt_view() instead of assuming it's PAGE_SIZE. I suppose it doesn't matter since we don't use the results on gen2 platforms where the tile size is 2k. v2: Update due to CbCr plane Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-5-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9c20c2ee742f..79900341f944 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2291,8 +2291,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, { struct drm_i915_private *dev_priv = to_i915(fb->dev); struct intel_rotation_info *info = &view->params.rotation_info; - unsigned int tile_height, tile_pitch; - unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, 0); + unsigned int tile_size, tile_width, tile_height, cpp; *view = i915_ggtt_view_normal; @@ -2310,19 +2309,24 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, info->uv_offset = fb->offsets[1]; info->fb_modifier = fb->modifier[0]; - tile_height = intel_tile_height(dev_priv, fb->modifier[0], cpp); - tile_pitch = PAGE_SIZE / tile_height; - info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_pitch); + tile_size = intel_tile_size(dev_priv); + + cpp = drm_format_plane_cpp(fb->pixel_format, 0); + tile_width = intel_tile_width(dev_priv, cpp, fb->modifier[0]); + tile_height = tile_size / tile_width; + + info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width); info->height_pages = DIV_ROUND_UP(fb->height, tile_height); - info->size = info->width_pages * info->height_pages * PAGE_SIZE; + info->size = info->width_pages * info->height_pages * tile_size; if (info->pixel_format == DRM_FORMAT_NV12) { cpp = drm_format_plane_cpp(fb->pixel_format, 1); - tile_height = intel_tile_height(dev_priv, fb->modifier[1], cpp); - tile_pitch = PAGE_SIZE / tile_height; - info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_pitch); + tile_width = intel_tile_width(dev_priv, fb->modifier[1], cpp); + tile_height = tile_size / tile_width; + + info->width_pages_uv = DIV_ROUND_UP(fb->pitches[1], tile_width); info->height_pages_uv = DIV_ROUND_UP(fb->height / 2, tile_height); - info->size_uv = info->width_pages_uv * info->height_pages_uv * PAGE_SIZE; + info->size_uv = info->width_pages_uv * info->height_pages_uv * tile_size; } } -- GitLab From d843310d146452105e2bc54b8d82e52ad727697f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:35 +0200 Subject: [PATCH 0208/5324] drm/i915: Use intel_tile_{size,width,height}() in intel_gen4_compute_page_offset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make intel_gen4_compute_page_offset() ready for other tiling formats besied X-tile by getting the tile dimensions through intel_tile_{size,width,height}(). Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-6-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 79900341f944..8a76e29256ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2464,15 +2464,20 @@ unsigned long intel_gen4_compute_page_offset(struct drm_i915_private *dev_priv, unsigned int pitch) { if (fb_modifier != DRM_FORMAT_MOD_NONE) { + unsigned int tile_size, tile_width, tile_height; unsigned int tile_rows, tiles; - tile_rows = *y / 8; - *y %= 8; + tile_size = intel_tile_size(dev_priv); + tile_width = intel_tile_width(dev_priv, fb_modifier, cpp); + tile_height = tile_size / tile_width; + + tile_rows = *y / tile_height; + *y %= tile_height; - tiles = *x / (512/cpp); - *x %= 512/cpp; + tiles = *x / (tile_width/cpp); + *x %= tile_width/cpp; - return tile_rows * pitch * 8 + tiles * 4096; + return tile_rows * pitch * tile_height + tiles * tile_size; } else { unsigned int alignment = intel_linear_alignment(dev_priv) - 1; unsigned int offset; -- GitLab From ce1e5c140ce945ef6fc4ee4803f0c2f774873d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:36 +0200 Subject: [PATCH 0209/5324] drm/i915: s/intel_gen4_compute_page_offset/intel_compute_tile_offset/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since intel_gen4_compute_page_offset() can now handle tiling formats all the way down to gen2, rename it to intel_compute_tile_offset(). Not that we actually use it on gen2/3 since there's no DSPSURF etc. registers which would take a page aligned address. v2: s/page/tile/ (Daniel) Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-7-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 26 +++++++++++++------------- drivers/gpu/drm/i915/intel_drv.h | 10 +++++----- drivers/gpu/drm/i915/intel_sprite.c | 24 ++++++++++++------------ 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8a76e29256ef..bffeacf86189 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2457,11 +2457,11 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel * is assumed to be a power-of-two. */ -unsigned long intel_gen4_compute_page_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, - unsigned int pitch) +unsigned long intel_compute_tile_offset(struct drm_i915_private *dev_priv, + int *x, int *y, + uint64_t fb_modifier, + unsigned int cpp, + unsigned int pitch) { if (fb_modifier != DRM_FORMAT_MOD_NONE) { unsigned int tile_size, tile_width, tile_height; @@ -2784,10 +2784,10 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (INTEL_INFO(dev)->gen >= 4) { intel_crtc->dspaddr_offset = - intel_gen4_compute_page_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, - fb->pitches[0]); + intel_compute_tile_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; } else { intel_crtc->dspaddr_offset = linear_offset; @@ -2892,10 +2892,10 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, linear_offset = y * fb->pitches[0] + x * pixel_size; intel_crtc->dspaddr_offset = - intel_gen4_compute_page_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, - fb->pitches[0]); + intel_compute_tile_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { dspcntr |= DISPPLANE_ROTATE_180; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6aaaa8d3b81a..059b46e22c31 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1195,11 +1195,11 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pipe_enabled(d, p) assert_pipe(d, p, true) #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) -unsigned long intel_gen4_compute_page_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, - unsigned int pitch); +unsigned long intel_compute_tile_offset(struct drm_i915_private *dev_priv, + int *x, int *y, + uint64_t fb_modifier, + unsigned int cpp, + unsigned int pitch); void intel_prepare_reset(struct drm_device *dev); void intel_finish_reset(struct drm_device *dev); void hsw_enable_pc8(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 64083d720a00..22589fce9a50 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -423,10 +423,10 @@ vlv_update_plane(struct drm_plane *dplane, crtc_h--; linear_offset = y * fb->pitches[0] + x * pixel_size; - sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, - fb->pitches[0]); + sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= sprsurf_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { @@ -557,10 +557,10 @@ ivb_update_plane(struct drm_plane *plane, sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * pixel_size; - sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, - fb->pitches[0]); + sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= sprsurf_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { @@ -696,10 +696,10 @@ ilk_update_plane(struct drm_plane *plane, dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; linear_offset = y * fb->pitches[0] + x * pixel_size; - dvssurf_offset = intel_gen4_compute_page_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, - fb->pitches[0]); + dvssurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, + fb->modifier[0], + pixel_size, + fb->pitches[0]); linear_offset -= dvssurf_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { -- GitLab From 603525d72219f8aee13f2c029b91c7c1435a01a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Jan 2016 21:08:37 +0200 Subject: [PATCH 0210/5324] drm/i915: Refactor intel_surf_alignment() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull the code to determine the surface alignment for both linear and tiled surfaces into a separate function intel_surf_alignment(). This will be used not only for the vma alignment but actually aligning the plane SURF once SKL+ starts using intel_compute_page_offset() (since SKL+ needs >4K alignment for tiled surfaces too). Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452625717-9713-8-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 45 +++++++++++++--------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bffeacf86189..e5eb341c6ca3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2330,7 +2330,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, } } -static unsigned int intel_linear_alignment(struct drm_i915_private *dev_priv) +static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv) { if (INTEL_INFO(dev_priv)->gen >= 9) return 256 * 1024; @@ -2343,6 +2343,25 @@ static unsigned int intel_linear_alignment(struct drm_i915_private *dev_priv) return 0; } +static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv, + uint64_t fb_modifier) +{ + switch (fb_modifier) { + case DRM_FORMAT_MOD_NONE: + return intel_linear_alignment(dev_priv); + case I915_FORMAT_MOD_X_TILED: + if (INTEL_INFO(dev_priv)->gen >= 9) + return 256 * 1024; + return 0; + case I915_FORMAT_MOD_Y_TILED: + case I915_FORMAT_MOD_Yf_TILED: + return 1 * 1024 * 1024; + default: + MISSING_CASE(fb_modifier); + return 0; + } +} + int intel_pin_and_fence_fb_obj(struct drm_plane *plane, struct drm_framebuffer *fb, @@ -2357,29 +2376,7 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - switch (fb->modifier[0]) { - case DRM_FORMAT_MOD_NONE: - alignment = intel_linear_alignment(dev_priv); - break; - case I915_FORMAT_MOD_X_TILED: - if (INTEL_INFO(dev)->gen >= 9) - alignment = 256 * 1024; - else { - /* pin() will align the object as required by fence */ - alignment = 0; - } - break; - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_Yf_TILED: - if (WARN_ONCE(INTEL_INFO(dev)->gen < 9, - "Y tiling bo slipped through, driver bug!\n")) - return -EINVAL; - alignment = 1 * 1024 * 1024; - break; - default: - MISSING_CASE(fb->modifier[0]); - return -EINVAL; - } + alignment = intel_surf_alignment(dev_priv, fb->modifier[0]); intel_fill_fb_ggtt_view(&view, fb, plane_state); -- GitLab From fcac9d571567e8bf952616f4a271eea5b4b407ea Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Wed, 13 Jan 2016 14:28:13 -0500 Subject: [PATCH 0211/5324] Orangefs: add protocol information to Documentation/filesystems/orangefs.txt Signed-off-by: Mike Marshall --- Documentation/filesystems/orangefs.txt | 218 ++++++++++++++++++++++++- 1 file changed, 217 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt index ec9c8416427e..925a53e52097 100644 --- a/Documentation/filesystems/orangefs.txt +++ b/Documentation/filesystems/orangefs.txt @@ -115,7 +115,7 @@ The following mount options are accepted: DEBUGGING ========= -If you want the debug (GOSSIP) statments in a particular +If you want the debug (GOSSIP) statements in a particular source file (inode.c for example) go to syslog: echo inode > /sys/kernel/debug/orangefs/kernel-debug @@ -135,3 +135,219 @@ All debugging: Get a list of all debugging keywords: cat /sys/kernel/debug/orangefs/debug-help + + +PROTOCOL BETWEEN KERNEL MODULE AND USERSPACE +============================================ + +Orangefs is a user space filesystem and an associated kernel module. +We'll just refer to the user space part of Orangefs as "userspace" +from here on out. Orangefs descends from PVFS, and userspace code +still uses PVFS for function and variable names. Userspace typedefs +many of the important structures. Function and variable names in +the kernel module have been transitioned to "orangefs", and The Linux +Coding Style avoids typedefs, so kernel module structures that +correspond to userspace structures are not typedefed. + +The kernel module implements a pseudo device that userspace +can read from and write to. Userspace can also manipulate the +kernel module through the pseudo device with ioctl. + +THE BUFMAP: + +At startup userspace allocates two page-size-aligned (posix_memalign) +mlocked memory buffers, one is used for IO and one is used for readdir +operations. The IO buffer is 41943040 bytes and the readdir buffer is +4194304 bytes. Each buffer contains logical chunks, or partitions, and +a pointer to each buffer is added to its own PVFS_dev_map_desc structure +which also describes its total size, as well as the size and number of +the partitions. + +A pointer to the IO buffer's PVFS_dev_map_desc structure is sent to a +mapping routine in the kernel module with an ioctl. The structure is +copied from user space to kernel space with copy_from_user and is used +to initialize the kernel module's "bufmap" (struct orangefs_bufmap), which +then contains: + + * refcnt - a reference counter + * desc_size - PVFS2_BUFMAP_DEFAULT_DESC_SIZE (4194304) - the IO buffer's + partition size, which represents the filesystem's block size and + is used for s_blocksize in super blocks. + * desc_count - PVFS2_BUFMAP_DEFAULT_DESC_COUNT (10) - the number of + partitions in the IO buffer. + * desc_shift - log2(desc_size), used for s_blocksize_bits in super blocks. + * total_size - the total size of the IO buffer. + * page_count - the number of 4096 byte pages in the IO buffer. + * page_array - a pointer to page_count * (sizeof(struct page*)) bytes + of kcalloced memory. This memory is used as an array of pointers + to each of the pages in the IO buffer through a call to get_user_pages. + * desc_array - a pointer to desc_count * (sizeof(struct orangefs_bufmap_desc)) + bytes of kcalloced memory. This memory is further intialized: + + user_desc is the kernel's copy of the IO buffer's ORANGEFS_dev_map_desc + structure. user_desc->ptr points to the IO buffer. + + pages_per_desc = bufmap->desc_size / PAGE_SIZE + offset = 0 + + bufmap->desc_array[0].page_array = &bufmap->page_array[offset] + bufmap->desc_array[0].array_count = pages_per_desc = 1024 + bufmap->desc_array[0].uaddr = (user_desc->ptr) + (0 * 1024 * 4096) + offset += 1024 + . + . + . + bufmap->desc_array[9].page_array = &bufmap->page_array[offset] + bufmap->desc_array[9].array_count = pages_per_desc = 1024 + bufmap->desc_array[9].uaddr = (user_desc->ptr) + + (9 * 1024 * 4096) + offset += 1024 + + * buffer_index_array - a desc_count sized array of ints, used to + indicate which of the IO buffer's partitions are available to use. + * buffer_index_lock - a spinlock to protect buffer_index_array during update. + * readdir_index_array - a five (ORANGEFS_READDIR_DEFAULT_DESC_COUNT) element + int array used to indicate which of the readdir buffer's partitions are + available to use. + * readdir_index_lock - a spinlock to protect readdir_index_array during + update. + +OPERATIONS: + +The kernel module builds an "op" (struct orangefs_kernel_op_s) when it +needs to communicate with userspace. Part of the op contains the "upcall" +which expresses the request to userspace. Part of the op eventually +contains the "downcall" which expresses the results of the request. + +The slab allocator is used to keep a cache of op structures handy. + +The life cycle of a typical op goes like this: + + - obtain and initialize an op structure from the op_cache. + + - queue the op to the pvfs device so that its upcall data can be + read by userspace. + + - wait for userspace to write downcall data back to the pvfs device. + + - consume the downcall and return the op struct to the op_cache. + +Some ops are atypical with respect to their payloads: readdir and io ops. + + - readdir ops use the smaller of the two pre-allocated pre-partitioned + memory buffers. The readdir buffer is only available to userspace. + The kernel module obtains an index to a free partition before launching + a readdir op. Userspace deposits the results into the indexed partition + and then writes them to back to the pvfs device. + + - io (read and write) ops use the larger of the two pre-allocated + pre-partitioned memory buffers. The IO buffer is accessible from + both userspace and the kernel module. The kernel module obtains an + index to a free partition before launching an io op. The kernel module + deposits write data into the indexed partition, to be consumed + directly by userspace. Userspace deposits the results of read + requests into the indexed partition, to be consumed directly + by the kernel module. + +Responses to kernel requests are all packaged in pvfs2_downcall_t +structs. Besides a few other members, pvfs2_downcall_t contains a +union of structs, each of which is associated with a particular +response type. + +The several members outside of the union are: + - int32_t type - type of operation. + - int32_t status - return code for the operation. + - int64_t trailer_size - 0 unless readdir operation. + - char *trailer_buf - initialized to NULL, used during readdir operations. + +The appropriate member inside the union is filled out for any +particular response. + + PVFS2_VFS_OP_FILE_IO + fill a pvfs2_io_response_t + + PVFS2_VFS_OP_LOOKUP + fill a PVFS_object_kref + + PVFS2_VFS_OP_CREATE + fill a PVFS_object_kref + + PVFS2_VFS_OP_SYMLINK + fill a PVFS_object_kref + + PVFS2_VFS_OP_GETATTR + fill in a PVFS_sys_attr_s (tons of stuff the kernel doesn't need) + fill in a string with the link target when the object is a symlink. + + PVFS2_VFS_OP_MKDIR + fill a PVFS_object_kref + + PVFS2_VFS_OP_STATFS + fill a pvfs2_statfs_response_t with useless info . It is hard for + us to know, in a timely fashion, these statistics about our + distributed network filesystem. + + PVFS2_VFS_OP_FS_MOUNT + fill a pvfs2_fs_mount_response_t which is just like a PVFS_object_kref + except its members are in a different order and "__pad1" is replaced + with "id". + + PVFS2_VFS_OP_GETXATTR + fill a pvfs2_getxattr_response_t + + PVFS2_VFS_OP_LISTXATTR + fill a pvfs2_listxattr_response_t + + PVFS2_VFS_OP_PARAM + fill a pvfs2_param_response_t + + PVFS2_VFS_OP_PERF_COUNT + fill a pvfs2_perf_count_response_t + + PVFS2_VFS_OP_FSKEY + file a pvfs2_fs_key_response_t + + PVFS2_VFS_OP_READDIR + jamb everything needed to represent a pvfs2_readdir_response_t into + the readdir buffer descriptor specified in the upcall. + +writev() on /dev/pvfs2-req is used to pass responses to the requests +made by the kernel side. + +A buffer_list containing: + - a pointer to the prepared response to the request from the + kernel (struct pvfs2_downcall_t). + - and also, in the case of a readdir request, a pointer to a + buffer containing descriptors for the objects in the target + directory. +... is sent to the function (PINT_dev_write_list) which performs +the writev. + +PINT_dev_write_list has a local iovec array: struct iovec io_array[10]; + +The first four elements of io_array are initialized like this for all +responses: + + io_array[0].iov_base = address of local variable "proto_ver" (int32_t) + io_array[0].iov_len = sizeof(int32_t) + + io_array[1].iov_base = address of global variable "pdev_magic" (int32_t) + io_array[1].iov_len = sizeof(int32_t) + + io_array[2].iov_base = address of parameter "tag" (PVFS_id_gen_t) + io_array[2].iov_len = sizeof(int64_t) + + io_array[3].iov_base = address of out_downcall member (pvfs2_downcall_t) + of global variable vfs_request (vfs_request_t) + io_array[3].iov_len = sizeof(pvfs2_downcall_t) + +Readdir responses initialize the fifth element io_array like this: + + io_array[4].iov_base = contents of member trailer_buf (char *) + from out_downcall member of global variable + vfs_request + io_array[4].iov_len = contents of member trailer_size (PVFS_size) + from out_downcall member of global variable + vfs_request + + -- GitLab From 87ad321287ae99a8932af1a19ac99849284a62bd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 14 Jan 2016 12:53:34 +0200 Subject: [PATCH 0212/5324] drm/i915: add onoff utility function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a common function to return "on" or "off" string based on the argument, and drop the local versions of it. This is the onoff version of commit 42a8ca4cb4a48ddbf40e8edb291425e76bcdc230 Author: Jani Nikula Date: Thu Aug 27 16:23:30 2015 +0300 drm/i915: add yesno utility function Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452768814-29787-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 6 +++--- drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/intel_display.c | 30 +++++++++++----------------- drivers/gpu/drm/i915/intel_dp.c | 9 ++------- drivers/gpu/drm/i915/intel_pm.c | 11 +++++----- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f17a2b0c2493..975af3568521 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1335,8 +1335,8 @@ static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, return 0; DRM_DEBUG_KMS("waiting for GT wells to go %s (%08x)\n", - wait_for_on ? "on" : "off", - I915_READ(VLV_GTLC_PW_STATUS)); + onoff(wait_for_on), + I915_READ(VLV_GTLC_PW_STATUS)); /* * RC6 transitioning can be delayed up to 2 msec (see @@ -1345,7 +1345,7 @@ static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, err = wait_for(COND, 3); if (err) DRM_ERROR("timeout waiting for GT wells to go %s\n", - wait_for_on ? "on" : "off"); + onoff(wait_for_on)); return err; #undef COND diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 104bd1809936..eb7bb97f7316 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -102,6 +102,11 @@ static inline const char *yesno(bool v) return v ? "yes" : "no"; } +static inline const char *onoff(bool v) +{ + return v ? "on" : "off"; +} + enum pipe { INVALID_PIPE = -1, PIPE_A = 0, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e5eb341c6ca3..aa24f79d85bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1150,11 +1150,6 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc) } } -static const char *state_string(bool enabled) -{ - return enabled ? "on" : "off"; -} - /* Only for pre-ILK configs */ void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) @@ -1166,7 +1161,7 @@ void assert_pll(struct drm_i915_private *dev_priv, cur_state = !!(val & DPLL_VCO_ENABLE); I915_STATE_WARN(cur_state != state, "PLL state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } /* XXX: the dsi pll is shared between MIPI DSI ports */ @@ -1182,7 +1177,7 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state) cur_state = val & DSI_PLL_VCO_EN; I915_STATE_WARN(cur_state != state, "DSI PLL state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true) #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false) @@ -1206,14 +1201,13 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, bool cur_state; struct intel_dpll_hw_state hw_state; - if (WARN (!pll, - "asserting DPLL %s with no DPLL\n", state_string(state))) + if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state))) return; cur_state = pll->get_hw_state(dev_priv, pll, &hw_state); I915_STATE_WARN(cur_state != state, "%s assertion failure (expected %s, current %s)\n", - pll->name, state_string(state), state_string(cur_state)); + pll->name, onoff(state), onoff(cur_state)); } static void assert_fdi_tx(struct drm_i915_private *dev_priv, @@ -1233,7 +1227,7 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv, } I915_STATE_WARN(cur_state != state, "FDI TX state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } #define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true) #define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false) @@ -1248,7 +1242,7 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv, cur_state = !!(val & FDI_RX_ENABLE); I915_STATE_WARN(cur_state != state, "FDI RX state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } #define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true) #define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false) @@ -1280,7 +1274,7 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, cur_state = !!(val & FDI_RX_PLL_ENABLE); I915_STATE_WARN(cur_state != state, "FDI RX PLL assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } void assert_panel_unlocked(struct drm_i915_private *dev_priv, @@ -1338,7 +1332,7 @@ static void assert_cursor(struct drm_i915_private *dev_priv, I915_STATE_WARN(cur_state != state, "cursor on pipe %c assertion failure (expected %s, current %s)\n", - pipe_name(pipe), state_string(state), state_string(cur_state)); + pipe_name(pipe), onoff(state), onoff(cur_state)); } #define assert_cursor_enabled(d, p) assert_cursor(d, p, true) #define assert_cursor_disabled(d, p) assert_cursor(d, p, false) @@ -1365,7 +1359,7 @@ void assert_pipe(struct drm_i915_private *dev_priv, I915_STATE_WARN(cur_state != state, "pipe %c assertion failure (expected %s, current %s)\n", - pipe_name(pipe), state_string(state), state_string(cur_state)); + pipe_name(pipe), onoff(state), onoff(cur_state)); } static void assert_plane(struct drm_i915_private *dev_priv, @@ -1378,7 +1372,7 @@ static void assert_plane(struct drm_i915_private *dev_priv, cur_state = !!(val & DISPLAY_PLANE_ENABLE); I915_STATE_WARN(cur_state != state, "plane %c assertion failure (expected %s, current %s)\n", - plane_name(plane), state_string(state), state_string(cur_state)); + plane_name(plane), onoff(state), onoff(cur_state)); } #define assert_plane_enabled(d, p) assert_plane(d, p, true) @@ -16317,7 +16311,7 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, for_each_pipe(dev_priv, i) { err_printf(m, "Pipe [%d]:\n", i); err_printf(m, " Power: %s\n", - error->pipe[i].power_domain_on ? "on" : "off"); + onoff(error->pipe[i].power_domain_on)); err_printf(m, " SRC: %08x\n", error->pipe[i].source); err_printf(m, " STAT: %08x\n", error->pipe[i].stat); @@ -16345,7 +16339,7 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, err_printf(m, "CPU transcoder: %c\n", transcoder_name(error->transcoder[i].cpu_transcoder)); err_printf(m, " Power: %s\n", - error->transcoder[i].power_domain_on ? "on" : "off"); + onoff(error->transcoder[i].power_domain_on)); err_printf(m, " CONF: %08x\n", error->transcoder[i].conf); err_printf(m, " HTOTAL: %08x\n", error->transcoder[i].htotal); err_printf(m, " HBLANK: %08x\n", error->transcoder[i].hblank); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9e02dd789b86..3999afa440bd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2238,11 +2238,6 @@ static void intel_edp_backlight_power(struct intel_connector *connector, _intel_edp_backlight_off(intel_dp); } -static const char *state_string(bool enabled) -{ - return enabled ? "on" : "off"; -} - static void assert_dp_port(struct intel_dp *intel_dp, bool state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); @@ -2252,7 +2247,7 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state) I915_STATE_WARN(cur_state != state, "DP port %c state assertion failure (expected %s, current %s)\n", port_name(dig_port->port), - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } #define assert_dp_port_disabled(d) assert_dp_port((d), false) @@ -2262,7 +2257,7 @@ static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state) I915_STATE_WARN(cur_state != state, "eDP PLL state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); + onoff(state), onoff(cur_state)); } #define assert_edp_pll_enabled(d) assert_edp_pll((d), true) #define assert_edp_pll_disabled(d) assert_edp_pll((d), false) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9df9e9a22f3c..465ca76df201 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4590,13 +4590,13 @@ static void intel_print_rc6_info(struct drm_device *dev, u32 mode) } if (HAS_RC6p(dev)) DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s RC6p %s RC6pp %s\n", - (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off", - (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off", - (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off"); + onoff(mode & GEN6_RC_CTL_RC6_ENABLE), + onoff(mode & GEN6_RC_CTL_RC6p_ENABLE), + onoff(mode & GEN6_RC_CTL_RC6pp_ENABLE)); else DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s\n", - (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); + onoff(mode & GEN6_RC_CTL_RC6_ENABLE)); } static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) @@ -4774,8 +4774,7 @@ static void gen9_enable_rc6(struct drm_device *dev) /* 3a: Enable RC6 */ if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) rc6_mask = GEN6_RC_CTL_RC6_ENABLE; - DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? - "on" : "off"); + DRM_INFO("RC6 %s\n", onoff(rc6_mask & GEN6_RC_CTL_RC6_ENABLE)); /* WaRsUseTimeoutMode */ if (IS_SKL_REVID(dev, 0, SKL_REVID_D0) || IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { -- GitLab From f1ecaf8f9c9924badd4c8f690e39632d31edb500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Jan 2016 14:53:34 +0200 Subject: [PATCH 0213/5324] drm/i915: Start WM computation from scratch on ILK-BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ilk_compute_pipe_wm() assumes as zeroed pipe_wm structure when it starts. We used to pass such a zeroed struct in, but this got broken when the pipe_wm structure got embedded in the crtc state. To fix it without too much fuzz, we need to resort to a memset(). Fixes: 4e0963c7663b ("drm/i915: Calculate pipe watermarks into CRTC state (v3)") Cc: Matt Roper Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1452776015-22076-1-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 465ca76df201..966c4c2c416f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2317,6 +2317,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, return PTR_ERR(cstate); pipe_wm = &cstate->wm.optimal.ilk; + memset(pipe_wm, 0, sizeof(*pipe_wm)); for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { ps = drm_atomic_get_plane_state(state, -- GitLab From d890565c44447db08fd9d07f5b02928a07a88c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Jan 2016 14:53:35 +0200 Subject: [PATCH 0214/5324] drm/i915: Use the active wm config for merging on ILK-BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ilk_program_watermarks() is supposed to merge the active watermarks from all pipes. Thus we need to use the active config too instead of some precomputed stuff. Fixes: aa363136866c ("drm/i915: Calculate watermark configuration during atomic check (v2)") Cc: Matt Roper Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1452776015-22076-2-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 966c4c2c416f..6b2b3e331a09 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3680,23 +3680,43 @@ static void skl_update_wm(struct drm_crtc *crtc) dev_priv->wm.skl_hw = *results; } +static void ilk_compute_wm_config(struct drm_device *dev, + struct intel_wm_config *config) +{ + struct intel_crtc *crtc; + + /* Compute the currently _active_ config */ + for_each_intel_crtc(dev, crtc) { + const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; + + if (!wm->pipe_enabled) + continue; + + config->sprites_enabled |= wm->sprites_enabled; + config->sprites_scaled |= wm->sprites_scaled; + config->num_pipes_active++; + } +} + static void ilk_program_watermarks(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; - struct intel_wm_config *config = &dev_priv->wm.config; + struct intel_wm_config config = {}; struct ilk_wm_values results = {}; enum intel_ddb_partitioning partitioning; - ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_1_2, &max); - ilk_wm_merge(dev, config, &max, &lp_wm_1_2); + ilk_compute_wm_config(dev, &config); + + ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); + ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); /* 5/6 split only in single pipe config on IVB+ */ if (INTEL_INFO(dev)->gen >= 7 && - config->num_pipes_active == 1 && config->sprites_enabled) { - ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_5_6, &max); - ilk_wm_merge(dev, config, &max, &lp_wm_5_6); + config.num_pipes_active == 1 && config.sprites_enabled) { + ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max); + ilk_wm_merge(dev, &config, &max, &lp_wm_5_6); best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6); } else { -- GitLab From 965fd602a6436f689f4f2fe40a6789582778ccd5 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 13 Jan 2016 18:59:39 -0800 Subject: [PATCH 0215/5324] drm/i915: Make sure DC writes are coherent on flush. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to set the DC FLUSH PIPE_CONTROL bit on Gen7+ to guarantee that writes performed via the HDC are visible in memory. Fixes an intermittent failure in a Piglit test that writes to a BO from a shader using GL atomic counters (implemented as HDC untyped atomics) and then expects the memory to read back the same value after mapping it on the CPU. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91298 Tested-by: Mark Janes Cc: Rodrigo Vivi Cc: stable@vger.kernel.org Signed-off-by: Francisco Jerez Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452740379-3194-1-git-send-email-currojerez@riseup.net Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_lrc.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5027699c5291..f5d89c845ede 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1735,6 +1735,7 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, if (flush_domains) { flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_DC_FLUSH_ENABLE; flags |= PIPE_CONTROL_FLUSH_ENABLE; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4060acf0601a..8cd8aabcc3ff 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -331,6 +331,7 @@ gen7_render_ring_flush(struct drm_i915_gem_request *req, if (flush_domains) { flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_DC_FLUSH_ENABLE; flags |= PIPE_CONTROL_FLUSH_ENABLE; } if (invalidate_domains) { @@ -403,6 +404,7 @@ gen8_render_ring_flush(struct drm_i915_gem_request *req, if (flush_domains) { flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_DC_FLUSH_ENABLE; flags |= PIPE_CONTROL_FLUSH_ENABLE; } if (invalidate_domains) { -- GitLab From 6765bd6dd28eb3c087e5011a2944c00872dd5906 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 14 Jan 2016 17:12:07 +0200 Subject: [PATCH 0216/5324] drm/i915/bios: Fix the sequence size calculations for MIPI seq v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two errors in a single line. The size was read from the wrong offset, and the end index didn't take the five bytes for sequence byte and size of sequence into account. Fix it all, and break up the calculations a bit to make it clearer. Cc: Ville Syrjälä Reported-and-tested-by: Mika Kahola Reviewed-by: Ville Syrjälä Fixes: 2a33d93486f2 ("drm/i915/bios: add support for MIPI sequence block v3") Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452784327-27258-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_bios.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 12e2f8b8bf9c..bf62a19c8f69 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -842,6 +842,7 @@ static int goto_next_sequence_v3(const u8 *data, int index, int total) { int seq_end; u16 len; + u32 size_of_sequence; /* * Could skip sequence based on Size of Sequence alone, but also do some @@ -852,14 +853,24 @@ static int goto_next_sequence_v3(const u8 *data, int index, int total) return 0; } - seq_end = index + *((const u32 *)(data + 1)); + /* Skip Sequence Byte. */ + index++; + + /* + * Size of Sequence. Excludes the Sequence Byte and the size itself, + * includes MIPI_SEQ_ELEM_END byte, excludes the final MIPI_SEQ_END + * byte. + */ + size_of_sequence = *((const uint32_t *)(data + index)); + index += 4; + + seq_end = index + size_of_sequence; if (seq_end > total) { DRM_ERROR("Invalid sequence size\n"); return 0; } - /* Skip Sequence Byte and Size of Sequence. */ - for (index = index + 5; index < total; index += len) { + for (; index < total; index += len) { u8 operation_byte = *(data + index); index++; -- GitLab From 013dd9e038723bbd2aa67be51847384b75be8253 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 13 Jan 2016 16:35:20 +0200 Subject: [PATCH 0217/5324] drm/i915/dp: fall back to 18 bpp when sink capability is unknown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per DP spec, the source device should fall back to 18 bpp, VESA range RGB when the sink capability is unknown. Fix the color depth clamping. 18 bpp color depth should ensure full color range in automatic mode. The clamping has been HDMI specific since its introduction in commit 996a2239f93b03c5972923f04b097f65565c5bed Author: Daniel Vetter Date: Fri Apr 19 11:24:34 2013 +0200 drm/i915: Disable high-bpc on pre-1.4 EDID screens Cc: stable@vger.kernel.org Reported-and-tested-by: Dihan Wickremasuriya Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=105331 Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452695720-7076-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aa24f79d85bf..68a98570f658 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12157,11 +12157,21 @@ connected_sink_compute_bpp(struct intel_connector *connector, pipe_config->pipe_bpp = connector->base.display_info.bpc*3; } - /* Clamp bpp to 8 on screens without EDID 1.4 */ - if (connector->base.display_info.bpc == 0 && bpp > 24) { - DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n", - bpp); - pipe_config->pipe_bpp = 24; + /* Clamp bpp to default limit on screens without EDID 1.4 */ + if (connector->base.display_info.bpc == 0) { + int type = connector->base.connector_type; + int clamp_bpp = 24; + + /* Fall back to 18 bpp when DP sink capability is unknown. */ + if (type == DRM_MODE_CONNECTOR_DisplayPort || + type == DRM_MODE_CONNECTOR_eDP) + clamp_bpp = 18; + + if (bpp > clamp_bpp) { + DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of %d\n", + bpp, clamp_bpp); + pipe_config->pipe_bpp = clamp_bpp; + } } } -- GitLab From 92752d9974882e2e5384e92668f02a134f9c7463 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 15 Jan 2016 14:46:29 +0100 Subject: [PATCH 0218/5324] mtd: mtk-nor: Drop bogus __init from mtk_nor_init() WARNING: drivers/mtd/spi-nor/mtk-quadspi.o(.text+0x77e): Section mismatch in reference from the function mtk_nor_drv_probe() to the function .init.text:mtk_nor_init() The function mtk_nor_drv_probe() references the function __init mtk_nor_init(). This is often because mtk_nor_drv_probe lacks a __init annotation or the annotation of mtk_nor_init is wrong. Drop the bogus __init from mtk_nor_init() to kill this warning. Signed-off-by: Geert Uytterhoeven Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/mtk-quadspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c index d5f850d035bb..8bed1a4cb79c 100644 --- a/drivers/mtd/spi-nor/mtk-quadspi.c +++ b/drivers/mtd/spi-nor/mtk-quadspi.c @@ -371,8 +371,8 @@ static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, return ret; } -static int __init mtk_nor_init(struct mt8173_nor *mt8173_nor, - struct device_node *flash_node) +static int mtk_nor_init(struct mt8173_nor *mt8173_nor, + struct device_node *flash_node) { int ret; struct spi_nor *nor; -- GitLab From f9bdbd6c46c8ce0bb95f5b708a4a4a4b6b9a5917 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 13 Jan 2016 22:38:08 +0100 Subject: [PATCH 0219/5324] mtd: nuc900_nand: read correct SMISR register The nuc900_nand driver has always passed an incorrect register address in its nuc900_check_rb() function, which cannot possibly work, and in some configurations gives us a build warning: drivers/mtd/nand/nuc900_nand.c: In function 'nuc900_check_rb': drivers/mtd/nand/nuc900_nand.c:27:23: warning: passing argument 1 of '__raw_readl' makes pointer from integer without a cast [-Wint-conversion] #define REG_SMISR 0xac drivers/mtd/nand/nuc900_nand.c:118:20: note: in expansion of macro 'REG_SMISR' val = __raw_readl(REG_SMISR); This makes sure we actually read from the register rather than from (void *)0x000000ac in user space. I suspect nobody noticed this before because the nuc900_nand_devready() function never gets called, or nobody uses this driver on an upstream kernel. Possibly even both. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- drivers/mtd/nand/nuc900_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 220ddfcf29f5..dbc5b571c2bb 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c @@ -113,7 +113,7 @@ static int nuc900_check_rb(struct nuc900_nand *nand) { unsigned int val; spin_lock(&nand->lock); - val = __raw_readl(REG_SMISR); + val = __raw_readl(nand->reg + REG_SMISR); val &= READYBUSY; spin_unlock(&nand->lock); -- GitLab From 1808f8cc6cb2842c53147eccfd5e88044d0d22a6 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Fri, 15 Jan 2016 13:10:52 -0500 Subject: [PATCH 0220/5324] Orangefs: add verification to decode_dirents Also add comments to decode_dirents and make it more readable. Signed-off-by: Mike Marshall --- fs/orangefs/dir.c | 118 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 25 deletions(-) diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 58558e37fb8a..6f5836d6a7a3 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -15,7 +15,14 @@ struct readdir_handle_s { }; /* - * decode routine needed by kmod to make sense of the shared page for readdirs. + * decode routine used by kmod to deal with the blob sent from + * userspace for readdirs. The blob contains zero or more of these + * sub-blobs: + * __u32 - represents length of the character string that follows. + * string - between 1 and ORANGEFS_NAME_MAX bytes long. + * padding - (if needed) to cause the __u32 plus the string to be + * eight byte aligned. + * khandle - sizeof(khandle) bytes. */ static long decode_dirents(char *ptr, size_t size, struct orangefs_readdir_response_s *readdir) @@ -24,54 +31,115 @@ static long decode_dirents(char *ptr, size_t size, struct orangefs_readdir_response_s *rd = (struct orangefs_readdir_response_s *) ptr; char *buf = ptr; + int khandle_size = sizeof(struct orangefs_khandle); + size_t offset = offsetof(struct orangefs_readdir_response_s, + dirent_array); + /* 8 reflects eight byte alignment */ + int smallest_blob = khandle_size + 8; + __u32 len; + int aligned_len; + int sizeof_u32 = sizeof(__u32); + long ret; - if (size < offsetof(struct orangefs_readdir_response_s, dirent_array)) - return -EINVAL; + gossip_debug(GOSSIP_DIR_DEBUG, "%s: size:%zu:\n", __func__, size); + + /* size is = offset on empty dirs, > offset on non-empty dirs... */ + if (size < offset) { + gossip_err("%s: size:%zu: offset:%zu:\n", + __func__, + size, + offset); + ret = -EINVAL; + goto out; + } + + if ((size == offset) && (readdir->orangefs_dirent_outcount != 0)) { + gossip_err("%s: size:%zu: dirent_outcount:%d:\n", + __func__, + size, + readdir->orangefs_dirent_outcount); + ret = -EINVAL; + goto out; + } readdir->token = rd->token; readdir->orangefs_dirent_outcount = rd->orangefs_dirent_outcount; readdir->dirent_array = kcalloc(readdir->orangefs_dirent_outcount, sizeof(*readdir->dirent_array), GFP_KERNEL); - if (readdir->dirent_array == NULL) - return -ENOMEM; + if (readdir->dirent_array == NULL) { + gossip_err("%s: kcalloc failed.\n", __func__); + ret = -ENOMEM; + goto out; + } - buf += offsetof(struct orangefs_readdir_response_s, dirent_array); - size -= offsetof(struct orangefs_readdir_response_s, dirent_array); + buf += offset; + size -= offset; for (i = 0; i < readdir->orangefs_dirent_outcount; i++) { - __u32 len; - - if (size < 4) - goto Einval; + if (size < smallest_blob) { + gossip_err("%s: size:%zu: smallest_blob:%d:\n", + __func__, + size, + smallest_blob); + ret = -EINVAL; + goto free; + } len = *(__u32 *)buf; - if (len >= (unsigned)-24) - goto Einval; + if ((len < 1) || (len > ORANGEFS_NAME_MAX)) { + gossip_err("%s: len:%d:\n", __func__, len); + ret = -EINVAL; + goto free; + } - readdir->dirent_array[i].d_name = buf + 4; + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: size:%zu: len:%d:\n", + __func__, + size, + len); + + readdir->dirent_array[i].d_name = buf + sizeof_u32; readdir->dirent_array[i].d_length = len; /* - * Round 4 + len + 1, which is the encoded size plus the string - * plus the null terminator to the nearest eight byte boundry. + * Calculate "aligned" length of this string and its + * associated __u32 descriptor. */ - len = ((4 + len + 1) + 7) & ~7; - if (size < len + 16) - goto Einval; - size -= len + 16; + aligned_len = ((sizeof_u32 + len + 1) + 7) & ~7; + gossip_debug(GOSSIP_DIR_DEBUG, + "%s: aligned_len:%d:\n", + __func__, + aligned_len); - buf += len; + /* + * The end of the blob should coincide with the end + * of the last sub-blob. + */ + if (size < aligned_len + khandle_size) { + gossip_err("%s: ran off the end of the blob.\n", + __func__); + ret = -EINVAL; + goto free; + } + size -= aligned_len + khandle_size; + + buf += aligned_len; readdir->dirent_array[i].khandle = *(struct orangefs_khandle *) buf; - buf += 16; + buf += khandle_size; } - return buf - ptr; -Einval: + ret = buf - ptr; + gossip_debug(GOSSIP_DIR_DEBUG, "%s: returning:%ld:\n", __func__, ret); + goto out; + +free: kfree(readdir->dirent_array); readdir->dirent_array = NULL; - return -EINVAL; + +out: + return ret; } static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf, -- GitLab From 0b05e1e0c945ff4e8635890982fafa5434b262d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Jan 2016 15:22:09 +0200 Subject: [PATCH 0221/5324] drm/i915: Don't leak framebuffer_references if drm_framebuffer_init() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't increment obj->framebuffer_references until we know we actually managed to create the framebuffer. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452777736-4909-2-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 68a98570f658..c532c3d605ac 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14905,7 +14905,6 @@ static int intel_framebuffer_init(struct drm_device *dev, drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); intel_fb->obj = obj; - intel_fb->obj->framebuffer_references++; ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); if (ret) { @@ -14913,6 +14912,8 @@ static int intel_framebuffer_init(struct drm_device *dev, return ret; } + intel_fb->obj->framebuffer_references++; + return 0; } -- GitLab From b5e16987a09ef3e3215f0d14a0d99b4e83ab7e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Jan 2016 15:22:10 +0200 Subject: [PATCH 0222/5324] drm/i915: Set i915_ggtt_view_normal type explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just for clarity set the type for i915_ggtt_view_normal explicitly. While at it fix the indentation fail for i915_ggtt_view_rotated. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452777736-4909-3-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 56f4f2e58d53..d7f9ddd52840 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -96,9 +96,11 @@ static int i915_get_ggtt_vma_pages(struct i915_vma *vma); -const struct i915_ggtt_view i915_ggtt_view_normal; +const struct i915_ggtt_view i915_ggtt_view_normal = { + .type = I915_GGTT_VIEW_NORMAL, +}; const struct i915_ggtt_view i915_ggtt_view_rotated = { - .type = I915_GGTT_VIEW_ROTATED + .type = I915_GGTT_VIEW_ROTATED, }; static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) -- GitLab From 2d7f3bdb2cf6656386cb9ca1b02dd6df66fb05e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 14 Jan 2016 15:22:11 +0200 Subject: [PATCH 0223/5324] drm/i915: Pass the dma_addr_t array as const to rotate_pages() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rotate_pages() doesn't modify the passed in dma addresses, so make them const. Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452777736-4909-4-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d7f9ddd52840..7377b6725c33 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3331,7 +3331,7 @@ i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, } static struct scatterlist * -rotate_pages(dma_addr_t *in, unsigned int offset, +rotate_pages(const dma_addr_t *in, unsigned int offset, unsigned int width, unsigned int height, struct sg_table *st, struct scatterlist *sg) { -- GitLab From 07096bd3c9d83f043c733c592974aa8ea93ba2db Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 14 Jan 2016 14:00:09 +0800 Subject: [PATCH 0224/5324] drm/crtc_helper/set_config: Remove redundant handling when set->fb is NULL We've done sanity NULL pointer check on set->fb at the beginning of drm_crtc_helper_set_config() and bailed out if necessary, thus any later on check or case handling is redundant. Signed-off-by: Liu Ying Link: http://patchwork.freedesktop.org/patch/msgid/1452751210-19216-1-git-send-email-gnuiyl@gmail.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a02a7f9a6a9d..63e88819b91e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -578,8 +578,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (set->crtc->primary->fb == NULL) { DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); mode_changed = true; - } else if (set->fb == NULL) { - mode_changed = true; } else if (set->fb->pixel_format != set->crtc->primary->fb->pixel_format) { mode_changed = true; -- GitLab From 2deafc7e163be631183bdfc066e2f636e7818e00 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 14 Jan 2016 14:00:10 +0800 Subject: [PATCH 0225/5324] drm/crtc_helper/set_config: Remove redundant NULL pointer check on set->mode We've done sanity NULL pointer check on set->mode at the beginning of drm_crtc_helper_set_config() and bailed out if necessary, thus any later on check is redundant. Signed-off-by: Liu Ying Link: http://patchwork.freedesktop.org/patch/msgid/1452751210-19216-2-git-send-email-gnuiyl@gmail.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 63e88819b91e..5d4bc6441d88 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -588,7 +588,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (set->x != set->crtc->x || set->y != set->crtc->y) fb_changed = true; - if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { + if (!drm_mode_equal(set->mode, &set->crtc->mode)) { DRM_DEBUG_KMS("modes are different, full mode set\n"); drm_mode_debug_printmodeline(&set->crtc->mode); drm_mode_debug_printmodeline(set->mode); -- GitLab From c6c5c7fa7f3ec7d35541e9e4c6feb4ccd6cca7c9 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 18 Jan 2016 11:36:35 +0800 Subject: [PATCH 0226/5324] drm/atomic-helper: Remove redundant local var old_crtc_state in disable_outputs One of the two local variables old_crtc_state is redundantly defined in the function disable_outputs(). It has only a scope partway through the block for_each_connector_in_state. So, let's remove it and use the one which has the scope within the function disable_outputs(). Signed-off-by: Liu Ying Link: http://patchwork.freedesktop.org/patch/msgid/1453088195-2564-1-git-send-email-gnuiyl@gmail.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 57cccd68ca52..b9d8b5393955 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -617,7 +617,6 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) for_each_connector_in_state(old_state, connector, old_conn_state, i) { const struct drm_encoder_helper_funcs *funcs; struct drm_encoder *encoder; - struct drm_crtc_state *old_crtc_state; /* Shut down everything that's in the changeset and currently * still on. So need to check the old, saved state. */ -- GitLab From e0313db047c2f2e368c95a8f03653f9723678e82 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 15 Jan 2016 15:11:12 +0000 Subject: [PATCH 0227/5324] drm/i915: Only grab timestamps when needed No need to call ktime_get_raw_ns twice per unlimited wait and can also elimate a local variable. v2: Added comment about silencing the compiler warning. (Daniel Vetter) Signed-off-by: Tvrtko Ursulin Reviewed-by: Dave Gordon Acked-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452870672-13901-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_gem.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ddc21d4b388d..6b0102da859c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1251,7 +1251,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; DEFINE_WAIT(wait); unsigned long timeout_expire; - s64 before, now; + s64 before = 0; /* Only to silence a compiler warning. */ int ret; WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled"); @@ -1271,14 +1271,17 @@ int __i915_wait_request(struct drm_i915_gem_request *req, return -ETIME; timeout_expire = jiffies + nsecs_to_jiffies_timeout(*timeout); + + /* + * Record current time in case interrupted by signal, or wedged. + */ + before = ktime_get_raw_ns(); } if (INTEL_INFO(dev_priv)->gen >= 6) gen6_rps_boost(dev_priv, rps, req->emitted_jiffies); - /* Record current time in case interrupted by signal, or wedged */ trace_i915_gem_request_wait_begin(req); - before = ktime_get_raw_ns(); /* Optimistic spin for the next jiffie before touching IRQs */ ret = __i915_spin_request(req, state); @@ -1343,11 +1346,10 @@ int __i915_wait_request(struct drm_i915_gem_request *req, finish_wait(&ring->irq_queue, &wait); out: - now = ktime_get_raw_ns(); trace_i915_gem_request_wait_end(req); if (timeout) { - s64 tres = *timeout - (now - before); + s64 tres = *timeout - (ktime_get_raw_ns() - before); *timeout = tres < 0 ? 0 : tres; -- GitLab From ca82580c9ceace0d52fe7376b8a72bb3b36f612b Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 15 Jan 2016 15:10:27 +0000 Subject: [PATCH 0228/5324] drm/i915: Do not call API requiring struct_mutex where it is not available LRC code was calling GEM API like i915_gem_obj_ggtt_offset from places where the struct_mutex cannot be grabbed (irq handlers). To avoid that this patch caches some interesting bits and values in the engine and context structures. Some usages are also removed where they are not needed like a few asserts which are either impossible or have been checked already during engine initialization. Side benefit is also that interrupt handlers and command submission stop evaluating invariant conditionals, like what Gen we are running on, on every interrupt and every command submitted. This patch deals with logical ring context id and descriptors while subsequent patches will deal with the remaining issues. v2: * Cache the VMA instead of the address. (Chris Wilson) * Incorporate Dave Gordon's good comments and function name. v3: * Extract ctx descriptor template to a function and group functions dealing with ctx descriptor & co together near top of the file. (Dave Gordon) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Daniel Vetter Cc: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1452870629-13830-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 15 +-- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem_gtt.h | 1 - drivers/gpu/drm/i915/intel_lrc.c | 151 ++++++++++++++---------- drivers/gpu/drm/i915/intel_lrc.h | 4 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + 6 files changed, 103 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e3377abc0d4d..0b3550f05026 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1994,12 +1994,13 @@ static int i915_context_status(struct seq_file *m, void *unused) } static void i915_dump_lrc_obj(struct seq_file *m, - struct intel_engine_cs *ring, - struct drm_i915_gem_object *ctx_obj) + struct intel_context *ctx, + struct intel_engine_cs *ring) { struct page *page; uint32_t *reg_state; int j; + struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; unsigned long ggtt_offset = 0; if (ctx_obj == NULL) { @@ -2009,7 +2010,7 @@ static void i915_dump_lrc_obj(struct seq_file *m, } seq_printf(m, "CONTEXT: %s %u\n", ring->name, - intel_execlists_ctx_id(ctx_obj)); + intel_execlists_ctx_id(ctx, ring)); if (!i915_gem_obj_ggtt_bound(ctx_obj)) seq_puts(m, "\tNot bound in GGTT\n"); @@ -2058,8 +2059,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) { for_each_ring(ring, dev_priv, i) { if (ring->default_context != ctx) - i915_dump_lrc_obj(m, ring, - ctx->engine[i].state); + i915_dump_lrc_obj(m, ctx, ring); } } @@ -2133,11 +2133,8 @@ static int i915_execlists(struct seq_file *m, void *data) seq_printf(m, "\t%d requests in queue\n", count); if (head_req) { - struct drm_i915_gem_object *ctx_obj; - - ctx_obj = head_req->ctx->engine[ring_id].state; seq_printf(m, "\tHead request id: %u\n", - intel_execlists_ctx_id(ctx_obj)); + intel_execlists_ctx_id(head_req->ctx, ring)); seq_printf(m, "\tHead request tail: %u\n", head_req->tail); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb7bb97f7316..acff98b9c148 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -888,6 +888,8 @@ struct intel_context { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; int pin_count; + struct i915_vma *lrc_vma; + u64 lrc_desc; } engine[I915_NUM_RINGS]; struct list_head link; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index b448ad832dcf..e5737963ab79 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -44,7 +44,6 @@ typedef uint64_t gen8_ppgtt_pml4e_t; #define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) - /* gen6-hsw has bit 11-4 for physical addr bit 39-32 */ #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f5d89c845ede..86042dc1802c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -263,65 +263,92 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +static void +logical_ring_init_platform_invariants(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + + ring->disable_lite_restore_wa = (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || + IS_BXT_REVID(dev, 0, BXT_REVID_A1)) && + (ring->id == VCS || ring->id == VCS2); + + ring->ctx_desc_template = GEN8_CTX_VALID; + ring->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) << + GEN8_CTX_ADDRESSING_MODE_SHIFT; + if (IS_GEN8(dev)) + ring->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT; + ring->ctx_desc_template |= GEN8_CTX_PRIVILEGE; + + /* TODO: WaDisableLiteRestore when we start using semaphore + * signalling between Command Streamers */ + /* ring->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE; */ + + /* WaEnableForceRestoreInCtxtDescForVCS:skl */ + /* WaEnableForceRestoreInCtxtDescForVCS:bxt */ + if (ring->disable_lite_restore_wa) + ring->ctx_desc_template |= GEN8_CTX_FORCE_RESTORE; +} + /** - * intel_execlists_ctx_id() - get the Execlists Context ID - * @ctx_obj: Logical Ring Context backing object. + * intel_lr_context_descriptor_update() - calculate & cache the descriptor + * descriptor for a pinned context * - * Do not confuse with ctx->id! Unfortunately we have a name overload - * here: the old context ID we pass to userspace as a handler so that - * they can refer to a context, and the new context ID we pass to the - * ELSP so that the GPU can inform us of the context status via - * interrupts. + * @ctx: Context to work on + * @ring: Engine the descriptor will be used with * - * Return: 20-bits globally unique context ID. + * The context descriptor encodes various attributes of a context, + * including its GTT address and some flags. Because it's fairly + * expensive to calculate, we'll just do it once and cache the result, + * which remains valid until the context is unpinned. + * + * This is what a descriptor looks like, from LSB to MSB: + * bits 0-11: flags, GEN8_CTX_* (cached in ctx_desc_template) + * bits 12-31: LRCA, GTT address of (the HWSP of) this context + * bits 32-51: ctx ID, a globally unique tag (the LRCA again!) + * bits 52-63: reserved, may encode the engine ID (for GuC) */ -u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj) +static void +intel_lr_context_descriptor_update(struct intel_context *ctx, + struct intel_engine_cs *ring) { - u32 lrca = i915_gem_obj_ggtt_offset(ctx_obj) + - LRC_PPHWSP_PN * PAGE_SIZE; + uint64_t lrca, desc; - /* LRCA is required to be 4K aligned so the more significant 20 bits - * are globally unique */ - return lrca >> 12; -} + lrca = ctx->engine[ring->id].lrc_vma->node.start + + LRC_PPHWSP_PN * PAGE_SIZE; -static bool disable_lite_restore_wa(struct intel_engine_cs *ring) -{ - struct drm_device *dev = ring->dev; + desc = ring->ctx_desc_template; /* bits 0-11 */ + desc |= lrca; /* bits 12-31 */ + desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */ - return (IS_SKL_REVID(dev, 0, SKL_REVID_B0) || - IS_BXT_REVID(dev, 0, BXT_REVID_A1)) && - (ring->id == VCS || ring->id == VCS2); + ctx->engine[ring->id].lrc_desc = desc; } uint64_t intel_lr_context_descriptor(struct intel_context *ctx, struct intel_engine_cs *ring) { - struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; - uint64_t desc; - uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj) + - LRC_PPHWSP_PN * PAGE_SIZE; - - WARN_ON(lrca & 0xFFFFFFFF00000FFFULL); - - desc = GEN8_CTX_VALID; - desc |= GEN8_CTX_ADDRESSING_MODE(dev) << GEN8_CTX_ADDRESSING_MODE_SHIFT; - if (IS_GEN8(ctx_obj->base.dev)) - desc |= GEN8_CTX_L3LLC_COHERENT; - desc |= GEN8_CTX_PRIVILEGE; - desc |= lrca; - desc |= (u64)intel_execlists_ctx_id(ctx_obj) << GEN8_CTX_ID_SHIFT; - - /* TODO: WaDisableLiteRestore when we start using semaphore - * signalling between Command Streamers */ - /* desc |= GEN8_CTX_FORCE_RESTORE; */ - - /* WaEnableForceRestoreInCtxtDescForVCS:skl */ - /* WaEnableForceRestoreInCtxtDescForVCS:bxt */ - if (disable_lite_restore_wa(ring)) - desc |= GEN8_CTX_FORCE_RESTORE; + return ctx->engine[ring->id].lrc_desc; +} - return desc; +/** + * intel_execlists_ctx_id() - get the Execlists Context ID + * @ctx: Context to get the ID for + * @ring: Engine to get the ID for + * + * Do not confuse with ctx->id! Unfortunately we have a name overload + * here: the old context ID we pass to userspace as a handler so that + * they can refer to a context, and the new context ID we pass to the + * ELSP so that the GPU can inform us of the context status via + * interrupts. + * + * The context ID is a portion of the context descriptor, so we can + * just extract the required part from the cached descriptor. + * + * Return: 20-bits globally unique context ID. + */ +u32 intel_execlists_ctx_id(struct intel_context *ctx, + struct intel_engine_cs *ring) +{ + return intel_lr_context_descriptor(ctx, ring) >> GEN8_CTX_ID_SHIFT; } static void execlists_elsp_write(struct drm_i915_gem_request *rq0, @@ -369,8 +396,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) uint32_t *reg_state; BUG_ON(!ctx_obj); - WARN_ON(!i915_gem_obj_is_pinned(ctx_obj)); - WARN_ON(!i915_gem_obj_is_pinned(rb_obj)); page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN); reg_state = kmap_atomic(page); @@ -477,9 +502,7 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, execlist_link); if (head_req != NULL) { - struct drm_i915_gem_object *ctx_obj = - head_req->ctx->engine[ring->id].state; - if (intel_execlists_ctx_id(ctx_obj) == request_id) { + if (intel_execlists_ctx_id(head_req->ctx, ring) == request_id) { WARN(head_req->elsp_submitted == 0, "Never submitted head request\n"); @@ -556,7 +579,7 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring) } } - if (disable_lite_restore_wa(ring)) { + if (ring->disable_lite_restore_wa) { /* Prevent a ctx to preempt itself */ if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) && (submit_contexts != 0)) @@ -1039,14 +1062,16 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) } static int intel_lr_context_do_pin(struct intel_engine_cs *ring, - struct drm_i915_gem_object *ctx_obj, - struct intel_ringbuffer *ringbuf) + struct intel_context *ctx) { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - int ret = 0; + struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + int ret; WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, PIN_OFFSET_BIAS | GUC_WOPCM_TOP); if (ret) @@ -1056,6 +1081,8 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, if (ret) goto unpin_ctx_obj; + ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); + intel_lr_context_descriptor_update(ctx, ring); ctx_obj->dirty = true; /* Invalidate GuC TLB. */ @@ -1074,11 +1101,9 @@ static int intel_lr_context_pin(struct drm_i915_gem_request *rq) { int ret = 0; struct intel_engine_cs *ring = rq->ring; - struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; - struct intel_ringbuffer *ringbuf = rq->ringbuf; if (rq->ctx->engine[ring->id].pin_count++ == 0) { - ret = intel_lr_context_do_pin(ring, ctx_obj, ringbuf); + ret = intel_lr_context_do_pin(ring, rq->ctx); if (ret) goto reset_pin_count; } @@ -1100,6 +1125,8 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq) if (--rq->ctx->engine[ring->id].pin_count == 0) { intel_unpin_ringbuffer_obj(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); + rq->ctx->engine[ring->id].lrc_vma = NULL; + rq->ctx->engine[ring->id].lrc_desc = 0; } } } @@ -1939,6 +1966,9 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) ring->status_page.obj = NULL; } + ring->disable_lite_restore_wa = false; + ring->ctx_desc_template = 0; + lrc_destroy_wa_ctx_obj(ring); ring->dev = NULL; } @@ -1989,6 +2019,8 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) INIT_LIST_HEAD(&ring->execlist_retired_req_list); spin_lock_init(&ring->execlist_lock); + logical_ring_init_platform_invariants(ring); + ret = i915_cmd_parser_init_ring(ring); if (ret) goto error; @@ -1998,10 +2030,7 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) goto error; /* As this is the default context, always pin it */ - ret = intel_lr_context_do_pin( - ring, - ring->default_context->engine[ring->id].state, - ring->default_context->engine[ring->id].ringbuf); + ret = intel_lr_context_do_pin(ring, ring->default_context); if (ret) { DRM_ERROR( "Failed to pin and map ringbuffer %s: %d\n", diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index de41ad6cd63d..49af638f6213 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -107,13 +107,15 @@ void intel_lr_context_reset(struct drm_device *dev, uint64_t intel_lr_context_descriptor(struct intel_context *ctx, struct intel_engine_cs *ring); +u32 intel_execlists_ctx_id(struct intel_context *ctx, + struct intel_engine_cs *ring); + /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); struct i915_execbuffer_params; int intel_execlists_submission(struct i915_execbuffer_params *params, struct drm_i915_gem_execbuffer2 *args, struct list_head *vmas); -u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj); void intel_lrc_irq_handler(struct intel_engine_cs *ring); void intel_execlists_retire_requests(struct intel_engine_cs *ring); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 7349d9258191..85ce2272f92c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -269,6 +269,8 @@ struct intel_engine_cs { struct list_head execlist_queue; struct list_head execlist_retired_req_list; u8 next_context_status_buffer; + bool disable_lite_restore_wa; + u32 ctx_desc_template; u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct drm_i915_gem_request *request); int (*emit_flush)(struct drm_i915_gem_request *request, -- GitLab From 0eb973d31d0aadb6bc801fd6d796afecbbfc3d5b Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 15 Jan 2016 15:10:28 +0000 Subject: [PATCH 0229/5324] drm/i915: Cache ringbuffer GTT VMA Purpose is to avoid calling i915_gem_obj_ggtt_offset from the interrupt context without the big lock held. v2: Renamed gtt_start to gtt_offset. (Daniel Vetter) v3: Cache the VMA instead of address. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Daniel Vetter Cc: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452870629-13830-2-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 3 +-- drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 86042dc1802c..588cad58a196 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -391,7 +391,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) struct intel_engine_cs *ring = rq->ring; struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; - struct drm_i915_gem_object *rb_obj = rq->ringbuf->obj; struct page *page; uint32_t *reg_state; @@ -401,7 +400,7 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) reg_state = kmap_atomic(page); reg_state[CTX_RING_TAIL+1] = rq->tail; - reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(rb_obj); + reg_state[CTX_RING_BUFFER_START+1] = rq->ringbuf->vma->node.start; if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) { /* True 32b PPGTT with dynamic page allocation: update PDP diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8cd8aabcc3ff..d4e33ac02efa 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1999,6 +1999,7 @@ void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf) else iounmap(ringbuf->virtual_start); ringbuf->virtual_start = NULL; + ringbuf->vma = NULL; i915_gem_object_ggtt_unpin(ringbuf->obj); } @@ -2065,6 +2066,8 @@ int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, } } + ringbuf->vma = i915_gem_obj_to_ggtt(obj); + return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 85ce2272f92c..ede57954080e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -99,6 +99,7 @@ struct intel_ring_hangcheck { struct intel_ringbuffer { struct drm_i915_gem_object *obj; void __iomem *virtual_start; + struct i915_vma *vma; struct intel_engine_cs *ring; struct list_head link; -- GitLab From 82352e908acd36d7244c75a008c9f27a2ced44d5 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 15 Jan 2016 17:12:45 +0000 Subject: [PATCH 0230/5324] drm/i915: Cache LRC state page in the context LRC lifetime is well defined so we can cache the page pointing to the object backing store in the context in order to avoid walking over the object SG page list from the interrupt context without the big lock held. v2: Also cache the mapping. (Chris Wilson) v3: Unmap on the error path. v4: No need to cache the page. (Chris Wilson) v5: No need to dirty the page on unpin. (Chris Wilson) v6: kmap() cannot fail and use kmap_to_page to simplify unpin. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Dave Gordon Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1452877965-32042-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 39 +++++++++++++++++--------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index acff98b9c148..af301482e6f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -890,6 +890,7 @@ struct intel_context { int pin_count; struct i915_vma *lrc_vma; u64 lrc_desc; + uint32_t *lrc_reg_state; } engine[I915_NUM_RINGS]; struct list_head link; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 588cad58a196..faaf49077fea 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -390,14 +390,7 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) { struct intel_engine_cs *ring = rq->ring; struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; - struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; - struct page *page; - uint32_t *reg_state; - - BUG_ON(!ctx_obj); - - page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN); - reg_state = kmap_atomic(page); + uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state; reg_state[CTX_RING_TAIL+1] = rq->tail; reg_state[CTX_RING_BUFFER_START+1] = rq->ringbuf->vma->node.start; @@ -414,8 +407,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) ASSIGN_CTX_PDP(ppgtt, reg_state, 0); } - kunmap_atomic(reg_state); - return 0; } @@ -1067,6 +1058,7 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + struct page *lrc_state_page; int ret; WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); @@ -1076,12 +1068,19 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, if (ret) return ret; + lrc_state_page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN); + if (WARN_ON(!lrc_state_page)) { + ret = -ENODEV; + goto unpin_ctx_obj; + } + ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf); if (ret) goto unpin_ctx_obj; ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); intel_lr_context_descriptor_update(ctx, ring); + ctx->engine[ring->id].lrc_reg_state = kmap(lrc_state_page); ctx_obj->dirty = true; /* Invalidate GuC TLB. */ @@ -1119,14 +1118,18 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq) struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; struct intel_ringbuffer *ringbuf = rq->ringbuf; - if (ctx_obj) { - WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); - if (--rq->ctx->engine[ring->id].pin_count == 0) { - intel_unpin_ringbuffer_obj(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); - rq->ctx->engine[ring->id].lrc_vma = NULL; - rq->ctx->engine[ring->id].lrc_desc = 0; - } + WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + + if (!ctx_obj) + return; + + if (--rq->ctx->engine[ring->id].pin_count == 0) { + kunmap(kmap_to_page(rq->ctx->engine[ring->id].lrc_reg_state)); + intel_unpin_ringbuffer_obj(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); + rq->ctx->engine[ring->id].lrc_vma = NULL; + rq->ctx->engine[ring->id].lrc_desc = 0; + rq->ctx->engine[ring->id].lrc_reg_state = NULL; } } -- GitLab From a9d8adad731171559b24eb27c9db4a64238b7ef0 Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Wed, 13 Jan 2016 11:01:50 -0800 Subject: [PATCH 0231/5324] drm/i915/guc: Fix a memory leak where guc->execbuf_client is not freed During driver unloading, the guc_client created for command submission needs to be released to avoid memory leak. The struct_mutex needs to be held before tearing down GuC. v1: Move i915_guc_submission_disable out of i915_guc_submission_fini and take struct_mutex lock before release GuC client. (Dave Gordon) v2: Add the locking for failure case in guc_fw_fetch. (Dave Gordon) Add i915_guc_submission_fini for failure case in intel_guc_ucode_load. Signed-off-by: Alex Dai Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1452711710-4505-1-git-send-email-yu.dai@intel.com --- drivers/gpu/drm/i915/intel_guc_loader.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index d20788ffd341..3accd914490f 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -445,6 +445,7 @@ int intel_guc_ucode_load(struct drm_device *dev) direct_interrupts_to_host(dev_priv); i915_guc_submission_disable(dev); + i915_guc_submission_fini(dev); return err; } @@ -561,10 +562,12 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw) DRM_ERROR("Failed to fetch GuC firmware from %s (error %d)\n", guc_fw->guc_fw_path, err); + mutex_lock(&dev->struct_mutex); obj = guc_fw->guc_fw_obj; if (obj) drm_gem_object_unreference(&obj->base); guc_fw->guc_fw_obj = NULL; + mutex_unlock(&dev->struct_mutex); release_firmware(fw); /* OK even if fw is NULL */ guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL; @@ -631,10 +634,11 @@ void intel_guc_ucode_fini(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; + mutex_lock(&dev->struct_mutex); direct_interrupts_to_host(dev_priv); + i915_guc_submission_disable(dev); i915_guc_submission_fini(dev); - mutex_lock(&dev->struct_mutex); if (guc_fw->guc_fw_obj) drm_gem_object_unreference(&guc_fw->guc_fw_obj->base); guc_fw->guc_fw_obj = NULL; -- GitLab From 693bdc28a733dba68b86af295e7509812fec35d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 15 Jan 2016 20:46:53 +0200 Subject: [PATCH 0232/5324] drm/i915: Don't reject primary plane windowing with color keying enabled on SKL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On SKL+ plane scaling is mutually exclusive with color keying. The code check for this, but during some refactoring the code got changed to also reject primary plane windowing when color keying is used. There is no such restriction in the hardware, so restore the original logic. Cc: Maarten Lankhorst Fixes: 061e4b8d650a ("drm/i915: clean up atomic plane check functions, v2.") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1452883613-28549-1-git-send-email-ville.syrjala@linux.intel.com Cc: stable@vger.kernel.org Reviewed-by: Matt Roper Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_display.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccb3e3f47450..9b6e726666c3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14019,11 +14019,12 @@ intel_check_primary_plane(struct drm_plane *plane, int max_scale = DRM_PLANE_HELPER_NO_SCALING; bool can_position = false; - /* use scaler when colorkey is not required */ - if (INTEL_INFO(plane->dev)->gen >= 9 && - state->ckey.flags == I915_SET_COLORKEY_NONE) { - min_scale = 1; - max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state); + if (INTEL_INFO(plane->dev)->gen >= 9) { + /* use scaler when colorkey is not required */ + if (state->ckey.flags == I915_SET_COLORKEY_NONE) { + min_scale = 1; + max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state); + } can_position = true; } -- GitLab From fa5a7970d372c9c9beb3a0ce79ee1d0c23387d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 15 Oct 2015 17:01:58 +0300 Subject: [PATCH 0233/5324] drm/i915: skl_update_scaler() wants a rotation bitmask instead of bit number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass BIT(DRM_ROTATE_0) instead of DRM_ROTATE_0 to skl_update_scaler(). The former is a mask, the latter just the bit number. Fortunately the only thing skl_update_scaler() does with the rotation is check if it's 90/270 degrees or not, and so in this case it would still do the right thing. Cc: Chandra Konduru Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1444917718-28495-1-git-send-email-ville.syrjala@linux.intel.com Fixes: 6156a45602f9 ("drm/i915: skylake primary plane scaling using shared scalers") Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9b6e726666c3..a851cb70479e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4438,7 +4438,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX); return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, - &state->scaler_state.scaler_id, DRM_ROTATE_0, + &state->scaler_state.scaler_id, BIT(DRM_ROTATE_0), state->pipe_src_w, state->pipe_src_h, adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); } -- GitLab From aa45950bac01bf9319328e67696cf0b231cec39d Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Mon, 18 Jan 2016 23:54:20 +0800 Subject: [PATCH 0234/5324] drm/i915: use hlist_for_each_entry Use hlist_for_each_entry() instead of hlist_for_each() to simplify the code. Signed-off-by: Geliang Tang Link: http://patchwork.freedesktop.org/patch/msgid/b80568b2990ebcc145229a132f045e852ac51ad6.1453126187.git.geliangtang@163.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d469c4779ff5..4edf1c062210 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -193,13 +193,10 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle) return eb->lut[handle]; } else { struct hlist_head *head; - struct hlist_node *node; + struct i915_vma *vma; head = &eb->buckets[handle & eb->and]; - hlist_for_each(node, head) { - struct i915_vma *vma; - - vma = hlist_entry(node, struct i915_vma, exec_node); + hlist_for_each_entry(vma, head, exec_node) { if (vma->exec_handle == handle) return vma; } -- GitLab From 25aaa3a1e5dba6256fd4a548f088ee1ebbc4b5f8 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 19 Jan 2016 09:26:48 +0100 Subject: [PATCH 0235/5324] drm: initialize default rotation value to DRM_ROTATE_0 When no console framebuffer is enabled, the default plane state is defined by plane reset function. If driver uses generic helper, then rotation property is set to zero. This is not a valid value for that enum. This patch sets default rotation value to DRM_ROTATE_0. Signed-off-by: Marek Szyprowski Link: http://patchwork.freedesktop.org/patch/msgid/1453192008-13283-1-git-send-email-m.szyprowski@samsung.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index b9d8b5393955..f0c39840bacf 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2532,8 +2532,10 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane) kfree(plane->state); plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); - if (plane->state) + if (plane->state) { plane->state->plane = plane; + plane->state->rotation = BIT(DRM_ROTATE_0); + } } EXPORT_SYMBOL(drm_atomic_helper_plane_reset); -- GitLab From cbfc2d26ac7364b45fbc6f5790a043c72c8a2230 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Jan 2016 17:38:15 +0000 Subject: [PATCH 0236/5324] drm/i915: Demote user facing DMC firmware load failure message This is an expected error given the lack of the firmware so emit it at KERN_NOTICE and not KERN_ERROR. Also include the firmware URL in the user facing message so that the user can investigate and fix the issue on their own, and also explain the consequence in plain language. The complete failure message, including the first line from the firmware loader, becomes i915 0000:00:02.0: Direct firmware load for i915/skl_dmc_ver1.bin failed with error -2 i915 0000:00:02.0: Failed to load DMC firmware [https://01.org/linuxgraphics/intel-linux-graphics-firmwares], disabling runtime power management. Signed-off-by: Chris Wilson Cc: Damien Lespiau Cc: Imre Deak Cc: Sunil Kamath Cc: Daniel Vetter Cc: Animesh Manna Cc: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452706695-13518-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_csr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 3f2850029c17..5c2f9a40c81b 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -44,6 +44,8 @@ #define I915_CSR_SKL "i915/skl_dmc_ver1.bin" #define I915_CSR_BXT "i915/bxt_dmc_ver1.bin" +#define FIRMWARE_URL "https://01.org/linuxgraphics/intel-linux-graphics-firmwares" + MODULE_FIRMWARE(I915_CSR_SKL); MODULE_FIRMWARE(I915_CSR_BXT); @@ -282,7 +284,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, csr->version < SKL_CSR_VERSION_REQUIRED) { DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," " please upgrade to v%u.%u or later" - " [https://01.org/linuxgraphics/intel-linux-graphics-firmwares].\n", + " [" FIRMWARE_URL "].\n", CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version), CSR_VERSION_MAJOR(SKL_CSR_VERSION_REQUIRED), @@ -400,7 +402,10 @@ static void csr_load_work_fn(struct work_struct *work) CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version)); } else { - DRM_ERROR("Failed to load DMC firmware, disabling rpm\n"); + dev_notice(dev_priv->dev->dev, + "Failed to load DMC firmware" + " [" FIRMWARE_URL "]," + " disabling runtime power management.\n"); } release_firmware(fw); -- GitLab From cf0c27715bd640628d39421f3d232c87d7e08954 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Tue, 19 Jan 2016 12:04:40 -0500 Subject: [PATCH 0237/5324] Orangefs: make gossip statement more palatable to xtensa Thanks to Intel's kbuild test robot Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 4 ++-- fs/orangefs/orangefs-kernel.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 0f01d3edfc2b..5da5ef616b85 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -275,10 +275,10 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ret); if (total < MAX_DEV_REQ_DOWNSIZE) { - gossip_err("%s: total:%d: must be at least:%lu:\n", + gossip_err("%s: total:%d: must be at least:%u:\n", __func__, total, - MAX_DEV_REQ_DOWNSIZE); + (unsigned int) MAX_DEV_REQ_DOWNSIZE); ret = -EFAULT; goto out; } diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 1c87e0bbdfe8..6dcc38a5f117 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -75,9 +75,9 @@ #define ORANGEFS_MAX_MOUNT_OPT_LEN 0x00000080 #define ORANGEFS_MAX_FSKEY_LEN 64 -#define MAX_DEV_REQ_UPSIZE (2*sizeof(__s32) + \ +#define MAX_DEV_REQ_UPSIZE (2 * sizeof(__s32) + \ sizeof(__u64) + sizeof(struct orangefs_upcall_s)) -#define MAX_DEV_REQ_DOWNSIZE (2*sizeof(__s32) + \ +#define MAX_DEV_REQ_DOWNSIZE (2 * sizeof(__s32) + \ sizeof(__u64) + sizeof(struct orangefs_downcall_s)) /* borrowed from irda.h */ -- GitLab From f3272e7a7456240209e758d6a995acbae1d21e8e Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Mon, 18 Jan 2016 15:59:36 +0000 Subject: [PATCH 0238/5324] drm/i915/gen9: Correct max save/restore register count during gpu reset with GuC In GuC submission mode, driver has to provide a list of registers to be save/restored during gpu reset, make the max no. of registers value consistent with that of the value defined in FW. If they are not in sync then register save/restore during gpu reset won't work as expected. Cc: Alex Dai Cc: Dave Gordon Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453132776-22229-1-git-send-email-arun.siluvery@linux.intel.com Reviewed-by: Alex Dai Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_guc_fwif.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index b4632f0bf7b2..1856a4740b83 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -370,7 +370,7 @@ struct guc_policies { #define GUC_REGSET_SAVE_DEFAULT_VALUE 0x8 #define GUC_REGSET_SAVE_CURRENT_VALUE 0x10 -#define GUC_REGSET_MAX_REGISTERS 20 +#define GUC_REGSET_MAX_REGISTERS 25 #define GUC_MMIO_WHITE_LIST_START 0x24d0 #define GUC_MMIO_WHITE_LIST_MAX 12 #define GUC_S3_SAVE_SPACE_PAGES 10 -- GitLab From 38e5cced0173657853cf1f058b59f869630cad7a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 18 Jan 2016 09:19:46 +0200 Subject: [PATCH 0239/5324] drm/i915/sdvo: revert bogus kernel-doc comments to normal comments The comments were never proper kernel-doc, but with SDVO it's not worth the trouble to make them kernel-doc. Just turn them into normal comments. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1453101588-18008-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_sdvo_regs.h | 76 +++++++++++++------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 2e2d4eb4a00d..db0ed499268a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -24,8 +24,8 @@ * Eric Anholt */ -/** - * @file SDVO command definitions and structures. +/* + * SDVO command definitions and structures. */ #define SDVO_OUTPUT_FIRST (0) @@ -66,39 +66,39 @@ struct intel_sdvo_caps { #define DTD_FLAG_VSYNC_POSITIVE (1 << 2) #define DTD_FLAG_INTERLACE (1 << 7) -/** This matches the EDID DTD structure, more or less */ +/* This matches the EDID DTD structure, more or less */ struct intel_sdvo_dtd { struct { - u16 clock; /**< pixel clock, in 10kHz units */ - u8 h_active; /**< lower 8 bits (pixels) */ - u8 h_blank; /**< lower 8 bits (pixels) */ - u8 h_high; /**< upper 4 bits each h_active, h_blank */ - u8 v_active; /**< lower 8 bits (lines) */ - u8 v_blank; /**< lower 8 bits (lines) */ - u8 v_high; /**< upper 4 bits each v_active, v_blank */ + u16 clock; /* pixel clock, in 10kHz units */ + u8 h_active; /* lower 8 bits (pixels) */ + u8 h_blank; /* lower 8 bits (pixels) */ + u8 h_high; /* upper 4 bits each h_active, h_blank */ + u8 v_active; /* lower 8 bits (lines) */ + u8 v_blank; /* lower 8 bits (lines) */ + u8 v_high; /* upper 4 bits each v_active, v_blank */ } part1; struct { - u8 h_sync_off; /**< lower 8 bits, from hblank start */ - u8 h_sync_width; /**< lower 8 bits (pixels) */ - /** lower 4 bits each vsync offset, vsync width */ + u8 h_sync_off; /* lower 8 bits, from hblank start */ + u8 h_sync_width; /* lower 8 bits (pixels) */ + /* lower 4 bits each vsync offset, vsync width */ u8 v_sync_off_width; - /** + /* * 2 high bits of hsync offset, 2 high bits of hsync width, * bits 4-5 of vsync offset, and 2 high bits of vsync width. */ u8 sync_off_width_high; u8 dtd_flags; u8 sdvo_flags; - /** bits 6-7 of vsync offset at bits 6-7 */ + /* bits 6-7 of vsync offset at bits 6-7 */ u8 v_sync_off_high; u8 reserved; } part2; } __packed; struct intel_sdvo_pixel_clock_range { - u16 min; /**< pixel clock, in 10kHz units */ - u16 max; /**< pixel clock, in 10kHz units */ + u16 min; /* pixel clock, in 10kHz units */ + u16 max; /* pixel clock, in 10kHz units */ } __packed; struct intel_sdvo_preferred_input_timing_args { @@ -144,7 +144,7 @@ struct intel_sdvo_preferred_input_timing_args { #define SDVO_CMD_RESET 0x01 -/** Returns a struct intel_sdvo_caps */ +/* Returns a struct intel_sdvo_caps */ #define SDVO_CMD_GET_DEVICE_CAPS 0x02 #define SDVO_CMD_GET_FIRMWARE_REV 0x86 @@ -152,7 +152,7 @@ struct intel_sdvo_preferred_input_timing_args { # define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 # define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 -/** +/* * Reports which inputs are trained (managed to sync). * * Devices must have trained within 2 vsyncs of a mode change. @@ -164,10 +164,10 @@ struct intel_sdvo_get_trained_inputs_response { unsigned int pad:6; } __packed; -/** Returns a struct intel_sdvo_output_flags of active outputs. */ +/* Returns a struct intel_sdvo_output_flags of active outputs. */ #define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 -/** +/* * Sets the current set of active outputs. * * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP @@ -175,7 +175,7 @@ struct intel_sdvo_get_trained_inputs_response { */ #define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 -/** +/* * Returns the current mapping of SDVO inputs to outputs on the device. * * Returns two struct intel_sdvo_output_flags structures. @@ -185,29 +185,29 @@ struct intel_sdvo_in_out_map { u16 in0, in1; }; -/** +/* * Sets the current mapping of SDVO inputs to outputs on the device. * * Takes two struct i380_sdvo_output_flags structures. */ #define SDVO_CMD_SET_IN_OUT_MAP 0x07 -/** +/* * Returns a struct intel_sdvo_output_flags of attached displays. */ #define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b -/** +/* * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging. */ #define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c -/** +/* * Takes a struct intel_sdvo_output_flags. */ #define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d -/** +/* * Returns a struct intel_sdvo_output_flags of displays with hot plug * interrupts enabled. */ @@ -221,7 +221,7 @@ struct intel_sdvo_get_interrupt_event_source_response { unsigned int pad:6; } __packed; -/** +/* * Selects which input is affected by future input commands. * * Commands affected include SET_INPUT_TIMINGS_PART[12], @@ -234,7 +234,7 @@ struct intel_sdvo_set_target_input_args { unsigned int pad:7; } __packed; -/** +/* * Takes a struct intel_sdvo_output_flags of which outputs are targeted by * future output commands. * @@ -280,7 +280,7 @@ struct intel_sdvo_set_target_input_args { # define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) # define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 -/** +/* * Generates a DTD based on the given width, height, and flags. * * This will be supported by any device supporting scaling or interlaced @@ -300,24 +300,24 @@ struct intel_sdvo_set_target_input_args { #define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b #define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c -/** Returns a struct intel_sdvo_pixel_clock_range */ +/* Returns a struct intel_sdvo_pixel_clock_range */ #define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d -/** Returns a struct intel_sdvo_pixel_clock_range */ +/* Returns a struct intel_sdvo_pixel_clock_range */ #define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e -/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ +/* Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ #define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f -/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ +/* Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ #define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 -/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ +/* Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ #define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 # define SDVO_CLOCK_RATE_MULT_1X (1 << 0) # define SDVO_CLOCK_RATE_MULT_2X (1 << 1) # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 -/** 6 bytes of bit flags for TV formats shared by all TV format functions */ +/* 6 bytes of bit flags for TV formats shared by all TV format functions */ struct intel_sdvo_tv_format { unsigned int ntsc_m:1; unsigned int ntsc_j:1; @@ -376,7 +376,7 @@ struct intel_sdvo_tv_format { #define SDVO_CMD_SET_TV_FORMAT 0x29 -/** Returns the resolutiosn that can be used with the given TV format */ +/* Returns the resolutiosn that can be used with the given TV format */ #define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 struct intel_sdvo_sdtv_resolution_request { unsigned int ntsc_m:1; @@ -539,7 +539,7 @@ struct intel_sdvo_hdtv_resolution_reply { #define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d #define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e #define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f -/** +/* * The panel power sequencing parameters are in units of milliseconds. * The high fields are bits 8:9 of the 10-bit values. */ -- GitLab From e2828914723a0739058c263af4f74a05a9bd85bb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 18 Jan 2016 09:19:47 +0200 Subject: [PATCH 0240/5324] drm/i915: turn some bogus kernel-doc comments to normal comments Apparently accidental or misplaced /** kernel-doc comments, confusing the tool. Turn them to normal comments. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1453101588-18008-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6b2b3e331a09..7e6e70054d6a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4138,7 +4138,7 @@ void intel_update_watermarks(struct drm_crtc *crtc) dev_priv->display.update_wm(crtc); } -/** +/* * Lock protecting IPS related data structures */ DEFINE_SPINLOCK(mchdev_lock); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ede57954080e..91ac8a9bd903 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -410,7 +410,7 @@ intel_write_status_page(struct intel_engine_cs *ring, ring->status_page.page_addr[reg] = value; } -/** +/* * Reads a dword out of the status page, which is written to from the command * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or * MI_STORE_DATA_IMM. -- GitLab From 18afd443f7f92c3cf514af531e020c8d992e49ac Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 18 Jan 2016 09:19:48 +0200 Subject: [PATCH 0241/5324] drm/i915: add DOC: headline to RC6 kernel-doc Without the DOC:, kernel-doc confuses the documentation block for something else. Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1453101588-18008-3-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7e6e70054d6a..180555553fa2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -32,6 +32,8 @@ #include /** + * DOC: RC6 + * * RC6 is a special power stage which allows the GPU to enter an very * low-voltage mode when idle, using down to 0V while at this stage. This * stage is entered automatically when the GPU is idle when RC6 support is -- GitLab From bf22045250fafbe733277e13300eaa240ba2104d Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 19 Jan 2016 11:43:04 -0800 Subject: [PATCH 0242/5324] Revert "drm/i915: Add two-stage ILK-style watermark programming (v10)" This reverts commit 396e33ae204f52abebec9e578f44c749305500f4. This commit was triggering some FIFO underrun warnings on ILK-IVB platforms (but surprisingly not on HSW/BDW that share more or less the same codepaths). These underruns were caught by the continuous integration (CI) system and could be reproduced consistently when running the basic acceptance tests (BAT) on the affected platforms. Note that this revert will cause a visible regression for some end-users; the "flicker when mouse moves between monitors in X" issue that was reported before this patch was merged will now return. However regressions that are visible to CI have higher priority since they prevent proper testing of future patches on those platforms. Hopefully we'll be able to figure out the cause of the underruns quickly and remerge an improved version of this patch to fix the regression. Cc: Daniel Vetter Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93640 Signed-off-by: Matt Roper Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453232584-8543-1-git-send-email-matthew.d.roper@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 1 - drivers/gpu/drm/i915/i915_drv.h | 13 +-- drivers/gpu/drm/i915/intel_atomic.c | 1 - drivers/gpu/drm/i915/intel_display.c | 92 +-------------- drivers/gpu/drm/i915/intel_drv.h | 28 +---- drivers/gpu/drm/i915/intel_pm.c | 162 ++++++++------------------- 6 files changed, 56 insertions(+), 241 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a0f5659032fc..d70d96fe553b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -896,7 +896,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->sb_lock); mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); - mutex_init(&dev_priv->wm.wm_mutex); intel_pm_setup(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af301482e6f8..d3b98c228683 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -628,11 +628,7 @@ struct drm_i915_display_funcs { struct dpll *best_clock); int (*compute_pipe_wm)(struct intel_crtc *crtc, struct drm_atomic_state *state); - int (*compute_intermediate_wm)(struct drm_device *dev, - struct intel_crtc *intel_crtc, - struct intel_crtc_state *newstate); - void (*initial_watermarks)(struct intel_crtc_state *cstate); - void (*optimize_watermarks)(struct intel_crtc_state *cstate); + void (*program_watermarks)(struct intel_crtc_state *cstate); void (*update_wm)(struct drm_crtc *crtc); int (*modeset_calc_cdclk)(struct drm_atomic_state *state); void (*modeset_commit_cdclk)(struct drm_atomic_state *state); @@ -1938,13 +1934,6 @@ struct drm_i915_private { }; uint8_t max_level; - - /* - * Should be held around atomic WM register writing; also - * protects * intel_crtc->wm.active and - * cstate->wm.need_postvbl_update. - */ - struct mutex wm_mutex; } wm; struct i915_runtime_pm pm; diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 9682d94af710..4625f8a9ba12 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -97,7 +97,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->disable_lp_wm = false; crtc_state->disable_cxsr = false; crtc_state->wm_changed = false; - crtc_state->wm.need_postvbl_update = false; return &crtc_state->base; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a851cb70479e..3260fc639b07 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4833,42 +4833,7 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) intel_set_memory_cxsr(dev_priv, false); } - /* - * IVB workaround: must disable low power watermarks for at least - * one frame before enabling scaling. LP watermarks can be re-enabled - * when scaling is disabled. - * - * WaCxSRDisabledForSpriteScaling:ivb - */ - if (pipe_config->disable_lp_wm) { - ilk_disable_lp_wm(dev); - intel_wait_for_vblank(dev, crtc->pipe); - } - - /* - * If we're doing a modeset, we're done. No need to do any pre-vblank - * watermark programming here. - */ - if (needs_modeset(&pipe_config->base)) - return; - - /* - * For platforms that support atomic watermarks, program the - * 'intermediate' watermarks immediately. On pre-gen9 platforms, these - * will be the intermediate values that are safe for both pre- and - * post- vblank; when vblank happens, the 'active' values will be set - * to the final 'target' values and we'll do this again to get the - * optimal watermarks. For gen9+ platforms, the values we program here - * will be the final target values which will get automatically latched - * at vblank time; no further programming will be necessary. - * - * If a platform hasn't been transitioned to atomic watermarks yet, - * we'll continue to update watermarks the old way, if flags tell - * us to. - */ - if (dev_priv->display.initial_watermarks != NULL) - dev_priv->display.initial_watermarks(pipe_config); - else if (pipe_config->wm_changed) + if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed) intel_update_watermarks(&crtc->base); } @@ -11914,11 +11879,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, pipe_config->wm_changed = true; } - /* Pre-gen9 platforms need two-step watermark updates */ - if (pipe_config->wm_changed && INTEL_INFO(dev)->gen < 9 && - dev_priv->display.optimize_watermarks) - to_intel_crtc_state(crtc_state)->wm.need_postvbl_update = true; - if (visible || was_visible) intel_crtc->atomic.fb_bits |= to_intel_plane(plane)->frontbuffer_bit; @@ -12075,29 +12035,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, ret = 0; if (dev_priv->display.compute_pipe_wm) { ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); - if (ret) { - DRM_DEBUG_KMS("Target pipe watermarks are invalid\n"); - return ret; - } - } - - if (dev_priv->display.compute_intermediate_wm && - !to_intel_atomic_state(state)->skip_intermediate_wm) { - if (WARN_ON(!dev_priv->display.compute_pipe_wm)) - return 0; - - /* - * Calculate 'intermediate' watermarks that satisfy both the - * old state and the new state. We can program these - * immediately. - */ - ret = dev_priv->display.compute_intermediate_wm(crtc->dev, - intel_crtc, - pipe_config); - if (ret) { - DRM_DEBUG_KMS("No valid intermediate pipe watermarks are possible\n"); + if (ret) return ret; - } } if (INTEL_INFO(dev)->gen >= 9) { @@ -13562,7 +13501,6 @@ static int intel_atomic_commit(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; - struct intel_crtc_state *intel_cstate; int ret = 0, i; bool hw_check = intel_state->modeset; @@ -13662,20 +13600,6 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_helper_wait_for_vblanks(dev, state); - /* - * Now that the vblank has passed, we can go ahead and program the - * optimal watermarks on platforms that need two-step watermark - * programming. - * - * TODO: Move this (and other cleanup) to an async worker eventually. - */ - for_each_crtc_in_state(state, crtc, crtc_state, i) { - intel_cstate = to_intel_crtc_state(crtc->state); - - if (dev_priv->display.optimize_watermarks) - dev_priv->display.optimize_watermarks(intel_cstate); - } - mutex_lock(&dev->struct_mutex); drm_atomic_helper_cleanup_planes(dev, state); mutex_unlock(&dev->struct_mutex); @@ -15342,7 +15266,7 @@ static void sanitize_watermarks(struct drm_device *dev) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.optimize_watermarks) + if (!dev_priv->display.program_watermarks) return; /* @@ -15363,13 +15287,6 @@ static void sanitize_watermarks(struct drm_device *dev) if (WARN_ON(IS_ERR(state))) goto fail; - /* - * Hardware readout is the only time we don't want to calculate - * intermediate watermarks (since we don't trust the current - * watermarks). - */ - to_intel_atomic_state(state)->skip_intermediate_wm = true; - ret = intel_atomic_check(dev, state); if (ret) { /* @@ -15392,8 +15309,7 @@ static void sanitize_watermarks(struct drm_device *dev) for_each_crtc_in_state(state, crtc, cstate, i) { struct intel_crtc_state *cs = to_intel_crtc_state(cstate); - cs->wm.need_postvbl_update = true; - dev_priv->display.optimize_watermarks(cs); + dev_priv->display.program_watermarks(cs); } drm_atomic_state_free(state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 059b46e22c31..15917e3a3352 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -260,12 +260,6 @@ struct intel_atomic_state { struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; struct intel_wm_config wm_config; - - /* - * Current watermarks can't be trusted during hardware readout, so - * don't bother calculating intermediate watermarks. - */ - bool skip_intermediate_wm; }; struct intel_plane_state { @@ -513,29 +507,13 @@ struct intel_crtc_state { struct { /* - * Optimal watermarks, programmed post-vblank when this state - * is committed. + * optimal watermarks, programmed post-vblank when this state + * is committed */ union { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } optimal; - - /* - * Intermediate watermarks; these can be programmed immediately - * since they satisfy both the current configuration we're - * switching away from and the new configuration we're switching - * to. - */ - struct intel_pipe_wm intermediate; - - /* - * Platforms with two-step watermark programming will need to - * update watermark programming post-vblank to switch from the - * safe intermediate watermarks to the optimal final - * watermarks. - */ - bool need_postvbl_update; } wm; }; @@ -622,7 +600,6 @@ struct intel_crtc { struct intel_pipe_wm ilk; struct skl_pipe_wm skl; } active; - /* allow CxSR on this pipe */ bool cxsr_allowed; } wm; @@ -1583,7 +1560,6 @@ void skl_wm_get_hw_state(struct drm_device *dev); void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, struct skl_ddb_allocation *ddb /* out */); uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); -bool ilk_disable_lp_wm(struct drm_device *dev); /* intel_sdvo.c */ bool intel_sdvo_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 180555553fa2..20bf854eae8c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2275,29 +2275,6 @@ static void skl_setup_wm_latency(struct drm_device *dev) intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); } -static bool ilk_validate_pipe_wm(struct drm_device *dev, - struct intel_pipe_wm *pipe_wm) -{ - /* LP0 watermark maximums depend on this pipe alone */ - const struct intel_wm_config config = { - .num_pipes_active = 1, - .sprites_enabled = pipe_wm->sprites_enabled, - .sprites_scaled = pipe_wm->sprites_scaled, - }; - struct ilk_wm_maximums max; - - /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); - - /* At least LP0 must be valid */ - if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) { - DRM_DEBUG_KMS("LP0 watermark invalid\n"); - return false; - } - - return true; -} - /* Compute new watermarks for the pipe */ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct drm_atomic_state *state) @@ -2312,6 +2289,10 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, struct intel_plane_state *sprstate = NULL; struct intel_plane_state *curstate = NULL; int level, max_level = ilk_wm_max_level(dev); + /* LP0 watermark maximums depend on this pipe alone */ + struct intel_wm_config config = { + .num_pipes_active = 1, + }; struct ilk_wm_maximums max; cstate = intel_atomic_get_crtc_state(state, intel_crtc); @@ -2335,18 +2316,21 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, curstate = to_intel_plane_state(ps); } - pipe_wm->pipe_enabled = cstate->base.active; - pipe_wm->sprites_enabled = sprstate->visible; - pipe_wm->sprites_scaled = sprstate->visible && + config.sprites_enabled = sprstate->visible; + config.sprites_scaled = sprstate->visible && (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 || drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); + pipe_wm->pipe_enabled = cstate->base.active; + pipe_wm->sprites_enabled = config.sprites_enabled; + pipe_wm->sprites_scaled = config.sprites_scaled; + /* ILK/SNB: LP2+ watermarks only w/o sprites */ if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible) max_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ - if (pipe_wm->sprites_scaled) + if (config.sprites_scaled) max_level = 0; ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, @@ -2355,8 +2339,12 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, if (IS_HASWELL(dev) || IS_BROADWELL(dev)) pipe_wm->linetime = hsw_compute_linetime_wm(dev, cstate); - if (!ilk_validate_pipe_wm(dev, pipe_wm)) - return false; + /* LP0 watermarks always use 1/2 DDB partitioning */ + ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); + + /* At least LP0 must be valid */ + if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) + return -EINVAL; ilk_compute_wm_reg_maximums(dev, 1, &max); @@ -2380,59 +2368,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, return 0; } -/* - * Build a set of 'intermediate' watermark values that satisfy both the old - * state and the new state. These can be programmed to the hardware - * immediately. - */ -static int ilk_compute_intermediate_wm(struct drm_device *dev, - struct intel_crtc *intel_crtc, - struct intel_crtc_state *newstate) -{ - struct intel_pipe_wm *a = &newstate->wm.intermediate; - struct intel_pipe_wm *b = &intel_crtc->wm.active.ilk; - int level, max_level = ilk_wm_max_level(dev); - - /* - * Start with the final, target watermarks, then combine with the - * currently active watermarks to get values that are safe both before - * and after the vblank. - */ - *a = newstate->wm.optimal.ilk; - a->pipe_enabled |= b->pipe_enabled; - a->sprites_enabled |= b->sprites_enabled; - a->sprites_scaled |= b->sprites_scaled; - - for (level = 0; level <= max_level; level++) { - struct intel_wm_level *a_wm = &a->wm[level]; - const struct intel_wm_level *b_wm = &b->wm[level]; - - a_wm->enable &= b_wm->enable; - a_wm->pri_val = max(a_wm->pri_val, b_wm->pri_val); - a_wm->spr_val = max(a_wm->spr_val, b_wm->spr_val); - a_wm->cur_val = max(a_wm->cur_val, b_wm->cur_val); - a_wm->fbc_val = max(a_wm->fbc_val, b_wm->fbc_val); - } - - /* - * We need to make sure that these merged watermark values are - * actually a valid configuration themselves. If they're not, - * there's no safe way to transition from the old state to - * the new state, so we need to fail the atomic transaction. - */ - if (!ilk_validate_pipe_wm(dev, a)) - return -EINVAL; - - /* - * If our intermediate WM are identical to the final WM, then we can - * omit the post-vblank programming; only update if it's different. - */ - if (memcmp(a, &newstate->wm.optimal.ilk, sizeof(*a)) != 0) - newstate->wm.need_postvbl_update = false; - - return 0; -} - /* * Merge the watermarks from all active pipes for a specific level. */ @@ -2445,7 +2380,9 @@ static void ilk_merge_wm_level(struct drm_device *dev, ret_wm->enable = true; for_each_intel_crtc(dev, intel_crtc) { - const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk; + const struct intel_crtc_state *cstate = + to_intel_crtc_state(intel_crtc->base.state); + const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; const struct intel_wm_level *wm = &active->wm[level]; if (!active->pipe_enabled) @@ -2593,14 +2530,15 @@ static void ilk_compute_wm_results(struct drm_device *dev, /* LP0 register values */ for_each_intel_crtc(dev, intel_crtc) { + const struct intel_crtc_state *cstate = + to_intel_crtc_state(intel_crtc->base.state); enum pipe pipe = intel_crtc->pipe; - const struct intel_wm_level *r = - &intel_crtc->wm.active.ilk.wm[0]; + const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0]; if (WARN_ON(!r->enable)) continue; - results->wm_linetime[pipe] = intel_crtc->wm.active.ilk.linetime; + results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime; results->wm_pipe[pipe] = (r->pri_val << WM0_PIPE_PLANE_SHIFT) | @@ -2807,7 +2745,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, dev_priv->wm.hw = *results; } -bool ilk_disable_lp_wm(struct drm_device *dev) +static bool ilk_disable_lp_wm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -3700,9 +3638,11 @@ static void ilk_compute_wm_config(struct drm_device *dev, } } -static void ilk_program_watermarks(struct drm_i915_private *dev_priv) +static void ilk_program_watermarks(struct intel_crtc_state *cstate) { - struct drm_device *dev = dev_priv->dev; + struct drm_crtc *crtc = cstate->base.crtc; + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config config = {}; @@ -3733,28 +3673,28 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) ilk_write_wm_values(dev_priv, &results); } -static void ilk_initial_watermarks(struct intel_crtc_state *cstate) +static void ilk_update_wm(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); - - mutex_lock(&dev_priv->wm.wm_mutex); - intel_crtc->wm.active.ilk = cstate->wm.intermediate; - ilk_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->wm.wm_mutex); -} + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); -static void ilk_optimize_watermarks(struct intel_crtc_state *cstate) -{ - struct drm_i915_private *dev_priv = to_i915(cstate->base.crtc->dev); - struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); + WARN_ON(cstate->base.active != intel_crtc->active); - mutex_lock(&dev_priv->wm.wm_mutex); - if (cstate->wm.need_postvbl_update) { - intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; - ilk_program_watermarks(dev_priv); + /* + * IVB workaround: must disable low power watermarks for at least + * one frame before enabling scaling. LP watermarks can be re-enabled + * when scaling is disabled. + * + * WaCxSRDisabledForSpriteScaling:ivb + */ + if (cstate->disable_lp_wm) { + ilk_disable_lp_wm(crtc->dev); + intel_wait_for_vblank(crtc->dev, intel_crtc->pipe); } - mutex_unlock(&dev_priv->wm.wm_mutex); + + intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; + + ilk_program_watermarks(cstate); } static void skl_pipe_wm_active_state(uint32_t val, @@ -7081,13 +7021,9 @@ void intel_init_pm(struct drm_device *dev) dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { + dev_priv->display.update_wm = ilk_update_wm; dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; - dev_priv->display.compute_intermediate_wm = - ilk_compute_intermediate_wm; - dev_priv->display.initial_watermarks = - ilk_initial_watermarks; - dev_priv->display.optimize_watermarks = - ilk_optimize_watermarks; + dev_priv->display.program_watermarks = ilk_program_watermarks; } else { DRM_DEBUG_KMS("Failed to read display plane latency. " "Disable CxSR\n"); -- GitLab From 3f36b93797bd773eb27e31cf53e3d1f9e64c77ab Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 19 Jan 2016 15:25:17 +0000 Subject: [PATCH 0243/5324] drm/i915: Do not put big intel_crtc_state on the stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having this on stack triggers the -Wframe-larger-than=1024 and is not nice to put such big things on the kernel stack anyway. This required a little bit of refactoring to handle the new failure path from vlv_force_pll_on. v2: Corrected some whitespace. Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Cc: John Harrison Cc: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453217117-26125-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 60 ++++++++++++++++++---------- drivers/gpu/drm/i915/intel_dp.c | 8 +++- drivers/gpu/drm/i915/intel_drv.h | 4 +- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3260fc639b07..f5c7f9fbb5ff 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7600,26 +7600,34 @@ static void chv_prepare_pll(struct intel_crtc *crtc, * in cases where we need the PLL enabled even when @pipe is not going to * be enabled. */ -void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, - const struct dpll *dpll) +int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, + const struct dpll *dpll) { struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); - struct intel_crtc_state pipe_config = { - .base.crtc = &crtc->base, - .pixel_multiplier = 1, - .dpll = *dpll, - }; + struct intel_crtc_state *pipe_config; + + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) + return -ENOMEM; + + pipe_config->base.crtc = &crtc->base; + pipe_config->pixel_multiplier = 1; + pipe_config->dpll = *dpll; if (IS_CHERRYVIEW(dev)) { - chv_compute_dpll(crtc, &pipe_config); - chv_prepare_pll(crtc, &pipe_config); - chv_enable_pll(crtc, &pipe_config); + chv_compute_dpll(crtc, pipe_config); + chv_prepare_pll(crtc, pipe_config); + chv_enable_pll(crtc, pipe_config); } else { - vlv_compute_dpll(crtc, &pipe_config); - vlv_prepare_pll(crtc, &pipe_config); - vlv_enable_pll(crtc, &pipe_config); + vlv_compute_dpll(crtc, pipe_config); + vlv_prepare_pll(crtc, pipe_config); + vlv_enable_pll(crtc, pipe_config); } + + kfree(pipe_config); + + return 0; } /** @@ -10793,7 +10801,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; struct drm_display_mode *mode; - struct intel_crtc_state pipe_config; + struct intel_crtc_state *pipe_config; int htot = I915_READ(HTOTAL(cpu_transcoder)); int hsync = I915_READ(HSYNC(cpu_transcoder)); int vtot = I915_READ(VTOTAL(cpu_transcoder)); @@ -10804,6 +10812,12 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, if (!mode) return NULL; + pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); + if (!pipe_config) { + kfree(mode); + return NULL; + } + /* * Construct a pipe_config sufficient for getting the clock info * back out of crtc_clock_get. @@ -10811,14 +10825,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need * to use a real value here instead. */ - pipe_config.cpu_transcoder = (enum transcoder) pipe; - pipe_config.pixel_multiplier = 1; - pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe)); - pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe)); - pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe)); - i9xx_crtc_clock_get(intel_crtc, &pipe_config); - - mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier; + pipe_config->cpu_transcoder = (enum transcoder) pipe; + pipe_config->pixel_multiplier = 1; + pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(pipe)); + pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(pipe)); + pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(pipe)); + i9xx_crtc_clock_get(intel_crtc, pipe_config); + + mode->clock = pipe_config->port_clock / pipe_config->pixel_multiplier; mode->hdisplay = (htot & 0xffff) + 1; mode->htotal = ((htot & 0xffff0000) >> 16) + 1; mode->hsync_start = (hsync & 0xffff) + 1; @@ -10830,6 +10844,8 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, drm_mode_set_name(mode); + kfree(pipe_config); + return mode; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 17612548c58d..e2bea710614f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -335,8 +335,12 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) release_cl_override = IS_CHERRYVIEW(dev) && !chv_phy_powergate_ch(dev_priv, phy, ch, true); - vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ? - &chv_dpll[0].dpll : &vlv_dpll[0].dpll); + if (vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ? + &chv_dpll[0].dpll : &vlv_dpll[0].dpll)) { + DRM_ERROR("Failed to force on pll for pipe %c!\n", + pipe_name(pipe)); + return; + } } /* diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 15917e3a3352..bc970125ec76 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1154,8 +1154,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, struct intel_crtc_state *state); -void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, - const struct dpll *dpll); +int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe, + const struct dpll *dpll); void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe); /* modesetting asserts */ -- GitLab From 70c0616d5a8458ae9148d74309cede07ba2f5164 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 20 Jan 2016 10:59:34 +0000 Subject: [PATCH 0244/5324] drm/fb_cma_helper: remove duplicate const from drm_fb_cma_alloc Duplicated const, only one is required. Also reformat line to ensure it is less than 80 columns wide. Signed-off-by: Colin Ian King Link: http://patchwork.freedesktop.org/patch/msgid/1453287574-3645-1-git-send-email-colin.king@canonical.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_cma_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index c895b6fddbd8..bb88e3df9257 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c @@ -74,7 +74,8 @@ static struct drm_framebuffer_funcs drm_fb_cma_funcs = { }; static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, - const const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_cma_object **obj, + const struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gem_cma_object **obj, unsigned int num_planes) { struct drm_fb_cma *fb_cma; -- GitLab From e794129444aba459e9bedf5080bfb4605f933c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 19 Jan 2016 18:23:17 +0200 Subject: [PATCH 0245/5324] drm/i915: Fix NULL plane->fb oops on SKL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this atomic age, we can't trust the plane->fb pointer anymore. It might get update too late. Instead we are supposed to use the plane_state->fb pointer instead. Let's do that in intel_plane_obj_offset() and avoid problems from dereferencing the potentially stale plane->fb pointer. Paulo found this with 'kms_frontbuffer_tracking --show-hidden --run-subtest nop-1p-rte' but it can be reproduced with just plain old kms_setplane. I was too lazy to bisect this, so not sure exactly when it broke. The most obvious candidate commit ce7f17285639 ("drm/i915: Fix i915_ggtt_view_equal to handle rotation correctly") was actually still fine, so it must have broken some time after that. Here's the resulting fireworks: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] PGD 8a5f6067 PUD 8a5f5067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm intel_gtt agpgart netconsole mousedev hid_generic psmouse usbhid atkbd libps2 coretemp hwmon efi_pstore intel_rapl iosf_mbi x86_pkg_temp_thermal efivars pcspkr e1000e sdhci_pci ptp pps_core sdhci i2c_i801 mmc_core i2c_hid hid i8042 serio evdev sch_fq_codel ip_tables x_tables ipv6 autofs4 CPU: 1 PID: 260 Comm: kms_plane Not tainted 4.4.0-skl+ #171 Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.R00.B104.B00.1511030553 11/03/2015 task: ffff88008bde2d80 ti: ffff88008a6ec000 task.ti: ffff88008a6ec000 RIP: 0010:[] [] intel_fill_fb_ggtt_view+0x1b/0x15a [i915] RSP: 0018:ffff88008a6efa10 EFLAGS: 00010086 RAX: 0000000000000001 RBX: ffff8801674f4240 RCX: 0000000000000014 RDX: ffff88008a7440c0 RSI: 0000000000000000 RDI: ffff88008a6efa40 RBP: ffff88008a6efa30 R08: ffff88008bde3598 R09: 0000000000000001 R10: ffff88008b782000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff88008a7440c0 R14: 0000000000000000 R15: ffff88008a7449c0 FS: 00007fa0c07a28c0(0000) GS:ffff88016ec40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000008a6ff000 CR4: 00000000003406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Stack: ffff8801674f4240 0000000000000000 ffff88008a7440c0 0000000000000000 ffff88008a6efaa0 ffffffffa02daf25 ffffffff814ec80e 0000000000070298 ffff8800850d0000 ffff88008a6efaa0 ffffffffa02c49c2 0000000000000002 Call Trace: [] intel_plane_obj_offset+0x2d/0xa9 [i915] [] ? _raw_spin_unlock_irqrestore+0x4b/0x60 [] ? gen9_write32+0x2e8/0x3b8 [i915] [] skl_update_plane+0x203/0x4c5 [i915] [] intel_plane_atomic_update+0x53/0x6a [i915] [] drm_atomic_helper_commit_planes_on_crtc+0x142/0x1d5 [drm_kms_helper] [] intel_atomic_commit+0x1262/0x1350 [i915] [] ? __drm_atomic_helper_crtc_duplicate_state+0x2f/0x41 [drm_kms_helper] [] ? drm_atomic_check_only+0x3e3/0x552 [drm] [] drm_atomic_commit+0x4d/0x52 [drm] [] drm_atomic_helper_update_plane+0xcb/0x118 [drm_kms_helper] [] __setplane_internal+0x1c8/0x224 [drm] [] drm_mode_setplane+0x14e/0x172 [drm] [] drm_ioctl+0x265/0x3ad [drm] [] ? drm_mode_cursor_common+0x158/0x158 [drm] [] ? current_kernel_time64+0x5e/0x98 [] ? trace_hardirqs_on_caller+0x17a/0x196 [] do_vfs_ioctl+0x42b/0x4ea [] ? __fget_light+0x4d/0x71 [] SyS_ioctl+0x43/0x61 [] entry_SYSCALL_64_fastpath+0x12/0x6f Cc: drm-intel-fixes@lists.freedesktop.org Cc: Paulo Zanoni Testcase: igt/kms_plane Reported-by: Paulo Zanoni Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453220597-28973-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f5c7f9fbb5ff..06ab6df8ad48 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2940,7 +2940,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane, struct i915_vma *vma; u64 offset; - intel_fill_fb_ggtt_view(&view, intel_plane->base.fb, + intel_fill_fb_ggtt_view(&view, intel_plane->base.state->fb, intel_plane->base.state); vma = i915_gem_obj_to_ggtt_view(obj, &view); -- GitLab From 26827088392196d0e8464dae599bd5ff9992cb82 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Tue, 19 Jan 2016 19:02:53 +0000 Subject: [PATCH 0246/5324] drm/i915: simplify allocation of driver-internal requests There are a number of places where the driver needs a request, but isn't working on behalf of any specific user or in a specific context. At present, we associate them with the per-engine default context. A future patch will abolish those per-engine context pointers; but we can already eliminate a lot of the references to them, just by making the allocator allow NULL as a shorthand for "an appropriate context for this ring", which will mean that the callers don't need to know anything about how the "appropriate context" is found (e.g. per-ring vs per-device, etc). So this patch renames the existing i915_gem_request_alloc(), and makes it local (static inline), and replaces it with a wrapper that provides a default if the context is NULL, and also has a nicer calling convention (doesn't require a pointer to an output parameter). Then we change all callers to use the new convention: OLD: err = i915_gem_request_alloc(ring, user_ctx, &req); if (err) ... NEW: req = i915_gem_request_alloc(ring, user_ctx); if (IS_ERR(req)) ... OLD: err = i915_gem_request_alloc(ring, ring->default_context, &req); if (err) ... NEW: req = i915_gem_request_alloc(ring, NULL); if (IS_ERR(req)) ... v4: Rebased Signed-off-by: Dave Gordon Reviewed-by: Nick Hoath Link: http://patchwork.freedesktop.org/patch/msgid/1453230175-19330-2-git-send-email-david.s.gordon@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 +-- drivers/gpu/drm/i915/i915_gem.c | 55 +++++++++++++++++----- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 14 ++++-- drivers/gpu/drm/i915/intel_display.c | 6 ++- drivers/gpu/drm/i915/intel_lrc.c | 9 ++-- drivers/gpu/drm/i915/intel_overlay.c | 24 +++++----- 6 files changed, 74 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d3b98c228683..125659488756 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2268,9 +2268,9 @@ struct drm_i915_gem_request { }; -int i915_gem_request_alloc(struct intel_engine_cs *ring, - struct intel_context *ctx, - struct drm_i915_gem_request **req_out); +struct drm_i915_gem_request * __must_check +i915_gem_request_alloc(struct intel_engine_cs *engine, + struct intel_context *ctx); void i915_gem_request_cancel(struct drm_i915_gem_request *req); void i915_gem_request_free(struct kref *req_ref); int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6b0102da859c..8e716b6b5d59 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2690,9 +2690,10 @@ void i915_gem_request_free(struct kref *req_ref) kmem_cache_free(req->i915->requests, req); } -int i915_gem_request_alloc(struct intel_engine_cs *ring, - struct intel_context *ctx, - struct drm_i915_gem_request **req_out) +static inline int +__i915_gem_request_alloc(struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_request **req_out) { struct drm_i915_private *dev_priv = to_i915(ring->dev); struct drm_i915_gem_request *req; @@ -2755,6 +2756,31 @@ int i915_gem_request_alloc(struct intel_engine_cs *ring, return ret; } +/** + * i915_gem_request_alloc - allocate a request structure + * + * @engine: engine that we wish to issue the request on. + * @ctx: context that the request will be associated with. + * This can be NULL if the request is not directly related to + * any specific user context, in which case this function will + * choose an appropriate context to use. + * + * Returns a pointer to the allocated request if successful, + * or an error code if not. + */ +struct drm_i915_gem_request * +i915_gem_request_alloc(struct intel_engine_cs *engine, + struct intel_context *ctx) +{ + struct drm_i915_gem_request *req; + int err; + + if (ctx == NULL) + ctx = engine->default_context; + err = __i915_gem_request_alloc(engine, ctx, &req); + return err ? ERR_PTR(err) : req; +} + void i915_gem_request_cancel(struct drm_i915_gem_request *req) { intel_ring_reserved_space_cancel(req->ringbuf); @@ -3172,9 +3198,13 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj, return 0; if (*to_req == NULL) { - ret = i915_gem_request_alloc(to, to->default_context, to_req); - if (ret) - return ret; + struct drm_i915_gem_request *req; + + req = i915_gem_request_alloc(to, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); + + *to_req = req; } trace_i915_gem_ring_sync_to(*to_req, from, from_req); @@ -3374,9 +3404,9 @@ int i915_gpu_idle(struct drm_device *dev) if (!i915.enable_execlists) { struct drm_i915_gem_request *req; - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) - return ret; + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); ret = i915_switch_context(req); if (ret) { @@ -4871,10 +4901,9 @@ i915_gem_init_hw(struct drm_device *dev) for_each_ring(ring, dev_priv, i) { struct drm_i915_gem_request *req; - WARN_ON(!ring->default_context); - - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) { + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) { + ret = PTR_ERR(req); i915_gem_cleanup_ringbuffer(dev); goto out; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4edf1c062210..dc32018ee2e9 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1381,6 +1381,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_exec_object2 *exec) { struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_request *req = NULL; struct eb_vmas *eb; struct drm_i915_gem_object *batch_obj; struct drm_i915_gem_exec_object2 shadow_exec_entry; @@ -1602,11 +1603,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm); /* Allocate a request for this batch buffer nice and early. */ - ret = i915_gem_request_alloc(ring, ctx, ¶ms->request); - if (ret) + req = i915_gem_request_alloc(ring, ctx); + if (IS_ERR(req)) { + ret = PTR_ERR(req); goto err_batch_unpin; + } - ret = i915_gem_request_add_to_client(params->request, file); + ret = i915_gem_request_add_to_client(req, file); if (ret) goto err_batch_unpin; @@ -1622,6 +1625,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, params->dispatch_flags = dispatch_flags; params->batch_obj = batch_obj; params->ctx = ctx; + params->request = req; ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas); @@ -1645,8 +1649,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * must be freed again. If it was submitted then it is being tracked * on the active request list and no clean up is required here. */ - if (ret && params->request) - i915_gem_request_cancel(params->request); + if (ret && req) + i915_gem_request_cancel(req); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 06ab6df8ad48..8104511ad302 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11690,9 +11690,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, obj->last_write_req); } else { if (!request) { - ret = i915_gem_request_alloc(ring, ring->default_context, &request); - if (ret) + request = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(request)) { + ret = PTR_ERR(request); goto cleanup_unpin; + } } ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index faaf49077fea..ec2482daffa6 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2520,11 +2520,10 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx, if (ctx != ring->default_context && ring->init_context) { struct drm_i915_gem_request *req; - ret = i915_gem_request_alloc(ring, - ctx, &req); - if (ret) { - DRM_ERROR("ring create req: %d\n", - ret); + req = i915_gem_request_alloc(ring, ctx); + if (IS_ERR(req)) { + ret = PTR_ERR(req); + DRM_ERROR("ring create req: %d\n", ret); goto error_ringbuf; } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 76f1980a7541..9168413fe204 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -240,9 +240,9 @@ static int intel_overlay_on(struct intel_overlay *overlay) WARN_ON(overlay->active); WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) - return ret; + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); ret = intel_ring_begin(req, 4); if (ret) { @@ -283,9 +283,9 @@ static int intel_overlay_continue(struct intel_overlay *overlay, if (tmp & (1 << 17)) DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) - return ret; + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); ret = intel_ring_begin(req, 2); if (ret) { @@ -349,9 +349,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) * of the hw. Do it in both cases */ flip_addr |= OFC_UPDATE; - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) - return ret; + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); ret = intel_ring_begin(req, 6); if (ret) { @@ -423,9 +423,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) /* synchronous slowpath */ struct drm_i915_gem_request *req; - ret = i915_gem_request_alloc(ring, ring->default_context, &req); - if (ret) - return ret; + req = i915_gem_request_alloc(ring, NULL); + if (IS_ERR(req)) + return PTR_ERR(req); ret = intel_ring_begin(req, 2); if (ret) { -- GitLab From ed54c1a1d11cbc09a3cc14f8fc1a0fb129efb64d Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Tue, 19 Jan 2016 19:02:54 +0000 Subject: [PATCH 0247/5324] drm/i915: abolish separate per-ring default_context pointers Now that we've eliminated a lot of uses of ring->default_context, we can eliminate the pointer itself. All the engines share the same default intel_context, so we can just keep a single reference to it in the dev_priv structure rather than one in each of the engine[] elements. This make refcounting more sensible too, as we now have a refcount of one for the one pointer, rather than a refcount of one but multiple pointers. From an idea by Chris Wilson. v2: transform an extra instance of ring->default_context introduced by 42f1cae8c drm/i915: Restore inhibiting the load of the default context That patch's commentary includes: v2: Mark the global default context as uninitialized on GPU reset so that the context-local workarounds are reloaded upon re-enabling The code implementing that now also benefits from the replacement of the multiple (per-ring) pointers to the default context with a single pointer to the unique kernel context. v4: Rebased, remove underused local (Nick Hoath) Signed-off-by: Dave Gordon Reviewed-by: Nick Hoath Cc: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1453230175-19330-3-git-send-email-david.s.gordon@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +-- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 6 ++--- drivers/gpu/drm/i915/i915_gem_context.c | 29 ++++++++-------------- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_guc_submission.c | 6 ++--- drivers/gpu/drm/i915/intel_lrc.c | 17 +++++++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 8 files changed, 31 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0b3550f05026..37c2c5009d9a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1961,7 +1961,7 @@ static int i915_context_status(struct seq_file *m, void *unused) seq_puts(m, "HW context "); describe_ctx(m, ctx); for_each_ring(ring, dev_priv, i) { - if (ring->default_context == ctx) + if (dev_priv->kernel_context == ctx) seq_printf(m, "(default context %s) ", ring->name); } @@ -2058,7 +2058,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) list_for_each_entry(ctx, &dev_priv->context_list, link) { for_each_ring(ring, dev_priv, i) { - if (ring->default_context != ctx) + if (dev_priv->kernel_context != ctx) i915_dump_lrc_obj(m, ctx, ring); } } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 125659488756..840368de3f4f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1948,6 +1948,8 @@ struct drm_i915_private { void (*stop_ring)(struct intel_engine_cs *ring); } gt; + struct intel_context *kernel_context; + bool edp_low_vswing; /* perform PHY state sanity checks? */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8e716b6b5d59..06abe1bf5afc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2680,7 +2680,7 @@ void i915_gem_request_free(struct kref *req_ref) if (ctx) { if (i915.enable_execlists) { - if (ctx != req->ring->default_context) + if (ctx != req->i915->kernel_context) intel_lr_context_unpin(req); } @@ -2776,7 +2776,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, int err; if (ctx == NULL) - ctx = engine->default_context; + ctx = to_i915(engine->dev)->kernel_context; err = __i915_gem_request_alloc(engine, ctx, &req); return err ? ERR_PTR(err) : req; } @@ -4864,7 +4864,7 @@ i915_gem_init_hw(struct drm_device *dev) */ init_unused_rings(dev); - BUG_ON(!dev_priv->ring[RCS].default_context); + BUG_ON(!dev_priv->kernel_context); ret = i915_ppgtt_init_hw(dev); if (ret) { diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index c25083c78ba7..6a4f64b03db6 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -347,22 +347,20 @@ void i915_gem_context_reset(struct drm_device *dev) i915_gem_context_unreference(lctx); ring->last_context = NULL; } - - /* Force the GPU state to be reinitialised on enabling */ - if (ring->default_context) - ring->default_context->legacy_hw_ctx.initialized = false; } + + /* Force the GPU state to be reinitialised on enabling */ + dev_priv->kernel_context->legacy_hw_ctx.initialized = false; } int i915_gem_context_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_context *ctx; - int i; /* Init should only be called once per module load. Eventually the * restriction on the context_disabled check can be loosened. */ - if (WARN_ON(dev_priv->ring[RCS].default_context)) + if (WARN_ON(dev_priv->kernel_context)) return 0; if (intel_vgpu_active(dev) && HAS_LOGICAL_RING_CONTEXTS(dev)) { @@ -392,12 +390,7 @@ int i915_gem_context_init(struct drm_device *dev) return PTR_ERR(ctx); } - for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_engine_cs *ring = &dev_priv->ring[i]; - - /* NB: RCS will hold a ref for all rings */ - ring->default_context = ctx; - } + dev_priv->kernel_context = ctx; DRM_DEBUG_DRIVER("%s context support initialized\n", i915.enable_execlists ? "LR" : @@ -408,7 +401,7 @@ int i915_gem_context_init(struct drm_device *dev) void i915_gem_context_fini(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_context *dctx = dev_priv->ring[RCS].default_context; + struct intel_context *dctx = dev_priv->kernel_context; int i; if (dctx->legacy_hw_ctx.rcs_state) { @@ -435,17 +428,17 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); } - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = I915_NUM_RINGS; --i >= 0;) { struct intel_engine_cs *ring = &dev_priv->ring[i]; - if (ring->last_context) + if (ring->last_context) { i915_gem_context_unreference(ring->last_context); - - ring->default_context = NULL; - ring->last_context = NULL; + ring->last_context = NULL; + } } i915_gem_context_unreference(dctx); + dev_priv->kernel_context = NULL; } int i915_gem_context_enable(struct drm_i915_gem_request *req) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 06ca4082735b..7eeb24427785 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1050,7 +1050,7 @@ static void i915_gem_record_rings(struct drm_device *dev, if (request) rbuf = request->ctx->engine[ring->id].ringbuf; else - rbuf = ring->default_context->engine[ring->id].ringbuf; + rbuf = dev_priv->kernel_context->engine[ring->id].ringbuf; } else rbuf = ring->buffer; diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 9c244247c13e..51ae5c1f806d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -964,7 +964,7 @@ int i915_guc_submission_enable(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc *guc = &dev_priv->guc; - struct intel_context *ctx = dev_priv->ring[RCS].default_context; + struct intel_context *ctx = dev_priv->kernel_context; struct i915_guc_client *client; /* client for execbuf submission */ @@ -1021,7 +1021,7 @@ int intel_guc_suspend(struct drm_device *dev) if (!i915.enable_guc_submission) return 0; - ctx = dev_priv->ring[RCS].default_context; + ctx = dev_priv->kernel_context; data[0] = HOST2GUC_ACTION_ENTER_S_STATE; /* any value greater than GUC_POWER_D0 */ @@ -1047,7 +1047,7 @@ int intel_guc_resume(struct drm_device *dev) if (!i915.enable_guc_submission) return 0; - ctx = dev_priv->ring[RCS].default_context; + ctx = dev_priv->kernel_context; data[0] = HOST2GUC_ACTION_EXIT_S_STATE; data[1] = GUC_POWER_D0; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ec2482daffa6..2c6da4013b1a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -598,7 +598,7 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) struct drm_i915_gem_request *cursor; int num_elements = 0; - if (request->ctx != ring->default_context) + if (request->ctx != request->i915->kernel_context) intel_lr_context_pin(request); i915_gem_request_reference(request); @@ -690,7 +690,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request request->ringbuf = request->ctx->engine[request->ring->id].ringbuf; - if (request->ctx != request->ring->default_context) { + if (request->ctx != request->i915->kernel_context) { ret = intel_lr_context_pin(request); if (ret) return ret; @@ -1006,7 +1006,7 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring) struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; - if (ctx_obj && (ctx != ring->default_context)) + if (ctx_obj && (ctx != req->i915->kernel_context)) intel_lr_context_unpin(req); list_del(&req->execlist_link); i915_gem_request_unreference(req); @@ -1529,7 +1529,7 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) u8 next_context_status_buffer_hw; lrc_setup_hardware_status_page(ring, - ring->default_context->engine[ring->id].state); + dev_priv->kernel_context->engine[ring->id].state); I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); @@ -2005,6 +2005,7 @@ logical_ring_default_irqs(struct intel_engine_cs *ring, unsigned shift) static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) { + struct intel_context *dctx = to_i915(dev)->kernel_context; int ret; /* Intentionally left blank. */ @@ -2027,12 +2028,12 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) if (ret) goto error; - ret = intel_lr_context_deferred_alloc(ring->default_context, ring); + ret = intel_lr_context_deferred_alloc(dctx, ring); if (ret) goto error; /* As this is the default context, always pin it */ - ret = intel_lr_context_do_pin(ring, ring->default_context); + ret = intel_lr_context_do_pin(ring, dctx); if (ret) { DRM_ERROR( "Failed to pin and map ringbuffer %s: %d\n", @@ -2398,7 +2399,7 @@ void intel_lr_context_free(struct intel_context *ctx) ctx->engine[i].ringbuf; struct intel_engine_cs *ring = ringbuf->ring; - if (ctx == ring->default_context) { + if (ctx == ctx->i915->kernel_context) { intel_unpin_ringbuffer_obj(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); } @@ -2517,7 +2518,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx, ctx->engine[ring->id].ringbuf = ringbuf; ctx->engine[ring->id].state = ctx_obj; - if (ctx != ring->default_context && ring->init_context) { + if (ctx != ctx->i915->kernel_context && ring->init_context) { struct drm_i915_gem_request *req; req = i915_gem_request_alloc(ring, ctx); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 91ac8a9bd903..0014fcaa5a0c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -309,7 +309,6 @@ struct intel_engine_cs { wait_queue_head_t irq_queue; - struct intel_context *default_context; struct intel_context *last_context; struct intel_ring_hangcheck hangcheck; -- GitLab From e28e404c3e93378c6ef3e2e6c9c5b1ab51e54bc4 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Tue, 19 Jan 2016 19:02:55 +0000 Subject: [PATCH 0248/5324] drm/i915: tidy up a few leftovers There are a few bits of code which the transformations implemented by the previous patch reveal to be suboptimal, once the notion of a per- ring default context has gone away. So this tidies up the leftovers. It could have been squashed into the previous patch, but that would have made that patch less clearly a simple transformation. In particular, any change which alters the code block structure or indentation has been deferred into this separate patch, because such things tend to make diffs more difficult to read. v4: Rebased Signed-off-by: Dave Gordon Reviewed-by: Nick Hoath Link: http://patchwork.freedesktop.org/patch/msgid/1453230175-19330-4-git-send-email-david.s.gordon@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 15 ++++-------- drivers/gpu/drm/i915/i915_gem.c | 6 ++--- drivers/gpu/drm/i915/intel_lrc.c | 38 +++++++++++++---------------- 3 files changed, 24 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 37c2c5009d9a..c5db23511184 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1960,11 +1960,8 @@ static int i915_context_status(struct seq_file *m, void *unused) seq_puts(m, "HW context "); describe_ctx(m, ctx); - for_each_ring(ring, dev_priv, i) { - if (dev_priv->kernel_context == ctx) - seq_printf(m, "(default context %s) ", - ring->name); - } + if (ctx == dev_priv->kernel_context) + seq_printf(m, "(kernel context) "); if (i915.enable_execlists) { seq_putc(m, '\n'); @@ -2056,12 +2053,10 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) if (ret) return ret; - list_for_each_entry(ctx, &dev_priv->context_list, link) { - for_each_ring(ring, dev_priv, i) { - if (dev_priv->kernel_context != ctx) + list_for_each_entry(ctx, &dev_priv->context_list, link) + if (ctx != dev_priv->kernel_context) + for_each_ring(ring, dev_priv, i) i915_dump_lrc_obj(m, ctx, ring); - } - } mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 06abe1bf5afc..6a3e4ee7f7e2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2679,10 +2679,8 @@ void i915_gem_request_free(struct kref *req_ref) i915_gem_request_remove_from_client(req); if (ctx) { - if (i915.enable_execlists) { - if (ctx != req->i915->kernel_context) - intel_lr_context_unpin(req); - } + if (i915.enable_execlists && ctx != req->i915->kernel_context) + intel_lr_context_unpin(req); i915_gem_context_unreference(ctx); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2c6da4013b1a..134379dc4dd9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -686,16 +686,10 @@ static int execlists_move_to_gpu(struct drm_i915_gem_request *req, int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request) { - int ret; + int ret = 0; request->ringbuf = request->ctx->engine[request->ring->id].ringbuf; - if (request->ctx != request->i915->kernel_context) { - ret = intel_lr_context_pin(request); - if (ret) - return ret; - } - if (i915.enable_guc_submission) { /* * Check that the GuC has space for the request before @@ -709,7 +703,10 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request return ret; } - return 0; + if (request->ctx != request->i915->kernel_context) + ret = intel_lr_context_pin(request); + + return ret; } static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, @@ -2391,22 +2388,21 @@ void intel_lr_context_free(struct intel_context *ctx) { int i; - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = I915_NUM_RINGS; --i >= 0; ) { + struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; - if (ctx_obj) { - struct intel_ringbuffer *ringbuf = - ctx->engine[i].ringbuf; - struct intel_engine_cs *ring = ringbuf->ring; + if (!ctx_obj) + continue; - if (ctx == ctx->i915->kernel_context) { - intel_unpin_ringbuffer_obj(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); - } - WARN_ON(ctx->engine[ring->id].pin_count); - intel_ringbuffer_free(ringbuf); - drm_gem_object_unreference(&ctx_obj->base); + if (ctx == ctx->i915->kernel_context) { + intel_unpin_ringbuffer_obj(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); } + + WARN_ON(ctx->engine[i].pin_count); + intel_ringbuffer_free(ringbuf); + drm_gem_object_unreference(&ctx_obj->base); } } @@ -2481,7 +2477,7 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, */ int intel_lr_context_deferred_alloc(struct intel_context *ctx, - struct intel_engine_cs *ring) + struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; struct drm_i915_gem_object *ctx_obj; -- GitLab From 6fa283b07e708913aa5fb38a3a20ba7adc05ba56 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jan 2016 21:00:56 +0100 Subject: [PATCH 0249/5324] drm/i915: Tune down "GT register while GT waking disabled" message We've had this since forever, and's randomly reporting issues and as such causing piles&piles of CI noise. Mika is working on proper debug infrastructure for this, and on fixing this properly. Meanwhile make CI more useful for everyone else. Cc: Mika Kuoppala Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93121 Signed-off-by: Daniel Vetter Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1453233656-12955-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 975af3568521..706b8eabfaf4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1356,7 +1356,7 @@ static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) if (!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEERR)) return; - DRM_ERROR("GT register access while GT waking disabled\n"); + DRM_DEBUG_DRIVER("GT register access while GT waking disabled\n"); I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); } -- GitLab From c81eeea6c14b212016104f4256c65f93ad230a86 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 20 Jan 2016 12:32:23 +0200 Subject: [PATCH 0250/5324] drm/i915: Limit the auto arming of mmio debugs on vlv/chv The capability to detect unclaimed register access was recently introduced for vlv/chv platforms. Apparently there are plenty of unclaimed access on these platforms, resulting in new dmesg warns. But as we are trying to form a beachhead for CI/Bat, all new warns are adding to the noise and thus not desirable at this point in time. Make it so that if in these platforms the automatic arming was responsible for mmio_debug enabling, ignore the warns. If user/dev wants to fix these, he can still do so by i915.mmio_debug=1234. Cc: Daniel Vetter Signed-off-by: Mika Kuoppala Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453285943-24614-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_uncore.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c3c13dc929cb..bfa79e5c214e 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -631,6 +631,15 @@ __unclaimed_reg_debug(struct drm_i915_private *dev_priv, const bool read, const bool before) { + /* XXX. We limit the auto arming traces for mmio + * debugs on these platforms. There are just too many + * revealed by these and CI/Bat suffers from the noise. + * Please fix and then re-enable the automatic traces. + */ + if (i915.mmio_debug < 2 && + (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))) + return; + if (WARN(check_for_unclaimed_mmio(dev_priv), "Unclaimed register detected %s %s register 0x%x\n", before ? "before" : "after", -- GitLab From 7c17d377374ddbcfb7873366559fc4ed8b296e11 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 20 Jan 2016 15:43:35 +0200 Subject: [PATCH 0251/5324] drm/i915: Use ordered seqno write interrupt generation on gen8+ execlists Broadwell and later currently use the same unordered command sequence to update the seqno in the HWS status page and then assert the user interrupt. We should apply the w/a from legacy (where we do an mmio read to delay the seqno read after the interrupt), but this is not enough to enforce coherent seqno visibilty on Skylake. Rather than search for the proper post-interrupt seqno barrier, use a strongly ordered command sequence to write the seqno, then assert the user interrupt from the ring. v2: Move around the wa tail dwords to avoid adding duplicate code. v3: Add references, comments on workarounds and bit5 check. References: https://bugs.freedesktop.org/show_bug.cgi?id=93693 Testcase: igt/gem_ring_sync_loop #skl Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1453297415-17793-1-git-send-email-mika.kuoppala@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 89 +++++++++++++++++-------- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 134379dc4dd9..7f47948d5c40 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -760,23 +760,34 @@ static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, * on a queue waiting for the ELSP to be ready to accept a new context submission. At that * point, the tail *inside* the context is updated and the ELSP written to. */ -static void +static int intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) { - struct intel_engine_cs *ring = request->ring; + struct intel_ringbuffer *ringbuf = request->ringbuf; struct drm_i915_private *dev_priv = request->i915; - intel_logical_ring_advance(request->ringbuf); + intel_logical_ring_advance(ringbuf); + request->tail = ringbuf->tail; - request->tail = request->ringbuf->tail; + /* + * Here we add two extra NOOPs as padding to avoid + * lite restore of a context with HEAD==TAIL. + * + * Caller must reserve WA_TAIL_DWORDS for us! + */ + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_advance(ringbuf); - if (intel_ring_stopped(ring)) - return; + if (intel_ring_stopped(request->ring)) + return 0; if (dev_priv->guc.execbuf_client) i915_guc_submit(dev_priv->guc.execbuf_client, request); else execlists_context_queue(request); + + return 0; } static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf) @@ -1845,44 +1856,65 @@ static void bxt_a_set_seqno(struct intel_engine_cs *ring, u32 seqno) intel_flush_status_page(ring, I915_GEM_HWS_INDEX); } +/* + * Reserve space for 2 NOOPs at the end of each request to be + * used as a workaround for not being allowed to do lite + * restore with HEAD==TAIL (WaIdleLiteRestore). + */ +#define WA_TAIL_DWORDS 2 + +static inline u32 hws_seqno_address(struct intel_engine_cs *engine) +{ + return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR; +} + static int gen8_emit_request(struct drm_i915_gem_request *request) { struct intel_ringbuffer *ringbuf = request->ringbuf; - struct intel_engine_cs *ring = ringbuf->ring; - u32 cmd; int ret; - /* - * Reserve space for 2 NOOPs at the end of each request to be - * used as a workaround for not being allowed to do lite - * restore with HEAD==TAIL (WaIdleLiteRestore). - */ - ret = intel_logical_ring_begin(request, 8); + ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS); if (ret) return ret; - cmd = MI_STORE_DWORD_IMM_GEN4; - cmd |= MI_GLOBAL_GTT; + /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */ + BUILD_BUG_ON(I915_GEM_HWS_INDEX_ADDR & (1 << 5)); - intel_logical_ring_emit(ringbuf, cmd); intel_logical_ring_emit(ringbuf, - (ring->status_page.gfx_addr + - (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT))); + (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW); + intel_logical_ring_emit(ringbuf, + hws_seqno_address(request->ring) | + MI_FLUSH_DW_USE_GTT); intel_logical_ring_emit(ringbuf, 0); intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); intel_logical_ring_emit(ringbuf, MI_NOOP); - intel_logical_ring_advance_and_submit(request); + return intel_logical_ring_advance_and_submit(request); +} - /* - * Here we add two extra NOOPs as padding to avoid - * lite restore of a context with HEAD==TAIL. - */ - intel_logical_ring_emit(ringbuf, MI_NOOP); - intel_logical_ring_emit(ringbuf, MI_NOOP); - intel_logical_ring_advance(ringbuf); +static int gen8_emit_request_render(struct drm_i915_gem_request *request) +{ + struct intel_ringbuffer *ringbuf = request->ringbuf; + int ret; - return 0; + ret = intel_logical_ring_begin(request, 6 + WA_TAIL_DWORDS); + if (ret) + return ret; + + /* w/a for post sync ops following a GPGPU operation we + * need a prior CS_STALL, which is emitted by the flush + * following the batch. + */ + intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(5)); + intel_logical_ring_emit(ringbuf, + (PIPE_CONTROL_GLOBAL_GTT_IVB | + PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_QW_WRITE)); + intel_logical_ring_emit(ringbuf, hws_seqno_address(request->ring)); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); + intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); + return intel_logical_ring_advance_and_submit(request); } static int intel_lr_context_render_state_init(struct drm_i915_gem_request *req) @@ -2069,6 +2101,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->init_context = gen8_init_rcs_context; ring->cleanup = intel_fini_pipe_control; ring->emit_flush = gen8_emit_flush_render; + ring->emit_request = gen8_emit_request_render; ring->dev = dev; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 0014fcaa5a0c..b6c7cd2b8a40 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -426,6 +426,7 @@ intel_write_status_page(struct intel_engine_cs *ring, * The area from dword 0x30 to 0x3ff is available for driver usage. */ #define I915_GEM_HWS_INDEX 0x30 +#define I915_GEM_HWS_INDEX_ADDR (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT) #define I915_GEM_HWS_SCRATCH_INDEX 0x40 #define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT) -- GitLab From de1add360522c876c25ef2bbbbab1c94bdb509ab Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 15 Jan 2016 15:12:50 +0000 Subject: [PATCH 0252/5324] drm/i915: Decouple execbuf uAPI from internal implementation At the moment execbuf ring selection is fully coupled to internal ring ids which is not a good thing on its own. This dependency is also spread between two source files and not spelled out at either side which makes it hidden and fragile. This patch decouples this dependency by introducing an explicit translation table of execbuf uAPI to ring id close to the only call site (i915_gem_do_execbuffer). This way we are free to change driver internal implementation details without breaking userspace. All state relating to the uAPI is now contained in, or next to, i915_gem_do_execbuffer. As a side benefit, this patch decreases the compiled size of i915_gem_do_execbuffer. v2: Extract ring selection into eb_select_ring. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Cc: Chris Wilson Reviewed-by: Chris Wilson Acked-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452870770-13981-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_gem.c | 2 + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 139 +++++++++++---------- drivers/gpu/drm/i915/intel_ringbuffer.h | 10 +- 4 files changed, 81 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 840368de3f4f..204661f9873d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -334,7 +334,7 @@ struct drm_i915_file_private { unsigned boosts; } rps; - struct intel_engine_cs *bsd_ring; + unsigned int bsd_ring; }; enum intel_dpll_id { @@ -1299,7 +1299,7 @@ struct i915_gem_mm { bool busy; /* the indicator for dispatch video commands on two BSD rings */ - int bsd_ring_dispatch_index; + unsigned int bsd_ring_dispatch_index; /** Bit 6 swizzling required for X tiling */ uint32_t bit_6_swizzle_x; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6a3e4ee7f7e2..0ed731ed6976 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5141,6 +5141,8 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) spin_lock_init(&file_priv->mm.lock); INIT_LIST_HEAD(&file_priv->mm.request_list); + file_priv->bsd_ring = -1; + ret = i915_gem_context_open(dev, file); if (ret) kfree(file_priv); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index dc32018ee2e9..2dc08ce1079a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1325,33 +1325,23 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, /** * Find one BSD ring to dispatch the corresponding BSD command. - * The Ring ID is returned. + * The ring index is returned. */ -static int gen8_dispatch_bsd_ring(struct drm_device *dev, - struct drm_file *file) +static unsigned int +gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_file_private *file_priv = file->driver_priv; - /* Check whether the file_priv is using one ring */ - if (file_priv->bsd_ring) - return file_priv->bsd_ring->id; - else { - /* If no, use the ping-pong mechanism to select one ring */ - int ring_id; - - mutex_lock(&dev->struct_mutex); - if (dev_priv->mm.bsd_ring_dispatch_index == 0) { - ring_id = VCS; - dev_priv->mm.bsd_ring_dispatch_index = 1; - } else { - ring_id = VCS2; - dev_priv->mm.bsd_ring_dispatch_index = 0; - } - file_priv->bsd_ring = &dev_priv->ring[ring_id]; - mutex_unlock(&dev->struct_mutex); - return ring_id; + /* Check whether the file_priv has already selected one ring. */ + if ((int)file_priv->bsd_ring < 0) { + /* If not, use the ping-pong mechanism to select one. */ + mutex_lock(&dev_priv->dev->struct_mutex); + file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index; + dev_priv->mm.bsd_ring_dispatch_index ^= 1; + mutex_unlock(&dev_priv->dev->struct_mutex); } + + return file_priv->bsd_ring; } static struct drm_i915_gem_object * @@ -1374,6 +1364,63 @@ eb_get_batch(struct eb_vmas *eb) return vma->obj; } +#define I915_USER_RINGS (4) + +static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = { + [I915_EXEC_DEFAULT] = RCS, + [I915_EXEC_RENDER] = RCS, + [I915_EXEC_BLT] = BCS, + [I915_EXEC_BSD] = VCS, + [I915_EXEC_VEBOX] = VECS +}; + +static int +eb_select_ring(struct drm_i915_private *dev_priv, + struct drm_file *file, + struct drm_i915_gem_execbuffer2 *args, + struct intel_engine_cs **ring) +{ + unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK; + + if (user_ring_id > I915_USER_RINGS) { + DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id); + return -EINVAL; + } + + if ((user_ring_id != I915_EXEC_BSD) && + ((args->flags & I915_EXEC_BSD_MASK) != 0)) { + DRM_DEBUG("execbuf with non bsd ring but with invalid " + "bsd dispatch flags: %d\n", (int)(args->flags)); + return -EINVAL; + } + + if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) { + unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK; + + if (bsd_idx == I915_EXEC_BSD_DEFAULT) { + bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file); + } else if (bsd_idx >= I915_EXEC_BSD_RING1 && + bsd_idx <= I915_EXEC_BSD_RING2) { + bsd_idx--; + } else { + DRM_DEBUG("execbuf with unknown bsd ring: %u\n", + bsd_idx); + return -EINVAL; + } + + *ring = &dev_priv->ring[_VCS(bsd_idx)]; + } else { + *ring = &dev_priv->ring[user_ring_map[user_ring_id]]; + } + + if (!intel_ring_initialized(*ring)) { + DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id); + return -EINVAL; + } + + return 0; +} + static int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file, @@ -1412,51 +1459,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (args->flags & I915_EXEC_IS_PINNED) dispatch_flags |= I915_DISPATCH_PINNED; - if ((args->flags & I915_EXEC_RING_MASK) > LAST_USER_RING) { - DRM_DEBUG("execbuf with unknown ring: %d\n", - (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; - } - - if (((args->flags & I915_EXEC_RING_MASK) != I915_EXEC_BSD) && - ((args->flags & I915_EXEC_BSD_MASK) != 0)) { - DRM_DEBUG("execbuf with non bsd ring but with invalid " - "bsd dispatch flags: %d\n", (int)(args->flags)); - return -EINVAL; - } - - if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT) - ring = &dev_priv->ring[RCS]; - else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) { - if (HAS_BSD2(dev)) { - int ring_id; - - switch (args->flags & I915_EXEC_BSD_MASK) { - case I915_EXEC_BSD_DEFAULT: - ring_id = gen8_dispatch_bsd_ring(dev, file); - ring = &dev_priv->ring[ring_id]; - break; - case I915_EXEC_BSD_RING1: - ring = &dev_priv->ring[VCS]; - break; - case I915_EXEC_BSD_RING2: - ring = &dev_priv->ring[VCS2]; - break; - default: - DRM_DEBUG("execbuf with unknown bsd ring: %d\n", - (int)(args->flags & I915_EXEC_BSD_MASK)); - return -EINVAL; - } - } else - ring = &dev_priv->ring[VCS]; - } else - ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1]; - - if (!intel_ring_initialized(ring)) { - DRM_DEBUG("execbuf with invalid ring: %d\n", - (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; - } + ret = eb_select_ring(dev_priv, file, args, &ring); + if (ret) + return ret; if (args->buffer_count < 1) { DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b6c7cd2b8a40..5b44ca63405d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -149,14 +149,14 @@ struct i915_ctx_workarounds { struct intel_engine_cs { const char *name; enum intel_ring_id { - RCS = 0x0, - VCS, + RCS = 0, BCS, - VECS, - VCS2 + VCS, + VCS2, /* Keep instances of the same type engine together. */ + VECS } id; #define I915_NUM_RINGS 5 -#define LAST_USER_RING (VECS + 1) +#define _VCS(n) (VCS + (n)) u32 mmio_base; struct drm_device *dev; struct intel_ringbuffer *buffer; -- GitLab From 426960bed3217f72a1b7bb94f084d79cc616ec0f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 Jan 2016 16:51:46 +0000 Subject: [PATCH 0253/5324] drm/i915: Seal busy-ioctl uABI and prevent leaking of internal ids Tvrtko was looking through the execbuffer-ioctl and noticed that the uABI was tightly coupled to our internal engine identifiers. Close inspection also revealed that we leak those internal engine identifiers through the busy-ioctl, and those internal identifiers already do not match the user identifiers. Fortuitiously, there is only one user of the set of busy rings from the busy-ioctl, and they only wish to choose between the RENDER and the BLT engines. Let's fix the userspace ABI while we still can. v2: Update the uAPI documentation to explain the identifiers. Signed-off-by: Chris Wilson Testcase: igt/gem_busy Cc: Tvrtko Ursulin Cc: Daniel Vetter Reviewed-by: Tvrtko Ursulin Acked-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452876706-21620-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 18 +++++++++++--- drivers/gpu/drm/i915/intel_lrc.c | 5 ++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 5 ++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + include/uapi/drm/i915_drm.h | 33 ++++++++++++++++++++++--- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0ed731ed6976..371bbb28c471 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4358,10 +4358,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, if (ret) goto unref; - BUILD_BUG_ON(I915_NUM_RINGS > 16); - args->busy = obj->active << 16; - if (obj->last_write_req) - args->busy |= obj->last_write_req->ring->id; + args->busy = 0; + if (obj->active) { + int i; + + for (i = 0; i < I915_NUM_RINGS; i++) { + struct drm_i915_gem_request *req; + + req = obj->last_read_req[i]; + if (req) + args->busy |= 1 << (16 + req->ring->exec_id); + } + if (obj->last_write_req) + args->busy |= obj->last_write_req->ring->exec_id; + } unref: drm_gem_object_unreference(&obj->base); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 7f47948d5c40..73d4347429df 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2085,6 +2085,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->name = "render ring"; ring->id = RCS; + ring->exec_id = I915_EXEC_RENDER; ring->mmio_base = RENDER_RING_BASE; logical_ring_default_irqs(ring, GEN8_RCS_IRQ_SHIFT); @@ -2135,6 +2136,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->name = "bsd ring"; ring->id = VCS; + ring->exec_id = I915_EXEC_BSD; ring->mmio_base = GEN6_BSD_RING_BASE; logical_ring_default_irqs(ring, GEN8_VCS1_IRQ_SHIFT); @@ -2150,6 +2152,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->name = "bsd2 ring"; ring->id = VCS2; + ring->exec_id = I915_EXEC_BSD; ring->mmio_base = GEN8_BSD2_RING_BASE; logical_ring_default_irqs(ring, GEN8_VCS2_IRQ_SHIFT); @@ -2165,6 +2168,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->name = "blitter ring"; ring->id = BCS; + ring->exec_id = I915_EXEC_BLT; ring->mmio_base = BLT_RING_BASE; logical_ring_default_irqs(ring, GEN8_BCS_IRQ_SHIFT); @@ -2180,6 +2184,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->name = "video enhancement ring"; ring->id = VECS; + ring->exec_id = I915_EXEC_VEBOX; ring->mmio_base = VEBOX_RING_BASE; logical_ring_default_irqs(ring, GEN8_VECS_IRQ_SHIFT); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d4e33ac02efa..9030e2bca0c0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2683,6 +2683,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->name = "render ring"; ring->id = RCS; + ring->exec_id = I915_EXEC_RENDER; ring->mmio_base = RENDER_RING_BASE; if (INTEL_INFO(dev)->gen >= 8) { @@ -2831,6 +2832,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) ring->name = "bsd ring"; ring->id = VCS; + ring->exec_id = I915_EXEC_BSD; ring->write_tail = ring_write_tail; if (INTEL_INFO(dev)->gen >= 6) { @@ -2907,6 +2909,7 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) ring->name = "bsd2 ring"; ring->id = VCS2; + ring->exec_id = I915_EXEC_BSD; ring->write_tail = ring_write_tail; ring->mmio_base = GEN8_BSD2_RING_BASE; @@ -2937,6 +2940,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) ring->name = "blitter ring"; ring->id = BCS; + ring->exec_id = I915_EXEC_BLT; ring->mmio_base = BLT_RING_BASE; ring->write_tail = ring_write_tail; @@ -2994,6 +2998,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) ring->name = "video enhancement ring"; ring->id = VECS; + ring->exec_id = I915_EXEC_VEBOX; ring->mmio_base = VEBOX_RING_BASE; ring->write_tail = ring_write_tail; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 5b44ca63405d..b12f2aabd104 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -157,6 +157,7 @@ struct intel_engine_cs { } id; #define I915_NUM_RINGS 5 #define _VCS(n) (VCS + (n)) + unsigned int exec_id; u32 mmio_base; struct drm_device *dev; struct intel_ringbuffer *buffer; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index acf21026c78a..6a19371391fa 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -812,10 +812,35 @@ struct drm_i915_gem_busy { /** Handle of the buffer to check for busy */ __u32 handle; - /** Return busy status (1 if busy, 0 if idle). - * The high word is used to indicate on which rings the object - * currently resides: - * 16:31 - busy (r or r/w) rings (16 render, 17 bsd, 18 blt, etc) + /** Return busy status + * + * A return of 0 implies that the object is idle (after + * having flushed any pending activity), and a non-zero return that + * the object is still in-flight on the GPU. (The GPU has not yet + * signaled completion for all pending requests that reference the + * object.) + * + * The returned dword is split into two fields to indicate both + * the engines on which the object is being read, and the + * engine on which it is currently being written (if any). + * + * The low word (bits 0:15) indicate if the object is being written + * to by any engine (there can only be one, as the GEM implicit + * synchronisation rules force writes to be serialised). Only the + * engine for the last write is reported. + * + * The high word (bits 16:31) are a bitmask of which engines are + * currently reading from the object. Multiple engines may be + * reading from the object simultaneously. + * + * The value of each engine is the same as specified in the + * EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc. + * Note I915_EXEC_DEFAULT is a symbolic value and is mapped to + * the I915_EXEC_RENDER engine for execution, and so it is never + * reported as active itself. Some hardware may have parallel + * execution engines, e.g. multiple media engines, which are + * mapped to the same identifier in the EXECBUFFER2 ioctl and + * so are not separately reported for busyness. */ __u32 busy; }; -- GitLab From 753b11ef8e92a1c1bbe97f2a5ec14bdd1ef2e6fe Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 21 Jan 2016 14:11:59 +0000 Subject: [PATCH 0254/5324] x86/efi: Setup separate EFI page tables in kexec paths The switch to using a new dedicated page table for EFI runtime calls in commit commit 67a9108ed431 ("x86/efi: Build our own page table structures") failed to take into account changes required for the kexec code paths, which are unfortunately duplicated in the EFI code. Call the allocation and setup functions in kexec_enter_virtual_mode() just like we do for __efi_enter_virtual_mode() to avoid hitting NULL-pointer dereferences when making EFI runtime calls. At the very least, the call to efi_setup_page_tables() should have existed for kexec before the following commit: 67a9108ed431 ("x86/efi: Build our own page table structures") Things just magically worked because we were actually using the kernel's page tables that contained the required mappings. Reported-by: Srikar Dronamraju Tested-by: Srikar Dronamraju Signed-off-by: Matt Fleming Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Young Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Raghavendra K T Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1453385519-11477-1-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 3c1f3cd7b2ba..bdd9477f937c 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -815,6 +815,7 @@ static void __init kexec_enter_virtual_mode(void) { #ifdef CONFIG_KEXEC_CORE efi_memory_desc_t *md; + unsigned int num_pages; void *p; efi.systab = NULL; @@ -829,6 +830,12 @@ static void __init kexec_enter_virtual_mode(void) return; } + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + /* * Map efi regions which were passed via setup_data. The virt_addr is a * fixed addr which was used in first kernel of a kexec boot. @@ -843,6 +850,14 @@ static void __init kexec_enter_virtual_mode(void) BUG_ON(!efi.systab); + num_pages = ALIGN(memmap.nr_map * memmap.desc_size, PAGE_SIZE); + num_pages >>= PAGE_SHIFT; + + if (efi_setup_page_tables(memmap.phys_map, num_pages)) { + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_sync_low_kernel_mappings(); /* -- GitLab From 23819f2eaab87080b0190ed94a0728fc8ea84711 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Sun, 10 Jan 2016 07:46:39 +0100 Subject: [PATCH 0255/5324] mtd: nand: mpc5121: use 'of_machine_is_compatible' to simplify code The current code is the same as 'of_machine_is_compatible'. So use it in order to remove a few lines of code and to be more consistent with other parts of the kernel. Signed-off-by: Christophe JAILLET Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/mpc5121_nfc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 6b93e899d4e9..5d7843ffff6a 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -626,7 +626,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) static int mpc5121_nfc_probe(struct platform_device *op) { - struct device_node *rootnode, *dn = op->dev.of_node; + struct device_node *dn = op->dev.of_node; struct clk *clk; struct device *dev = &op->dev; struct mpc5121_nfc_prv *prv; @@ -712,18 +712,15 @@ static int mpc5121_nfc_probe(struct platform_device *op) chip->ecc.mode = NAND_ECC_SOFT; /* Support external chip-select logic on ADS5121 board */ - rootnode = of_find_node_by_path("/"); - if (of_device_is_compatible(rootnode, "fsl,mpc5121ads")) { + if (of_machine_is_compatible("fsl,mpc5121ads")) { retval = ads5121_chipselect_init(mtd); if (retval) { dev_err(dev, "Chipselect init error!\n"); - of_node_put(rootnode); return retval; } chip->select_chip = ads5121_select_chip; } - of_node_put(rootnode); /* Enable NFC clock */ clk = devm_clk_get(dev, "ipg"); -- GitLab From c03d996900f9d063b47ef7462885a9085c8a587f Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 2 Dec 2015 12:01:05 +0100 Subject: [PATCH 0256/5324] mtd: nand: add NAND_NEED_SCRAMBLING option flag Some MLC NANDs are sensitive to repeated patterns and require data to be scrambled in order to limit the number of bitflips. Add a new flag to let the NAND controller know about this constraint. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index bdd68e22b5a5..a13dfd5bc58b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -168,6 +168,12 @@ typedef enum { /* Device supports subpage reads */ #define NAND_SUBPAGE_READ 0x00001000 +/* + * Some MLC NANDs need data scrambling to limit bitflips caused by repeated + * patterns. + */ +#define NAND_NEED_SCRAMBLING 0x00002000 + /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG -- GitLab From 8ebc5637154dc58378c85ea7d0047fbc72cfc2d7 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 2 Dec 2015 12:01:06 +0100 Subject: [PATCH 0257/5324] mtd: nand: add NAND_NEED_SCRAMBLING flag to the H27UCG8T2ATR-BC definition The H27UCG8T2ATR-BC requires an external data scrambler. Reflect this constraint in the nand_flash_ids definition. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_ids.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index a8804a3da076..ccc05f5b2695 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -50,8 +50,8 @@ struct nand_flash_dev nand_flash_ids[] = { SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) }, {"H27UCG8T2ATR-BC 64G 3.3V 8-bit", { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} }, - SZ_8K, SZ_8K, SZ_2M, 0, 6, 640, NAND_ECC_INFO(40, SZ_1K), - 4 }, + SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640, + NAND_ECC_INFO(40, SZ_1K), 4 }, LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), -- GitLab From 4be4e03efc7f45ec002e8eddc83c22f80fed392c Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 2 Dec 2015 12:01:07 +0100 Subject: [PATCH 0258/5324] mtd: nand: sunxi: add randomizer support Add support for the randomizer engine available in Allwinner's NFC IP. Randomization is useful to support modern NAND chips which are sensitive to repeated patterns. On such NANDs you might experience an unexpectedly high number of bitflips when you repeat the same pattern all over a given NAND block. Randomizing input data mitigate this problem by avoiding such repeated patterns. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/sunxi_nand.c | 287 +++++++++++++++++++++++++++++++--- 1 file changed, 261 insertions(+), 26 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 51e10a35fe08..5f700719d5c2 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -60,6 +60,7 @@ #define NFC_REG_ECC_ERR_CNT(x) ((0x0040 + (x)) & ~0x3) #define NFC_REG_USER_DATA(x) (0x0050 + ((x) * 4)) #define NFC_REG_SPARE_AREA 0x00A0 +#define NFC_REG_PAT_ID 0x00A4 #define NFC_RAM0_BASE 0x0400 #define NFC_RAM1_BASE 0x0800 @@ -538,6 +539,174 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); } +/* These seed values have been extracted from Allwinner's BSP */ +static const u16 sunxi_nfc_randomizer_page_seeds[] = { + 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, + 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436, + 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d, + 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130, + 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56, + 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55, + 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb, + 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17, + 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62, + 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064, + 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126, + 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e, + 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3, + 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b, + 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d, + 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db, +}; + +/* + * sunxi_nfc_randomizer_ecc512_seeds and sunxi_nfc_randomizer_ecc1024_seeds + * have been generated using + * sunxi_nfc_randomizer_step(seed, (step_size * 8) + 15), which is what + * the randomizer engine does internally before de/scrambling OOB data. + * + * Those tables are statically defined to avoid calculating randomizer state + * at runtime. + */ +static const u16 sunxi_nfc_randomizer_ecc512_seeds[] = { + 0x3346, 0x367f, 0x1f18, 0x769a, 0x4f64, 0x068c, 0x2ef1, 0x6b64, + 0x28a9, 0x15d7, 0x30f8, 0x3659, 0x53db, 0x7c5f, 0x71d4, 0x4409, + 0x26eb, 0x03cc, 0x655d, 0x47d4, 0x4daa, 0x0877, 0x712d, 0x3617, + 0x3264, 0x49aa, 0x7f9e, 0x588e, 0x4fbc, 0x7176, 0x7f91, 0x6c6d, + 0x4b95, 0x5fb7, 0x3844, 0x4037, 0x0184, 0x081b, 0x0ee8, 0x5b91, + 0x293d, 0x1f71, 0x0e6f, 0x402b, 0x5122, 0x1e52, 0x22be, 0x3d2d, + 0x75bc, 0x7c60, 0x6291, 0x1a2f, 0x61d4, 0x74aa, 0x4140, 0x29ab, + 0x472d, 0x2852, 0x017e, 0x15e8, 0x5ec2, 0x17cf, 0x7d0f, 0x06b8, + 0x117a, 0x6b94, 0x789b, 0x3126, 0x6ac5, 0x5be7, 0x150f, 0x51f8, + 0x7889, 0x0aa5, 0x663d, 0x77e8, 0x0b87, 0x3dcb, 0x360d, 0x218b, + 0x512f, 0x7dc9, 0x6a4d, 0x630a, 0x3547, 0x1dd2, 0x5aea, 0x69a5, + 0x7bfa, 0x5e4f, 0x1519, 0x6430, 0x3a0e, 0x5eb3, 0x5425, 0x0c7a, + 0x5540, 0x3670, 0x63c1, 0x31e9, 0x5a39, 0x2de7, 0x5979, 0x2891, + 0x1562, 0x014b, 0x5b05, 0x2756, 0x5a34, 0x13aa, 0x6cb5, 0x2c36, + 0x5e72, 0x1306, 0x0861, 0x15ef, 0x1ee8, 0x5a37, 0x7ac4, 0x45dd, + 0x44c4, 0x7266, 0x2f41, 0x3ccc, 0x045e, 0x7d40, 0x7c66, 0x0fa0, +}; + +static const u16 sunxi_nfc_randomizer_ecc1024_seeds[] = { + 0x2cf5, 0x35f1, 0x63a4, 0x5274, 0x2bd2, 0x778b, 0x7285, 0x32b6, + 0x6a5c, 0x70d6, 0x757d, 0x6769, 0x5375, 0x1e81, 0x0cf3, 0x3982, + 0x6787, 0x042a, 0x6c49, 0x1925, 0x56a8, 0x40a9, 0x063e, 0x7bd9, + 0x4dbf, 0x55ec, 0x672e, 0x7334, 0x5185, 0x4d00, 0x232a, 0x7e07, + 0x445d, 0x6b92, 0x528f, 0x4255, 0x53ba, 0x7d82, 0x2a2e, 0x3a4e, + 0x75eb, 0x450c, 0x6844, 0x1b5d, 0x581a, 0x4cc6, 0x0379, 0x37b2, + 0x419f, 0x0e92, 0x6b27, 0x5624, 0x01e3, 0x07c1, 0x44a5, 0x130c, + 0x13e8, 0x5910, 0x0876, 0x60c5, 0x54e3, 0x5b7f, 0x2269, 0x509f, + 0x7665, 0x36fd, 0x3e9a, 0x0579, 0x6295, 0x14ef, 0x0a81, 0x1bcc, + 0x4b16, 0x64db, 0x0514, 0x4f07, 0x0591, 0x3576, 0x6853, 0x0d9e, + 0x259f, 0x38b7, 0x64fb, 0x3094, 0x4693, 0x6ddd, 0x29bb, 0x0bc8, + 0x3f47, 0x490e, 0x0c0e, 0x7933, 0x3c9e, 0x5840, 0x398d, 0x3e68, + 0x4af1, 0x71f5, 0x57cf, 0x1121, 0x64eb, 0x3579, 0x15ac, 0x584d, + 0x5f2a, 0x47e2, 0x6528, 0x6eac, 0x196e, 0x6b96, 0x0450, 0x0179, + 0x609c, 0x06e1, 0x4626, 0x42c7, 0x273e, 0x486f, 0x0705, 0x1601, + 0x145b, 0x407e, 0x062b, 0x57a5, 0x53f9, 0x5659, 0x4410, 0x3ccd, +}; + +static u16 sunxi_nfc_randomizer_step(u16 state, int count) +{ + state &= 0x7fff; + + /* + * This loop is just a simple implementation of a Fibonacci LFSR using + * the x16 + x15 + 1 polynomial. + */ + while (count--) + state = ((state >> 1) | + (((state ^ (state >> 1)) & 1) << 14)) & 0x7fff; + + return state; +} + +static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc) +{ + const u16 *seeds = sunxi_nfc_randomizer_page_seeds; + int mod = mtd->erasesize / mtd->writesize; + + if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds)) + mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds); + + if (ecc) { + if (mtd->ecc_step_size == 512) + seeds = sunxi_nfc_randomizer_ecc512_seeds; + else + seeds = sunxi_nfc_randomizer_ecc1024_seeds; + } + + return seeds[page % mod]; +} + +static void sunxi_nfc_randomizer_config(struct mtd_info *mtd, + int page, bool ecc) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL); + u16 state; + + if (!(nand->options & NAND_NEED_SCRAMBLING)) + return; + + ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL); + state = sunxi_nfc_randomizer_state(mtd, page, ecc); + ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK; + writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL); +} + +static void sunxi_nfc_randomizer_enable(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + + if (!(nand->options & NAND_NEED_SCRAMBLING)) + return; + + writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN, + nfc->regs + NFC_REG_ECC_CTL); +} + +static void sunxi_nfc_randomizer_disable(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd->priv; + struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + + if (!(nand->options & NAND_NEED_SCRAMBLING)) + return; + + writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN, + nfc->regs + NFC_REG_ECC_CTL); +} + +static void sunxi_nfc_randomize_bbm(struct mtd_info *mtd, int page, u8 *bbm) +{ + u16 state = sunxi_nfc_randomizer_state(mtd, page, true); + + bbm[0] ^= state; + bbm[1] ^= sunxi_nfc_randomizer_step(state, 8); +} + +static void sunxi_nfc_randomizer_write_buf(struct mtd_info *mtd, + const uint8_t *buf, int len, + bool ecc, int page) +{ + sunxi_nfc_randomizer_config(mtd, page, ecc); + sunxi_nfc_randomizer_enable(mtd); + sunxi_nfc_write_buf(mtd, buf, len); + sunxi_nfc_randomizer_disable(mtd); +} + +static void sunxi_nfc_randomizer_read_buf(struct mtd_info *mtd, uint8_t *buf, + int len, bool ecc, int page) +{ + sunxi_nfc_randomizer_config(mtd, page, ecc); + sunxi_nfc_randomizer_enable(mtd); + sunxi_nfc_read_buf(mtd, buf, len); + sunxi_nfc_randomizer_disable(mtd); +} + static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) { struct nand_chip *nand = mtd_to_nand(mtd); @@ -574,18 +743,20 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, u8 *data, int data_off, u8 *oob, int oob_off, int *cur_off, - unsigned int *max_bitflips) + unsigned int *max_bitflips, + bool bbm, int page) { struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); struct nand_ecc_ctrl *ecc = &nand->ecc; + int raw_mode = 0; u32 status; int ret; if (*cur_off != data_off) nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1); - sunxi_nfc_read_buf(mtd, NULL, ecc->size); + sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page); if (data_off + ecc->size != oob_off) nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1); @@ -594,25 +765,54 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, if (ret) return ret; + sunxi_nfc_randomizer_enable(mtd); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, nfc->regs + NFC_REG_CMD); ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + sunxi_nfc_randomizer_disable(mtd); if (ret) return ret; + *cur_off = oob_off + ecc->bytes + 4; + status = readl(nfc->regs + NFC_REG_ECC_ST); + if (status & NFC_ECC_PAT_FOUND(0)) { + u8 pattern = 0xff; + + if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1))) + pattern = 0x0; + + memset(data, pattern, ecc->size); + memset(oob, pattern, ecc->bytes + 4); + + return 1; + } + ret = NFC_ECC_ERR_CNT(0, readl(nfc->regs + NFC_REG_ECC_ERR_CNT(0))); memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1); - sunxi_nfc_read_buf(mtd, oob, ecc->bytes + 4); + sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page); if (status & NFC_ECC_ERR(0)) { + /* + * Re-read the data with the randomizer disabled to identify + * bitflips in erased pages. + */ + if (nand->options & NAND_NEED_SCRAMBLING) { + nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1); + nand->read_buf(mtd, data, ecc->size); + nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1); + nand->read_buf(mtd, oob, ecc->bytes + 4); + } + ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, ecc->bytes + 4, NULL, 0, ecc->strength); + if (ret >= 0) + raw_mode = 1; } else { /* * The engine protects 4 bytes of OOB data per chunk. @@ -620,6 +820,10 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, */ sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(0)), oob); + + /* De-randomize the Bad Block Marker. */ + if (bbm && nand->options & NAND_NEED_SCRAMBLING) + sunxi_nfc_randomize_bbm(mtd, page, oob); } if (ret < 0) { @@ -629,13 +833,12 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, *max_bitflips = max_t(unsigned int, *max_bitflips, ret); } - *cur_off = oob_off + ecc->bytes + 4; - - return 0; + return raw_mode; } static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd, - u8 *oob, int *cur_off) + u8 *oob, int *cur_off, + bool randomize, int page) { struct nand_chip *nand = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &nand->ecc; @@ -649,7 +852,11 @@ static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd, nand->cmdfunc(mtd, NAND_CMD_RNDOUT, offset + mtd->writesize, -1); - sunxi_nfc_read_buf(mtd, oob + offset, len); + if (!randomize) + sunxi_nfc_read_buf(mtd, oob + offset, len); + else + sunxi_nfc_randomizer_read_buf(mtd, oob + offset, len, + false, page); *cur_off = mtd->oobsize + mtd->writesize; } @@ -662,7 +869,8 @@ static inline u32 sunxi_nfc_buf_to_user_data(const u8 *buf) static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, const u8 *data, int data_off, const u8 *oob, int oob_off, - int *cur_off) + int *cur_off, bool bbm, + int page) { struct nand_chip *nand = mtd_to_nand(mtd); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); @@ -672,11 +880,20 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, if (data_off != *cur_off) nand->cmdfunc(mtd, NAND_CMD_RNDIN, data_off, -1); - sunxi_nfc_write_buf(mtd, data, ecc->size); + sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page); /* Fill OOB data in */ - writel(sunxi_nfc_buf_to_user_data(oob), - nfc->regs + NFC_REG_USER_DATA(0)); + if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) { + u8 user_data[4]; + + memcpy(user_data, oob, 4); + sunxi_nfc_randomize_bbm(mtd, page, user_data); + writel(sunxi_nfc_buf_to_user_data(user_data), + nfc->regs + NFC_REG_USER_DATA(0)); + } else { + writel(sunxi_nfc_buf_to_user_data(oob), + nfc->regs + NFC_REG_USER_DATA(0)); + } if (data_off + ecc->size != oob_off) nand->cmdfunc(mtd, NAND_CMD_RNDIN, oob_off, -1); @@ -685,11 +902,13 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, if (ret) return ret; + sunxi_nfc_randomizer_enable(mtd); writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | NFC_ECC_OP, nfc->regs + NFC_REG_CMD); ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + sunxi_nfc_randomizer_disable(mtd); if (ret) return ret; @@ -699,7 +918,8 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, } static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd, - u8 *oob, int *cur_off) + u8 *oob, int *cur_off, + int page) { struct nand_chip *nand = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &nand->ecc; @@ -713,7 +933,7 @@ static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd, nand->cmdfunc(mtd, NAND_CMD_RNDIN, offset + mtd->writesize, -1); - sunxi_nfc_write_buf(mtd, oob + offset, len); + sunxi_nfc_randomizer_write_buf(mtd, oob + offset, len, false, page); *cur_off = mtd->oobsize + mtd->writesize; } @@ -725,6 +945,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc = &chip->ecc; unsigned int max_bitflips = 0; int ret, i, cur_off = 0; + bool raw_mode = false; sunxi_nfc_hw_ecc_enable(mtd); @@ -736,13 +957,17 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob, oob_off + mtd->writesize, - &cur_off, &max_bitflips); - if (ret) + &cur_off, &max_bitflips, + !i, page); + if (ret < 0) return ret; + else if (ret) + raw_mode = true; } if (oob_required) - sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off); + sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off, + !raw_mode, page); sunxi_nfc_hw_ecc_disable(mtd); @@ -767,13 +992,14 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, oob, oob_off + mtd->writesize, - &cur_off); + &cur_off, !i, page); if (ret) return ret; } - if (oob_required) - sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi, &cur_off); + if (oob_required || (chip->options & NAND_NEED_SCRAMBLING)) + sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi, + &cur_off, page); sunxi_nfc_hw_ecc_disable(mtd); @@ -788,6 +1014,7 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc = &chip->ecc; unsigned int max_bitflips = 0; int ret, i, cur_off = 0; + bool raw_mode = false; sunxi_nfc_hw_ecc_enable(mtd); @@ -799,13 +1026,16 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd, ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob, oob_off, &cur_off, - &max_bitflips); - if (ret) + &max_bitflips, !i, page); + if (ret < 0) return ret; + else if (ret) + raw_mode = true; } if (oob_required) - sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off); + sunxi_nfc_hw_ecc_read_extra_oob(mtd, chip->oob_poi, &cur_off, + !raw_mode, page); sunxi_nfc_hw_ecc_disable(mtd); @@ -829,13 +1059,15 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd, const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4)); ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off, - oob, oob_off, &cur_off); + oob, oob_off, &cur_off, + false, page); if (ret) return ret; } - if (oob_required) - sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi, &cur_off); + if (oob_required || (chip->options & NAND_NEED_SCRAMBLING)) + sunxi_nfc_hw_ecc_write_extra_oob(mtd, chip->oob_poi, + &cur_off, page); sunxi_nfc_hw_ecc_disable(mtd); @@ -1345,6 +1577,9 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, if (nand->bbt_options & NAND_BBT_USE_FLASH) nand->bbt_options |= NAND_BBT_NO_OOB; + if (nand->options & NAND_NEED_SCRAMBLING) + nand->options |= NAND_NO_SUBPAGE_WRITE; + ret = sunxi_nand_chip_init_timings(chip, np); if (ret) { dev_err(dev, "could not configure chip timings: %d\n", ret); -- GitLab From 3e1dd9aa8228cdbbf604006b179efc9312001fb3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 11:33:40 -0500 Subject: [PATCH 0259/5324] orangefs: use DEFINE_MUTEX (and mutex_init() had been too late) Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-mod.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index cac52a9175db..7434fa036328 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -70,7 +70,7 @@ module_param(op_timeout_secs, int, 0); module_param(slot_timeout_secs, int, 0); /* synchronizes the request device file */ -struct mutex devreq_mutex; +DEFINE_MUTEX(devreq_mutex); /* * Blocks non-priority requests from being queued for servicing. This @@ -78,7 +78,7 @@ struct mutex devreq_mutex; * for now it's only being used to stall the op addition to the request * list */ -struct mutex request_mutex; +DEFINE_MUTEX(request_mutex); /* hash table for storing operations waiting for matching downcall */ struct list_head *htable_ops_in_progress; @@ -160,9 +160,6 @@ static int __init orangefs_init(void) goto cleanup_kiocb; } - mutex_init(&devreq_mutex); - mutex_init(&request_mutex); - htable_ops_in_progress = kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL); if (!htable_ops_in_progress) { -- GitLab From fb6d2526e92e56d3f41bfec45daf1ce09dd59e7b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 12:00:26 -0500 Subject: [PATCH 0260/5324] orangefs: generic_file_open() is pointless for character devices Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 5da5ef616b85..fb7f092f94ba 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -85,9 +85,8 @@ static int orangefs_devreq_open(struct inode *inode, struct file *file) mutex_lock(&devreq_mutex); if (open_access_count == 0) { - ret = generic_file_open(inode, file); - if (ret == 0) - open_access_count++; + open_access_count++; + ret = 0; } else { DUMP_DEVICE_ERROR(); } -- GitLab From 83595db05214eb49477b2ffb7d18ce4e7468c776 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 12:03:05 -0500 Subject: [PATCH 0261/5324] orangefs: ->poll() is only called between successful ->open() and ->release() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index fb7f092f94ba..4cecc7c4f760 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -966,14 +966,12 @@ static unsigned int orangefs_devreq_poll(struct file *file, { int poll_revent_mask = 0; - if (open_access_count == 1) { - poll_wait(file, &orangefs_request_list_waitq, poll_table); + poll_wait(file, &orangefs_request_list_waitq, poll_table); - spin_lock(&orangefs_request_list_lock); - if (!list_empty(&orangefs_request_list)) - poll_revent_mask |= POLL_IN; - spin_unlock(&orangefs_request_list_lock); - } + spin_lock(&orangefs_request_list_lock); + if (!list_empty(&orangefs_request_list)) + poll_revent_mask |= POLL_IN; + spin_unlock(&orangefs_request_list_lock); return poll_revent_mask; } -- GitLab From 8016387ce78b4c5147241b798cf6d1fa400e4944 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 12:05:47 -0500 Subject: [PATCH 0262/5324] orangefs: kill ioctl32 rudiments Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 4cecc7c4f760..456b5189f772 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -898,23 +898,6 @@ static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd, #endif /* CONFIG_COMPAT is in .config */ -/* - * The following two ioctl32 functions had been refactored into the above - * CONFIG_COMPAT ifdef, but that was an over simplification that was - * not noticed until we tried to compile on power pc... - */ -#if (defined(CONFIG_COMPAT) && !defined(HAVE_REGISTER_IOCTL32_CONVERSION)) || !defined(CONFIG_COMPAT) -static int orangefs_ioctl32_init(void) -{ - return 0; -} - -static void orangefs_ioctl32_cleanup(void) -{ - return; -} -#endif - /* the assigned character device major number */ static int orangefs_dev_major; @@ -924,13 +907,6 @@ static int orangefs_dev_major; */ int orangefs_dev_init(void) { - int ret; - - /* register the ioctl32 sub-system */ - ret = orangefs_ioctl32_init(); - if (ret < 0) - return ret; - /* register orangefs-req device */ orangefs_dev_major = register_chrdev(0, ORANGEFS_REQDEVICE_NAME, @@ -939,7 +915,6 @@ int orangefs_dev_init(void) gossip_debug(GOSSIP_DEV_DEBUG, "Failed to register /dev/%s (error %d)\n", ORANGEFS_REQDEVICE_NAME, orangefs_dev_major); - orangefs_ioctl32_cleanup(); return orangefs_dev_major; } @@ -957,8 +932,6 @@ void orangefs_dev_cleanup(void) gossip_debug(GOSSIP_DEV_DEBUG, "*** /dev/%s character device unregistered ***\n", ORANGEFS_REQDEVICE_NAME); - /* unregister the ioctl32 sub-system */ - orangefs_ioctl32_cleanup(); } static unsigned int orangefs_devreq_poll(struct file *file, -- GitLab From 90e54e36c95536a476db0fe01daa556d647aca2c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 12:07:49 -0500 Subject: [PATCH 0263/5324] orangefs: ->poll() doesn't need spinlock not just for list_empty()... Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 456b5189f772..b58fab2a9c26 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -941,10 +941,8 @@ static unsigned int orangefs_devreq_poll(struct file *file, poll_wait(file, &orangefs_request_list_waitq, poll_table); - spin_lock(&orangefs_request_list_lock); if (!list_empty(&orangefs_request_list)) poll_revent_mask |= POLL_IN; - spin_unlock(&orangefs_request_list_lock); return poll_revent_mask; } -- GitLab From fc916da52dde736605137c7d528e2cdec7f81bca Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 19 Jan 2016 12:26:13 -0500 Subject: [PATCH 0264/5324] orangefs: get rid of macros Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 41 -------------------------------- fs/orangefs/waitqueue.c | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 6dcc38a5f117..d9b5b512bd83 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -619,47 +619,6 @@ extern wait_queue_head_t orangefs_bufmap_init_waitq; /* * misc convenience macros */ -#define add_op_to_request_list(op) \ -do { \ - spin_lock(&orangefs_request_list_lock); \ - spin_lock(&op->lock); \ - set_op_state_waiting(op); \ - list_add_tail(&op->list, &orangefs_request_list); \ - spin_unlock(&orangefs_request_list_lock); \ - spin_unlock(&op->lock); \ - wake_up_interruptible(&orangefs_request_list_waitq); \ -} while (0) - -#define add_priority_op_to_request_list(op) \ - do { \ - spin_lock(&orangefs_request_list_lock); \ - spin_lock(&op->lock); \ - set_op_state_waiting(op); \ - \ - list_add(&op->list, &orangefs_request_list); \ - spin_unlock(&orangefs_request_list_lock); \ - spin_unlock(&op->lock); \ - wake_up_interruptible(&orangefs_request_list_waitq); \ -} while (0) - -#define remove_op_from_request_list(op) \ - do { \ - struct list_head *tmp = NULL; \ - struct list_head *tmp_safe = NULL; \ - struct orangefs_kernel_op_s *tmp_op = NULL; \ - \ - spin_lock(&orangefs_request_list_lock); \ - list_for_each_safe(tmp, tmp_safe, &orangefs_request_list) { \ - tmp_op = list_entry(tmp, \ - struct orangefs_kernel_op_s, \ - list); \ - if (tmp_op && (tmp_op == op)) { \ - list_del(&tmp_op->list); \ - break; \ - } \ - } \ - spin_unlock(&orangefs_request_list_lock); \ - } while (0) #define ORANGEFS_OP_INTERRUPTIBLE 1 /* service_operation() is interruptible */ #define ORANGEFS_OP_PRIORITY 2 /* service_operation() is high priority */ diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 751c3c640a52..4730baf686b2 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -41,6 +41,31 @@ void purge_waiting_ops(void) spin_unlock(&orangefs_request_list_lock); } +static inline void +add_op_to_request_list(struct orangefs_kernel_op_s *op) +{ + spin_lock(&orangefs_request_list_lock); + spin_lock(&op->lock); + set_op_state_waiting(op); + list_add_tail(&op->list, &orangefs_request_list); + spin_unlock(&orangefs_request_list_lock); + spin_unlock(&op->lock); + wake_up_interruptible(&orangefs_request_list_waitq); +} + +static inline +void add_priority_op_to_request_list(struct orangefs_kernel_op_s *op) +{ + spin_lock(&orangefs_request_list_lock); + spin_lock(&op->lock); + set_op_state_waiting(op); + + list_add(&op->list, &orangefs_request_list); + spin_unlock(&orangefs_request_list_lock); + spin_unlock(&op->lock); + wake_up_interruptible(&orangefs_request_list_waitq); +} + /* * submits a ORANGEFS operation and waits for it to complete * @@ -252,6 +277,25 @@ int service_operation(struct orangefs_kernel_op_s *op, return ret; } +static inline void remove_op_from_request_list(struct orangefs_kernel_op_s *op) +{ + struct list_head *tmp = NULL; + struct list_head *tmp_safe = NULL; + struct orangefs_kernel_op_s *tmp_op = NULL; + + spin_lock(&orangefs_request_list_lock); + list_for_each_safe(tmp, tmp_safe, &orangefs_request_list) { + tmp_op = list_entry(tmp, + struct orangefs_kernel_op_s, + list); + if (tmp_op && (tmp_op == op)) { + list_del(&tmp_op->list); + break; + } + } + spin_unlock(&orangefs_request_list_lock); +} + void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) { /* -- GitLab From 1264ddfdb7afda6f2c994ac30cad925fec346bae Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 21:55:47 -0500 Subject: [PATCH 0265/5324] orangefs: kill orangefs_inode_s ->list no users... Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index d9b5b512bd83..ab2b9b061996 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -270,9 +270,6 @@ struct orangefs_inode_s { * with this object */ unsigned long pinode_flags; - - /* All allocated orangefs_inode_s objects are chained to a list */ - struct list_head list; }; #define P_ATIME_FLAG 0 -- GitLab From e07db0a2c2e910d6619bfff962d73bd9c886c604 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 22:21:41 -0500 Subject: [PATCH 0266/5324] make orangefs_clean_up_interrupted_operation() static Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 1 - fs/orangefs/waitqueue.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index ab2b9b061996..d78f3852bc4d 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -476,7 +476,6 @@ void purge_inprogress_ops(void); */ int wait_for_matching_downcall(struct orangefs_kernel_op_s *op); int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op); -void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op); void purge_waiting_ops(void); /* diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 4730baf686b2..bc86f16c2037 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -296,7 +296,7 @@ static inline void remove_op_from_request_list(struct orangefs_kernel_op_s *op) spin_unlock(&orangefs_request_list_lock); } -void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) +static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) { /* * handle interrupted cases depending on what state we were in when -- GitLab From b7ae37b09e069a5d8d604caabd6675456a0d89fc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 22:58:58 -0500 Subject: [PATCH 0267/5324] orangefs: make wait_for_...downcall() static Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 2 -- fs/orangefs/waitqueue.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index d78f3852bc4d..825545a7d167 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -474,8 +474,6 @@ void purge_inprogress_ops(void); /* * defined in waitqueue.c */ -int wait_for_matching_downcall(struct orangefs_kernel_op_s *op); -int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op); void purge_waiting_ops(void); /* diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index bc86f16c2037..0b04f4197526 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -382,7 +382,7 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s * operation since client-core seems to be exiting too often * or if we were interrupted. */ -int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) +static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; DEFINE_WAIT(wait_entry); @@ -488,7 +488,7 @@ int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) * cancellation upcall anyway. the only way to exit this is to either * timeout or have the cancellation be serviced properly. */ -int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) +static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) { int ret = -EINVAL; DEFINE_WAIT(wait_entry); -- GitLab From 831d0949799be75ed84c1c6a4541ebcd74edba6c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 23:17:37 -0500 Subject: [PATCH 0268/5324] orangefs: move wakeups into set_op_state_{serviced,purged}() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 13 ++++--------- fs/orangefs/orangefs-kernel.h | 12 ++++++++++-- fs/orangefs/orangefs-mod.c | 1 - fs/orangefs/waitqueue.c | 1 - 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index b58fab2a9c26..dadeb381f9fc 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -415,8 +415,6 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, set_op_state_serviced(op); spin_unlock(&op->lock); - wake_up_interruptible(&op->waitq); - while (1) { spin_lock(&op->lock); prepare_to_wait_exclusive( @@ -464,17 +462,14 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, } else { /* * tell the vfs op waiting on a waitqueue that - * this op is done - */ - spin_lock(&op->lock); - set_op_state_serviced(op); - spin_unlock(&op->lock); - /* + * this op is done - * for every other operation (i.e. non-I/O), we need to * wake up the callers for downcall completion * notification */ - wake_up_interruptible(&op->waitq); + spin_lock(&op->lock); + set_op_state_serviced(op); + spin_unlock(&op->lock); } out: return ret; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 825545a7d167..160c4c6a4d17 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -105,8 +105,16 @@ enum orangefs_vfs_op_states { #define set_op_state_waiting(op) ((op)->op_state = OP_VFS_STATE_WAITING) #define set_op_state_inprogress(op) ((op)->op_state = OP_VFS_STATE_INPROGR) -#define set_op_state_serviced(op) ((op)->op_state = OP_VFS_STATE_SERVICED) -#define set_op_state_purged(op) ((op)->op_state |= OP_VFS_STATE_PURGED) +static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op) +{ + op->op_state = OP_VFS_STATE_SERVICED; + wake_up_interruptible(&op->waitq); +} +static inline void set_op_state_purged(struct orangefs_kernel_op_s *op) +{ + op->op_state |= OP_VFS_STATE_PURGED; + wake_up_interruptible(&op->waitq); +} #define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING) #define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR) diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index 7434fa036328..d0257f8b8cd3 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -303,7 +303,6 @@ void purge_inprogress_ops(void) get_opname_string(op)); set_op_state_purged(op); spin_unlock(&op->lock); - wake_up_interruptible(&op->waitq); } } } diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 0b04f4197526..641de05fa739 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -36,7 +36,6 @@ void purge_waiting_ops(void) spin_lock(&op->lock); set_op_state_purged(op); spin_unlock(&op->lock); - wake_up_interruptible(&op->waitq); } spin_unlock(&orangefs_request_list_lock); } -- GitLab From ade3d78104e08809569acef37dc905066d320726 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 22:58:58 -0500 Subject: [PATCH 0269/5324] orangefs: make wait_for_...downcall() static Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 641de05fa739..a257891dd3ea 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -16,6 +16,9 @@ #include "orangefs-kernel.h" #include "orangefs-bufmap.h" +static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *); +static int wait_for_matching_downcall(struct orangefs_kernel_op_s *); + /* * What we do in this function is to walk the list of operations that are * present in the request queue and mark them as purged. -- GitLab From 60831949cca782d54bd1f370fbadf17b772d6741 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 21 Jan 2016 23:17:37 -0500 Subject: [PATCH 0270/5324] orangefs: move wakeups into set_op_state_{serviced,purged}() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-kernel.h | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 160c4c6a4d17..4219b2f9a5ae 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -103,24 +103,6 @@ enum orangefs_vfs_op_states { OP_VFS_STATE_PURGED = 8, }; -#define set_op_state_waiting(op) ((op)->op_state = OP_VFS_STATE_WAITING) -#define set_op_state_inprogress(op) ((op)->op_state = OP_VFS_STATE_INPROGR) -static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op) -{ - op->op_state = OP_VFS_STATE_SERVICED; - wake_up_interruptible(&op->waitq); -} -static inline void set_op_state_purged(struct orangefs_kernel_op_s *op) -{ - op->op_state |= OP_VFS_STATE_PURGED; - wake_up_interruptible(&op->waitq); -} - -#define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING) -#define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR) -#define op_state_serviced(op) ((op)->op_state & OP_VFS_STATE_SERVICED) -#define op_state_purged(op) ((op)->op_state & OP_VFS_STATE_PURGED) - #define get_op(op) \ do { \ atomic_inc(&(op)->ref_count); \ @@ -259,6 +241,24 @@ struct orangefs_kernel_op_s { struct list_head list; }; +#define set_op_state_waiting(op) ((op)->op_state = OP_VFS_STATE_WAITING) +#define set_op_state_inprogress(op) ((op)->op_state = OP_VFS_STATE_INPROGR) +static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op) +{ + op->op_state = OP_VFS_STATE_SERVICED; + wake_up_interruptible(&op->waitq); +} +static inline void set_op_state_purged(struct orangefs_kernel_op_s *op) +{ + op->op_state |= OP_VFS_STATE_PURGED; + wake_up_interruptible(&op->waitq); +} + +#define op_state_waiting(op) ((op)->op_state & OP_VFS_STATE_WAITING) +#define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR) +#define op_state_serviced(op) ((op)->op_state & OP_VFS_STATE_SERVICED) +#define op_state_purged(op) ((op)->op_state & OP_VFS_STATE_PURGED) + /* per inode private orangefs info */ struct orangefs_inode_s { struct orangefs_object_kref refn; -- GitLab From 96acf9d65e70e0eb2716e3e46c45f4acb8256f1a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Jan 2016 13:34:32 -0500 Subject: [PATCH 0271/5324] orangefs: nothing should remain in request list and in hash ... otherwise some thread is running in .text that is about to be freed. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-mod.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index d0257f8b8cd3..bd9fbfe2ccee 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -236,8 +236,6 @@ static int __init orangefs_init(void) static void __exit orangefs_exit(void) { int i = 0; - struct orangefs_kernel_op_s *cur_op = NULL; - gossip_debug(GOSSIP_INIT_DEBUG, "orangefs: orangefs_exit called\n"); unregister_filesystem(&orangefs_fs_type); @@ -245,27 +243,9 @@ static void __exit orangefs_exit(void) orangefs_sysfs_exit(); fsid_key_table_finalize(); orangefs_dev_cleanup(); - /* clear out all pending upcall op requests */ - spin_lock(&orangefs_request_list_lock); - while (!list_empty(&orangefs_request_list)) { - cur_op = list_entry(orangefs_request_list.next, - struct orangefs_kernel_op_s, - list); - list_del(&cur_op->list); - gossip_debug(GOSSIP_INIT_DEBUG, - "Freeing unhandled upcall request type %d\n", - cur_op->upcall.type); - op_release(cur_op); - } - spin_unlock(&orangefs_request_list_lock); - + BUG_ON(!list_empty(&orangefs_request_list)); for (i = 0; i < hash_table_size; i++) - while (!list_empty(&htable_ops_in_progress[i])) { - cur_op = list_entry(htable_ops_in_progress[i].next, - struct orangefs_kernel_op_s, - list); - op_release(cur_op); - } + BUG_ON(!list_empty(&htable_ops_in_progress[i])); kiocb_cache_finalize(); orangefs_inode_cache_finalize(); -- GitLab From fee25ce12504ff071254fd213055c3f1d3004622 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Jan 2016 19:46:08 -0500 Subject: [PATCH 0272/5324] orangefs: make sure that reopening pvfs2-req won't overlap with the end of close Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index dadeb381f9fc..92573d9cc17c 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -85,7 +85,7 @@ static int orangefs_devreq_open(struct inode *inode, struct file *file) mutex_lock(&devreq_mutex); if (open_access_count == 0) { - open_access_count++; + open_access_count = 1; ret = 0; } else { DUMP_DEVICE_ERROR(); @@ -533,12 +533,11 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) if (orangefs_get_bufmap_init()) orangefs_bufmap_finalize(); - open_access_count--; + open_access_count = -1; unmounted = mark_all_pending_mounts(); gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n", (unmounted ? "UNMOUNTED" : "MOUNTED")); - mutex_unlock(&devreq_mutex); /* * Walk through the list of ops in the request list, mark them @@ -552,6 +551,8 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) purge_inprogress_ops(); gossip_debug(GOSSIP_DEV_DEBUG, "pvfs2-client-core: device close complete\n"); + open_access_count = 0; + mutex_unlock(&devreq_mutex); return 0; } -- GitLab From ed42fe059389daa35a2aa10ec832e9f8d0a9e59e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Jan 2016 19:47:47 -0500 Subject: [PATCH 0273/5324] orangefs: hopefully saner op refcounting and locking * create with refcount 1 * make op_release() decrement and free if zero (i.e. old put_op() has become that). * mark when submitter has given up waiting; from that point nobody else can move between the lists, change state, etc. * have daemon read/write_iter grab a reference when picking op and *always* give it up in the end * don't put into hash until we know it's been successfully passed to daemon * move op->lock _lower_ than htab_in_progress_lock (and make sure to take it in purge_inprogress_ops()) Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 112 ++++++++++++++++++---------------- fs/orangefs/file.c | 17 ++---- fs/orangefs/orangefs-cache.c | 5 +- fs/orangefs/orangefs-kernel.h | 46 +++++++------- fs/orangefs/orangefs-mod.c | 2 + fs/orangefs/orangefs-sysfs.c | 28 +++------ fs/orangefs/orangefs-utils.c | 16 ++--- fs/orangefs/waitqueue.c | 24 ++------ 8 files changed, 107 insertions(+), 143 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 92573d9cc17c..b7a6aa44ce3e 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -43,9 +43,7 @@ static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op) { int index = hash_func(op->tag, hash_table_size); - spin_lock(&htable_ops_in_progress_lock); list_add_tail(&op->list, &htable_ops_in_progress[index]); - spin_unlock(&htable_ops_in_progress_lock); } static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag) @@ -60,8 +58,9 @@ static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag) next, &htable_ops_in_progress[index], list) { - if (op->tag == tag) { - list_del(&op->list); + if (op->tag == tag && !op_state_purged(op)) { + list_del_init(&op->list); + get_op(op); /* increase ref count. */ spin_unlock(&htable_ops_in_progress_lock); return op; } @@ -127,12 +126,17 @@ static ssize_t orangefs_devreq_read(struct file *file, return -EINVAL; } +restart: /* Get next op (if any) from top of list. */ spin_lock(&orangefs_request_list_lock); list_for_each_entry_safe(op, temp, &orangefs_request_list, list) { __s32 fsid; /* This lock is held past the end of the loop when we break. */ spin_lock(&op->lock); + if (unlikely(op_state_purged(op))) { + spin_unlock(&op->lock); + continue; + } fsid = fsid_of_op(op); if (fsid != ORANGEFS_FS_ID_NULL) { @@ -197,16 +201,10 @@ static ssize_t orangefs_devreq_read(struct file *file, spin_unlock(&orangefs_request_list_lock); return -EAGAIN; } - - /* - * Set the operation to be in progress and move it between lists since - * it has been sent to the client. - */ - set_op_state_inprogress(cur_op); - - list_del(&cur_op->list); + list_del_init(&cur_op->list); + get_op(op); spin_unlock(&orangefs_request_list_lock); - orangefs_devreq_add_op(cur_op); + spin_unlock(&cur_op->lock); /* Push the upcall out. */ @@ -224,6 +222,25 @@ static ssize_t orangefs_devreq_read(struct file *file, if (ret != 0) goto error; + spin_lock(&htable_ops_in_progress_lock); + spin_lock(&cur_op->lock); + if (unlikely(op_state_given_up(cur_op))) { + spin_unlock(&cur_op->lock); + spin_unlock(&htable_ops_in_progress_lock); + op_release(cur_op); + goto restart; + } + + /* + * Set the operation to be in progress and move it between lists since + * it has been sent to the client. + */ + set_op_state_inprogress(cur_op); + orangefs_devreq_add_op(cur_op); + spin_unlock(&cur_op->lock); + spin_unlock(&htable_ops_in_progress_lock); + op_release(cur_op); + /* The client only asks to read one size buffer. */ return MAX_DEV_REQ_UPSIZE; error: @@ -235,11 +252,13 @@ static ssize_t orangefs_devreq_read(struct file *file, gossip_err("orangefs: Failed to copy data to user space\n"); spin_lock(&orangefs_request_list_lock); spin_lock(&cur_op->lock); - set_op_state_waiting(cur_op); - orangefs_devreq_remove_op(cur_op->tag); - list_add(&cur_op->list, &orangefs_request_list); + if (likely(!op_state_given_up(cur_op))) { + set_op_state_waiting(cur_op); + list_add(&cur_op->list, &orangefs_request_list); + } spin_unlock(&cur_op->lock); spin_unlock(&orangefs_request_list_lock); + op_release(cur_op); return -EFAULT; } @@ -278,15 +297,13 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, __func__, total, (unsigned int) MAX_DEV_REQ_DOWNSIZE); - ret = -EFAULT; - goto out; + return -EFAULT; } n = copy_from_iter(&head, head_size, iter); if (n < head_size) { gossip_err("%s: failed to copy head.\n", __func__); - ret = -EFAULT; - goto out; + return -EFAULT; } if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) { @@ -295,31 +312,26 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, __func__, head.version, ORANGEFS_MINIMUM_USERSPACE_VERSION); - ret = -EPROTO; - goto out; + return -EPROTO; } if (head.magic != ORANGEFS_DEVREQ_MAGIC) { gossip_err("Error: Device magic number does not match.\n"); - ret = -EPROTO; - goto out; + return -EPROTO; } op = orangefs_devreq_remove_op(head.tag); if (!op) { gossip_err("WARNING: No one's waiting for tag %llu\n", llu(head.tag)); - goto out; + return ret; } - get_op(op); /* increase ref count. */ - n = copy_from_iter(&op->downcall, downcall_size, iter); if (n != downcall_size) { gossip_err("%s: failed to copy downcall.\n", __func__); - put_op(op); ret = -EFAULT; - goto out; + goto Broken; } if (op->downcall.status) @@ -339,9 +351,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, downcall_size, op->downcall.trailer_size, total); - put_op(op); ret = -EFAULT; - goto out; + goto Broken; } /* Only READDIR operations should have trailers. */ @@ -350,9 +361,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, gossip_err("%s: %x operation with trailer.", __func__, op->downcall.type); - put_op(op); ret = -EFAULT; - goto out; + goto Broken; } /* READDIR operations should always have trailers. */ @@ -361,9 +371,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, gossip_err("%s: %x operation with no trailer.", __func__, op->downcall.type); - put_op(op); ret = -EFAULT; - goto out; + goto Broken; } if (op->downcall.type != ORANGEFS_VFS_OP_READDIR) @@ -374,9 +383,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, if (op->downcall.trailer_buf == NULL) { gossip_err("%s: failed trailer vmalloc.\n", __func__); - put_op(op); ret = -ENOMEM; - goto out; + goto Broken; } memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size); n = copy_from_iter(op->downcall.trailer_buf, @@ -385,9 +393,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, if (n != op->downcall.trailer_size) { gossip_err("%s: failed to copy trailer.\n", __func__); vfree(op->downcall.trailer_buf); - put_op(op); ret = -EFAULT; - goto out; + goto Broken; } wakeup: @@ -404,7 +411,6 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, * the buffers are done being used. */ if (op->downcall.type == ORANGEFS_VFS_OP_FILE_IO) { - int timed_out = 0; DEFINE_WAIT(wait_entry); /* @@ -412,7 +418,8 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, * that this op is done */ spin_lock(&op->lock); - set_op_state_serviced(op); + if (!op_state_given_up(op)) + set_op_state_serviced(op); spin_unlock(&op->lock); while (1) { @@ -435,7 +442,6 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, gossip_debug(GOSSIP_DEV_DEBUG, "%s: timed out.\n", __func__); - timed_out = 1; break; } continue; @@ -450,15 +456,6 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, spin_lock(&op->lock); finish_wait(&op->io_completion_waitq, &wait_entry); spin_unlock(&op->lock); - - /* NOTE: for I/O operations we handle releasing the op - * object except in the case of timeout. the reason we - * can't free the op in timeout cases is that the op - * service logic in the vfs retries operations using - * the same op ptr, thus it can't be freed. - */ - if (!timed_out) - op_release(op); } else { /* * tell the vfs op waiting on a waitqueue that @@ -468,11 +465,22 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, * notification */ spin_lock(&op->lock); - set_op_state_serviced(op); + if (!op_state_given_up(op)) + set_op_state_serviced(op); spin_unlock(&op->lock); } out: + op_release(op); return ret; + +Broken: + spin_lock(&op->lock); + if (!op_state_given_up(op)) { + op->downcall.status = ret; + set_op_state_serviced(op); + } + spin_unlock(&op->lock); + goto out; } /* Returns whether any FS are still pending remounted */ diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 171013ae0036..df3404ba60af 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -105,10 +105,9 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod ssize_t ret; new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO); - if (!new_op) { - ret = -ENOMEM; - goto out; - } + if (!new_op) + return -ENOMEM; + /* synchronous I/O */ new_op->upcall.req.io.async_vfs_io = ORANGEFS_VFS_SYNC_IO; new_op->upcall.req.io.readahead_size = readahead_size; @@ -234,12 +233,9 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod /* * tell the device file owner waiting on I/O that this read has - * completed and it can return now. in this exact case, on - * wakeup the daemon will free the op, so we *cannot* touch it - * after this. + * completed and it can return now. */ wake_up_daemon_for_return(new_op); - new_op = NULL; out: if (buffer_index >= 0) { @@ -249,10 +245,7 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod __func__, handle, buffer_index); buffer_index = -1; } - if (new_op) { - op_release(new_op); - new_op = NULL; - } + op_release(new_op); return ret; } diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index dd4335ff8c10..adc3ab013fdf 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -120,7 +120,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) init_waitqueue_head(&new_op->waitq); init_waitqueue_head(&new_op->io_completion_waitq); - atomic_set(&new_op->ref_count, 0); + atomic_set(&new_op->ref_count, 1); orangefs_op_initialize(new_op); @@ -149,14 +149,13 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) return new_op; } -void op_release(struct orangefs_kernel_op_s *orangefs_op) +void __op_release(struct orangefs_kernel_op_s *orangefs_op) { if (orangefs_op) { gossip_debug(GOSSIP_CACHE_DEBUG, "Releasing OP (%p: %llu)\n", orangefs_op, llu(orangefs_op->tag)); - orangefs_op_initialize(orangefs_op); kmem_cache_free(op_cache, orangefs_op); } else { gossip_err("NULL pointer in op_release\n"); diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 4219b2f9a5ae..f96ec3da6b00 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -94,6 +94,7 @@ sizeof(__u64) + sizeof(struct orangefs_downcall_s)) * serviced - op has matching downcall; ok * purged - op has to start a timer since client-core * exited uncleanly before servicing op + * given up - submitter has given up waiting for it */ enum orangefs_vfs_op_states { OP_VFS_STATE_UNKNOWN = 0, @@ -101,30 +102,9 @@ enum orangefs_vfs_op_states { OP_VFS_STATE_INPROGR = 2, OP_VFS_STATE_SERVICED = 4, OP_VFS_STATE_PURGED = 8, + OP_VFS_STATE_GIVEN_UP = 16, }; -#define get_op(op) \ - do { \ - atomic_inc(&(op)->ref_count); \ - gossip_debug(GOSSIP_DEV_DEBUG, \ - "(get) Alloced OP (%p:%llu)\n", \ - op, \ - llu((op)->tag)); \ - } while (0) - -#define put_op(op) \ - do { \ - if (atomic_sub_and_test(1, &(op)->ref_count) == 1) { \ - gossip_debug(GOSSIP_DEV_DEBUG, \ - "(put) Releasing OP (%p:%llu)\n", \ - op, \ - llu((op)->tag)); \ - op_release(op); \ - } \ - } while (0) - -#define op_wait(op) (atomic_read(&(op)->ref_count) <= 2 ? 0 : 1) - /* * Defines for controlling whether I/O upcalls are for async or sync operations */ @@ -258,6 +238,25 @@ static inline void set_op_state_purged(struct orangefs_kernel_op_s *op) #define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR) #define op_state_serviced(op) ((op)->op_state & OP_VFS_STATE_SERVICED) #define op_state_purged(op) ((op)->op_state & OP_VFS_STATE_PURGED) +#define op_state_given_up(op) ((op)->op_state & OP_VFS_STATE_GIVEN_UP) + +static inline void get_op(struct orangefs_kernel_op_s *op) +{ + atomic_inc(&op->ref_count); + gossip_debug(GOSSIP_DEV_DEBUG, + "(get) Alloced OP (%p:%llu)\n", op, llu(op->tag)); +} + +void __op_release(struct orangefs_kernel_op_s *op); + +static inline void op_release(struct orangefs_kernel_op_s *op) +{ + if (atomic_dec_and_test(&op->ref_count)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "(put) Releasing OP (%p:%llu)\n", op, llu((op)->tag)); + __op_release(op); + } +} /* per inode private orangefs info */ struct orangefs_inode_s { @@ -459,7 +458,6 @@ int op_cache_initialize(void); int op_cache_finalize(void); struct orangefs_kernel_op_s *op_alloc(__s32 type); char *get_opname_string(struct orangefs_kernel_op_s *new_op); -void op_release(struct orangefs_kernel_op_s *op); int dev_req_cache_initialize(void); int dev_req_cache_finalize(void); @@ -665,11 +663,9 @@ int service_operation(struct orangefs_kernel_op_s *op, do { \ if (!op_state_serviced(new_op)) { \ orangefs_cancel_op_in_progress(new_op->tag); \ - op_release(new_op); \ } else { \ wake_up_daemon_for_return(new_op); \ } \ - new_op = NULL; \ orangefs_bufmap_put(bufmap, buffer_index); \ buffer_index = -1; \ } while (0) diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index bd9fbfe2ccee..e07874e26372 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -271,6 +271,7 @@ void purge_inprogress_ops(void) struct orangefs_kernel_op_s *op; struct orangefs_kernel_op_s *next; + spin_lock(&htable_ops_in_progress_lock); list_for_each_entry_safe(op, next, &htable_ops_in_progress[i], @@ -284,6 +285,7 @@ void purge_inprogress_ops(void) set_op_state_purged(op); spin_unlock(&op->lock); } + spin_unlock(&htable_ops_in_progress_lock); } } diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c index 3d360383ea22..83f4053bd11b 100644 --- a/fs/orangefs/orangefs-sysfs.c +++ b/fs/orangefs/orangefs-sysfs.c @@ -773,10 +773,8 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT; new_op = op_alloc(op_alloc_type); - if (!new_op) { - rc = -ENOMEM; - goto out; - } + if (!new_op) + return -ENOMEM; /* Can't do a service_operation if the client is not running... */ rc = is_daemon_in_service(); @@ -931,11 +929,7 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) } } - /* - * if we got ENOMEM, then op_alloc probably failed... - */ - if (rc != -ENOMEM) - op_release(new_op); + op_release(new_op); return rc; @@ -1039,10 +1033,8 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) kobj_id); new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); - if (!new_op) { - rc = -ENOMEM; - goto out; - } + if (!new_op) + return -EINVAL; /* sic */ /* Can't do a service_operation if the client is not running... */ rc = is_daemon_in_service(); @@ -1269,15 +1261,9 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } out: - /* - * if we got ENOMEM, then op_alloc probably failed... - */ - if (rc == -ENOMEM) - rc = 0; - else - op_release(new_op); + op_release(new_op); - if (rc == 0) + if (rc == -ENOMEM || rc == 0) rc = -EINVAL; return rc; diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index f21233201ce3..a6117787ee8d 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -429,19 +429,15 @@ int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr) ret = copy_attributes_from_inode(inode, &new_op->upcall.req.setattr.attributes, iattr); - if (ret < 0) { - op_release(new_op); - return ret; - } - - ret = service_operation(new_op, __func__, + if (ret >= 0) { + ret = service_operation(new_op, __func__, get_interruptible_flag(inode)); - gossip_debug(GOSSIP_UTILS_DEBUG, - "orangefs_inode_setattr: returning %d\n", - ret); + gossip_debug(GOSSIP_UTILS_DEBUG, + "orangefs_inode_setattr: returning %d\n", + ret); + } - /* when request is serviced properly, free req op struct */ op_release(new_op); /* diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index a257891dd3ea..2e9468f57981 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -279,25 +279,6 @@ int service_operation(struct orangefs_kernel_op_s *op, return ret; } -static inline void remove_op_from_request_list(struct orangefs_kernel_op_s *op) -{ - struct list_head *tmp = NULL; - struct list_head *tmp_safe = NULL; - struct orangefs_kernel_op_s *tmp_op = NULL; - - spin_lock(&orangefs_request_list_lock); - list_for_each_safe(tmp, tmp_safe, &orangefs_request_list) { - tmp_op = list_entry(tmp, - struct orangefs_kernel_op_s, - list); - if (tmp_op && (tmp_op == op)) { - list_del(&tmp_op->list); - break; - } - } - spin_unlock(&orangefs_request_list_lock); -} - static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) { /* @@ -334,6 +315,7 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s } spin_lock(&op->lock); + op->op_state |= OP_VFS_STATE_GIVEN_UP; if (op_state_waiting(op)) { /* @@ -341,7 +323,9 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s * list. */ spin_unlock(&op->lock); - remove_op_from_request_list(op); + spin_lock(&orangefs_request_list_lock); + list_del(&op->list); + spin_unlock(&orangefs_request_list_lock); gossip_debug(GOSSIP_WAIT_DEBUG, "Interrupted: Removed op %p from request_list\n", op); -- GitLab From e1056a9cc35c878b6615d0fc84d3f338c89a38fa Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 12:26:56 -0500 Subject: [PATCH 0274/5324] orangefs: remove cargo-culting spin_lock_irqsave() in service_operation() Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 2e9468f57981..b8a2fcbcce64 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -86,9 +86,6 @@ int service_operation(struct orangefs_kernel_op_s *op, sigset_t orig_sigset; int ret = 0; - /* irqflags and wait_entry are only used IF the client-core aborts */ - unsigned long irqflags; - DEFINE_WAIT(wait_entry); op->upcall.tgid = current->tgid; @@ -230,11 +227,9 @@ int service_operation(struct orangefs_kernel_op_s *op, * let process sleep for a few seconds so shared * memory system can be initialized. */ - spin_lock_irqsave(&op->lock, irqflags); prepare_to_wait(&orangefs_bufmap_init_waitq, &wait_entry, TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&op->lock, irqflags); /* * Wait for orangefs_bufmap_initialize() to wake me up @@ -251,9 +246,7 @@ int service_operation(struct orangefs_kernel_op_s *op, "Is shared memory available? (%d).\n", orangefs_get_bufmap_init()); - spin_lock_irqsave(&op->lock, irqflags); finish_wait(&orangefs_bufmap_init_waitq, &wait_entry); - spin_unlock_irqrestore(&op->lock, irqflags); if (orangefs_get_bufmap_init() == 0) { gossip_err("%s:The shared memory system has not started in %d seconds after the client core restarted. Aborting user's request(%s).\n", -- GitLab From 70c6ea26ff2d2df420d573f8f0f22853336c0b56 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:04:19 -0500 Subject: [PATCH 0275/5324] orangefs: reduce nesting in wait_for_matching_downcall() reorder if branches... Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 118 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index b8a2fcbcce64..8c07a070e2b6 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -376,79 +376,77 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) } spin_unlock(&op->lock); - if (!signal_pending(current)) { - /* - * if this was our first attempt and client-core - * has not purged our operation, we are happy to - * simply wait - */ - spin_lock(&op->lock); - if (op->attempts == 0 && !op_state_purged(op)) { - spin_unlock(&op->lock); - schedule(); - } else { - spin_unlock(&op->lock); - /* - * subsequent attempts, we retry exactly once - * with timeouts - */ - if (!schedule_timeout(MSECS_TO_JIFFIES - (1000 * op_timeout_secs))) { - gossip_debug(GOSSIP_WAIT_DEBUG, - "*** %s:" - " operation timed out (tag" - " %llu, %p, att %d)\n", - __func__, - llu(op->tag), - op, - op->attempts); - ret = -ETIMEDOUT; - orangefs_clean_up_interrupted_operation - (op); - break; - } - } - spin_lock(&op->lock); - op->attempts++; + if (unlikely(signal_pending(current))) { + gossip_debug(GOSSIP_WAIT_DEBUG, + "*** %s:" + " operation interrupted by a signal (tag " + "%llu, op %p)\n", + __func__, + llu(op->tag), + op); + orangefs_clean_up_interrupted_operation(op); + ret = -EINTR; + break; + } + + /* + * if this was our first attempt and client-core + * has not purged our operation, we are happy to + * simply wait + */ + spin_lock(&op->lock); + if (op->attempts == 0 && !op_state_purged(op)) { + spin_unlock(&op->lock); + schedule(); + } else { + spin_unlock(&op->lock); /* - * if the operation was purged in the meantime, it - * is better to requeue it afresh but ensure that - * we have not been purged repeatedly. This could - * happen if client-core crashes when an op - * is being serviced, so we requeue the op, client - * core crashes again so we requeue the op, client - * core starts, and so on... + * subsequent attempts, we retry exactly once + * with timeouts */ - if (op_state_purged(op)) { - ret = (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ? - -EAGAIN : - -EIO; - spin_unlock(&op->lock); + if (!schedule_timeout(MSECS_TO_JIFFIES + (1000 * op_timeout_secs))) { gossip_debug(GOSSIP_WAIT_DEBUG, "*** %s:" - " operation purged (tag " - "%llu, %p, att %d)\n", + " operation timed out (tag" + " %llu, %p, att %d)\n", __func__, llu(op->tag), op, op->attempts); + ret = -ETIMEDOUT; orangefs_clean_up_interrupted_operation(op); break; } + } + spin_lock(&op->lock); + op->attempts++; + /* + * if the operation was purged in the meantime, it + * is better to requeue it afresh but ensure that + * we have not been purged repeatedly. This could + * happen if client-core crashes when an op + * is being serviced, so we requeue the op, client + * core crashes again so we requeue the op, client + * core starts, and so on... + */ + if (op_state_purged(op)) { + ret = (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ? + -EAGAIN : + -EIO; spin_unlock(&op->lock); - continue; + gossip_debug(GOSSIP_WAIT_DEBUG, + "*** %s:" + " operation purged (tag " + "%llu, %p, att %d)\n", + __func__, + llu(op->tag), + op, + op->attempts); + orangefs_clean_up_interrupted_operation(op); + break; } - - gossip_debug(GOSSIP_WAIT_DEBUG, - "*** %s:" - " operation interrupted by a signal (tag " - "%llu, op %p)\n", - __func__, - llu(op->tag), - op); - orangefs_clean_up_interrupted_operation(op); - ret = -EINTR; - break; + spin_unlock(&op->lock); } spin_lock(&op->lock); -- GitLab From eab9b38939fae1b7731570478718a5d1b2f28ea9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:09:05 -0500 Subject: [PATCH 0276/5324] orangefs_clean_up_interrupted_operation: call with op->lock held Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 8c07a070e2b6..699ffd8b2a51 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -279,35 +279,8 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s * the interruption is detected. there is a coarse grained lock * across the operation. * - * NOTE: be sure not to reverse lock ordering by locking an op lock - * while holding the request_list lock. Here, we first lock the op - * and then lock the appropriate list. + * Called with op->lock held. */ - if (!op) { - gossip_debug(GOSSIP_WAIT_DEBUG, - "%s: op is null, ignoring\n", - __func__); - return; - } - - /* - * one more sanity check, make sure it's in one of the possible states - * or don't try to cancel it - */ - if (!(op_state_waiting(op) || - op_state_in_progress(op) || - op_state_serviced(op) || - op_state_purged(op))) { - gossip_debug(GOSSIP_WAIT_DEBUG, - "%s: op %p not in a valid state (%0x), " - "ignoring\n", - __func__, - op, - op->op_state); - return; - } - - spin_lock(&op->lock); op->op_state |= OP_VFS_STATE_GIVEN_UP; if (op_state_waiting(op)) { @@ -374,7 +347,6 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) ret = 0; break; } - spin_unlock(&op->lock); if (unlikely(signal_pending(current))) { gossip_debug(GOSSIP_WAIT_DEBUG, @@ -394,7 +366,6 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) * has not purged our operation, we are happy to * simply wait */ - spin_lock(&op->lock); if (op->attempts == 0 && !op_state_purged(op)) { spin_unlock(&op->lock); schedule(); @@ -415,6 +386,7 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) op, op->attempts); ret = -ETIMEDOUT; + spin_lock(&op->lock); orangefs_clean_up_interrupted_operation(op); break; } @@ -434,7 +406,6 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) ret = (op->attempts < ORANGEFS_PURGE_RETRY_COUNT) ? -EAGAIN : -EIO; - spin_unlock(&op->lock); gossip_debug(GOSSIP_WAIT_DEBUG, "*** %s:" " operation purged (tag " @@ -481,7 +452,6 @@ static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) ret = 0; break; } - spin_unlock(&op->lock); if (signal_pending(current)) { gossip_debug(GOSSIP_WAIT_DEBUG, @@ -498,6 +468,7 @@ static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) gossip_debug(GOSSIP_WAIT_DEBUG, "%s:About to call schedule_timeout.\n", __func__); + spin_unlock(&op->lock); ret = schedule_timeout(MSECS_TO_JIFFIES(1000 * op_timeout_secs)); @@ -510,6 +481,7 @@ static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) "%s:*** operation timed out: %p\n", __func__, op); + spin_lock(&op->lock); orangefs_clean_up_interrupted_operation(op); ret = -ETIMEDOUT; break; -- GitLab From 727cbfea623b78d46ce8e0f8c931b5189f3fe2e0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:17:55 -0500 Subject: [PATCH 0277/5324] orangefs: get rid of MSECS_TO_JIFFIES All timeouts are in _seconds_, so all calls are of form MSECS_TO_JIFFIES(n * 1000), which is a convoluted way to spell n * HZ. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 4 +--- fs/orangefs/orangefs-bufmap.c | 4 +--- fs/orangefs/orangefs-kernel.h | 5 ----- fs/orangefs/waitqueue.c | 10 ++++------ 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index b7a6aa44ce3e..d8c436a0aa1b 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -435,9 +435,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, spin_unlock(&op->lock); if (!signal_pending(current)) { - int timeout = - MSECS_TO_JIFFIES(1000 * - op_timeout_secs); + int timeout = op_timeout_secs * HZ; if (!schedule_timeout(timeout)) { gossip_debug(GOSSIP_DEV_DEBUG, "%s: timed out.\n", diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index 15baecb8094d..c60019de1fd8 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -377,13 +377,11 @@ static int wait_for_a_slot(struct slot_args *slargs, int *buffer_index) break; if (!signal_pending(current)) { - int timeout = - MSECS_TO_JIFFIES(1000 * slot_timeout_secs); gossip_debug(GOSSIP_BUFMAP_DEBUG, "[BUFMAP]: waiting %d " "seconds for a slot\n", slot_timeout_secs); - if (!schedule_timeout(timeout)) { + if (!schedule_timeout(slot_timeout_secs * HZ)) { gossip_debug(GOSSIP_BUFMAP_DEBUG, "*** wait_for_a_slot timed out\n"); ret = -ETIMEDOUT; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index f96ec3da6b00..2b72806d0f68 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -80,11 +80,6 @@ sizeof(__u64) + sizeof(struct orangefs_upcall_s)) #define MAX_DEV_REQ_DOWNSIZE (2 * sizeof(__s32) + \ sizeof(__u64) + sizeof(struct orangefs_downcall_s)) -/* borrowed from irda.h */ -#ifndef MSECS_TO_JIFFIES -#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000) -#endif - /* * valid orangefs kernel operation states * diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index 699ffd8b2a51..cdbf57bef3eb 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -235,8 +235,8 @@ int service_operation(struct orangefs_kernel_op_s *op, * Wait for orangefs_bufmap_initialize() to wake me up * within the allotted time. */ - ret = schedule_timeout(MSECS_TO_JIFFIES - (1000 * ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS)); + ret = schedule_timeout( + ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS * HZ); gossip_debug(GOSSIP_WAIT_DEBUG, "Value returned from schedule_timeout:" @@ -375,8 +375,7 @@ static int wait_for_matching_downcall(struct orangefs_kernel_op_s *op) * subsequent attempts, we retry exactly once * with timeouts */ - if (!schedule_timeout(MSECS_TO_JIFFIES - (1000 * op_timeout_secs))) { + if (!schedule_timeout(op_timeout_secs * HZ)) { gossip_debug(GOSSIP_WAIT_DEBUG, "*** %s:" " operation timed out (tag" @@ -469,8 +468,7 @@ static int wait_for_cancellation_downcall(struct orangefs_kernel_op_s *op) "%s:About to call schedule_timeout.\n", __func__); spin_unlock(&op->lock); - ret = - schedule_timeout(MSECS_TO_JIFFIES(1000 * op_timeout_secs)); + ret = schedule_timeout(op_timeout_secs * HZ); gossip_debug(GOSSIP_WAIT_DEBUG, "%s:Value returned from schedule_timeout(%d).\n", -- GitLab From 4f55e39732ad0bd05d70c88e174e747d55e3685c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:27:50 -0500 Subject: [PATCH 0278/5324] if ORANGEFS_VFS_OP_FILE_IO request had been given up, don't bother waiting ... we are not going to get woken up anyway, so it's just going to time out and whine. Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index d8c436a0aa1b..3879f2b7cf29 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -418,8 +418,11 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, * that this op is done */ spin_lock(&op->lock); - if (!op_state_given_up(op)) - set_op_state_serviced(op); + if (unlikely(op_state_given_up(op))) { + spin_unlock(&op->lock); + goto out; + } + set_op_state_serviced(op); spin_unlock(&op->lock); while (1) { @@ -433,22 +436,19 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, break; } spin_unlock(&op->lock); - - if (!signal_pending(current)) { - int timeout = op_timeout_secs * HZ; - if (!schedule_timeout(timeout)) { - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: timed out.\n", - __func__); - break; - } - continue; + if (unlikely(signal_pending(current))) { + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: signal on I/O wait, aborting\n", + __func__); + break; } - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: signal on I/O wait, aborting\n", - __func__); - break; + if (!schedule_timeout(op_timeout_secs * HZ)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: timed out.\n", + __func__); + break; + } } spin_lock(&op->lock); -- GitLab From 2a9e5c22605f5db6040535b10dce5fbc3a7db3bd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:45:46 -0500 Subject: [PATCH 0279/5324] orangefs: don't reinvent completion.h... Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 75 ++++++++++------------------------- fs/orangefs/file.c | 5 +-- fs/orangefs/orangefs-cache.c | 1 - fs/orangefs/orangefs-kernel.h | 3 +- fs/orangefs/orangefs-utils.c | 2 +- 5 files changed, 24 insertions(+), 62 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 3879f2b7cf29..812844faa7f5 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -398,6 +398,17 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, } wakeup: + /* + * tell the vfs op waiting on a waitqueue + * that this op is done + */ + spin_lock(&op->lock); + if (unlikely(op_state_given_up(op))) { + spin_unlock(&op->lock); + goto out; + } + set_op_state_serviced(op); + spin_unlock(&op->lock); /* * If this operation is an I/O operation we need to wait @@ -411,61 +422,17 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, * the buffers are done being used. */ if (op->downcall.type == ORANGEFS_VFS_OP_FILE_IO) { - DEFINE_WAIT(wait_entry); - - /* - * tell the vfs op waiting on a waitqueue - * that this op is done - */ - spin_lock(&op->lock); - if (unlikely(op_state_given_up(op))) { - spin_unlock(&op->lock); - goto out; - } - set_op_state_serviced(op); - spin_unlock(&op->lock); - - while (1) { - spin_lock(&op->lock); - prepare_to_wait_exclusive( - &op->io_completion_waitq, - &wait_entry, - TASK_INTERRUPTIBLE); - if (op->io_completed) { - spin_unlock(&op->lock); - break; - } - spin_unlock(&op->lock); - if (unlikely(signal_pending(current))) { - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: signal on I/O wait, aborting\n", - __func__); - break; - } - - if (!schedule_timeout(op_timeout_secs * HZ)) { - gossip_debug(GOSSIP_DEV_DEBUG, - "%s: timed out.\n", - __func__); - break; - } + long n = wait_for_completion_interruptible_timeout(&op->done, + op_timeout_secs * HZ); + if (unlikely(n < 0)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: signal on I/O wait, aborting\n", + __func__); + } else if (unlikely(n == 0)) { + gossip_debug(GOSSIP_DEV_DEBUG, + "%s: timed out.\n", + __func__); } - - spin_lock(&op->lock); - finish_wait(&op->io_completion_waitq, &wait_entry); - spin_unlock(&op->lock); - } else { - /* - * tell the vfs op waiting on a waitqueue that - * this op is done - - * for every other operation (i.e. non-I/O), we need to - * wake up the callers for downcall completion - * notification - */ - spin_lock(&op->lock); - if (!op_state_given_up(op)) - set_op_state_serviced(op); - spin_unlock(&op->lock); } out: op_release(op); diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index df3404ba60af..7af0adba29aa 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -16,10 +16,7 @@ #define wake_up_daemon_for_return(op) \ do { \ - spin_lock(&op->lock); \ - op->io_completed = 1; \ - spin_unlock(&op->lock); \ - wake_up_interruptible(&op->io_completion_waitq);\ + complete(&op->done); \ } while (0) /* diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index adc3ab013fdf..90c11a0daf74 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -119,7 +119,6 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) spin_lock_init(&new_op->lock); init_waitqueue_head(&new_op->waitq); - init_waitqueue_head(&new_op->io_completion_waitq); atomic_set(&new_op->ref_count, 1); orangefs_op_initialize(new_op); diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 2b72806d0f68..58e523c23637 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -201,8 +201,7 @@ struct orangefs_kernel_op_s { wait_queue_head_t waitq; spinlock_t lock; - int io_completed; - wait_queue_head_t io_completion_waitq; + struct completion done; atomic_t ref_count; diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index a6117787ee8d..ca7edcfae873 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -597,7 +597,7 @@ void orangefs_op_initialize(struct orangefs_kernel_op_s *op) { if (op) { spin_lock(&op->lock); - op->io_completed = 0; + init_completion(&op->done); op->upcall.type = ORANGEFS_VFS_OP_INVALID; op->downcall.type = ORANGEFS_VFS_OP_INVALID; -- GitLab From b0bc3a7b621cb8d7bcce507f323249a7340f4141 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 13:50:37 -0500 Subject: [PATCH 0280/5324] orangefs: move handle_io_error() to file.c Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 47 ++++++++++++++++++++++++++++++----- fs/orangefs/orangefs-kernel.h | 40 ----------------------------- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 7af0adba29aa..c585063d1100 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -14,11 +14,6 @@ #include #include -#define wake_up_daemon_for_return(op) \ -do { \ - complete(&op->done); \ -} while (0) - /* * Copy to client-core's address space from the buffers specified * by the iovec upto total_size bytes. @@ -87,6 +82,46 @@ static int postcopy_buffers(struct orangefs_bufmap *bufmap, return ret; } +/* + * handles two possible error cases, depending on context. + * + * by design, our vfs i/o errors need to be handled in one of two ways, + * depending on where the error occured. + * + * if the error happens in the waitqueue code because we either timed + * out or a signal was raised while waiting, we need to cancel the + * userspace i/o operation and free the op manually. this is done to + * avoid having the device start writing application data to our shared + * bufmap pages without us expecting it. + * + * FIXME: POSSIBLE OPTIMIZATION: + * However, if we timed out or if we got a signal AND our upcall was never + * picked off the queue (i.e. we were in OP_VFS_STATE_WAITING), then we don't + * need to send a cancellation upcall. The way we can handle this is + * set error_exit to 2 in such cases and 1 whenever cancellation has to be + * sent and have handle_error + * take care of this situation as well.. + * + * if a orangefs sysint level error occured and i/o has been completed, + * there is no need to cancel the operation, as the user has finished + * using the bufmap page and so there is no danger in this case. in + * this case, we wake up the device normally so that it may free the + * op, as normal. + * + * note the only reason this is a macro is because both read and write + * cases need the exact same handling code. + */ +#define handle_io_error() \ +do { \ + if (!op_state_serviced(new_op)) { \ + orangefs_cancel_op_in_progress(new_op->tag); \ + } else { \ + complete(&new_op->done); \ + } \ + orangefs_bufmap_put(bufmap, buffer_index); \ + buffer_index = -1; \ +} while (0) + /* * Post and wait for the I/O upcall to finish */ @@ -232,7 +267,7 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod * tell the device file owner waiting on I/O that this read has * completed and it can return now. */ - wake_up_daemon_for_return(new_op); + complete(&new_op->done); out: if (buffer_index >= 0) { diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 58e523c23637..e11fc67d7773 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -624,46 +624,6 @@ int service_operation(struct orangefs_kernel_op_s *op, const char *op_name, int flags); -/* - * handles two possible error cases, depending on context. - * - * by design, our vfs i/o errors need to be handled in one of two ways, - * depending on where the error occured. - * - * if the error happens in the waitqueue code because we either timed - * out or a signal was raised while waiting, we need to cancel the - * userspace i/o operation and free the op manually. this is done to - * avoid having the device start writing application data to our shared - * bufmap pages without us expecting it. - * - * FIXME: POSSIBLE OPTIMIZATION: - * However, if we timed out or if we got a signal AND our upcall was never - * picked off the queue (i.e. we were in OP_VFS_STATE_WAITING), then we don't - * need to send a cancellation upcall. The way we can handle this is - * set error_exit to 2 in such cases and 1 whenever cancellation has to be - * sent and have handle_error - * take care of this situation as well.. - * - * if a orangefs sysint level error occured and i/o has been completed, - * there is no need to cancel the operation, as the user has finished - * using the bufmap page and so there is no danger in this case. in - * this case, we wake up the device normally so that it may free the - * op, as normal. - * - * note the only reason this is a macro is because both read and write - * cases need the exact same handling code. - */ -#define handle_io_error() \ -do { \ - if (!op_state_serviced(new_op)) { \ - orangefs_cancel_op_in_progress(new_op->tag); \ - } else { \ - wake_up_daemon_for_return(new_op); \ - } \ - orangefs_bufmap_put(bufmap, buffer_index); \ - buffer_index = -1; \ -} while (0) - #define get_interruptible_flag(inode) \ ((ORANGEFS_SB(inode->i_sb)->flags & ORANGEFS_OPT_INTR) ? \ ORANGEFS_OP_INTERRUPTIBLE : 0) -- GitLab From 115b93a8595c878759c7c1fdbd95fbbeacbe9168 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Jan 2016 14:04:31 -0500 Subject: [PATCH 0281/5324] orangefs: clean up op_alloc() fold orangefs_op_initialize() in there, don't bother locking something nobody else could've seen yet, use kmem_cache_zalloc() instead of explicit memset()... Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-cache.c | 13 +++++++++---- fs/orangefs/orangefs-kernel.h | 2 -- fs/orangefs/orangefs-utils.c | 16 ---------------- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index 90c11a0daf74..e72ac2083ac0 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -111,17 +111,22 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) { struct orangefs_kernel_op_s *new_op = NULL; - new_op = kmem_cache_alloc(op_cache, ORANGEFS_CACHE_ALLOC_FLAGS); + new_op = kmem_cache_zalloc(op_cache, ORANGEFS_CACHE_ALLOC_FLAGS); if (new_op) { - memset(new_op, 0, sizeof(struct orangefs_kernel_op_s)); - INIT_LIST_HEAD(&new_op->list); spin_lock_init(&new_op->lock); init_waitqueue_head(&new_op->waitq); atomic_set(&new_op->ref_count, 1); - orangefs_op_initialize(new_op); + init_completion(&new_op->done); + + new_op->upcall.type = ORANGEFS_VFS_OP_INVALID; + new_op->downcall.type = ORANGEFS_VFS_OP_INVALID; + new_op->downcall.status = -1; + + new_op->op_state = OP_VFS_STATE_UNKNOWN; + new_op->tag = 0; /* initialize the op specific tag and upcall credentials */ spin_lock(&next_tag_value_lock); diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index e11fc67d7773..9c876762f825 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -565,8 +565,6 @@ int orangefs_inode_getattr(struct inode *inode, __u32 mask); int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr); -void orangefs_op_initialize(struct orangefs_kernel_op_s *op); - void orangefs_make_bad_inode(struct inode *inode); void orangefs_block_signals(sigset_t *); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index ca7edcfae873..92a38b0091f2 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -593,22 +593,6 @@ int orangefs_cancel_op_in_progress(__u64 tag) return ret; } -void orangefs_op_initialize(struct orangefs_kernel_op_s *op) -{ - if (op) { - spin_lock(&op->lock); - init_completion(&op->done); - - op->upcall.type = ORANGEFS_VFS_OP_INVALID; - op->downcall.type = ORANGEFS_VFS_OP_INVALID; - op->downcall.status = -1; - - op->op_state = OP_VFS_STATE_UNKNOWN; - op->tag = 0; - spin_unlock(&op->lock); - } -} - void orangefs_make_bad_inode(struct inode *inode) { if (is_root_handle(inode)) { -- GitLab From 12197bf21c26e23053fa6223f3a731a965542986 Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Wed, 13 Jan 2016 17:34:13 +0100 Subject: [PATCH 0282/5324] mtd: atmel_nand: Do not warn on bitflips When using multi-bit ECC, it is normal for the NAND Flash driver to correct bit errors during the life of the product. Those errors will only be cleared once a threshold has been reached, and corrections can occur regularly before this. Use only dev_dbg and not dev_info to report the bitflips, to keep the system log clean when everything works correctly. Signed-off-by: Romain Izard Acked-by: Wenyou Yang Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index bddcf83d6859..0ae6cba5bef5 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -825,7 +825,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, *(buf + byte_pos) ^= (1 << bit_pos); pos = sector_num * host->pmecc_sector_size + byte_pos; - dev_info(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", + dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", pos, bit_pos, err_byte, *(buf + byte_pos)); } else { /* Bit flip in OOB area */ @@ -835,7 +835,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, ecc[tmp] ^= (1 << bit_pos); pos = tmp + nand_chip->ecc.layout->eccpos[0]; - dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", + dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", pos, bit_pos, err_byte, ecc[tmp]); } -- GitLab From 46c135c208a3a80bd7f12dee0032bbc6d507a0d9 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 22 Jan 2016 18:57:13 -0800 Subject: [PATCH 0283/5324] mtd: nand: sunxi: use mtd_div_by_ws() helper Suggested-by: Richard Weinberger Signed-off-by: Brian Norris Acked-by: Boris Brezillon --- drivers/mtd/nand/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 5f700719d5c2..b5ea6b312df0 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -624,7 +624,7 @@ static u16 sunxi_nfc_randomizer_step(u16 state, int count) static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc) { const u16 *seeds = sunxi_nfc_randomizer_page_seeds; - int mod = mtd->erasesize / mtd->writesize; + int mod = mtd_div_by_ws(mtd->erasesize, mtd); if (mod > ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds)) mod = ARRAY_SIZE(sunxi_nfc_randomizer_page_seeds); -- GitLab From 54ca3cd594db58d65b3670f2af452c1104b09ac6 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 14 Jan 2016 15:44:49 +0100 Subject: [PATCH 0284/5324] mtd: nand: remove EXPORT_SYMBOL of nand_scan_bbt() Since commit 17799359e7b3fa6ef4f2bf926cd6821cf7903ecf ("mtd: nand_bbt: make nand_scan_bbt() static"), the nand_scan_bbt() function is marked as static but is still exported using EXPORT_SYMBOL(), which doesn't make much sense. This commit gets rid of the useless EXPORT_SYMBOL. Signed-off-by: Thomas Petazzoni Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_bbt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 4b6a7085b442..2fbb523df066 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1373,5 +1373,3 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) return ret; } - -EXPORT_SYMBOL(nand_scan_bbt); -- GitLab From fd2a2f20c7a8173acd4858e5178eb40fd7c025b9 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 14 Jan 2016 15:44:50 +0100 Subject: [PATCH 0285/5324] mtd: onenand: make onenand_scan_bbt() static Like was done in commit 17799359e7b3fa6ef4f2bf926cd6821cf7903ecf ("mtd: nand_bbt: make nand_scan_bbt() static") for the NAND code, this commit makes the onenand_scan_bbt() function static in the OneNAND code, since it is only used in onenand_bbt.c itself. Consequently, the EXPORT_SYMBOL() and declaration in bbm.h are also removed. Signed-off-by: Thomas Petazzoni Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/onenand/onenand_bbt.c | 3 +-- include/linux/mtd/bbm.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 08d0085f3e93..5f8d47073c97 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -179,7 +179,7 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) * by the onenand_release function. * */ -int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) +static int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct onenand_chip *this = mtd->priv; struct bbm_info *bbm = this->bbm; @@ -248,5 +248,4 @@ int onenand_default_bbt(struct mtd_info *mtd) return onenand_scan_bbt(mtd, bbm->badblock_pattern); } -EXPORT_SYMBOL(onenand_scan_bbt); EXPORT_SYMBOL(onenand_default_bbt); diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 36bb6a503f19..3bf8f954b642 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -166,7 +166,6 @@ struct bbm_info { }; /* OneNAND BBT interface */ -extern int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); extern int onenand_default_bbt(struct mtd_info *mtd); #endif /* __LINUX_MTD_BBM_H */ -- GitLab From d652436102b1580d8d968a2047decbb737cc4e6d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 14 Jan 2016 15:44:51 +0100 Subject: [PATCH 0286/5324] mtd: onenand: unexport onenand_default_bbt() The onenand_default_bbt() function is only used by the OneNAND core and not by drivers, so there is no real need to export it. Additionally, the corresponding nand_default_bbt() for regular NANDs is not exported either, so for consistency reasons, this commit removes the EXPORT_SYMBOL on onenand_default_bbt(). Signed-off-by: Thomas Petazzoni Reviewed-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/onenand/onenand_bbt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 5f8d47073c97..680188a88130 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -247,5 +247,3 @@ int onenand_default_bbt(struct mtd_info *mtd) return onenand_scan_bbt(mtd, bbm->badblock_pattern); } - -EXPORT_SYMBOL(onenand_default_bbt); -- GitLab From 2a36a5c30eab9cd1c9d2d08bd27cd763325d70c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 5 Dec 2015 02:09:43 +0100 Subject: [PATCH 0287/5324] mtd: bcm47xxpart: limit scanned flash area on BCM47XX (MIPS) only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We allowed using bcm47xxpart on BCM5301X arch with commit: 9e3afa5f5c7 ("mtd: bcm47xxpart: allow enabling on ARCH_BCM_5301X") BCM5301X devices may contain some partitions in higher memory, e.g. Netgear R8000 has board_data at 0x2600000. To detect them we should use size limit on MIPS only. Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- drivers/mtd/bcm47xxpart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 8282f47bcf5d..b06d4c4553ed 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -118,8 +118,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, /* Parse block by block looking for magics */ for (offset = 0; offset <= master->size - blocksize; offset += blocksize) { - /* Nothing more in higher memory */ - if (offset >= 0x2000000) + /* Nothing more in higher memory on BCM47XX (MIPS) */ + if (config_enabled(CONFIG_BCM47XX) && offset >= 0x2000000) break; if (curr_part >= BCM47XXPART_MAX_PARTS) { -- GitLab From 36bcc0c9c2bc8f56569cd735ba531a51358d7c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 6 Dec 2015 11:31:38 +0100 Subject: [PATCH 0288/5324] mtd: bcm47xxpart: don't fail because of bit-flips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bit-flip errors may occur on NAND flashes and are harmless. Handle them gracefully as read content is still reliable and can be parsed. Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- drivers/mtd/bcm47xxpart.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index b06d4c4553ed..845dd27d9f41 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -66,11 +66,13 @@ static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, { uint32_t buf; size_t bytes_read; + int err; - if (mtd_read(master, offset, sizeof(buf), &bytes_read, - (uint8_t *)&buf) < 0) { - pr_err("mtd_read error while parsing (offset: 0x%X)!\n", - offset); + err = mtd_read(master, offset, sizeof(buf), &bytes_read, + (uint8_t *)&buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", + offset, err); goto out_default; } @@ -95,6 +97,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, int trx_part = -1; int last_trx_part = -1; int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int err; /* * Some really old flashes (like AT45DB*) had smaller erasesize-s, but @@ -128,10 +131,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, } /* Read beginning of the block */ - if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, - &bytes_read, (uint8_t *)buf) < 0) { - pr_err("mtd_read error while parsing (offset: 0x%X)!\n", - offset); + err = mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, + &bytes_read, (uint8_t *)buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", + offset, err); continue; } @@ -254,10 +258,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, } /* Read middle of the block */ - if (mtd_read(master, offset + 0x8000, 0x4, - &bytes_read, (uint8_t *)buf) < 0) { - pr_err("mtd_read error while parsing (offset: 0x%X)!\n", - offset); + err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read, + (uint8_t *)buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", + offset, err); continue; } @@ -277,10 +282,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, } offset = master->size - possible_nvram_sizes[i]; - if (mtd_read(master, offset, 0x4, &bytes_read, - (uint8_t *)buf) < 0) { - pr_err("mtd_read error while reading at offset 0x%X!\n", - offset); + err = mtd_read(master, offset, 0x4, &bytes_read, + (uint8_t *)buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("mtd_read error while reading (offset 0x%X): %d\n", + offset, err); continue; } -- GitLab From 026918e71111afe88382f8d800a852d3e36bf3d4 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Wed, 2 Dec 2015 16:47:40 -0600 Subject: [PATCH 0289/5324] mtd: nand: gpmi: add gpmi dsm supend/resume support i.MX6SX supports deep sleep mode(DSM) that may turn off GPMI/BCH power during suspend, add gpmi nand suspend/resume function to release DMA channel in suspend function and re-init GPMI/BCH controller during resume function. Although it is not necessary to restore GPMI/BCH registers value for i.MX6QDL, the code doesn't distinguish different platforms to keep the code simple. Signed-off-by: Huang Shijie Signed-off-by: Han Xu Signed-off-by: Brian Norris --- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 47 +++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 235ddcb58f39..9c311b06018b 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1,7 +1,7 @@ /* * Freescale GPMI NAND Flash Driver * - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. * Copyright (C) 2008 Embedded Alley Solutions, Inc. * * This program is free software; you can redistribute it and/or modify @@ -2033,9 +2033,54 @@ static int gpmi_nand_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int gpmi_pm_suspend(struct device *dev) +{ + struct gpmi_nand_data *this = dev_get_drvdata(dev); + + release_dma_channels(this); + return 0; +} + +static int gpmi_pm_resume(struct device *dev) +{ + struct gpmi_nand_data *this = dev_get_drvdata(dev); + int ret; + + ret = acquire_dma_channels(this); + if (ret < 0) + return ret; + + /* re-init the GPMI registers */ + this->flags &= ~GPMI_TIMING_INIT_OK; + ret = gpmi_init(this); + if (ret) { + dev_err(this->dev, "Error setting GPMI : %d\n", ret); + return ret; + } + + /* re-init the BCH registers */ + ret = bch_set_geometry(this); + if (ret) { + dev_err(this->dev, "Error setting BCH : %d\n", ret); + return ret; + } + + /* re-init others */ + gpmi_extra_init(this); + + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops gpmi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(gpmi_pm_suspend, gpmi_pm_resume) +}; + static struct platform_driver gpmi_nand_driver = { .driver = { .name = "gpmi-nand", + .pm = &gpmi_pm_ops, .of_match_table = gpmi_nand_id_table, }, .probe = gpmi_nand_probe, -- GitLab From b8b0e465ddb0c9cb16089ddfed68a8569e006465 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Wed, 2 Dec 2015 16:47:43 -0600 Subject: [PATCH 0290/5324] mtd: nand: gpmi: may use minimum required ecc for 744 oobsize NAND By default NAND driver will choose the highest ecc strength that oob could contain, in this case, for some 8K+744 NAND flash, the ecc strength will be up to 52bit, which beyonds the i.MX6QDL BCH capability (40bit). This patch allows the NAND driver try to use minimum required ecc strength if it failed to use the highest ecc, even without explicitly claiming "fsl,use-minimum-ecc" in dts. Signed-off-by: Han Xu Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 9c311b06018b..8122c699ccf2 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -136,7 +136,7 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) * * We may have available oob space in this case. */ -static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) +static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) { struct bch_geometry *geo = &this->bch_geometry; struct nand_chip *chip = &this->nand; @@ -145,7 +145,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) unsigned int block_mark_bit_offset; if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) - return false; + return -EINVAL; switch (chip->ecc_step_ds) { case SZ_512: @@ -158,19 +158,19 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) dev_err(this->dev, "unsupported nand chip. ecc bits : %d, ecc size : %d\n", chip->ecc_strength_ds, chip->ecc_step_ds); - return false; + return -EINVAL; } geo->ecc_chunk_size = chip->ecc_step_ds; geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); if (!gpmi_check_ecc(this)) - return false; + return -EINVAL; /* Keep the C >= O */ if (geo->ecc_chunk_size < mtd->oobsize) { dev_err(this->dev, "unsupported nand chip. ecc size: %d, oob size : %d\n", chip->ecc_step_ds, mtd->oobsize); - return false; + return -EINVAL; } /* The default value, see comment in the legacy_set_geometry(). */ @@ -242,7 +242,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) + ALIGN(geo->ecc_chunk_count, 4); if (!this->swap_block_mark) - return true; + return 0; /* For bit swap. */ block_mark_bit_offset = mtd->writesize * 8 - @@ -251,7 +251,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) geo->block_mark_byte_offset = block_mark_bit_offset / 8; geo->block_mark_bit_offset = block_mark_bit_offset % 8; - return true; + return 0; } static int legacy_set_geometry(struct gpmi_nand_data *this) @@ -285,7 +285,8 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) geo->ecc_strength = get_ecc_strength(this); if (!gpmi_check_ecc(this)) { dev_err(this->dev, - "required ecc strength of the NAND chip: %d is not supported by the GPMI controller (%d)\n", + "ecc strength: %d cannot be supported by the controller (%d)\n" + "try to use minimum ecc strength that NAND chip required\n", geo->ecc_strength, this->devdata->bch_max_ecc_strength); return -EINVAL; @@ -366,10 +367,11 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) int common_nfc_set_geometry(struct gpmi_nand_data *this) { - if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc") - && set_geometry_by_ecc_info(this)) - return 0; - return legacy_set_geometry(this); + if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) + || legacy_set_geometry(this)) + return set_geometry_by_ecc_info(this); + + return 0; } struct dma_chan *get_dma_chan(struct gpmi_nand_data *this) -- GitLab From e88b7f7d6ca47531af602cfb6abdb31ea13eabc3 Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Fri, 15 Jan 2016 11:34:56 +0100 Subject: [PATCH 0291/5324] mtd: atmel_nand: Simplify error messages The error messages when the ECC controller is misconfigured through the device tree are very precise. As a result they can (and will) get obsolete when new revisions of the controller appear. Simplify them before adding the support for the new revision. Signed-off-by: Romain Izard Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 0ae6cba5bef5..ad9f4b062049 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1550,7 +1550,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host, if ((val != 2) && (val != 4) && (val != 8) && (val != 12) && (val != 24)) { dev_err(host->dev, - "Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n", + "Required ECC strength not supported: %u\n", val); return -EINVAL; } @@ -1560,7 +1560,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host, if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) == 0) { if ((val != 512) && (val != 1024)) { dev_err(host->dev, - "Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n", + "Required ECC sector size not supported: %u\n", val); return -EINVAL; } -- GitLab From 8ce06d379a06b4d5c9f944bb60e80b084d16bfc0 Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Fri, 15 Jan 2016 11:34:57 +0100 Subject: [PATCH 0292/5324] mtd: atmel_nand: Use of_device_get_match_data Remove the need for forward declaration and the risk for a null pointer when accessing the private part of the compatible match table, by using the newly introduced of_device_get_match_data function. Signed-off-by: Romain Izard Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index ad9f4b062049..affe7a7e9ad7 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1486,8 +1486,6 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) ecc_writel(host->ecc, CR, ATMEL_ECC_RST); } -static const struct of_device_id atmel_nand_dt_ids[]; - static int atmel_of_init_port(struct atmel_nand_host *host, struct device_node *np) { @@ -1498,7 +1496,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host, enum of_gpio_flags flags = 0; host->caps = (struct atmel_nand_caps *) - of_match_device(atmel_nand_dt_ids, host->dev)->data; + of_device_get_match_data(host->dev); if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { if (val >= 32) { -- GitLab From 947eaebc318d63ada82901cea86c586ac3d854f0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 24 Jan 2016 22:49:17 +0100 Subject: [PATCH 0293/5324] drm/i915: Update DRIVER_DATE to 20160124 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 204661f9873d..afb0beee9975 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -59,7 +59,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20160111" +#define DRIVER_DATE "20160124" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ -- GitLab From f4f58ed19b9ee303985f47352f795631a979294c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jan 2016 14:12:52 -0500 Subject: [PATCH 0294/5324] NFSv4.x: Remove hard coded slotids in callback channel Instead, use the values encoded in the slot table itself. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 6 +++--- fs/nfs/nfs4proc.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index f0939d097406..83a66a8f40f2 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -361,7 +361,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) dprintk("%s enter. slotid %u seqid %u\n", __func__, args->csa_slotid, args->csa_sequenceid); - if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS) + if (args->csa_slotid > tbl->server_highest_slotid) return htonl(NFS4ERR_BADSLOT); slot = tbl->slots + args->csa_slotid; @@ -489,8 +489,8 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, sizeof(res->csr_sessionid)); res->csr_sequenceid = args->csa_sequenceid; res->csr_slotid = args->csa_slotid; - res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; - res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; + res->csr_highestslotid = tbl->server_highest_slotid; + res->csr_target_highestslotid = tbl->target_highest_slotid; status = validate_seqid(tbl, args); if (status) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4bfc33ad0563..be685e236bd5 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7319,7 +7319,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) args->bc_attrs.max_resp_sz = PAGE_SIZE; args->bc_attrs.max_resp_sz_cached = 0; args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS; - args->bc_attrs.max_reqs = 1; + args->bc_attrs.max_reqs = NFS41_BC_MAX_CALLBACKS; dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u " "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", -- GitLab From f74a834a0e1b35e39e917a1a88a62817610ee20b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jan 2016 17:15:37 -0500 Subject: [PATCH 0295/5324] NFSv4.x: CB_SEQUENCE should return NFS4ERR_DELAY if still executing See RFC5661 Section 2.10.6.2: if retrying a request, and the old one is still in progress, we must return NFS4ERR_DELAY as the reply to sequence. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 83a66a8f40f2..e0844fdbd9ac 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -375,6 +375,8 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", __func__, args->csa_sequenceid); + if (tbl->highest_used_slotid != NFS4_NO_SLOT) + return htonl(NFS4ERR_DELAY); /* Signal process_op to set this error on next op */ if (args->csa_cachethis == 0) return htonl(NFS4ERR_RETRY_UNCACHED_REP); -- GitLab From 80f9642724af5dfab7d330481fa22e07fde084da Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jan 2016 15:21:08 -0500 Subject: [PATCH 0296/5324] NFSv4.x: Enforce the ca_maxresponsesize_cached on the back channel We have no duplicate reply cache, so we always set the back channel ca_maxresponsesize_cached to zero when negotiating the session. That means we should always error out as soon as we see the server set args->csa_cachethis. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index e0844fdbd9ac..345df6309017 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -381,9 +381,8 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) if (args->csa_cachethis == 0) return htonl(NFS4ERR_RETRY_UNCACHED_REP); - /* The ca_maxresponsesize_cached is 0 with no DRC */ - else if (args->csa_cachethis == 1) - return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); + /* Liar! We never allowed you to set csa_cachethis != 0 */ + return htonl(NFS4ERR_SEQ_FALSE_RETRY); } /* Wraparound */ @@ -500,6 +499,10 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, cps->slotid = args->csa_slotid; + /* The ca_maxresponsesize_cached is 0 with no DRC */ + if (args->csa_cachethis != 0) + return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); + /* * Check for pending referring calls. If a match is found, a * related callback was received before the response to the original -- GitLab From 5f83d86cf531d737ba2ca9c3cc500ff331fbd43e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jan 2016 16:57:58 -0500 Subject: [PATCH 0297/5324] NFSv4.x: Fix wraparound issues when validing the callback sequence id We need to make sure that we don't allow args->csa_sequenceid == 0. Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 43 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 345df6309017..79c93b3bbfec 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -354,23 +354,15 @@ __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args, * a single outstanding callback request at a time. */ static __be32 -validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) +validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot, + const struct cb_sequenceargs * args) { - struct nfs4_slot *slot; - - dprintk("%s enter. slotid %u seqid %u\n", - __func__, args->csa_slotid, args->csa_sequenceid); + dprintk("%s enter. slotid %u seqid %u, slot table seqid: %u\n", + __func__, args->csa_slotid, args->csa_sequenceid, slot->seq_nr); if (args->csa_slotid > tbl->server_highest_slotid) return htonl(NFS4ERR_BADSLOT); - slot = tbl->slots + args->csa_slotid; - dprintk("%s slot table seqid: %u\n", __func__, slot->seq_nr); - - /* Normal */ - if (likely(args->csa_sequenceid == slot->seq_nr + 1)) - goto out_ok; - /* Replay */ if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", @@ -386,16 +378,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) } /* Wraparound */ - if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { - slot->seq_nr = 1; - goto out_ok; - } + if (unlikely(slot->seq_nr == 0xFFFFFFFFU)) { + if (args->csa_sequenceid == 1) + return htonl(NFS4_OK); + } else if (likely(args->csa_sequenceid == slot->seq_nr + 1)) + return htonl(NFS4_OK); /* Misordered request */ return htonl(NFS4ERR_SEQ_MISORDERED); -out_ok: - tbl->highest_used_slotid = args->csa_slotid; - return htonl(NFS4_OK); } /* @@ -486,6 +476,13 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, goto out_unlock; } + status = validate_seqid(tbl, slot, args); + if (status) + goto out_unlock; + + cps->slotid = args->csa_slotid; + tbl->highest_used_slotid = args->csa_slotid; + memcpy(&res->csr_sessionid, &args->csa_sessionid, sizeof(res->csr_sessionid)); res->csr_sequenceid = args->csa_sequenceid; @@ -493,12 +490,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, res->csr_highestslotid = tbl->server_highest_slotid; res->csr_target_highestslotid = tbl->target_highest_slotid; - status = validate_seqid(tbl, args); - if (status) - goto out_unlock; - - cps->slotid = args->csa_slotid; - /* The ca_maxresponsesize_cached is 0 with no DRC */ if (args->csa_cachethis != 0) return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); @@ -518,7 +509,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, * If CB_SEQUENCE returns an error, then the state of the slot * (sequence ID, cached reply) MUST NOT change. */ - slot->seq_nr++; + slot->seq_nr = args->csa_sequenceid; out_unlock: spin_unlock(&tbl->slot_tbl_lock); -- GitLab From f47553325ede35ecfb82311342452a8f0f27ad2e Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Thu, 7 Jan 2016 16:25:44 +0800 Subject: [PATCH 0298/5324] ARM: dts: rockchip: set the pinctrl default setting for rk3036 i2s Sometime will hang if you set the i2s pinctrl as the none setting. Let's set the pinctrl as the default setting to enable the gpio bias. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index b9567c1e0687..8f1bb0fbf768 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -579,12 +579,12 @@ i2s { i2s_bus: i2s-bus { - rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_none>, - <1 1 RK_FUNC_1 &pcfg_pull_none>, - <1 2 RK_FUNC_1 &pcfg_pull_none>, - <1 3 RK_FUNC_1 &pcfg_pull_none>, - <1 4 RK_FUNC_1 &pcfg_pull_none>, - <1 5 RK_FUNC_1 &pcfg_pull_none>; + rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_default>, + <1 1 RK_FUNC_1 &pcfg_pull_default>, + <1 2 RK_FUNC_1 &pcfg_pull_default>, + <1 3 RK_FUNC_1 &pcfg_pull_default>, + <1 4 RK_FUNC_1 &pcfg_pull_default>, + <1 5 RK_FUNC_1 &pcfg_pull_default>; }; }; -- GitLab From 3860aa1ccfe01adb6c3fd09e880d812ceb408e5c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 9 Jan 2016 03:18:51 +0100 Subject: [PATCH 0299/5324] ARM: dts: rockchip: swap i2s clock ordering on rk3036 For sound setups using the simple-card mechanism, the main clock (sysclk) is expected to be the first element. For the i2s-driver itself it doesn't matter, as it uses named clocks, so we can just swap them. Reported-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index 8f1bb0fbf768..ee457a2e997e 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -241,8 +241,8 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S>, <&cru SCLK_I2S>; + clock-names = "i2s_clk", "i2s_hclk"; + clocks = <&cru SCLK_I2S>, <&cru HCLK_I2S>; dmas = <&pdma 0>, <&pdma 1>; dma-names = "tx", "rx"; pinctrl-names = "default"; -- GitLab From 47bf3a5c9e2aadaa6bfdff151e139196f1334c06 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Thu, 7 Jan 2016 16:25:45 +0800 Subject: [PATCH 0300/5324] ARM: dts: rockchip: add the sound setup for rk3036-kylin board The rk3036-kylin board uses a rt5616 audio codec connected to the i2s and can use the simple card to tie everyting together. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 992f9cadbc04..b28762522da0 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -46,6 +46,30 @@ model = "Rockchip RK3036 KylinBoard"; compatible = "rockchip,rk3036-kylin", "rockchip,rk3036"; + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rt5616-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC1", "Microphone Jack", + "MIC2", "Microphone Jack", + "Microphone Jack", "micbias1", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + + simple-audio-card,codec { + sound-dai = <&rt5616>; + }; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -257,6 +281,17 @@ &i2c2 { status = "okay"; + + rt5616: rt5616@1b { + compatible = "rt5616"; + reg = <0x1b>; + #sound-dai-cells = <0>; + }; +}; + +&i2s { + #sound-dai-cells = <0>; + status = "okay"; }; &sdio { -- GitLab From b270a63de5b37a6e8d2e18cabbaf14d255a609ba Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Thu, 31 Dec 2015 10:13:52 +0100 Subject: [PATCH 0301/5324] ARM: dts: rockchip: Add LEDs via gpio-leds for Radxa Rock2 Square Describe the two user-controllable LEDs on Rock2 Square boards. All information have been retrieved from the schematics and the vendor devicetree. The default-triggers mimic the behaviour of the vendor-kernel to keep functionalities in sync. Signed-off-by: Romain Perier Reviewed-by: Sjoerd Simons Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-rock2-square.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index c5453a0b07fc..bcaf868a76bb 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -49,6 +49,22 @@ stdout-path = "serial2:115200n8"; }; + gpio-leds { + compatible = "gpio-leds"; + + heartbeat { + gpios = <&gpio7 15 GPIO_ACTIVE_LOW>; + label = "rock2:green:state1"; + linux,default-trigger = "heartbeat"; + }; + + mmc { + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + label = "rock2:blue:state2"; + linux,default-trigger = "mmc0"; + }; + }; + ir: ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; -- GitLab From 5d69fa0f27f5bdff449858a20b7f50f08b9f33d8 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 15 Jan 2016 21:49:51 +0800 Subject: [PATCH 0302/5324] ARM: dts: rockchip: enable the uart0 for kylin board This patch is enabling the uart0 for bluetooth module. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index b28762522da0..c748d2cbeed6 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -308,6 +308,10 @@ pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; }; +&uart0 { + status = "okay"; +}; + &uart2 { status = "okay"; }; -- GitLab From 99dc9fdc3105116b46273577e9641d7304b3046e Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 15 Jan 2016 21:49:52 +0800 Subject: [PATCH 0303/5324] ARM: dts: rockchip: enable the high speed on sdio for kylin board We want to the higher speed for wifi module working. Bootup kernel log: ... mmc_host mmc0: Bus speed (slot 0) = 37125000Hz (slot req 37500000Hz, actual 37125000HZ div = 0) or run 'cat /sys/kernel/debug/clk/clk_summary |grep phase -C 1' to check Otherwise, the mmc0 will run 400khz defalult value to work. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index c748d2cbeed6..905e187da381 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -299,6 +299,7 @@ broken-cd; bus-width = <4>; + cap-sd-highspeed; cap-sdio-irq; default-sample-phase = <90>; keep-power-in-suspend; @@ -306,6 +307,10 @@ num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; }; &uart0 { -- GitLab From 4a9d0b033702566cde2f33ed19ff9c8a90b7fe8f Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 15 Jan 2016 21:49:53 +0800 Subject: [PATCH 0304/5324] ARM: dts: rockchip: add the sdio power sequence for kylin board This patch adds the sdio power sequence for kylin board. The WLAN attached to a SDIO interface, wifi/bluetooth have reset and power been needed to enable. AFAIK, the simple power sequence provider sets a value for multiple GPIOs. So the reset and power of WlAN chip can be handled in mmc power sequence. On the module itself this is one of these, that should can be handled by reset GPIOs in simple mmc power sequence. The Bluetooth host wake is high active from bootup, this patch is also set pinctrl bias as the default to enable the pull up in soc internal. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 905e187da381..6a32b234525a 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -46,6 +46,23 @@ model = "Rockchip RK3036 KylinBoard"; compatible = "rockchip,rk3036-kylin", "rockchip,rk3036"; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_wake_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - SDIO_RESET_L_WL_RST + * - SDIO_RESET_L_BT_EN + */ + reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>, /* WL_REG_ON */ + <&gpio0 27 GPIO_ACTIVE_LOW>, /* WL_RST */ + <&gpio2 9 GPIO_ACTIVE_LOW>; /* BT_EN */ + }; + sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; @@ -303,6 +320,7 @@ cap-sdio-irq; default-sample-phase = <90>; keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; non-removable; num-slots = <1>; pinctrl-names = "default"; @@ -336,6 +354,12 @@ }; }; + sdio { + bt_wake_h: bt-wake-h { + rockchip,pins = <2 8 RK_FUNC_GPIO &pcfg_pull_default>; + }; + }; + sleep { global_pwroff: global-pwroff { rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>; -- GitLab From 6cff705b2dd944a14768e6a63c0773831583488e Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 15 Jan 2016 21:49:54 +0800 Subject: [PATCH 0305/5324] ARM: dts: rockchip: add the sdmmc for kylin board Although We can add the sdmmc node, shouldn't enable it. Since the sdmmc is reusing the same pin with uart2. Unfortunately, the uart2 is used by the debug port, so that will cause the debug information can't display on console if enabling the sdmmc. As we have supported the sdmmc (sd card) on hardware for kylin board. So, maybe we can have the sdmmc node in kylin dts, not to enable it. Anyway, you only need add the okay status if someone want to enable the sdmmc. e.g. if you use the adb to debug with android os. You can add the status = "okay" to enable the sdmmc for sd card working. The default status is disabling it. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 6a32b234525a..190f22cc95ef 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -331,6 +331,17 @@ sd-uhs-sdr104; }; +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; +}; + &uart0 { status = "okay"; }; @@ -360,6 +371,12 @@ }; }; + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <2 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + sleep { global_pwroff: global-pwroff { rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>; -- GitLab From ac79e0ef419681206ddb5aec502d2486090575a9 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 15 Jan 2016 21:26:18 +0800 Subject: [PATCH 0306/5324] ARM: dts: rockchip: enable pwm3 as pwm regulator for rk3066a based boards Rayeager/Bqcurie2/Marsboard use pwm3 modulate the vdd_logic voltage, so enable it. Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a-bqcurie2.dts | 16 ++++++++++++++++ arch/arm/boot/dts/rk3066a-marsboard.dts | 16 ++++++++++++++++ arch/arm/boot/dts/rk3066a-rayeager.dts | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 38c91a839795..8a58bb3d7b6b 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -53,6 +53,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -203,6 +215,10 @@ disable-wp; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts index 7cdc308bfac5..a2b763e949b4 100644 --- a/arch/arm/boot/dts/rk3066a-marsboard.dts +++ b/arch/arm/boot/dts/rk3066a-marsboard.dts @@ -52,6 +52,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: sdmmc-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -194,6 +206,10 @@ }; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 341c1f87936a..84f44f5ee3de 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -74,6 +74,18 @@ }; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vsys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vsys"; @@ -431,6 +443,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + &saradc { vref-supply = <&vcc_25>; status = "okay"; -- GitLab From 3a4294927afabd1cb0acbf0ae4fa0f2d96f09c69 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 15 Jan 2016 21:25:21 +0800 Subject: [PATCH 0307/5324] ARM: dts: rockchip: increase vdd_arm voltage for rk3066a based boards The current vdd_arm voltage is too low, increase it will make the system more stable. Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 58bac5053858..81cf60c42712 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -61,11 +61,13 @@ reg = <0x0>; operating-points = < /* kHz uV */ - 1008000 1075000 - 816000 1025000 - 600000 1025000 - 504000 1000000 - 312000 975000 + 1416000 1300000 + 1200000 1175000 + 1008000 1125000 + 816000 1125000 + 600000 1100000 + 504000 1100000 + 312000 1075000 >; clock-latency = <40000>; clocks = <&cru ARMCLK>; -- GitLab From cab6f070ab53df0fa8a17e95ca7518a8c8e42e69 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Wed, 6 Jan 2016 12:03:56 +0800 Subject: [PATCH 0308/5324] ARM: dts: rockchip: add rk3288 mipi_dsi nodes Add a mipi_dsi node, and also add mipi_dsi endpoints to vopb and vopl output port nodes. Signed-off-by: Chris Zhong Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288.dtsi | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 8ac49f3efc17..f0a091949f42 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -815,6 +815,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopb>; }; + vopb_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopb>; + }; }; }; @@ -848,6 +852,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopl>; }; + vopl_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopl>; + }; }; }; @@ -861,6 +869,37 @@ status = "disabled"; }; + mipi_dsi: mipi@ff960000 { + compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0xff960000 0x4000>; + interrupts = ; + clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>; + clock-names = "ref", "pclk"; + rockchip,grf = <&grf>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + mipi_in: port { + #address-cells = <1>; + #size-cells = <0>; + mipi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_mipi>; + }; + mipi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_mipi>; + }; + }; + }; + }; + hdmi: hdmi@ff980000 { compatible = "rockchip,rk3288-dw-hdmi"; reg = <0xff980000 0x20000>; -- GitLab From 30c4cbcd48b010259597436017228430edcfe242 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sat, 9 Jan 2016 13:54:17 +0100 Subject: [PATCH 0309/5324] ARM: dts: rockchip: Add the iodomains for the Rock2 SOM Add the IO domain configuration for the Rock2 SOM and model the fixed regulator used as the vqmmc for the EMMC device. Signed-off-by: Sjoerd Simons Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-rock2-som.dtsi | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 1ece66f3e162..e1ee9f949035 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -61,6 +61,31 @@ clock-output-names = "ext_gmac"; }; + io_domains: io-domains { + compatible = "rockchip,rk3288-io-voltage-domain"; + rockchip,grf = <&grf>; + + audio-supply = <&vcc_io>; + bb-supply = <&vcc_io>; + dvp-supply = <&vcc_18>; + flash0-supply = <&vcc_flash>; + flash1-supply = <&vccio_pmu>; + gpio30-supply = <&vccio_pmu>; + gpio1830 = <&vcc_io>; + lcdc-supply = <&vcc_io>; + sdcard-supply = <&vccio_sd>; + wifi-supply = <&vcc_18>; + }; + + vcc_flash: flash-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <150>; + vin-supply = <&vcc_io>; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -85,6 +110,7 @@ pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; status = "okay"; }; -- GitLab From ee16bbd289a63e3036d31dcd809e411e9a5dbd5d Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Fri, 15 Jan 2016 19:54:14 +0800 Subject: [PATCH 0310/5324] clk: rockchip: rk3036: enable the CLK_IGNORE_UNUSED flag for hclk_vio_bus HCLK_VIO_BUS is the noc bus controller clock for display module, due to it shouldn't belong to any driver, but we need it enabled, so just mark it as the CLK_IGNORE_UNUSED flag. Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index ebce98033fbb..9c317a3b81e5 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -376,7 +376,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS), GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), - GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), + GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), /* hclk_video gates */ -- GitLab From 535ebd428aeb07c3327947281306f2943f2c9faa Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 19 Jan 2016 10:01:08 +0100 Subject: [PATCH 0311/5324] clk: rockchip: rk3368: fix cpuclk mux bit of big cpu-cluster Both clusters have their mux bit in bit 7 of their respective register. For whatever reason the big cluster currently lists bit 15 which is definitly wrong. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org --- drivers/clk/rockchip/clk-rk3368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index be0ede522269..473b36f0830a 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -165,7 +165,7 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = { .core_reg = RK3368_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, - .mux_core_shift = 15, + .mux_core_shift = 7, }; static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { -- GitLab From c6d5fe2ca8286f35a79f7345c9378c39d48a1527 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 19 Jan 2016 10:09:22 +0100 Subject: [PATCH 0312/5324] clk: rockchip: rk3368: fix cpuclk core dividers Similar to commit 9880d4277f6a ("clk: rockchip: fix rk3288 cpuclk core dividers") it seems the cpuclk dividers are one to high on the rk3368 as well. And again similar to the previous fix, we opt to make the divider list contain the values to be written to use the same paradigm for them on all supported socs. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org --- drivers/clk/rockchip/clk-rk3368.c | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 473b36f0830a..82a0c3e528ce 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -218,29 +218,29 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { } static struct rockchip_cpuclk_rate_table rk3368_cpuclkb_rates[] __initdata = { - RK3368_CPUCLKB_RATE(1512000000, 2, 6, 6), - RK3368_CPUCLKB_RATE(1488000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1416000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1200000000, 2, 4, 4), - RK3368_CPUCLKB_RATE(1008000000, 2, 4, 4), - RK3368_CPUCLKB_RATE( 816000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 600000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKB_RATE(1512000000, 1, 5, 5), + RK3368_CPUCLKB_RATE(1488000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1416000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1200000000, 1, 3, 3), + RK3368_CPUCLKB_RATE(1008000000, 1, 3, 3), + RK3368_CPUCLKB_RATE( 816000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 600000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 312000000, 1, 1, 1), }; static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = { - RK3368_CPUCLKL_RATE(1512000000, 2, 7, 7), - RK3368_CPUCLKL_RATE(1488000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1416000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1200000000, 2, 5, 5), - RK3368_CPUCLKL_RATE(1008000000, 2, 5, 5), - RK3368_CPUCLKL_RATE( 816000000, 2, 4, 4), - RK3368_CPUCLKL_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 600000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKL_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKL_RATE(1512000000, 1, 6, 6), + RK3368_CPUCLKL_RATE(1488000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1416000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1200000000, 1, 4, 4), + RK3368_CPUCLKL_RATE(1008000000, 1, 4, 4), + RK3368_CPUCLKL_RATE( 816000000, 1, 3, 3), + RK3368_CPUCLKL_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 600000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1), }; static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { -- GitLab From 0f28d98463498c61c61a38aacbf9f69e92e85e9d Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 20 Jan 2016 19:22:38 +0100 Subject: [PATCH 0313/5324] clk: rockchip: rk3368: fix parents of video encoder/decoder The vdpu and vepu clocks can also be parented to the npll and current parent list also is wrong as it would use the npll as "usbphy" source, so adapt the parent to the correct one. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org --- drivers/clk/rockchip/clk-rk3368.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 82a0c3e528ce..990e1dc7529d 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -384,10 +384,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 3 */ - COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3368_CLKGATE_CON(4), 6, GFLAGS), - COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3368_CLKGATE_CON(4), 7, GFLAGS), -- GitLab From fd0c0740fac17a014704ef89d8c8b1768711ca59 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 20 Jan 2016 21:47:57 +0100 Subject: [PATCH 0314/5324] clk: rockchip: rk3368: fix hdmi_cec gate-register Fix a typo making the sclk_hdmi_cec access a wrong register to handle its gate. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org --- drivers/clk/rockchip/clk-rk3368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 990e1dc7529d..7016ed24bbe5 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -442,7 +442,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK3368_CLKGATE_CON(4), 13, GFLAGS), GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, - RK3368_CLKGATE_CON(5), 12, GFLAGS), + RK3368_CLKGATE_CON(4), 12, GFLAGS), COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(21), 15, 1, MFLAGS, -- GitLab From c840f28bbf643c361c463bcb8fb815d0b2dad4e8 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 25 Sep 2015 10:14:57 +0800 Subject: [PATCH 0315/5324] arm64: Enable the timer on Rockchip architecture On the RK3368 SoC, support the APB timers for rockchip platform. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm64/Kconfig.platforms | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..8a0952275291 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -60,6 +60,7 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select PINCTRL select PINCTRL_ROCKCHIP + select ROCKCHIP_TIMER help This enables support for the ARMv8 based Rockchip chipsets, like the RK3368. -- GitLab From 3e33d4e46d8d920c817b18f72c9a41911850c61f Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 11 Jan 2016 02:36:38 -0800 Subject: [PATCH 0316/5324] dt-bindings: add power-domain header for RK3368 SoCs According to a description from TRM, add all the power domains. Signed-off-by: zhangqing Reviewed-by: Caesar Wang Signed-off-by: Heiko Stuebner --- include/dt-bindings/power/rk3368-power.h | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 include/dt-bindings/power/rk3368-power.h diff --git a/include/dt-bindings/power/rk3368-power.h b/include/dt-bindings/power/rk3368-power.h new file mode 100644 index 000000000000..93633d57ed84 --- /dev/null +++ b/include/dt-bindings/power/rk3368-power.h @@ -0,0 +1,28 @@ +#ifndef __DT_BINDINGS_POWER_RK3368_POWER_H__ +#define __DT_BINDINGS_POWER_RK3368_POWER_H__ + +/* VD_CORE */ +#define RK3368_PD_A53_L0 0 +#define RK3368_PD_A53_L1 1 +#define RK3368_PD_A53_L2 2 +#define RK3368_PD_A53_L3 3 +#define RK3368_PD_SCU_L 4 +#define RK3368_PD_A53_B0 5 +#define RK3368_PD_A53_B1 6 +#define RK3368_PD_A53_B2 7 +#define RK3368_PD_A53_B3 8 +#define RK3368_PD_SCU_B 9 + +/* VD_LOGIC */ +#define RK3368_PD_BUS 10 +#define RK3368_PD_PERI 11 +#define RK3368_PD_VIO 12 +#define RK3368_PD_ALIVE 13 +#define RK3368_PD_VIDEO 14 +#define RK3368_PD_GPU_0 15 +#define RK3368_PD_GPU_1 16 + +/* VD_PMU */ +#define RK3368_PD_PMU 17 + +#endif -- GitLab From 1f164bd5b7dd4a1903c274ca70bf1ab11684db99 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 11 Jan 2016 02:36:40 -0800 Subject: [PATCH 0317/5324] dt-bindings: modify document of Rockchip power domains Modify binding documentation for the power domains found on Rockchip RK3368 SoCs. Signed-off-by: zhangqing Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- .../bindings/soc/rockchip/power_domain.txt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 112756e11802..13dc6a3fdb4a 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt @@ -6,6 +6,7 @@ powered up/down by software based on different application scenes to save power. Required properties for power domain controller: - compatible: Should be one of the following. "rockchip,rk3288-power-controller" - for RK3288 SoCs. + "rockchip,rk3368-power-controller" - for RK3368 SoCs. - #power-domain-cells: Number of cells in a power-domain specifier. Should be 1 for multiple PM domains. - #address-cells: Should be 1. @@ -14,6 +15,7 @@ Required properties for power domain controller: Required properties for power domain sub nodes: - reg: index of the power domain, should use macros in: "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. + "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain. - clocks (optional): phandles to clocks which need to be enabled while power domain switches state. @@ -31,11 +33,24 @@ Example: }; }; + power: power-controller { + compatible = "rockchip,rk3368-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + pd_gpu_1 { + reg = ; + clocks = <&cru ACLK_GPU_CFG>; + }; + }; + Node of a device using power domains must have a power-domains property, containing a phandle to the power device node and an index specifying which power domain to use. The index should use macros in: "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. + "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain. Example of the node using power domain: @@ -44,3 +59,9 @@ Example of the node using power domain: power-domains = <&power RK3288_PD_GPU>; /* ... */ }; + + node { + /* ... */ + power-domains = <&power RK3368_PD_GPU_1>; + /* ... */ + }; -- GitLab From 6f31ef2c5c3487fc69c2a34573db88b2f46498ba Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 8 Jan 2016 17:14:42 -0800 Subject: [PATCH 0318/5324] clk: sunxi: Drop clk.h include This file is a clock provider, not a clk consumer. Drop the clk.h include. Cc: Jens Kuske Cc: Maxime Ripard Signed-off-by: Stephen Boyd Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sun8i-bus-gates.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index e32d18ba252b..1113eb98c9b4 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include -- GitLab From ce3dd55b99b151a90ac1701c6825f2ae2d49b54e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 22 Dec 2015 12:27:47 +0000 Subject: [PATCH 0319/5324] arm64: Introduce Allwinner SoC config option To prepare for supporting the Allwinner A64 SoC, introduce a config option to allow compiling Allwinner (aka. sunxi) specific drivers for ARM64. This patch just defines the ARCH_SUNXI symbol to allow Allwinner specific drivers to be selected during kernel configuration. Signed-off-by: Andre Przywara Acked-by: Arnd Bergmann Signed-off-by: Maxime Ripard --- arch/arm64/Kconfig.platforms | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bde..3f9d5ed96cc8 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -1,5 +1,10 @@ menu "Platform selection" +config ARCH_SUNXI + bool "Allwinner sunxi 64-bit SoC Family" + help + This enables support for Allwinner sunxi based SoCs like the A64. + config ARCH_BCM_IPROC bool "Broadcom iProc SoC Family" help -- GitLab From 2d3e8f70317cc6df93465e51f451d41bad32e010 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 22 Dec 2015 12:27:43 +0000 Subject: [PATCH 0320/5324] drivers: sunxi-rsb: fix error output type "len" is actually a size_t in this function here, so properly annotate the dev_err printf type to allow compilation for 64-bit architectures. Signed-off-by: Andre Przywara Acked-by: Arnd Bergmann Signed-off-by: Maxime Ripard --- drivers/bus/sunxi-rsb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 25996e256110..795c9d9c96a6 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -330,7 +330,7 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_RD32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } @@ -372,7 +372,7 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_WR32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } -- GitLab From 925c87109b2beb0b10f15714fcea02c3d9c15de6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Dec 2015 23:35:00 +0100 Subject: [PATCH 0321/5324] ARM: dts: sun4i: Add touchscreen node to inet9f-rev03 tablet dts file Add a node describing the focaltech ft5406ee8 touchscreen found on inet-9f-rev03 / qware qw tb-g100 tablets. Signed-off-by: Hans de Goede Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts index ca49b0d0ce1e..bba4f9cf9bf5 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts @@ -253,6 +253,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { -- GitLab From 75313a075e787495234b5c7bc3dcbf57c69cf162 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Dec 2015 23:35:01 +0100 Subject: [PATCH 0322/5324] ARM: dts: sun4i: Add touchscreen node to chuwi-v7 dts file Add a node describing the focaltech ft5306de4 touchscreen found on chuwi-v7-cw0825 tablets. Signed-off-by: Hans de Goede Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts index 53660894ea95..023b03efa5ff 100644 --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts @@ -45,6 +45,7 @@ #include "sunxi-common-regulators.dtsi" #include #include +#include / { model = "Chuwi V7 CW0825"; @@ -88,6 +89,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5306de4: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <1024>; + touchscreen-size-y = <768>; + }; }; &lradc { -- GitLab From 1b4dcd01f72f64a8a7db666a309a0afd00fe8a11 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Dec 2015 23:35:02 +0100 Subject: [PATCH 0323/5324] ARM: dts: sun4i: Add touchscreen node to inet97fv2 dts file Add a node describing the focaltech ft5306de4 touchscreen found on inet97fv2 tablets. Signed-off-by: Hans de Goede Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts index 77c31dab86b1..04b0d2d1ae6c 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts @@ -48,6 +48,7 @@ #include #include +#include / { model = "INet-97F Rev 02"; @@ -93,6 +94,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { -- GitLab From 7c929aa6e34eb8efd886df1cae62adb825f608a1 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Wed, 6 Jan 2016 21:11:53 +0800 Subject: [PATCH 0324/5324] ARM: dts: sun8i: Add Allwinner A83T dtsi Allwinner A83T is new octa-core cortex-a7 SOC. This adds the basic dtsi, the clocks differs from earlier sun8i SOCs. Signed-off-by: Vishnu Patekar [Maxime: Removed empty chosen node] Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 198 ++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 arch/arm/boot/dts/sun8i-a83t.dtsi diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi new file mode 100644 index 000000000000..bad5df7175b4 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -0,0 +1,198 @@ +/* + * Copyright 2015 Vishnu Patekar + * + * Vishnu Patekar + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) 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 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. + + */ + +#include "skeleton.dtsi" + +#include + +#include + +/ { + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <1>; + }; + + cpu@2 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <2>; + }; + + cpu@3 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <3>; + }; + + cpu@100 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x100>; + }; + + cpu@101 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x101>; + }; + + cpu@102 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x102>; + }; + + cpu@103 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x103>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + osc32k: osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "osc32k"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-a83t-pinctrl"; + interrupts = , + , + ; + reg = <0x01c20800 0x400>; + clocks = <&osc24M>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <3>; + #gpio-cells = <3>; + + mmc0_pins_a: mmc0@0 { + allwinner,pins = "PF0", "PF1", "PF2", + "PF3", "PF4", "PF5"; + allwinner,function = "mmc0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_a: uart0@0 { + allwinner,pins = "PF2", "PF4"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_b: uart0@1 { + allwinner,pins = "PB9", "PB10"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&osc24M>; + status = "disabled"; + }; + + gic: interrupt-controller@01c81000 { + compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; + reg = <0x01c81000 0x1000>, + <0x01c82000 0x1000>, + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = ; + }; + }; +}; -- GitLab From b9c34584d74606731eb2c7131f179a96f8194700 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Wed, 6 Jan 2016 21:11:54 +0800 Subject: [PATCH 0325/5324] ARM: dts: sun8i: Add A83T HomletV2 Board by Allwinner H8Homlet Proto v2.0 Board is A83T Dev Board by Allwinner. It has UART, ethernet, USB, HDMI, etc ports on it. A83T patches are tested on this board. It has UART, ethernet, USB, HDMI, etc ports on it. For FEL mode it needs USB A-A(Male) cable. I used uart0 which is multiplexed to microsd pins PF2 and PF4. Enabled UART0 Header(PB9, PB10 pins). Signed-off-by: Vishnu Patekar Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/Makefile | 1 + .../dts/sun8i-a83t-allwinner-h8homlet-v2.dts | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26..884ef92bb4cc 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -691,6 +691,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-ippo-q8h-v1.2.dtb \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ + sun8i-a83t-allwinner-h8homlet-v2.dtb \ sun8i-h3-orangepi-plus.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts new file mode 100644 index 000000000000..342e1d33fa1c --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Vishnu Patekar + * Vishnu Patekar + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) 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 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. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" + +/ { + model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; + compatible = "allwinner,h8homlet-v2", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; -- GitLab From 85c19acf578243b7f9d349cb4e24e113661e9990 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Sun, 17 Jan 2016 00:24:55 +0800 Subject: [PATCH 0326/5324] ARM: dts: sun8i: Enable timer node for A83T A83T timer is compatible with that of earlier SOCs. Just add timer node to enable and re-use it. Signed-off-by: Vishnu Patekar Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index bad5df7175b4..08df5598df9c 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -174,6 +174,14 @@ }; }; + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0xa0>; + interrupts = , + ; + clocks = <&osc24M>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; -- GitLab From b1dc902fdaec1cba1b1c8300cffecc515d126753 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Jan 2016 00:24:56 +0800 Subject: [PATCH 0327/5324] ARM: dts: sun8i: Add watchdog device node for A83T The A83T, like previous Allwinner SoCs, has a watchdog as part of its timer block. Add a device node for it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 08df5598df9c..8d27b6381257 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -182,6 +182,13 @@ clocks = <&osc24M>; }; + watchdog@01c20ca0 { + compatible = "allwinner,sun6i-a31-wdt"; + reg = <0x01c20ca0 0x20>; + interrupts = ; + clocks = <&osc24M>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; -- GitLab From ac6e4349b36a0a986d21b9f700ef1c727b8790d3 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Jan 2016 00:24:57 +0800 Subject: [PATCH 0328/5324] ARM: dts: sun8i: Add device tree for Cubietruck Plus Cubietruck Plus is a A83T/H8 based development board. The board has standard DDR3 SDRAM, AXP818 PMIC/codec, SD/MMC, eMMC, USB 2.0 host via HSIC USB Hub, USB OTG, SATA via USB bridge, gigabit ethernet, WiFi, headphone out / mic in, and various GPIO headers. The board also has an EEPROM on i2c0 which holds the MAC address. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/Makefile | 1 + .../boot/dts/sun8i-a83t-cubietruck-plus.dts | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 884ef92bb4cc..e062fb36ca5b 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -692,6 +692,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-cubietruck-plus.dtb \ sun8i-h3-orangepi-plus.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts new file mode 100644 index 000000000000..88b1e0970b8d --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) 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 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. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" + +/ { + model = "Cubietech Cubietruck Plus"; + compatible = "cubietech,cubietruck-plus", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; -- GitLab From db30fce1eea58e50ae8b2722704b4f529c394dba Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 25 Nov 2015 16:39:04 +0100 Subject: [PATCH 0329/5324] ARM: sun5i: chip: Add CPU regulator for cpufreq The current DT doesn't have a phandle to the CPU regulator in the CPU node, which disables the CPU voltage scaling entirely. Add that phandle. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts index 530ab28e9ca2..f6898c6b84d4 100644 --- a/arch/arm/boot/dts/sun5i-r8-chip.dts +++ b/arch/arm/boot/dts/sun5i-r8-chip.dts @@ -70,6 +70,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + &ehci0 { status = "okay"; }; -- GitLab From 74124439b93065c35b840f381bb26f61452c18e5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:38 +0800 Subject: [PATCH 0330/5324] ARM: dts: sun8i: sina33: Enable hardware reset and HS-DDR for eMMC mmc2 has a special pin for eMMC hardware reset, which is controllable from the controller. Add the "mmc-cap-hw-reset" property to denote that this controller supports this function, and the pins are actually used. Also increase the signal drive strength for mmc2 pins, for HS-DDR mode support. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts index 13ce68f06dd6..bd2a3beb4629 100644 --- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts +++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts @@ -109,10 +109,13 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; &mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; /* eMMC is missing pull-ups */ allwinner,pull = ; }; -- GitLab From 3a95221352a99d2dda7fc4890f70481abef22766 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:39 +0800 Subject: [PATCH 0331/5324] ARM: dts: sun9i: Use sun9i specific mmc compatible sun9i/A80 MMC controllers have a larger FIFO, and the FIFO DMA trigger levels can be increased. Also, the mmc module clock parent has a higher clock rate, and the sample and output delay phases are different. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun9i-a80.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi index e838f206f2a0..f4f61b02be1a 100644 --- a/arch/arm/boot/dts/sun9i-a80.dtsi +++ b/arch/arm/boot/dts/sun9i-a80.dtsi @@ -543,7 +543,7 @@ }; mmc0: mmc@01c0f000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>, <&mmc0_clk 1>, <&mmc0_clk 2>; @@ -557,7 +557,7 @@ }; mmc1: mmc@01c10000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c10000 0x1000>; clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>, <&mmc1_clk 1>, <&mmc1_clk 2>; @@ -571,7 +571,7 @@ }; mmc2: mmc@01c11000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c11000 0x1000>; clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>, <&mmc2_clk 1>, <&mmc2_clk 2>; @@ -585,7 +585,7 @@ }; mmc3: mmc@01c12000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c12000 0x1000>; clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>, <&mmc3_clk 1>, <&mmc3_clk 2>; -- GitLab From a22f8b22a9496396d7a8512225dace208645e04c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:35 +0800 Subject: [PATCH 0332/5324] ARM: dts: sun6i: Add mmc3 pins for 8 bit emmc mmc2 and mmc3 are available on the same pins, with different mux values. However, only mmc3 supports 8 bit DDR transfer modes. Since preference for mmc3 over mmc2 is due to DDR transfer modes, just set the drive strength to 40mA, which is needed for DDR. This pinmux setting also includes the hardware reset pin for emmc. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun6i-a31.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index b6ad7850fac6..1867af24ff52 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -709,6 +709,16 @@ allwinner,pull = ; }; + mmc3_8bit_emmc_pins: mmc3@1 { + allwinner,pins = "PC6", "PC7", "PC8", "PC9", + "PC10", "PC11", "PC12", + "PC13", "PC14", "PC15", + "PC24"; + allwinner,function = "mmc3"; + allwinner,drive = ; + allwinner,pull = ; + }; + gmac_pins_mii_a: gmac_mii@0 { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA8", "PA9", "PA11", -- GitLab From 9fc1db1b7e4d9fc254968b1e0340732a60fba0a6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:36 +0800 Subject: [PATCH 0333/5324] ARM: dts: sun6i: sina31s: Switch to mmc3 for onboard eMMC According to Allwinner, only mmc3 supports 8 bit DDR transfers for eMMC. Switch to mmc3 for the onboard eMMC, and also assign vqmmc for signal voltage sensing, and "cap-mmc-hw-reset" to denote this instance can use eMMC hardware reset. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi index ea69fb8ad4d8..4ec0c8679b2e 100644 --- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi +++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi @@ -61,12 +61,14 @@ }; /* eMMC on core board */ -&mmc2 { +&mmc3 { pinctrl-names = "default"; - pinctrl-0 = <&mmc2_8bit_emmc_pins>; + pinctrl-0 = <&mmc3_8bit_emmc_pins>; vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; -- GitLab From 3b5d8dce4c0b063962b409bb0b1db84f3a4e8410 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:37 +0800 Subject: [PATCH 0334/5324] ARM: dts: sun8i: Include SDC2_RST pin in mmc2_8bit_pins mmc2_8bit_pins is used with eMMC chips, which also have a reset pin. The MMC controller also has a reset output that is supported. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index 6f88fb0ddbc7..7e05e09e61c7 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -381,7 +381,7 @@ allwinner,pins = "PC5", "PC6", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", - "PC15"; + "PC15", "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; -- GitLab From 675ec62b08480fe1250c70cba61ad6e74652ed6f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:40 +0800 Subject: [PATCH 0335/5324] ARM: dts: sun9i: Include SDC2_RST pin in mmc2_8bit_pins mmc2_8bit_pins is used with eMMC chips, which also have a reset pin. The MMC controller also has a reset output that is supported. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun9i-a80.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi index f4f61b02be1a..f68b3242b33a 100644 --- a/arch/arm/boot/dts/sun9i-a80.dtsi +++ b/arch/arm/boot/dts/sun9i-a80.dtsi @@ -704,7 +704,8 @@ mmc2_8bit_pins: mmc2_8bit { allwinner,pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", - "PC13", "PC14", "PC15"; + "PC13", "PC14", "PC15", + "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; -- GitLab From 02df9cb85e156924339f2244aec29dcc37d9ab8c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:41 +0800 Subject: [PATCH 0336/5324] ARM: dts: sun9i: a80-optimus: Enable hardware reset and HS-DDR for eMMC mmc2 has a special pin for eMMC hardware reset, which is controllable from the controller. Add the "mmc-cap-hw-reset" property to denote that this controller supports this function, and the pins are actually used. Also increase the signal drive strength for mmc2 pins, for HS-DDR mode support. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun9i-a80-optimus.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts index c0060e4f7379..958160e40fd0 100644 --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts @@ -174,9 +174,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + ®_usb1_vbus { pinctrl-0 = <&usb1_vbus_pin_optimus>; gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ -- GitLab From 8826532c76da7e6f157aa319dbf358c067f5877f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 21 Jan 2016 13:26:42 +0800 Subject: [PATCH 0337/5324] ARM: dts: sun9i: cubieboard4: Enable hardware reset and HS-DDR for eMMC mmc2 has a special pin for eMMC hardware reset, which is controllable from the controller. Add the "mmc-cap-hw-reset" property to denote that this controller supports this function, and the pins are actually used. Also increase the signal drive strength for mmc2 pins, for HS-DDR mode support. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun9i-a80-cubieboard4.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts index 382bd9fc5647..eb2ccd0a3bd5 100644 --- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts @@ -111,9 +111,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + &r_ir { status = "okay"; }; -- GitLab From e2102cea9bced786a07ae5c244eff6e5e03376e3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 19 Jan 2016 10:06:21 +0100 Subject: [PATCH 0338/5324] arm64: dts: r8a7795: Complete SYS-DMAC nodes Complete the dma-controller nodes for SYS-DMAC 0 to 2. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 93 +++++++++++++++++++++++- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index bb353cde1253..221a8f5d24af 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -333,15 +333,102 @@ }; dmac0: dma-controller@e6700000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 219>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac1: dma-controller@e7300000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7300000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 218>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac2: dma-controller@e7310000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7310000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 217>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; avb: ethernet@e6800000 { -- GitLab From 406663ed61c8ad2b792824af1c1bc0e4faa711c6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 11 Jan 2016 19:41:14 +0100 Subject: [PATCH 0339/5324] ARM: shmobile: defconfig: Do not enable CONFIG_CPU_BPREDICT_DISABLE Do not disable branch prediction, as this has a big performance impact. After re-enabling branch prediction, __loop_delay() runs 16 (Cortex A15) or 11 (Cortex A9) times faster than before. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/shmobile_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 969738324a5d..5208b5caacd1 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -20,7 +20,6 @@ CONFIG_ARCH_R8A7791=y CONFIG_ARCH_R8A7793=y CONFIG_ARCH_R8A7794=y CONFIG_ARCH_SH73A0=y -CONFIG_CPU_BPREDICT_DISABLE=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y CONFIG_PCI=y -- GitLab From d7d5974b156e2ef7436483de00ccada5987c9d31 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 18 Nov 2015 14:20:34 -0800 Subject: [PATCH 0340/5324] ARM: dts: gose: Add GPIO keys to DT Instantiate the GPIO keys in the gose device tree. Based on similar work for the koelsch board by Laurent Pinchart. Signed-off-by: Simon Horman Tested-by: Magnus Damm --- arch/arm/boot/dts/r8a7793-gose.dts | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index baa59fe84298..ccbc1c66cc6c 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -31,6 +31,88 @@ device_type = "memory"; reg = <0 0x40000000 0 0x40000000>; }; + + gpio-keys { + compatible = "gpio-keys"; + + key-1 { + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-1"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-2 { + gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-2"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-3 { + gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-3"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-4 { + gpios = <&gpio5 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-4"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-a { + gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW30"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-b { + gpios = <&gpio7 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW31"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-c { + gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW32"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-d { + gpios = <&gpio7 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW33"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-e { + gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW34"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-f { + gpios = <&gpio7 5 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW35"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-g { + gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW36"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + }; }; &extal_clk { -- GitLab From 3b18d8593d4cb6880c6647c26ccfcd3eb5a849d9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 18 Nov 2015 14:20:35 -0800 Subject: [PATCH 0341/5324] ARM: dts: gose: Add GPIO leds to DT Instantiate the GPIO leds in the gose device tree. Based on similar work for the koelsch board by Magnus Damm. Signed-off-by: Simon Horman Tested-by: Magnus Damm --- arch/arm/boot/dts/r8a7793-gose.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index ccbc1c66cc6c..90b587c3c736 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -113,6 +113,22 @@ debounce-interval = <20>; }; }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + label = "LED6"; + }; + led7 { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + label = "LED7"; + }; + led8 { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + label = "LED8"; + }; + }; }; &extal_clk { -- GitLab From c5af8a4248d3cb01078d2a20df28081dd588b0e3 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 25 Dec 2015 01:45:30 +0300 Subject: [PATCH 0342/5324] ARM: dts: porter: add DU DT support Define the Porter board dependent part of the DU device node. Add the device node for Analog Devices ADV7511W HDMI transmitter to I2C2 bus and the HDMI connector. Add the necessary subnodes to interconnect DU and HDMI devices. Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-porter.dts | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 6713b1ea732b..fe81fa0e478c 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -78,6 +78,29 @@ states = <3300000 1 1800000 0>; }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x16_clk: x16-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; }; &extal_clk { @@ -139,6 +162,11 @@ renesas,groups = "can0_data"; renesas,function = "can0"; }; + + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; }; &scif0 { @@ -241,6 +269,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &sata0 { @@ -304,3 +364,24 @@ status = "okay"; }; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7791_CLK_DU0>, + <&mstp7_clks R8A7791_CLK_DU1>, + <&mstp7_clks R8A7791_CLK_LVDS0>, + <&x3_clk>, <&x16_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@1 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + }; +}; -- GitLab From 7aed17f4450ba6863937797d88dab64088f38ccc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 28 Dec 2015 12:40:21 +0200 Subject: [PATCH 0343/5324] ARM: dts: r8a7793: Add I2C master nodes to DT Instantiate all the 9 I2C controllers in the disabled state. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 135 ++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index aef9e69d6c26..f9d92de4f65b 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -19,6 +19,15 @@ #size-cells = <2>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; spi0 = &qspi; }; @@ -230,6 +239,120 @@ power-domains = <&cpg_clocks>; }; + /* The memory map in the User's Manual maps the cores to bus numbers */ + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6508000 0 0x40>; + interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C0>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6518000 0 0x40>; + interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C1>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6530000 0 0x40>; + interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C2>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6540000 0 0x40>; + interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C3>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c4: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6520000 0 0x40>; + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C4>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c5: i2c@e6528000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6528000 0 0x40>; + interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_I2C5>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <110>; + status = "disabled"; + }; + + i2c6: i2c@e60b0000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe60b0000 0 0x425>; + interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7793_CLK_IICDVFS>; + dmas = <&dmac0 0x77>, <&dmac0 0x78>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c7: i2c@e6500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6500000 0 0x425>; + interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7793_CLK_IIC0>; + dmas = <&dmac0 0x61>, <&dmac0 0x62>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c8: i2c@e6510000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6510000 0 0x425>; + interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7793_CLK_IIC1>; + dmas = <&dmac0 0x65>, <&dmac0 0x66>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + pfc: pfc@e6060000 { compatible = "renesas,pfc-r8a7793"; reg = <0 0xe6060000 0 0x250>; @@ -820,19 +943,25 @@ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, - <&cpg_clocks R8A7793_CLK_QSPI>; + <&cpg_clocks R8A7793_CLK_QSPI>, <&hp_clk>, + <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, + <&hp_clk>, <&hp_clk>; #clock-cells = <1>; clock-indices = < R8A7793_CLK_GPIO7 R8A7793_CLK_GPIO6 R8A7793_CLK_GPIO5 R8A7793_CLK_GPIO4 R8A7793_CLK_GPIO3 R8A7793_CLK_GPIO2 R8A7793_CLK_GPIO1 R8A7793_CLK_GPIO0 - R8A7793_CLK_QSPI_MOD + R8A7793_CLK_QSPI_MOD R8A7793_CLK_I2C5 + R8A7793_CLK_IICDVFS R8A7793_CLK_I2C4 + R8A7793_CLK_I2C3 R8A7793_CLK_I2C2 + R8A7793_CLK_I2C1 R8A7793_CLK_I2C0 >; clock-output-names = "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0", - "qspi_mod"; + "qspi_mod", "i2c5", "i2c6", "i2c4", + "i2c3", "i2c2", "i2c1", "i2c0"; }; mstp11_clks: mstp11_clks@e615099c { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; -- GitLab From 6b78e6ae688b09aa75376537bcfa990c9d4eff07 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 4 Jan 2016 21:36:59 +1100 Subject: [PATCH 0344/5324] ARM: dts: alt: Add QSPI device to DT Enable the QSPI controller in the alt device tree. Based similar work for the silk board by by Vladimir Barinov and Sergei Shtylyov. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7794-alt.dts | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts index 2394e4883786..773f304d1142 100644 --- a/arch/arm/boot/dts/r8a7794-alt.dts +++ b/arch/arm/boot/dts/r8a7794-alt.dts @@ -138,6 +138,13 @@ status = "okay"; }; +&pfc { + qspi_pins: spi0 { + renesas,groups = "qspi_ctrl", "qspi_data4"; + renesas,function = "qspi"; + }; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -197,3 +204,42 @@ status = "okay"; }; + +&qspi { + pinctrl-0 = <&qspi_pins>; + pinctrl-names = "default"; + + status = "okay"; + + flash@0 { + compatible = "spansion,s25fl512s", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <30000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-cpol; + spi-cpha; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "loader"; + reg = <0x00000000 0x00040000>; + read-only; + }; + partition@40000 { + label = "system"; + reg = <0x00040000 0x00040000>; + read-only; + }; + partition@80000 { + label = "user"; + reg = <0x00080000 0x03f80000>; + }; + }; + }; +}; -- GitLab From d87ec94aee6dc62ed5db4cad7dba47006c0dd00e Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 4 Jan 2016 08:20:17 +1100 Subject: [PATCH 0345/5324] ARM: dts: r8a7790: use fallback usbhs compatibility string Use recently added fallback compatibility string in r8a7790 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7790.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 7dfd393bfc7e..4d9af0f46fab 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -746,7 +746,7 @@ }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7790"; + compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; -- GitLab From 8cf1d454b24961223fc3e8d26808d4f72b484a1b Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 4 Jan 2016 08:20:18 +1100 Subject: [PATCH 0346/5324] ARM: dts: r8a7791: use fallback usbhs compatibility string Use recently added fallback compatibility string in r8a7791 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7791.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 2a369ddcb6fd..829224d2a3ed 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -822,7 +822,7 @@ }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7791"; + compatible = "renesas,usbhs-r8a7791", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp7_clks R8A7791_CLK_HSUSB>; -- GitLab From 1472ffa81a9089af6250e299068f9a877369333f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 8 Dec 2015 14:24:50 +0900 Subject: [PATCH 0347/5324] ARM: dts: r8a7794: use fallback usbhs compatibility string Use recently added fallback compatibility string in r8a7794 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7794.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 6c78f1fae90f..f8cd3a0beebf 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -724,7 +724,7 @@ }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7794"; + compatible = "renesas,usbhs-r8a7794", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp7_clks R8A7794_CLK_HSUSB>; -- GitLab From cefe5a56d3ffcdad0c63dda37f90845f42518e0a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Jan 2016 09:15:41 +1100 Subject: [PATCH 0348/5324] ARM: dts: r8a7793: move dmac nodes Move dmac nodes in the r8a7793 device tree to match their location in the r8a7791 device tree to aid comparison between the device trees of these similar SoCs. Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 124 ++++++++++++++++----------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index f9d92de4f65b..0ce7cc420c9d 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -239,6 +239,68 @@ power-domains = <&cpg_clocks>; }; + dmac0: dma-controller@e6700000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x20000>; + interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH + 0 200 IRQ_TYPE_LEVEL_HIGH + 0 201 IRQ_TYPE_LEVEL_HIGH + 0 202 IRQ_TYPE_LEVEL_HIGH + 0 203 IRQ_TYPE_LEVEL_HIGH + 0 204 IRQ_TYPE_LEVEL_HIGH + 0 205 IRQ_TYPE_LEVEL_HIGH + 0 206 IRQ_TYPE_LEVEL_HIGH + 0 207 IRQ_TYPE_LEVEL_HIGH + 0 208 IRQ_TYPE_LEVEL_HIGH + 0 209 IRQ_TYPE_LEVEL_HIGH + 0 210 IRQ_TYPE_LEVEL_HIGH + 0 211 IRQ_TYPE_LEVEL_HIGH + 0 212 IRQ_TYPE_LEVEL_HIGH + 0 213 IRQ_TYPE_LEVEL_HIGH + 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC0>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <15>; + }; + + dmac1: dma-controller@e6720000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xe6720000 0 0x20000>; + interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH + 0 216 IRQ_TYPE_LEVEL_HIGH + 0 217 IRQ_TYPE_LEVEL_HIGH + 0 218 IRQ_TYPE_LEVEL_HIGH + 0 219 IRQ_TYPE_LEVEL_HIGH + 0 308 IRQ_TYPE_LEVEL_HIGH + 0 309 IRQ_TYPE_LEVEL_HIGH + 0 310 IRQ_TYPE_LEVEL_HIGH + 0 311 IRQ_TYPE_LEVEL_HIGH + 0 312 IRQ_TYPE_LEVEL_HIGH + 0 313 IRQ_TYPE_LEVEL_HIGH + 0 314 IRQ_TYPE_LEVEL_HIGH + 0 315 IRQ_TYPE_LEVEL_HIGH + 0 316 IRQ_TYPE_LEVEL_HIGH + 0 317 IRQ_TYPE_LEVEL_HIGH + 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC1>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <15>; + }; + /* The memory map in the User's Manual maps the cores to bus numbers */ i2c0: i2c@e6508000 { #address-cells = <1>; @@ -358,68 +420,6 @@ reg = <0 0xe6060000 0 0x250>; }; - dmac0: dma-controller@e6700000 { - compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; - reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "error", - "ch0", "ch1", "ch2", "ch3", - "ch4", "ch5", "ch6", "ch7", - "ch8", "ch9", "ch10", "ch11", - "ch12", "ch13", "ch14"; - clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC0>; - clock-names = "fck"; - power-domains = <&cpg_clocks>; - #dma-cells = <1>; - dma-channels = <15>; - }; - - dmac1: dma-controller@e6720000 { - compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; - reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "error", - "ch0", "ch1", "ch2", "ch3", - "ch4", "ch5", "ch6", "ch7", - "ch8", "ch9", "ch10", "ch11", - "ch12", "ch13", "ch14"; - clocks = <&mstp2_clks R8A7793_CLK_SYS_DMAC1>; - clock-names = "fck"; - power-domains = <&cpg_clocks>; - #dma-cells = <1>; - dma-channels = <15>; - }; - scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; -- GitLab From f6890af3ad2b6440d287c8ee97b3f38e18b0674e Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Jan 2016 09:16:20 +1100 Subject: [PATCH 0349/5324] ARM: dts: gose: add i2c2 bus to device tree Activate i2c2 bus in r8a7793/gose device tree. Based on similar work for the r8a7791/koelsch by Wolfram Sang. Acked-by: Geert Uytterhoeven Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 90b587c3c736..987ed03b1e02 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -136,6 +136,11 @@ }; &pfc { + i2c2_pins: i2c2 { + renesas,groups = "i2c2"; + renesas,function = "i2c2"; + }; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; @@ -234,3 +239,17 @@ }; }; }; + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <100000>; + + eeprom@50 { + compatible = "renesas,r1ex24002", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; -- GitLab From 3abb4d5fc3a1fbfdd414d50d9c1d01bfd453c4a9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 15 Jan 2016 11:44:15 +0900 Subject: [PATCH 0350/5324] ARM: dts: r8a7790: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7791 device tree. Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 368 ++++++++++++++++----------------- 1 file changed, 184 insertions(+), 184 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 4d9af0f46fab..cc7eccf0ada7 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -121,13 +121,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -140,7 +140,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 30>; @@ -153,7 +153,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 30>; @@ -166,7 +166,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -179,7 +179,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -192,7 +192,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -205,24 +205,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7790_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7790_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -235,14 +235,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7790_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -257,10 +257,10 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R8A7790_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -268,22 +268,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -299,22 +299,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -330,20 +330,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -359,20 +359,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -388,8 +388,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -400,8 +400,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -414,7 +414,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -426,7 +426,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -438,7 +438,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -450,7 +450,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -462,7 +462,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -475,7 +475,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -488,7 +488,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x425>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC2>; dmas = <&dmac0 0x69>, <&dmac0 0x6a>; dma-names = "tx", "rx"; @@ -501,7 +501,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -512,7 +512,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -525,7 +525,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>; dmas = <&dmac0 0xe1>, <&dmac0 0xe2>; dma-names = "tx", "rx"; @@ -543,7 +543,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -554,7 +554,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee120000 0 0x328>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI1>; dmas = <&dmac1 0xc9>, <&dmac1 0xca>; dma-names = "tx", "rx"; @@ -565,7 +565,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI2>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -576,7 +576,7 @@ sdhi3: sd@ee160000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI3>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -587,7 +587,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7790", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; clock-names = "sci_ick"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; @@ -599,7 +599,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7790", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>; clock-names = "sci_ick"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; @@ -611,7 +611,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7790", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>; clock-names = "sci_ick"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; @@ -623,7 +623,7 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a7790", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>; clock-names = "sci_ick"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; @@ -635,7 +635,7 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a7790", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>; clock-names = "sci_ick"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; @@ -647,7 +647,7 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a7790", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>; clock-names = "sci_ick"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; @@ -659,7 +659,7 @@ scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7790", "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; @@ -671,7 +671,7 @@ scif1: serial@e6e68000 { compatible = "renesas,scif-r8a7790", "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; @@ -683,7 +683,7 @@ hscif0: serial@e62c0000 { compatible = "renesas,hscif-r8a7790", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; @@ -695,7 +695,7 @@ hscif1: serial@e62c8000 { compatible = "renesas,hscif-r8a7790", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; @@ -707,7 +707,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7790"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -719,7 +719,7 @@ avb: ethernet@e6800000 { compatible = "renesas,etheravb-r8a7790"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -730,7 +730,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -739,7 +739,7 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -748,7 +748,7 @@ hsusb: usb@e6590000 { compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -783,7 +783,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -792,7 +792,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -801,7 +801,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -810,7 +810,7 @@ vin3: video@e6ef3000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef3000 0 0x1000>; - interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -819,7 +819,7 @@ vsp1@fe920000 { compatible = "renesas,vsp1"; reg = <0 0xfe920000 0 0x8000>; - interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>; power-domains = <&cpg_clocks>; @@ -832,7 +832,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -846,7 +846,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -860,7 +860,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -877,9 +877,9 @@ <0 0xfeb90000 0 0x1c>, <0 0xfeb94000 0 0x1c>; reg-names = "du", "lvds.0", "lvds.1"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>, - <0 269 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp7_clks R8A7790_CLK_DU0>, <&mstp7_clks R8A7790_CLK_DU1>, <&mstp7_clks R8A7790_CLK_DU2>, @@ -913,7 +913,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN0>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -924,7 +924,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN1>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -935,7 +935,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7790"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -1401,7 +1401,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7790", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1415,7 +1415,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1428,7 +1428,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1441,7 +1441,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1454,7 +1454,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6c90000 0 0x0064>; - interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>; dmas = <&dmac0 0x45>, <&dmac0 0x46>; dma-names = "tx", "rx"; @@ -1467,7 +1467,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7790"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1480,7 +1480,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1491,9 +1491,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1515,7 +1515,7 @@ device_type = "pci"; reg = <0 0xee0b0000 0 0xc00>, <0 0xee0a0000 0 0x1100>; - interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1526,9 +1526,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; }; pci2: pci@ee0d0000 { @@ -1538,7 +1538,7 @@ power-domains = <&cpg_clocks>; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; status = "disabled"; bus-range = <2 2>; @@ -1547,9 +1547,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1580,12 +1580,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1664,52 +1664,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1717,52 +1717,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; @@ -1772,8 +1772,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1781,7 +1781,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1789,8 +1789,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1798,7 +1798,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1806,8 +1806,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1815,7 +1815,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; -- GitLab From 386a9291134b55493b2af2bc1317eeeb05f8a49a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 15 Jan 2016 11:44:16 +0900 Subject: [PATCH 0351/5324] ARM: dts: r8a7791: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7791 device tree. Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 386 ++++++++++++++++----------------- 1 file changed, 193 insertions(+), 193 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 829224d2a3ed..6b3b02c0c58a 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -78,13 +78,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -97,7 +97,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -110,7 +110,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -123,7 +123,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -136,7 +136,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -149,7 +149,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -162,7 +162,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -175,7 +175,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -188,24 +188,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7791_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7791_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -218,14 +218,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7791_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -240,16 +240,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7791_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -257,22 +257,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -288,22 +288,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -319,20 +319,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -348,20 +348,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -377,8 +377,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -389,8 +389,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -404,7 +404,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -416,7 +416,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -428,7 +428,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -440,7 +440,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -452,7 +452,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C4>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -465,7 +465,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C5>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -478,7 +478,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -491,7 +491,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -504,7 +504,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -520,7 +520,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -533,7 +533,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -544,7 +544,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI1>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -555,7 +555,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI2>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -566,7 +566,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>; clock-names = "sci_ick"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; @@ -578,7 +578,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>; clock-names = "sci_ick"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; @@ -590,7 +590,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>; clock-names = "sci_ick"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; @@ -602,7 +602,7 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>; clock-names = "sci_ick"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; @@ -614,7 +614,7 @@ scifa4: serial@e6c78000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>; clock-names = "sci_ick"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; @@ -626,7 +626,7 @@ scifa5: serial@e6c80000 { compatible = "renesas,scifa-r8a7791", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>; clock-names = "sci_ick"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; @@ -638,7 +638,7 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a7791", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>; clock-names = "sci_ick"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; @@ -650,7 +650,7 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a7791", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>; clock-names = "sci_ick"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; @@ -662,7 +662,7 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a7791", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>; clock-names = "sci_ick"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; @@ -674,7 +674,7 @@ scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; @@ -686,7 +686,7 @@ scif1: serial@e6e68000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; @@ -698,7 +698,7 @@ scif2: serial@e6e58000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; @@ -710,7 +710,7 @@ scif3: serial@e6ea8000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; clock-names = "sci_ick"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; @@ -722,7 +722,7 @@ scif4: serial@e6ee0000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; clock-names = "sci_ick"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; @@ -734,7 +734,7 @@ scif5: serial@e6ee8000 { compatible = "renesas,scif-r8a7791", "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; clock-names = "sci_ick"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; @@ -746,7 +746,7 @@ hscif0: serial@e62c0000 { compatible = "renesas,hscif-r8a7791", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; @@ -758,7 +758,7 @@ hscif1: serial@e62c8000 { compatible = "renesas,hscif-r8a7791", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; @@ -770,7 +770,7 @@ hscif2: serial@e62d0000 { compatible = "renesas,hscif-r8a7791", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; @@ -782,7 +782,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7791"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -795,7 +795,7 @@ compatible = "renesas,etheravb-r8a7791", "renesas,etheravb-rcar-gen2"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -806,7 +806,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -815,7 +815,7 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -824,7 +824,7 @@ hsusb: usb@e6590000 { compatible = "renesas,usbhs-r8a7791", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -859,7 +859,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -868,7 +868,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -877,7 +877,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -886,7 +886,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -900,7 +900,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -914,7 +914,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -930,8 +930,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7791_CLK_DU0>, <&mstp7_clks R8A7791_CLK_DU1>, <&mstp7_clks R8A7791_CLK_LVDS0>; @@ -958,7 +958,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN0>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -969,7 +969,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN1>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -980,7 +980,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7791"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -1432,7 +1432,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7791", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1446,7 +1446,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1459,7 +1459,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1472,7 +1472,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1485,7 +1485,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7791"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1498,7 +1498,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1509,9 +1509,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1533,7 +1533,7 @@ device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1544,9 +1544,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1577,12 +1577,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1592,8 +1592,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1601,7 +1601,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1609,8 +1609,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1618,7 +1618,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1626,8 +1626,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1635,7 +1635,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1643,8 +1643,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1721,52 +1721,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1774,52 +1774,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; -- GitLab From 84e734f497cd48f60c16c400d14b8da08cd281dc Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 13 Jan 2016 02:06:08 +0300 Subject: [PATCH 0352/5324] ARM: dts: silk: add DU DT support Define the SILK board dependent part of the DU device node. Add the device nodes for the Analog Devices ADV7511W HDMI transmitter (connected to DU0) and ADV7123 video DAC (connected to DU1). Add the necessary subnodes to interconnect DU, HDMI/VDAC devices, and HDMI/VGA connectors. Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794-silk.dts | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts index 5153e3af25d9..98b8bcca84da 100644 --- a/arch/arm/boot/dts/r8a7794-silk.dts +++ b/arch/arm/boot/dts/r8a7794-silk.dts @@ -64,6 +64,61 @@ states = <3300000 1 1800000 0>; }; + + vga-encoder { + compatible = "adi,adv7123"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7123_in: endpoint { + remote-endpoint = <&du_out_rgb1>; + }; + }; + port@1 { + reg = <1>; + adv7123_out: endpoint { + remote-endpoint = <&vga_in>; + }; + }; + }; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + vga { + compatible = "vga-connector"; + + port { + vga_in: endpoint { + remote-endpoint = <&adv7123_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; }; &extal_clk { @@ -164,6 +219,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb0>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &mmcif0 { @@ -258,3 +345,25 @@ &usbphy { status = "okay"; }; + +&du { + status = "okay"; + + clocks = <&mstp7_clks R8A7794_CLK_DU0>, + <&mstp7_clks R8A7794_CLK_DU0>, + <&x2_clk>, <&x3_clk>; + clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + endpoint { + remote-endpoint = <&adv7123_in>; + }; + }; + }; +}; -- GitLab From 214e8481fe1fef5e88f80f0da6c9bfbd1963099f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 18 Jan 2016 14:18:43 +0900 Subject: [PATCH 0353/5324] ARM: dts: r8a7793: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7793 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7793.dtsi | 216 ++++++++++++++++----------------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 0ce7cc420c9d..ea1196b99d52 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -63,13 +63,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -82,7 +82,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -95,7 +95,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -108,7 +108,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -121,7 +121,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -134,7 +134,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -147,7 +147,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -160,7 +160,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -173,24 +173,24 @@ thermal@e61f0000 { compatible = "renesas,thermal-r8a7793", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7793_CLK_THERMAL>; power-domains = <&cpg_clocks>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7793_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -203,14 +203,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7793_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -225,16 +225,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7793_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -242,22 +242,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -273,22 +273,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -307,7 +307,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -319,7 +319,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -331,7 +331,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -343,7 +343,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -355,7 +355,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C4>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -368,7 +368,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7793"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_I2C5>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -381,7 +381,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -394,7 +394,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7793_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -407,7 +407,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7793_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -423,7 +423,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>; clock-names = "sci_ick"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; @@ -435,7 +435,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>; clock-names = "sci_ick"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; @@ -447,7 +447,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>; clock-names = "sci_ick"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; @@ -459,7 +459,7 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>; clock-names = "sci_ick"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; @@ -471,7 +471,7 @@ scifa4: serial@e6c78000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>; clock-names = "sci_ick"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; @@ -483,7 +483,7 @@ scifa5: serial@e6c80000 { compatible = "renesas,scifa-r8a7793", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>; clock-names = "sci_ick"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; @@ -495,7 +495,7 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a7793", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>; clock-names = "sci_ick"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; @@ -507,7 +507,7 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a7793", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>; clock-names = "sci_ick"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; @@ -519,7 +519,7 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a7793", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>; clock-names = "sci_ick"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; @@ -531,7 +531,7 @@ scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; @@ -543,7 +543,7 @@ scif1: serial@e6e68000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; @@ -555,7 +555,7 @@ scif2: serial@e6e58000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; @@ -567,7 +567,7 @@ scif3: serial@e6ea8000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; clock-names = "sci_ick"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; @@ -579,7 +579,7 @@ scif4: serial@e6ee0000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; clock-names = "sci_ick"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; @@ -591,7 +591,7 @@ scif5: serial@e6ee8000 { compatible = "renesas,scif-r8a7793", "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; clock-names = "sci_ick"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; @@ -603,7 +603,7 @@ hscif0: serial@e62c0000 { compatible = "renesas,hscif-r8a7793", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; @@ -615,7 +615,7 @@ hscif1: serial@e62c8000 { compatible = "renesas,hscif-r8a7793", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; @@ -627,7 +627,7 @@ hscif2: serial@e62d0000 { compatible = "renesas,hscif-r8a7793", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; @@ -639,7 +639,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7793"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7793_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -651,7 +651,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7793", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -667,8 +667,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7793_CLK_DU0>, <&mstp7_clks R8A7793_CLK_DU1>, <&mstp7_clks R8A7793_CLK_LVDS0>; @@ -978,8 +978,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -987,7 +987,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -995,8 +995,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1004,7 +1004,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1012,8 +1012,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1021,7 +1021,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1029,8 +1029,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; -- GitLab From 1eca825f5dfeeb657e99cb07b271602adec622a6 Mon Sep 17 00:00:00 2001 From: Hakjoo Kim Date: Sun, 15 Mar 2015 23:00:33 +0100 Subject: [PATCH 0354/5324] ARM: dts: Add pinctrl support to exynos5410 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the required pin configuration support to Exynos5410 using pinctrl interface. Signed-off-by: Hakjoo Kim [AF: Rebased, style changes] Signed-off-by: Andreas Färber Reviewed-by: Krzysztof Kozlowski Tested-by: Pavel Fedin [k.kozlowski: Move pinctrl nodes into soc node] Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5410-pinctrl.dtsi | 406 ++++++++++++++++++++++ arch/arm/boot/dts/exynos5410.dtsi | 36 ++ 2 files changed, 442 insertions(+) create mode 100644 arch/arm/boot/dts/exynos5410-pinctrl.dtsi diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi new file mode 100644 index 000000000000..f9aa6bb55464 --- /dev/null +++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi @@ -0,0 +1,406 @@ +/* + * Exynos5410 SoC pin-mux and pin-config device tree source + * + * Copyright (c) 2013 Hardkernel Co., Ltd. + * http://www.hardkernel.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +&pinctrl_0 { + gpa0: gpa0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa1: gpa1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa2: gpa2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb0: gpb0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb1: gpb1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb2: gpb2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb3: gpb3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc0: gpc0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc3: gpc3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc1: gpc1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc2: gpc2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm5: gpm5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpd1: gpd1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe0: gpe0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe1: gpe1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf0: gpf0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf1: gpf1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg0: gpg0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg1: gpg1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg2: gpg2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph0: gph0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph1: gph1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm7: gpm7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy0: gpy0 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy1: gpy1 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy2: gpy2 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy3: gpy3 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy4: gpy4 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy5: gpy5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy6: gpy6 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy7: gpy7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpx0: gpx0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <23 0>, + <24 0>, + <25 0>, + <25 1>, + <26 0>, + <26 1>, + <27 0>, + <27 1>; + }; + + gpx1: gpx1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <28 0>, + <28 1>, + <29 0>, + <29 1>, + <30 0>, + <30 1>, + <31 0>, + <31 1>; + }; + + gpx2: gpx2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpx3: gpx3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_1 { + gpj0: gpj0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj1: gpj1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj2: gpj2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj3: gpj3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj4: gpj4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk0: gpk0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk1: gpk1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk2: gpk2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk3: gpk3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_2 { + gpv0: gpv0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv1: gpv1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv2: gpv2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv3: gpv3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv4: gpv4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_3 { + gpz: gpz { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index fad0779b1b6e..b0a27c095e22 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -21,6 +21,10 @@ interrupt-parent = <&gic>; aliases { + pinctrl0 = &pinctrl_0; + pinctrl1 = &pinctrl_1; + pinctrl2 = &pinctrl_2; + pinctrl3 = &pinctrl_3; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -205,6 +209,36 @@ status = "disabled"; }; + pinctrl_0: pinctrl@13400000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x13400000 0x1000>; + interrupts = <0 45 0>; + + wakeup-interrupt-controller { + compatible = "samsung,exynos4210-wakeup-eint"; + interrupt-parent = <&gic>; + interrupts = <0 32 0>; + }; + }; + + pinctrl_1: pinctrl@14000000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x14000000 0x1000>; + interrupts = <0 46 0>; + }; + + pinctrl_2: pinctrl@10d10000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x10d10000 0x1000>; + interrupts = <0 50 0>; + }; + + pinctrl_3: pinctrl@03860000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x03860000 0x1000>; + interrupts = <0 47 0>; + }; + uart0: serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; @@ -233,3 +267,5 @@ }; }; }; + +#include "exynos5410-pinctrl.dtsi" -- GitLab From df4400acde0e96847c7a54bde19ebb039e0356cf Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Sat, 12 Dec 2015 13:13:58 +0530 Subject: [PATCH 0355/5324] ARM: dts: Add SROM device node for exynos4 Add device node of SROM controller for exynos4. CC: Rob Herring CC: Mark Rutland CC: Ian Campbell Signed-off-by: Pankaj Dubey Reviewed-by: Krzysztof Kozlowski Signed-off-by: Kukjin Kim [k.kozlowski: fixed size of mapped SROMC memory region] Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 045785c44c04..ca621a92319e 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -76,6 +76,11 @@ reg = <0x10000000 0x100>; }; + sromc@12570000 { + compatible = "samsung,exynos-srom"; + reg = <0x12570000 0x14>; + }; + mipi_phy: video-phy@10020710 { compatible = "samsung,s5pv210-mipi-video-phy"; #phy-cells = <1>; -- GitLab From c3ede5e0a3c149d289ea1828ec3d244bc643b0e9 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Sat, 12 Dec 2015 13:13:59 +0530 Subject: [PATCH 0356/5324] ARM: dts: Add SROM device node for exynos5 Add SROM controller device node for exynos5. CC: Rob Herring CC: Mark Rutland CC: Ian Campbell Signed-off-by: Pankaj Dubey Reviewed-by: Krzysztof Kozlowski Signed-off-by: Kukjin Kim [k.kozlowski: fixed size of mapped SROMC memory region] Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi index e2439e87ee4a..b61d1f637510 100644 --- a/arch/arm/boot/dts/exynos5.dtsi +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -30,6 +30,11 @@ reg = <0x10000000 0x100>; }; + sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + }; + combiner: interrupt-controller@10440000 { compatible = "samsung,exynos4210-combiner"; #interrupt-cells = <2>; -- GitLab From d2deef6c61e65d1e0cee40c1d74fa99007da8c84 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Mon, 16 Nov 2015 10:43:03 +0300 Subject: [PATCH 0357/5324] ARM: dts: Add SROM to exynos5410 This machine uses own SoC device tree file, add missing part. Signed-off-by: Pavel Fedin Reviewed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5410.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index fad0779b1b6e..66f7fc6e29ef 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -97,6 +97,11 @@ reg = <0x10000000 0x100>; }; + sromc: sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + }; + pmu_system_controller: system-controller@10040000 { compatible = "samsung,exynos5410-pmu", "syscon"; reg = <0x10040000 0x5000>; -- GitLab From a090435727f6ccf0c5e77793ca48681122e5b950 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Mon, 16 Nov 2015 10:43:05 +0300 Subject: [PATCH 0358/5324] ARM: dts: Add Ethernet chip to exynos5410-smdk5410 The chip is smsc9115, connected via SROMc bank 3. Additionally, some GPIO initialization is required. Signed-off-by: Pavel Fedin Reviewed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5410-smdk5410.dts | 41 +++++++++++++++++++++++ arch/arm/boot/dts/exynos5410.dtsi | 6 ++++ 2 files changed, 47 insertions(+) diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index cebeaab3abec..a731fbe28ebc 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5410.dtsi" +#include / { model = "Samsung SMDK5410 board based on EXYNOS5410"; compatible = "samsung,smdk5410", "samsung,exynos5410", "samsung,exynos5"; @@ -61,6 +62,46 @@ disable-wp; }; +&pinctrl_0 { + srom_ctl: srom-ctl { + samsung,pins = "gpy0-3", "gpy0-4", "gpy0-5", + "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3"; + samsung,pin-function = <2>; + samsung,pin-drv = <0>; + }; + + srom_ebi: srom-ebi { + samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3", + "gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7", + "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3", + "gpy5-4", "gpy5-5", "gpy5-6", "gpy5-7", + "gpy6-0", "gpy6-1", "gpy6-2", "gpy6-3", + "gpy6-4", "gpy6-5", "gpy6-6", "gpy6-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; +}; + +&sromc { + pinctrl-names = "default"; + pinctrl-0 = <&srom_ctl>, <&srom_ebi>; + + ethernet@3,0 { + compatible = "smsc,lan9115"; + reg = <3 0 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gpx0>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + reg-io-width = <2>; + smsc,irq-push-pull; + smsc,force-internal-phy; + + samsung,srom-page-mode = <1>; + samsung,srom-timing = <9 12 1 9 1 1>; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index 88f6a1be0593..f3490f567344 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -104,6 +104,12 @@ sromc: sromc@12250000 { compatible = "samsung,exynos-srom"; reg = <0x12250000 0x14>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x04000000 0x20000 + 1 0 0x05000000 0x20000 + 2 0 0x06000000 0x20000 + 3 0 0x07000000 0x20000>; }; pmu_system_controller: system-controller@10040000 { -- GitLab From 8904305a473ff342bd03838ed012f5b65829048c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 4 Jan 2016 10:33:24 +0900 Subject: [PATCH 0359/5324] ARM: exynos_defconfig: Enable NEON, accelerated crypto and cpufreq stats Enable the kernel NEON mode and asm/NEON accelerated crypto algorithms which should bring performance benefits on Exynos SoCs. Enable these as modules because they are optional, not essential anyhow for platform booting nor related directly to Exynos Soc. All accelerated algorithms pass booting self-tests on Odroid XU4 (Exynos5422) and Trats2 (Exynos4412). Additionally enable cpufreq statistics as they are useful for debugging. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Anand Moon Reviewed-by: Javier Martinez Canillas --- arch/arm/configs/exynos_defconfig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 24dcd2bb1215..0aee1e035be9 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -26,12 +26,14 @@ CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y CONFIG_CPU_IDLE=y CONFIG_ARM_EXYNOS_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -238,7 +240,11 @@ CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y -CONFIG_CRYPTO_SHA256=y +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRC_CCITT=y CONFIG_FONTS=y CONFIG_FONT_7x14=y -- GitLab From 2c658a730083fd84729e30a7c5b3c045347c391a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 7 Jan 2016 10:26:36 +0900 Subject: [PATCH 0360/5324] ARM: exynos_defconfig: Enable s5p-secss driver The Exynos SoC provides a Security SubSystem block for accelerating some cryptographic operations. Enable the driver for it - s5p-secss to utilize the hardware acceleration. Currently the s5p-secss driver supports AES in CBC and ECB modes. However on Odroid XU4 (Exynos5422) and Trats2 (Exynos4412) boards this change introduces one booting error (because of unaligned buffers): alg: skcipher: encryption failed on chunk test 1 for ecb-aes-s5p: ret=22 The cbc-aes-s5p properly registers itself and passes self-tests. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Anand Moon Reviewed-by: Javier Martinez Canillas --- arch/arm/configs/exynos_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 0aee1e035be9..c47c7e069873 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -240,6 +240,7 @@ CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y +CONFIG_CRYPTO_DEV_S5P=y CONFIG_ARM_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM_NEON=m CONFIG_CRYPTO_SHA256_ARM=m -- GitLab From 9b3f105ef6c75ef4f7f1bd982195db814830d78b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 17 Sep 2015 08:04:51 +0900 Subject: [PATCH 0361/5324] cpufreq: s5pv210: remove superfluous CONFIG_PM ifdefs CONFIG_PM ifdefs are superfluous and can be removed. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Viresh Kumar Signed-off-by: Kukjin Kim Signed-off-by: Krzysztof Kozlowski --- drivers/cpufreq/s5pv210-cpufreq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 051a8a8224cd..a145b319d171 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -576,10 +576,8 @@ static struct cpufreq_driver s5pv210_driver = { .get = cpufreq_generic_get, .init = s5pv210_cpu_init, .name = "s5pv210", -#ifdef CONFIG_PM .suspend = cpufreq_generic_suspend, .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ -#endif }; static struct notifier_block s5pv210_cpufreq_reboot_notifier = { -- GitLab From cb4f2d7537686e6b0bfad0bc433d1cbd68a7eb08 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 11 Jan 2016 20:40:28 +0900 Subject: [PATCH 0362/5324] ARM: dts: Allow simultaneous usage exynos-rng and s5p-sss drivers on exynos5 The s5p-sss crypto HW acceleration driver supports only AES algorithms thus it accesses only registers from feeder (offset 0x0, length 0x100) and AES (offset 0x200, length 0x100) blocks of Security SubSystem (SSS). The exynos-rng Pseudo Random Number Generator driver accesses only PRNG block at offset 0x400 (length 0x100). Narrow the size of memory mapped by s5p-sss driver so both drivers can be loaded at the same time. Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5250.dtsi | 2 +- arch/arm/boot/dts/exynos5420.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 33e2d5f7315b..234403422c6f 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -807,7 +807,7 @@ sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 48a0a55314f5..7c8a606d65aa 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -859,7 +859,7 @@ sss: sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; -- GitLab From 40f8cf4b5cb606c593be25cbf71c34d505815b90 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 22 Jan 2016 08:53:45 +0100 Subject: [PATCH 0363/5324] drm/fbdev-helper: Explain how to debug console_lock fun Every new KMS driver writer seems to run into this and wonder how exactly drm_fb_helper_initial_config can die doing nothing at all. Set up some big warnings signs around this newbie trap to avoid future frustration and wasting everyone's time. v2: Edits from Laurent. Cc: Carlos Palminha Cc: Xinliang Liu Cc: laurent.pinchart@ideasonboard.com Reviewed-by: Laurent Pinchart Link: http://patchwork.freedesktop.org/patch/msgid/1453449225-10954-1-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 1e103c4c6ee0..76a364e62081 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2091,6 +2091,27 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) * drm_fb_helper_fill_fix() are provided as helpers to setup simple default * values for the fbdev info structure. * + * HANG DEBUGGING: + * + * When you have fbcon support built-in or already loaded, this function will do + * a full modeset to setup the fbdev console. Due to locking misdesign in the + * VT/fbdev subsystem that entire modeset sequence has to be done while holding + * console_lock. Until console_unlock is called no dmesg lines will be sent out + * to consoles, not even serial console. This means when your driver crashes, + * you will see absolutely nothing else but a system stuck in this function, + * with no further output. Any kind of printk() you place within your own driver + * or in the drm core modeset code will also never show up. + * + * Standard debug practice is to run the fbcon setup without taking the + * console_lock as a hack, to be able to see backtraces and crashes on the + * serial line. This can be done by setting the fb.lockless_register_fb=1 kernel + * cmdline option. + * + * The other option is to just disable fbdev emulation since very likely the + * first modest from userspace will crash in the same way, and is even easier to + * debug. This can be done by setting the drm_kms_helper.fbdev_emulation=0 + * kernel cmdline option. + * * RETURNS: * Zero if everything went ok, nonzero otherwise. */ -- GitLab From bcb877e4dcf21c3ba486fd7cc563126f08c39b8a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:40:55 +0100 Subject: [PATCH 0364/5324] drm: kerneldoc for drm_fops.c Just prep work before I throw more drm_event refactorings on top. Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-2-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- Documentation/DocBook/gpu.tmpl | 48 +----------- drivers/gpu/drm/drm_fops.c | 129 +++++++++++++++++++++++++++------ include/drm/drmP.h | 17 ++--- 3 files changed, 117 insertions(+), 77 deletions(-) diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index a8669330b456..12731c296ff1 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -2886,52 +2886,8 @@ void (*postclose) (struct drm_device *, struct drm_file *); File Operations - const struct file_operations *fops - File operations for the DRM device node. - - Drivers must define the file operations structure that forms the DRM - userspace API entry point, even though most of those operations are - implemented in the DRM core. The open, - release and ioctl - operations are handled by - - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - #ifdef CONFIG_COMPAT - .compat_ioctl = drm_compat_ioctl, - #endif - - - - Drivers that implement private ioctls that requires 32/64bit - compatibility support must provide their own - compat_ioctl handler that processes private - ioctls and calls drm_compat_ioctl for core ioctls. - - - The read and poll - operations provide support for reading DRM events and polling them. They - are implemented by - - .poll = drm_poll, - .read = drm_read, - .llseek = no_llseek, - - - - The memory mapping implementation varies depending on how the driver - manages memory. Pre-GEM drivers will use drm_mmap, - while GEM-aware drivers will use drm_gem_mmap. See - . - - .mmap = drm_gem_mmap, - - - - No other file operation is supported by the DRM API. - +!Pdrivers/gpu/drm/drm_fops.c file operations +!Edrivers/gpu/drm/drm_fops.c IOCTLs diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 1ea8790e5090..1551d65db24e 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -1,4 +1,4 @@ -/** +/* * \file drm_fops.c * File operations for DRM * @@ -44,6 +44,46 @@ /* from BKL pushdown */ DEFINE_MUTEX(drm_global_mutex); +/** + * DOC: file operations + * + * Drivers must define the file operations structure that forms the DRM + * userspace API entry point, even though most of those operations are + * implemented in the DRM core. The mandatory functions are drm_open(), + * drm_read(), drm_ioctl() and drm_compat_ioctl if CONFIG_COMPAT is enabled. + * Drivers which implement private ioctls that require 32/64 bit compatibility + * support must provided their onw .compat_ioctl() handler that processes + * private ioctls and calls drm_compat_ioctl() for core ioctls. + * + * In addition drm_read() and drm_poll() provide support for DRM events. DRM + * events are a generic and extensible means to send asynchronous events to + * userspace through the file descriptor. They are used to send vblank event and + * page flip completions by the KMS API. But drivers can also use it for their + * own needs, e.g. to signal completion of rendering. + * + * The memory mapping implementation will vary depending on how the driver + * manages memory. Legacy drivers will use the deprecated drm_legacy_mmap() + * function, modern drivers should use one of the provided memory-manager + * specific implementations. For GEM-based drivers this is drm_gem_mmap(). + * + * No other file operations are supported by the DRM userspace API. Overall the + * following is an example #file_operations structure: + * + * static const example_drm_fops = { + * .owner = THIS_MODULE, + * .open = drm_open, + * .release = drm_release, + * .unlocked_ioctl = drm_ioctl, + * #ifdef CONFIG_COMPAT + * .compat_ioctl = drm_compat_ioctl, + * #endif + * .poll = drm_poll, + * .read = drm_read, + * .llseek = no_llseek, + * .mmap = drm_gem_mmap, + * }; + */ + static int drm_open_helper(struct file *filp, struct drm_minor *minor); static int drm_setup(struct drm_device * dev) @@ -67,15 +107,17 @@ static int drm_setup(struct drm_device * dev) } /** - * Open file. + * drm_open - open method for DRM file + * @inode: device inode + * @filp: file pointer. * - * \param inode device inode - * \param filp file pointer. - * \return zero on success or a negative number on failure. + * This function must be used by drivers as their .open() #file_operations + * method. It looks up the correct DRM device and instantiates all the per-file + * resources for it. + * + * RETURNS: * - * Searches the DRM device with the same minor number, calls open_helper(), and - * increments the device open count. If the open count was previous at zero, - * i.e., it's the first that the device is open, then calls setup(). + * 0 on success or negative errno value on falure. */ int drm_open(struct inode *inode, struct file *filp) { @@ -112,7 +154,7 @@ int drm_open(struct inode *inode, struct file *filp) } EXPORT_SYMBOL(drm_open); -/** +/* * Check whether DRI will run on this CPU. * * \return non-zero if the DRI will run on this CPU, or zero otherwise. @@ -125,7 +167,7 @@ static int drm_cpu_valid(void) return 1; } -/** +/* * drm_new_set_master - Allocate a new master object and become master for the * associated master realm. * @@ -179,7 +221,7 @@ int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) return ret; } -/** +/* * Called whenever a process opens /dev/drm. * * \param filp file pointer. @@ -333,7 +375,7 @@ static void drm_events_release(struct drm_file *file_priv) spin_unlock_irqrestore(&dev->event_lock, flags); } -/** +/* * drm_legacy_dev_reinit * * Reinitializes a legacy/ums drm device in it's lastclose function. @@ -350,7 +392,7 @@ static void drm_legacy_dev_reinit(struct drm_device *dev) dev->if_version = 0; } -/** +/* * Take down the DRM device. * * \param dev DRM device structure. @@ -387,16 +429,17 @@ int drm_lastclose(struct drm_device * dev) } /** - * Release file. + * drm_release - release method for DRM file + * @inode: device inode + * @filp: file pointer. * - * \param inode device inode - * \param file_priv DRM file private. - * \return zero on success or a negative number on failure. + * This function must be used by drivers as their .release() #file_operations + * method. It frees any resources associated with the open file, and if this is + * the last open file for the DRM device also proceeds to call drm_lastclose(). * - * If the hardware lock is held then free it, and take it again for the kernel - * context since it's necessary to reclaim buffers. Unlink the file private - * data from its list and free it. Decreases the open count and if it reaches - * zero calls drm_lastclose(). + * RETURNS: + * + * Always succeeds and returns 0. */ int drm_release(struct inode *inode, struct file *filp) { @@ -451,7 +494,7 @@ int drm_release(struct inode *inode, struct file *filp) if (file_priv->is_master) { struct drm_master *master = file_priv->master; - /** + /* * Since the master is disappearing, so is the * possibility to lock. */ @@ -508,6 +551,32 @@ int drm_release(struct inode *inode, struct file *filp) } EXPORT_SYMBOL(drm_release); +/** + * drm_read - read method for DRM file + * @filp: file pointer + * @buffer: userspace destination pointer for the read + * @count: count in bytes to read + * @offset: offset to read + * + * This function must be used by drivers as their .read() #file_operations + * method iff they use DRM events for asynchronous signalling to userspace. + * Since events are used by the KMS API for vblank and page flip completion this + * means all modern display drivers must use it. + * + * @offset is ignore, DRM events are read like a pipe. Therefore drivers also + * must set the .llseek() #file_operation to no_llseek(). Polling support is + * provided by drm_poll(). + * + * This function will only ever read a full event. Therefore userspace must + * supply a big enough buffer to fit any event to ensure forward progress. Since + * the maximum event space is currently 4K it's recommended to just use that for + * safety. + * + * RETURNS: + * + * Number of bytes read (always aligned to full events, and can be 0) or a + * negative error code on failure. + */ ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset) { @@ -578,6 +647,22 @@ ssize_t drm_read(struct file *filp, char __user *buffer, } EXPORT_SYMBOL(drm_read); +/** + * drm_poll - poll method for DRM file + * @filp: file pointer + * @wait: poll waiter table + * + * This function must be used by drivers as their .read() #file_operations + * method iff they use DRM events for asynchronous signalling to userspace. + * Since events are used by the KMS API for vblank and page flip completion this + * means all modern display drivers must use it. + * + * See also drm_read(). + * + * RETURNS: + * + * Mask of POLL flags indicating the current status of the file. + */ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) { struct drm_file *file_priv = filp->private_data; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d7162cf1c3e1..a46a34fc67b3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -919,15 +919,14 @@ extern long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); - /* Device support (drm_fops.h) */ -extern int drm_open(struct inode *inode, struct file *filp); -extern ssize_t drm_read(struct file *filp, char __user *buffer, - size_t count, loff_t *offset); -extern int drm_release(struct inode *inode, struct file *filp); -extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); - - /* Mapping support (drm_vm.h) */ -extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); +/* File Operations (drm_fops.c) */ +int drm_open(struct inode *inode, struct file *filp); +ssize_t drm_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset); +int drm_release(struct inode *inode, struct file *filp); +int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); + +unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); /* Misc. IOCTL support (drm_ioctl.c) */ int drm_noop(struct drm_device *dev, void *data, -- GitLab From 2dd500f1870e3d852488c9b30c4ecec91c6e2eea Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:40:56 +0100 Subject: [PATCH 0365/5324] drm: Add functions to setup/tear down drm_events. An attempt at not spreading out the file_priv->event_space stuff out quite so far and wide. And I think fixes something in ipp_get_event() that is broken (or if they are doing something more weird/subtle, then breaks it in a fun way). Based upon a patch from Rob Clark, rebased and polished. v2: Spelling fixes (Alex). Cc: Alex Deucher Acked-by: Daniel Stone Reviewed-by: Alex Deucher Cc: Rob Clark Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-3-git-send-email-daniel.vetter@ffwll.ch Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_atomic.c | 44 ++++++----------------- drivers/gpu/drm/drm_crtc.c | 36 ++++++------------- drivers/gpu/drm/drm_fops.c | 67 ++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 7 +++- 4 files changed, 94 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3f74193885f1..8fb469c4e4b8 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1347,44 +1347,23 @@ static struct drm_pending_vblank_event *create_vblank_event( struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) { struct drm_pending_vblank_event *e = NULL; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - if (file_priv->event_space < sizeof e->event) { - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } - file_priv->event_space -= sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); + int ret; e = kzalloc(sizeof *e, GFP_KERNEL); - if (e == NULL) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } + if (!e) + return NULL; e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof e->event; + e->event.base.length = sizeof(e->event); e->event.user_data = user_data; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; - -out: - return e; -} -static void destroy_vblank_event(struct drm_device *dev, - struct drm_file *file_priv, struct drm_pending_vblank_event *e) -{ - unsigned long flags; + ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); + if (ret) { + kfree(e); + return NULL; + } - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); + return e; } static int atomic_set_prop(struct drm_atomic_state *state, @@ -1646,8 +1625,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, if (!crtc_state->event) continue; - destroy_vblank_event(dev, file_priv, - crtc_state->event); + drm_event_cancel_free(dev, &crtc_state->event->base); } } diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d40bab29747e..6e6514ef9968 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -5265,7 +5265,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, struct drm_crtc *crtc; struct drm_framebuffer *fb = NULL; struct drm_pending_vblank_event *e = NULL; - unsigned long flags; int ret = -EINVAL; if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || @@ -5316,41 +5315,26 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, } if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - ret = -ENOMEM; - spin_lock_irqsave(&dev->event_lock, flags); - if (file_priv->event_space < sizeof(e->event)) { - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } - file_priv->event_space -= sizeof(e->event); - spin_unlock_irqrestore(&dev->event_lock, flags); - - e = kzalloc(sizeof(*e), GFP_KERNEL); - if (e == NULL) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof(e->event); - spin_unlock_irqrestore(&dev->event_lock, flags); + e = kzalloc(sizeof *e, GFP_KERNEL); + if (!e) { + ret = -ENOMEM; goto out; } - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; e->event.base.length = sizeof(e->event); e->event.user_data = page_flip->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = - (void (*) (struct drm_pending_event *)) kfree; + ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); + if (ret) { + kfree(e); + goto out; + } } crtc->primary->old_fb = crtc->primary->fb; ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof(e->event); - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - } + if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) + drm_event_cancel_free(dev, &e->base); /* Keep the old fb, don't unref it. */ crtc->primary->old_fb = NULL; } else { diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 1551d65db24e..f9eacbb2d1dd 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -676,3 +676,70 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) return mask; } EXPORT_SYMBOL(drm_poll); + +/** + * drm_event_reserve_init - init a DRM event and reserve space for it + * @dev: DRM device + * @file_priv: DRM file private data + * @p: tracking structure for the pending event + * @e: actual event data to deliver to userspace + * + * This function prepares the passed in event for eventual delivery. If the event + * doesn't get delivered (because the IOCTL fails later on, before queuing up + * anything) then the even must be cancelled and freed using + * drm_event_cancel_free(). + * + * If callers embedded @p into a larger structure it must be allocated with + * kmalloc and @p must be the first member element. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ +int drm_event_reserve_init(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_pending_event *p, + struct drm_event *e) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&dev->event_lock, flags); + + if (file_priv->event_space < e->length) { + ret = -ENOMEM; + goto out; + } + + file_priv->event_space -= e->length; + + p->event = e; + p->file_priv = file_priv; + + /* we *could* pass this in as arg, but everyone uses kfree: */ + p->destroy = (void (*) (struct drm_pending_event *)) kfree; + +out: + spin_unlock_irqrestore(&dev->event_lock, flags); + return ret; +} +EXPORT_SYMBOL(drm_event_reserve_init); + +/** + * drm_event_cancel_free - free a DRM event and release it's space + * @dev: DRM device + * @p: tracking structure for the pending event + * + * This function frees the event @p initialized with drm_event_reserve_init() + * and releases any allocated space. + */ +void drm_event_cancel_free(struct drm_device *dev, + struct drm_pending_event *p) +{ + unsigned long flags; + spin_lock_irqsave(&dev->event_lock, flags); + p->file_priv->event_space += p->event->length; + spin_unlock_irqrestore(&dev->event_lock, flags); + p->destroy(p); +} +EXPORT_SYMBOL(drm_event_cancel_free); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index a46a34fc67b3..04a66468e6e0 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -925,8 +925,13 @@ ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset); int drm_release(struct inode *inode, struct file *filp); int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); - unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); +int drm_event_reserve_init(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_pending_event *p, + struct drm_event *e); +void drm_event_cancel_free(struct drm_device *dev, + struct drm_pending_event *p); /* Misc. IOCTL support (drm_ioctl.c) */ int drm_noop(struct drm_device *dev, void *data, -- GitLab From 7142a348e7714102ec705cca5fa2e092f29f4834 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:40:57 +0100 Subject: [PATCH 0366/5324] drm/exynos: Use the new event init/free functions Also fixes a bug in IPP with not correctly checking/allocating for space in the event space. Not a too serious bug since it's not a real ringbuffer, just a limit to avoid too much kernel allocations. Cc: Rob Clark Cc: Inki Dae Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-4-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 31 +++++++------------------ drivers/gpu/drm/exynos/exynos_drm_ipp.c | 23 +++++++----------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index c17efdb238a6..82e7f95dfed9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -1072,7 +1072,6 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, struct drm_exynos_pending_g2d_event *e; struct g2d_cmdlist_node *node; struct g2d_cmdlist *cmdlist; - unsigned long flags; int size; int ret; @@ -1094,21 +1093,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, node->event = NULL; if (req->event_type != G2D_EVENT_NOT) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - if (file->event_space < sizeof(e->event)) { - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - ret = -ENOMEM; - goto err; - } - file->event_space -= sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - e = kzalloc(sizeof(*node->event), GFP_KERNEL); if (!e) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - ret = -ENOMEM; goto err; } @@ -1116,9 +1102,12 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, e->event.base.type = DRM_EXYNOS_G2D_EVENT; e->event.base.length = sizeof(e->event); e->event.user_data = req->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; + + ret = drm_event_reserve_init(drm_dev, file, &e->base, &e->event.base); + if (ret) { + kfree(e); + goto err; + } node->event = e; } @@ -1219,12 +1208,8 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, err_unmap: g2d_unmap_cmdlist_gem(g2d, node, file); err_free_event: - if (node->event) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - kfree(node->event); - } + if (node->event) + drm_event_cancel_free(drm_dev, &node->event->base); err: g2d_put_cmdlist(g2d, node); return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 67d24236e745..c8819c05e2dd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -618,27 +618,18 @@ static void ipp_clean_mem_nodes(struct drm_device *drm_dev, mutex_unlock(&c_node->mem_lock); } -static void ipp_free_event(struct drm_pending_event *event) -{ - kfree(event); -} - static int ipp_get_event(struct drm_device *drm_dev, struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf) { struct drm_exynos_ipp_send_event *e; - unsigned long flags; + int ret; DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id); e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - c_node->filp->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + if (!e) return -ENOMEM; - } /* make event */ e->event.base.type = DRM_EXYNOS_IPP_EVENT; @@ -646,9 +637,13 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.user_data = qbuf->user_data; e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; - e->base.event = &e->event.base; - e->base.file_priv = c_node->filp; - e->base.destroy = ipp_free_event; + + ret = drm_event_reserve_init(drm_dev, c_node->filp, &e->base, &e->event.base); + if (ret) { + kfree(e); + return ret; + } + mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list); mutex_unlock(&c_node->event_lock); -- GitLab From 6d3729ac1332e3b63b7a140d29fb60ef77d61af6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:40:58 +0100 Subject: [PATCH 0367/5324] drm/vmwgfx: Use the new event init/free functions Cc: Rob Clark Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-5-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 32 +++++++-------------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 8e689b439890..eda93bf52a6e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -1025,38 +1025,26 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv, struct vmw_event_fence_pending *event; struct vmw_fence_manager *fman = fman_from_fence(fence); struct drm_device *dev = fman->dev_priv->dev; - unsigned long irq_flags; int ret; - spin_lock_irqsave(&dev->event_lock, irq_flags); - - ret = (file_priv->event_space < sizeof(event->event)) ? -EBUSY : 0; - if (likely(ret == 0)) - file_priv->event_space -= sizeof(event->event); - - spin_unlock_irqrestore(&dev->event_lock, irq_flags); - - if (unlikely(ret != 0)) { - DRM_ERROR("Failed to allocate event space for this file.\n"); - goto out_no_space; - } - - event = kzalloc(sizeof(*event), GFP_KERNEL); if (unlikely(event == NULL)) { DRM_ERROR("Failed to allocate an event.\n"); ret = -ENOMEM; - goto out_no_event; + goto out_no_space; } event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; event->event.base.length = sizeof(*event); event->event.user_data = user_data; - event->base.event = &event->event.base; - event->base.file_priv = file_priv; - event->base.destroy = (void (*) (struct drm_pending_event *)) kfree; + ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed to allocate event space for this file.\n"); + kfree(event); + goto out_no_space; + } if (flags & DRM_VMW_FE_FLAG_REQ_TIME) ret = vmw_event_fence_action_queue(file_priv, fence, @@ -1076,11 +1064,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv, return 0; out_no_queue: - event->base.destroy(&event->base); -out_no_event: - spin_lock_irqsave(&dev->event_lock, irq_flags); - file_priv->event_space += sizeof(*event); - spin_unlock_irqrestore(&dev->event_lock, irq_flags); + drm_event_cancel_free(dev, &event->base); out_no_space: return ret; } -- GitLab From dfa31117dbf01e0aac76674a87a103200347e220 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sat, 9 Jan 2016 13:54:18 +0100 Subject: [PATCH 0368/5324] ARM: dts: rockchip: Add the SDIO wifi on Radxa Rock2 square Enable the sdio0 slot on the Rock2 square which has a broadcom wifi chip attached and add a power sequence to enable the wifi chip and turn on the required 32k clock. Signed-off-by: Sjoerd Simons Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-rock2-square.dts | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index bcaf868a76bb..dd3ad2e93a6d 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -86,6 +86,15 @@ #sound-dai-cells = <0>; }; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; + }; + vcc_usb_host: vcc-host-regulator { compatible = "regulator-fixed"; enable-active-high; @@ -111,6 +120,21 @@ }; }; +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_18>; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; @@ -135,7 +159,7 @@ }; &i2c0 { - hym8563@51 { + hym8563: hym8563@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; @@ -177,6 +201,12 @@ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + sdio { + wifi_enable: wifi-enable { + rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; }; &spdif { -- GitLab From b662f6d03aeeb20c0f795f469341778f4577a6bf Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 21 Jan 2016 20:32:09 +0800 Subject: [PATCH 0369/5324] dt-bindings: rockchip-dw-mshc: add RK3368 dw-mshc description rk3368 dtsi file add dw-mshc compatible "rockchip,rk3368-dw-mshc" but didn't add it into rockchip-dw-mshc.txt. Signed-off-by: Shawn Lin Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 3dc13b68fc3f..634e2490795e 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -13,6 +13,7 @@ Required Properties: - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following, before RK3288 - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 + - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 Optional Properties: * clocks: from common clock binding: if ciu_drive and ciu_sample are -- GitLab From 296759c91e60c7fc84708d926161ee928697b0eb Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Thu, 21 Jan 2016 13:57:13 +0100 Subject: [PATCH 0370/5324] ARM: dts: rockchip: Bump sd card pin drive strength up on firefly boards It seems some firefly boards need 12mA drive strength for sdmmc. Using 4mA/8mA drive strength will cause the kernel to fail to recognize the sd card correctly. Increased the sdmmc lines drive strength from 4mA to 12mA. Signed-off-by: Wadim Egorov Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-firefly.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 4e3fd9aefe34..49ec20d24082 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -408,6 +408,11 @@ output-low; }; + pcfg_pull_up_drv_12ma: pcfg-pull-up-drv-12ma { + bias-pull-up; + drive-strength = <12>; + }; + act8846 { pwr_hold: pwr-hold { rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>; @@ -457,6 +462,25 @@ }; sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on firefly board so bump up to 12ma. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + sdmmc_pwr: sdmmc-pwr { rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; -- GitLab From 0082180c8dd22c3b813618882ec9629d94172214 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Thu, 14 Jan 2016 09:08:41 +0800 Subject: [PATCH 0371/5324] ARM: dts: rockchip: add soc-specific compatibles for rk3036 SoCs While drivers will bind to the generic compatible values, this enables the use of more specialized drivers in the future, if the need arises. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index ee457a2e997e..78974492cb11 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -161,7 +161,7 @@ }; usb_otg: usb@10180000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x10180000 0x40000>; interrupts = ; @@ -176,7 +176,7 @@ }; usb_host: usb@101c0000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x101c0000 0x40000>; interrupts = ; @@ -211,7 +211,7 @@ }; emmc: dwmmc@1021c000 { - compatible = "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x1021c000 0x4000>; interrupts = ; broken-cd; @@ -327,7 +327,7 @@ }; i2c1: i2c@20056000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20056000 0x1000>; interrupts = ; #address-cells = <1>; @@ -340,7 +340,7 @@ }; i2c2: i2c@2005a000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x2005a000 0x1000>; interrupts = ; #address-cells = <1>; @@ -395,7 +395,7 @@ }; i2c0: i2c@20072000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20072000 0x1000>; interrupts = ; #address-cells = <1>; -- GitLab From 63d8c7b9c32004506516f498fa05881c8d258442 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 13:55:00 +0800 Subject: [PATCH 0372/5324] clk: sunxi: usb: Sort clk providers by chip family and name The latest addition of H3 USB clocks placed them at the bottom. Move it before A80 (sun9i), so they are sorted by SoC family then name. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-usb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index 67b8e38f4ee9..5432b1c198a4 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -216,6 +216,18 @@ static void __init sun8i_a23_usb_setup(struct device_node *node) } CLK_OF_DECLARE(sun8i_a23_usb, "allwinner,sun8i-a23-usb-clk", sun8i_a23_usb_setup); +static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { + .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | + BIT(11) | BIT(10) | BIT(9) | BIT(8), + .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), +}; + +static void __init sun8i_h3_usb_setup(struct device_node *node) +{ + sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); +} +CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); + static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), .reset_mask = BIT(19) | BIT(18) | BIT(17), @@ -243,15 +255,3 @@ static void __init sun9i_a80_usb_phy_setup(struct device_node *node) sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); } CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); - -static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { - .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | - BIT(11) | BIT(10) | BIT(9) | BIT(8), - .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), -}; - -static void __init sun8i_h3_usb_setup(struct device_node *node) -{ - sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); -} -CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); -- GitLab From b7c9b91db202452ed91b0620b80a516093f71715 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 22 Jan 2016 19:02:29 +0900 Subject: [PATCH 0373/5324] clk: shmobile: r8a7795: Add USB3.0 clocks Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven --- drivers/clk/shmobile/r8a7795-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 13e994772dfd..fc260b3306aa 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -122,6 +122,8 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), -- GitLab From d056c9b81918675c6dedbfae042c2329effad786 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 8 Dec 2015 18:49:53 +0100 Subject: [PATCH 0374/5324] reset: remove unnecessary local variable initialization from of_reset_control_get_by_index There is no need to initialize rstc, as it is unconditionally assigned the return value of a kzalloc call before use. Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 87376638948d..4a63b379361c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(reset_control_status); struct reset_control *of_reset_control_get_by_index(struct device_node *node, int index) { - struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); + struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; struct of_phandle_args args; int rstc_id; -- GitLab From 203d4f347d86aa9e78342457aa7a3844c4fadd1d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Jan 2016 16:24:45 +0100 Subject: [PATCH 0375/5324] reset: Make reset_control_ops const The ops pointer is holding a pointer to a structure that is usually not modified. Make it const. Signed-off-by: Maxime Ripard Signed-off-by: Philipp Zabel --- include/linux/reset-controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index ce6b962ffed4..a3a5bcdb1d02 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -38,7 +38,7 @@ struct of_phandle_args; * @nr_resets: number of reset controls in this reset controller device */ struct reset_controller_dev { - struct reset_control_ops *ops; + const struct reset_control_ops *ops; struct module *owner; struct list_head list; struct device_node *of_node; -- GitLab From e677774f502635c70cb3180fc51ec7ff8c4b27ea Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 14 Jan 2016 16:24:44 +0100 Subject: [PATCH 0376/5324] reset: Move DT cell size check to the core The core currently doesn't check that the DT cell size matches what the driver declares, which means that every xlate function needs to duplicate that check. Make sure that of_reset_control_get checks for this to avoid duplication and errors. Signed-off-by: Maxime Ripard Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 4a63b379361c..f15f150b79da 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -45,9 +45,6 @@ struct reset_control { static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec) { - if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) - return -EINVAL; - if (reset_spec->args[0] >= rcdev->nr_resets) return -EINVAL; @@ -178,6 +175,11 @@ struct reset_control *of_reset_control_get_by_index(struct device_node *node, return ERR_PTR(-EPROBE_DEFER); } + if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { + mutex_unlock(&reset_controller_list_mutex); + return ERR_PTR(-EINVAL); + } + rstc_id = rcdev->of_xlate(rcdev, &args); if (rstc_id < 0) { mutex_unlock(&reset_controller_list_mutex); -- GitLab From c41ef91f65ea6151969dde699b206794772d407b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 24 Jan 2016 01:19:57 +0900 Subject: [PATCH 0377/5324] reset: hisilicon: check return value of reset_controller_register() The newly added hisilicon reset driver missed the subsystem-wide fixup by commit d1f15aa09558 ("reset: check return value of reset_controller_register()"). So fix it now. Signed-off-by: Masahiro Yamada Signed-off-by: Philipp Zabel --- drivers/reset/hisilicon/hi6220_reset.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 7787a9b1cc67..744b2e796442 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -83,9 +83,7 @@ static int hi6220_reset_probe(struct platform_device *pdev) data->rc_dev.ops = &hi6220_reset_ops; data->rc_dev.of_node = pdev->dev.of_node; - reset_controller_register(&data->rc_dev); - - return 0; + return reset_controller_register(&data->rc_dev); } static const struct of_device_id hi6220_reset_match[] = { -- GitLab From d566ebc3c06c17b108b5b844f9d08259e3b7ba84 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:00 -0800 Subject: [PATCH 0378/5324] clk: rockchip: rk3368: fix edp_24m parent The edp_24m parent select bit define is: 1'b0:xin24m 1'b1:1'b0(dummy) so adapt the parent sel bit to the currect one. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 7016ed24bbe5..dab759b2d18c 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -121,7 +121,7 @@ PNAME(mux_i2s_2ch_p) = { "i2s_2ch_src", "i2s_2ch_frac", "dummy", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "ext_i2s", "xin12m" }; -PNAME(mux_edp_24m_p) = { "dummy", "xin24m" }; +PNAME(mux_edp_24m_p) = { "xin24m", "dummy" }; PNAME(mux_vip_out_p) = { "vip_src", "xin24m" }; PNAME(mux_usbphy480m_p) = { "usbotg_out", "xin24m" }; PNAME(mux_hsic_usbphy480m_p) = { "usbotg_out", "dummy" }; -- GitLab From 0bbe62eb92755ff7c16c859e96a3877de56e32c9 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:01 -0800 Subject: [PATCH 0379/5324] clk: rockchip: rk3368: enable the CLK_SET_RATE_PARENT flag for spdif_8ch SPDIF_8CH set freq need to select parent and calculate parent freq. so just mark it as the CLK_SET_RATE_PARENT flag. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index dab759b2d18c..caf0b944d813 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -353,7 +353,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(32), 0, RK3368_CLKGATE_CON(6), 5, GFLAGS), - COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, + COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(31), 8, 2, MFLAGS, RK3368_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(0, "i2s_2ch_src", mux_pll_src_cpll_gpll_p, 0, -- GitLab From e8099067de751106d82333e29ce5b6a76ba653f6 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:02 -0800 Subject: [PATCH 0380/5324] clk: rockchip: rk3368: enable the CLK_SET_RATE_PARENT flag for i2s_2ch I2S_2CH set freq need to select parent and calculate parent freq. so just mark it as the CLK_SET_RATE_PARENT flag. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index caf0b944d813..e90abe8bf7c0 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -362,7 +362,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(54), 0, RK3368_CLKGATE_CON(5), 14, GFLAGS), - COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, 0, + COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(53), 8, 2, MFLAGS, RK3368_CLKGATE_CON(5), 15, GFLAGS), -- GitLab From 90191625ec0d075ac0748181ae1b947b0b30297e Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 25 Jan 2016 15:33:43 +0800 Subject: [PATCH 0381/5324] arm64: dts: rockchip: add rk3368 tuning clk for emmc and sdmmc Add tuning clk for emmc and sdmmc, otherwise I get the following failure while enabling mmc-hs200-1_8v. dwmmc_rockchip ff0f0000.dwmmc: Tuning clock (sample_clk) not defined. mmc0: tuning execution failed mmc0: error -5 whilst initialising MMC card With it dwmmc_rockchip ff0f0000.dwmmc: Successfully tuned phase to 170 mmc0: new HS200 MMC card at address 0001 mmcblk0: mmc0:0001 M8G1GC 7.28 GiB Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3368.dtsi | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 122777b1441e..49d119103e31 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -231,8 +231,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0c0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; @@ -254,8 +255,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0f0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; -- GitLab From 77b04a0428ea83d000634f06eb3b37ee92d9f866 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Fri, 22 Jan 2016 12:42:47 +0000 Subject: [PATCH 0382/5324] drm/i915: More use of the cached LRC state Since: commit 82352e908acd36d7244c75a008c9f27a2ced44d5 Author: Tvrtko Ursulin Date: Fri Jan 15 17:12:45 2016 +0000 drm/i915: Cache LRC state page in the context and: commit 0eb973d31d0aadb6bc801fd6d796afecbbfc3d5b Author: Tvrtko Ursulin Date: Fri Jan 15 15:10:28 2016 +0000 drm/i915: Cache ringbuffer GTT VMA We can also remove the ring buffer start updates on every context update since the address will not change for the duration of the LRC pin. For GuC we can remove the update altogether because it only cares about the ring buffer start. Signed-off-by: Tvrtko Ursulin Cc: Alex Dai Cc: Dave Gordon Cc: Chris Wilson Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1453466567-33369-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 27 ---------------------- drivers/gpu/drm/i915/intel_lrc.c | 6 +++-- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 51ae5c1f806d..7a7e1e5d807b 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -560,29 +560,6 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc, return 0; } -#define CTX_RING_BUFFER_START 0x08 - -/* Update the ringbuffer pointer in a saved context image */ -static void lr_context_update(struct drm_i915_gem_request *rq) -{ - enum intel_ring_id ring_id = rq->ring->id; - struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring_id].state; - struct drm_i915_gem_object *rb_obj = rq->ringbuf->obj; - struct page *page; - uint32_t *reg_state; - - BUG_ON(!ctx_obj); - WARN_ON(!i915_gem_obj_is_pinned(ctx_obj)); - WARN_ON(!i915_gem_obj_is_pinned(rb_obj)); - - page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN); - reg_state = kmap_atomic(page); - - reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(rb_obj); - - kunmap_atomic(reg_state); -} - /** * i915_guc_submit() - Submit commands through GuC * @client: the guc client where commands will go through @@ -597,10 +574,6 @@ int i915_guc_submit(struct i915_guc_client *client, enum intel_ring_id ring_id = rq->ring->id; int q_ret, b_ret; - /* Need this because of the deferred pin ctx and ring */ - /* Shall we move this right after ring is pinned? */ - lr_context_update(rq); - q_ret = guc_add_workqueue_item(client, rq); if (q_ret == 0) b_ret = guc_ring_doorbell(client); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 73d4347429df..116c10f56e66 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -393,7 +393,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq) uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state; reg_state[CTX_RING_TAIL+1] = rq->tail; - reg_state[CTX_RING_BUFFER_START+1] = rq->ringbuf->vma->node.start; if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) { /* True 32b PPGTT with dynamic page allocation: update PDP @@ -1067,6 +1066,7 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; struct page *lrc_state_page; + uint32_t *lrc_reg_state; int ret; WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); @@ -1088,7 +1088,9 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); intel_lr_context_descriptor_update(ctx, ring); - ctx->engine[ring->id].lrc_reg_state = kmap(lrc_state_page); + lrc_reg_state = kmap(lrc_state_page); + lrc_reg_state[CTX_RING_BUFFER_START+1] = ringbuf->vma->node.start; + ctx->engine[ring->id].lrc_reg_state = lrc_reg_state; ctx_obj->dirty = true; /* Invalidate GuC TLB. */ -- GitLab From 397097b026190309f4eec630db0e2f5ba498542e Mon Sep 17 00:00:00 2001 From: Alex Dai Date: Sat, 23 Jan 2016 11:58:14 -0800 Subject: [PATCH 0383/5324] drm/i915/guc: Decouple GuC engine id from ring id Previously GuC uses ring id as engine id because of same definition. But this is not true since this commit: commit de1add360522c876c25ef2bbbbab1c94bdb509ab Author: Tvrtko Ursulin Date: Fri Jan 15 15:12:50 2016 +0000 drm/i915: Decouple execbuf uAPI from internal implementation Added GuC engine id into GuC interface to decouple it from ring id used by driver. v2: Keep ring name print out in debugfs; using for_each_ring() where possible to keep driver consistent. (Chris W.) Signed-off-by: Alex Dai Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1453579094-29860-1-git-send-email-yu.dai@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 12 +++---- drivers/gpu/drm/i915/i915_guc_submission.c | 38 ++++++++++------------ drivers/gpu/drm/i915/intel_guc.h | 6 ++-- drivers/gpu/drm/i915/intel_guc_fwif.h | 17 +++++++--- drivers/gpu/drm/i915/intel_lrc.c | 5 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c5db23511184..cea184459256 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2463,9 +2463,9 @@ static void i915_guc_client_info(struct seq_file *m, for_each_ring(ring, dev_priv, i) { seq_printf(m, "\tSubmissions: %llu %s\n", - client->submissions[i], + client->submissions[ring->guc_id], ring->name); - tot += client->submissions[i]; + tot += client->submissions[ring->guc_id]; } seq_printf(m, "\tTotal: %llu\n", tot); } @@ -2502,10 +2502,10 @@ static int i915_guc_info(struct seq_file *m, void *data) seq_printf(m, "\nGuC submissions:\n"); for_each_ring(ring, dev_priv, i) { - seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x %9d\n", - ring->name, guc.submissions[i], - guc.last_seqno[i], guc.last_seqno[i]); - total += guc.submissions[i]; + seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n", + ring->name, guc.submissions[ring->guc_id], + guc.last_seqno[ring->guc_id]); + total += guc.submissions[ring->guc_id]; } seq_printf(m, "\t%s: %llu\n", "Total", total); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 7a7e1e5d807b..d7543efc8a5e 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -376,6 +376,8 @@ static void guc_init_proc_desc(struct intel_guc *guc, static void guc_init_ctx_desc(struct intel_guc *guc, struct i915_guc_client *client) { + struct drm_i915_private *dev_priv = guc_to_i915(guc); + struct intel_engine_cs *ring; struct intel_context *ctx = client->owner; struct guc_context_desc desc; struct sg_table *sg; @@ -388,10 +390,8 @@ static void guc_init_ctx_desc(struct intel_guc *guc, desc.priority = client->priority; desc.db_id = client->doorbell_id; - for (i = 0; i < I915_NUM_RINGS; i++) { - struct guc_execlist_context *lrc = &desc.lrc[i]; - struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; - struct intel_engine_cs *ring; + for_each_ring(ring, dev_priv, i) { + struct guc_execlist_context *lrc = &desc.lrc[ring->guc_id]; struct drm_i915_gem_object *obj; uint64_t ctx_desc; @@ -406,7 +406,6 @@ static void guc_init_ctx_desc(struct intel_guc *guc, if (!obj) break; /* XXX: continue? */ - ring = ringbuf->ring; ctx_desc = intel_lr_context_descriptor(ctx, ring); lrc->context_desc = (u32)ctx_desc; @@ -414,16 +413,16 @@ static void guc_init_ctx_desc(struct intel_guc *guc, lrc->ring_lcra = i915_gem_obj_ggtt_offset(obj) + LRC_STATE_PN * PAGE_SIZE; lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) | - (ring->id << GUC_ELC_ENGINE_OFFSET); + (ring->guc_id << GUC_ELC_ENGINE_OFFSET); - obj = ringbuf->obj; + obj = ctx->engine[i].ringbuf->obj; lrc->ring_begin = i915_gem_obj_ggtt_offset(obj); lrc->ring_end = lrc->ring_begin + obj->base.size - 1; lrc->ring_next_free_location = lrc->ring_begin; lrc->ring_current_tail_pointer_value = 0; - desc.engines_used |= (1 << ring->id); + desc.engines_used |= (1 << ring->guc_id); } WARN_ON(desc.engines_used == 0); @@ -510,7 +509,6 @@ int i915_guc_wq_check_space(struct i915_guc_client *gc) static int guc_add_workqueue_item(struct i915_guc_client *gc, struct drm_i915_gem_request *rq) { - enum intel_ring_id ring_id = rq->ring->id; struct guc_wq_item *wqi; void *base; u32 tail, wq_len, wq_off, space; @@ -544,7 +542,7 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc, wq_len = sizeof(struct guc_wq_item) / sizeof(u32) - 1; wqi->header = WQ_TYPE_INORDER | (wq_len << WQ_LEN_SHIFT) | - (ring_id << WQ_TARGET_SHIFT) | + (rq->ring->guc_id << WQ_TARGET_SHIFT) | WQ_NO_WCFLUSH_WAIT; /* The GuC wants only the low-order word of the context descriptor */ @@ -571,14 +569,14 @@ int i915_guc_submit(struct i915_guc_client *client, struct drm_i915_gem_request *rq) { struct intel_guc *guc = client->guc; - enum intel_ring_id ring_id = rq->ring->id; + unsigned int engine_id = rq->ring->guc_id; int q_ret, b_ret; q_ret = guc_add_workqueue_item(client, rq); if (q_ret == 0) b_ret = guc_ring_doorbell(client); - client->submissions[ring_id] += 1; + client->submissions[engine_id] += 1; if (q_ret) { client->q_fail += 1; client->retcode = q_ret; @@ -588,8 +586,8 @@ int i915_guc_submit(struct i915_guc_client *client, } else { client->retcode = 0; } - guc->submissions[ring_id] += 1; - guc->last_seqno[ring_id] = rq->seqno; + guc->submissions[engine_id] += 1; + guc->last_seqno[engine_id] = rq->seqno; return q_ret; } @@ -821,7 +819,7 @@ static void init_guc_policies(struct guc_policies *policies) policies->max_num_work_items = POLICY_MAX_NUM_WI; for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) { - for (i = 0; i < I915_NUM_RINGS; i++) { + for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) { policy = &policies->policy[p][i]; policy->execution_quantum = 1000000; @@ -873,7 +871,7 @@ static void guc_create_ads(struct intel_guc *guc) ads->golden_context_lrca = ring->status_page.gfx_addr; for_each_ring(ring, dev_priv, i) - ads->eng_state_size[i] = intel_lr_context_size(ring); + ads->eng_state_size[ring->guc_id] = intel_lr_context_size(ring); /* GuC scheduling policies */ policies = (void *)ads + sizeof(struct guc_ads); @@ -885,12 +883,12 @@ static void guc_create_ads(struct intel_guc *guc) /* MMIO reg state */ reg_state = (void *)policies + sizeof(struct guc_policies); - for (i = 0; i < I915_NUM_RINGS; i++) { - reg_state->mmio_white_list[i].mmio_start = - dev_priv->ring[i].mmio_base + GUC_MMIO_WHITE_LIST_START; + for_each_ring(ring, dev_priv, i) { + reg_state->mmio_white_list[ring->guc_id].mmio_start = + ring->mmio_base + GUC_MMIO_WHITE_LIST_START; /* Nothing to be saved or restored for now. */ - reg_state->mmio_white_list[i].count = 0; + reg_state->mmio_white_list[ring->guc_id].count = 0; } ads->reg_state_addr = ads->scheduler_policies + diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 045b1491ff7a..73002e901ff2 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -46,7 +46,7 @@ struct i915_guc_client { uint32_t wq_head; /* GuC submission statistics & status */ - uint64_t submissions[I915_NUM_RINGS]; + uint64_t submissions[GUC_MAX_ENGINES_NUM]; uint32_t q_fail; uint32_t b_fail; int retcode; @@ -106,8 +106,8 @@ struct intel_guc { uint32_t action_fail; /* Total number of failures */ int32_t action_err; /* Last error code */ - uint64_t submissions[I915_NUM_RINGS]; - uint32_t last_seqno[I915_NUM_RINGS]; + uint64_t submissions[GUC_MAX_ENGINES_NUM]; + uint32_t last_seqno[GUC_MAX_ENGINES_NUM]; }; /* intel_guc_loader.c */ diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 1856a4740b83..2de57ffe5e18 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -44,6 +44,13 @@ #define GUC_MAX_GPU_CONTEXTS 1024 #define GUC_INVALID_CTX_ID GUC_MAX_GPU_CONTEXTS +#define GUC_RENDER_ENGINE 0 +#define GUC_VIDEO_ENGINE 1 +#define GUC_BLITTER_ENGINE 2 +#define GUC_VIDEOENHANCE_ENGINE 3 +#define GUC_VIDEO_ENGINE2 4 +#define GUC_MAX_ENGINES_NUM (GUC_VIDEO_ENGINE2 + 1) + /* Work queue item header definitions */ #define WQ_STATUS_ACTIVE 1 #define WQ_STATUS_SUSPENDED 2 @@ -285,7 +292,7 @@ struct guc_context_desc { u64 db_trigger_phy; u16 db_id; - struct guc_execlist_context lrc[I915_NUM_RINGS]; + struct guc_execlist_context lrc[GUC_MAX_ENGINES_NUM]; u8 attribute; @@ -344,7 +351,7 @@ struct guc_policy { } __packed; struct guc_policies { - struct guc_policy policy[GUC_CTX_PRIORITY_NUM][I915_NUM_RINGS]; + struct guc_policy policy[GUC_CTX_PRIORITY_NUM][GUC_MAX_ENGINES_NUM]; /* In micro seconds. How much time to allow before DPC processing is * called back via interrupt (to prevent DPC queue drain starving). @@ -388,14 +395,14 @@ struct guc_mmio_regset { struct guc_mmio_reg_state { struct guc_mmio_regset global_reg; - struct guc_mmio_regset engine_reg[I915_NUM_RINGS]; + struct guc_mmio_regset engine_reg[GUC_MAX_ENGINES_NUM]; /* MMIO registers that are set as non privileged */ struct __packed { u32 mmio_start; u32 offsets[GUC_MMIO_WHITE_LIST_MAX]; u32 count; - } mmio_white_list[I915_NUM_RINGS]; + } mmio_white_list[GUC_MAX_ENGINES_NUM]; } __packed; /* GuC Additional Data Struct */ @@ -406,7 +413,7 @@ struct guc_ads { u32 golden_context_lrca; u32 scheduler_policies; u32 reserved0[3]; - u32 eng_state_size[I915_NUM_RINGS]; + u32 eng_state_size[GUC_MAX_ENGINES_NUM]; u32 reserved2[4]; } __packed; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 116c10f56e66..da97bc5666b5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2088,6 +2088,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->name = "render ring"; ring->id = RCS; ring->exec_id = I915_EXEC_RENDER; + ring->guc_id = GUC_RENDER_ENGINE; ring->mmio_base = RENDER_RING_BASE; logical_ring_default_irqs(ring, GEN8_RCS_IRQ_SHIFT); @@ -2139,6 +2140,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->name = "bsd ring"; ring->id = VCS; ring->exec_id = I915_EXEC_BSD; + ring->guc_id = GUC_VIDEO_ENGINE; ring->mmio_base = GEN6_BSD_RING_BASE; logical_ring_default_irqs(ring, GEN8_VCS1_IRQ_SHIFT); @@ -2155,6 +2157,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->name = "bsd2 ring"; ring->id = VCS2; ring->exec_id = I915_EXEC_BSD; + ring->guc_id = GUC_VIDEO_ENGINE2; ring->mmio_base = GEN8_BSD2_RING_BASE; logical_ring_default_irqs(ring, GEN8_VCS2_IRQ_SHIFT); @@ -2171,6 +2174,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->name = "blitter ring"; ring->id = BCS; ring->exec_id = I915_EXEC_BLT; + ring->guc_id = GUC_BLITTER_ENGINE; ring->mmio_base = BLT_RING_BASE; logical_ring_default_irqs(ring, GEN8_BCS_IRQ_SHIFT); @@ -2187,6 +2191,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->name = "video enhancement ring"; ring->id = VECS; ring->exec_id = I915_EXEC_VEBOX; + ring->guc_id = GUC_VIDEOENHANCE_ENGINE; ring->mmio_base = VEBOX_RING_BASE; logical_ring_default_irqs(ring, GEN8_VECS_IRQ_SHIFT); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b12f2aabd104..566b0ae10ce0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -158,6 +158,7 @@ struct intel_engine_cs { #define I915_NUM_RINGS 5 #define _VCS(n) (VCS + (n)) unsigned int exec_id; + unsigned int guc_id; u32 mmio_base; struct drm_device *dev; struct intel_ringbuffer *buffer; -- GitLab From 6b7958f4bb834c6872118526f37900f17a4b5851 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 23 Dec 2015 16:26:54 +0100 Subject: [PATCH 0384/5324] ARM: mvebu: Add USB nop xceiv support in mvebu_v7_defconfig The Armada 38x based boards use this "PHY" with their xhci usb controller. It would be also used for Armada 39x and Armada 375 base boars which also had xhci controller. Signed-off-by: Gregory CLEMENT --- arch/arm/configs/mvebu_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index c6729bf0a8dd..cf363abd974e 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -109,6 +109,7 @@ CONFIG_USB_XHCI_MVEBU=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_STORAGE=y +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y -- GitLab From df5ea015984633526874619ca1288fc5f2cf47c0 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 25 Jan 2016 12:19:26 +0100 Subject: [PATCH 0385/5324] ARM: dts: rockchip: Assign RK3288 EDP_24M input centrally The EDP 24M clock can be fed either by an SoC internal fixed clock or from an external IC. Change the default parent to the internal clock in the main rk3288 dtsi, to ensure (by default) it gets setup with a non-orphaned clock (hardware defaults to the externa clock). This prevents potential issues when the clock framework get support for deferring on orphaned clocks, while specific boards can always change the parent clock if an external input is preferred. Signed-off-by: Sjoerd Simons Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-veyron.dtsi | 5 ----- arch/arm/boot/dts/rk3288.dtsi | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 9fce91ffff6f..5e61f07724d4 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -340,11 +340,6 @@ i2c-scl-rising-time-ns = <1000>; }; -&power { - assigned-clocks = <&cru SCLK_EDP_24M>; - assigned-clock-parents = <&xin24m>; -}; - &pwm1 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index f0a091949f42..c5d7e61c2272 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -630,6 +630,9 @@ #address-cells = <1>; #size-cells = <0>; + assigned-clocks = <&cru SCLK_EDP_24M>; + assigned-clock-parents = <&xin24m>; + /* * Note: Although SCLK_* are the working clocks * of device without including on the NOC, needed for -- GitLab From 219a5859c855b1e6e2663eb63a7f942a6bbdfb52 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:28 +0100 Subject: [PATCH 0386/5324] clk: rockchip: fix usbphy-related clocks The otgphy clocks really only drive the phy blocks. These in turn contain plls that then generate the 480m clocks the clock controller uses to supply some other clocks like uart0, gpu or the video-codec. So fix this structure to actually respect that hirarchy and removed that usb480m fixed-rate clock working as a placeholder till now, as this wouldn't even work if the supplying phy gets turned off while its pll-output gets used elsewhere. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Acked-by: Michael Turquette --- arch/arm/boot/dts/rk3288-veyron.dtsi | 2 +- drivers/clk/rockchip/clk-rk3188.c | 11 +++-------- drivers/clk/rockchip/clk-rk3288.c | 16 +++++----------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 9fce91ffff6f..cb27a8f5a8e2 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -421,7 +421,7 @@ status = "okay"; assigned-clocks = <&cru SCLK_USBPHY480M_SRC>; - assigned-clock-parents = <&cru SCLK_OTGPHY0>; + assigned-clock-parents = <&usbphy0>; dr_mode = "host"; }; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 7f7444cbf6fc..73954907111e 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -343,9 +343,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -662,7 +662,7 @@ static struct clk_div_table div_rk3188_aclk_core_t[] = { { /* sentinel */ }, }; -PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", +PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = @@ -769,11 +769,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) pr_warn("%s: could not register clock xin12m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 984fc187d12e..0d23937c594a 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,8 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", - "sclk_otgphy0" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", + "sclk_otgphy0_480m" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; @@ -537,11 +537,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), @@ -894,12 +894,6 @@ static void __init rk3288_clk_init(struct device_node *np) pr_warn("%s: could not register clock xin12m: %ld\n", __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", "hclk_vcodec_pre_v", 0, 1, 4); if (IS_ERR(clk)) -- GitLab From 0ace8217c242bb3b89263bb38d13ce52960d83d9 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:27 +0100 Subject: [PATCH 0387/5324] ARM: dts: rockchip: add clock-cells for usb phy nodes Add the #clock-cells properties for the usbphy nodes as they provide the pll-clocks now. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Reviewed-by: Michael Turquette Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 2 ++ arch/arm/boot/dts/rk3188.dtsi | 2 ++ arch/arm/boot/dts/rk3288.dtsi | 3 +++ 3 files changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 81cf60c42712..56922730d285 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -202,6 +202,7 @@ reg = <0x17c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -209,6 +210,7 @@ reg = <0x188>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 348d46b7ada5..9271833958f9 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -171,6 +171,7 @@ reg = <0x10c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -178,6 +179,7 @@ reg = <0x11c>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index c5d7e61c2272..6abbab67ce99 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -968,6 +968,7 @@ reg = <0x320>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -975,6 +976,7 @@ reg = <0x334>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy2: usb-phy2 { @@ -982,6 +984,7 @@ reg = <0x348>; clocks = <&cru SCLK_OTGPHY2>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; -- GitLab From 8c20b67f2873bffb37cb64b806af0aca0212dae4 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 11 Jan 2016 02:36:39 -0800 Subject: [PATCH 0388/5324] soc: rockchip: power-domain: Modify power domain driver for rk3368 This driver is modified to support RK3368 SoC. Signed-off-by: zhangqing Reviewed-by: Caesar Wang Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 534c58937a56..6cdffb13c862 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -18,6 +18,7 @@ #include #include #include +#include struct rockchip_domain_info { int pwr_mask; @@ -75,6 +76,9 @@ struct rockchip_pmu { #define DOMAIN_RK3288(pwr, status, req) \ DOMAIN(pwr, status, req, req, (req) + 16) +#define DOMAIN_RK3368(pwr, status, req) \ + DOMAIN(pwr, status, req, (req) + 16, req) + static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) { struct rockchip_pmu *pmu = pd->pmu; @@ -444,6 +448,14 @@ static const struct rockchip_domain_info rk3288_pm_domains[] = { [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), }; +static const struct rockchip_domain_info rk3368_pm_domains[] = { + [RK3368_PD_PERI] = DOMAIN_RK3368(13, 12, 6), + [RK3368_PD_VIO] = DOMAIN_RK3368(15, 14, 8), + [RK3368_PD_VIDEO] = DOMAIN_RK3368(14, 13, 7), + [RK3368_PD_GPU_0] = DOMAIN_RK3368(16, 15, 2), + [RK3368_PD_GPU_1] = DOMAIN_RK3368(17, 16, 2), +}; + static const struct rockchip_pmu_info rk3288_pmu = { .pwr_offset = 0x08, .status_offset = 0x0c, @@ -461,11 +473,32 @@ static const struct rockchip_pmu_info rk3288_pmu = { .domain_info = rk3288_pm_domains, }; +static const struct rockchip_pmu_info rk3368_pmu = { + .pwr_offset = 0x0c, + .status_offset = 0x10, + .req_offset = 0x3c, + .idle_offset = 0x40, + .ack_offset = 0x40, + + .core_pwrcnt_offset = 0x48, + .gpu_pwrcnt_offset = 0x50, + + .core_power_transition_time = 24, + .gpu_power_transition_time = 24, + + .num_domains = ARRAY_SIZE(rk3368_pm_domains), + .domain_info = rk3368_pm_domains, +}; + static const struct of_device_id rockchip_pm_domain_dt_match[] = { { .compatible = "rockchip,rk3288-power-controller", .data = (void *)&rk3288_pmu, }, + { + .compatible = "rockchip,rk3368-power-controller", + .data = (void *)&rk3368_pmu, + }, { /* sentinel */ }, }; -- GitLab From 810d82e6830100615e7481813a862d26ffcff6bd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 23 Jan 2016 15:18:18 -0500 Subject: [PATCH 0389/5324] NFSv4.x: Allow multiple callbacks in flight Hook the callback channel into the same session management machinery as we use for the forward channel. Signed-off-by: Trond Myklebust --- fs/nfs/callback.h | 3 ++- fs/nfs/callback_proc.c | 14 +++++++---- fs/nfs/callback_xdr.c | 12 ++++++---- fs/nfs/nfs4session.c | 54 ++++++++++++++++++++++++++++++++---------- fs/nfs/nfs4session.h | 8 +++++++ 5 files changed, 69 insertions(+), 22 deletions(-) diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index ff8195bd75ea..5fe1cecbf9f0 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -37,10 +37,11 @@ enum nfs4_callback_opnum { OP_CB_ILLEGAL = 10044, }; +struct nfs4_slot; struct cb_process_state { __be32 drc_status; struct nfs_client *clp; - u32 slotid; + struct nfs4_slot *slot; u32 minorversion; struct net *net; }; diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 79c93b3bbfec..efd079d28946 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -367,7 +367,7 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot, if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", __func__, args->csa_sequenceid); - if (tbl->highest_used_slotid != NFS4_NO_SLOT) + if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return htonl(NFS4ERR_DELAY); /* Signal process_op to set this error on next op */ if (args->csa_cachethis == 0) @@ -476,12 +476,18 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, goto out_unlock; } + status = htonl(NFS4ERR_BADSLOT); + slot = nfs4_lookup_slot(tbl, args->csa_slotid); + if (IS_ERR(slot)) + goto out_unlock; status = validate_seqid(tbl, slot, args); if (status) goto out_unlock; - - cps->slotid = args->csa_slotid; - tbl->highest_used_slotid = args->csa_slotid; + if (!nfs4_try_to_lock_slot(tbl, slot)) { + status = htonl(NFS4ERR_DELAY); + goto out_unlock; + } + cps->slot = slot; memcpy(&res->csr_sessionid, &args->csa_sessionid, sizeof(res->csr_sessionid)); diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 646cdac73488..976c90608e56 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -752,7 +752,8 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) return htonl(NFS_OK); } -static void nfs4_callback_free_slot(struct nfs4_session *session) +static void nfs4_callback_free_slot(struct nfs4_session *session, + struct nfs4_slot *slot) { struct nfs4_slot_table *tbl = &session->bc_slot_table; @@ -761,15 +762,17 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) * Let the state manager know callback processing done. * A single slot, so highest used slotid is either 0 or -1 */ - tbl->highest_used_slotid = NFS4_NO_SLOT; + nfs4_free_slot(tbl, slot); nfs4_slot_tbl_drain_complete(tbl); spin_unlock(&tbl->slot_tbl_lock); } static void nfs4_cb_free_slot(struct cb_process_state *cps) { - if (cps->slotid != NFS4_NO_SLOT) - nfs4_callback_free_slot(cps->clp->cl_session); + if (cps->slot) { + nfs4_callback_free_slot(cps->clp->cl_session, cps->slot); + cps->slot = NULL; + } } #else /* CONFIG_NFS_V4_1 */ @@ -893,7 +896,6 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r struct cb_process_state cps = { .drc_status = 0, .clp = NULL, - .slotid = NFS4_NO_SLOT, .net = SVC_NET(rqstp), }; unsigned int nops = 0; diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index e23366effcfb..332d06e64fa9 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c @@ -135,6 +135,43 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, return ERR_PTR(-ENOMEM); } +static void nfs4_lock_slot(struct nfs4_slot_table *tbl, + struct nfs4_slot *slot) +{ + u32 slotid = slot->slot_nr; + + __set_bit(slotid, tbl->used_slots); + if (slotid > tbl->highest_used_slotid || + tbl->highest_used_slotid == NFS4_NO_SLOT) + tbl->highest_used_slotid = slotid; + slot->generation = tbl->generation; +} + +/* + * nfs4_try_to_lock_slot - Given a slot try to allocate it + * + * Note: must be called with the slot_tbl_lock held. + */ +bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) +{ + if (nfs4_test_locked_slot(tbl, slot->slot_nr)) + return false; + nfs4_lock_slot(tbl, slot); + return true; +} + +/* + * nfs4_lookup_slot - Find a slot but don't allocate it + * + * Note: must be called with the slot_tbl_lock held. + */ +struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid) +{ + if (slotid <= tbl->max_slotid) + return nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); + return ERR_PTR(-E2BIG); +} + /* * nfs4_alloc_slot - efficiently look for a free slot * @@ -153,18 +190,11 @@ struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) __func__, tbl->used_slots[0], tbl->highest_used_slotid, tbl->max_slotid + 1); slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1); - if (slotid > tbl->max_slotid) - goto out; - ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); - if (IS_ERR(ret)) - goto out; - __set_bit(slotid, tbl->used_slots); - if (slotid > tbl->highest_used_slotid || - tbl->highest_used_slotid == NFS4_NO_SLOT) - tbl->highest_used_slotid = slotid; - ret->generation = tbl->generation; - -out: + if (slotid <= tbl->max_slotid) { + ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); + if (!IS_ERR(ret)) + nfs4_lock_slot(tbl, ret); + } dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n", __func__, tbl->used_slots[0], tbl->highest_used_slotid, !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT); diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index e3ea2c5324d6..5b51298d1d03 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -77,6 +77,8 @@ extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, unsigned int max_reqs, const char *queue); extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); +extern struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid); +extern bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, @@ -88,6 +90,12 @@ static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl) return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); } +static inline bool nfs4_test_locked_slot(const struct nfs4_slot_table *tbl, + u32 slotid) +{ + return !!test_bit(slotid, tbl->used_slots); +} + #if defined(CONFIG_NFS_V4_1) extern void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, u32 target_highest_slotid); -- GitLab From 10eadc253ddf8325bc6daafdbed67438cfede84c Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Thu, 7 Jan 2016 11:03:14 -0800 Subject: [PATCH 0390/5324] dtc: create tool to diff device trees Create script to diff device trees. The device tree can be in any of the forms recognized by the dtc compiler: - source - binary blob - file system tree (from /proc/devicetree) If the device tree is a source file, then it is pre-processed in the same way as it would be when built in the linux kernel source tree before diffing. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- scripts/dtc/dtx_diff | 343 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100755 scripts/dtc/dtx_diff diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff new file mode 100755 index 000000000000..f1160053d75e --- /dev/null +++ b/scripts/dtc/dtx_diff @@ -0,0 +1,343 @@ +#! /bin/bash + +# Copyright (C) 2015 Frank Rowand +# +# 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; version 2 of the License. + + +usage() { + + # use spaces instead of tabs in the usage message + cat >&2 <tmp_dtx_1.dts + `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts + `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts + rm tmp_dtx_1.dts tmp_dtx_2.dts + + If DTx_1 and DTx_2 are in different directories, then this script will + add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes + a local file that exists in both the path of DTx_1 and DTx_2 then the + file in the path of DTx_1 will incorrectly be included. Possible + workaround: + + `basename $0` DTx_1 >tmp_dtx_1.dts + `basename $0` DTx_2 >tmp_dtx_2.dts + `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts + rm tmp_dtx_1.dts tmp_dtx_2.dts + +eod +} + + +compile_to_dts() { + + dtx="$1" + + if [ -d "${dtx}" ] ; then + + # ----- input is file tree + + if ( ! ${DTC} -I fs ${dtx} ) ; then + exit 3 + fi + + elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then + + magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` + if [ "${magic}" = "d00dfeed" ] ; then + + # ----- input is FDT (binary blob) + + if ( ! ${DTC} -I dtb ${dtx} ) ; then + exit 3 + fi + + return + + fi + + # ----- input is DTS (source) + + if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ + | ${DTC} -I dts ) ; then + return + fi + + echo "" >&2 + echo "Possible hints to resolve the above error:" >&2 + echo " (hints might not fix the problem)" >&2 + + hint_given=0 + + if [ "${ARCH}" = "" ] ; then + hint_given=1 + echo "" >&2 + echo " shell variable \$ARCH not set" >&2 + fi + + dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` + + if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then + hint_given=1 + echo "" >&2 + echo " architecture ${dtx_arch} is in file path," >&2 + echo " but does not match shell variable \$ARCH" >&2 + echo " (${ARCH}) does not match shell variable" >&2 + echo " \$ARCH (${ARCH})" >&2 + fi + + if [ ! -d ${srctree}/arch/${ARCH} ] ; then + hint_given=1 + echo "" >&2 + echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 + echo " Is \$ARCH='${ARCH}' correct?" >&2 + echo " Possible fix: use '-s' option" >&2 + + git_root=`git rev-parse --show-toplevel 2>/dev/null` + if [ -d ${git_root}/arch/ ] ; then + echo " Possible fix: use '-S' option" >&2 + fi + fi + + if [ $hint_given = 0 ] ; then + echo "" >&2 + echo " No hints available." >&2 + fi + + echo "" >&2 + + exit 3 + + else + echo "" >&2 + echo "ERROR: ${dtx} does not exist or is not readable" >&2 + echo "" >&2 + exit 2 + fi + +} + + +# ----- start of script + +cmd_diff=0 +diff_flags="-u" +dtx_file_1="" +dtx_file_2="" +dtc_sort="-s" +help=0 +srctree="" + + +while [ $# -gt 0 ] ; do + + case $1 in + + -f ) + diff_flags="--unified=999999" + shift + ;; + + -h | -help | --help ) + help=1 + shift + ;; + + -s ) + srctree="$2" + shift 2 + ;; + + -S ) + git_root=`git rev-parse --show-toplevel 2>/dev/null` + srctree="${git_root}" + shift + ;; + + -u ) + dtc_sort="" + shift + ;; + + *) + if [ "${dtx_file_1}" = "" ] ; then + dtx_file_1="$1" + elif [ "${dtx_file_2}" = "" ] ; then + dtx_file_2="$1" + else + echo "" >&2 + echo "ERROR: Unexpected parameter: $1" >&2 + echo "" >&2 + exit 2 + fi + shift + ;; + + esac + +done + +if [ "${srctree}" = "" ] ; then + srctree="." +fi + +if [ "${dtx_file_2}" != "" ]; then + cmd_diff=1 +fi + +if (( ${help} )) ; then + usage + exit 1 +fi + +# this must follow check for ${help} +if [ "${dtx_file_1}" = "" ]; then + echo "" >&2 + echo "ERROR: parameter DTx required" >&2 + echo "" >&2 + exit 2 +fi + + +# ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH + +if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then + __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" +elif [ "${KBUILD_OUTPUT}" = "" ] ; then + __KBUILD_OUTPUT="." +else + __KBUILD_OUTPUT="${KBUILD_OUTPUT}" +fi + +DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" + +if [ ! -x ${DTC} ] ; then + __DTC="dtc" + if ( ! which ${__DTC} >/dev/null ) ; then + + # use spaces instead of tabs in the error message + cat >&2 < Date: Mon, 25 Jan 2016 12:41:19 +0100 Subject: [PATCH 0391/5324] drm/i915: Remove select to deleted STOP_MACHINE from Kconfig Commit 5bab6f60cb4d ("drm/i915: Serialise updates to GGTT with access through GGTT on Braswell") depended upon a working stop_machine() and so forced the selection of STOP_MACHINE. However, commit 86fffe4a61dd ("kernel: remove stop_machine() Kconfig dependency") removed the option STOP_MACHINE from init/Kconfig and ensured that stop_machine() universally works. Due to the order in which the patches were applied, removing the select from DRM_I915 got lost during merging. Remove the now obsolete select statement. Signed-off-by: Andreas Ziegler Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1453722079-2604-1-git-send-email-andreas.ziegler@fau.de Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index fcd77b27514d..051eab33e4c7 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -10,7 +10,6 @@ config DRM_I915 # the shmem_readpage() which depends upon tmpfs select SHMEM select TMPFS - select STOP_MACHINE select DRM_KMS_HELPER select DRM_PANEL select DRM_MIPI_DSI -- GitLab From 727c62d29c3a0b982fb72ef993db95e9d2036e07 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Jan 2016 20:44:10 +0900 Subject: [PATCH 0392/5324] ARM: mv78xx0: use "depends on" instead of "if" after prompt This platform recently moved to multi-platform, so missed the global fixup by commit e32465429490 ("ARM: use "depends on" for SoC configs instead of "if" after prompt"). Fix it now. Signed-off-by: Masahiro Yamada Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mv78xx0/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig index a32575fa3fba..c32f85559c65 100644 --- a/arch/arm/mach-mv78xx0/Kconfig +++ b/arch/arm/mach-mv78xx0/Kconfig @@ -1,5 +1,6 @@ menuconfig ARCH_MV78XX0 - bool "Marvell MV78xx0" if ARCH_MULTI_V5 + bool "Marvell MV78xx0" + depends on ARCH_MULTI_V5 select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select MVEBU_MBUS -- GitLab From 33136b06d54915680c36f4cd89dadef068b88974 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:47 +0000 Subject: [PATCH 0393/5324] drm/i915/gen9: Add framework to whitelist specific GPU registers Some of the HW registers are privileged and cannot be written to from non-privileged batch buffers coming from userspace unless they are added to the HW whitelist. This whitelist is maintained by HW and it is different from SW whitelist. Userspace need write access to them to implement preemption related WA. The reason for using this approach is, the register bits that control preemption granularity at the HW level are not context save/restored; so even if we set these bits always in kernel they are going to change once the context is switched out. We can consider making them non-privileged by default but these registers also contain other chicken bits which should not be allowed to be modified. In the later revisions controlling bits are save/restored at context level but in the existing revisions these are exported via other debug registers and should be on the whitelist. This patch adds changes to provide HW with a list of registers to be whitelisted. HW checks this list during execution and provides access accordingly. HW imposes a limit on the number of registers on whitelist and it is per-engine. At this point we are only enabling whitelist for RCS and we don't foresee any requirement for other engines. The registers to be whitelisted are added using generic workaround list mechanism, even these are only enablers for userspace workarounds. But by sharing this mechanism we get some test assets without additional cost (Mika). v2: rebase v3: parameterize RING_FORCE_TO_NONPRIV() as _MMIO() should be limited to i915_reg.h (Ville), drop inline for wa_ring_whitelist_reg (Mika). v4: improvements suggested by Chris Wilson. Clarify that this is HW whitelist and different from the one maintained in driver. This list is engine specific but it gets initialized along with other WA which is RCS specific thing, so make it clear that we are not doing any cross engine setup during initialization. Make HW whitelist count of each engine available in debugfs. Reviewed-by: Chris Wilson Reviewed-by: Mika Kuoppala Cc: Mika Kuoppala Cc: Chris Wilson Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-2-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 15 ++++++++++----- drivers/gpu/drm/i915/i915_drv.h | 9 ++++++++- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index cea184459256..863012a2602e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3221,9 +3221,11 @@ static int i915_wa_registers(struct seq_file *m, void *unused) { int i; int ret; + struct intel_engine_cs *ring; struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_workarounds *workarounds = &dev_priv->workarounds; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) @@ -3231,15 +3233,18 @@ static int i915_wa_registers(struct seq_file *m, void *unused) intel_runtime_pm_get(dev_priv); - seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count); - for (i = 0; i < dev_priv->workarounds.count; ++i) { + seq_printf(m, "Workarounds applied: %d\n", workarounds->count); + for_each_ring(ring, dev_priv, i) + seq_printf(m, "HW whitelist count for %s: %d\n", + ring->name, workarounds->hw_whitelist_count[i]); + for (i = 0; i < workarounds->count; ++i) { i915_reg_t addr; u32 mask, value, read; bool ok; - addr = dev_priv->workarounds.reg[i].addr; - mask = dev_priv->workarounds.reg[i].mask; - value = dev_priv->workarounds.reg[i].value; + addr = workarounds->reg[i].addr; + mask = workarounds->reg[i].mask; + value = workarounds->reg[i].value; read = I915_READ(addr); ok = (value & mask) == (read & mask); seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, status: %s\n", diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index afb0beee9975..211af534e5d0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1657,11 +1657,18 @@ struct i915_wa_reg { u32 mask; }; -#define I915_MAX_WA_REGS 16 +/* + * RING_MAX_NONPRIV_SLOTS is per-engine but at this point we are only + * allowing it for RCS as we don't foresee any requirement of having + * a whitelist for other engines. When it is really required for + * other engines then the limit need to be increased. + */ +#define I915_MAX_WA_REGS (16 + RING_MAX_NONPRIV_SLOTS) struct i915_workarounds { struct i915_wa_reg reg[I915_MAX_WA_REGS]; u32 count; + u32 hw_whitelist_count[I915_NUM_RINGS]; }; struct i915_virtual_gpu { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0a988895165f..79388147184c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1635,6 +1635,9 @@ enum skl_disp_power_wells { #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ #define RING_WAIT_SEMAPHORE (1<<10) /* gen6+ */ +#define RING_FORCE_TO_NONPRIV(base, i) _MMIO(((base)+0x4D0) + (i)*4) +#define RING_MAX_NONPRIV_SLOTS 12 + #define GEN7_TLB_RD_ADDR _MMIO(0x4700) #if 0 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9030e2bca0c0..43fa1403159e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -789,6 +789,22 @@ static int wa_add(struct drm_i915_private *dev_priv, #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val) +static int wa_ring_whitelist_reg(struct intel_engine_cs *ring, i915_reg_t reg) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct i915_workarounds *wa = &dev_priv->workarounds; + const uint32_t index = wa->hw_whitelist_count[ring->id]; + + if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS)) + return -EINVAL; + + WA_WRITE(RING_FORCE_TO_NONPRIV(ring->mmio_base, index), + i915_mmio_reg_offset(reg)); + wa->hw_whitelist_count[ring->id]++; + + return 0; +} + static int gen8_init_workarounds(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; @@ -1117,6 +1133,7 @@ int init_workarounds_ring(struct intel_engine_cs *ring) WARN_ON(ring->id != RCS); dev_priv->workarounds.count = 0; + dev_priv->workarounds.hw_whitelist_count[RCS] = 0; if (IS_BROADWELL(dev)) return bdw_init_workarounds(ring); -- GitLab From e0f3fa096d6f319d1177b05d824fd8b36517368c Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:48 +0000 Subject: [PATCH 0394/5324] drm/i915/gen9: Add GEN8_CS_CHICKEN1 to HW whitelist Required for WaEnablePreemptionGranularityControlByUMD:skl,bxt This register is added to HW whitelist to support WA required for future enabling of pre-emptive command execution, WA implementation will be in userspace and it cannot program this register if it is not on HW whitelist. v2: explain purpose of WA (Chris) Reviewed-by: Nick Hoath Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-3-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 79388147184c..511732ea0138 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5998,6 +5998,8 @@ enum skl_disp_power_wells { #define FF_SLICE_CS_CHICKEN2 _MMIO(0x20e4) #define GEN9_TSG_BARRIER_ACK_DISABLE (1<<8) +#define GEN8_CS_CHICKEN1 _MMIO(0x2580) + /* GEN7 chicken */ #define GEN7_COMMON_SLICE_CHICKEN1 _MMIO(0x7010) # define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 43fa1403159e..c938b93c4f83 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -910,6 +910,7 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t tmp; + int ret; /* WaEnableLbsSlaRetryTimerDecrement:skl */ I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | @@ -980,6 +981,11 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) /* WaDisableSTUnitPowerOptimization:skl,bxt */ WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt */ + ret= wa_ring_whitelist_reg(ring, GEN8_CS_CHICKEN1); + if (ret) + return ret; + return 0; } -- GitLab From 3669ab6191b24ee800a5f78d3748b7d96df12115 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:49 +0000 Subject: [PATCH 0395/5324] drm/i915/gen9: Add HDC_CHICKEN1 to HW whitelist Required for WaAllowUMDToModifyHDCChicken1:skl,bxt This register is added to HW whitelist to support WA required for future enabling of pre-emptive command execution, WA implementation will be in userspace and it cannot program this register if it is not on HW whitelist. v2: explain purpose of changes (Chris) Reviewed-by: Nick Hoath Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-4-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 511732ea0138..ed887cfc47f1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6045,6 +6045,8 @@ enum skl_disp_power_wells { #define HDC_FORCE_NON_COHERENT (1<<4) #define HDC_BARRIER_PERFORMANCE_DISABLE (1<<10) +#define GEN8_HDC_CHICKEN1 _MMIO(0x7304) + /* GEN9 chicken */ #define SLICE_ECO_CHICKEN0 _MMIO(0x7308) #define PIXEL_MASK_CAMMING_DISABLE (1 << 14) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c938b93c4f83..62f535c1b78e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -986,6 +986,11 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) if (ret) return ret; + /* WaAllowUMDToModifyHDCChicken1:skl,bxt */ + ret = wa_ring_whitelist_reg(ring, GEN8_HDC_CHICKEN1); + if (ret) + return ret; + return 0; } -- GitLab From 2c8580e4e21c17011e78e7ac4e1fbab8b0d632bf Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:50 +0000 Subject: [PATCH 0396/5324] drm/i915/bxt: Add GEN9_CS_DEBUG_MODE1 to HW whitelist Required for, WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt WaDisableObjectLevelPreemptionForInstancedDraw:bxt WaDisableObjectLevelPreemtionForInstanceId:bxt According to WA database these are only applicable for BXT:A0 but since A0 and A1 shares the same GT these are extended for A1 as well. These are also required for SKL until B0 but not adding them because they are pre-production steppings. This register is added to HW whitelist to support WA required for future enabling of pre-emptive command execution, WA implementation will be in userspace and it cannot program this register if it is not on HW whitelist. v2: use lower case in register defines (Nick) v3: explain purpose of changes (Chris) Reviewed-by: Nick Hoath Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-5-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ed887cfc47f1..c51e7e909457 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5998,6 +5998,7 @@ enum skl_disp_power_wells { #define FF_SLICE_CS_CHICKEN2 _MMIO(0x20e4) #define GEN9_TSG_BARRIER_ACK_DISABLE (1<<8) +#define GEN9_CS_DEBUG_MODE1 _MMIO(0x20ec) #define GEN8_CS_CHICKEN1 _MMIO(0x2580) /* GEN7 chicken */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 62f535c1b78e..a99f8340fb47 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1133,6 +1133,15 @@ static int bxt_init_workarounds(struct intel_engine_cs *ring) GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); } + /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */ + /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */ + /* WaDisableObjectLevelPreemtionForInstanceId:bxt */ + if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { + ret = wa_ring_whitelist_reg(ring, GEN9_CS_DEBUG_MODE1); + if (ret) + return ret; + } + return 0; } -- GitLab From a786d53a2cf14f2c7abb6731f530aef1a8a1086a Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:51 +0000 Subject: [PATCH 0397/5324] drm/i915/bxt: Add GEN8_L3SQCREG4 to HW whitelist Required for WaDisableLSQCROPERFforOCL:bxt According to WA database these are only applicable for BXT:A0 but since A0 and A1 shares the same GT these are extended for A1 as well. This register is added to HW whitelist to support WA required for future enabling of pre-emptive command execution, WA implementation will be in userspace and it cannot program this register if it is not on HW whitelist. v2: explain purpose of changes (Chris) Reviewed-by: Nick Hoath Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-6-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a99f8340fb47..12eb1e0f786b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1136,10 +1136,15 @@ static int bxt_init_workarounds(struct intel_engine_cs *ring) /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */ /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */ /* WaDisableObjectLevelPreemtionForInstanceId:bxt */ + /* WaDisableLSQCROPERFforOCL:bxt */ if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) { ret = wa_ring_whitelist_reg(ring, GEN9_CS_DEBUG_MODE1); if (ret) return ret; + + ret = wa_ring_whitelist_reg(ring, GEN8_L3SQCREG4); + if (ret) + return ret; } return 0; -- GitLab From 6107497eee9f0f9de6f2aa8708db20842637d472 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:52 +0000 Subject: [PATCH 0398/5324] drm/i915/skl: Add GEN8_L3SQCREG4 to HW whitelist Required for WaDisableLSQCROPERFforOCL:skl This register is added to HW whitelist to support WA required for future enabling of pre-emptive command execution, WA implementation will be in userspace and it cannot program this register if it is not on HW whitelist. v2: explain purpose of changes (Chris) Reviewed-by: Nick Hoath Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-7-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 12eb1e0f786b..262a7ea9e9c4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1098,6 +1098,11 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) GEN7_HALF_SLICE_CHICKEN1, GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); + /* WaDisableLSQCROPERFforOCL:skl */ + ret = wa_ring_whitelist_reg(ring, GEN8_L3SQCREG4); + if (ret) + return ret; + return skl_tune_iz_hashing(ring); } -- GitLab From a78536e73f35471417df1de561d8e8b83da28734 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:53 +0000 Subject: [PATCH 0399/5324] drm/i915/skl: Enable Per context Preemption granularity control Per context preemption granularity control is only available from SKL:E0+ Actual WA is to disable percontext preemption granularity control until D0 which is the default case so this is equivalent to the inverse of WaDisablePerCtxtPreemptionGranularityControl:skl v2: add some detail to commit msg (Chris) Reviewed-by: Nick Hoath Cc: Dave Gordon Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-8-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c51e7e909457..65e32a317d63 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5995,6 +5995,9 @@ enum skl_disp_power_wells { #define SKL_DFSM_CDCLK_LIMIT_450 (2 << 23) #define SKL_DFSM_CDCLK_LIMIT_337_5 (3 << 23) +#define GEN7_FF_SLICE_CS_CHICKEN1 _MMIO(0x20e0) +#define GEN9_FFSC_PERCTX_PREEMPT_CTRL (1<<14) + #define FF_SLICE_CS_CHICKEN2 _MMIO(0x20e4) #define GEN9_TSG_BARRIER_ACK_DISABLE (1<<8) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 262a7ea9e9c4..d07c6a9e7b40 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1046,6 +1046,16 @@ static int skl_init_workarounds(struct intel_engine_cs *ring) if (ret) return ret; + /* + * Actual WA is to disable percontext preemption granularity control + * until D0 which is the default case so this is equivalent to + * !WaDisablePerCtxtPreemptionGranularityControl:skl + */ + if (IS_SKL_REVID(dev, SKL_REVID_E0, REVID_FOREVER)) { + I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, + _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); + } + if (IS_SKL_REVID(dev, 0, SKL_REVID_D0)) { /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ I915_WRITE(FF_SLICE_CS_CHICKEN2, -- GitLab From 6ecf56ae1d20d00a010a7d6d453031e413c674b8 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 21 Jan 2016 21:43:54 +0000 Subject: [PATCH 0400/5324] drm/i915/gen9: Add WaOCLCoherentLineFlush This is mainly required for future enabling of pre-emptive command execution. v2: explain purpose of change (Chris) Reviewed-by: Nick Hoath Cc: Dave Gordon Signed-off-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1453412634-29238-9-git-send-email-arun.siluvery@linux.intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d07c6a9e7b40..6f5b511bdb5d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -981,6 +981,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *ring) /* WaDisableSTUnitPowerOptimization:skl,bxt */ WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); + /* WaOCLCoherentLineFlush:skl,bxt */ + I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) | + GEN8_LQSC_FLUSH_COHERENT_LINES)); + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt */ ret= wa_ring_whitelist_reg(ring, GEN8_CS_CHICKEN1); if (ret) -- GitLab From 73efe5792bfa73589a7e04abf773f8b7a4c01650 Mon Sep 17 00:00:00 2001 From: Henry Chen Date: Mon, 4 Jan 2016 20:02:52 +0800 Subject: [PATCH 0401/5324] soc: mediatek: PMIC wrap: Clear the vldclr if state machine stay on FSM_VLDCLR state. Sometimes PMIC is too busy to send data in time to cause pmic wrap timeout, because pmic wrap is waiting for FSM_VLDCLR after finishing WACS2_CMD. It just return error when issue happened, so the state machine will stay on FSM_VLDCLR state when data send back later by PMIC and timeout again in next time because pmic wrap waiting for FSM_IDLE state at the beginning of the read/write function. Clear the vldclr when timeout if state machine stay on FSM_VLDCLR. Signed-off-by: Henry Chen Tested-by: Ricky Liang Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-pmic-wrap.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index 105597a885cb..696071b66c41 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -412,6 +412,20 @@ static bool pwrap_is_fsm_vldclr(struct pmic_wrapper *wrp) return PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR; } +/* + * Timeout issue sometimes caused by the last read command + * failed because pmic wrap could not got the FSM_VLDCLR + * in time after finishing WACS2_CMD. It made state machine + * still on FSM_VLDCLR and timeout next time. + * Check the status of FSM and clear the vldclr to recovery the + * error. + */ +static inline void pwrap_leave_fsm_vldclr(struct pmic_wrapper *wrp) +{ + if (pwrap_is_fsm_vldclr(wrp)) + pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR); +} + static bool pwrap_is_sync_idle(struct pmic_wrapper *wrp) { return pwrap_readl(wrp, PWRAP_WACS2_RDATA) & PWRAP_STATE_SYNC_IDLE0; @@ -445,8 +459,10 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata) int ret; ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); - if (ret) + if (ret) { + pwrap_leave_fsm_vldclr(wrp); return ret; + } pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata, PWRAP_WACS2_CMD); @@ -459,8 +475,10 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) int ret; ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle); - if (ret) + if (ret) { + pwrap_leave_fsm_vldclr(wrp); return ret; + } pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD); -- GitLab From fd63892fcf28d839694d50d7d355ca0cbde401a1 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 5 Jan 2016 17:24:28 +0100 Subject: [PATCH 0402/5324] ARM: mediatek: add MT7623 smp bringup code Add support for booting secondary CPUs on MT7623. Signed-off-by: John Crispin Signed-off-by: Matthias Brugger --- arch/arm/mach-mediatek/platsmp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index a1b07eeaaf5b..306a8dd00166 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -44,6 +44,12 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = { { 0x38, 0x3c, 0x40 }, }; +static const struct mtk_smp_boot_info mtk_mt7623_boot = { + 0x10202000, 0x34, + { 0x534c4131, 0x4c415332, 0x41534c33 }, + { 0x38, 0x3c, 0x40 }, +}; + static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, @@ -51,6 +57,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, + { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, }; static void __iomem *mtk_smp_base; -- GitLab From a3bbfbb0bc6bd40406ef2aea940719312600813e Mon Sep 17 00:00:00 2001 From: Henry Chen Date: Thu, 21 Jan 2016 19:04:00 +0800 Subject: [PATCH 0403/5324] soc: mediatek: PMIC wrap: clear the STAUPD_TRIG bit of WDT_SRC_EN Since STAUPD interrupts aren't handled on mt8173, disable watchdog timeout monitor of STAUPD to avoid WDT_INT triggered by STAUPD. Signed-off-by: Henry Chen Reviewed-by: Daniel Kurtz Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-pmic-wrap.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index 696071b66c41..0d9b19a78d27 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -60,6 +60,15 @@ #define PWRAP_MAN_CMD_OP_OUTD (0x9 << 8) #define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8) +/* macro for Watch Dog Timer Source */ +#define PWRAP_WDT_SRC_EN_STAUPD_TRIG (1 << 25) +#define PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE (1 << 20) +#define PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE (1 << 6) +#define PWRAP_WDT_SRC_MASK_ALL 0xffffffff +#define PWRAP_WDT_SRC_MASK_NO_STAUPD ~(PWRAP_WDT_SRC_EN_STAUPD_TRIG | \ + PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \ + PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE) + /* macro for slave device wrapper registers */ #define PWRAP_DEW_BASE 0xbc00 #define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0) @@ -822,7 +831,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); static int pwrap_probe(struct platform_device *pdev) { - int ret, irq; + int ret, irq, wdt_src; struct pmic_wrapper *wrp; struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id = @@ -912,7 +921,13 @@ static int pwrap_probe(struct platform_device *pdev) /* Initialize watchdog, may not be done by the bootloader */ pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT); - pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN); + /* + * Since STAUPD was not used on mt8173 platform, + * so STAUPD of WDT_SRC which should be turned off + */ + wdt_src = pwrap_is_mt8173(wrp) ? + PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL; + pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN); pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN); pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN); -- GitLab From 5b0fb1ea134b9f53f7ccd606e26283f40e0f8208 Mon Sep 17 00:00:00 2001 From: Louis Yu Date: Thu, 7 Jan 2016 20:09:43 +0800 Subject: [PATCH 0404/5324] ARM: mediatek: add mt2701 smp bringup code Add support for booting secondary CPUs on mt2701. Signed-off-by: Louis Yu Signed-off-by: Matthias Brugger --- arch/arm/mach-mediatek/platsmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index 306a8dd00166..b821e34474b6 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -53,6 +53,7 @@ static const struct mtk_smp_boot_info mtk_mt7623_boot = { static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, + { .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot }, }; static const struct of_device_id mtk_smp_boot_infos[] __initconst = { -- GitLab From be29523da38f959799fddceb25d052e498ab625a Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Wed, 30 Dec 2015 09:30:40 +0100 Subject: [PATCH 0405/5324] soc: mediatek: SCPSYS: use builtin_platform_driver SCPSYS can't be built as module. Use builtin_platform_driver instead. For this probe must not be __init and the data accessed can't be __initconst. Remove this macros. To make the impact as small as possible, fold scp_domain_data into scp_domain via a pointer. Cc: Sascha Hauer Cc: Arnd Bergmann Reported-by: Daniel Kurtz Signed-off-by: Matthias Brugger Reviewed-by: Daniel Kurtz Tested-by: Daniel Kurtz Acked-by: Arnd Bergmann --- drivers/soc/mediatek/mtk-scpsys.c | 49 +++++++++++++------------------ 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 0221387e5e27..837effe19907 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -76,7 +76,7 @@ struct scp_domain_data { bool active_wakeup; }; -static const struct scp_domain_data scp_domain_data[] __initconst = { +static const struct scp_domain_data scp_domain_data[] = { [MT8173_POWER_DOMAIN_VDEC] = { .name = "vdec", .sta_mask = PWR_STATUS_VDEC, @@ -174,12 +174,7 @@ struct scp_domain { struct generic_pm_domain genpd; struct scp *scp; struct clk *clk[MAX_CLKS]; - u32 sta_mask; - void __iomem *ctl_addr; - u32 sram_pdn_bits; - u32 sram_pdn_ack_bits; - u32 bus_prot_mask; - bool active_wakeup; + const struct scp_domain_data *data; struct regulator *supply; }; @@ -195,8 +190,9 @@ static int scpsys_domain_is_on(struct scp_domain *scpd) { struct scp *scp = scpd->scp; - u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask; - u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask; + u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask; + u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & + scpd->data->sta_mask; /* * A domain is on when both status bits are set. If only one is set @@ -217,8 +213,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) struct scp *scp = scpd->scp; unsigned long timeout; bool expired; - void __iomem *ctl_addr = scpd->ctl_addr; - u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; + void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; + u32 sram_pdn_ack = scpd->data->sram_pdn_ack_bits; u32 val; int ret; int i; @@ -273,7 +269,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) val |= PWR_RST_B_BIT; writel(val, ctl_addr); - val &= ~scpd->sram_pdn_bits; + val &= ~scpd->data->sram_pdn_bits; writel(val, ctl_addr); /* wait until SRAM_PDN_ACK all 0 */ @@ -292,9 +288,9 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) expired = true; } - if (scpd->bus_prot_mask) { + if (scpd->data->bus_prot_mask) { ret = mtk_infracfg_clear_bus_protection(scp->infracfg, - scpd->bus_prot_mask); + scpd->data->bus_prot_mask); if (ret) goto err_pwr_ack; } @@ -321,21 +317,21 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) struct scp *scp = scpd->scp; unsigned long timeout; bool expired; - void __iomem *ctl_addr = scpd->ctl_addr; - u32 pdn_ack = scpd->sram_pdn_ack_bits; + void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; + u32 pdn_ack = scpd->data->sram_pdn_ack_bits; u32 val; int ret; int i; - if (scpd->bus_prot_mask) { + if (scpd->data->bus_prot_mask) { ret = mtk_infracfg_set_bus_protection(scp->infracfg, - scpd->bus_prot_mask); + scpd->data->bus_prot_mask); if (ret) goto out; } val = readl(ctl_addr); - val |= scpd->sram_pdn_bits; + val |= scpd->data->sram_pdn_bits; writel(val, ctl_addr); /* wait until SRAM_PDN_ACK all 1 */ @@ -409,10 +405,10 @@ static bool scpsys_active_wakeup(struct device *dev) genpd = pd_to_genpd(dev->pm_domain); scpd = container_of(genpd, struct scp_domain, genpd); - return scpd->active_wakeup; + return scpd->data->active_wakeup; } -static int __init scpsys_probe(struct platform_device *pdev) +static int scpsys_probe(struct platform_device *pdev) { struct genpd_onecell_data *pd_data; struct resource *res; @@ -485,12 +481,7 @@ static int __init scpsys_probe(struct platform_device *pdev) pd_data->domains[i] = genpd; scpd->scp = scp; - scpd->sta_mask = data->sta_mask; - scpd->ctl_addr = scp->base + data->ctl_offs; - scpd->sram_pdn_bits = data->sram_pdn_bits; - scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; - scpd->bus_prot_mask = data->bus_prot_mask; - scpd->active_wakeup = data->active_wakeup; + scpd->data = data; for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) scpd->clk[j] = clk[data->clk_id[j]]; @@ -542,10 +533,12 @@ static const struct of_device_id of_scpsys_match_tbl[] = { }; static struct platform_driver scpsys_drv = { + .probe = scpsys_probe, .driver = { .name = "mtk-scpsys", + .suppress_bind_attrs = true, .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_scpsys_match_tbl), }, }; -builtin_platform_driver_probe(scpsys_drv, scpsys_probe); +builtin_platform_driver(scpsys_drv); -- GitLab From 768e159f433c97f5221a3662217de5a1cb3b9b95 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 21 Jan 2016 17:32:43 +0000 Subject: [PATCH 0406/5324] drm/i915: Improve handling of overlapping objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generic interval tree we use to speed up range invalidation is an augmented rbtree that can report all overlapping intervals for a given range. Therefore we do not need to degrade to a linear list if we find overlapping objects. Oops. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Michał Winiarski Link: http://patchwork.freedesktop.org/patch/msgid/1453397563-2848-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Michał Winiarski Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_userptr.c | 181 +++++++----------------- 1 file changed, 50 insertions(+), 131 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 19fb0bddc1cd..74a4d1714879 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -49,21 +49,18 @@ struct i915_mmu_notifier { struct hlist_node node; struct mmu_notifier mn; struct rb_root objects; - struct list_head linear; - bool has_linear; }; struct i915_mmu_object { struct i915_mmu_notifier *mn; + struct drm_i915_gem_object *obj; struct interval_tree_node it; struct list_head link; - struct drm_i915_gem_object *obj; struct work_struct work; - bool active; - bool is_linear; + bool attached; }; -static void __cancel_userptr__worker(struct work_struct *work) +static void cancel_userptr(struct work_struct *work) { struct i915_mmu_object *mo = container_of(work, typeof(*mo), work); struct drm_i915_gem_object *obj = mo->obj; @@ -94,24 +91,22 @@ static void __cancel_userptr__worker(struct work_struct *work) mutex_unlock(&dev->struct_mutex); } -static unsigned long cancel_userptr(struct i915_mmu_object *mo) +static void add_object(struct i915_mmu_object *mo) { - unsigned long end = mo->obj->userptr.ptr + mo->obj->base.size; - - /* The mmu_object is released late when destroying the - * GEM object so it is entirely possible to gain a - * reference on an object in the process of being freed - * since our serialisation is via the spinlock and not - * the struct_mutex - and consequently use it after it - * is freed and then double free it. - */ - if (mo->active && kref_get_unless_zero(&mo->obj->base.refcount)) { - schedule_work(&mo->work); - /* only schedule one work packet to avoid the refleak */ - mo->active = false; - } + if (mo->attached) + return; + + interval_tree_insert(&mo->it, &mo->mn->objects); + mo->attached = true; +} - return end; +static void del_object(struct i915_mmu_object *mo) +{ + if (!mo->attached) + return; + + interval_tree_remove(&mo->it, &mo->mn->objects); + mo->attached = false; } static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, @@ -122,28 +117,36 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, struct i915_mmu_notifier *mn = container_of(_mn, struct i915_mmu_notifier, mn); struct i915_mmu_object *mo; + struct interval_tree_node *it; + LIST_HEAD(cancelled); + + if (RB_EMPTY_ROOT(&mn->objects)) + return; /* interval ranges are inclusive, but invalidate range is exclusive */ end--; spin_lock(&mn->lock); - if (mn->has_linear) { - list_for_each_entry(mo, &mn->linear, link) { - if (mo->it.last < start || mo->it.start > end) - continue; - - cancel_userptr(mo); - } - } else { - struct interval_tree_node *it; + it = interval_tree_iter_first(&mn->objects, start, end); + while (it) { + /* The mmu_object is released late when destroying the + * GEM object so it is entirely possible to gain a + * reference on an object in the process of being freed + * since our serialisation is via the spinlock and not + * the struct_mutex - and consequently use it after it + * is freed and then double free it. To prevent that + * use-after-free we only acquire a reference on the + * object if it is not in the process of being destroyed. + */ + mo = container_of(it, struct i915_mmu_object, it); + if (kref_get_unless_zero(&mo->obj->base.refcount)) + schedule_work(&mo->work); - it = interval_tree_iter_first(&mn->objects, start, end); - while (it) { - mo = container_of(it, struct i915_mmu_object, it); - start = cancel_userptr(mo); - it = interval_tree_iter_next(it, start, end); - } + list_add(&mo->link, &cancelled); + it = interval_tree_iter_next(it, start, end); } + list_for_each_entry(mo, &cancelled, link) + del_object(mo); spin_unlock(&mn->lock); } @@ -164,8 +167,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) spin_lock_init(&mn->lock); mn->mn.ops = &i915_gem_userptr_notifier; mn->objects = RB_ROOT; - INIT_LIST_HEAD(&mn->linear); - mn->has_linear = false; /* Protected by mmap_sem (write-lock) */ ret = __mmu_notifier_register(&mn->mn, mm); @@ -177,85 +178,6 @@ i915_mmu_notifier_create(struct mm_struct *mm) return mn; } -static int -i915_mmu_notifier_add(struct drm_device *dev, - struct i915_mmu_notifier *mn, - struct i915_mmu_object *mo) -{ - struct interval_tree_node *it; - int ret = 0; - - /* By this point we have already done a lot of expensive setup that - * we do not want to repeat just because the caller (e.g. X) has a - * signal pending (and partly because of that expensive setup, X - * using an interrupt timer is likely to get stuck in an EINTR loop). - */ - mutex_lock(&dev->struct_mutex); - - /* Make sure we drop the final active reference (and thereby - * remove the objects from the interval tree) before we do - * the check for overlapping objects. - */ - i915_gem_retire_requests(dev); - - spin_lock(&mn->lock); - it = interval_tree_iter_first(&mn->objects, - mo->it.start, mo->it.last); - if (it) { - struct drm_i915_gem_object *obj; - - /* We only need to check the first object in the range as it - * either has cancelled gup work queued and we need to - * return back to the user to give time for the gup-workers - * to flush their object references upon which the object will - * be removed from the interval-tree, or the the range is - * still in use by another client and the overlap is invalid. - * - * If we do have an overlap, we cannot use the interval tree - * for fast range invalidation. - */ - - obj = container_of(it, struct i915_mmu_object, it)->obj; - if (!obj->userptr.workers) - mn->has_linear = mo->is_linear = true; - else - ret = -EAGAIN; - } else - interval_tree_insert(&mo->it, &mn->objects); - - if (ret == 0) - list_add(&mo->link, &mn->linear); - - spin_unlock(&mn->lock); - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -static bool i915_mmu_notifier_has_linear(struct i915_mmu_notifier *mn) -{ - struct i915_mmu_object *mo; - - list_for_each_entry(mo, &mn->linear, link) - if (mo->is_linear) - return true; - - return false; -} - -static void -i915_mmu_notifier_del(struct i915_mmu_notifier *mn, - struct i915_mmu_object *mo) -{ - spin_lock(&mn->lock); - list_del(&mo->link); - if (mo->is_linear) - mn->has_linear = i915_mmu_notifier_has_linear(mn); - else - interval_tree_remove(&mo->it, &mn->objects); - spin_unlock(&mn->lock); -} - static void i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) { @@ -265,7 +187,9 @@ i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) if (mo == NULL) return; - i915_mmu_notifier_del(mo->mn, mo); + spin_lock(&mo->mn->lock); + del_object(mo); + spin_unlock(&mo->mn->lock); kfree(mo); obj->userptr.mmu_object = NULL; @@ -299,7 +223,6 @@ i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, { struct i915_mmu_notifier *mn; struct i915_mmu_object *mo; - int ret; if (flags & I915_USERPTR_UNSYNCHRONIZED) return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; @@ -316,16 +239,10 @@ i915_gem_userptr_init__mmu_notifier(struct drm_i915_gem_object *obj, return -ENOMEM; mo->mn = mn; - mo->it.start = obj->userptr.ptr; - mo->it.last = mo->it.start + obj->base.size - 1; mo->obj = obj; - INIT_WORK(&mo->work, __cancel_userptr__worker); - - ret = i915_mmu_notifier_add(obj->base.dev, mn, mo); - if (ret) { - kfree(mo); - return ret; - } + mo->it.start = obj->userptr.ptr; + mo->it.last = obj->userptr.ptr + obj->base.size - 1; + INIT_WORK(&mo->work, cancel_userptr); obj->userptr.mmu_object = mo; return 0; @@ -552,8 +469,10 @@ __i915_gem_userptr_set_active(struct drm_i915_gem_object *obj, /* In order to serialise get_pages with an outstanding * cancel_userptr, we must drop the struct_mutex and try again. */ - if (!value || !work_pending(&obj->userptr.mmu_object->work)) - obj->userptr.mmu_object->active = value; + if (!value) + del_object(obj->userptr.mmu_object); + else if (!work_pending(&obj->userptr.mmu_object->work)) + add_object(obj->userptr.mmu_object); else ret = -EAGAIN; spin_unlock(&obj->userptr.mmu_object->mn->lock); -- GitLab From 1803c035efb88afb9d3e7feb279ac29a83216382 Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Thu, 21 Jan 2016 19:37:45 +0000 Subject: [PATCH 0407/5324] drm/i915: Fix context/engine cleanup order Swap the order of context & engine cleanup, so that contexts are cleaned up first, and *then* engines. This is a more sensible order anyway, but in particular has become necessary since the 'intel_ring_initialized() must be simple and inline' patch, which now uses ring->dev as an 'initialised' flag, so it can now be NULL after engine teardown. This in turn can cause a problem in the context code, which (used to) check the ring->dev->struct_mutex -- causing a fault if ring->dev was NULL. Also rename the cleanup function to reflect what it actually does (cleanup engines, not a ringbuffer), and fix an annoying whitespace issue. v2: Also make the fix in i915_load_modeset_init, not just in i915_driver_unload (Chris Wilson) v3: Had extra stuff in it. v4: Reverted extra stuff (so we're back to v2). Rebased and updated commentary above (Dave Gordon). Signed-off-by: Nick Hoath Signed-off-by: Dave Gordon Reviewed-by: Chris Wilson (v2) Cc: Mika Kuoppala Cc: Daniel Vetter Cc: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1453405067-32890-3-git-send-email-david.s.gordon@intel.com Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 23 ++++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d70d96fe553b..4725e8d61d0f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -451,8 +451,8 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); + i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: intel_guc_ucode_fini(dev); @@ -1196,8 +1196,8 @@ int i915_driver_unload(struct drm_device *dev) intel_guc_ucode_fini(dev); mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); + i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 211af534e5d0..01cc982f5497 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3019,7 +3019,7 @@ int i915_gem_init_rings(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice); void i915_gem_init_swizzling(struct drm_device *dev); -void i915_gem_cleanup_ringbuffer(struct drm_device *dev); +void i915_gem_cleanup_engines(struct drm_device *dev); int __must_check i915_gpu_idle(struct drm_device *dev); int __must_check i915_gem_suspend(struct drm_device *dev); void __i915_add_request(struct drm_i915_gem_request *req, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 371bbb28c471..799a53ad04f2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4912,7 +4912,7 @@ i915_gem_init_hw(struct drm_device *dev) req = i915_gem_request_alloc(ring, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4925,7 +4925,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4933,7 +4933,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -5008,7 +5008,7 @@ int i915_gem_init(struct drm_device *dev) } void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) +i915_gem_cleanup_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; @@ -5017,13 +5017,14 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) for_each_ring(ring, dev_priv, i) dev_priv->gt.cleanup_ring(ring); - if (i915.enable_execlists) - /* - * Neither the BIOS, ourselves or any other kernel - * expects the system to be in execlists mode on startup, - * so we need to reset the GPU back to legacy mode. - */ - intel_gpu_reset(dev); + if (i915.enable_execlists) { + /* + * Neither the BIOS, ourselves or any other kernel + * expects the system to be in execlists mode on startup, + * so we need to reset the GPU back to legacy mode. + */ + intel_gpu_reset(dev); + } } static void -- GitLab From fb740cf2492cc1e8f2216bc5ad9f5b2c49a32752 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:40:59 +0100 Subject: [PATCH 0408/5324] drm: Create drm_send_event helpers Use them in the core vblank code and exynos/vmwgfx drivers. Note that the difference between wake_up_all and _interruptible in vmwgfx doesn't matter since the only waiter is the core code in drm_fops.c. And that is interruptible. v2: Adjust existing kerneldoc too. Reviewed-by: Alex Deucher (v1) Acked-by: Daniel Stone Cc: Alex Deucher Cc: Thomas Hellstrom Cc: Inki Dae Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-6-git-send-email-daniel.vetter@ffwll.ch Reviewed-by: Laurent Pinchart [danvet: Squash in compile fixup, spotted by 0-day.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fops.c | 42 ++++++++++++++++++++++++- drivers/gpu/drm/drm_irq.c | 7 ++--- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 6 +--- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 6 +--- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 3 +- include/drm/drmP.h | 2 ++ 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index f9eacbb2d1dd..e13501e3606e 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -687,7 +687,9 @@ EXPORT_SYMBOL(drm_poll); * This function prepares the passed in event for eventual delivery. If the event * doesn't get delivered (because the IOCTL fails later on, before queuing up * anything) then the even must be cancelled and freed using - * drm_event_cancel_free(). + * drm_event_cancel_free(). Successfully initialized events should be sent out + * using drm_send_event() or drm_send_event_locked() to signal completion of the + * asynchronous event to userspace. * * If callers embedded @p into a larger structure it must be allocated with * kmalloc and @p must be the first member element. @@ -743,3 +745,41 @@ void drm_event_cancel_free(struct drm_device *dev, p->destroy(p); } EXPORT_SYMBOL(drm_event_cancel_free); + +/** + * drm_send_event_locked - send DRM event to file descriptor + * @dev: DRM device + * @e: DRM event to deliver + * + * This function sends the event @e, initialized with drm_event_reserve_init(), + * to its associated userspace DRM file. Callers must already hold + * dev->event_lock, see drm_send_event() for the unlocked version. + */ +void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) +{ + assert_spin_locked(&dev->event_lock); + + list_add_tail(&e->link, + &e->file_priv->event_list); + wake_up_interruptible(&e->file_priv->event_wait); +} +EXPORT_SYMBOL(drm_send_event_locked); + +/** + * drm_send_event - send DRM event to file descriptor + * @dev: DRM device + * @e: DRM event to deliver + * + * This function sends the event @e, initialized with drm_event_reserve_init(), + * to its associated userspace DRM file. This function acquires dev->event_lock, + * see drm_send_event_locked() for callers which already hold this lock. + */ +void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) +{ + unsigned long irqflags; + + spin_lock_irqsave(&dev->event_lock, irqflags); + drm_send_event_locked(dev, e); + spin_unlock_irqrestore(&dev->event_lock, irqflags); +} +EXPORT_SYMBOL(drm_send_event); diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index d12a4efa651b..4ec8bca643ac 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -983,15 +983,12 @@ static void send_vblank_event(struct drm_device *dev, struct drm_pending_vblank_event *e, unsigned long seq, struct timeval *now) { - assert_spin_locked(&dev->event_lock); - e->event.sequence = seq; e->event.tv_sec = now->tv_sec; e->event.tv_usec = now->tv_usec; - list_add_tail(&e->base.link, - &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); + drm_send_event_locked(dev, &e->base); + trace_drm_vblank_event_delivered(e->base.pid, e->pipe, e->event.sequence); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 82e7f95dfed9..99369816ff97 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -880,7 +880,6 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node; struct drm_exynos_pending_g2d_event *e; struct timeval now; - unsigned long flags; if (list_empty(&runqueue_node->event_list)) return; @@ -893,10 +892,7 @@ static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no) e->event.tv_usec = now.tv_usec; e->event.cmdlist_no = cmdlist_no; - spin_lock_irqsave(&drm_dev->event_lock, flags); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + drm_send_event(drm_dev, &e->base); } static irqreturn_t g2d_irq_handler(int irq, void *dev_id) diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index c8819c05e2dd..3eab0d15f0b4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -1407,7 +1407,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_send_event *e; struct list_head *head; struct timeval now; - unsigned long flags; u32 tbuf_id[EXYNOS_DRM_OPS_MAX] = {0, }; int ret, i; @@ -1520,10 +1519,7 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, for_each_ipp_ops(i) e->event.buf_id[i] = tbuf_id[i]; - spin_lock_irqsave(&drm_dev->event_lock, flags); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); + drm_send_event(drm_dev, &e->base); mutex_unlock(&c_node->event_lock); DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n", diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index eda93bf52a6e..e0edf149d9d5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -880,9 +880,8 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) } list_del_init(&eaction->fpriv_head); - list_add_tail(&eaction->event->link, &file_priv->event_list); eaction->event = NULL; - wake_up_all(&file_priv->event_wait); + drm_send_event_locked(dev, eaction->event); spin_unlock_irqrestore(&dev->event_lock, irq_flags); } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 04a66468e6e0..306ef32ec086 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -932,6 +932,8 @@ int drm_event_reserve_init(struct drm_device *dev, struct drm_event *e); void drm_event_cancel_free(struct drm_device *dev, struct drm_pending_event *p); +void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); +void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); /* Misc. IOCTL support (drm_ioctl.c) */ int drm_noop(struct drm_device *dev, void *data, -- GitLab From 0b5ef656f764e6cc1fe1e0aaf080a19560f2f76a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:41:00 +0100 Subject: [PATCH 0409/5324] drm/fsl: Remove preclose hook Doesn't do anything, but annoys when auditing them all. Cc: Jianwei Wang Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-7-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index fca97d3fc846..9648b7f9a31c 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c @@ -112,10 +112,6 @@ static int fsl_dcu_unload(struct drm_device *dev) return 0; } -static void fsl_dcu_drm_preclose(struct drm_device *dev, struct drm_file *file) -{ -} - static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) { struct drm_device *dev = arg; @@ -191,7 +187,6 @@ static struct drm_driver fsl_dcu_drm_driver = { | DRIVER_PRIME | DRIVER_ATOMIC, .load = fsl_dcu_load, .unload = fsl_dcu_unload, - .preclose = fsl_dcu_drm_preclose, .irq_handler = fsl_dcu_drm_irq, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = fsl_dcu_drm_enable_vblank, -- GitLab From d704f8e1a649a6dc1cca693846df96e54d80744f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:41:01 +0100 Subject: [PATCH 0410/5324] drm/armada: Remove NULL open/pre/postclose hooks The compiler will do this, but the void hits when grepping all the hooks for a subsystem wide audit are slightly annoying. So remove them for next time around. Cc: Russell King Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-8-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/armada/armada_drv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 3bd7e1cde99e..82043c204b76 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -188,9 +188,6 @@ static const struct file_operations armada_drm_fops = { static struct drm_driver armada_drm_driver = { .load = armada_drm_load, - .open = NULL, - .preclose = NULL, - .postclose = NULL, .lastclose = armada_drm_lastclose, .unload = armada_drm_unload, .set_busid = drm_platform_set_busid, -- GitLab From 941a77b078e6127c4d441439ad1669347750288e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jan 2016 22:41:02 +0100 Subject: [PATCH 0411/5324] drm/gma500: Remove empty preclose hook I'm auditing them all, empty ones just confuse ... Cc: Patrik Jakobsson Acked-by: Daniel Stone Reviewed-by: Alex Deucher Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-9-git-send-email-daniel.vetter@ffwll.ch Acked-by: Patrik Jakobsson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/gma500/psb_drv.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 92e7e5795398..4e1c6850520e 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -442,14 +442,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, /* FIXME: do we need to wrap the other side of this */ } -/* - * When a client dies: - * - Check for and clean up flipped page state - */ -static void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv) -{ -} - static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { return drm_get_pci_dev(pdev, ent, &driver); @@ -495,7 +487,6 @@ static struct drm_driver driver = { .load = psb_driver_load, .unload = psb_driver_unload, .lastclose = psb_driver_lastclose, - .preclose = psb_driver_preclose, .set_busid = drm_pci_set_busid, .num_ioctls = ARRAY_SIZE(psb_ioctls), -- GitLab From 09859d2a3c2090ae2452cbf1c8fdde30ba38d934 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 13 Jan 2016 15:31:16 +0100 Subject: [PATCH 0412/5324] drm/crtc-helper: Add caveat to disable_unused_functions doc This shouldn't be used by atomic drivers any more, it confuses the state tracking. Cc: Maxime Ripard Cc: Laurent Pinchart Acked-by: Laurent Pinchart Link: http://patchwork.freedesktop.org/patch/msgid/1452695476-31147-1-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc_helper.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 5d4bc6441d88..9f8b894f4480 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -220,6 +220,15 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev) * disconnected connectors. Then it will disable all unused encoders and CRTCs * either by calling their disable callback if available or by calling their * dpms callback with DRM_MODE_DPMS_OFF. + * + * NOTE: + * + * This function is part of the legacy modeset helper library and will cause + * major confusion with atomic drivers. This is because atomic helpers guarantee + * to never call ->disable() hooks on a disabled function, or ->enable() hooks + * on an enabled functions. drm_helper_disable_unused_functions() on the other + * hand throws such guarantees into the wind and calls disable hooks + * unconditionally on unused functions. */ void drm_helper_disable_unused_functions(struct drm_device *dev) { -- GitLab From 8d1a0ae724ad74ef7946a45e3b2d3e01f39df02b Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Wed, 13 Jan 2016 23:36:26 -0500 Subject: [PATCH 0413/5324] ARM: perf: Set ARMv7 SDER SUNIDEN bit ARMv7 counters other than the CPU cycle counter only work if the Secure Debug Enable Register (SDER) SUNIDEN bit is set. Since access to the SDER is only possible in secure state, it will only be done if the device tree property "secure-reg-access" is set. Without this: Performance counter stats for 'sleep 1': 14606094 cycles # 0.000 GHz 0 instructions # 0.00 insns per cycle After applying: Performance counter stats for 'sleep 1': 5843809 cycles 2566484 instructions # 0.44 insns per cycle 1.020144000 seconds time elapsed Some platforms (eg i.MX53) may also need additional platform specific setup. Acked-by: Rob Herring Signed-off-by: Martin Fuzzey Signed-off-by: Pooya Keshavarzi Signed-off-by: George G. Davis [will: add warning if property is found on arm64] Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/arm/pmu.txt | 10 ++++++++++ arch/arm/kernel/perf_event_v7.c | 13 ++++++++++++- drivers/perf/arm_pmu.c | 9 +++++++++ include/linux/perf/arm_pmu.h | 1 + 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 56518839f52a..b6056d3bca06 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -46,6 +46,16 @@ Optional properties: - qcom,no-pc-write : Indicates that this PMU doesn't support the 0xc and 0xd events. +- secure-reg-access : Indicates that the ARMv7 Secure Debug Enable Register + (SDER) is accessible. This will cause the driver to do + any setup required that is only possible in ARMv7 secure + state. If not present the ARMv7 SDER will not be touched, + which means the PMU may fail to operate unless external + code (bootloader or security monitor) has performed the + appropriate initialisation. Note that this property is + not valid for non-ARMv7 CPUs or ARMv7 CPUs booting Linux + in Non-secure state. + Example: pmu { diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4152158f6e6a..15063851cd10 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -712,6 +712,11 @@ static const struct attribute_group *armv7_pmuv2_attr_groups[] = { #define ARMV7_EXCLUDE_USER (1 << 30) #define ARMV7_INCLUDE_HYP (1 << 27) +/* + * Secure debug enable reg + */ +#define ARMV7_SDER_SUNIDEN BIT(1) /* Permit non-invasive debug */ + static inline u32 armv7_pmnc_read(void) { u32 val; @@ -1094,7 +1099,13 @@ static int armv7pmu_set_event_filter(struct hw_perf_event *event, static void armv7pmu_reset(void *info) { struct arm_pmu *cpu_pmu = (struct arm_pmu *)info; - u32 idx, nb_cnt = cpu_pmu->num_events; + u32 idx, nb_cnt = cpu_pmu->num_events, val; + + if (cpu_pmu->secure_access) { + asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val)); + val |= ARMV7_SDER_SUNIDEN; + asm volatile("mcr p15, 0, %0, c1, c1, 1" : : "r" (val)); + } /* The counter and interrupt enable registers are unknown at reset. */ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 166637f2917c..eb5bee07526b 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -889,6 +889,15 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { init_fn = of_id->data; + pmu->secure_access = of_property_read_bool(pdev->dev.of_node, + "secure-reg-access"); + + /* arm64 systems boot only as non-secure */ + if (IS_ENABLED(CONFIG_ARM64) && pmu->secure_access) { + pr_warn("ignoring \"secure-reg-access\" property for arm64\n"); + pmu->secure_access = false; + } + ret = of_pmu_irq_cfg(pmu); if (!ret) ret = init_fn(pmu); diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index 83b5e34c6580..2d5eaaa90078 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -104,6 +104,7 @@ struct arm_pmu { atomic_t active_events; struct mutex reserve_mutex; u64 max_period; + bool secure_access; /* 32-bit ARM only */ struct platform_device *plat_device; struct pmu_hw_events __percpu *hw_events; struct notifier_block hotplug_nb; -- GitLab From 133e1e5acd4a63c4a0dcc413e90d5decdbce9c4a Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Mon, 25 Jan 2016 18:04:15 -0500 Subject: [PATCH 0414/5324] audit: stop an old auditd being starved out by a new auditd Nothing prevents a new auditd starting up and replacing a valid audit_pid when an old auditd is still running, effectively starving out the old auditd since audit_pid no longer points to the old valid auditd. If no message to auditd has been attempted since auditd died unnaturally or got killed, audit_pid will still indicate it is alive. There isn't an easy way to detect if an old auditd is still running on the existing audit_pid other than attempting to send a message to see if it fails. An -ECONNREFUSED almost certainly means it disappeared and can be replaced. Other errors are not so straightforward and may indicate transient problems that will resolve themselves and the old auditd will recover. Yet others will likely need manual intervention for which a new auditd will not solve the problem. Send a new message type (AUDIT_REPLACE) to the old auditd containing a u32 with the PID of the new auditd. If the audit replace message succeeds (or doesn't fail with certainty), fail to register the new auditd and return an error (-EEXIST). This is expected to make the patch preventing an old auditd orphaning a new auditd redundant. V3: Switch audit message type from 1000 to 1300 block. Signed-off-by: Richard Guy Briggs Signed-off-by: Paul Moore --- include/uapi/linux/audit.h | 1 + kernel/audit.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 843540c398eb..d820aa979620 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h @@ -110,6 +110,7 @@ #define AUDIT_SECCOMP 1326 /* Secure Computing event */ #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */ #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ +#define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ diff --git a/kernel/audit.c b/kernel/audit.c index d6dd95cc59e6..2fd63d6879c5 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -809,6 +809,16 @@ static int audit_set_feature(struct sk_buff *skb) return 0; } +static int audit_replace(pid_t pid) +{ + struct sk_buff *skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0, + &pid, sizeof(pid)); + + if (!skb) + return -ENOMEM; + return netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); +} + static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { u32 seq; @@ -870,9 +880,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } if (s.mask & AUDIT_STATUS_PID) { int new_pid = s.pid; + pid_t requesting_pid = task_tgid_vnr(current); - if ((!new_pid) && (task_tgid_vnr(current) != audit_pid)) + if ((!new_pid) && (requesting_pid != audit_pid)) return -EACCES; + if (audit_pid && new_pid && + audit_replace(requesting_pid) != -ECONNREFUSED) + return -EEXIST; if (audit_enabled != AUDIT_OFF) audit_log_config_change("audit_pid", new_pid, audit_pid, 1); audit_pid = new_pid; -- GitLab From 935c9e7ff06abf12c45155f75ec2f712d3768095 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Mon, 25 Jan 2016 18:04:15 -0500 Subject: [PATCH 0415/5324] audit: log failed attempts to change audit_pid configuration Failed attempts to change the audit_pid configuration are not presently logged. One case is an attempt to starve an old auditd by starting up a new auditd when the old one is still alive and active. The other case is an attempt to orphan a new auditd when an old auditd shuts down. Log both as AUDIT_CONFIG_CHANGE messages with failure result. Signed-off-by: Richard Guy Briggs Signed-off-by: Paul Moore --- kernel/audit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/audit.c b/kernel/audit.c index 2fd63d6879c5..8fa7533bf106 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -882,11 +882,15 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) int new_pid = s.pid; pid_t requesting_pid = task_tgid_vnr(current); - if ((!new_pid) && (requesting_pid != audit_pid)) + if ((!new_pid) && (requesting_pid != audit_pid)) { + audit_log_config_change("audit_pid", new_pid, audit_pid, 0); return -EACCES; + } if (audit_pid && new_pid && - audit_replace(requesting_pid) != -ECONNREFUSED) + audit_replace(requesting_pid) != -ECONNREFUSED) { + audit_log_config_change("audit_pid", new_pid, audit_pid, 0); return -EEXIST; + } if (audit_enabled != AUDIT_OFF) audit_log_config_change("audit_pid", new_pid, audit_pid, 1); audit_pid = new_pid; -- GitLab From b682572fc55edd4efcba8b8f29ac057b27980963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jarosz?= Date: Tue, 19 Jan 2016 13:09:19 +0100 Subject: [PATCH 0416/5324] clk: rockchip: Add new id for rk3066 tsadc clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds new id for the sclk supplying the tsadc on rk3066 socs. Signed-off-by: Paweł Jarosz Signed-off-by: Heiko Stuebner --- include/dt-bindings/clock/rk3188-cru-common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h index 8df77a7c030b..4f53e70f68ee 100644 --- a/include/dt-bindings/clock/rk3188-cru-common.h +++ b/include/dt-bindings/clock/rk3188-cru-common.h @@ -55,6 +55,7 @@ #define SCLK_TIMER6 90 #define SCLK_JTAG 91 #define SCLK_SMC 92 +#define SCLK_TSADC 93 #define DCLK_LCDC0 190 #define DCLK_LCDC1 191 -- GitLab From 2c41b5a775dc2a9d04b56ca6b2827025b8bddeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jarosz?= Date: Tue, 19 Jan 2016 13:09:20 +0100 Subject: [PATCH 0417/5324] clk: rockchip: add tsadc clock on rk3066 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set clock id for sclk_tsadc gating clock of tsadc in rk3066 Signed-off-by: Paweł Jarosz Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 73954907111e..3d4f2c629682 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -605,7 +605,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 2, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(34), 0, 16, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), -- GitLab From 00f8508bc994405f6debfbfcd51e37b22b461378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jarosz?= Date: Tue, 19 Jan 2016 13:09:21 +0100 Subject: [PATCH 0418/5324] ARM: dts: rockchip: add tsadc node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the device node for the TSADC found on rk3066. Signed-off-by: Paweł Jarosz Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 56922730d285..cb0a552e0b18 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -190,6 +190,16 @@ clock-names = "timer", "pclk"; }; + tsadc: tsadc@20060000 { + compatible = "rockchip,rk3066-tsadc"; + reg = <0x20060000 0x100>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "saradc", "apb_pclk"; + interrupts = ; + #io-channel-cells = <1>; + status = "disabled"; + }; + usbphy: phy { compatible = "rockchip,rk3066a-usb-phy", "rockchip,rk3288-usb-phy"; rockchip,grf = <&grf>; -- GitLab From 171f2ef82284f61b763a620747806ec2724d1a84 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 22 Jan 2016 19:03:22 +0900 Subject: [PATCH 0419/5324] arm64: dts: r8a7795: Add USB3.0 host device nodes Signed-off-by: Yoshihiro Shimoda Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 221a8f5d24af..119549e6502d 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -862,5 +862,23 @@ clocks = <&cpg CPG_MOD 815>; status = "disabled"; }; + + xhci0: usb@ee000000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee000000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&cpg>; + status = "disabled"; + }; + + xhci1: usb@ee0400000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee040000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 327>; + power-domains = <&cpg>; + status = "disabled"; + }; }; }; -- GitLab From e1995f5586c9a60eefb188bc4ce3d4f37a6b835b Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Sun, 10 Jan 2016 20:25:40 -0800 Subject: [PATCH 0420/5324] ARM: mvebu_v5_defconfig: Enable sound module needed for OpenRD OpenRD-Client requires the CS42L51 codec. Signed-off-by: Martin Michlmayr Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/configs/mvebu_v5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index af29780accdc..9317e5a5b730 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -137,6 +137,7 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_KIRKWOOD_SOC=y CONFIG_SND_SOC_ALC5623=y +CONFIG_SND_SOC_CS42L51_I2C=y CONFIG_SND_SIMPLE_CARD=y CONFIG_HID_DRAGONRISE=y CONFIG_HID_GYRATION=y -- GitLab From f8543c06b3948102d50ee6dfdbb06f1e7945baf1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:25:57 +0100 Subject: [PATCH 0421/5324] mtd: inftl: kill unused oobinfo field Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/inftl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h index 02cd5f9b79b8..8255118be0f0 100644 --- a/include/linux/mtd/inftl.h +++ b/include/linux/mtd/inftl.h @@ -44,7 +44,6 @@ struct INFTLrecord { unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */ struct erase_info instr; - struct nand_ecclayout oobinfo; }; int INFTL_mount(struct INFTLrecord *s); -- GitLab From 2c9e57799f1b7ef35a9e7f774edac6b3feac6399 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:25:58 +0100 Subject: [PATCH 0422/5324] mtd: nftl: kill unused oobinfo field Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nftl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h index b059629e22bc..044daa02b8ff 100644 --- a/include/linux/mtd/nftl.h +++ b/include/linux/mtd/nftl.h @@ -50,7 +50,6 @@ struct NFTLrecord { unsigned int nb_blocks; /* number of physical blocks */ unsigned int nb_boot_blocks; /* number of blocks used by the bios */ struct erase_info instr; - struct nand_ecclayout oobinfo; }; int NFTL_mount(struct NFTLrecord *s); -- GitLab From f88f44cbf10cf5bd42d6e46ea6625d9bfa5f155d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:25:59 +0100 Subject: [PATCH 0423/5324] mtd: nand: s3c2410: kill the ->ecc_layout field The s3c2410 is allowing board data to overload the default ECC layout defined inside the driver, but this feature is not used by board specific definitions. Kill this field so that we can easily move to a model where ecclayout are dynamically allocated by the NAND controller driver. Signed-off-by: Boris Brezillon Acked-by: Krzysztof Kozlowski Signed-off-by: Brian Norris --- arch/arm/plat-samsung/devs.c | 9 --------- drivers/mtd/nand/s3c2410.c | 3 --- include/linux/platform_data/mtd-nand-s3c2410.h | 1 - 3 files changed, 13 deletions(-) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index b53d4ff3befb..84baa16f4c0b 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -727,15 +727,6 @@ static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) return -ENOMEM; } - if (set->ecc_layout) { - ptr = kmemdup(set->ecc_layout, - sizeof(struct nand_ecclayout), GFP_KERNEL); - set->ecc_layout = ptr; - - if (!ptr) - return -ENOMEM; - } - return 0; } diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 01ac74fa3b95..9c9397b54b2c 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c @@ -861,9 +861,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.mode = NAND_ECC_SOFT; #endif - if (set->ecc_layout != NULL) - chip->ecc.layout = set->ecc_layout; - if (set->disable_ecc) chip->ecc.mode = NAND_ECC_NONE; diff --git a/include/linux/platform_data/mtd-nand-s3c2410.h b/include/linux/platform_data/mtd-nand-s3c2410.h index 36bb92172f47..c55e42ee57fa 100644 --- a/include/linux/platform_data/mtd-nand-s3c2410.h +++ b/include/linux/platform_data/mtd-nand-s3c2410.h @@ -40,7 +40,6 @@ struct s3c2410_nand_set { char *name; int *nr_map; struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; }; struct s3c2410_platform_nand { -- GitLab From d5e83ea7dc510fe8e7b4a54e5a93f3dd760f6d7e Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:26:00 +0100 Subject: [PATCH 0424/5324] mtd: nand: jz4740: kill the ->ecc_layout field ->ecc_layout is not used by any board file. Kill this field to avoid any confusion. New boards are encouraged to use the default ECC layout defined in NAND core. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- arch/mips/include/asm/mach-jz4740/jz4740_nand.h | 2 -- drivers/mtd/nand/jz4740_nand.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index 79cff26d8b36..398733e3e2cf 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h @@ -25,8 +25,6 @@ struct jz_nand_platform_data { int num_partitions; struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; - unsigned char banks[JZ_NAND_NUM_BANKS]; void (*ident_callback)(struct platform_device *, struct nand_chip *, diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index b19d2a9a5eb9..673ceb2a0b44 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -427,9 +427,6 @@ static int jz_nand_probe(struct platform_device *pdev) chip->ecc.strength = 4; chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; - if (pdata) - chip->ecc.layout = pdata->ecc_layout; - chip->chip_delay = 50; chip->cmd_ctrl = jz_nand_cmd_ctrl; chip->select_chip = jz_nand_select_chip; -- GitLab From 02db97a9de1c80bd5551ba46d901cb4d912f78f2 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:26:01 +0100 Subject: [PATCH 0425/5324] mtd: nand: kill unused ->ecclayout field in platform_nand_chip struct This field is not set in any board file and can thus be dropped. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/plat_nand.c | 1 - include/linux/mtd/nand.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index a0e26dea1424..e4e50da30444 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c @@ -73,7 +73,6 @@ static int plat_nand_probe(struct platform_device *pdev) data->chip.bbt_options |= pdata->chip.bbt_options; data->chip.ecc.hwctl = pdata->ctrl.hwcontrol; - data->chip.ecc.layout = pdata->chip.ecclayout; data->chip.ecc.mode = NAND_ECC_SOFT; platform_set_drvdata(pdev, data); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index a13dfd5bc58b..7604f4be3386 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -902,7 +902,6 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, * @chip_delay: R/B delay value in us * @options: Option flags, e.g. 16bit buswidth * @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH - * @ecclayout: ECC layout info structure * @part_probe_types: NULL-terminated array of probe types */ struct platform_nand_chip { @@ -910,7 +909,6 @@ struct platform_nand_chip { int chip_offset; int nr_partitions; struct mtd_partition *partitions; - struct nand_ecclayout *ecclayout; int chip_delay; unsigned int options; unsigned int bbt_options; -- GitLab From 8be721beb30f14bac915ca1357a0b584d03c0749 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:26:02 +0100 Subject: [PATCH 0426/5324] staging: mt29f_spinand: kill unused ecclayout field The spinand_info struct embeds a pointer to an ecclayout definition, but this field is never used in the mt29f driver. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/staging/mt29f_spinand/mt29f_spinand.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h index ae62975cf44a..457dc7ffdaf1 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.h +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.h @@ -78,7 +78,6 @@ #define BL_ALL_UNLOCKED 0 struct spinand_info { - struct nand_ecclayout *ecclayout; struct spi_device *spi; void *priv; }; -- GitLab From f771749e3a4905e631dafa073543ef429c7cc855 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:26:03 +0100 Subject: [PATCH 0427/5324] mtd: nand: lpc32xx_mlc: fix ecc.size According to the ECC layout description the actual ecc.size is 512 bytes and not mtd->writesize. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- drivers/mtd/nand/lpc32xx_mlc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 9bc435d72a86..d8c3e7afcc0b 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c @@ -750,7 +750,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) } nand_chip->ecc.mode = NAND_ECC_HW; - nand_chip->ecc.size = mtd->writesize; + nand_chip->ecc.size = 512; nand_chip->ecc.layout = &lpc32xx_nand_oob; host->mlcsubpages = mtd->writesize / 512; -- GitLab From 420b4629b5b9d08893c459b55a7a266caa734ebd Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 7 Dec 2015 23:26:04 +0100 Subject: [PATCH 0428/5324] mtd: nand: vf610: remove useless mtd->ecclayout assignment The NAND core layer is already taking care of ecclayout propagation. Remove this useless assignment. Signed-off-by: Boris Brezillon Acked-by: Stefan Agner Signed-off-by: Brian Norris --- drivers/mtd/nand/vf610_nfc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 034420f313d5..293feb19b0b1 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -795,8 +795,6 @@ static int vf610_nfc_probe(struct platform_device *pdev) goto error; } - /* propagate ecc.layout to mtd_info */ - mtd->ecclayout = chip->ecc.layout; chip->ecc.read_page = vf610_nfc_read_page; chip->ecc.write_page = vf610_nfc_write_page; -- GitLab From 15c0be7bec002f9a529dd0966d0db96dde176fd0 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jan 2016 23:24:10 +0100 Subject: [PATCH 0429/5324] mtd: Fix dependencies for !HAS_IOMEM archs Not every arch has io memory. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger Acked-by: Geert Uytterhoeven Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 2 ++ drivers/mtd/spi-nor/Kconfig | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 20f01b3ec23d..545d82b100b6 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -74,6 +74,7 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR config MTD_NAND_GPIO tristate "GPIO assisted NAND Flash driver" depends on GPIOLIB || COMPILE_TEST + depends on HAS_IOMEM help This enables a NAND flash driver where control signals are connected to GPIO pins, and commands and data are communicated @@ -463,6 +464,7 @@ config MTD_NAND_MPC5121_NFC config MTD_NAND_VF610_NFC tristate "Support for Freescale NFC for VF610/MPC5125" depends on (SOC_VF610 || COMPILE_TEST) + depends on HAS_IOMEM help Enables support for NAND Flash Controller on some Freescale processors like the VF610, MPC5125, MCF54418 or Kinetis K70. diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 0dc927540b3d..83befab4b5b4 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig @@ -9,6 +9,7 @@ if MTD_SPI_NOR config MTD_MT81xx_NOR tristate "Mediatek MT81xx SPI NOR flash controller" + depends on HAS_IOMEM help This enables access to SPI NOR flash, using MT81xx SPI NOR flash controller. This controller does not support generic SPI BUS, it only -- GitLab From e8b63288b37dbb8457b510c9d96f6006da4653f6 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Tue, 26 Jan 2016 16:34:00 +0300 Subject: [PATCH 0430/5324] clk: rockchip: add hclk_cpubus to the list of rk3188 critical clocks hclk_cpubus needs to keep running because it is needed for devices like the rom, i2s0 or spdif to be accessible via cpu. Without that all accesses to devices (readl/writel) return wrong data. So add it to the list of critical clocks. Fixes: 78eaf6095cc763c ("clk: rockchip: disable unused clocks") Signed-off-by: Alexander Kochetkov Cc: stable@vger.kernel.org # 4.1.x- Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 3d4f2c629682..cc1d09d77edd 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -748,6 +748,7 @@ static const char *const rk3188_critical_clocks[] __initconst = { "hclk_peri", "pclk_cpu", "pclk_peri", + "hclk_cpubus" }; static void __init rk3188_common_clk_init(struct device_node *np) -- GitLab From f19768ce0e84ac8a1ab03f87784bdf94bf94e140 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Oct 2015 16:00:35 +0100 Subject: [PATCH 0431/5324] ARM: orion: implement ARM delay timer Implement an ARM delay timer to be used for udelay() on orion legacy platforms. This allows us to skip the delay loop calibration at boot. It also means that udelay() will be unaffected by CPU frequency changes when cpufreq is enabled on these platforms. Tested-by: Russell King Acked-by: Andrew Lunn Signed-off-by: Russell King --- arch/arm/plat-orion/time.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac812..ffb93db68e9c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * MBus bridge block registers. @@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) timer_base = _timer_base; } +static unsigned long orion_delay_timer_read(void) +{ + return ~readl(timer_base + TIMER0_VAL_OFF); +} + +static struct delay_timer orion_delay_timer = { + .read_current_timer = orion_delay_timer_read, +}; + void __init orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, unsigned int irq, unsigned int tclk) @@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, ticks_per_jiffy = (tclk + HZ/2) / HZ; + orion_delay_timer.freq = tclk; + register_current_timer_delay(&orion_delay_timer); + /* * Set scale and timer for sched_clock. */ -- GitLab From d78e13a8a8b795b605eb58a48365591f2e7c690b Mon Sep 17 00:00:00 2001 From: Juri Lelli Date: Thu, 7 Jan 2016 16:27:33 +0100 Subject: [PATCH 0432/5324] ARM: 8497/1: initialize cpu_scale to its default Instead of looping through all cpus calling set_capacity_scale, we can initialise cpu_scale per-cpu variables to SCHED_CAPACITY_SCALE with their definition. Acked-by: Vincent Guittot Signed-off-by: Juri Lelli Signed-off-by: Russell King --- arch/arm/kernel/topology.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 08b7847bf912..ec279d161b32 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -40,7 +40,7 @@ * to run the rebalance_domains for all idle cores and the cpu_capacity can be * updated during this sequence. */ -static DEFINE_PER_CPU(unsigned long, cpu_scale); +static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) { @@ -306,8 +306,6 @@ void __init init_cpu_topology(void) cpu_topo->socket_id = -1; cpumask_clear(&cpu_topo->core_sibling); cpumask_clear(&cpu_topo->thread_sibling); - - set_capacity_scale(cpu, SCHED_CAPACITY_SCALE); } smp_wmb(); -- GitLab From 9023cc8268c6ba358417d31112ed96e1feb73e56 Mon Sep 17 00:00:00 2001 From: Andiii Date: Thu, 14 Jan 2016 07:17:00 +0100 Subject: [PATCH 0433/5324] ARM: 8499/1: irq: l2c: do not print error in case of missing l2c from arm: irq: l2c: do not print error in case of missing l2c from dtb In some architectures the L2 cache controller is integrated in the processor's block itself and it doesn't use any external cache controller. This means that an entry in the board's dtb related to the l2c is not necessary. Distinguish between error codes and do not print anything in case l2x0_of_init() doesn't find any L2C DTB entry and returns -ENODEV. This patch mutes the following error message: L2C: failed to init: -19 on boards like odroid-xu4, cortex A7/A15, which don't have external cache controller. Signed-off-by: Andi Shyti Reported-by: Krzysztof Kozlowski Reviewed-by: Krzysztof Kozlowski Tested-by: Krzysztof Kozlowski Signed-off-by: Russell King --- arch/arm/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 1d45320ee125..ece04a457486 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -95,7 +95,7 @@ void __init init_IRQ(void) outer_cache.write_sec = machine_desc->l2c_write_sec; ret = l2x0_of_init(machine_desc->l2c_aux_val, machine_desc->l2c_aux_mask); - if (ret) + if (ret && ret != -ENODEV) pr_err("L2C: failed to init: %d\n", ret); } -- GitLab From 3ea03a9d512ca19d59315492230e954a1653ff6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 26 Jan 2016 23:35:16 +0100 Subject: [PATCH 0434/5324] ARM: BCM5301X: Add DT for D-Link DIR-885L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's device based on BCM47094 which is quite similar to BCM4709 except for higher CPU frequency. This device has 2 flash memories, it boots from serial one and stores firmware on NAND. Other than that we define standard stuff like LEDs, buttons and UART. Signed-off-by: Rafał Miłecki Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 111 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26..e75711c6fd7e 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -79,6 +79,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4709-buffalo-wxr-1900dhp.dtb \ bcm4709-netgear-r7000.dtb \ bcm4709-netgear-r8000.dtb \ + bcm47094-dlink-dir-885l.dtb \ bcm94708.dtb \ bcm94709.dtb \ bcm953012k.dtb diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts new file mode 100644 index 000000000000..6c83538bc2d7 --- /dev/null +++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts @@ -0,0 +1,111 @@ +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * DTS for D-Link DIR-885L + * + * Copyright (C) 2016 Rafał Miłecki + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" + +/ { + compatible = "dlink,dir-885l", "brcm,bcm47094", "brcm,bcm4708"; + model = "D-Link DIR-885L"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + nand: nand@18028000 { + nandcs@0 { + partition@0 { + label = "firmware"; + reg = <0x00000000 0x08000000>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + power-white { + label = "bcm53xx:white:power"; + gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + wan-white { + label = "bcm53xx:white:wan"; + gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + power-amber { + label = "bcm53xx:amber:power"; + gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + wan-amber { + label = "bcm53xx:amber:wan"; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + usb3-white { + label = "bcm53xx:white:usb3"; + gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 2ghz { + label = "bcm53xx:white:2ghz"; + gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 5ghz { + label = "bcm53xx:white:5ghz"; + gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>; + }; + + /* Switch: router / extender */ + extender { + label = "Extender"; + linux,code = ; + gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&uart0 { + status = "okay"; + clock-frequency = <125000000>; +}; -- GitLab From ae6b99bc6928d13856172f287ee21be2eac39673 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 11 Jan 2016 12:59:59 +0900 Subject: [PATCH 0435/5324] ARM: shmobile: enable XHCI_RCAR in defconfig Signed-off-by: Simon Horman --- arch/arm/configs/shmobile_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 5208b5caacd1..b7b714c3958c 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -162,6 +162,8 @@ CONFIG_SND_SOC_RSRC_CARD=y CONFIG_SND_SOC_AK4642=y CONFIG_SND_SOC_WM8978=y CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_RCAR=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_R8A66597_HCD=y -- GitLab From 20cc7dd4d03d912d28a642701f08c7dba8622436 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 11 Jan 2016 13:00:00 +0900 Subject: [PATCH 0436/5324] ARM: multi_v7_defconfig: Enable XHCI_RCAR This is used by Renesas R-Car SoCs. Signed-off-by: Simon Horman --- arch/arm/configs/multi_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 314f6be2dca2..69d6a6d358cb 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -577,6 +577,7 @@ CONFIG_SND_SOC_WM8978=m CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MVEBU=y +CONFIG_USB_XHCI_RCAR=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MSM=m CONFIG_USB_EHCI_EXYNOS=y -- GitLab From 1e78dbe717b1668e1660556930d952447c7c1197 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Oct 2015 17:13:07 +0100 Subject: [PATCH 0437/5324] ARM: orion: implement ARM delay timer Implement an ARM delay timer to be used for udelay() on orion legacy platforms. This allows us to skip the delay loop calibration at boot. It also means that udelay() will be unaffected by CPU frequency changes when cpufreq is enabled on these platforms. Signed-off-by: Russell King Tested-by: Russell King Acked-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/plat-orion/time.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac812..ffb93db68e9c 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * MBus bridge block registers. @@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) timer_base = _timer_base; } +static unsigned long orion_delay_timer_read(void) +{ + return ~readl(timer_base + TIMER0_VAL_OFF); +} + +static struct delay_timer orion_delay_timer = { + .read_current_timer = orion_delay_timer_read, +}; + void __init orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, unsigned int irq, unsigned int tclk) @@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, ticks_per_jiffy = (tclk + HZ/2) / HZ; + orion_delay_timer.freq = tclk; + register_current_timer_delay(&orion_delay_timer); + /* * Set scale and timer for sched_clock. */ -- GitLab From 9a15a87338d9f28593172ec7ec2c628f3ae494b9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Jan 2016 13:40:29 +0100 Subject: [PATCH 0438/5324] Revert "drm/i915: Fix context/engine cleanup order" This reverts commit 1803c035efb88afb9d3e7feb279ac29a83216382. It seems to blow up on module unload due to a use-after free hitting a BUG_ON with CONFIG_DEBUG_SG. Quoting from Tvrtko's mail: "I've decoded the instructions and it pointed to SG_MAGIC checking: 488b8098010000 mov 0x198(%rax),%rax ba21436587 mov $0x87654321,%edx 488b00 mov (%rax),%rax *** CRASH "Grep showed 0x87654321 is SG_MAGIC, so likely candidate for this code pattern is: static inline struct page *sg_page(struct scatterlist *sg) { BUG_ON(sg->sg_magic != SG_MAGIC); BUG_ON(sg_is_chain(sg)); return (struct page *)((sg)->page_link & ~0x3); } "Which would mean the offender is in intel_logical_ring_cleanup is most likely: ... if (ring->status_page.obj) { kunmap(sg_page(ring->status_page.obj->pages->sgl)); ring->status_page.obj = NULL; } ... "I think that the i915_gem_context_fini will do a final unref on dev_priv->kernel_context and then the ring buff has a copy which is left dangling because: lrc_setup_hardware_status_page(ring, dev_priv->kernel_context->engine[ring->id].state); and: ring->status_page.obj = default_ctx_obj; "Where default_ctx_obj == dev_priv->kernel_context->engine[ring->id].state So indeed looks like the unload ordering is the trigger. In fact it is almost the same fragility wrt/ kernel_context hidden dependency I expressed my worry about in an e-mail yesterday or so. It only shows if CONFIG_DEBUG_SG is set, otherwise it accesses freed memory and probably just survives." This causes serious trouble in our CI system since it took out all gen8+ machines. Not yet clear why this wasn't caught in pre-merge testing. Backtrace from CI, for posterity: [ 163.737836] general protection fault: 0000 [#1] PREEMPT SMP [ 163.737849] Modules linked in: ax88179_178a usbnet mii snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic i915(-) x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm mei_me mei i2c_hid e1000e ptp pps_core [last unloaded: snd_hda_intel] [ 163.737902] CPU: 0 PID: 5812 Comm: rmmod Tainted: G U W 4.5.0-rc1-gfxbench+ #1 [ 163.737911] Hardware name: System manufacturer System Product Name/Z170M-PLUS, BIOS 0505 11/16/2015 [ 163.737920] task: ffff8800bb99cf80 ti: ffff88022ff2c000 task.ti: ffff88022ff2c000 [ 163.737928] RIP: 0010:[] [] intel_logical_ring_cleanup+0x83/0x100 [i915] [ 163.737969] RSP: 0018:ffff88022ff2fd30 EFLAGS: 00010282 [ 163.737975] RAX: 6b6b6b6b6b6b6b6b RBX: ffff8800bb2f31b8 RCX: 0000000000000002 [ 163.737982] RDX: 0000000087654321 RSI: 000000000000000d RDI: ffff8800bb2f31f0 [ 163.737989] RBP: ffff88022ff2fd40 R08: 0000000000000000 R09: 0000000000000001 [ 163.737996] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800bb2f0000 [ 163.738003] R13: ffff8800bb2f8fc8 R14: ffff8800bb285668 R15: 000055af1ae55210 [ 163.738010] FS: 00007f187014b700(0000) GS:ffff88023bc00000(0000) knlGS:0000000000000000 [ 163.738021] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 163.738030] CR2: 0000558f84e4cbc8 CR3: 000000022cd55000 CR4: 00000000003406f0 [ 163.738039] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 163.738048] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 163.738057] Stack: [ 163.738062] ffff8800bb2f31b8 ffff8800bb2f0000 ffff88022ff2fd70 ffffffffa0180414 [ 163.738079] ffff8800bb2f0000 ffff8800bb285668 ffff8800bb2856c8 ffffffffa0242460 [ 163.738094] ffff88022ff2fd98 ffffffffa0202d30 ffff8800bb285668 ffff8800bb285668 [ 163.738109] Call Trace: [ 163.738140] [] i915_gem_cleanup_engines+0x34/0x60 [i915] [ 163.738185] [] i915_driver_unload+0x150/0x270 [i915] [ 163.738198] [] drm_dev_unregister+0x24/0xa0 [ 163.738208] [] drm_put_dev+0x1e/0x60 [ 163.738225] [] i915_pci_remove+0x10/0x20 [i915] [ 163.738237] [] pci_device_remove+0x34/0xb0 [ 163.738249] [] __device_release_driver+0x95/0x140 [ 163.738259] [] driver_detach+0xb6/0xc0 [ 163.738268] [] bus_remove_driver+0x53/0xd0 [ 163.738278] [] driver_unregister+0x27/0x50 [ 163.738289] [] pci_unregister_driver+0x25/0x70 [ 163.738299] [] drm_pci_exit+0x74/0x90 [ 163.738337] [] i915_exit+0x20/0x1a5 [i915] [ 163.738349] [] SyS_delete_module+0x18f/0x1f0 [ 163.738361] [] entry_SYSCALL_64_fastpath+0x16/0x73 [ 163.738370] Code: ff d0 48 89 df e8 de a1 fd ff 48 8d 7b 38 e8 25 ab fd ff 48 8b 83 90 00 00 00 48 85 c0 74 25 48 8b 80 98 01 00 00 ba 21 43 65 87 <48> 8b 00 48 39 10 75 3c f6 40 08 01 75 38 48 c7 83 90 00 00 00 [ 163.738459] RIP [] intel_logical_ring_cleanup+0x83/0x100 [i915] [ 163.738498] RSP [ 163.738507] ---[ end trace 68f69ce4740fa44f ]--- Cc: Nick Hoath Cc: Dave Gordon Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Tested-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 23 +++++++++++------------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4725e8d61d0f..d70d96fe553b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -451,8 +451,8 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); - i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: intel_guc_ucode_fini(dev); @@ -1196,8 +1196,8 @@ int i915_driver_unload(struct drm_device *dev) intel_guc_ucode_fini(dev); mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); - i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 01cc982f5497..211af534e5d0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3019,7 +3019,7 @@ int i915_gem_init_rings(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice); void i915_gem_init_swizzling(struct drm_device *dev); -void i915_gem_cleanup_engines(struct drm_device *dev); +void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int __must_check i915_gpu_idle(struct drm_device *dev); int __must_check i915_gem_suspend(struct drm_device *dev); void __i915_add_request(struct drm_i915_gem_request *req, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 799a53ad04f2..371bbb28c471 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4912,7 +4912,7 @@ i915_gem_init_hw(struct drm_device *dev) req = i915_gem_request_alloc(ring, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); - i915_gem_cleanup_engines(dev); + i915_gem_cleanup_ringbuffer(dev); goto out; } @@ -4925,7 +4925,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_engines(dev); + i915_gem_cleanup_ringbuffer(dev); goto out; } @@ -4933,7 +4933,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_engines(dev); + i915_gem_cleanup_ringbuffer(dev); goto out; } @@ -5008,7 +5008,7 @@ int i915_gem_init(struct drm_device *dev) } void -i915_gem_cleanup_engines(struct drm_device *dev) +i915_gem_cleanup_ringbuffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; @@ -5017,14 +5017,13 @@ i915_gem_cleanup_engines(struct drm_device *dev) for_each_ring(ring, dev_priv, i) dev_priv->gt.cleanup_ring(ring); - if (i915.enable_execlists) { - /* - * Neither the BIOS, ourselves or any other kernel - * expects the system to be in execlists mode on startup, - * so we need to reset the GPU back to legacy mode. - */ - intel_gpu_reset(dev); - } + if (i915.enable_execlists) + /* + * Neither the BIOS, ourselves or any other kernel + * expects the system to be in execlists mode on startup, + * so we need to reset the GPU back to legacy mode. + */ + intel_gpu_reset(dev); } static void -- GitLab From 89250fec1c2b7846cd994e91d8dd7398e67ae129 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:26 +0200 Subject: [PATCH 0439/5324] drm/i915: Sanitize DMC/CSR ucode cleanup code commit ebae38d061df3deffa7c17b030ea14a5216ee55f Author: Animesh Manna Date: Wed Oct 28 23:58:55 2015 +0200 drm/i915/gen9: csr_init after runtime pm enable moved the DMC/CSR initialization later during driver loading, but didn't move the cleanup earlier correspondingly during unloading. Fix this up. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d70d96fe553b..4b2c073f20e7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -404,7 +404,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ret = intel_irq_install(dev_priv); if (ret) - goto cleanup_gem_stolen; + goto cleanup_csr; intel_setup_gmbus(dev); @@ -458,7 +458,8 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_guc_ucode_fini(dev); drm_irq_uninstall(dev); intel_teardown_gmbus(dev); -cleanup_gem_stolen: +cleanup_csr: + intel_csr_ucode_fini(dev_priv); i915_gem_cleanup_stolen(dev); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); @@ -945,7 +946,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = i915_gem_gtt_init(dev); if (ret) - goto out_freecsr; + goto out_uncore_fini; /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ @@ -1115,8 +1116,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) io_mapping_free(dev_priv->gtt.mappable); out_gtt: i915_global_gtt_cleanup(dev); -out_freecsr: - intel_csr_ucode_fini(dev_priv); +out_uncore_fini: intel_uncore_fini(dev); pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: @@ -1182,6 +1182,8 @@ int i915_driver_unload(struct drm_device *dev) vga_switcheroo_unregister_client(dev->pdev); vga_client_register(dev->pdev, NULL, NULL, NULL); + intel_csr_ucode_fini(dev_priv); + /* Free error state after interrupts are fully disabled. */ cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); i915_destroy_error_state(dev); @@ -1202,8 +1204,6 @@ int i915_driver_unload(struct drm_device *dev) intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); - intel_csr_ucode_fini(dev_priv); - intel_teardown_mchbar(dev); destroy_workqueue(dev_priv->hotplug.dp_wq); -- GitLab From 02036cee8373712d154a7cac76e1325f93fce9e5 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:27 +0200 Subject: [PATCH 0440/5324] drm/i915: Sanitize i915_get_bridge_dev() error path Clarify the name of the label on the error path, making it clear what's being cleaned up. The kmem_cache_destroy() calls are NOPs on the corresponding error path. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4b2c073f20e7..5caea9e97fcf 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -916,7 +916,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (i915_get_bridge_dev(dev)) { ret = -EIO; - goto free_priv; + goto out_runtime_pm_put; } mmio_bar = IS_GEN2(dev) ? 1 : 0; @@ -1121,11 +1121,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); -free_priv: kmem_cache_destroy(dev_priv->requests); kmem_cache_destroy(dev_priv->vmas); kmem_cache_destroy(dev_priv->objects); - +out_runtime_pm_put: intel_runtime_pm_put(dev_priv); kfree(dev_priv); -- GitLab From a8a40589257a280b49c7d9b744910036d11aac5d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:28 +0200 Subject: [PATCH 0441/5324] drm/i915: Sanitize GEM shrinker init and clean-up Factor out the common GEM shrinker clean-up code and call the shrinker init function from the same function from where the corresponding shrinker clean-up function is called. Also add sanity checking to the shrinker and OOM registration calls. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 7 +++---- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 2 -- drivers/gpu/drm/i915/i915_gem_shrinker.c | 16 ++++++++++++++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5caea9e97fcf..adc5fe728bc5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1035,6 +1035,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_opregion_setup(dev); i915_gem_load(dev); + i915_gem_shrinker_init(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there @@ -1098,8 +1099,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); out_gem_unload: - WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); - unregister_shrinker(&dev_priv->mm.shrinker); + i915_gem_shrinker_cleanup(dev_priv); if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); @@ -1152,8 +1152,7 @@ int i915_driver_unload(struct drm_device *dev) i915_teardown_sysfs(dev); - WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); - unregister_shrinker(&dev_priv->mm.shrinker); + i915_gem_shrinker_cleanup(dev_priv); io_mapping_free(dev_priv->gtt.mappable); arch_phys_wc_del(dev_priv->gtt.mtrr); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 211af534e5d0..abfb8c9e5a8c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3261,6 +3261,7 @@ unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, #define I915_SHRINK_ACTIVE 0x8 unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); void i915_gem_shrinker_init(struct drm_i915_private *dev_priv); +void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv); /* i915_gem_tiling.c */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 371bbb28c471..7ce76c24a5c6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5100,8 +5100,6 @@ i915_gem_load(struct drm_device *dev) dev_priv->mm.interruptible = true; - i915_gem_shrinker_init(dev_priv); - mutex_init(&dev_priv->fb_tracking.lock); } diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 16da9c1422cc..58c1e592bbdb 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -367,8 +367,20 @@ void i915_gem_shrinker_init(struct drm_i915_private *dev_priv) dev_priv->mm.shrinker.scan_objects = i915_gem_shrinker_scan; dev_priv->mm.shrinker.count_objects = i915_gem_shrinker_count; dev_priv->mm.shrinker.seeks = DEFAULT_SEEKS; - register_shrinker(&dev_priv->mm.shrinker); + WARN_ON(register_shrinker(&dev_priv->mm.shrinker)); dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom; - register_oom_notifier(&dev_priv->mm.oom_notifier); + WARN_ON(register_oom_notifier(&dev_priv->mm.oom_notifier)); +} + +/** + * i915_gem_shrinker_cleanup - Clean up i915 shrinker + * @dev_priv: i915 device + * + * This function unregisters the i915 shrinker and OOM handler. + */ +void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv) +{ + WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); + unregister_shrinker(&dev_priv->mm.shrinker); } -- GitLab From d64aa096a4fb0f438563ad8126123766c2190aa8 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:29 +0200 Subject: [PATCH 0442/5324] drm/i915: Sanitize i915_gem_load() init and clean-up Factor out common clean-up code for the GEM load time init function. Also rename i915_gem_load() to i915_gem_load_init() to have a better match with its new clean-up function. No functional change. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-5-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 10 +++------- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 11 ++++++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index adc5fe728bc5..348366cd471c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1034,7 +1034,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_setup_mchbar(dev); intel_opregion_setup(dev); - i915_gem_load(dev); + i915_gem_load_init(dev); i915_gem_shrinker_init(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the @@ -1121,9 +1121,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); - kmem_cache_destroy(dev_priv->requests); - kmem_cache_destroy(dev_priv->vmas); - kmem_cache_destroy(dev_priv->objects); + i915_gem_load_cleanup(dev); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); @@ -1215,9 +1213,7 @@ int i915_driver_unload(struct drm_device *dev) if (dev_priv->regs != NULL) pci_iounmap(dev->pdev, dev_priv->regs); - kmem_cache_destroy(dev_priv->requests); - kmem_cache_destroy(dev_priv->vmas); - kmem_cache_destroy(dev_priv->objects); + i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); kfree(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index abfb8c9e5a8c..905e90f25957 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2848,7 +2848,8 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -void i915_gem_load(struct drm_device *dev); +void i915_gem_load_init(struct drm_device *dev); +void i915_gem_load_cleanup(struct drm_device *dev); void *i915_gem_object_alloc(struct drm_device *dev); void i915_gem_object_free(struct drm_i915_gem_object *obj); void i915_gem_object_init(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7ce76c24a5c6..c1bb6a61745c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5034,7 +5034,7 @@ init_ring_lists(struct intel_engine_cs *ring) } void -i915_gem_load(struct drm_device *dev) +i915_gem_load_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; @@ -5103,6 +5103,15 @@ i915_gem_load(struct drm_device *dev) mutex_init(&dev_priv->fb_tracking.lock); } +void i915_gem_load_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + kmem_cache_destroy(dev_priv->requests); + kmem_cache_destroy(dev_priv->vmas); + kmem_cache_destroy(dev_priv->objects); +} + void i915_gem_release(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; -- GitLab From 399bb5b6db027b1834d10496909d60214779126c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:30 +0200 Subject: [PATCH 0443/5324] drm/i915: Move allocation of various workqueues earlier during init Workqueue initalization doesn't depend on any other device specific resource, so move it close to the beginning, so we don't need to consider them when thinking about dependencies for other resources. Also factor out things to separate init/cleanup functions to make i915_driver_load()/unload() clearer, atm it's somewhat difficult to follow there in what order resources are inited/cleaned-up. Suggested-by: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-6-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 101 ++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 348366cd471c..1446e6390227 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -856,6 +856,54 @@ static void intel_init_dpio(struct drm_i915_private *dev_priv) } } +static int i915_workqueues_init(struct drm_i915_private *dev_priv) +{ + /* + * The i915 workqueue is primarily used for batched retirement of + * requests (and thus managing bo) once the task has been completed + * by the GPU. i915_gem_retire_requests() is called directly when we + * need high-priority retirement, such as waiting for an explicit + * bo. + * + * It is also used for periodic low-priority events, such as + * idle-timers and recording error state. + * + * All tasks on the workqueue are expected to acquire the dev mutex + * so there is no point in running more than one instance of the + * workqueue at any time. Use an ordered one. + */ + dev_priv->wq = alloc_ordered_workqueue("i915", 0); + if (dev_priv->wq == NULL) + goto out_err; + + dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); + if (dev_priv->hotplug.dp_wq == NULL) + goto out_free_wq; + + dev_priv->gpu_error.hangcheck_wq = + alloc_ordered_workqueue("i915-hangcheck", 0); + if (dev_priv->gpu_error.hangcheck_wq == NULL) + goto out_free_dp_wq; + + return 0; + +out_free_dp_wq: + destroy_workqueue(dev_priv->hotplug.dp_wq); +out_free_wq: + destroy_workqueue(dev_priv->wq); +out_err: + DRM_ERROR("Failed to allocate workqueues.\n"); + + return -ENOMEM; +} + +static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) +{ + destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); + destroy_workqueue(dev_priv->hotplug.dp_wq); + destroy_workqueue(dev_priv->wq); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -898,6 +946,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) mutex_init(&dev_priv->modeset_restore_lock); mutex_init(&dev_priv->av_mutex); + ret = i915_workqueues_init(dev_priv); + if (ret < 0) + goto out_free_priv; + intel_pm_setup(dev); intel_runtime_pm_get(dev_priv); @@ -992,41 +1044,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, aperture_size); - /* The i915 workqueue is primarily used for batched retirement of - * requests (and thus managing bo) once the task has been completed - * by the GPU. i915_gem_retire_requests() is called directly when we - * need high-priority retirement, such as waiting for an explicit - * bo. - * - * It is also used for periodic low-priority events, such as - * idle-timers and recording error state. - * - * All tasks on the workqueue are expected to acquire the dev mutex - * so there is no point in running more than one instance of the - * workqueue at any time. Use an ordered one. - */ - dev_priv->wq = alloc_ordered_workqueue("i915", 0); - if (dev_priv->wq == NULL) { - DRM_ERROR("Failed to create our workqueue.\n"); - ret = -ENOMEM; - goto out_mtrrfree; - } - - dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); - if (dev_priv->hotplug.dp_wq == NULL) { - DRM_ERROR("Failed to create our dp workqueue.\n"); - ret = -ENOMEM; - goto out_freewq; - } - - dev_priv->gpu_error.hangcheck_wq = - alloc_ordered_workqueue("i915-hangcheck", 0); - if (dev_priv->gpu_error.hangcheck_wq == NULL) { - DRM_ERROR("Failed to create our hangcheck workqueue.\n"); - ret = -ENOMEM; - goto out_freedpwq; - } - intel_irq_init(dev_priv); intel_uncore_sanitize(dev); @@ -1106,12 +1123,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_teardown_mchbar(dev); pm_qos_remove_request(&dev_priv->pm_qos); - destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); -out_freedpwq: - destroy_workqueue(dev_priv->hotplug.dp_wq); -out_freewq: - destroy_workqueue(dev_priv->wq); -out_mtrrfree: arch_phys_wc_del(dev_priv->gtt.mtrr); io_mapping_free(dev_priv->gtt.mappable); out_gtt: @@ -1124,8 +1135,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) i915_gem_load_cleanup(dev); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); - + i915_workqueues_cleanup(dev_priv); +out_free_priv: kfree(dev_priv); + return ret; } @@ -1202,9 +1215,6 @@ int i915_driver_unload(struct drm_device *dev) intel_teardown_mchbar(dev); - destroy_workqueue(dev_priv->hotplug.dp_wq); - destroy_workqueue(dev_priv->wq); - destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); pm_qos_remove_request(&dev_priv->pm_qos); i915_global_gtt_cleanup(dev); @@ -1215,6 +1225,7 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); + i915_workqueues_cleanup(dev_priv); kfree(dev_priv); return 0; -- GitLab From ad5c3d3ffbb26094b0b76751aef4ee4e4854996c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:31 +0200 Subject: [PATCH 0444/5324] drm/i915: Move MCHBAR setup earlier during init Move the MCHBAR setup right after the MMIO setup, since the two things are logically related and the MCHBAR setup code doesn't depend on any other device specific resource. We'll also need MCHBAR to be ready earlier in an upcoming patch, so this is also a preparation for that. Factor out the init/clean-up code to separate functions to make things clearer in the i915_driver_load()/unload() functions. Suggested-by: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-7-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 71 +++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1446e6390227..697807d925c4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -904,6 +904,46 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) destroy_workqueue(dev_priv->wq); } +static int i915_mmio_setup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + int mmio_bar; + int mmio_size; + + mmio_bar = IS_GEN2(dev) ? 1 : 0; + /* + * Before gen4, the registers and the GTT are behind different BARs. + * However, from gen4 onwards, the registers and the GTT are shared + * in the same BAR, so we want to restrict this ioremap from + * clobbering the GTT which we want ioremap_wc instead. Fortunately, + * the register BAR remains the same size for all the earlier + * generations up to Ironlake. + */ + if (INTEL_INFO(dev)->gen < 5) + mmio_size = 512 * 1024; + else + mmio_size = 2 * 1024 * 1024; + dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); + if (dev_priv->regs == NULL) { + DRM_ERROR("failed to map registers\n"); + + return -EIO; + } + + /* Try to make sure MCHBAR is enabled before poking at it */ + intel_setup_mchbar(dev); + + return 0; +} + +static void i915_mmio_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + intel_teardown_mchbar(dev); + pci_iounmap(dev->pdev, dev_priv->regs); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -919,7 +959,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; struct intel_device_info *info, *device_info; - int ret = 0, mmio_bar, mmio_size; + int ret = 0; uint32_t aperture_size; info = (struct intel_device_info *) flags; @@ -971,25 +1011,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_runtime_pm_put; } - mmio_bar = IS_GEN2(dev) ? 1 : 0; - /* Before gen4, the registers and the GTT are behind different BARs. - * However, from gen4 onwards, the registers and the GTT are shared - * in the same BAR, so we want to restrict this ioremap from - * clobbering the GTT which we want ioremap_wc instead. Fortunately, - * the register BAR remains the same size for all the earlier - * generations up to Ironlake. - */ - if (info->gen < 5) - mmio_size = 512*1024; - else - mmio_size = 2*1024*1024; - - dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); - if (!dev_priv->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -EIO; + ret = i915_mmio_setup(dev); + if (ret < 0) goto put_bridge; - } /* This must be called before any calls to HAS_PCH_* */ intel_detect_pch(dev); @@ -1047,8 +1071,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_irq_init(dev_priv); intel_uncore_sanitize(dev); - /* Try to make sure MCHBAR is enabled before poking at it */ - intel_setup_mchbar(dev); intel_opregion_setup(dev); i915_gem_load_init(dev); @@ -1129,7 +1151,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) i915_global_gtt_cleanup(dev); out_uncore_fini: intel_uncore_fini(dev); - pci_iounmap(dev->pdev, dev_priv->regs); + i915_mmio_cleanup(dev); put_bridge: pci_dev_put(dev_priv->bridge_dev); i915_gem_load_cleanup(dev); @@ -1213,15 +1235,12 @@ int i915_driver_unload(struct drm_device *dev) intel_fbc_cleanup_cfb(dev_priv); i915_gem_cleanup_stolen(dev); - intel_teardown_mchbar(dev); - pm_qos_remove_request(&dev_priv->pm_qos); i915_global_gtt_cleanup(dev); intel_uncore_fini(dev); - if (dev_priv->regs != NULL) - pci_iounmap(dev->pdev, dev_priv->regs); + i915_mmio_cleanup(dev); i915_gem_load_cleanup(dev); pci_dev_put(dev_priv->bridge_dev); -- GitLab From a4eba47b25c7077b5b1473b950ae2ff9bcf19fd5 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 19 Jan 2016 15:26:32 +0200 Subject: [PATCH 0445/5324] drm/i915: Move stolen memory initialization earlier during loading The only device specific dependency of the stolen memory setup is the MMIO mapping and the stolen memory size. Both are already available in i915_gtt_init(), so move the stolen initialization to there. The clean-up code for i915_gtt_init() is in i915_global_gtt_cleanup(), so move the stolen memory clean-up code there too. This will be needed by an upcoming patch that needs the details of the memory we reserve, but the change is also part of our generic goal to move the initialization of resources with no or little dependencies on other device specific resources towards the beginning of the init sequence. Suggested-by: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1453209992-25995-8-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 10 ---------- drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 697807d925c4..db9b0c6840a0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -391,13 +391,6 @@ static int i915_load_modeset_init(struct drm_device *dev) if (ret) goto cleanup_vga_client; - /* Initialise stolen first so that we may reserve preallocated - * objects for the BIOS to KMS transition. - */ - ret = i915_gem_init_stolen(dev); - if (ret) - goto cleanup_vga_switcheroo; - intel_power_domains_init_hw(dev_priv, false); intel_csr_ucode_init(dev_priv); @@ -460,8 +453,6 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_teardown_gmbus(dev); cleanup_csr: intel_csr_ucode_fini(dev_priv); - i915_gem_cleanup_stolen(dev); -cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); @@ -1233,7 +1224,6 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); - i915_gem_cleanup_stolen(dev); pm_qos_remove_request(&dev_priv->pm_qos); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 7377b6725c33..2ccb2b52e3bb 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2809,6 +2809,8 @@ void i915_global_gtt_cleanup(struct drm_device *dev) ppgtt->base.cleanup(&ppgtt->base); } + i915_gem_cleanup_stolen(dev); + if (drm_mm_initialized(&vm->mm)) { if (intel_vgpu_active(dev)) intel_vgt_deballoon(); @@ -3181,6 +3183,14 @@ int i915_gem_gtt_init(struct drm_device *dev) if (ret) return ret; + /* + * Initialise stolen early so that we may reserve preallocated + * objects for the BIOS to KMS transition. + */ + ret = i915_gem_init_stolen(dev); + if (ret) + goto out_gtt_cleanup; + /* GMADR is the PCI mmio aperture into the global GTT. */ DRM_INFO("Memory usable by graphics device = %lluM\n", gtt->base.total >> 20); @@ -3200,6 +3210,11 @@ int i915_gem_gtt_init(struct drm_device *dev) DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); return 0; + +out_gtt_cleanup: + gtt->base.cleanup(&dev_priv->gtt.base); + + return ret; } void i915_gem_restore_gtt_mappings(struct drm_device *dev) -- GitLab From 7c1639e73bc9012a7f66476623836174a3e4763c Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Sat, 23 Jan 2016 16:18:17 +0100 Subject: [PATCH 0446/5324] ARM: dts: sunxi: Add sunxi-itead-core-common.dtsi Itead have a core module board that can be populated with either an Allwinner A10 or A20 SoC. This patch creates a common dtsi which these boards can use. Signed-off-by: Marcus Cooper Signed-off-by: Maxime Ripard --- .../arm/boot/dts/sunxi-itead-core-common.dtsi | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 arch/arm/boot/dts/sunxi-itead-core-common.dtsi diff --git a/arch/arm/boot/dts/sunxi-itead-core-common.dtsi b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi new file mode 100644 index 000000000000..2565d5137a17 --- /dev/null +++ b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi @@ -0,0 +1,136 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) 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 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. + */ + +#include "sunxi-common-regulators.dtsi" + +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; -- GitLab From d27415d4662386e1c81076957abca1788c3ff90b Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Sat, 23 Jan 2016 16:18:18 +0100 Subject: [PATCH 0447/5324] ARM: dts: sun7i: Add Itead Ibox support The Itead Ibox is a multi board device based on the Allwinner A20 SoC. It contains the A20 Itead Core module and a base board for the external interfaces. The core module comes with 4GB NAND and 1GB DDR RAM. The base board to which the core board is connected provides 3 USB 2.0 Host ports, 1 USB 2.0 OTG, 1 uSD slot, 10/100 Ethernet port, HDMI, IR receiver, SPDIF and a 32-pin GPIO header. This header expands the features of core board by exposing the VGA pins, audio In/Out pins, SATA, SPI, I2C, UARTS, USB-OTG and power. Signed-off-by: Marcus Cooper Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun7i-a20-itead-ibox.dts | 125 +++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 arch/arm/boot/dts/sun7i-a20-itead-ibox.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index e062fb36ca5b..58e461a038e8 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -666,6 +666,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-cubieboard2.dtb \ sun7i-a20-cubietruck.dtb \ sun7i-a20-hummingbird.dtb \ + sun7i-a20-itead-ibox.dtb \ sun7i-a20-i12-tvbox.dtb \ sun7i-a20-icnova-swac.dtb \ sun7i-a20-m3.dtb \ diff --git a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts new file mode 100644 index 000000000000..661c21d9bdbd --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts @@ -0,0 +1,125 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) 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 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. + */ + +/dts-v1/; +#include "sun7i-a20.dtsi" +#include "sunxi-itead-core-common.dtsi" + +/ { + model = "Itead Ibox A20"; + compatible = "itead,itead-ibox-a20", "allwinner,sun7i-a20"; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_itead_core>; + + green { + label = "itead_core:green:usr"; + gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + blue { + label = "itead_core:blue:usr"; + gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&codec { + status = "okay"; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_mii_a>; + phy = <&phy1>; + phy-mode = "mii"; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&i2c0 { + axp209: pmic@34 { + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&ir0 { + pinctrl-names = "default"; + pinctrl-0 = <&ir0_rx_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ + cd-inverted; + status = "okay"; +}; + +&pio { + led_pins_itead_core: led_pins@0 { + allwinner,pins = "PH20","PH21"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_ahci_5v { + status = "okay"; +}; -- GitLab From deb74a24eb02aa7ae40b4be6fae0add522d3f7bb Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Sat, 23 Jan 2016 16:18:19 +0100 Subject: [PATCH 0448/5324] ARM: dts: sun4i: Itead Iteaduino to use common code Convert the Itead Iteaduino A10 to use the new common itead core dtsi. Signed-off-by: Marcus Cooper Signed-off-by: Maxime Ripard --- .../dts/sun4i-a10-itead-iteaduino-plus.dts | 86 +------------------ 1 file changed, 2 insertions(+), 84 deletions(-) diff --git a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts index 985e15503378..4e798f014c99 100644 --- a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts +++ b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts @@ -1,5 +1,6 @@ /* * Copyright 2015 Josef Gajdusek + * Copyright 2015 - Marcus Cooper * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -42,22 +43,11 @@ /dts-v1/; #include "sun4i-a10.dtsi" -#include "sunxi-common-regulators.dtsi" - -#include -#include +#include "sunxi-itead-core-common.dtsi" / { model = "Iteaduino Plus A10"; compatible = "itead,iteaduino-plus-a10", "allwinner,sun4i-a10"; - - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; }; &ahci { @@ -65,18 +55,6 @@ status = "okay"; }; -&cpu0 { - cpu-supply = <®_dcdc2>; -}; - -&ehci0 { - status = "okay"; -}; - -&ehci1 { - status = "okay"; -}; - &emac { pinctrl-names = "default"; pinctrl-0 = <&emac_pins_a>; @@ -89,12 +67,7 @@ }; &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; - axp209: pmic@34 { - reg = <0x34>; interrupts = <0>; }; }; @@ -135,68 +108,13 @@ status = "okay"; }; -&ohci0 { - status = "okay"; -}; - -&ohci1 { - status = "okay"; -}; - ®_ahci_5v { status = "okay"; }; -#include "axp209.dtsi" - -®_dcdc2 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1450000>; - regulator-name = "vdd-cpu"; -}; - -®_dcdc3 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1400000>; - regulator-name = "vdd-int-dll"; -}; - -®_ldo1 { - regulator-name = "vdd-rtc"; -}; - -®_ldo2 { - regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "avcc"; -}; - -®_usb1_vbus { - status = "okay"; -}; - -®_usb2_vbus { - status = "okay"; -}; - &spi0 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>; status = "okay"; }; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -}; - -&usbphy { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; - status = "okay"; -}; -- GitLab From b3e919e03ce84d9768c0e1c12066f502c5bbd485 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:38 +0800 Subject: [PATCH 0449/5324] clk: sunxi: factors: Make struct clk_factors_config table const struct clk_factors_config contains shifts/widths for the factors of the factors clk. This is used to read out the factors from the register value. In no case is it written to, so make it const. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 4 ++-- drivers/clk/sunxi/clk-factors.h | 4 ++-- drivers/clk/sunxi/clk-mod0.c | 2 +- drivers/clk/sunxi/clk-sun9i-core.c | 8 ++++---- drivers/clk/sunxi/clk-sunxi.c | 16 ++++++++-------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 59428dbd607a..928c079da193 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -48,7 +48,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, u32 reg; unsigned long rate; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; /* Fetch the register value */ reg = readl(factors->reg); @@ -123,7 +123,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, u8 n = 0, k = 0, m = 0, p = 0; u32 reg; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; unsigned long flags = 0; factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 171085ab5513..060319be2b99 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -23,7 +23,7 @@ struct factors_data { int enable; int mux; int muxmask; - struct clk_factors_config *table; + const struct clk_factors_config *table; void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); const char *name; }; @@ -31,7 +31,7 @@ struct factors_data { struct clk_factors { struct clk_hw hw; void __iomem *reg; - struct clk_factors_config *config; + const struct clk_factors_config *config; void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); spinlock_t *lock; }; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index d167e1efb927..c67fea1a128d 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -62,7 +62,7 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, } /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun4i_a10_mod0_config = { +static const struct clk_factors_config sun4i_a10_mod0_config = { .mshift = 0, .mwidth = 4, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 6c4c98324d3c..37c85caaef88 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -71,7 +71,7 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, *p_ret = p; } -static struct clk_factors_config sun9i_a80_pll4_config = { +static const struct clk_factors_config sun9i_a80_pll4_config = { .mshift = 18, .mwidth = 1, .nshift = 8, @@ -134,7 +134,7 @@ static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, *m = div; } -static struct clk_factors_config sun9i_a80_gt_config = { +static const struct clk_factors_config sun9i_a80_gt_config = { .mshift = 0, .mwidth = 2, }; @@ -199,7 +199,7 @@ static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, *p = _p; } -static struct clk_factors_config sun9i_a80_ahb_config = { +static const struct clk_factors_config sun9i_a80_ahb_config = { .pshift = 0, .pwidth = 2, }; @@ -289,7 +289,7 @@ static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, *p = calcp; } -static struct clk_factors_config sun9i_a80_apb1_config = { +static const struct clk_factors_config sun9i_a80_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5ba2188ee99c..3609f080cc9a 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -608,7 +608,7 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, * sunxi_factors_clk_setup() - Setup function for factor clocks */ -static struct clk_factors_config sun4i_pll1_config = { +static const struct clk_factors_config sun4i_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -619,7 +619,7 @@ static struct clk_factors_config sun4i_pll1_config = { .pwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll1_config = { +static const struct clk_factors_config sun6i_a31_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -629,7 +629,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun8i_a23_pll1_config = { +static const struct clk_factors_config sun8i_a23_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -641,14 +641,14 @@ static struct clk_factors_config sun8i_a23_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun4i_pll5_config = { +static const struct clk_factors_config sun4i_pll5_config = { .nshift = 8, .nwidth = 5, .kshift = 4, .kwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll6_config = { +static const struct clk_factors_config sun6i_a31_pll6_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -656,12 +656,12 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .n_start = 1, }; -static struct clk_factors_config sun5i_a13_ahb_config = { +static const struct clk_factors_config sun5i_a13_ahb_config = { .pshift = 4, .pwidth = 2, }; -static struct clk_factors_config sun4i_apb1_config = { +static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, @@ -669,7 +669,7 @@ static struct clk_factors_config sun4i_apb1_config = { }; /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun7i_a20_out_config = { +static const struct clk_factors_config sun7i_a20_out_config = { .mshift = 8, .mwidth = 5, .pshift = 20, -- GitLab From 14628e4444ea8b5ea058e1bd663ff62f2e731feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 26 Dec 2015 00:40:12 +0100 Subject: [PATCH 0450/5324] ARM: dts: n900: Include adp1653 device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds adp1653 device into n900 DT structure. DT support in adp1653 driver is there since v4.2-rc1 version. Signed-off-by: Pali Rohár Acked-by: Pavel Machek Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-n900.dts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 74d8f7eb5563..20603f3f9bd0 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -522,6 +522,21 @@ amstaos,cover-comp-gain = <16>; }; + adp1653: led-controller@30 { + compatible = "adi,adp1653"; + reg = <0x30>; + enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; /* 88 */ + + flash { + flash-timeout-us = <500000>; + flash-max-microamp = <320000>; + led-max-microamp = <50000>; + }; + indicator { + led-max-microamp = <17500>; + }; + }; + lp5523: lp5523@32 { compatible = "national,lp5523"; reg = <0x32>; -- GitLab From 9ee9e281fce92af834e4aa1e017dbca397355f1c Mon Sep 17 00:00:00 2001 From: M'boumba Cedric Madianga Date: Fri, 16 Oct 2015 15:59:00 +0200 Subject: [PATCH 0451/5324] ARM: dts: Add STM32 DMA support for STM32F429 MCU This patch adds STM32 DMA bindings for STM32F429. Signed-off-by: M'boumba Cedric Madianga Signed-off-by: Maxime Coquelin --- arch/arm/boot/dts/stm32f429.dtsi | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 5e1e234e8c0a..eaf7a7242993 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -175,6 +175,37 @@ clocks = <&clk_hse>; }; + dma1: dma-controller@40026000 { + compatible = "st,stm32-dma"; + reg = <0x40026000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&rcc 0 21>; + #dma-cells = <4>; + }; + + dma2: dma-controller@40026400 { + compatible = "st,stm32-dma"; + reg = <0x40026400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&rcc 0 22>; + #dma-cells = <4>; + st,mem2mem; + }; + rng: rng@50060800 { compatible = "st,stm32-rng"; reg = <0x50060800 0x400>; -- GitLab From 78ca95c76900e7587d6e076f8162a440f19431ae Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:39 +0800 Subject: [PATCH 0452/5324] clk: sunxi: factors: Add clk cleanup in sunxi_factors_register() error path sunxi_factors_register() does not check for failures or cleanup after clk_register_composite() or other clk-related calls. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 44 ++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 928c079da193..3a18abfb6e09 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -172,7 +172,7 @@ struct clk *sunxi_factors_register(struct device_node *node, struct clk_hw *mux_hw = NULL; const char *clk_name = node->name; const char *parents[FACTORS_MAX_PARENTS]; - int i = 0; + int ret, i = 0; /* if we have a mux, we will have >1 parents */ i = of_clk_parent_fill(node, parents, FACTORS_MAX_PARENTS); @@ -188,7 +188,7 @@ struct clk *sunxi_factors_register(struct device_node *node, factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); if (!factors) - return NULL; + goto err_factors; /* set up factors properties */ factors->reg = reg; @@ -199,10 +199,8 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a gate if this factor clock can be gated */ if (data->enable) { gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); - if (!gate) { - kfree(factors); - return NULL; - } + if (!gate) + goto err_gate; /* set up gate properties */ gate->reg = reg; @@ -214,11 +212,8 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a mux if this factor clock can be muxed */ if (data->mux) { mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(factors); - kfree(gate); - return NULL; - } + if (!mux) + goto err_mux; /* set up gate properties */ mux->reg = reg; @@ -233,11 +228,30 @@ struct clk *sunxi_factors_register(struct device_node *node, mux_hw, &clk_mux_ops, &factors->hw, &clk_factors_ops, gate_hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) + goto err_register; - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) + goto err_provider; + + ret = clk_register_clkdev(clk, clk_name, NULL); + if (ret) + goto err_clkdev; return clk; + +err_clkdev: + of_clk_del_provider(node); +err_provider: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_register: + kfree(mux); +err_mux: + kfree(gate); +err_gate: + kfree(factors); +err_factors: + return NULL; } -- GitLab From 4cbeaebb8af1c86691d1a2d3328d82a01f4380a5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:40 +0800 Subject: [PATCH 0453/5324] clk: sunxi: factors: Add unregister function sunxi's factors clk did not have an unregister function. This means multiple structs were leaked whenever a factors clk was unregistered. Add an unregister function for it. Also keep pointers to the mux and gate structs so they can be freed. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 25 +++++++++++++++++++++++++ drivers/clk/sunxi/clk-factors.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 3a18abfb6e09..a6571177a5c4 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -202,6 +202,8 @@ struct clk *sunxi_factors_register(struct device_node *node, if (!gate) goto err_gate; + factors->gate = gate; + /* set up gate properties */ gate->reg = reg; gate->bit_idx = data->enable; @@ -215,6 +217,8 @@ struct clk *sunxi_factors_register(struct device_node *node, if (!mux) goto err_mux; + factors->mux = mux; + /* set up gate properties */ mux->reg = reg; mux->shift = data->mux; @@ -255,3 +259,24 @@ struct clk *sunxi_factors_register(struct device_node *node, err_factors: return NULL; } + +void sunxi_factors_unregister(struct device_node *node, struct clk *clk) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct clk_factors *factors; + const char *name; + + if (!hw) + return; + + factors = to_clk_factors(hw); + name = clk_hw_get_name(hw); + + /* No unregister call for clkdev_* */ + of_clk_del_provider(node); + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); + kfree(factors->mux); + kfree(factors->gate); + kfree(factors); +} diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 060319be2b99..7ea1379a7cda 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -34,6 +34,9 @@ struct clk_factors { const struct clk_factors_config *config; void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); spinlock_t *lock; + /* for cleanup */ + struct clk_mux *mux; + struct clk_gate *gate; }; struct clk *sunxi_factors_register(struct device_node *node, @@ -41,4 +44,6 @@ struct clk *sunxi_factors_register(struct device_node *node, spinlock_t *lock, void __iomem *reg); +void sunxi_factors_unregister(struct device_node *node, struct clk *clk); + #endif -- GitLab From cfa63688603398e8de4315cd626f81516c88a4c4 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:42 +0800 Subject: [PATCH 0454/5324] clk: sunxi: factors: Consolidate get_factors parameters into a struct The .get_factors callback of factors_clk has 6 parameters. To extend factors_clk in any way that requires adding parameters to .get_factors would make that list even longer, not to mention changing all the function declarations. Do this once now and consolidate all the parameters into a struct. Also drop the space before function pointer arguments, since checkpatch complains. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 24 ++-- drivers/clk/sunxi/clk-factors.h | 13 +- drivers/clk/sunxi/clk-mod0.c | 20 +-- drivers/clk/sunxi/clk-sun8i-mbus.c | 18 +-- drivers/clk/sunxi/clk-sun9i-core.c | 77 ++++------ drivers/clk/sunxi/clk-sunxi.c | 222 ++++++++++++----------------- 6 files changed, 155 insertions(+), 219 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index a6571177a5c4..4a8e36a53287 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -73,8 +73,13 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct clk_factors *factors = to_clk_factors(hw); - factors->get_factors((u32 *)&rate, (u32)*parent_rate, - NULL, NULL, NULL, NULL); + struct factors_request req = { + .rate = rate, + .parent_rate = *parent_rate, + }; + + factors->get_factors(&req); + return rate; } @@ -120,13 +125,16 @@ static int clk_factors_determine_rate(struct clk_hw *hw, static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u8 n = 0, k = 0, m = 0, p = 0; + struct factors_request req = { + .rate = rate, + .parent_rate = parent_rate, + }; u32 reg; struct clk_factors *factors = to_clk_factors(hw); const struct clk_factors_config *config = factors->config; unsigned long flags = 0; - factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); + factors->get_factors(&req); if (factors->lock) spin_lock_irqsave(factors->lock, flags); @@ -135,10 +143,10 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, reg = readl(factors->reg); /* Set up the new factors - macros do not do anything if width is 0 */ - reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); - reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); - reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); - reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); + reg = FACTOR_SET(config->nshift, config->nwidth, reg, req.n); + reg = FACTOR_SET(config->kshift, config->kwidth, reg, req.k); + reg = FACTOR_SET(config->mshift, config->mwidth, reg, req.m); + reg = FACTOR_SET(config->pshift, config->pwidth, reg, req.p); /* Apply them now */ writel(reg, factors->reg); diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 7ea1379a7cda..f09d7c214533 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -19,12 +19,21 @@ struct clk_factors_config { u8 n_start; }; +struct factors_request { + unsigned long rate; + unsigned long parent_rate; + u8 n; + u8 k; + u8 m; + u8 p; +}; + struct factors_data { int enable; int mux; int muxmask; const struct clk_factors_config *table; - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); + void (*getter)(struct factors_request *req); const char *name; }; @@ -32,7 +41,7 @@ struct clk_factors { struct clk_hw hw; void __iomem *reg; const struct clk_factors_config *config; - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); + void (*get_factors)(struct factors_request *req); spinlock_t *lock; /* for cleanup */ struct clk_mux *mux; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index c67fea1a128d..578bff0dd251 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -28,17 +28,16 @@ * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_a10_get_mod0_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 16) calcp = 0; @@ -51,14 +50,9 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /* user manual says "n" but it's really "p" */ diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index bf117a636d23..78683f02a37d 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -26,8 +26,7 @@ * rate = parent_rate / (m + 1); */ -static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_mbus_factors(struct factors_request *req) { u8 div; @@ -35,21 +34,16 @@ static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, * These clocks can only divide, so we will never be able to * achieve frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div > 8) div = 8; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (m == NULL) - return; - - *m = div - 1; + req->rate = req->parent_rate / div; + req->m = div - 1; } static struct clk_factors_config sun8i_a23_mbus_config = { diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 37c85caaef88..a81211062ecb 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -32,15 +32,14 @@ * p and m are named div1 and div2 in Allwinner's SDK */ -static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, - u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret) +static void sun9i_a80_get_pll4_factors(struct factors_request *req) { int n; int m = 1; int p = 1; /* Normalize value to a 6 MHz multiple (24 MHz / 4) */ - n = DIV_ROUND_UP(*freq, 6000000); + n = DIV_ROUND_UP(req->rate, 6000000); /* If n is too large switch to steps of 12 MHz */ if (n > 255) { @@ -60,15 +59,10 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, else if (n < 12) n = 12; - *freq = ((24000000 * n) >> p) / (m + 1); - - /* we were called to round the frequency, we can now return */ - if (n_ret == NULL) - return; - - *n_ret = n; - *m_ret = m; - *p_ret = p; + req->rate = ((24000000 * n) >> p) / (m + 1); + req->n = n; + req->m = m; + req->p = p; } static const struct clk_factors_config sun9i_a80_pll4_config = { @@ -111,27 +105,21 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se * rate = parent_rate / (m + 1); */ -static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_gt_factors(struct factors_request *req) { u32 div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* maximum divider is 4 */ if (div > 4) div = 4; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (!m) - return; - - *m = div; + req->rate = req->parent_rate / div; + req->m = div; } static const struct clk_factors_config sun9i_a80_gt_config = { @@ -176,27 +164,21 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); * rate = parent_rate >> p; */ -static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_ahb_factors(struct factors_request *req) { u32 _p; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* maximum p is 3 */ if (_p > 3) _p = 3; - *freq = parent_rate >> _p; - - /* we were called to round the frequency, we can now return */ - if (!p) - return; - - *p = _p; + req->rate = req->parent_rate >> _p; + req->p = _p; } static const struct clk_factors_config sun9i_a80_ahb_config = { @@ -262,31 +244,22 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se * rate = (parent_rate >> p) / (m + 1); */ -static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_apb1_factors(struct factors_request *req) { u32 div; - u8 calcm, calcp; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Highest possible divider is 256 (p = 3, m = 31) */ if (div > 256) div = 256; - calcp = order_base_2(div); - calcm = (parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->p = order_base_2(div); + req->m = (req->parent_rate >> req->p) - 1; + req->rate = (req->parent_rate >> req->p) / (req->m + 1); } static const struct clk_factors_config sun9i_a80_apb1_config = { diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 3609f080cc9a..a57c36c104dc 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -246,49 +246,45 @@ CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_se * parent_rate is always 24Mhz */ -static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 3 for divs under 10 */ if (div < 10) - *p = 3; + req->p = 3; /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ else if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4; } /** @@ -297,15 +293,14 @@ static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); * parent_rate should always be 24MHz */ -static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll1_factors(struct factors_request *req) { /* * We can operate only on MHz, this will make our life easier * later. */ - u32 freq_mhz = *freq / 1000000; - u32 parent_freq_mhz = parent_rate / 1000000; + u32 freq_mhz = req->rate / 1000000; + u32 parent_freq_mhz = req->parent_rate / 1000000; /* * Round down the frequency to the closest multiple of either @@ -319,28 +314,20 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, else freq_mhz = round_freq_16; - *freq = freq_mhz * 1000000; - - /* - * If the factors pointer are null, we were just called to - * round down the frequency. - * Exit. - */ - if (n == NULL) - return; + req->rate = freq_mhz * 1000000; /* If the frequency is a multiple of 32 MHz, k is always 3 */ if (!(freq_mhz % 32)) - *k = 3; + req->k = 3; /* If the frequency is a multiple of 9 MHz, k is always 2 */ else if (!(freq_mhz % 9)) - *k = 2; + req->k = 2; /* If the frequency is a multiple of 8 MHz, k is always 1 */ else if (!(freq_mhz % 8)) - *k = 1; + req->k = 1; /* Otherwise, we don't use the k factor */ else - *k = 0; + req->k = 0; /* * If the frequency is a multiple of 2 but not a multiple of @@ -351,27 +338,28 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * somehow relates to this frequency. */ if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) - *m = 2; + req->m = 2; /* * If the frequency is a multiple of 6MHz, but the factor is * odd, m will be 3 */ else if ((freq_mhz / 6) & 1) - *m = 3; + req->m = 3; /* Otherwise, we end up with m = 1 */ else - *m = 1; + req->m = 1; /* Calculate n thanks to the above factors we already got */ - *n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1; + req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz) + - 1; /* * If n end up being outbound, and that we can still decrease * m, do it. */ - if ((*n + 1) > 31 && (*m + 1) > 1) { - *n = (*n + 1) / 2 - 1; - *m = (*m + 1) / 2 - 1; + if ((req->n + 1) > 31 && (req->m + 1) > 1) { + req->n = (req->n + 1) / 2 - 1; + req->m = (req->m + 1) / 2 - 1; } } @@ -382,45 +370,41 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 2 for divs under 20 and odd divs under 32 */ if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4 - 1; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4 - 1; } /** @@ -430,29 +414,24 @@ static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll5_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; if (div < 31) - *k = 0; + req->k = 0; else if (div / 2 < 31) - *k = 1; + req->k = 1; else if (div / 3 < 31) - *k = 2; + req->k = 2; else - *k = 3; + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + req->n = DIV_ROUND_UP(div, (req->k + 1)); } /** @@ -462,24 +441,19 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll6_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *k = div / 32; - if (*k > 3) - *k = 3; + req->k = div / 32; + if (req->k > 3) + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)) - 1; + req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1; } /** @@ -488,37 +462,32 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, * rate = parent_rate >> p */ -static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun5i_a13_get_ahb_factors(struct factors_request *req) { u32 div; /* divide only */ - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; /* * user manual says valid speed is 8k ~ 276M, but tests show it * can work at speeds up to 300M, just after reparenting to pll6 */ - if (*freq < 8000) - *freq = 8000; - if (*freq > 300000000) - *freq = 300000000; + if (req->rate < 8000) + req->rate = 8000; + if (req->rate > 300000000) + req->rate = 300000000; - div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* p = 0 ~ 3 */ if (div > 3) div = 3; - *freq = parent_rate >> div; + req->rate = req->parent_rate >> div; - /* we were called to round the frequency, we can now return */ - if (p == NULL) - return; - - *p = div; + req->p = div; } /** @@ -527,39 +496,34 @@ static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_apb1_factors(struct factors_request *req) { u8 calcm, calcp; + int div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - parent_rate = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Invalid rate! */ - if (parent_rate > 32) + if (div > 32) return; - if (parent_rate <= 4) + if (div <= 4) calcp = 0; - else if (parent_rate <= 8) + else if (div <= 8) calcp = 1; - else if (parent_rate <= 16) + else if (div <= 16) calcp = 2; else calcp = 3; - calcm = (parent_rate >> calcp) - 1; - - *freq = (parent_rate >> calcp) / (calcm + 1); + calcm = (req->parent_rate >> calcp) - 1; - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / (calcm + 1); + req->m = calcm; + req->p = calcp; } @@ -571,17 +535,16 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun7i_a20_get_out_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 32) calcp = 0; @@ -594,14 +557,9 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /** -- GitLab From be8df3704ce86b784a2e3a3d04c62dbb5cc9eff6 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Sat, 17 Oct 2015 18:36:10 +0200 Subject: [PATCH 0455/5324] ARM: config: Enable GPIO Led driver in stm32_defconfig Acked-by: Linus Walleij Acked-by: Patrice Chotard Signed-off-by: Maxime Coquelin --- arch/arm/configs/stm32_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec5250547d14..1e5ec2a0e4cf 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -52,6 +52,7 @@ CONFIG_SERIAL_STM32_CONSOLE=y # CONFIG_USB_SUPPORT is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_DMADEVICES=y -- GitLab From 12e47442c2a1322c2762072fd6ea07462f1b04ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 26 Dec 2015 00:32:25 +0100 Subject: [PATCH 0456/5324] ARM: dts: omap3: Include missing bandgap data for ti-soc-thermal driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver for omap3 with documentation is there since v4.4-rc1. Signed-off-by: Pali Rohár Acked-by: Pavel Machek Tested-by: Pavel Machek [tony@atomide.com: added thermal-sensor-cells as suggested by Roger] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap34xx.dtsi | 6 ++++++ arch/arm/boot/dts/omap36xx.dtsi | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 4f6b2d5b1902..387dc31822fe 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -54,6 +54,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap34xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index 86253de5a97a..f19c87bd6bf3 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -86,6 +86,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap36xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; -- GitLab From 2ac6e66ed6dbd5bf167d994a78a041ed4c2db654 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Wed, 30 Dec 2015 13:41:33 +0200 Subject: [PATCH 0457/5324] ARM: dts: cm-t335: Add support for CAN bus Add CAN bus pinmux. Enable D_CAN bus controllers 0 and 1 The pinmux of uart1 node contradicts the pinmux of dcan0 and dcan1 nodes. U-Boot should delete the uart1 or dcan0/1 nodes. Signed-off-by: Uri Mashiach Acked-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-cm-t335.dts | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index 42e9b665582a..93997a2da8c1 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -134,6 +134,24 @@ >; }; + dcan0_pins: pinmux_dcan0_pins { + pinctrl-single,pins = < + /* uart1_ctsn.dcan0_tx */ + AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2) + /* uart1_rtsn.dcan0_rx */ + AM33XX_IOPAD(0x97C, PIN_INPUT | MUX_MODE2) + >; + }; + + dcan1_pins: pinmux_dcan1_pins { + pinctrl-single,pins = < + /* uart1_rxd.dcan1_tx */ + AM33XX_IOPAD(0x980, PIN_OUTPUT | MUX_MODE2) + /* uart1_txd.dcan1_rx */ + AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE2) + >; + }; + ecap0_pins: pinmux_ecap0_pins { pinctrl-single,pins = < /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ @@ -394,3 +412,15 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; }; + +&dcan0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan0_pins>; +}; + +&dcan1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan1_pins>; +}; -- GitLab From 511fc6d85b6bc6c28b830d082ebeeb5dcea4563b Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Wed, 30 Dec 2015 13:41:34 +0200 Subject: [PATCH 0458/5324] ARM: dts: cm-t335: add touchscreen support Touchscreen and analog digital converter configurations. Signed-off-by: Uri Mashiach Acked-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-cm-t335.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index 93997a2da8c1..f0c880ff33a6 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -424,3 +424,20 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dcan1_pins>; }; + +/* Touschscreen and analog digital converter */ +&tscadc { + status = "okay"; + tsc { + ti,wires = <4>; + ti,x-plate-resistance = <200>; + ti,coordinate-readouts = <5>; + ti,wire-config = <0x01 0x10 0x23 0x32>; + ti,charge-delay = <0x400>; + }; + + adc { + ti,adc-channels = <4 5 6 7>; + }; +}; + -- GitLab From 48ab364478e77ab36798eb8fff385edb3eddc357 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Wed, 30 Dec 2015 13:41:35 +0200 Subject: [PATCH 0459/5324] ARM: dts: cm-t335: add audio support The TLV320AIC23B codec is connected to the CPU by McASP controller 1 for data and I2C0 for control. Modifications: - Enable and configure McASP controller 1. - Add TLV320AIC23B codec pinmux. - Add TLV320AIC23B codec configurations. - Use simple-audio-card as CPU to codec glue. Signed-off-by: Uri Mashiach Acked-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-cm-t335.dts | 69 ++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index f0c880ff33a6..af6dbba093f3 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -46,6 +46,36 @@ brightness-levels = <0 51 53 56 62 75 101 152 255>; default-brightness-level = <8>; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "cm-t335"; + + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Headphone", "Headphone Jack"; + + simple-audio-card,routing = + "Headphone Jack", "LHPOUT", + "Headphone Jack", "RHPOUT", + "LLINEIN", "Line In", + "RLINEIN", "Line In", + "MICIN", "Mic Jack"; + + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&tlv320aic23>; + system-clock-frequency = <12000000>; + }; + }; }; &am33xx_pinmux { @@ -248,6 +278,20 @@ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7) >; }; + + /* TLV320AIC23B codec */ + mcasp1_pins: pinmux_mcasp1_pins { + pinctrl-single,pins = < + /* MII1_CRS.mcasp1_aclkx */ + AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_RX_ER.mcasp1_fsx */ + AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_COL.mcasp1_axr2 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* RMII1_REF_CLK.mcasp1_axr3 */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) + >; + }; }; &uart0 { @@ -282,6 +326,13 @@ status = "okay"; compatible = "emmicro,em3027"; reg = <0x56>; }; + /* Audio codec */ + tlv320aic23: codec@1a { + compatible = "ti,tlv320aic23"; + reg = <0x1a>; + #sound-dai-cells= <0>; + status = "okay"; + }; }; &usb { @@ -441,3 +492,21 @@ status = "okay"; }; }; +/* CPU audio */ +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcasp1_pins>; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 16 serializers */ + num-serializer = <16>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; + + #sound-dai-cells= <0>; + status = "okay"; +}; -- GitLab From 444d66fafab89195a75752bbefb48b030bd24740 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Wed, 30 Dec 2015 15:35:33 +0200 Subject: [PATCH 0460/5324] ARM: dts: add spi wifi support to cm-t335 Device tree modifications: - Pinmux for SPI0 and WiFi GPIOs. - SPI0 node with wlcore as a child node. Signed-off-by: Uri Mashiach Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-cm-t335.dts | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index af6dbba093f3..5d5fb62d8fbe 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "am33xx.dtsi" +#include / { model = "CompuLab CM-T335"; @@ -40,6 +41,15 @@ regulator-max-microvolt = <3300000>; }; + /* Regulator for WiFi */ + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vwlan_fixed"; + gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */ + enable-active-high; + regulator-boot-off; + }; + backlight { compatible = "pwm-backlight"; pwms = <&ecap0 0 50000 0>; @@ -271,6 +281,21 @@ >; }; + spi0_pins: pinmux_spi0_pins { + pinctrl-single,pins = < + /* spi0_sclk.spi0_sclk */ + AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0) + /* spi0_d0.spi0_d0 */ + AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0) + /* spi0_d1.spi0_d1 */ + AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0) + /* spi0_cs0.spi0_cs0 */ + AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0) + /* spi0_cs1.spi0_cs1 */ + AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0) + >; + }; + /* wl1271 bluetooth */ bluetooth_pins: pinmux_bluetooth_pins { pinctrl-single,pins = < @@ -292,6 +317,16 @@ AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) >; }; + + /* wl1271 WiFi */ + wifi_pins: pinmux_wifi_pins { + pinctrl-single,pins = < + /* EMU1.gpio3_8 - WiFi IRQ */ + AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7) + /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */ + AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7) + >; + }; }; &uart0 { @@ -510,3 +545,23 @@ status = "okay"; #sound-dai-cells= <0>; status = "okay"; }; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + ti,pindir-d0-out-d1-in = <1>; + /* WLS1271 WiFi */ + wlcore: wlcore@1 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pins>; + reg = <1>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupt-parent = <&gpio3>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + vwlan-supply = <&vwlan_fixed>; + }; +}; -- GitLab From 96d3bb1a0e0059d12d6ffb05fadeb3361b04b21e Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 9 Jan 2016 04:19:34 +0100 Subject: [PATCH 0461/5324] ARM: dts: N950: Add wlan support Add support for the wl1271 wlan chip. As far as I can see N9 uses the same chip with the same enable and irq gpio, but they use the mmc interface instead of the spi interface. Signed-off-by: Sebastian Reichel Acked-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-n950-n9.dtsi | 15 ++++++++++++++ arch/arm/boot/dts/omap3-n950.dts | 29 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index a2c2b8d8dd2c..ab1174bb409e 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -31,6 +31,14 @@ startup-delay-us = <150>; enable-active-high; }; + + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "VWLAN"; + gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>; /* gpio 35 */ + enable-active-high; + regulator-boot-off; + }; }; &omap3_pmx_core { @@ -44,6 +52,13 @@ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */ >; }; + + wlan_pins: pinmux_wlan_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE4) /* gpio 35 - wlan enable */ + OMAP3_CORE1_IOPAD(0x208a, PIN_INPUT | MUX_MODE4) /* gpio 42 - wlan irq */ + >; + }; }; &i2c1 { diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index 0885b34d5d7d..e5967262f28b 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -17,6 +17,17 @@ compatible = "nokia,omap3-n950", "ti,omap36xx", "ti,omap3"; }; +&omap3_pmx_core { + spi4_pins: pinmux_spi4_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */ + OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */ + OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */ + OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */ + >; + }; +}; + &i2c2 { smia_1: camera@10 { compatible = "nokia,smia"; @@ -53,3 +64,21 @@ }; }; }; + +&mcspi4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi4_pins>; + + wlcore: wlcore@0 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wlan_pins>; + reg = <0>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupts-extended = <&gpio2 10 IRQ_TYPE_LEVEL_HIGH>; /* gpio 42 */ + vwlan-supply = <&vwlan_fixed>; + }; +}; -- GitLab From fa65fc6b8ea7eee3dcf3529c7b61311386a98a02 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Wed, 14 Oct 2015 18:21:32 +0200 Subject: [PATCH 0462/5324] ARM: Kconfig: Introduce MACH_STM32F429 flag This patch introduces the MACH_STM32F429 to make possible to only select STM32F429 pinctrl driver. By default, all the MACH_STM32Fxxx flags will be set with STM32 defconfig. Acked-by: Patrice Chotard Acked-by: Linus Walleij Signed-off-by: Maxime Coquelin --- arch/arm/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4f799e567fc8..ca16120606ca 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -883,6 +883,11 @@ config ARCH_STM32 help Support for STMicroelectronics STM32 processors. +config MACH_STM32F429 + bool "STMicrolectronics STM32F429" + depends on ARCH_STM32 + default y + # Definitions to make life easier config ARCH_ACORN bool -- GitLab From f64e980450027e15dce5e9ec4ee19bab98aee4c5 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Wed, 14 Oct 2015 18:32:42 +0200 Subject: [PATCH 0463/5324] ARM: mach-stm32: Select pinctrl Acked-by: Linus Walleij Acked-by: Patrice Chotard Signed-off-by: Maxime Coquelin --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ca16120606ca..84b7291de5c2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -879,6 +879,7 @@ config ARCH_STM32 select ARCH_HAS_RESET_CONTROLLER select ARMV7M_SYSTICK select CLKSRC_STM32 + select PINCTRL select RESET_CONTROLLER help Support for STMicroelectronics STM32 processors. -- GitLab From febe6569fae4b5e663f0a31d9dbf054d3b588ff5 Mon Sep 17 00:00:00 2001 From: Jens Kuske Date: Wed, 27 Jan 2016 14:51:13 +0100 Subject: [PATCH 0464/5324] drivers: soc: sunxi: Fix mask generation for SRAM mapping GENMASK is inclusive on both ends, therefor one has to be subtracted from the width. Also fixes the mask for debug output. Signed-off-by: Jens Kuske Signed-off-by: Maxime Ripard --- drivers/soc/sunxi/sunxi_sram.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index bc52670c8f4b..99e354c8f53f 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -117,7 +117,7 @@ static int sunxi_sram_show(struct seq_file *s, void *data) val = readl(base + sram_data->reg); val >>= sram_data->offset; - val &= sram_data->width; + val &= GENMASK(sram_data->width - 1, 0); for (func = sram_data->func; func->func; func++) { seq_printf(s, "\t\t%s%c\n", func->func, @@ -208,7 +208,8 @@ int sunxi_sram_claim(struct device *dev) return -EBUSY; } - mask = GENMASK(sram_data->offset + sram_data->width, sram_data->offset); + mask = GENMASK(sram_data->offset + sram_data->width - 1, + sram_data->offset); val = readl(base + sram_data->reg); val &= ~mask; writel(val | ((device << sram_data->offset) & mask), -- GitLab From 145794121f0029f18b2754a91b0b313304167b39 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Wed, 21 Oct 2015 11:10:13 +0100 Subject: [PATCH 0465/5324] ARM: dts: Replace legacy *,wakeup property with wakeup-source on s5pv210 Though the keyboard and other driver will continue to support the legacy "gpio-key,wakeup", "linux,input-wakeup" boolean property to enable the wakeup source, "wakeup-source" is the new standard binding. This patch replaces all the legacy wakeup properties with the unified "wakeup-source" property in order to avoid any futher copy-paste duplication. Cc: Marek Szyprowski Signed-off-by: Sudeep Holla Reviewed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/s5pv210-aquila.dts | 4 ++-- arch/arm/boot/dts/s5pv210-goni.dts | 4 ++-- arch/arm/boot/dts/s5pv210-smdkv210.dts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts index aa64faa72970..da24ab570b0e 100644 --- a/arch/arm/boot/dts/s5pv210-aquila.dts +++ b/arch/arm/boot/dts/s5pv210-aquila.dts @@ -257,7 +257,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -268,7 +268,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts index 3b76eeeb8410..0a33d402138e 100644 --- a/arch/arm/boot/dts/s5pv210-goni.dts +++ b/arch/arm/boot/dts/s5pv210-goni.dts @@ -239,7 +239,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -250,7 +250,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts index da7d210df670..54fcc3fc82e2 100644 --- a/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -59,7 +59,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <8>; samsung,keypad-num-columns = <8>; pinctrl-names = "default"; -- GitLab From da536e276ded60084a24af47b97ed76741be7605 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 Jan 2016 11:17:16 -0600 Subject: [PATCH 0466/5324] ARM: imx_v6_v7_defconfig: enable psci default i.MX7D uboot support psci firmware. Enabled psci default. Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 2d5253dcc226..1e792efe139b 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -47,6 +47,7 @@ CONFIG_PCI=y CONFIG_PCI_MSI=y CONFIG_PCI_IMX6=y CONFIG_SMP=y +CONFIG_ARM_PSCI=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y CONFIG_HIGHMEM=y -- GitLab From cfefb762ad296331cc117a1067d8b09741bb86c4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Dubois Date: Sat, 26 Dec 2015 23:16:08 +0100 Subject: [PATCH 0467/5324] ARM: imx6: fix cleanup path in imx6q_suspend_init() The wrong pointer is passed to the ioumap function in the cleanup path Signed-off-by: Jean-Christophe Dubois Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/mach-imx/pm-imx6.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 4470376af5f8..58924b3844df 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -561,13 +561,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) goto put_node; pl310_cache_map_failed: - iounmap(&pm_info->gpc_base.vbase); + iounmap(pm_info->gpc_base.vbase); gpc_map_failed: - iounmap(&pm_info->iomuxc_base.vbase); + iounmap(pm_info->iomuxc_base.vbase); iomuxc_map_failed: - iounmap(&pm_info->src_base.vbase); + iounmap(pm_info->src_base.vbase); src_map_failed: - iounmap(&pm_info->mmdc_base.vbase); + iounmap(pm_info->mmdc_base.vbase); put_node: of_node_put(node); -- GitLab From 608f4f7e4e3d7dbc9d5bcaddf8663cc0560c4cd6 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 Jan 2016 11:17:15 -0600 Subject: [PATCH 0468/5324] ARM: imx: select HAVE_ARM_ARCH_TIMER if selected i.MX7D i.MX7D Supported ARCH Timer. Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 15df34fbdf44..da42fdf7470b 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -561,6 +561,7 @@ config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D select ARM_GIC + select HAVE_ARM_ARCH_TIMER select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC -- GitLab From e914ecebf12f39441c9d21c13dce728d6ff6a1f1 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 5 Jan 2016 11:17:17 -0600 Subject: [PATCH 0469/5324] ARM: imx7d: correct chip version information The commond 'cat /sys/devices/soc0/revision' can show correct soc version information. "unknow revision" message in imx_print_silicon_rev() will never work for digprog. Signed-off-by: Frank Li Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 231bb250c571..bd3555ee88c8 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -151,7 +151,14 @@ void __init imx_init_revision_from_anatop(void) revision = IMX_CHIP_REVISION_1_5; break; default: - revision = IMX_CHIP_REVISION_UNKNOWN; + /* + * Fail back to return raw register value instead of 0xff. + * It will be easy to know version information in SOC if it + * can't be recognized by known version. And some chip's (i.MX7D) + * digprog value match linux version format, so it needn't map + * again and we can use register value directly. + */ + revision = digprog & 0xff; } mxc_set_cpu_type(digprog >> 16 & 0xff); -- GitLab From 15b6b804b6e43297d9c05306554a39d8891966f9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Jan 2016 12:06:46 +0300 Subject: [PATCH 0470/5324] drm/vmwgfx: fix a NULL dereference We dereference "eaction->event" inside the call to drm_send_event_locked() so should hold off on setting it to NULL until afterward. Fixes: fb740cf2492c ("drm: Create drm_send_event helpers") Signed-off-by: Dan Carpenter Link: http://patchwork.freedesktop.org/patch/msgid/20160128090646.GA5824@mwanda Signed-off-by: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index e0edf149d9d5..37c305b62608 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -880,8 +880,8 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) } list_del_init(&eaction->fpriv_head); - eaction->event = NULL; drm_send_event_locked(dev, eaction->event); + eaction->event = NULL; spin_unlock_irqrestore(&dev->event_lock, irq_flags); } -- GitLab From d9da6aa035c6dfdb003ff9776532b9b356d83f15 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 27 Jan 2016 13:41:09 +0000 Subject: [PATCH 0471/5324] drm/i915: Fix VCS ring selection after uapi decoupling This got broken in: commit de1add360522c876c25ef2bbbbab1c94bdb509ab Author: Tvrtko Ursulin Date: Fri Jan 15 15:12:50 2016 +0000 drm/i915: Decouple execbuf uAPI from internal implementation BSD ring flags need to be shifted before they can be considered indices into the ring array. Reported by Zhipeng Gong. v2: Simplify the code. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Daniel Vetter Cc: Chris Wilson Cc: Zhipeng Gong Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1453902069-31353-1-git-send-email-tvrtko.ursulin@linux.intel.com Testcase: igt/gem_exec_basic # bdw-gt3 --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1 + include/uapi/drm/i915_drm.h | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 2dc08ce1079a..5cb57f642ac1 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1401,6 +1401,7 @@ eb_select_ring(struct drm_i915_private *dev_priv, bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file); } else if (bsd_idx >= I915_EXEC_BSD_RING1 && bsd_idx <= I915_EXEC_BSD_RING2) { + bsd_idx >>= I915_EXEC_BSD_SHIFT; bsd_idx--; } else { DRM_DEBUG("execbuf with unknown bsd ring: %u\n", diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 6a19371391fa..a5524cc95ff8 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -772,10 +772,12 @@ struct drm_i915_gem_execbuffer2 { #define I915_EXEC_HANDLE_LUT (1<<12) /** Used for switching BSD rings on the platforms with two BSD rings */ -#define I915_EXEC_BSD_MASK (3<<13) -#define I915_EXEC_BSD_DEFAULT (0<<13) /* default ping-pong mode */ -#define I915_EXEC_BSD_RING1 (1<<13) -#define I915_EXEC_BSD_RING2 (2<<13) +#define I915_EXEC_BSD_SHIFT (13) +#define I915_EXEC_BSD_MASK (3 << I915_EXEC_BSD_SHIFT) +/* default ping-pong mode */ +#define I915_EXEC_BSD_DEFAULT (0 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT) /** Tell the kernel that the batchbuffer is processed by * the resource streamer. -- GitLab From 4f0d20ec19691b034e4b80928b6454c9f9d5ef90 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 11 Dec 2015 15:05:56 +0900 Subject: [PATCH 0472/5324] ARM: dts: Make CPU configuration more readable on exynos542x/5800 Exynos5420 and Exynos5800 boards boot from big core (A15) but Exynos5422 boards choose otherwise: LITTLE core (A7) (on Exynos5422 this is property of the board - configurable by pulling up/down gpg2-1). To make user-visible CPU ordering more consistent the 'cpus' node was overridden by exynos5422-cpus.dtsi. However this is a little bit ugly and error-prone. Overriding the CPU child nodes requires to basically reverse what was done initially in exynos5420.dtsi. Instead, split CPU configuration entirely to separate files which should be included by board DTS. Suggested-by: Viresh Kumar Signed-off-by: Krzysztof Kozlowski Reviewed-by: Viresh Kumar Reviewed-by: Chanho Park --- arch/arm/boot/dts/exynos5420-arndale-octa.dts | 1 + arch/arm/boot/dts/exynos5420-cpus.dtsi | 92 +++++++++++++ arch/arm/boot/dts/exynos5420-peach-pit.dts | 1 + arch/arm/boot/dts/exynos5420-smdk5420.dts | 1 + arch/arm/boot/dts/exynos5420.dtsi | 72 +--------- arch/arm/boot/dts/exynos5422-cpus.dtsi | 130 ++++++++++-------- arch/arm/boot/dts/exynos5800-peach-pi.dts | 1 + 7 files changed, 170 insertions(+), 128 deletions(-) create mode 100644 arch/arm/boot/dts/exynos5420-cpus.dtsi diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 4ecef6981d5c..365eec6f6687 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include #include #include diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi new file mode 100644 index 000000000000..7aaf0313274f --- /dev/null +++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi @@ -0,0 +1,92 @@ +/* + * SAMSUNG EXYNOS5420 SoC cpu device tree source + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This file provides desired ordering for Exynos5420 and Exynos5800 + * boards: CPU[0123] being the A15. + * + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x0>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + + cpu4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; + + cpu5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; + + cpu6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; + + cpu7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 35cfb07dc4bb..61a0c0df337a 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pit Rev 6+"; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index ac35aefd320f..1935a0b671e9 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include / { diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 7c8a606d65aa..6c102c46af73 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -50,74 +50,10 @@ usbdrdphy1 = &usbdrd_phy1; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; - }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; - }; - - cpu2: cpu@2 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; - }; - - cpu3: cpu@3 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; - }; - - cpu4: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; - }; - - cpu5: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; - }; - - cpu6: cpu@102 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; - }; - - cpu7: cpu@103 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; - }; - }; + /* + * The 'cpus' node is not present here but instead it is provided + * by exynos5420-cpus.dtsi or exynos5422-cpus.dtsi. + */ cci: cci@10d20000 { compatible = "arm,cci-400"; diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi index b7f60c855459..33028ac76a33 100644 --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi @@ -4,78 +4,88 @@ * Copyright (c) 2015 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * The only difference between EXYNOS5422 and EXYNOS5800 is cpu ordering. The - * EXYNOS5422 is booting from Cortex-A7 core while the EXYNOS5800 is booting - * from Cortex-A15 core. + * This file provides desired ordering for Exynos5422: CPU[0123] being the A7. * - * EXYNOS5422 based board files can include this file to provide cpu ordering - * which could boot a cortex-a7 from cpu0. + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -&cpu0 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; -&cpu1 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu0: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; -&cpu2 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu1: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; -&cpu3 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu2: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; -&cpu4 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu3: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + }; -&cpu5 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu4: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x0>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; -&cpu6 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu5: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + + cpu6: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; -&cpu7 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + cpu7: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + }; + }; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 064176f201e7..279322b83351 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5800.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pi Rev 10+"; -- GitLab From 8b51c5e730fb66048f48437b17a024d2107347c3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Dec 2015 18:33:15 +0100 Subject: [PATCH 0473/5324] ARM: dts: Add cluster regulator supply properties for exynos542x/5800 Add cluster regulator supply properties as a preparation to adding generic cpufreq-dt driver support for Exynos542x and Exynos5800 based boards. Cc: Doug Anderson Cc: Javier Martinez Canillas Cc: Andreas Faerber Cc: Thomas Abraham Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Krzysztof Kozlowski Acked-by: Viresh Kumar Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5420-arndale-octa.dts | 8 ++++++++ arch/arm/boot/dts/exynos5420-peach-pit.dts | 8 ++++++++ arch/arm/boot/dts/exynos5420-smdk5420.dts | 8 ++++++++ arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 8 ++++++++ arch/arm/boot/dts/exynos5800-peach-pi.dts | 8 ++++++++ 5 files changed, 40 insertions(+) diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 365eec6f6687..762f6ffece0c 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -53,6 +53,14 @@ }; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &usbdrd_dwc3_1 { dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 61a0c0df337a..f7b31e16d07f 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -144,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 1935a0b671e9..0785fedf441e 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -90,6 +90,14 @@ }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { pinctrl-names = "default"; pinctrl-0 = <&dp_hpd>; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 9134217446b8..1bd507bfa750 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -67,6 +67,14 @@ <19200000>; }; +&cpu0 { + cpu-supply = <&buck6_reg>; +}; + +&cpu4 { + cpu-supply = <&buck2_reg>; +}; + &hdmi { status = "okay"; hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 279322b83351..4731dbb5b450 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -144,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; -- GitLab From 66a4a1fb2398cc03637394a6ddfd077a5ee2acf4 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 15 Dec 2015 18:33:17 +0100 Subject: [PATCH 0474/5324] ARM: dts: Add CPU OPP properties for exynos542x/5800 For Exynos542x/5800 platforms, add CPU operating points for migrating from Exynos specific cpufreq driver to using generic cpufreq driver. Changes by Bartlomiej: - split Exynos5420 support from the original patch - merged Exynos5422 fixes from Ben Changes by Ben Gamari: - Port to operating-points-v2 Cc: Doug Anderson Cc: Javier Martinez Canillas Cc: Andreas Faerber Signed-off-by: Thomas Abraham Signed-off-by: Ben Gamari Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Krzysztof Kozlowski Acked-by: Viresh Kumar Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5420-cpus.dtsi | 10 +++ arch/arm/boot/dts/exynos5420.dtsi | 110 +++++++++++++++++++++++++ arch/arm/boot/dts/exynos5422-cpus.dtsi | 10 +++ 3 files changed, 130 insertions(+) diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi index 7aaf0313274f..261d25173f61 100644 --- a/arch/arm/boot/dts/exynos5420-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi @@ -29,8 +29,10 @@ device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0x0>; + clocks = <&clock CLK_ARM_CLK>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu1: cpu@1 { @@ -39,6 +41,7 @@ reg = <0x1>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu2: cpu@2 { @@ -47,6 +50,7 @@ reg = <0x2>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu3: cpu@3 { @@ -55,14 +59,17 @@ reg = <0x3>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu4: cpu@100 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu5: cpu@101 { @@ -71,6 +78,7 @@ reg = <0x101>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu6: cpu@102 { @@ -79,6 +87,7 @@ reg = <0x102>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu7: cpu@103 { @@ -87,6 +96,7 @@ reg = <0x103>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; }; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 6c102c46af73..2a405544ea46 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -50,6 +50,116 @@ usbdrdphy1 = &usbdrd_phy1; }; + cluster_a15_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + opp@1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1250000>; + clock-latency-ns = <140000>; + }; + opp@1700000000 { + opp-hz = /bits/ 64 <1700000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; + }; + opp@1600000000 { + opp-hz = /bits/ 64 <1600000000>; + opp-microvolt = <1175000>; + clock-latency-ns = <140000>; + }; + opp@1500000000 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <1137500>; + clock-latency-ns = <140000>; + }; + opp@1400000000 { + opp-hz = /bits/ 64 <1400000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; + }; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; + }; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1037500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1012500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = < 987500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = < 962500>; + clock-latency-ns = <140000>; + }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = < 937500>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = < 912500>; + clock-latency-ns = <140000>; + }; + }; + + cluster_a7_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1275000>; + clock-latency-ns = <140000>; + }; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1162500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; + }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1025000>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <975000>; + clock-latency-ns = <140000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <937500>; + clock-latency-ns = <140000>; + }; + }; + /* * The 'cpus' node is not present here but instead it is provided * by exynos5420-cpus.dtsi or exynos5422-cpus.dtsi. diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi index 33028ac76a33..9b46b9fbac4e 100644 --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi @@ -28,8 +28,10 @@ device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu1: cpu@101 { @@ -38,6 +40,7 @@ reg = <0x101>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu2: cpu@102 { @@ -46,6 +49,7 @@ reg = <0x102>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu3: cpu@103 { @@ -54,14 +58,17 @@ reg = <0x103>; clock-frequency = <1000000000>; cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; }; cpu4: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a15"; + clocks = <&clock CLK_ARM_CLK>; reg = <0x0>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu5: cpu@1 { @@ -70,6 +77,7 @@ reg = <0x1>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu6: cpu@2 { @@ -78,6 +86,7 @@ reg = <0x2>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; cpu7: cpu@3 { @@ -86,6 +95,7 @@ reg = <0x3>; clock-frequency = <1800000000>; cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; }; }; }; -- GitLab From 4869710caedf5f7cc6a893846e4045d0f35ac737 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 15 Dec 2015 18:33:20 +0100 Subject: [PATCH 0475/5324] ARM: dts: Extend existing CPU OPP for exynos5800 Fix CPU operating points for Exynos5800 (it use different voltages than Exynos5420 and supports additional frequencies). However don't use 2000MHz & 1900MHz OPPs (for A15 cores) and 1400MHz OPP (for A7 cores) for now as they are not available on all boards. Based on Hardkernel's kernel for ODROID-XU3 board. Changes by Ben Gamari: - Port to operating-points-v2 Cc: Doug Anderson Cc: Javier Martinez Canillas Cc: Andreas Faerber Cc: Thomas Abraham Signed-off-by: Ben Gamari Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Krzysztof Kozlowski Acked-by: Viresh Kumar Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5800.dtsi | 108 ++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi index c0bb3563cac1..8213016803e5 100644 --- a/arch/arm/boot/dts/exynos5800.dtsi +++ b/arch/arm/boot/dts/exynos5800.dtsi @@ -23,6 +23,114 @@ compatible = "samsung,exynos5800-clock"; }; +&cluster_a15_opp_table { + opp@1700000000 { + opp-microvolt = <1250000>; + }; + opp@1600000000 { + opp-microvolt = <1250000>; + }; + opp@1500000000 { + opp-microvolt = <1100000>; + }; + opp@1400000000 { + opp-microvolt = <1100000>; + }; + opp@1300000000 { + opp-microvolt = <1100000>; + }; + opp@1200000000 { + opp-microvolt = <1000000>; + }; + opp@1100000000 { + opp-microvolt = <1000000>; + }; + opp@1000000000 { + opp-microvolt = <1000000>; + }; + opp@900000000 { + opp-microvolt = <1000000>; + }; + opp@800000000 { + opp-microvolt = <900000>; + }; + opp@700000000 { + opp-microvolt = <900000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + +&cluster_a7_opp_table { + opp@1300000000 { + opp-microvolt = <1250000>; + }; + opp@1200000000 { + opp-microvolt = <1250000>; + }; + opp@1100000000 { + opp-microvolt = <1250000>; + }; + opp@1000000000 { + opp-microvolt = <1100000>; + }; + opp@900000000 { + opp-microvolt = <1100000>; + }; + opp@800000000 { + opp-microvolt = <1100000>; + }; + opp@700000000 { + opp-microvolt = <1000000>; + }; + opp@600000000 { + opp-microvolt = <1000000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + &mfc { compatible = "samsung,mfc-v8"; }; -- GitLab From 5399eb9b39081d6d2fc1a13d4ea85f1ceb2c8b44 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Oct 2015 14:01:32 +0100 Subject: [PATCH 0476/5324] dtbsinstall: don't move target directory out of the way No other kernel installation target moves the target directory out of the way, even deleting an old version of it. These are destructive operations, ones which the kernel build system should not be making. This behaviour prevents being able to do: make install INSTALL_PATH=/some/path/boot make dtbs_install INSTALL_DTBS_PATH=/some/path/boot As it causes the boot directory containing the kernel installed in step 1 to be moved to /some/path/boot.old. Things get even more fun if you do: make install dtbs_install INSTALL_PATH=/some/path/boot INSTALL_DTBS_PATH=/some/path/boot The kernel gets installed into /some/path/boot, then the directory gets renamed to /some/path/boot.old, and a new directory created to hold the dtbs. Even more fun if you supply -j2 when we end up with races in make. Remove this behaviour. If this behaviour is required at installation time, this should be done by the installation external to the kernel makefiles, just like it would be done for 'make modules_install'. Signed-off-by: Russell King Acked-by: Jason Cooper Acked-by: Rob Herring Signed-off-by: Michal Marek --- scripts/Makefile.dtbinst | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index 1c15717e0d56..a1be75d0a5fd 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst @@ -23,8 +23,6 @@ include $(src)/Makefile PHONY += __dtbs_install_prep __dtbs_install_prep: ifeq ("$(dtbinst-root)", "$(obj)") - $(Q)if [ -d $(INSTALL_DTBS_PATH).old ]; then rm -rf $(INSTALL_DTBS_PATH).old; fi - $(Q)if [ -d $(INSTALL_DTBS_PATH) ]; then mv $(INSTALL_DTBS_PATH) $(INSTALL_DTBS_PATH).old; fi $(Q)mkdir -p $(INSTALL_DTBS_PATH) endif -- GitLab From 05053d7a56388d0f44aa388cfe11d1ee2e325f81 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 9 Dec 2015 09:07:35 +0100 Subject: [PATCH 0477/5324] ARM: dts: Add GSCL block parent clock management to pm domain on exynos542x Add support for restoring GScaler parent clocks configuration when GSCL power domain is turned on. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos5420.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 2a405544ea46..bb559d0cd956 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -298,8 +298,10 @@ compatible = "samsung,exynos4210-pd"; reg = <0x10044000 0x20>; #power-domain-cells = <0>; - clocks = <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; - clock-names = "asb0", "asb1"; + clocks = <&clock CLK_FIN_PLL>, + <&clock CLK_MOUT_USER_ACLK300_GSCL>, + <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; + clock-names = "oscclk", "clk0", "asb0", "asb1"; }; isp_pd: power-domain@10044020 { -- GitLab From bb07698fc8d13ec74f4f5bd87b04953777ee6982 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 26 Jan 2016 11:30:18 +0800 Subject: [PATCH 0478/5324] clk: rockchip: fix wrong mmc phase shift for rk3228 mmc sample shift is 0 for rk3228 refer to user manaul. So it's broken if we enable mmc tuning for rk3228. Fixes: 307a2e9ac ("clk: rockchip: add clock controller for rk3228") Signed-off-by: Shawn Lin Reviewed-by: Xing Zheng Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3228.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 981a50205339..97f49aab8d42 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -605,13 +605,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), - MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), - MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), - MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), }; static const char *const rk3228_critical_clocks[] __initconst = { -- GitLab From e5292823c142c9873d7d18cf34e7d97fd8a38f86 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 28 Jan 2016 10:29:54 +0000 Subject: [PATCH 0479/5324] drm/i915: Make LRC (un)pinning work on context and engine Previously intel_lr_context_(un)pin were operating on requests which is in conflict with their names. If we make them take a context and an engine, it makes the names make more sense and it also makes future fixes possible. v2: Rebase for default_context/kernel_context change. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Chris Wilson Cc: Nick Hoath --- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 49 ++++++++++++++++---------------- drivers/gpu/drm/i915/intel_lrc.h | 3 +- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c1bb6a61745c..a928823507c5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2680,7 +2680,7 @@ void i915_gem_request_free(struct kref *req_ref) if (ctx) { if (i915.enable_execlists && ctx != req->i915->kernel_context) - intel_lr_context_unpin(req); + intel_lr_context_unpin(ctx, req->ring); i915_gem_context_unreference(ctx); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index da97bc5666b5..6c95aa19cc90 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -225,7 +225,8 @@ enum { #define GEN8_CTX_ID_SHIFT 32 #define CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT 0x17 -static int intel_lr_context_pin(struct drm_i915_gem_request *rq); +static int intel_lr_context_pin(struct intel_context *ctx, + struct intel_engine_cs *engine); static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, struct drm_i915_gem_object *default_ctx_obj); @@ -598,7 +599,7 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) int num_elements = 0; if (request->ctx != request->i915->kernel_context) - intel_lr_context_pin(request); + intel_lr_context_pin(request->ctx, ring); i915_gem_request_reference(request); @@ -703,7 +704,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request } if (request->ctx != request->i915->kernel_context) - ret = intel_lr_context_pin(request); + ret = intel_lr_context_pin(request->ctx, request->ring); return ret; } @@ -1014,7 +1015,8 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring) ctx->engine[ring->id].state; if (ctx_obj && (ctx != req->i915->kernel_context)) - intel_lr_context_unpin(req); + intel_lr_context_unpin(ctx, ring); + list_del(&req->execlist_link); i915_gem_request_unreference(req); } @@ -1058,8 +1060,8 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) return 0; } -static int intel_lr_context_do_pin(struct intel_engine_cs *ring, - struct intel_context *ctx) +static int intel_lr_context_do_pin(struct intel_context *ctx, + struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1105,41 +1107,40 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, return ret; } -static int intel_lr_context_pin(struct drm_i915_gem_request *rq) +static int intel_lr_context_pin(struct intel_context *ctx, + struct intel_engine_cs *engine) { int ret = 0; - struct intel_engine_cs *ring = rq->ring; - if (rq->ctx->engine[ring->id].pin_count++ == 0) { - ret = intel_lr_context_do_pin(ring, rq->ctx); + if (ctx->engine[engine->id].pin_count++ == 0) { + ret = intel_lr_context_do_pin(ctx, engine); if (ret) goto reset_pin_count; } return ret; reset_pin_count: - rq->ctx->engine[ring->id].pin_count = 0; + ctx->engine[engine->id].pin_count = 0; return ret; } -void intel_lr_context_unpin(struct drm_i915_gem_request *rq) +void intel_lr_context_unpin(struct intel_context *ctx, + struct intel_engine_cs *engine) { - struct intel_engine_cs *ring = rq->ring; - struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; - struct intel_ringbuffer *ringbuf = rq->ringbuf; + struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; - WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex)); - if (!ctx_obj) + if (WARN_ON_ONCE(!ctx_obj)) return; - if (--rq->ctx->engine[ring->id].pin_count == 0) { - kunmap(kmap_to_page(rq->ctx->engine[ring->id].lrc_reg_state)); - intel_unpin_ringbuffer_obj(ringbuf); + if (--ctx->engine[engine->id].pin_count == 0) { + kunmap(kmap_to_page(ctx->engine[engine->id].lrc_reg_state)); + intel_unpin_ringbuffer_obj(ctx->engine[engine->id].ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); - rq->ctx->engine[ring->id].lrc_vma = NULL; - rq->ctx->engine[ring->id].lrc_desc = 0; - rq->ctx->engine[ring->id].lrc_reg_state = NULL; + ctx->engine[engine->id].lrc_vma = NULL; + ctx->engine[engine->id].lrc_desc = 0; + ctx->engine[engine->id].lrc_reg_state = NULL; } } @@ -2064,7 +2065,7 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) goto error; /* As this is the default context, always pin it */ - ret = intel_lr_context_do_pin(ring, dctx); + ret = intel_lr_context_do_pin(dctx, ring); if (ret) { DRM_ERROR( "Failed to pin and map ringbuffer %s: %d\n", diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 49af638f6213..e6cda3e225d0 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -101,7 +101,8 @@ void intel_lr_context_free(struct intel_context *ctx); uint32_t intel_lr_context_size(struct intel_engine_cs *ring); int intel_lr_context_deferred_alloc(struct intel_context *ctx, struct intel_engine_cs *ring); -void intel_lr_context_unpin(struct drm_i915_gem_request *req); +void intel_lr_context_unpin(struct intel_context *ctx, + struct intel_engine_cs *engine); void intel_lr_context_reset(struct drm_device *dev, struct intel_context *ctx); uint64_t intel_lr_context_descriptor(struct intel_context *ctx, -- GitLab From 321fe304f1dd2dca025141b1d3211415af59020f Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 28 Jan 2016 10:29:55 +0000 Subject: [PATCH 0480/5324] drm/i915: Make LRC pinning own a reference to the context Will simplify the following fix and sounds logical. v2: Add some whitespace to separate logic better. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Chris Wilson Cc: Nick Hoath --- drivers/gpu/drm/i915/intel_lrc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6c95aa19cc90..61e64d78adbd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1116,6 +1116,8 @@ static int intel_lr_context_pin(struct intel_context *ctx, ret = intel_lr_context_do_pin(ctx, engine); if (ret) goto reset_pin_count; + + i915_gem_context_reference(ctx); } return ret; @@ -1141,6 +1143,8 @@ void intel_lr_context_unpin(struct intel_context *ctx, ctx->engine[engine->id].lrc_vma = NULL; ctx->engine[engine->id].lrc_desc = 0; ctx->engine[engine->id].lrc_reg_state = NULL; + + i915_gem_context_unreference(ctx); } } -- GitLab From a0b4a6a8dbb147159602f0f82847ccd87bee5de8 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 28 Jan 2016 10:29:56 +0000 Subject: [PATCH 0481/5324] drm/i915: Extract context unpinning to its own function Will enable cleaner implementation of a following fix and easier code unification in the future. Idea and code by Chris Wilson. v2: Do not return before last_contexts on engines are unpinned. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Cc: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_context.c | 30 ++++++++++--------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 6a4f64b03db6..bba17b9f1be5 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -321,6 +321,14 @@ i915_gem_create_context(struct drm_device *dev, return ERR_PTR(ret); } +static void i915_gem_context_unpin(struct intel_context *ctx, + struct intel_engine_cs *engine) +{ + if (engine->id == RCS && ctx->legacy_hw_ctx.rcs_state) + i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); + i915_gem_context_unreference(ctx); +} + void i915_gem_context_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -329,22 +337,15 @@ void i915_gem_context_reset(struct drm_device *dev) if (i915.enable_execlists) { struct intel_context *ctx; - list_for_each_entry(ctx, &dev_priv->context_list, link) { + list_for_each_entry(ctx, &dev_priv->context_list, link) intel_lr_context_reset(dev, ctx); - } - - return; } for (i = 0; i < I915_NUM_RINGS; i++) { struct intel_engine_cs *ring = &dev_priv->ring[i]; - struct intel_context *lctx = ring->last_context; - - if (lctx) { - if (lctx->legacy_hw_ctx.rcs_state && i == RCS) - i915_gem_object_ggtt_unpin(lctx->legacy_hw_ctx.rcs_state); - i915_gem_context_unreference(lctx); + if (ring->last_context) { + i915_gem_context_unpin(ring->last_context, ring); ring->last_context = NULL; } } @@ -417,13 +418,6 @@ void i915_gem_context_fini(struct drm_device *dev) * to offset the do_switch part, so that i915_gem_context_unreference() * can then free the base object correctly. */ WARN_ON(!dev_priv->ring[RCS].last_context); - if (dev_priv->ring[RCS].last_context == dctx) { - /* Fake switch to NULL context */ - WARN_ON(dctx->legacy_hw_ctx.rcs_state->active); - i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); - i915_gem_context_unreference(dctx); - dev_priv->ring[RCS].last_context = NULL; - } i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); } @@ -432,7 +426,7 @@ void i915_gem_context_fini(struct drm_device *dev) struct intel_engine_cs *ring = &dev_priv->ring[i]; if (ring->last_context) { - i915_gem_context_unreference(ring->last_context); + i915_gem_context_unpin(ring->last_context, ring); ring->last_context = NULL; } } -- GitLab From f4e2deceb6aaab661be3e13191cd13da3dd3b9c2 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 28 Jan 2016 10:29:57 +0000 Subject: [PATCH 0482/5324] drm/i915: Fix premature LRC unpin in GuC mode In GuC mode LRC pinning lifetime depends exclusively on the request liftime. Since that is terminated by the seqno update that opens up a race condition between GPU finishing writing out the context image and the driver unpinning the LRC. To extend the LRC lifetime we will employ a similar approach to what legacy ringbuffer submission does. We will start tracking the last submitted context per engine and keep it pinned until it is replaced by another one. Note that the driver unload path is a bit fragile and could benefit greatly from efforts to unify the legacy and exec list submission code paths. At the moment i915_gem_context_fini has special casing for the two which are potentialy not needed, and also depends on i915_gem_cleanup_ringbuffer running before itself. v2: * Move pinning into engine->emit_request and actually fix the reference/unreference logic. (Chris Wilson) * ring->dev can be NULL on driver unload so use a different route towards it. v3: * Rebase. * Handle the reset path. (Chris Wilson) * Exclude default context from the pinning - it is impossible to get it right before default context special casing in general is eliminated. v4: * Rebased & moved context tracking to intel_logical_ring_advance_and_submit. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Issue: VIZ-4277 Cc: Chris Wilson Cc: Nick Hoath Link: http://patchwork.freedesktop.org/patch/msgid/1453976997-25424-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_context.c | 10 +++++++--- drivers/gpu/drm/i915/intel_lrc.c | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index bba17b9f1be5..83a097c94911 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -324,9 +324,13 @@ i915_gem_create_context(struct drm_device *dev, static void i915_gem_context_unpin(struct intel_context *ctx, struct intel_engine_cs *engine) { - if (engine->id == RCS && ctx->legacy_hw_ctx.rcs_state) - i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); - i915_gem_context_unreference(ctx); + if (i915.enable_execlists) { + intel_lr_context_unpin(ctx, engine); + } else { + if (engine->id == RCS && ctx->legacy_hw_ctx.rcs_state) + i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); + i915_gem_context_unreference(ctx); + } } void i915_gem_context_reset(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 61e64d78adbd..3a03646e343d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -765,6 +765,7 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) { struct intel_ringbuffer *ringbuf = request->ringbuf; struct drm_i915_private *dev_priv = request->i915; + struct intel_engine_cs *engine = request->ring; intel_logical_ring_advance(ringbuf); request->tail = ringbuf->tail; @@ -779,9 +780,20 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) intel_logical_ring_emit(ringbuf, MI_NOOP); intel_logical_ring_advance(ringbuf); - if (intel_ring_stopped(request->ring)) + if (intel_ring_stopped(engine)) return 0; + if (engine->last_context != request->ctx) { + if (engine->last_context) + intel_lr_context_unpin(engine->last_context, engine); + if (request->ctx != request->i915->kernel_context) { + intel_lr_context_pin(request->ctx, engine); + engine->last_context = request->ctx; + } else { + engine->last_context = NULL; + } + } + if (dev_priv->guc.execbuf_client) i915_guc_submit(dev_priv->guc.execbuf_client, request); else @@ -1131,7 +1143,7 @@ void intel_lr_context_unpin(struct intel_context *ctx, { struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; - WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&ctx->i915->dev->struct_mutex)); if (WARN_ON_ONCE(!ctx_obj)) return; -- GitLab From 0aa498d59c67d925f2a53fdffd1d447727d65c22 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Thu, 28 Jan 2016 10:48:09 +0000 Subject: [PATCH 0483/5324] Fix pointer tests in error-handling paths In the error-handling paths of i915_gem_do_execbuffer() and intel_crtc_page_flip(), the local pointer-to-request variables were expected to be either valid pointers or NULL. Since 2682708 drm/i915: simplify allocation of driver-internal requests they could also be ERR_PTR() values, so the tests need to be updated to accommodate this case. Signed-off-by: Dave Gordon Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1453978089-29127-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5cb57f642ac1..8fd00d279447 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1655,7 +1655,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * must be freed again. If it was submitted then it is being tracked * on the active request list and no clean up is required here. */ - if (ret && req) + if (ret && !IS_ERR_OR_NULL(req)) i915_gem_request_cancel(req); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8104511ad302..b88cdac747eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11726,7 +11726,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_unpin: intel_unpin_fb_obj(fb, crtc->primary->state); cleanup_pending: - if (request) + if (!IS_ERR_OR_NULL(request)) i915_gem_request_cancel(request); atomic_dec(&intel_crtc->unpin_work_count); mutex_unlock(&dev->struct_mutex); -- GitLab From 7723f47dc685c7152d3ce217f09f036ec7f3f5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:22 +0200 Subject: [PATCH 0484/5324] drm/i915: Rename the rotated gtt view member to 'rotated' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also rename 'rotation_info' to 'rotated' to match the view type exactly, this should avoid confusion which union members is valid for each view type. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-2-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 4 ++-- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2ccb2b52e3bb..5b660ff7fbde 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3381,7 +3381,7 @@ static struct sg_table * intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, struct drm_i915_gem_object *obj) { - struct intel_rotation_info *rot_info = &ggtt_view->params.rotation_info; + struct intel_rotation_info *rot_info = &ggtt_view->params.rotated; unsigned int size_pages = rot_info->size >> PAGE_SHIFT; unsigned int size_pages_uv; struct sg_page_iter sg_iter; @@ -3613,7 +3613,7 @@ i915_ggtt_view_size(struct drm_i915_gem_object *obj, if (view->type == I915_GGTT_VIEW_NORMAL) { return obj->base.size; } else if (view->type == I915_GGTT_VIEW_ROTATED) { - return view->params.rotation_info.size; + return view->params.rotated.size; } else if (view->type == I915_GGTT_VIEW_PARTIAL) { return view->params.partial.size << PAGE_SHIFT; } else { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index e5737963ab79..f520c90e5377 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -155,7 +155,7 @@ struct i915_ggtt_view { u64 offset; unsigned int size; } partial; - struct intel_rotation_info rotation_info; + struct intel_rotation_info rotated; } params; struct sg_table *pages; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b88cdac747eb..f54e11922353 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2284,7 +2284,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, const struct drm_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(fb->dev); - struct intel_rotation_info *info = &view->params.rotation_info; + struct intel_rotation_info *info = &view->params.rotated; unsigned int tile_size, tile_width, tile_height, cpp; *view = i915_ggtt_view_normal; @@ -2951,7 +2951,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane, offset = vma->node.start; if (plane == 1) { - offset += vma->ggtt_view.params.rotation_info.uv_start_page * + offset += vma->ggtt_view.params.rotated.uv_start_page * PAGE_SIZE; } -- GitLab From 871302555b1dd19d91b8f78ae1d3790773098ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:23 +0200 Subject: [PATCH 0485/5324] drm/i915: Pass stride to rotate_pages() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass stride in addition to width and height to rotate_pages(). For now width and stride are the same, but once framebuffer offsets enter the scene that may no longer be the case. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-3-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 5b660ff7fbde..b5aac6eb1d61 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3348,6 +3348,7 @@ i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, static struct scatterlist * rotate_pages(const dma_addr_t *in, unsigned int offset, unsigned int width, unsigned int height, + unsigned int stride, struct sg_table *st, struct scatterlist *sg) { unsigned int column, row; @@ -3359,7 +3360,7 @@ rotate_pages(const dma_addr_t *in, unsigned int offset, } for (column = 0; column < width; column++) { - src_idx = width * (height - 1) + column; + src_idx = stride * (height - 1) + column; for (row = 0; row < height; row++) { st->nents++; /* We don't need the pages, but need to initialize @@ -3370,7 +3371,7 @@ rotate_pages(const dma_addr_t *in, unsigned int offset, sg_dma_address(sg) = in[offset + src_idx]; sg_dma_len(sg) = PAGE_SIZE; sg = sg_next(sg); - src_idx -= width; + src_idx -= stride; } } @@ -3423,6 +3424,7 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, /* Rotate the pages. */ sg = rotate_pages(page_addr_list, 0, rot_info->width_pages, rot_info->height_pages, + rot_info->width_pages, st, NULL); /* Append the UV plane if NV12. */ @@ -3438,6 +3440,7 @@ intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, rotate_pages(page_addr_list, uv_start_page, rot_info->width_pages_uv, rot_info->height_pages_uv, + rot_info->width_pages_uv, st, sg); } -- GitLab From 11d23e6fa186f91cc6b1ccf27bbb14810c9baefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:24 +0200 Subject: [PATCH 0486/5324] drm/i915: Pass rotation_info to intel_rotate_fb_obj_pages() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_rotate_fb_obj_pages() doens't need the entire gtt view, just the rotation info suffices. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-4-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b5aac6eb1d61..715a771f0b31 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3379,10 +3379,9 @@ rotate_pages(const dma_addr_t *in, unsigned int offset, } static struct sg_table * -intel_rotate_fb_obj_pages(struct i915_ggtt_view *ggtt_view, +intel_rotate_fb_obj_pages(struct intel_rotation_info *rot_info, struct drm_i915_gem_object *obj) { - struct intel_rotation_info *rot_info = &ggtt_view->params.rotated; unsigned int size_pages = rot_info->size >> PAGE_SHIFT; unsigned int size_pages_uv; struct sg_page_iter sg_iter; @@ -3522,7 +3521,7 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma) vma->ggtt_view.pages = vma->obj->pages; else if (vma->ggtt_view.type == I915_GGTT_VIEW_ROTATED) vma->ggtt_view.pages = - intel_rotate_fb_obj_pages(&vma->ggtt_view, vma->obj); + intel_rotate_fb_obj_pages(&vma->ggtt_view.params.rotated, vma->obj); else if (vma->ggtt_view.type == I915_GGTT_VIEW_PARTIAL) vma->ggtt_view.pages = intel_partial_pages(&vma->ggtt_view, vma->obj); -- GitLab From 54ea9da88fc89bbba0c2f888bdb265d9fd6a3945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:25 +0200 Subject: [PATCH 0487/5324] drm/i915: Make display gtt offsets u32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using 'unsigned long' for ggtt offsets doesn't make much sense. Use 'u32' instead since we've not yet seen a >4GiB ggtt. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++------------ drivers/gpu/drm/i915/intel_drv.h | 12 ++++++------ drivers/gpu/drm/i915/intel_sprite.c | 6 +++--- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f54e11922353..97af94a12960 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2448,11 +2448,11 @@ static void intel_unpin_fb_obj(struct drm_framebuffer *fb, /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel * is assumed to be a power-of-two. */ -unsigned long intel_compute_tile_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, - unsigned int pitch) +u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, + int *x, int *y, + uint64_t fb_modifier, + unsigned int cpp, + unsigned int pitch) { if (fb_modifier != DRM_FORMAT_MOD_NONE) { unsigned int tile_size, tile_width, tile_height; @@ -2706,14 +2706,12 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int plane = intel_crtc->plane; - unsigned long linear_offset; - int x = plane_state->src.x1 >> 16; - int y = plane_state->src.y1 >> 16; + u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); - int pixel_size; - - pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int x = plane_state->src.x1 >> 16; + int y = plane_state->src.y1 >> 16; dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -2839,7 +2837,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int plane = intel_crtc->plane; - unsigned long linear_offset; + u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bc970125ec76..f620023ed134 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -575,7 +575,7 @@ struct intel_crtc { /* Display surface base address adjustement for pageflips. Note that on * gen4+ this only adjusts up to a tile, offsets within a tile are * handled in the hw itself (with the TILEOFF register). */ - unsigned long dspaddr_offset; + u32 dspaddr_offset; int adjusted_x; int adjusted_y; @@ -1172,11 +1172,11 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state); #define assert_pipe_enabled(d, p) assert_pipe(d, p, true) #define assert_pipe_disabled(d, p) assert_pipe(d, p, false) -unsigned long intel_compute_tile_offset(struct drm_i915_private *dev_priv, - int *x, int *y, - uint64_t fb_modifier, - unsigned int cpp, - unsigned int pitch); +u32 intel_compute_tile_offset(struct drm_i915_private *dev_priv, + int *x, int *y, + uint64_t fb_modifier, + unsigned int cpp, + unsigned int pitch); void intel_prepare_reset(struct drm_device *dev); void intel_finish_reset(struct drm_device *dev); void hsw_enable_pc8(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0875c8e0ec0a..f1ee7db0811a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -350,7 +350,7 @@ vlv_update_plane(struct drm_plane *dplane, int pipe = intel_plane->pipe; int plane = intel_plane->plane; u32 sprctl; - unsigned long sprsurf_offset, linear_offset; + u32 sprsurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; @@ -493,7 +493,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_i915_gem_object *obj = intel_fb_obj(fb); enum pipe pipe = intel_plane->pipe; u32 sprctl, sprscale = 0; - unsigned long sprsurf_offset, linear_offset; + u32 sprsurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; @@ -635,8 +635,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int pipe = intel_plane->pipe; - unsigned long dvssurf_offset, linear_offset; u32 dvscntr, dvsscale; + u32 dvssurf_offset, linear_offset; int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; -- GitLab From ac484963f979b6ab490183f0e09a3a17175f5758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:26 +0200 Subject: [PATCH 0488/5324] drm/i915: Standardize on 'cpp' for bytes per pixel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We more or less randomly call the "bytes per pixel" value 'cpp', 'bytes_per_pixel', 'pixel_size', or even 'bpp'. Let's just pick one and stick to it. I've chosen 'cpp'. Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-6-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 22 ++--- drivers/gpu/drm/i915/intel_pm.c | 128 +++++++++++++-------------- drivers/gpu/drm/i915/intel_sprite.c | 34 +++---- 3 files changed, 87 insertions(+), 97 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 97af94a12960..23cce7df74b0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2709,7 +2709,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); - int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); int x = plane_state->src.x1 >> 16; int y = plane_state->src.y1 >> 16; @@ -2769,13 +2769,12 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, if (IS_G4X(dev)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * cpp; if (INTEL_INFO(dev)->gen >= 4) { intel_crtc->dspaddr_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, + fb->modifier[0], cpp, fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; } else { @@ -2792,7 +2791,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, data and adding to linear_offset*/ linear_offset += (crtc_state->pipe_src_h - 1) * fb->pitches[0] + - (crtc_state->pipe_src_w - 1) * pixel_size; + (crtc_state->pipe_src_w - 1) * cpp; } intel_crtc->adjusted_x = x; @@ -2840,7 +2839,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, u32 linear_offset; u32 dspcntr; i915_reg_t reg = DSPCNTR(plane); - int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); int x = plane_state->src.x1 >> 16; int y = plane_state->src.y1 >> 16; @@ -2879,11 +2878,10 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * cpp; intel_crtc->dspaddr_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, + fb->modifier[0], cpp, fb->pitches[0]); linear_offset -= intel_crtc->dspaddr_offset; if (plane_state->base.rotation == BIT(DRM_ROTATE_180)) { @@ -2897,7 +2895,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, data and adding to linear_offset*/ linear_offset += (crtc_state->pipe_src_h - 1) * fb->pitches[0] + - (crtc_state->pipe_src_w - 1) * pixel_size; + (crtc_state->pipe_src_w - 1) * cpp; } } @@ -14682,10 +14680,12 @@ u32 intel_fb_pitch_limit(struct drm_device *dev, uint64_t fb_modifier, u32 gen = INTEL_INFO(dev)->gen; if (gen >= 9) { + int cpp = drm_format_plane_cpp(pixel_format, 0); + /* "The stride in bytes must not exceed the of the size of 8K * pixels and 32K bytes." */ - return min(8192*drm_format_plane_cpp(pixel_format, 0), 32768); + return min(8192 * cpp, 32768); } else if (gen >= 5 && !IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { return 32*1024; } else if (gen >= 4) { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 20bf854eae8c..31bc4ea395ac 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -548,7 +548,7 @@ static const struct intel_watermark_params i845_wm_info = { * intel_calculate_wm - calculate watermark level * @clock_in_khz: pixel clock * @wm: chip FIFO params - * @pixel_size: display pixel size + * @cpp: bytes per pixel * @latency_ns: memory latency for the platform * * Calculate the watermark level (the level at which the display plane will @@ -564,8 +564,7 @@ static const struct intel_watermark_params i845_wm_info = { */ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, const struct intel_watermark_params *wm, - int fifo_size, - int pixel_size, + int fifo_size, int cpp, unsigned long latency_ns) { long entries_required, wm_size; @@ -576,7 +575,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, * clocks go from a few thousand to several hundred thousand. * latency is usually a few thousand */ - entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / + entries_required = ((clock_in_khz / 1000) * cpp * latency_ns) / 1000; entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); @@ -640,13 +639,13 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) crtc = single_enabled_crtc(dev); if (crtc) { const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode; - int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; + int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); int clock = adjusted_mode->crtc_clock; /* Display SR */ wm = intel_calculate_wm(clock, &pineview_display_wm, pineview_display_wm.fifo_size, - pixel_size, latency->display_sr); + cpp, latency->display_sr); reg = I915_READ(DSPFW1); reg &= ~DSPFW_SR_MASK; reg |= FW_WM(wm, SR); @@ -656,7 +655,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) /* cursor SR */ wm = intel_calculate_wm(clock, &pineview_cursor_wm, pineview_display_wm.fifo_size, - pixel_size, latency->cursor_sr); + cpp, latency->cursor_sr); reg = I915_READ(DSPFW3); reg &= ~DSPFW_CURSOR_SR_MASK; reg |= FW_WM(wm, CURSOR_SR); @@ -665,7 +664,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) /* Display HPLL off SR */ wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, pineview_display_hplloff_wm.fifo_size, - pixel_size, latency->display_hpll_disable); + cpp, latency->display_hpll_disable); reg = I915_READ(DSPFW3); reg &= ~DSPFW_HPLL_SR_MASK; reg |= FW_WM(wm, HPLL_SR); @@ -674,7 +673,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc) /* cursor HPLL off SR */ wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, pineview_display_hplloff_wm.fifo_size, - pixel_size, latency->cursor_hpll_disable); + cpp, latency->cursor_hpll_disable); reg = I915_READ(DSPFW3); reg &= ~DSPFW_HPLL_CURSOR_MASK; reg |= FW_WM(wm, HPLL_CURSOR); @@ -698,7 +697,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, { struct drm_crtc *crtc; const struct drm_display_mode *adjusted_mode; - int htotal, hdisplay, clock, pixel_size; + int htotal, hdisplay, clock, cpp; int line_time_us, line_count; int entries, tlb_miss; @@ -713,10 +712,10 @@ static bool g4x_compute_wm0(struct drm_device *dev, clock = adjusted_mode->crtc_clock; htotal = adjusted_mode->crtc_htotal; hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; - pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; + cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); /* Use the small buffer method to calculate plane watermark */ - entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; + entries = ((clock * cpp / 1000) * display_latency_ns) / 1000; tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; if (tlb_miss > 0) entries += tlb_miss; @@ -728,7 +727,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, /* Use the large buffer method to calculate cursor watermark */ line_time_us = max(htotal * 1000 / clock, 1); line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; - entries = line_count * crtc->cursor->state->crtc_w * pixel_size; + entries = line_count * crtc->cursor->state->crtc_w * cpp; tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; if (tlb_miss > 0) entries += tlb_miss; @@ -784,7 +783,7 @@ static bool g4x_compute_srwm(struct drm_device *dev, { struct drm_crtc *crtc; const struct drm_display_mode *adjusted_mode; - int hdisplay, htotal, pixel_size, clock; + int hdisplay, htotal, cpp, clock; unsigned long line_time_us; int line_count, line_size; int small, large; @@ -800,21 +799,21 @@ static bool g4x_compute_srwm(struct drm_device *dev, clock = adjusted_mode->crtc_clock; htotal = adjusted_mode->crtc_htotal; hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; - pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; + cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); line_time_us = max(htotal * 1000 / clock, 1); line_count = (latency_ns / line_time_us + 1000) / 1000; - line_size = hdisplay * pixel_size; + line_size = hdisplay * cpp; /* Use the minimum of the small and large buffer method for primary */ - small = ((clock * pixel_size / 1000) * latency_ns) / 1000; + small = ((clock * cpp / 1000) * latency_ns) / 1000; large = line_count * line_size; entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); *display_wm = entries + display->guard_size; /* calculate the self-refresh watermark for display cursor */ - entries = line_count * pixel_size * crtc->cursor->state->crtc_w; + entries = line_count * cpp * crtc->cursor->state->crtc_w; entries = DIV_ROUND_UP(entries, cursor->cacheline_size); *cursor_wm = entries + cursor->guard_size; @@ -906,13 +905,13 @@ enum vlv_wm_level { static unsigned int vlv_wm_method2(unsigned int pixel_rate, unsigned int pipe_htotal, unsigned int horiz_pixels, - unsigned int bytes_per_pixel, + unsigned int cpp, unsigned int latency) { unsigned int ret; ret = (latency * pixel_rate) / (pipe_htotal * 10000); - ret = (ret + 1) * horiz_pixels * bytes_per_pixel; + ret = (ret + 1) * horiz_pixels * cpp; ret = DIV_ROUND_UP(ret, 64); return ret; @@ -941,7 +940,7 @@ static uint16_t vlv_compute_wm_level(struct intel_plane *plane, int level) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - int clock, htotal, pixel_size, width, wm; + int clock, htotal, cpp, width, wm; if (dev_priv->wm.pri_latency[level] == 0) return USHRT_MAX; @@ -949,7 +948,7 @@ static uint16_t vlv_compute_wm_level(struct intel_plane *plane, if (!state->visible) return 0; - pixel_size = drm_format_plane_cpp(state->base.fb->pixel_format, 0); + cpp = drm_format_plane_cpp(state->base.fb->pixel_format, 0); clock = crtc->config->base.adjusted_mode.crtc_clock; htotal = crtc->config->base.adjusted_mode.crtc_htotal; width = crtc->config->pipe_src_w; @@ -965,7 +964,7 @@ static uint16_t vlv_compute_wm_level(struct intel_plane *plane, */ wm = 63; } else { - wm = vlv_wm_method2(clock, htotal, width, pixel_size, + wm = vlv_wm_method2(clock, htotal, width, cpp, dev_priv->wm.pri_latency[level] * 10); } @@ -1439,7 +1438,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) int clock = adjusted_mode->crtc_clock; int htotal = adjusted_mode->crtc_htotal; int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w; - int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8; + int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); unsigned long line_time_us; int entries; @@ -1447,7 +1446,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) /* Use ns/us then divide to preserve precision */ entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * hdisplay; + cpp * hdisplay; entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); srwm = I965_FIFO_SIZE - entries; if (srwm < 0) @@ -1457,7 +1456,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) entries, srwm); entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * crtc->cursor->state->crtc_w; + cpp * crtc->cursor->state->crtc_w; entries = DIV_ROUND_UP(entries, i965_cursor_wm_info.cacheline_size); cursor_sr = i965_cursor_wm_info.fifo_size - @@ -1518,7 +1517,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) crtc = intel_get_crtc_for_plane(dev, 0); if (intel_crtc_active(crtc)) { const struct drm_display_mode *adjusted_mode; - int cpp = crtc->primary->state->fb->bits_per_pixel / 8; + int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); if (IS_GEN2(dev)) cpp = 4; @@ -1540,7 +1539,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) crtc = intel_get_crtc_for_plane(dev, 1); if (intel_crtc_active(crtc)) { const struct drm_display_mode *adjusted_mode; - int cpp = crtc->primary->state->fb->bits_per_pixel / 8; + int cpp = drm_format_plane_cpp(crtc->primary->state->fb->pixel_format, 0); if (IS_GEN2(dev)) cpp = 4; @@ -1586,7 +1585,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) int clock = adjusted_mode->crtc_clock; int htotal = adjusted_mode->crtc_htotal; int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w; - int pixel_size = enabled->primary->state->fb->bits_per_pixel / 8; + int cpp = drm_format_plane_cpp(enabled->primary->state->fb->pixel_format, 0); unsigned long line_time_us; int entries; @@ -1594,7 +1593,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) /* Use ns/us then divide to preserve precision */ entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * hdisplay; + cpp * hdisplay; entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); srwm = wm_info->fifo_size - entries; @@ -1685,15 +1684,14 @@ uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config) } /* latency must be in 0.1us units. */ -static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, - uint32_t latency) +static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latency) { uint64_t ret; if (WARN(latency == 0, "Latency value missing\n")) return UINT_MAX; - ret = (uint64_t) pixel_rate * bytes_per_pixel * latency; + ret = (uint64_t) pixel_rate * cpp * latency; ret = DIV_ROUND_UP_ULL(ret, 64 * 10000) + 2; return ret; @@ -1701,7 +1699,7 @@ static uint32_t ilk_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, /* latency must be in 0.1us units. */ static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, - uint32_t horiz_pixels, uint8_t bytes_per_pixel, + uint32_t horiz_pixels, uint8_t cpp, uint32_t latency) { uint32_t ret; @@ -1712,13 +1710,13 @@ static uint32_t ilk_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, return UINT_MAX; ret = (latency * pixel_rate) / (pipe_htotal * 10000); - ret = (ret + 1) * horiz_pixels * bytes_per_pixel; + ret = (ret + 1) * horiz_pixels * cpp; ret = DIV_ROUND_UP(ret, 64) + 2; return ret; } static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, - uint8_t bytes_per_pixel) + uint8_t cpp) { /* * Neither of these should be possible since this function shouldn't be @@ -1726,12 +1724,12 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, * extra paranoid to avoid a potential divide-by-zero if we screw up * elsewhere in the driver. */ - if (WARN_ON(!bytes_per_pixel)) + if (WARN_ON(!cpp)) return 0; if (WARN_ON(!horiz_pixels)) return 0; - return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; + return DIV_ROUND_UP(pri_val * 64, horiz_pixels * cpp) + 2; } struct ilk_wm_maximums { @@ -1750,13 +1748,14 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, uint32_t mem_value, bool is_lp) { - int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + int cpp = pstate->base.fb ? + drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0; uint32_t method1, method2; if (!cstate->base.active || !pstate->visible) return 0; - method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); + method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), cpp, mem_value); if (!is_lp) return method1; @@ -1764,8 +1763,7 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate, method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, drm_rect_width(&pstate->dst), - bpp, - mem_value); + cpp, mem_value); return min(method1, method2); } @@ -1778,18 +1776,18 @@ static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate, const struct intel_plane_state *pstate, uint32_t mem_value) { - int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + int cpp = pstate->base.fb ? + drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0; uint32_t method1, method2; if (!cstate->base.active || !pstate->visible) return 0; - method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value); + method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), cpp, mem_value); method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, drm_rect_width(&pstate->dst), - bpp, - mem_value); + cpp, mem_value); return min(method1, method2); } @@ -1801,7 +1799,8 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, const struct intel_plane_state *pstate, uint32_t mem_value) { - int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + int cpp = pstate->base.fb ? + drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0; if (!cstate->base.active || !pstate->visible) return 0; @@ -1809,8 +1808,7 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, return ilk_wm_method2(ilk_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, drm_rect_width(&pstate->dst), - bpp, - mem_value); + cpp, mem_value); } /* Only for WM_LP. */ @@ -1818,12 +1816,13 @@ static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate, const struct intel_plane_state *pstate, uint32_t pri_val) { - int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0; + int cpp = pstate->base.fb ? + drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0; if (!cstate->base.active || !pstate->visible) return 0; - return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp); + return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), cpp); } static unsigned int ilk_display_fifo_size(const struct drm_device *dev) @@ -3042,26 +3041,25 @@ static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config) /* * The max latency should be 257 (max the punit can code is 255 and we add 2us - * for the read latency) and bytes_per_pixel should always be <= 8, so that + * for the read latency) and cpp should always be <= 8, so that * should allow pixel_rate up to ~2 GHz which seems sufficient since max * 2xcdclk is 1350 MHz and the pixel rate should never exceed that. */ -static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, - uint32_t latency) +static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latency) { uint32_t wm_intermediate_val, ret; if (latency == 0) return UINT_MAX; - wm_intermediate_val = latency * pixel_rate * bytes_per_pixel / 512; + wm_intermediate_val = latency * pixel_rate * cpp / 512; ret = DIV_ROUND_UP(wm_intermediate_val, 1000); return ret; } static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, - uint32_t horiz_pixels, uint8_t bytes_per_pixel, + uint32_t horiz_pixels, uint8_t cpp, uint64_t tiling, uint32_t latency) { uint32_t ret; @@ -3071,7 +3069,7 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, if (latency == 0) return UINT_MAX; - plane_bytes_per_line = horiz_pixels * bytes_per_pixel; + plane_bytes_per_line = horiz_pixels * cpp; if (tiling == I915_FORMAT_MOD_Y_TILED || tiling == I915_FORMAT_MOD_Yf_TILED) { @@ -3121,23 +3119,21 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, uint32_t plane_bytes_per_line, plane_blocks_per_line; uint32_t res_blocks, res_lines; uint32_t selected_result; - uint8_t bytes_per_pixel; + uint8_t cpp; if (latency == 0 || !cstate->base.active || !fb) return false; - bytes_per_pixel = drm_format_plane_cpp(fb->pixel_format, 0); + cpp = drm_format_plane_cpp(fb->pixel_format, 0); method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), - bytes_per_pixel, - latency); + cpp, latency); method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, cstate->pipe_src_w, - bytes_per_pixel, - fb->modifier[0], + cpp, fb->modifier[0], latency); - plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel; + plane_bytes_per_line = cstate->pipe_src_w * cpp; plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || @@ -3145,11 +3141,11 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, uint32_t min_scanlines = 4; uint32_t y_tile_minimum; if (intel_rotation_90_or_270(plane->state->rotation)) { - int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? + int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ? drm_format_plane_cpp(fb->pixel_format, 1) : drm_format_plane_cpp(fb->pixel_format, 0); - switch (bpp) { + switch (cpp) { case 1: min_scanlines = 16; break; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index f1ee7db0811a..a2582c455b36 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -351,7 +351,7 @@ vlv_update_plane(struct drm_plane *dplane, int plane = intel_plane->plane; u32 sprctl; u32 sprsurf_offset, linear_offset; - int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; int crtc_y = plane_state->dst.y1; @@ -422,10 +422,9 @@ vlv_update_plane(struct drm_plane *dplane, crtc_w--; crtc_h--; - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * cpp; sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, + fb->modifier[0], cpp, fb->pitches[0]); linear_offset -= sprsurf_offset; @@ -434,7 +433,7 @@ vlv_update_plane(struct drm_plane *dplane, x += src_w; y += src_h; - linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; + linear_offset += src_h * fb->pitches[0] + src_w * cpp; } if (key->flags) { @@ -494,7 +493,7 @@ ivb_update_plane(struct drm_plane *plane, enum pipe pipe = intel_plane->pipe; u32 sprctl, sprscale = 0; u32 sprsurf_offset, linear_offset; - int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; int crtc_y = plane_state->dst.y1; @@ -556,10 +555,9 @@ ivb_update_plane(struct drm_plane *plane, if (crtc_w != src_w || crtc_h != src_h) sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * cpp; sprsurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, + fb->modifier[0], cpp, fb->pitches[0]); linear_offset -= sprsurf_offset; @@ -570,8 +568,7 @@ ivb_update_plane(struct drm_plane *plane, if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { x += src_w; y += src_h; - linear_offset += src_h * fb->pitches[0] + - src_w * pixel_size; + linear_offset += src_h * fb->pitches[0] + src_w * cpp; } } @@ -637,7 +634,7 @@ ilk_update_plane(struct drm_plane *plane, int pipe = intel_plane->pipe; u32 dvscntr, dvsscale; u32 dvssurf_offset, linear_offset; - int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; int crtc_x = plane_state->dst.x1; int crtc_y = plane_state->dst.y1; @@ -695,10 +692,9 @@ ilk_update_plane(struct drm_plane *plane, if (crtc_w != src_w || crtc_h != src_h) dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; - linear_offset = y * fb->pitches[0] + x * pixel_size; + linear_offset = y * fb->pitches[0] + x * cpp; dvssurf_offset = intel_compute_tile_offset(dev_priv, &x, &y, - fb->modifier[0], - pixel_size, + fb->modifier[0], cpp, fb->pitches[0]); linear_offset -= dvssurf_offset; @@ -707,7 +703,7 @@ ilk_update_plane(struct drm_plane *plane, x += src_w; y += src_h; - linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; + linear_offset += src_h * fb->pitches[0] + src_w * cpp; } if (key->flags) { @@ -772,7 +768,6 @@ intel_check_sprite_plane(struct drm_plane *plane, int hscale, vscale; int max_scale, min_scale; bool can_scale; - int pixel_size; if (!fb) { state->visible = false; @@ -894,6 +889,7 @@ intel_check_sprite_plane(struct drm_plane *plane, /* Check size restrictions when scaling */ if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { unsigned int width_bytes; + int cpp = drm_format_plane_cpp(fb->pixel_format, 0); WARN_ON(!can_scale); @@ -905,9 +901,7 @@ intel_check_sprite_plane(struct drm_plane *plane, if (src_w < 3 || src_h < 3) state->visible = false; - pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); - width_bytes = ((src_x * pixel_size) & 63) + - src_w * pixel_size; + width_bytes = ((src_x * cpp) & 63) + src_w * cpp; if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 || width_bytes > 4096 || fb->pitches[0] > 4096)) { -- GitLab From b16bb01fd2d599ba5cbc031b2c5318eba29efbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 20 Jan 2016 21:05:28 +0200 Subject: [PATCH 0489/5324] drm/i915: Fix intel_tile_width() parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fb_modifiers and cpp arguments passed to intel_tile_width() in intel_fill_fb_ggtt_view() got accidentally swapped around. I'm pretty sure I fixed this already, but could be I lost the fix accidentally during some rebases or something. Anyway, fix it up for real. Fixes: d9b3288ecf2f ("drm/i915: change intel_fill_fb_ggtt_view() to use the real tile size") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1453316739-13296-8-git-send-email-ville.syrjala@linux.intel.com Testcase: igt/kms_rotation_crc/primary-rotation-90 Reviewed-by: Daniel Vetter Cc: drm-intel-fixes@lists.freedesktop.org --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 23cce7df74b0..304fc9637026 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2306,7 +2306,7 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, tile_size = intel_tile_size(dev_priv); cpp = drm_format_plane_cpp(fb->pixel_format, 0); - tile_width = intel_tile_width(dev_priv, cpp, fb->modifier[0]); + tile_width = intel_tile_width(dev_priv, fb->modifier[0], cpp); tile_height = tile_size / tile_width; info->width_pages = DIV_ROUND_UP(fb->pitches[0], tile_width); -- GitLab From 394f647e3ad073dab19ba081501e4a0ca05302c4 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Mon, 25 Jan 2016 15:33:39 -0500 Subject: [PATCH 0490/5324] orangefs: Util functions shouldn't operate on inode where it can be avoided. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-utils.c | 82 +++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 92a38b0091f2..035f050ae0e8 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -78,24 +78,55 @@ __s32 fsid_of_op(struct orangefs_kernel_op_s *op) return fsid; } -static void orangefs_set_inode_flags(struct inode *inode, - struct ORANGEFS_sys_attr_s *attrs) +static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs) { + int flags = 0; if (attrs->flags & ORANGEFS_IMMUTABLE_FL) - inode->i_flags |= S_IMMUTABLE; + flags |= S_IMMUTABLE; else - inode->i_flags &= ~S_IMMUTABLE; - + flags &= ~S_IMMUTABLE; if (attrs->flags & ORANGEFS_APPEND_FL) - inode->i_flags |= S_APPEND; + flags |= S_APPEND; else - inode->i_flags &= ~S_APPEND; - + flags &= ~S_APPEND; if (attrs->flags & ORANGEFS_NOATIME_FL) - inode->i_flags |= S_NOATIME; + flags |= S_NOATIME; else - inode->i_flags &= ~S_NOATIME; + flags &= ~S_NOATIME; + return flags; +} + +static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs) +{ + int perm_mode = 0; + + if (attrs->perms & ORANGEFS_O_EXECUTE) + perm_mode |= S_IXOTH; + if (attrs->perms & ORANGEFS_O_WRITE) + perm_mode |= S_IWOTH; + if (attrs->perms & ORANGEFS_O_READ) + perm_mode |= S_IROTH; + + if (attrs->perms & ORANGEFS_G_EXECUTE) + perm_mode |= S_IXGRP; + if (attrs->perms & ORANGEFS_G_WRITE) + perm_mode |= S_IWGRP; + if (attrs->perms & ORANGEFS_G_READ) + perm_mode |= S_IRGRP; + if (attrs->perms & ORANGEFS_U_EXECUTE) + perm_mode |= S_IXUSR; + if (attrs->perms & ORANGEFS_U_WRITE) + perm_mode |= S_IWUSR; + if (attrs->perms & ORANGEFS_U_READ) + perm_mode |= S_IRUSR; + + if (attrs->perms & ORANGEFS_G_SGID) + perm_mode |= S_ISGID; + if (attrs->perms & ORANGEFS_U_SUID) + perm_mode |= S_ISUID; + + return perm_mode; } /* NOTE: symname is ignored unless the inode is a sym link */ @@ -104,7 +135,6 @@ static int copy_attributes_to_inode(struct inode *inode, char *symname) { int ret = -1; - int perm_mode = 0; struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); loff_t inode_size = 0; loff_t rounded_up_size = 0; @@ -134,7 +164,7 @@ static int copy_attributes_to_inode(struct inode *inode, switch (attrs->objtype) { case ORANGEFS_TYPE_METAFILE: - orangefs_set_inode_flags(inode, attrs); + inode->i_flags = orangefs_inode_flags(attrs); if (attrs->mask & ORANGEFS_ATTR_SYS_SIZE) { inode_size = (loff_t) attrs->size; rounded_up_size = @@ -179,33 +209,7 @@ static int copy_attributes_to_inode(struct inode *inode, inode->i_mtime.tv_nsec = 0; inode->i_ctime.tv_nsec = 0; - if (attrs->perms & ORANGEFS_O_EXECUTE) - perm_mode |= S_IXOTH; - if (attrs->perms & ORANGEFS_O_WRITE) - perm_mode |= S_IWOTH; - if (attrs->perms & ORANGEFS_O_READ) - perm_mode |= S_IROTH; - - if (attrs->perms & ORANGEFS_G_EXECUTE) - perm_mode |= S_IXGRP; - if (attrs->perms & ORANGEFS_G_WRITE) - perm_mode |= S_IWGRP; - if (attrs->perms & ORANGEFS_G_READ) - perm_mode |= S_IRGRP; - - if (attrs->perms & ORANGEFS_U_EXECUTE) - perm_mode |= S_IXUSR; - if (attrs->perms & ORANGEFS_U_WRITE) - perm_mode |= S_IWUSR; - if (attrs->perms & ORANGEFS_U_READ) - perm_mode |= S_IRUSR; - - if (attrs->perms & ORANGEFS_G_SGID) - perm_mode |= S_ISGID; - if (attrs->perms & ORANGEFS_U_SUID) - perm_mode |= S_ISUID; - - inode->i_mode = perm_mode; + inode->i_mode = orangefs_inode_perms(attrs); if (is_root_handle(inode)) { /* special case: mark the root inode as sticky */ -- GitLab From 99109822f5cbe6d530eb55193b25aa5348f6134d Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Thu, 28 Jan 2016 10:19:40 -0500 Subject: [PATCH 0491/5324] orangefs: Fix revalidate. Previously, it would update a live inode. This was fixed, but it did not ever check that the inode attributes in the dcache are correct. This checks all inode attributes and rejects any that are not correct, which causes a lookup and thus a new getattr. Perhaps inode_operations->permission should replace or augment some of this. There is no actual caching, and this does a rather excessive amount of network operations back to the filesystem server. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/dcache.c | 98 ++++++++++++++--------- fs/orangefs/file.c | 4 +- fs/orangefs/inode.c | 6 +- fs/orangefs/orangefs-kernel.h | 2 +- fs/orangefs/orangefs-utils.c | 141 +++++++++++++++++++++++++++++----- 5 files changed, 187 insertions(+), 64 deletions(-) diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index 0419981f773e..e8fb79de37c6 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -43,24 +43,34 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) err = service_operation(new_op, "orangefs_lookup", get_interruptible_flag(parent_inode)); - if (err) - goto out_drop; - - if (new_op->downcall.status != 0 || - !match_handle(new_op->downcall.resp.lookup.refn.khandle, inode)) { - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s:%s:%d " - "lookup failure |%s| or no match |%s|.\n", - __FILE__, - __func__, - __LINE__, - new_op->downcall.status ? "true" : "false", - match_handle(new_op->downcall.resp.lookup.refn.khandle, - inode) ? "false" : "true"); - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s:%s:%d revalidate failed\n", - __FILE__, __func__, __LINE__); - goto out_drop; + + /* Positive dentry: reject if error or not the same inode. */ + if (inode) { + if (err) { + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d lookup failure.\n", + __FILE__, __func__, __LINE__); + goto out_drop; + } + if (!match_handle(new_op->downcall.resp.lookup.refn.khandle, + inode)) { + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d no match.\n", + __FILE__, __func__, __LINE__); + goto out_drop; + } + + /* Negative dentry: reject if success or error other than ENOENT. */ + } else { + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n", + __func__); + if (!err || err != -ENOENT) { + if (new_op->downcall.status != 0) + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s:%s:%d lookup failure.\n", + __FILE__, __func__, __LINE__); + goto out_drop; + } } ret = 1; @@ -70,6 +80,8 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) dput(parent_dentry); return ret; out_drop: + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d revalidate failed\n", + __FILE__, __func__, __LINE__); d_drop(dentry); goto out_release_op; } @@ -81,8 +93,7 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) */ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) { - struct inode *inode; - int ret = 0; + int ret; if (flags & LOOKUP_RCU) return -ECHILD; @@ -90,29 +101,42 @@ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p.\n", __func__, dentry); - /* find inode from dentry */ - if (!dentry->d_inode) { - gossip_debug(GOSSIP_DCACHE_DEBUG, - "%s: negative dentry.\n", - __func__); - goto out; + /* skip root handle lookups. */ + if (dentry->d_inode && is_root_handle(dentry->d_inode)) + return 1; + + /* + * If this passes, the positive dentry still exists or the negative + * dentry still does not exist. + */ + if (!orangefs_revalidate_lookup(dentry)) { + d_drop(dentry); + return 0; } - gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: inode valid.\n", __func__); - inode = dentry->d_inode; - - /* skip root handle lookups. */ - if (is_root_handle(inode)) { - ret = 1; + /* We do not need to continue with negative dentries. */ + if (!dentry->d_inode) goto out; - } - /* lookup the object. */ - if (orangefs_revalidate_lookup(dentry)) - ret = 1; + /* Now we must perform a getattr to validate the inode contents. */ + ret = orangefs_inode_getattr(dentry->d_inode, + ORANGEFS_ATTR_SYS_ALL_NOHINT, 1); + if (ret < 0) { + gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.\n", + __FILE__, __func__, __LINE__); + d_drop(dentry); + return 0; + } + if (ret == 0) { + d_drop(dentry); + return 0; + } out: - return ret; + gossip_debug(GOSSIP_DCACHE_DEBUG, + "%s: negative dentry or positive dentry and inode valid.\n", + __func__); + return 1; } const struct dentry_operations orangefs_dentry_operations = { diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index c585063d1100..7e6fe8d8ab2b 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -467,7 +467,7 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite /* Make sure generic_write_checks sees an up to date inode size. */ if (file->f_flags & O_APPEND) { rc = orangefs_inode_getattr(file->f_mapping->host, - ORANGEFS_ATTR_SYS_SIZE); + ORANGEFS_ATTR_SYS_SIZE, 0); if (rc) { gossip_err("%s: orangefs_inode_getattr failed, rc:%zd:.\n", __func__, rc); @@ -681,7 +681,7 @@ static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin) * NOTE: We are only interested in file size here, * so we set mask accordingly. */ - ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_SIZE); + ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_SIZE, 0); if (ret) { gossip_debug(GOSSIP_FILE_DEBUG, "%s:%s:%d calling make bad inode\n", diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 4724c92b61ac..040cd95b51c2 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -273,7 +273,7 @@ int orangefs_getattr(struct vfsmount *mnt, * fields/attributes of the inode would be refreshed. So again, we * dont have too much of a choice but refresh all the attributes. */ - ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); + ret = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0); if (ret == 0) { generic_fillattr(inode, kstat); /* override block size reported to stat */ @@ -392,7 +392,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref if (!inode || !(inode->i_state & I_NEW)) return inode; - error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); + error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0); if (error) { iget_failed(inode); return ERR_PTR(error); @@ -437,7 +437,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ - error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT); + error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0); if (error) goto out_iput; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 9c876762f825..3e258554688d 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -561,7 +561,7 @@ int orangefs_inode_setxattr(struct inode *inode, size_t size, int flags); -int orangefs_inode_getattr(struct inode *inode, __u32 mask); +int orangefs_inode_getattr(struct inode *inode, __u32 mask, int check); int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 035f050ae0e8..6cf29a439211 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -353,11 +353,91 @@ static inline int copy_attributes_from_inode(struct inode *inode, return 0; } +static int compare_attributes_to_inode(struct inode *inode, + struct ORANGEFS_sys_attr_s *attrs, + char *symname) +{ + struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); + loff_t inode_size, rounded_up_size; + + /* Compare file size. */ + + switch (attrs->objtype) { + case ORANGEFS_TYPE_METAFILE: + if(inode->i_flags != orangefs_inode_flags(attrs)) + return 0; + inode_size = attrs->size; + rounded_up_size = inode_size + (4096 - (inode_size % 4096)); + if (inode->i_bytes != inode_size || + inode->i_blocks != rounded_up_size/512) + return 0; + break; + case ORANGEFS_TYPE_SYMLINK: + if (symname && strlen(symname) != inode->i_size) + return 0; + break; + default: + if (inode->i_size != PAGE_CACHE_SIZE && + inode_get_bytes(inode) != PAGE_CACHE_SIZE) + return 0; + } + + /* Compare general attributes. */ + + if (!uid_eq(inode->i_uid, make_kuid(&init_user_ns, attrs->owner)) || + !gid_eq(inode->i_gid, make_kgid(&init_user_ns, attrs->group)) || + inode->i_atime.tv_sec != attrs->atime || + inode->i_mtime.tv_sec != attrs->mtime || + inode->i_ctime.tv_sec != attrs->ctime || + inode->i_atime.tv_nsec != 0 || + inode->i_mtime.tv_nsec != 0 || + inode->i_ctime.tv_nsec != 0) + return 0; + + if ((inode->i_mode & ~(S_ISVTX|S_IFREG|S_IFDIR|S_IFLNK)) != + orangefs_inode_perms(attrs)) + return 0; + + if (is_root_handle(inode)) + if (!(inode->i_mode & S_ISVTX)) + return 0; + + /* Compare file type. */ + + switch (attrs->objtype) { + case ORANGEFS_TYPE_METAFILE: + if (!(inode->i_mode & S_IFREG)) + return 0; + break; + case ORANGEFS_TYPE_DIRECTORY: + if (!(inode->i_mode & S_IFDIR)) + return 0; + if (inode->i_nlink != 1) + return 0; + break; + case ORANGEFS_TYPE_SYMLINK: + if (!(inode->i_mode & S_IFLNK)) + return 0; + if (orangefs_inode && symname) + if (strcmp(orangefs_inode->link_target, symname)) + return 0; + break; + default: + gossip_err("orangefs: compare_attributes_to_inode: got invalid attribute type %x\n", + attrs->objtype); + + } + + return 1; +} + /* - * issues a orangefs getattr request and fills in the appropriate inode - * attributes if successful. returns 0 on success; -errno otherwise + * Issues a orangefs getattr request and fills in the appropriate inode + * attributes if successful. When check is 0, returns 0 on success and -errno + * otherwise. When check is 1, returns 1 on success where the inode is valid + * and 0 on success where the inode is stale and -errno otherwise. */ -int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask) +int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask, int check) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct orangefs_kernel_op_s *new_op; @@ -379,27 +459,46 @@ int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask) if (ret != 0) goto out; - if (copy_attributes_to_inode(inode, - &new_op->downcall.resp.getattr.attributes, - new_op->downcall.resp.getattr.link_target)) { - gossip_err("%s: failed to copy attributes\n", __func__); - ret = -ENOENT; - goto out; - } + if (check) { + ret = compare_attributes_to_inode(inode, + &new_op->downcall.resp.getattr.attributes, + new_op->downcall.resp.getattr.link_target); - /* - * Store blksize in orangefs specific part of inode structure; we are - * only going to use this to report to stat to make sure it doesn't - * perturb any inode related code paths. - */ - if (new_op->downcall.resp.getattr.attributes.objtype == - ORANGEFS_TYPE_METAFILE) { - orangefs_inode->blksize = - new_op->downcall.resp.getattr.attributes.blksize; + if (new_op->downcall.resp.getattr.attributes.objtype == + ORANGEFS_TYPE_METAFILE) { + if (orangefs_inode->blksize != + new_op->downcall.resp.getattr.attributes.blksize) + ret = 0; + } else { + if (orangefs_inode->blksize != 1 << inode->i_blkbits) + ret = 0; + } } else { - /* mimic behavior of generic_fillattr() for other types. */ - orangefs_inode->blksize = (1 << inode->i_blkbits); + if (copy_attributes_to_inode(inode, + &new_op->downcall.resp.getattr.attributes, + new_op->downcall.resp.getattr.link_target)) { + gossip_err("%s: failed to copy attributes\n", __func__); + ret = -ENOENT; + goto out; + } + /* + * Store blksize in orangefs specific part of inode structure; + * we are only going to use this to report to stat to make sure + * it doesn't perturb any inode related code paths. + */ + if (new_op->downcall.resp.getattr.attributes.objtype == + ORANGEFS_TYPE_METAFILE) { + orangefs_inode->blksize = new_op->downcall.resp. + getattr.attributes.blksize; + } else { + /* + * mimic behavior of generic_fillattr() for other file + * types. + */ + orangefs_inode->blksize = (1 << inode->i_blkbits); + + } } out: -- GitLab From 36a0282a41493400428d7df8c99701fb4ee344c2 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 28 Jan 2016 15:59:58 +0000 Subject: [PATCH 0492/5324] ARM: dts: Replace legacy *,wakeup property with wakeup-source for exynos boards Though the keyboard and other driver will continue to support the legacy "gpio-key,wakeup", "linux-keypad,wakeup" boolean property to enable the wakeup source, "wakeup-source" is the new standard binding. This patch replaces all the legacy wakeup properties with the unified "wakeup-source" property in order to avoid any further copy-paste duplication. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sudeep Holla Signed-off-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250-monk.dts | 6 +++--- arch/arm/boot/dts/exynos3250-rinato.dts | 6 +++--- arch/arm/boot/dts/exynos4210-origen.dts | 10 +++++----- arch/arm/boot/dts/exynos4210-smdkv310.dts | 2 +- arch/arm/boot/dts/exynos4210-trats.dts | 2 +- arch/arm/boot/dts/exynos4210-universal_c210.dts | 4 ++-- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 2 +- arch/arm/boot/dts/exynos4412-odroidx.dts | 2 +- arch/arm/boot/dts/exynos4412-origen.dts | 2 +- arch/arm/boot/dts/exynos4412-smdk4412.dts | 2 +- arch/arm/boot/dts/exynos4412-trats2.dts | 4 ++-- arch/arm/boot/dts/exynos5250-arndale.dts | 12 ++++++------ arch/arm/boot/dts/exynos5250-snow-common.dtsi | 4 ++-- arch/arm/boot/dts/exynos5250-spring.dts | 4 ++-- arch/arm/boot/dts/exynos5420-arndale-octa.dts | 2 +- arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 ++-- arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 ++-- 17 files changed, 36 insertions(+), 36 deletions(-) diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 443a35085846..9e2840b59ae8 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -67,7 +67,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -185,7 +185,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 3e64d5dcdd60..1f102f3a1ab1 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -58,7 +58,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -246,7 +246,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 5821ad87e32c..ad7394c1d67a 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -60,35 +60,35 @@ label = "Up"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "Down"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "Back"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "Home"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { label = "Menu"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts index 104cbb33d2bb..94ca7d36ab37 100644 --- a/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -66,7 +66,7 @@ samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&keypad_rows &keypad_cols>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index a50be640f1b0..1df2f0bc1d76 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -112,7 +112,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 4f5d37920c8d..9a75e3effbc9 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -92,7 +92,7 @@ linux,code = <171>; label = "config"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; camera-key { @@ -107,7 +107,7 @@ linux,code = <116>; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 395c3ca9601e..5e5d3fecb04c 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -35,7 +35,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts index b44bb682e976..bf7b21b817e4 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -48,7 +48,7 @@ linux,code = ; label = "home key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 9e2e24c6177a..8bca699b7f20 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -423,7 +423,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <2>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts index a130ab39fa77..a51069f3c03b 100644 --- a/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -45,7 +45,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index a6f78c3da935..ed017cc7b14f 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -119,7 +119,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; key-ok { @@ -127,7 +127,7 @@ linux,code = <139>; label = "ok"; debounce-inteval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index c000532c1444..8b2acc74aa76 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -34,42 +34,42 @@ label = "SW-TACT2"; gpios = <&gpx1 4 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "SW-TACT3"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; up { label = "SW-TACT4"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "SW-TACT5"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "SW-TACT6"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; wakeup { label = "SW-TACT7"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index 5cb33ba5e296..95210ef6a6b5 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index c1edd6d038a9..0f500cb1eb2d 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 762f6ffece0c..a103ce8c3985 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -48,7 +48,7 @@ label = "SW-TACT1"; gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; }; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index f7b31e16d07f..3981ddb25036 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -65,7 +65,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -74,7 +74,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 4731dbb5b450..6e9edc1610c4 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -64,7 +64,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -73,7 +73,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; -- GitLab From 8d47e6af6f824e6f68f0af3f09816cc424e6fbac Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 18 Jan 2016 14:18:44 +0900 Subject: [PATCH 0493/5324] ARM: dts: r8a7794: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7794 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7794.dtsi | 234 ++++++++++++++++----------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index f8cd3a0beebf..21be4bdc4001 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -59,13 +59,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -78,7 +78,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -91,7 +91,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -104,7 +104,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -117,7 +117,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -130,7 +130,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 28>; @@ -143,7 +143,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 26>; @@ -156,8 +156,8 @@ cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7794_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -170,14 +170,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7794_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -189,10 +189,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; irqc0: interrupt-controller@e61c0000 { @@ -200,16 +200,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7794_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -222,22 +222,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -253,22 +253,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -284,7 +284,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>; clock-names = "sci_ick"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; @@ -296,7 +296,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>; clock-names = "sci_ick"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; @@ -308,7 +308,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>; clock-names = "sci_ick"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; @@ -320,7 +320,7 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>; clock-names = "sci_ick"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; @@ -332,7 +332,7 @@ scifa4: serial@e6c78000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>; clock-names = "sci_ick"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; @@ -344,7 +344,7 @@ scifa5: serial@e6c80000 { compatible = "renesas,scifa-r8a7794", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>; clock-names = "sci_ick"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; @@ -356,7 +356,7 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a7794", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>; clock-names = "sci_ick"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; @@ -368,7 +368,7 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a7794", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>; clock-names = "sci_ick"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; @@ -380,7 +380,7 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a7794", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>; clock-names = "sci_ick"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; @@ -392,7 +392,7 @@ scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; @@ -404,7 +404,7 @@ scif1: serial@e6e68000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; @@ -416,7 +416,7 @@ scif2: serial@e6e58000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; @@ -428,7 +428,7 @@ scif3: serial@e6ea8000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; clock-names = "sci_ick"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; @@ -440,7 +440,7 @@ scif4: serial@e6ee0000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; clock-names = "sci_ick"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; @@ -452,7 +452,7 @@ scif5: serial@e6ee8000 { compatible = "renesas,scif-r8a7794", "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; clock-names = "sci_ick"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; @@ -464,7 +464,7 @@ hscif0: serial@e62c0000 { compatible = "renesas,hscif-r8a7794", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; clock-names = "sci_ick"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; @@ -476,7 +476,7 @@ hscif1: serial@e62c8000 { compatible = "renesas,hscif-r8a7794", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; clock-names = "sci_ick"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; @@ -488,7 +488,7 @@ hscif2: serial@e62d0000 { compatible = "renesas,hscif-r8a7794", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; clock-names = "sci_ick"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; @@ -500,7 +500,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7794"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -513,7 +513,7 @@ i2c0: i2c@e6508000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C0>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -525,7 +525,7 @@ i2c1: i2c@e6518000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C1>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -537,7 +537,7 @@ i2c2: i2c@e6530000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C2>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -549,7 +549,7 @@ i2c3: i2c@e6540000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C3>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -561,7 +561,7 @@ i2c4: i2c@e6520000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C4>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -573,7 +573,7 @@ i2c5: i2c@e6528000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C5>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -585,7 +585,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -597,7 +597,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee100000 0 0x200>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -606,7 +606,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -615,7 +615,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -624,7 +624,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7794", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -638,7 +638,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -647,7 +647,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -658,7 +658,7 @@ device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -669,9 +669,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -693,7 +693,7 @@ device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -704,9 +704,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -726,7 +726,7 @@ hsusb: usb@e6590000 { compatible = "renesas,usbhs-r8a7794", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSUSB>; power-domains = <&cpg_clocks>; renesas,buswait = <4>; @@ -759,8 +759,8 @@ compatible = "renesas,du-r8a7794"; reg = <0 0xfeb00000 0 0x40000>; reg-names = "du"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7794_CLK_DU0>, <&mstp7_clks R8A7794_CLK_DU0>; clock-names = "du.0", "du.1"; @@ -1111,8 +1111,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1120,7 +1120,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1128,8 +1128,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1137,7 +1137,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1145,8 +1145,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1154,8 +1154,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; -- GitLab From 8871eb07c0e77196f1f6cd2ccd659516e3e5d9aa Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 18 Jan 2016 20:03:10 +0900 Subject: [PATCH 0494/5324] ARM: dts: r8a7793: gose: Add HDMI video out support This patch adds r8a7793 GOSE HDMI video out support. The r8a7793 GOSE board is similar to r8a7791 Koelsch. For those boards an on-board HDMI encoder chip provides HDMI video out and also a LVDS port is available for external LCD panels. Tested on r8a7793 Gose with HDMI hooked up to a Toshiba TV. Signed-off-by: Magnus Damm [simon: rebased; reused existing i2c2 node] Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 85 ++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 987ed03b1e02..0b4cc8d99390 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -129,6 +129,54 @@ label = "LED8"; }; }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + x13_clk: x13-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; +}; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7793_CLK_DU0>, + <&mstp7_clks R8A7793_CLK_DU1>, + <&mstp7_clks R8A7793_CLK_LVDS0>, + <&x13_clk>, <&x2_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + lvds_connector: endpoint { + }; + }; + }; }; &extal_clk { @@ -141,6 +189,11 @@ renesas,function = "i2c2"; }; + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; @@ -247,6 +300,38 @@ status = "okay"; clock-frequency = <100000>; + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + eeprom@50 { compatible = "renesas,r1ex24002", "atmel,24c02"; reg = <0x50>; -- GitLab From 0c34bd1e00b0c60407ede0ca0d49862ef6116fa5 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 21 Jan 2016 13:52:45 +0900 Subject: [PATCH 0495/5324] ARM: dts: r8a7778: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7778 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7778.dtsi | 87 +++++++++++++++++----------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 791aafd310a5..fc5e7243467a 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -17,6 +17,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -51,7 +52,7 @@ ether: ethernet@fde00000 { compatible = "renesas,ether-r8a7778"; reg = <0xfde00000 0x400>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7778_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -79,17 +80,17 @@ <0xfe780024 4>, <0xfe780044 4>, <0xfe780064 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -100,7 +101,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -111,7 +112,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -122,7 +123,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -133,7 +134,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 27>; @@ -151,7 +152,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc70000 0x1000>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -162,7 +163,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc71000 0x1000>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -173,7 +174,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc72000 0x1000>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -184,7 +185,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc73000 0x1000>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,9 +194,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -208,9 +209,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -223,9 +224,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -285,20 +286,20 @@ }; rcar_sound,ssi { - ssi3: ssi@3 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi4: ssi@4 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi5: ssi@5 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi6: ssi@6 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi7: ssi@7 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi8: ssi@8 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi9: ssi@9 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; + ssi3: ssi@3 { interrupts = ; }; + ssi4: ssi@4 { interrupts = ; }; + ssi5: ssi@5 { interrupts = ; }; + ssi6: ssi@6 { interrupts = ; }; + ssi7: ssi@7 { interrupts = ; }; + ssi8: ssi@8 { interrupts = ; }; + ssi9: ssi@9 { interrupts = ; }; }; }; scif0: serial@ffe40000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -308,7 +309,7 @@ scif1: serial@ffe41000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -318,7 +319,7 @@ scif2: serial@ffe42000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -328,7 +329,7 @@ scif3: serial@ffe43000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -338,7 +339,7 @@ scif4: serial@ffe44000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -348,7 +349,7 @@ scif5: serial@ffe45000 { compatible = "renesas,scif-r8a7778", "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -358,7 +359,7 @@ mmcif: mmc@ffe4e000 { compatible = "renesas,sh-mmcif"; reg = <0xffe4e000 0x100>; - interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_MMC>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -367,7 +368,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4c000 0x100>; - interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -376,7 +377,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4d000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -385,7 +386,7 @@ sdhi2: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4f000 0x100>; - interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -394,7 +395,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -405,7 +406,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -416,7 +417,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; -- GitLab From 854b7733fee0ebdb70e34ffa5f57de4cff319a49 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 21 Jan 2016 13:52:46 +0900 Subject: [PATCH 0496/5324] ARM: dts: r8a7779: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7779 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a7779.dtsi | 78 +++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 6afa909865b5..93f3fdf95e31 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -74,7 +74,7 @@ gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -85,7 +85,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -96,7 +96,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -107,7 +107,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -118,7 +118,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -129,7 +129,7 @@ gpio5: gpio@ffc45000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc45000 0x2c>; - interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -140,7 +140,7 @@ gpio6: gpio@ffc46000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc46000 0x2c>; - interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 9>; @@ -159,10 +159,10 @@ <0xfe780044 4>, <0xfe780064 4>, <0xfe780000 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; @@ -171,7 +171,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc70000 0x1000>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -182,7 +182,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc71000 0x1000>; - interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,7 +193,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc72000 0x1000>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -204,7 +204,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc73000 0x1000>; - interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -213,7 +213,7 @@ scif0: serial@ffe40000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -223,7 +223,7 @@ scif1: serial@ffe41000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -233,7 +233,7 @@ scif2: serial@ffe42000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -243,7 +243,7 @@ scif3: serial@ffe43000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -253,7 +253,7 @@ scif4: serial@ffe44000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -263,7 +263,7 @@ scif5: serial@ffe45000 { compatible = "renesas,scif-r8a7779", "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -283,9 +283,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -298,9 +298,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -313,9 +313,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -328,7 +328,7 @@ sata: sata@fc600000 { compatible = "renesas,sata-r8a7779", "renesas,rcar-sata"; reg = <0xfc600000 0x2000>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_SATA>; power-domains = <&cpg_clocks>; }; @@ -336,7 +336,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4c000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -345,7 +345,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4d000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -354,7 +354,7 @@ sdhi2: sd@ffe4e000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4e000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -363,7 +363,7 @@ sdhi3: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4f000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -372,7 +372,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -383,7 +383,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -394,7 +394,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -405,7 +405,7 @@ du: display@fff80000 { compatible = "renesas,du-r8a7779"; reg = <0 0xfff80000 0 0x40000>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; power-domains = <&cpg_clocks>; status = "disabled"; -- GitLab From 493b4da7c10ca647850627849bcf6031c0a80f13 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 21 Jan 2016 14:36:01 -0800 Subject: [PATCH 0497/5324] ARM: dts: porter: add sound support Define the Porter board dependent part of the R8A7791 sound device node. Add device node for Asahi Kasei AK4642 stereo codec to the I2C2 bus. Add the "simple-audio-card" device node to interconnect the SoC sound device and the codec. Signed-off-by: Sergei Shtylyov Acked-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-porter.dts | 71 ++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index fe81fa0e478c..5015eaa0ae50 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -8,6 +8,17 @@ * kind, whether express or implied. */ +/* + * SSI-AK4642 + * + * SW3: 1: AK4642 + * 3: ADV7511 + * + * This command is required before playback/capture: + * + * amixer set "LINEOUT Mixer DACL" on + */ + /dts-v1/; #include "r8a7791.dtsi" #include @@ -101,6 +112,30 @@ #clock-cells = <0>; clock-frequency = <74250000>; }; + + x14_clk: x14-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&soundcodec>; + simple-audio-card,frame-master = <&soundcodec>; + + simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + soundcodec: simple-audio-card,codec { + sound-dai = <&ak4642>; + clocks = <&x14_clk>; + }; + }; }; &extal_clk { @@ -167,6 +202,16 @@ renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; renesas,function = "du"; }; + + ssi_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + audio_clk_pins: audio_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; &scif0 { @@ -257,6 +302,12 @@ status = "okay"; clock-frequency = <400000>; + ak4642: codec@12 { + compatible = "asahi-kasei,ak4642"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + composite-in@20 { compatible = "adi,adv7180"; reg = <0x20>; @@ -385,3 +436,23 @@ }; }; }; + +&rcar_sound { + pinctrl-0 = <&ssi_pins &audio_clk_pins>; + pinctrl-names = "default"; + status = "okay"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + rcar_sound,dai { + dai0 { + playback = <&ssi0>; + capture = <&ssi1>; + }; + }; +}; + +&ssi1 { + shared-pin; +}; -- GitLab From 4d5746a3ec3a705028aeb81b34fbca70e523668a Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 25 Jan 2016 09:52:49 +0900 Subject: [PATCH 0498/5324] ARM: dts: r8a73a4: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a73a4 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r8a73a4.dtsi | 212 ++++++++++++++++----------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index cb4f7b2798fe..64f3efcd7ba5 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -39,10 +39,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; dbsc1: memory-controller@e6790000 { @@ -69,27 +69,27 @@ dma0: dma-controller@e6700020 { compatible = "renesas,shdma-r8a73a4"; reg = <0 0xe6700020 0 0x89e0>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH - 0 215 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -106,7 +106,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x428>; - interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC5>; power-domains = <&pd_a3sp>; @@ -116,7 +116,7 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -131,38 +131,38 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 4 IRQ_TYPE_LEVEL_HIGH>, - <0 5 IRQ_TYPE_LEVEL_HIGH>, - <0 6 IRQ_TYPE_LEVEL_HIGH>, - <0 7 IRQ_TYPE_LEVEL_HIGH>, - <0 8 IRQ_TYPE_LEVEL_HIGH>, - <0 9 IRQ_TYPE_LEVEL_HIGH>, - <0 10 IRQ_TYPE_LEVEL_HIGH>, - <0 11 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>, - <0 18 IRQ_TYPE_LEVEL_HIGH>, - <0 19 IRQ_TYPE_LEVEL_HIGH>, - <0 20 IRQ_TYPE_LEVEL_HIGH>, - <0 21 IRQ_TYPE_LEVEL_HIGH>, - <0 22 IRQ_TYPE_LEVEL_HIGH>, - <0 23 IRQ_TYPE_LEVEL_HIGH>, - <0 24 IRQ_TYPE_LEVEL_HIGH>, - <0 25 IRQ_TYPE_LEVEL_HIGH>, - <0 26 IRQ_TYPE_LEVEL_HIGH>, - <0 27 IRQ_TYPE_LEVEL_HIGH>, - <0 28 IRQ_TYPE_LEVEL_HIGH>, - <0 29 IRQ_TYPE_LEVEL_HIGH>, - <0 30 IRQ_TYPE_LEVEL_HIGH>, - <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -172,32 +172,32 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0200 0 0x200>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>, - <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>, - <0 39 IRQ_TYPE_LEVEL_HIGH>, - <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>, - <0 43 IRQ_TYPE_LEVEL_HIGH>, - <0 44 IRQ_TYPE_LEVEL_HIGH>, - <0 45 IRQ_TYPE_LEVEL_HIGH>, - <0 46 IRQ_TYPE_LEVEL_HIGH>, - <0 47 IRQ_TYPE_LEVEL_HIGH>, - <0 48 IRQ_TYPE_LEVEL_HIGH>, - <0 49 IRQ_TYPE_LEVEL_HIGH>, - <0 50 IRQ_TYPE_LEVEL_HIGH>, - <0 51 IRQ_TYPE_LEVEL_HIGH>, - <0 52 IRQ_TYPE_LEVEL_HIGH>, - <0 53 IRQ_TYPE_LEVEL_HIGH>, - <0 54 IRQ_TYPE_LEVEL_HIGH>, - <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>, - <0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -237,7 +237,7 @@ compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>; power-domains = <&pd_c5>; }; @@ -247,7 +247,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x428>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -258,7 +258,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x428>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -269,7 +269,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x428>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -280,7 +280,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6530000 0 0x428>; - interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -291,7 +291,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6540000 0 0x428>; - interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC4>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -302,7 +302,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6550000 0 0x428>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC6>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -313,7 +313,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6560000 0 0x428>; - interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC7>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -324,7 +324,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6570000 0 0x428>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_IIC8>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -333,7 +333,7 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c20000 0 0x100>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB0>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -343,7 +343,7 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c30000 0 0x100>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB1>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -353,7 +353,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c40000 0 0x100>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA0>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -363,7 +363,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c50000 0 0x100>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA1>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -373,7 +373,7 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6ce0000 0 0x100>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB2>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -383,7 +383,7 @@ scifb3: serial@e6cf0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6cf0000 0 0x100>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB3>; clock-names = "sci_ick"; power-domains = <&pd_c4>; @@ -393,7 +393,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee100000 0 0x100>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -403,7 +403,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee120000 0 0x100>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -413,7 +413,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -423,7 +423,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -433,7 +433,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF1>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -449,7 +449,7 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; bsc: bus@fec10000 { -- GitLab From e1e7b6fa83f0d8372392662ebdffdd79c71ba6a3 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 25 Jan 2016 09:52:58 +0900 Subject: [PATCH 0499/5324] ARM: dts: r8a7740: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r8a7740 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7740.dtsi | 143 +++++++++++++++++---------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 6ef954766eef..36bcb39cca03 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -11,6 +11,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -41,7 +42,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -58,7 +59,7 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; ptm { @@ -69,7 +70,7 @@ cmt1: timer@e6138000 { compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48"; reg = <0xe6138000 0x170>; - interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -89,14 +90,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -111,14 +112,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -133,14 +134,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -155,14 +156,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -171,7 +172,7 @@ compatible = "renesas,gether-r8a7740"; reg = <0xe9a00000 0x800>, <0xe9a01800 0x800>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_GETHER>; power-domains = <&pd_a4s>; phy-mode = "mii"; @@ -185,10 +186,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xfff20000 0x425>; - interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7740_CLK_IIC0>; power-domains = <&pd_a4r>; status = "disabled"; @@ -199,10 +200,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xe6c20000 0x425>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH - 0 71 IRQ_TYPE_LEVEL_HIGH - 0 72 IRQ_TYPE_LEVEL_HIGH - 0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,7 +212,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -221,7 +222,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -231,7 +232,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -241,7 +242,7 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -251,7 +252,7 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -261,7 +262,7 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -271,7 +272,7 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -281,7 +282,7 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -291,7 +292,7 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-r8a7740", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFB>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -329,8 +330,8 @@ mmcif0: mmc@e6bd0000 { compatible = "renesas,mmcif-r8a7740", "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH - 0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_MMC>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -339,9 +340,9 @@ sdhi0: sd@e6850000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6850000 0x100>; - interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH - 0 118 IRQ_TYPE_LEVEL_HIGH - 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -352,9 +353,9 @@ sdhi1: sd@e6860000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6860000 0x100>; - interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH - 0 122 IRQ_TYPE_LEVEL_HIGH - 0 123 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -365,9 +366,9 @@ sdhi2: sd@e6870000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6870000 0x100>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH - 0 126 IRQ_TYPE_LEVEL_HIGH - 0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A7740_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -379,7 +380,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2"; reg = <0xfe1f0000 0x400>; - interrupts = <0 9 0x4>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_FSI>; power-domains = <&pd_a4mp>; status = "disabled"; @@ -388,9 +389,9 @@ tmu0: timer@fff80000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff80000 0x2c>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU0>; clock-names = "fck"; power-domains = <&pd_a4r>; @@ -403,9 +404,9 @@ tmu1: timer@fff90000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff90000 0x2c>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU1>; clock-names = "fck"; power-domains = <&pd_a4r>; -- GitLab From 072d326542e491874c31adda10bf513b371e560c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 17:15:26 +0900 Subject: [PATCH 0500/5324] ARM: dts: r8a7793: add MSTP10 clocks to device tree Instantiate MSTP10 clocks in r8a7793 device tree. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 36 +++++++++++++++++++++++ include/dt-bindings/clock/r8a7793-clock.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index ea1196b99d52..c4459f147330 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -963,6 +963,42 @@ "qspi_mod", "i2c5", "i2c6", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0"; }; + mstp10_clks: mstp10_clks@e6150998 { + compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; + clocks = <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>; + + #clock-cells = <1>; + clock-indices = < + R8A7793_CLK_SSI_ALL + R8A7793_CLK_SSI9 R8A7793_CLK_SSI8 R8A7793_CLK_SSI7 R8A7793_CLK_SSI6 R8A7793_CLK_SSI5 + R8A7793_CLK_SSI4 R8A7793_CLK_SSI3 R8A7793_CLK_SSI2 R8A7793_CLK_SSI1 R8A7793_CLK_SSI0 + R8A7793_CLK_SCU_ALL + R8A7793_CLK_SCU_DVC1 R8A7793_CLK_SCU_DVC0 + R8A7793_CLK_SCU_CTU1_MIX1 R8A7793_CLK_SCU_CTU0_MIX0 + R8A7793_CLK_SCU_SRC9 R8A7793_CLK_SCU_SRC8 R8A7793_CLK_SCU_SRC7 R8A7793_CLK_SCU_SRC6 R8A7793_CLK_SCU_SRC5 + R8A7793_CLK_SCU_SRC4 R8A7793_CLK_SCU_SRC3 R8A7793_CLK_SCU_SRC2 R8A7793_CLK_SCU_SRC1 R8A7793_CLK_SCU_SRC0 + >; + clock-output-names = + "ssi-all", + "ssi9", "ssi8", "ssi7", "ssi6", "ssi5", + "ssi4", "ssi3", "ssi2", "ssi1", "ssi0", + "scu-all", + "scu-dvc1", "scu-dvc0", + "scu-ctu1-mix1", "scu-ctu0-mix0", + "scu-src9", "scu-src8", "scu-src7", "scu-src6", "scu-src5", + "scu-src4", "scu-src3", "scu-src2", "scu-src1", "scu-src0"; + }; mstp11_clks: mstp11_clks@e615099c { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>; diff --git a/include/dt-bindings/clock/r8a7793-clock.h b/include/dt-bindings/clock/r8a7793-clock.h index 1579e07f96a3..efcbc594fe82 100644 --- a/include/dt-bindings/clock/r8a7793-clock.h +++ b/include/dt-bindings/clock/r8a7793-clock.h @@ -145,6 +145,8 @@ #define R8A7793_CLK_SCU_ALL 17 #define R8A7793_CLK_SCU_DVC1 18 #define R8A7793_CLK_SCU_DVC0 19 +#define R8A7793_CLK_SCU_CTU1_MIX1 20 +#define R8A7793_CLK_SCU_CTU0_MIX0 21 #define R8A7793_CLK_SCU_SRC9 22 #define R8A7793_CLK_SCU_SRC8 23 #define R8A7793_CLK_SCU_SRC7 24 -- GitLab From ad6472bf11464d498fefcea9ae30ddf9255e4f49 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 17:16:12 +0900 Subject: [PATCH 0501/5324] ARM: dts: r8a7793: add audio clock to device tree Instantiate audio clock in r8a7793 device tree. audio_clk_a/b/c are required for R-Car sound. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index c4459f147330..530fa9488a4a 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -706,6 +706,29 @@ clock-output-names = "extal"; }; + /* + * The external audio clocks are configured as 0 Hz fixed frequency clocks by + * default. Boards that provide audio clocks should override them. + */ + audio_clk_a: audio_clk_a { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_a"; + }; + audio_clk_b: audio_clk_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_b"; + }; + audio_clk_c: audio_clk_c { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_c"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7793-cpg-clocks", -- GitLab From 892f09f1528d113f8d1e5983ecebd322236ded95 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 30 Nov 2015 16:11:37 +0900 Subject: [PATCH 0502/5324] ARM: dts: r8a7793: add m2 clock to device tree Declare m2 clock in r8a7793 device tree. Based on similar work for the r8a7791 by Laurent Pinchart. Acked-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 530fa9488a4a..6aabba6ef92c 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -817,6 +817,14 @@ clock-mult = <1>; clock-output-names = "p"; }; + m2_clk: m2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7793_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "m2"; + }; rclk_clk: rclk_clk { compatible = "fixed-factor-clock"; clocks = <&cpg_clocks R8A7793_CLK_PLL1>; -- GitLab From 951431e08636858bafabb7654c3aae0eac18d950 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 30 Nov 2015 15:51:12 +0900 Subject: [PATCH 0503/5324] ARM: dts: r8a7793: add R-Car sound support to device tree Instantiate R-Car sound node in r8a7793 device tree. This only supports PIO transfers. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 6aabba6ef92c..8b1ec47754ac 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -1101,4 +1101,87 @@ #iommu-cells = <1>; status = "disabled"; }; + + rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a7793", "renesas,rcar_sound-gen2"; + reg = <0 0xec500000 0 0x1000>, /* SCU */ + <0 0xec5a0000 0 0x100>, /* ADG */ + <0 0xec540000 0 0x1000>, /* SSIU */ + <0 0xec541000 0 0x280>; /* SSI */ + reg-names = "scu", "adg", "ssiu", "ssi"; + + clocks = <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI9>, <&mstp10_clks R8A7793_CLK_SSI8>, + <&mstp10_clks R8A7793_CLK_SSI7>, <&mstp10_clks R8A7793_CLK_SSI6>, + <&mstp10_clks R8A7793_CLK_SSI5>, <&mstp10_clks R8A7793_CLK_SSI4>, + <&mstp10_clks R8A7793_CLK_SSI3>, <&mstp10_clks R8A7793_CLK_SSI2>, + <&mstp10_clks R8A7793_CLK_SSI1>, <&mstp10_clks R8A7793_CLK_SSI0>, + <&mstp10_clks R8A7793_CLK_SCU_SRC9>, <&mstp10_clks R8A7793_CLK_SCU_SRC8>, + <&mstp10_clks R8A7793_CLK_SCU_SRC7>, <&mstp10_clks R8A7793_CLK_SCU_SRC6>, + <&mstp10_clks R8A7793_CLK_SCU_SRC5>, <&mstp10_clks R8A7793_CLK_SCU_SRC4>, + <&mstp10_clks R8A7793_CLK_SCU_SRC3>, <&mstp10_clks R8A7793_CLK_SCU_SRC2>, + <&mstp10_clks R8A7793_CLK_SCU_SRC1>, <&mstp10_clks R8A7793_CLK_SCU_SRC0>, + <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5", + "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", "src.5", + "src.4", "src.3", "src.2", "src.1", "src.0", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&cpg_clocks>; + + status = "disabled"; + + rcar_sound,src { + src0: src@0 { }; + src1: src@1 { }; + src2: src@2 { }; + src3: src@3 { }; + src4: src@4 { }; + src5: src@5 { }; + src6: src@6 { }; + src7: src@7 { }; + src8: src@8 { }; + src9: src@9 { }; + }; + + rcar_sound,ssi { + ssi0: ssi@0 { + interrupts = ; + }; + ssi1: ssi@1 { + interrupts = ; + }; + ssi2: ssi@2 { + interrupts = ; + }; + ssi3: ssi@3 { + interrupts = ; + }; + ssi4: ssi@4 { + interrupts = ; + }; + ssi5: ssi@5 { + interrupts = ; + }; + ssi6: ssi@6 { + interrupts = ; + }; + ssi7: ssi@7 { + interrupts = ; + }; + ssi8: ssi@8 { + interrupts = ; + }; + ssi9: ssi@9 { + interrupts = ; + }; + }; + }; }; -- GitLab From 4dfc6f8bbf821850c7a4e7f1364a42b63375ad4e Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 15:11:29 +0900 Subject: [PATCH 0504/5324] ARM: dts: r8a7793: add DVC support to device tree Add DVC support to sound node in r8a7793 device tree. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 8b1ec47754ac..3531d30fe107 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -1127,17 +1127,23 @@ <&mstp10_clks R8A7793_CLK_SCU_SRC5>, <&mstp10_clks R8A7793_CLK_SCU_SRC4>, <&mstp10_clks R8A7793_CLK_SCU_SRC3>, <&mstp10_clks R8A7793_CLK_SCU_SRC2>, <&mstp10_clks R8A7793_CLK_SCU_SRC1>, <&mstp10_clks R8A7793_CLK_SCU_SRC0>, + <&mstp10_clks R8A7793_CLK_SCU_DVC0>, <&mstp10_clks R8A7793_CLK_SCU_DVC1>, <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>; clock-names = "ssi-all", "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5", "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0", "src.9", "src.8", "src.7", "src.6", "src.5", "src.4", "src.3", "src.2", "src.1", "src.0", + "dvc.0", "dvc.1", "clk_a", "clk_b", "clk_c", "clk_i"; power-domains = <&cpg_clocks>; status = "disabled"; + rcar_sound,dvc { + dvc0: dvc@0 { }; + dvc1: dvc@1 { }; + }; rcar_sound,src { src0: src@0 { }; src1: src@1 { }; -- GitLab From 8d2883bddf47e3d59a4f041c6bd338f0d18783fe Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 30 Nov 2015 15:34:38 +0900 Subject: [PATCH 0505/5324] ARM: dts: r8a7793: add audio DMAC clocks to device tree Instantiate Audio DMA clocks in the r8a7791 device tree. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 3531d30fe107..cb6251e71ef9 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -924,10 +924,11 @@ mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>; - clocks = <&extal_clk>; + clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "thermal"; + clock-indices = ; + clock-output-names = "audmac0", "audmac1", "thermal"; }; mstp7_clks: mstp7_clks@e615014c { compatible = "renesas,r8a7793-mstp-clocks", -- GitLab From 6708eb73183e226ddd73dae128239e76b3807390 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 30 Nov 2015 15:34:38 +0900 Subject: [PATCH 0506/5324] ARM: dts: r8a7793: add audio DMAC to device tree Instantiate the two Audio DMA controllers in the r8a7791 device tree. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index cb6251e71ef9..2c9ab9f18b41 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -301,6 +301,64 @@ dma-channels = <15>; }; + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC0>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC1>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + /* The memory map in the User's Manual maps the cores to bus numbers */ i2c0: i2c@e6508000 { #address-cells = <1>; -- GitLab From 3cf7452a5ae2a90448121feb29810bf437d72f02 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 5 Jan 2016 09:24:42 +1100 Subject: [PATCH 0507/5324] ARM: dts: r8a7793: enable Audio DMAC peri peri via sound driver Audio DMAC peri peri is no longer DMAEngine. it is supported by sound driver. this patch enable it. Base on work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 2c9ab9f18b41..ddbda9d2c177 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -1172,8 +1172,9 @@ reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ - <0 0xec541000 0 0x280>; /* SSI */ - reg-names = "scu", "adg", "ssiu", "ssi"; + <0 0xec541000 0 0x280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; clocks = <&mstp10_clks R8A7793_CLK_SSI_ALL>, <&mstp10_clks R8A7793_CLK_SSI9>, <&mstp10_clks R8A7793_CLK_SSI8>, -- GitLab From f8905ce841deb22b43c6cc1f2ef47638e61bbec6 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 16:45:35 +0900 Subject: [PATCH 0508/5324] ARM: dts: gose: Enable sound PIO support in device tree Enable sound PIO support in the r8a7793/gose device tree. Based on similar work for the r8a7791/koelsch by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 0b4cc8d99390..395ea63746ac 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -8,6 +8,17 @@ * kind, whether express or implied. */ +/* + * SSI-AK4643 + * + * SW1: 1: AK4643 + * 2: CN22 + * 3: ADV7511 + * + * This command is required when Playback/Capture + * + * amixer set "LINEOUT Mixer DACL" on + */ /dts-v1/; #include "r8a7793.dtsi" #include @@ -130,6 +141,30 @@ }; }; + audio_clock: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + rsnd_ak4643: sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4643>; + clocks = <&audio_clock>; + }; + }; + hdmi-out { compatible = "hdmi-connector"; type = "a"; @@ -218,6 +253,16 @@ renesas,groups = "qspi_ctrl", "qspi_data4"; renesas,function = "qspi"; }; + + sound_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + sound_clk_pins: sound_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; ðer { @@ -300,6 +345,12 @@ status = "okay"; clock-frequency = <100000>; + ak4643: codec@12 { + compatible = "asahi-kasei,ak4643"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + hdmi@39 { compatible = "adi,adv7511w"; reg = <0x39>; @@ -338,3 +389,29 @@ pagesize = <16>; }; }; + +&rcar_sound { + pinctrl-0 = <&sound_pins &sound_clk_pins>; + pinctrl-names = "default"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + status = "okay"; + + rcar_sound,dai { + dai0 { + playback = <&ssi0>; + capture = <&ssi1>; + }; + }; +}; + +&ssi0 { + pio-transfer; +}; + +&ssi1 { + pio-transfer; + shared-pin; +}; -- GitLab From 96c1b8d8507102759c1e232f371ff333811ccdd9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 16:53:53 +0900 Subject: [PATCH 0509/5324] ARM: dts: gose: enable sound DMA support in device tree Enable DMA transfer to/from SSI in r8a7793/gose device tree. DMA [MEM] -> [SSI] DMA [MEM] <- [SSI] Based on similar work for the r8a7791/koelsch by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 395ea63746ac..a4b2dcb8e73d 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -408,10 +408,10 @@ }; &ssi0 { - pio-transfer; + no-busif; }; &ssi1 { - pio-transfer; + no-busif; shared-pin; }; -- GitLab From 402586d0cce05317100356cfd73f0c044c60ccd7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 16:55:59 +0900 Subject: [PATCH 0510/5324] ARM: dts: gose: enable sound DMA support via BUSIF in device tree Enable DMA transfer to/from SSIU in gose/r8a7791 device tree. DMA [MEM] -> [SSIU] -> [SSI] DMA [MEM] <- [SSIU] <- [SSI] Based on similar work for the r8a7791/koelsch by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index a4b2dcb8e73d..81bfe9484bbc 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -407,11 +407,6 @@ }; }; -&ssi0 { - no-busif; -}; - &ssi1 { - no-busif; shared-pin; }; -- GitLab From d2cde3b6103678a4f3d2079af744937dfc9c4104 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 16:57:33 +0900 Subject: [PATCH 0511/5324] ARM: dts: gose: enable sound DMA support via SRC in device tree Enable DMA transfer to/from SRC in r8a7793/gose device tree. DMA DMApp [MEM] -> [SRC] -> [SSIU] -> [SSI] DMA DMApp [MEM] <- [SRC] <- [SSIU] <- [SSI] Current sound driver is supporting SSI/SRC random connection. So, this patch is tring SSI0 -> SRC2 SSI1 <- SRC3 Based on similar work for the r8a7791/koeslch by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 81bfe9484bbc..17c87fe0944f 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -401,8 +401,8 @@ rcar_sound,dai { dai0 { - playback = <&ssi0>; - capture = <&ssi1>; + playback = <&ssi0 &src2>; + capture = <&ssi1 &src3>; }; }; }; -- GitLab From ae79f66db7e75dfe696df7f392f4db4980117306 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Wed, 2 Dec 2015 16:59:44 +0900 Subject: [PATCH 0512/5324] ARM: dts: gose: enable sound DMA support via DVC in device tree Enable DMA transfer using DVC in r8a7793/gose device tree. DMA DMApp [MEM] -> [SRC] -> [DVC] -> [SSIU] -> [SSI] DMA DMApp [MEM] <- [DVC] <- [SRC] <- [SSIU] <- [SSI] Based on similar work for the r8a7791/koelsch by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 17c87fe0944f..2fa052036dbc 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -18,7 +18,24 @@ * This command is required when Playback/Capture * * amixer set "LINEOUT Mixer DACL" on + * amixer set "DVC Out" 100% + * amixer set "DVC In" 100% + * + * You can use Mute + * + * amixer set "DVC Out Mute" on + * amixer set "DVC In Mute" on + * + * You can use Volume Ramp + * + * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" + * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" + * amixer set "DVC Out Ramp" on + * aplay xxx.wav & + * amixer set "DVC Out" 80% // Volume Down + * amixer set "DVC Out" 100% // Volume Up */ + /dts-v1/; #include "r8a7793.dtsi" #include @@ -401,8 +418,8 @@ rcar_sound,dai { dai0 { - playback = <&ssi0 &src2>; - capture = <&ssi1 &src3>; + playback = <&ssi0 &src2 &dvc0>; + capture = <&ssi1 &src3 &dvc1>; }; }; }; -- GitLab From f418cbb69a2f5a481bd5f210bb5c8c5cc9322224 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 18 Jan 2016 13:41:57 +0900 Subject: [PATCH 0513/5324] ARM: dts: r8a7793: enable audio DMAC in device tree Enable audio DMAC (= rcar-dmac) in r8a7793 device tree. Based on similar work for the r8a7791 by Kuninori Morimoto. Cc: Kuninori Morimoto Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- v4 * Use GIC_SPI in interrupts properties --- arch/arm/boot/dts/r8a7793.dtsi | 91 +++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index ddbda9d2c177..6817f14314e2 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -1201,52 +1201,119 @@ status = "disabled"; rcar_sound,dvc { - dvc0: dvc@0 { }; - dvc1: dvc@1 { }; + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; }; + rcar_sound,src { - src0: src@0 { }; - src1: src@1 { }; - src2: src@2 { }; - src3: src@3 { }; - src4: src@4 { }; - src5: src@5 { }; - src6: src@6 { }; - src7: src@7 { }; - src8: src@8 { }; - src9: src@9 { }; + src0: src@0 { + interrupts = ; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src@1 { + interrupts = ; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src@2 { + interrupts = ; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src@3 { + interrupts = ; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src@4 { + interrupts = ; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src@5 { + interrupts = ; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src@6 { + interrupts = ; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src@7 { + interrupts = ; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src@8 { + interrupts = ; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src@9 { + interrupts = ; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; }; rcar_sound,ssi { ssi0: ssi@0 { interrupts = ; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { interrupts = ; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { interrupts = ; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { interrupts = ; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { interrupts = ; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { interrupts = ; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { interrupts = ; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { interrupts = ; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { interrupts = ; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { interrupts = ; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; }; }; }; -- GitLab From 1e859111c128265f8d62b39ff322e42b1ddb5a20 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 25 Jan 2016 12:02:28 +0100 Subject: [PATCH 0514/5324] drm/i915: refine qemu south bridge detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test for the qemu q35 south bridge added by commit "39bfcd52 drm/i915: more virtual south bridge detection" also matches on real hardware. Having the check for virtual systems last in the list is not enough to avoid that ... Refine the check by additionally verifying the pci subsystem id to see whenever it *really* is qemu. [ v2: fix subvendor tyops ] Reported-and-tested-by: Bjørn Mork Signed-off-by: Gerd Hoffmann Tested-by: Bruno Wolff III Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1453719748-10944-1-git-send-email-kraxel@redhat.com --- drivers/gpu/drm/i915/i915_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 706b8eabfaf4..11d8414edbbe 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -501,7 +501,9 @@ void intel_detect_pch(struct drm_device *dev) WARN_ON(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev)); } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || - (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE)) { + ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && + pch->subsystem_vendor == 0x1af4 && + pch->subsystem_device == 0x1100)) { dev_priv->pch_type = intel_virt_detect_pch(dev); } else continue; -- GitLab From bbc396993a97246403f5979036f1b4637a56ef72 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 28 Jan 2016 15:22:05 -0800 Subject: [PATCH 0515/5324] drm/i915: Fix file permissions No functional change Signed-off-by: Mat Martineau Fixes: f8d03ea0053b ("drm/i915: increase the tries for HDMI hotplug live status checking") Link: http://patchwork.freedesktop.org/patch/msgid/1454023325-26265-1-git-send-email-mathew.j.martineau@linux.intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_hdmi.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 drivers/gpu/drm/i915/intel_hdmi.c diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c old mode 100755 new mode 100644 -- GitLab From 89aa027e6019d6e631a6c18c877e01f890a1800f Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Fri, 29 Jan 2016 10:58:02 +0300 Subject: [PATCH 0516/5324] clk: rockchip: Allow sclk_i2s0 and i2s0_frac to change their parents rate on rk3188 Allow sclk_i2s0 and i2s0_frac to change their parents rate as that the upstream dividers are purely there to feed sclk_i2s0 Tested on radxarock-lite. Signed-off-by: Alexander Kochetkov Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3188.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index cc1d09d77edd..629c65df1f2d 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -666,7 +666,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = - MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { @@ -722,7 +722,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(7), 0, RK2928_CLKGATE_CON(0), 10, GFLAGS, &rk3188_i2s0_fracmux), -- GitLab From 435b7be1d812cdbbad997f5279293770dff21abb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:43 +0800 Subject: [PATCH 0517/5324] clk: sunxi: factors: Support custom formulas Some clocks cannot be modelled using the standard factors clk formula, such as clocks with special pre-dividers on one parent, or clocks with all power-of-two dividers. Add support for a custom .recalc callback for factors clk. Also pass the current parent index to the .get_factor and .recalc callbacks. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 31 +++++++++++++++++++++++++++++-- drivers/clk/sunxi/clk-factors.h | 3 +++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 4a8e36a53287..2927b09d5e0d 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -63,6 +63,26 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) p = FACTOR_GET(config->pshift, config->pwidth, reg); + if (factors->recalc) { + struct factors_request factors_req = { + .parent_rate = parent_rate, + .n = n, + .k = k, + .m = m, + .p = p, + }; + + /* get mux details from mux clk structure */ + if (factors->mux) + factors_req.parent_index = + (reg >> factors->mux->shift) & + factors->mux->mask; + + factors->recalc(&factors_req); + + return factors_req.rate; + } + /* Calculate the rate */ rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); @@ -87,6 +107,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { + struct clk_factors *factors = to_clk_factors(hw); struct clk_hw *parent, *best_parent = NULL; int i, num_parents; unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; @@ -94,6 +115,10 @@ static int clk_factors_determine_rate(struct clk_hw *hw, /* find the parent that can help provide the fastest rate <= rate */ num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { + struct factors_request factors_req = { + .rate = req->rate, + .parent_index = i, + }; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -102,8 +127,9 @@ static int clk_factors_determine_rate(struct clk_hw *hw, else parent_rate = clk_hw_get_rate(parent); - child_rate = clk_factors_round_rate(hw, req->rate, - &parent_rate); + factors_req.parent_rate = parent_rate; + factors->get_factors(&factors_req); + child_rate = factors_req.rate; if (child_rate <= req->rate && child_rate > best_child_rate) { best_parent = parent; @@ -202,6 +228,7 @@ struct clk *sunxi_factors_register(struct device_node *node, factors->reg = reg; factors->config = data->table; factors->get_factors = data->getter; + factors->recalc = data->recalc; factors->lock = lock; /* Add a gate if this factor clock can be gated */ diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index f09d7c214533..a44a865a6b9e 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -22,6 +22,7 @@ struct clk_factors_config { struct factors_request { unsigned long rate; unsigned long parent_rate; + u8 parent_index; u8 n; u8 k; u8 m; @@ -34,6 +35,7 @@ struct factors_data { int muxmask; const struct clk_factors_config *table; void (*getter)(struct factors_request *req); + void (*recalc)(struct factors_request *req); const char *name; }; @@ -42,6 +44,7 @@ struct clk_factors { void __iomem *reg; const struct clk_factors_config *config; void (*get_factors)(struct factors_request *req); + void (*recalc)(struct factors_request *req); spinlock_t *lock; /* for cleanup */ struct clk_mux *mux; -- GitLab From 50d6ea47bab46645f28c439d9d8fb4840e10b486 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:44 +0800 Subject: [PATCH 0518/5324] clk: sunxi: factors: Drop round_rate from clk ops The common clock framework requires either determine_rate or round_rate to be implemented. We use determine_rate so we can pass the parent index to the get_factors callback. This cannot be done easily with round_rate, so just drop it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-factors.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 2927b09d5e0d..6e97f46c0c37 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -89,21 +89,6 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, return rate; } -static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct clk_factors *factors = to_clk_factors(hw); - struct factors_request req = { - .rate = rate, - .parent_rate = *parent_rate, - }; - - factors->get_factors(&req); - - - return rate; -} - static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -189,7 +174,6 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_factors_ops = { .determine_rate = clk_factors_determine_rate, .recalc_rate = clk_factors_recalc_rate, - .round_rate = clk_factors_round_rate, .set_rate = clk_factors_set_rate, }; -- GitLab From a78bb35552a800949b2bf68f372d3d6ccabdd790 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:45 +0800 Subject: [PATCH 0519/5324] clk: sunxi: rewrite sun6i-a31-ahb1-clk using factors clk with custom recalc The factors clk implementation has been extended to support custom recalc callbacks to support clocks that use one factor for certain parents only, like a pre-divider. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sunxi.c | 291 ++++++++++------------------------ 1 file changed, 83 insertions(+), 208 deletions(-) diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index a57c36c104dc..da15f2b12ab2 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -28,214 +28,6 @@ static DEFINE_SPINLOCK(clk_lock); -/** - * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk - */ - -#define SUN6I_AHB1_MAX_PARENTS 4 -#define SUN6I_AHB1_MUX_PARENT_PLL6 3 -#define SUN6I_AHB1_MUX_SHIFT 12 -/* un-shifted mask is what mux_clk expects */ -#define SUN6I_AHB1_MUX_MASK 0x3 -#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \ - SUN6I_AHB1_MUX_MASK) - -#define SUN6I_AHB1_DIV_SHIFT 4 -#define SUN6I_AHB1_DIV_MASK (0x3 << SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_GET(reg) ((reg & SUN6I_AHB1_DIV_MASK) >> \ - SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_DIV_MASK) | \ - (div << SUN6I_AHB1_DIV_SHIFT)) -#define SUN6I_AHB1_PLL6_DIV_SHIFT 6 -#define SUN6I_AHB1_PLL6_DIV_MASK (0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \ - SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \ - (div << SUN6I_AHB1_PLL6_DIV_SHIFT)) - -struct sun6i_ahb1_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw) - -static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long rate; - u32 reg; - - /* Fetch the register value */ - reg = readl(ahb1->reg); - - /* apply pre-divider first if parent is pll6 */ - if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6) - parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1; - - /* clk divider */ - rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg); - - return rate; -} - -static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp, - u8 parent, unsigned long parent_rate) -{ - u8 div, calcp, calcm = 1; - - /* - * clock can only divide, so we will never be able to achieve - * frequencies higher than the parent frequency - */ - if (parent_rate && rate > parent_rate) - rate = parent_rate; - - div = DIV_ROUND_UP(parent_rate, rate); - - /* calculate pre-divider if parent is pll6 */ - if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) { - if (div < 4) - calcp = 0; - else if (div / 2 < 4) - calcp = 1; - else if (div / 4 < 4) - calcp = 2; - else - calcp = 3; - - calcm = DIV_ROUND_UP(div, 1 << calcp); - } else { - calcp = __roundup_pow_of_two(div); - calcp = calcp > 3 ? 3 : calcp; - } - - /* we were asked to pass back divider values */ - if (divp) { - *divp = calcp; - *pre_divp = calcm - 1; - } - - return (parent_rate / calcm) >> calcp; -} - -static int sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - struct clk_hw *parent, *best_parent = NULL; - int i, num_parents; - unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; - - /* find the parent that can help provide the fastest rate <= rate */ - num_parents = clk_hw_get_num_parents(hw); - for (i = 0; i < num_parents; i++) { - parent = clk_hw_get_parent_by_index(hw, i); - if (!parent) - continue; - if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) - parent_rate = clk_hw_round_rate(parent, req->rate); - else - parent_rate = clk_hw_get_rate(parent); - - child_rate = sun6i_ahb1_clk_round(req->rate, NULL, NULL, i, - parent_rate); - - if (child_rate <= req->rate && child_rate > best_child_rate) { - best_parent = parent; - best = parent_rate; - best_child_rate = child_rate; - } - } - - if (!best_parent) - return -EINVAL; - - req->best_parent_hw = best_parent; - req->best_parent_rate = best; - req->rate = best_child_rate; - - return 0; -} - -static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long flags; - u8 div, pre_div, parent; - u32 reg; - - spin_lock_irqsave(&clk_lock, flags); - - reg = readl(ahb1->reg); - - /* need to know which parent is used to apply pre-divider */ - parent = SUN6I_AHB1_MUX_GET_PARENT(reg); - sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate); - - reg = SUN6I_AHB1_DIV_SET(reg, div); - reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div); - writel(reg, ahb1->reg); - - spin_unlock_irqrestore(&clk_lock, flags); - - return 0; -} - -static const struct clk_ops sun6i_ahb1_clk_ops = { - .determine_rate = sun6i_ahb1_clk_determine_rate, - .recalc_rate = sun6i_ahb1_clk_recalc_rate, - .set_rate = sun6i_ahb1_clk_set_rate, -}; - -static void __init sun6i_ahb1_clk_setup(struct device_node *node) -{ - struct clk *clk; - struct sun6i_ahb1_clk *ahb1; - struct clk_mux *mux; - const char *clk_name = node->name; - const char *parents[SUN6I_AHB1_MAX_PARENTS]; - void __iomem *reg; - int i; - - reg = of_io_request_and_map(node, 0, of_node_full_name(node)); - if (IS_ERR(reg)) - return; - - /* we have a mux, we will have >1 parents */ - i = of_clk_parent_fill(node, parents, SUN6I_AHB1_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); - - ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL); - if (!ahb1) - return; - - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(ahb1); - return; - } - - /* set up clock properties */ - mux->reg = reg; - mux->shift = SUN6I_AHB1_MUX_SHIFT; - mux->mask = SUN6I_AHB1_MUX_MASK; - mux->lock = &clk_lock; - ahb1->reg = reg; - - clk = clk_register_composite(NULL, clk_name, parents, i, - &mux->hw, &clk_mux_ops, - &ahb1->hw, &sun6i_ahb1_clk_ops, - NULL, NULL, 0); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } -} -CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup); - /* Maximum number of parents our clocks have */ #define SUNXI_MAX_PARENTS 5 @@ -490,6 +282,68 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req) req->p = div; } +#define SUN6I_AHB1_PARENT_PLL6 3 + +/** + * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB + * AHB rate is calculated as follows + * rate = parent_rate >> p + * + * if parent is pll6, then + * parent_rate = pll6 rate / (m + 1) + */ + +static void sun6i_get_ahb1_factors(struct factors_request *req) +{ + u8 div, calcp, calcm = 1; + + /* + * clock can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency + */ + if (req->parent_rate && req->rate > req->parent_rate) + req->rate = req->parent_rate; + + div = DIV_ROUND_UP(req->parent_rate, req->rate); + + /* calculate pre-divider if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) { + if (div < 4) + calcp = 0; + else if (div / 2 < 4) + calcp = 1; + else if (div / 4 < 4) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + } else { + calcp = __roundup_pow_of_two(div); + calcp = calcp > 3 ? 3 : calcp; + } + + req->rate = (req->parent_rate / calcm) >> calcp; + req->p = calcp; + req->m = calcm - 1; +} + +/** + * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and + * parent index + */ +static void sun6i_ahb1_recalc(struct factors_request *req) +{ + req->rate = req->parent_rate; + + /* apply pre-divider first if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) + req->rate /= req->m + 1; + + /* clk divider */ + req->rate >>= req->p; +} + /** * sun4i_get_apb1_factors() - calculates m, p factors for APB1 * APB1 rate is calculated as follows @@ -619,6 +473,13 @@ static const struct clk_factors_config sun5i_a13_ahb_config = { .pwidth = 2, }; +static const struct clk_factors_config sun6i_ahb1_config = { + .mshift = 6, + .mwidth = 2, + .pshift = 4, + .pwidth = 2, +}; + static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, @@ -686,6 +547,14 @@ static const struct factors_data sun5i_a13_ahb_data __initconst = { .getter = sun5i_a13_get_ahb_factors, }; +static const struct factors_data sun6i_ahb1_data __initconst = { + .mux = 12, + .muxmask = BIT(1) | BIT(0), + .table = &sun6i_ahb1_config, + .getter = sun6i_get_ahb1_factors, + .recalc = sun6i_ahb1_recalc, +}; + static const struct factors_data sun4i_apb1_data __initconst = { .mux = 24, .muxmask = BIT(1) | BIT(0), @@ -716,6 +585,12 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, return sunxi_factors_register(node, data, &clk_lock, reg); } +static void __init sun6i_ahb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_ahb1_data); +} +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", + sun6i_ahb1_clk_setup); /** -- GitLab From 3ca2377b6fed7c3db0c064ea73327cc6895e175d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:46 +0800 Subject: [PATCH 0520/5324] clk: sunxi: rewrite sun6i-ar100 using factors clk sun6i's AR100 clock is a classic factors clk case: AR100 = ((parent mux) >> p) / (m + 1) Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sun6i-ar100.c | 235 ++++++++-------------------- 1 file changed, 61 insertions(+), 174 deletions(-) diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 20887686bdbe..a7f5777834eb 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -8,211 +8,97 @@ * */ +#include #include #include #include #include +#include -#define SUN6I_AR100_MAX_PARENTS 4 -#define SUN6I_AR100_SHIFT_MASK 0x3 -#define SUN6I_AR100_SHIFT_MAX SUN6I_AR100_SHIFT_MASK -#define SUN6I_AR100_SHIFT_SHIFT 4 -#define SUN6I_AR100_DIV_MASK 0x1f -#define SUN6I_AR100_DIV_MAX (SUN6I_AR100_DIV_MASK + 1) -#define SUN6I_AR100_DIV_SHIFT 8 -#define SUN6I_AR100_MUX_MASK 0x3 -#define SUN6I_AR100_MUX_SHIFT 16 - -struct ar100_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw) -{ - return container_of(hw, struct ar100_clk, hw); -} - -static unsigned long ar100_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK; - int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK; - - return (parent_rate >> shift) / (div + 1); -} - -static int ar100_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int nparents = clk_hw_get_num_parents(hw); - long best_rate = -EINVAL; - int i; - - req->best_parent_hw = NULL; - - for (i = 0; i < nparents; i++) { - unsigned long parent_rate; - unsigned long tmp_rate; - struct clk_hw *parent; - unsigned long div; - int shift; - - parent = clk_hw_get_parent_by_index(hw, i); - parent_rate = clk_hw_get_rate(parent); - div = DIV_ROUND_UP(parent_rate, req->rate); - - /* - * The AR100 clk contains 2 divisors: - * - one power of 2 divisor - * - one regular divisor - * - * First check if we can safely shift (or divide by a power - * of 2) without losing precision on the requested rate. - */ - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; - - div >>= shift; - - /* - * Then if the divisor is still bigger than what the HW - * actually supports, use a bigger shift (or power of 2 - * divider) value and accept to lose some precision. - */ - while (div > SUN6I_AR100_DIV_MAX) { - shift++; - div >>= 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - break; - } - - /* - * If the shift value (or power of 2 divider) is bigger - * than what the HW actually support, skip this parent. - */ - if (shift > SUN6I_AR100_SHIFT_MAX) - continue; - - tmp_rate = (parent_rate >> shift) / div; - if (!req->best_parent_hw || tmp_rate > best_rate) { - req->best_parent_hw = parent; - req->best_parent_rate = parent_rate; - best_rate = tmp_rate; - } - } - - if (best_rate < 0) - return best_rate; - - req->rate = best_rate; - - return 0; -} - -static int ar100_set_parent(struct clk_hw *hw, u8 index) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - - if (index >= SUN6I_AR100_MAX_PARENTS) - return -EINVAL; - - val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT); - val |= (index << SUN6I_AR100_MUX_SHIFT); - writel(val, clk->reg); - - return 0; -} +#include "clk-factors.h" -static u8 ar100_get_parent(struct clk_hw *hw) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) & - SUN6I_AR100_MUX_MASK; -} - -static int ar100_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) +/** + * sun6i_get_ar100_factors - Calculates factors p, m for AR100 + * + * AR100 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ +static void sun6i_get_ar100_factors(struct factors_request *req) { - unsigned long div = parent_rate / rate; - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); + unsigned long div; int shift; - if (parent_rate % rate) - return -EINVAL; + /* clock only divides */ + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; + div = DIV_ROUND_UP(req->parent_rate, req->rate); - div >>= shift; + if (div < 32) + shift = 0; + else if (div >> 1 < 32) + shift = 1; + else if (div >> 2 < 32) + shift = 2; + else + shift = 3; - if (div > SUN6I_AR100_DIV_MAX) - return -EINVAL; + div >>= shift; - val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) | - (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT)); - val |= (shift << SUN6I_AR100_SHIFT_SHIFT) | - (div << SUN6I_AR100_DIV_SHIFT); - writel(val, clk->reg); + if (div > 32) + div = 32; - return 0; + req->rate = (req->parent_rate >> shift) / div; + req->m = div - 1; + req->p = shift; } -static struct clk_ops ar100_ops = { - .recalc_rate = ar100_recalc_rate, - .determine_rate = ar100_determine_rate, - .set_parent = ar100_set_parent, - .get_parent = ar100_get_parent, - .set_rate = ar100_set_rate, +static const struct clk_factors_config sun6i_ar100_config = { + .mwidth = 5, + .mshift = 8, + .pwidth = 2, + .pshift = 4, }; +static const struct factors_data sun6i_ar100_data __initconst = { + .mux = 16, + .muxmask = GENMASK(1, 0), + .table = &sun6i_ar100_config, + .getter = sun6i_get_ar100_factors, +}; + +static DEFINE_SPINLOCK(sun6i_ar100_lock); + static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) { - const char *parents[SUN6I_AR100_MAX_PARENTS]; struct device_node *np = pdev->dev.of_node; - const char *clk_name = np->name; - struct clk_init_data init; - struct ar100_clk *ar100; struct resource *r; + void __iomem *reg; struct clk *clk; - int nparents; - - ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); - if (!ar100) - return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ar100->reg = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(ar100->reg)) - return PTR_ERR(ar100->reg); + reg = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(reg)) + return PTR_ERR(reg); - nparents = of_clk_get_parent_count(np); - if (nparents > SUN6I_AR100_MAX_PARENTS) - nparents = SUN6I_AR100_MAX_PARENTS; - - of_clk_parent_fill(np, parents, nparents); + clk = sunxi_factors_register(np, &sun6i_ar100_data, &sun6i_ar100_lock, + reg); + if (!clk) + return -ENOMEM; - of_property_read_string(np, "clock-output-names", &clk_name); + platform_set_drvdata(pdev, clk); - init.name = clk_name; - init.ops = &ar100_ops; - init.parent_names = parents; - init.num_parents = nparents; - init.flags = 0; + return 0; +} - ar100->hw.init = &init; +static int sun6i_a31_ar100_clk_remove(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clk = platform_get_drvdata(pdev); - clk = clk_register(&pdev->dev, &ar100->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + sunxi_factors_unregister(np, clk); - return of_clk_add_provider(np, of_clk_src_simple_get, clk); + return 0; } static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { @@ -227,6 +113,7 @@ static struct platform_driver sun6i_a31_ar100_clk_driver = { .of_match_table = sun6i_a31_ar100_clk_dt_ids, }, .probe = sun6i_a31_ar100_clk_probe, + .remove = sun6i_a31_ar100_clk_remove, }; module_platform_driver(sun6i_a31_ar100_clk_driver); -- GitLab From 8f2bf2ad9673e187b5c2956497003f60e0885e5d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:47 +0800 Subject: [PATCH 0521/5324] clk: sunxi: rewrite sun8i-a23-mbus-clk using the simpler composite clk sun8i-a23-mbus-clk used sunxi's factors clk, which is nice for very complicated clocks, but is not really needed here. Convert sun8i-a23-mbus-clk to use clk_composite, as it is a gate + mux + divider. This makes the code easier to understand. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sun8i-mbus.c | 121 ++++++++++++++++++----------- 1 file changed, 76 insertions(+), 45 deletions(-) diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 78683f02a37d..3aaa9cbef791 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -15,68 +15,99 @@ */ #include +#include #include +#include +#include #include -#include "clk-factors.h" +#define SUN8I_MBUS_ENABLE 31 +#define SUN8I_MBUS_MUX_SHIFT 24 +#define SUN8I_MBUS_MUX_MASK 0x3 +#define SUN8I_MBUS_DIV_SHIFT 0 +#define SUN8I_MBUS_DIV_WIDTH 3 +#define SUN8I_MBUS_MAX_PARENTS 4 -/** - * sun8i_a23_get_mbus_factors() - calculates m factor for MBUS clocks - * MBUS rate is calculated as follows - * rate = parent_rate / (m + 1); - */ +static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); -static void sun8i_a23_get_mbus_factors(struct factors_request *req) +static void __init sun8i_a23_mbus_setup(struct device_node *node) { - u8 div; + int num_parents = of_clk_get_parent_count(node); + const char *parents[num_parents]; + const char *clk_name = node->name; + struct resource res; + struct clk_divider *div; + struct clk_gate *gate; + struct clk_mux *mux; + struct clk *clk; + void __iomem *reg; + int err; - /* - * These clocks can only divide, so we will never be able to - * achieve frequencies higher than the parent frequency - */ - if (req->rate > req->parent_rate) - req->rate = req->parent_rate; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (!reg) { + pr_err("Could not get registers for sun8i-mbus-clk\n"); + return; + } - div = DIV_ROUND_UP(req->parent_rate, req->rate); + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto err_unmap; - if (div > 8) - div = 8; + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto err_free_div; - req->rate = req->parent_rate / div; - req->m = div - 1; -} + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto err_free_mux; -static struct clk_factors_config sun8i_a23_mbus_config = { - .mshift = 0, - .mwidth = 3, -}; + of_property_read_string(node, "clock-output-names", &clk_name); + of_clk_parent_fill(node, parents, num_parents); -static const struct factors_data sun8i_a23_mbus_data __initconst = { - .enable = 31, - .mux = 24, - .muxmask = BIT(1) | BIT(0), - .table = &sun8i_a23_mbus_config, - .getter = sun8i_a23_get_mbus_factors, -}; + gate->reg = reg; + gate->bit_idx = SUN8I_MBUS_ENABLE; + gate->lock = &sun8i_a23_mbus_lock; -static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); + div->reg = reg; + div->shift = SUN8I_MBUS_DIV_SHIFT; + div->width = SUN8I_MBUS_DIV_WIDTH; + div->lock = &sun8i_a23_mbus_lock; -static void __init sun8i_a23_mbus_setup(struct device_node *node) -{ - struct clk *mbus; - void __iomem *reg; + mux->reg = reg; + mux->shift = SUN8I_MBUS_MUX_SHIFT; + mux->mask = SUN8I_MBUS_MUX_MASK; + mux->lock = &sun8i_a23_mbus_lock; - reg = of_iomap(node, 0); - if (!reg) { - pr_err("Could not get registers for a23-mbus-clk\n"); - return; - } + clk = clk_register_composite(NULL, clk_name, parents, num_parents, + &mux->hw, &clk_mux_ops, + &div->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(clk)) + goto err_free_gate; - mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data, - &sun8i_a23_mbus_lock, reg); + err = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (err) + goto err_unregister_clk; /* The MBUS clocks needs to be always enabled */ - __clk_get(mbus); - clk_prepare_enable(mbus); + __clk_get(clk); + clk_prepare_enable(clk); + + return; + +err_unregister_clk: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_free_gate: + kfree(gate); +err_free_mux: + kfree(mux); +err_free_div: + kfree(div); +err_unmap: + iounmap(reg); + of_address_to_resource(node, 0, &res); + release_mem_region(res.start, resource_size(&res)); } CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup); -- GitLab From cd6438c5f8446691afa4829fe1a9d7b656204f11 Mon Sep 17 00:00:00 2001 From: ZhengShunQian Date: Tue, 19 Jan 2016 15:03:00 +0800 Subject: [PATCH 0522/5324] iommu/rockchip: Reconstruct to support multi slaves There are some IPs, such as video encoder/decoder, contains 2 slave iommus, one for reading and the other for writing. They share the same irq and clock with master. This patch reconstructs to support this case by making them share the same Page Directory, Page Tables and even the register operations. That means every instruction to the reading MMU registers would be duplicated to the writing MMU and vice versa. Signed-off-by: ZhengShunQian Signed-off-by: Joerg Roedel --- drivers/iommu/rockchip-iommu.c | 214 +++++++++++++++++++++------------ 1 file changed, 135 insertions(+), 79 deletions(-) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index ebf0adb8e7ea..a6f593a0a29e 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -86,7 +86,8 @@ struct rk_iommu_domain { struct rk_iommu { struct device *dev; - void __iomem *base; + void __iomem **bases; + int num_mmu; int irq; struct list_head node; /* entry in rk_iommu_domain.iommus */ struct iommu_domain *domain; /* domain to which iommu is attached */ @@ -271,47 +272,70 @@ static u32 rk_iova_page_offset(dma_addr_t iova) return (u32)(iova & RK_IOVA_PAGE_MASK) >> RK_IOVA_PAGE_SHIFT; } -static u32 rk_iommu_read(struct rk_iommu *iommu, u32 offset) +static u32 rk_iommu_read(void __iomem *base, u32 offset) { - return readl(iommu->base + offset); + return readl(base + offset); } -static void rk_iommu_write(struct rk_iommu *iommu, u32 offset, u32 value) +static void rk_iommu_write(void __iomem *base, u32 offset, u32 value) { - writel(value, iommu->base + offset); + writel(value, base + offset); } static void rk_iommu_command(struct rk_iommu *iommu, u32 command) { - writel(command, iommu->base + RK_MMU_COMMAND); + int i; + + for (i = 0; i < iommu->num_mmu; i++) + writel(command, iommu->bases[i] + RK_MMU_COMMAND); } +static void rk_iommu_base_command(void __iomem *base, u32 command) +{ + writel(command, base + RK_MMU_COMMAND); +} static void rk_iommu_zap_lines(struct rk_iommu *iommu, dma_addr_t iova, size_t size) { + int i; + dma_addr_t iova_end = iova + size; /* * TODO(djkurtz): Figure out when it is more efficient to shootdown the * entire iotlb rather than iterate over individual iovas. */ - for (; iova < iova_end; iova += SPAGE_SIZE) - rk_iommu_write(iommu, RK_MMU_ZAP_ONE_LINE, iova); + for (i = 0; i < iommu->num_mmu; i++) + for (; iova < iova_end; iova += SPAGE_SIZE) + rk_iommu_write(iommu->bases[i], RK_MMU_ZAP_ONE_LINE, iova); } static bool rk_iommu_is_stall_active(struct rk_iommu *iommu) { - return rk_iommu_read(iommu, RK_MMU_STATUS) & RK_MMU_STATUS_STALL_ACTIVE; + bool active = true; + int i; + + for (i = 0; i < iommu->num_mmu; i++) + active &= rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) & + RK_MMU_STATUS_STALL_ACTIVE; + + return active; } static bool rk_iommu_is_paging_enabled(struct rk_iommu *iommu) { - return rk_iommu_read(iommu, RK_MMU_STATUS) & - RK_MMU_STATUS_PAGING_ENABLED; + bool enable = true; + int i; + + for (i = 0; i < iommu->num_mmu; i++) + enable &= rk_iommu_read(iommu->bases[i], RK_MMU_STATUS) & + RK_MMU_STATUS_PAGING_ENABLED; + + return enable; } static int rk_iommu_enable_stall(struct rk_iommu *iommu) { - int ret; + int ret, i; if (rk_iommu_is_stall_active(iommu)) return 0; @@ -324,15 +348,16 @@ static int rk_iommu_enable_stall(struct rk_iommu *iommu) ret = rk_wait_for(rk_iommu_is_stall_active(iommu), 1); if (ret) - dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n", - rk_iommu_read(iommu, RK_MMU_STATUS)); + for (i = 0; i < iommu->num_mmu; i++) + dev_err(iommu->dev, "Enable stall request timed out, status: %#08x\n", + rk_iommu_read(iommu->bases[i], RK_MMU_STATUS)); return ret; } static int rk_iommu_disable_stall(struct rk_iommu *iommu) { - int ret; + int ret, i; if (!rk_iommu_is_stall_active(iommu)) return 0; @@ -341,15 +366,16 @@ static int rk_iommu_disable_stall(struct rk_iommu *iommu) ret = rk_wait_for(!rk_iommu_is_stall_active(iommu), 1); if (ret) - dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n", - rk_iommu_read(iommu, RK_MMU_STATUS)); + for (i = 0; i < iommu->num_mmu; i++) + dev_err(iommu->dev, "Disable stall request timed out, status: %#08x\n", + rk_iommu_read(iommu->bases[i], RK_MMU_STATUS)); return ret; } static int rk_iommu_enable_paging(struct rk_iommu *iommu) { - int ret; + int ret, i; if (rk_iommu_is_paging_enabled(iommu)) return 0; @@ -358,15 +384,16 @@ static int rk_iommu_enable_paging(struct rk_iommu *iommu) ret = rk_wait_for(rk_iommu_is_paging_enabled(iommu), 1); if (ret) - dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n", - rk_iommu_read(iommu, RK_MMU_STATUS)); + for (i = 0; i < iommu->num_mmu; i++) + dev_err(iommu->dev, "Enable paging request timed out, status: %#08x\n", + rk_iommu_read(iommu->bases[i], RK_MMU_STATUS)); return ret; } static int rk_iommu_disable_paging(struct rk_iommu *iommu) { - int ret; + int ret, i; if (!rk_iommu_is_paging_enabled(iommu)) return 0; @@ -375,41 +402,49 @@ static int rk_iommu_disable_paging(struct rk_iommu *iommu) ret = rk_wait_for(!rk_iommu_is_paging_enabled(iommu), 1); if (ret) - dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n", - rk_iommu_read(iommu, RK_MMU_STATUS)); + for (i = 0; i < iommu->num_mmu; i++) + dev_err(iommu->dev, "Disable paging request timed out, status: %#08x\n", + rk_iommu_read(iommu->bases[i], RK_MMU_STATUS)); return ret; } static int rk_iommu_force_reset(struct rk_iommu *iommu) { - int ret; + int ret, i; u32 dte_addr; /* * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY * and verifying that upper 5 nybbles are read back. */ - rk_iommu_write(iommu, RK_MMU_DTE_ADDR, DTE_ADDR_DUMMY); + for (i = 0; i < iommu->num_mmu; i++) { + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, DTE_ADDR_DUMMY); - dte_addr = rk_iommu_read(iommu, RK_MMU_DTE_ADDR); - if (dte_addr != (DTE_ADDR_DUMMY & RK_DTE_PT_ADDRESS_MASK)) { - dev_err(iommu->dev, "Error during raw reset. MMU_DTE_ADDR is not functioning\n"); - return -EFAULT; + dte_addr = rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR); + if (dte_addr != (DTE_ADDR_DUMMY & RK_DTE_PT_ADDRESS_MASK)) { + dev_err(iommu->dev, "Error during raw reset. MMU_DTE_ADDR is not functioning\n"); + return -EFAULT; + } } rk_iommu_command(iommu, RK_MMU_CMD_FORCE_RESET); - ret = rk_wait_for(rk_iommu_read(iommu, RK_MMU_DTE_ADDR) == 0x00000000, - FORCE_RESET_TIMEOUT); - if (ret) - dev_err(iommu->dev, "FORCE_RESET command timed out\n"); + for (i = 0; i < iommu->num_mmu; i++) { + ret = rk_wait_for(rk_iommu_read(iommu->bases[i], RK_MMU_DTE_ADDR) == 0x00000000, + FORCE_RESET_TIMEOUT); + if (ret) { + dev_err(iommu->dev, "FORCE_RESET command timed out\n"); + return ret; + } + } - return ret; + return 0; } -static void log_iova(struct rk_iommu *iommu, dma_addr_t iova) +static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova) { + void __iomem *base = iommu->bases[index]; u32 dte_index, pte_index, page_offset; u32 mmu_dte_addr; phys_addr_t mmu_dte_addr_phys, dte_addr_phys; @@ -425,7 +460,7 @@ static void log_iova(struct rk_iommu *iommu, dma_addr_t iova) pte_index = rk_iova_pte_index(iova); page_offset = rk_iova_page_offset(iova); - mmu_dte_addr = rk_iommu_read(iommu, RK_MMU_DTE_ADDR); + mmu_dte_addr = rk_iommu_read(base, RK_MMU_DTE_ADDR); mmu_dte_addr_phys = (phys_addr_t)mmu_dte_addr; dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index); @@ -460,51 +495,56 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id) u32 status; u32 int_status; dma_addr_t iova; + irqreturn_t ret = IRQ_NONE; + int i; - int_status = rk_iommu_read(iommu, RK_MMU_INT_STATUS); - if (int_status == 0) - return IRQ_NONE; + for (i = 0; i < iommu->num_mmu; i++) { + int_status = rk_iommu_read(iommu->bases[i], RK_MMU_INT_STATUS); + if (int_status == 0) + continue; - iova = rk_iommu_read(iommu, RK_MMU_PAGE_FAULT_ADDR); + ret = IRQ_HANDLED; + iova = rk_iommu_read(iommu->bases[i], RK_MMU_PAGE_FAULT_ADDR); - if (int_status & RK_MMU_IRQ_PAGE_FAULT) { - int flags; + if (int_status & RK_MMU_IRQ_PAGE_FAULT) { + int flags; - status = rk_iommu_read(iommu, RK_MMU_STATUS); - flags = (status & RK_MMU_STATUS_PAGE_FAULT_IS_WRITE) ? - IOMMU_FAULT_WRITE : IOMMU_FAULT_READ; + status = rk_iommu_read(iommu->bases[i], RK_MMU_STATUS); + flags = (status & RK_MMU_STATUS_PAGE_FAULT_IS_WRITE) ? + IOMMU_FAULT_WRITE : IOMMU_FAULT_READ; - dev_err(iommu->dev, "Page fault at %pad of type %s\n", - &iova, - (flags == IOMMU_FAULT_WRITE) ? "write" : "read"); + dev_err(iommu->dev, "Page fault at %pad of type %s\n", + &iova, + (flags == IOMMU_FAULT_WRITE) ? "write" : "read"); - log_iova(iommu, iova); + log_iova(iommu, i, iova); - /* - * Report page fault to any installed handlers. - * Ignore the return code, though, since we always zap cache - * and clear the page fault anyway. - */ - if (iommu->domain) - report_iommu_fault(iommu->domain, iommu->dev, iova, - flags); - else - dev_err(iommu->dev, "Page fault while iommu not attached to domain?\n"); + /* + * Report page fault to any installed handlers. + * Ignore the return code, though, since we always zap cache + * and clear the page fault anyway. + */ + if (iommu->domain) + report_iommu_fault(iommu->domain, iommu->dev, iova, + flags); + else + dev_err(iommu->dev, "Page fault while iommu not attached to domain?\n"); - rk_iommu_command(iommu, RK_MMU_CMD_ZAP_CACHE); - rk_iommu_command(iommu, RK_MMU_CMD_PAGE_FAULT_DONE); - } + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); + rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_PAGE_FAULT_DONE); + } - if (int_status & RK_MMU_IRQ_BUS_ERROR) - dev_err(iommu->dev, "BUS_ERROR occurred at %pad\n", &iova); + if (int_status & RK_MMU_IRQ_BUS_ERROR) + dev_err(iommu->dev, "BUS_ERROR occurred at %pad\n", &iova); - if (int_status & ~RK_MMU_IRQ_MASK) - dev_err(iommu->dev, "unexpected int_status: %#08x\n", - int_status); + if (int_status & ~RK_MMU_IRQ_MASK) + dev_err(iommu->dev, "unexpected int_status: %#08x\n", + int_status); - rk_iommu_write(iommu, RK_MMU_INT_CLEAR, int_status); + rk_iommu_write(iommu->bases[i], RK_MMU_INT_CLEAR, int_status); + } - return IRQ_HANDLED; + return ret; } static phys_addr_t rk_iommu_iova_to_phys(struct iommu_domain *domain, @@ -746,7 +786,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain, struct rk_iommu *iommu; struct rk_iommu_domain *rk_domain = to_rk_domain(domain); unsigned long flags; - int ret; + int ret, i; phys_addr_t dte_addr; /* @@ -773,9 +813,11 @@ static int rk_iommu_attach_device(struct iommu_domain *domain, return ret; dte_addr = virt_to_phys(rk_domain->dt); - rk_iommu_write(iommu, RK_MMU_DTE_ADDR, dte_addr); - rk_iommu_command(iommu, RK_MMU_CMD_ZAP_CACHE); - rk_iommu_write(iommu, RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); + for (i = 0; i < iommu->num_mmu; i++) { + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dte_addr); + rk_iommu_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); + } ret = rk_iommu_enable_paging(iommu); if (ret) @@ -798,6 +840,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain, struct rk_iommu *iommu; struct rk_iommu_domain *rk_domain = to_rk_domain(domain); unsigned long flags; + int i; /* Allow 'virtual devices' (eg drm) to detach from domain */ iommu = rk_iommu_from_dev(dev); @@ -811,8 +854,10 @@ static void rk_iommu_detach_device(struct iommu_domain *domain, /* Ignore error while disabling, just keep going */ rk_iommu_enable_stall(iommu); rk_iommu_disable_paging(iommu); - rk_iommu_write(iommu, RK_MMU_INT_MASK, 0); - rk_iommu_write(iommu, RK_MMU_DTE_ADDR, 0); + for (i = 0; i < iommu->num_mmu; i++) { + rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 0); + rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, 0); + } rk_iommu_disable_stall(iommu); devm_free_irq(dev, iommu->irq, iommu); @@ -988,6 +1033,7 @@ static int rk_iommu_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rk_iommu *iommu; struct resource *res; + int i; iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); if (!iommu) @@ -995,11 +1041,21 @@ static int rk_iommu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, iommu); iommu->dev = dev; + iommu->num_mmu = 0; + iommu->bases = devm_kzalloc(dev, sizeof(*iommu->bases) * iommu->num_mmu, + GFP_KERNEL); + if (!iommu->bases) + return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - iommu->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(iommu->base)) - return PTR_ERR(iommu->base); + for (i = 0; i < pdev->num_resources; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + iommu->bases[i] = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(iommu->bases[i])) + continue; + iommu->num_mmu++; + } + if (iommu->num_mmu == 0) + return PTR_ERR(iommu->bases[0]); iommu->irq = platform_get_irq(pdev, 0); if (iommu->irq < 0) { -- GitLab From ca18d51d77eba6120f56761e5a0e541dbb07fa50 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 21 Jan 2016 18:03:05 -0200 Subject: [PATCH 0523/5324] drm/i915/fbc: wait for a vblank instead of 50ms when enabling Instead of waiting for 50ms, just wait until the next vblank, since it's the minimum requirement. The whole infrastructure of FBC is based on vblanks, so waiting for X vblanks instead of X milliseconds sounds like the correct way to go. Besides, 50ms may be less than a vblank on super slow modes that may or may not exist. There are some small improvements in PC state residency (due to the fact that we're now using 16ms for the common modes instead of 50ms), but the biggest advantage is still the correctness of being vblank-based instead of time-based. v2: - Rebase after changing the patch order. - Update the commit message. v3: - Fix bogus vblank_get() instead of vblank_count() (Ville). - Don't forget to call drm_crtc_vblank_{get,put} (Chris, Ville) - Adjust the performance details on the commit message. v4: - Don't grab the FBC mutex just to grab the vblank (Maarten) Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1453406585-10233-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_fbc.c | 39 ++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 905e90f25957..83b629b30c61 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -921,9 +921,9 @@ struct i915_fbc { struct intel_fbc_work { bool scheduled; + u32 scheduled_vblank; struct work_struct work; struct drm_framebuffer *fb; - unsigned long enable_jiffies; } work; const char *no_fbc_reason; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a1988a486b92..3993b431b02a 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -381,7 +381,17 @@ static void intel_fbc_work_fn(struct work_struct *__work) container_of(__work, struct drm_i915_private, fbc.work.work); struct intel_fbc_work *work = &dev_priv->fbc.work; struct intel_crtc *crtc = dev_priv->fbc.crtc; - int delay_ms = 50; + struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; + + if (drm_crtc_vblank_get(&crtc->base)) { + DRM_ERROR("vblank not available for FBC on pipe %c\n", + pipe_name(crtc->pipe)); + + mutex_lock(&dev_priv->fbc.lock); + work->scheduled = false; + mutex_unlock(&dev_priv->fbc.lock); + return; + } retry: /* Delay the actual enabling to let pageflipping cease and the @@ -390,14 +400,16 @@ static void intel_fbc_work_fn(struct work_struct *__work) * vblank to pass after disabling the FBC before we attempt * to modify the control registers. * - * A more complicated solution would involve tracking vblanks - * following the termination of the page-flipping sequence - * and indeed performing the enable as a co-routine and not - * waiting synchronously upon the vblank. - * * WaFbcWaitForVBlankBeforeEnable:ilk,snb + * + * It is also worth mentioning that since work->scheduled_vblank can be + * updated multiple times by the other threads, hitting the timeout is + * not an error condition. We'll just end up hitting the "goto retry" + * case below. */ - wait_remaining_ms_from_jiffies(work->enable_jiffies, delay_ms); + wait_event_timeout(vblank->queue, + drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank, + msecs_to_jiffies(50)); mutex_lock(&dev_priv->fbc.lock); @@ -406,8 +418,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) goto out; /* Were we delayed again while this function was sleeping? */ - if (time_after(work->enable_jiffies + msecs_to_jiffies(delay_ms), - jiffies)) { + if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) { mutex_unlock(&dev_priv->fbc.lock); goto retry; } @@ -419,6 +430,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) out: mutex_unlock(&dev_priv->fbc.lock); + drm_crtc_vblank_put(&crtc->base); } static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv) @@ -434,13 +446,20 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + if (drm_crtc_vblank_get(&crtc->base)) { + DRM_ERROR("vblank not available for FBC on pipe %c\n", + pipe_name(crtc->pipe)); + return; + } + /* It is useless to call intel_fbc_cancel_work() in this function since * we're not releasing fbc.lock, so it won't have an opportunity to grab * it to discover that it was cancelled. So we just update the expected * jiffy count. */ work->fb = crtc->base.primary->fb; work->scheduled = true; - work->enable_jiffies = jiffies; + work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); + drm_crtc_vblank_put(&crtc->base); schedule_work(&work->work); } -- GitLab From 615b40d7e441ee10b859ccc5a3e456c823f42cfa Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:35 -0200 Subject: [PATCH 0524/5324] drm/i915/fbc: extract intel_fbc_can_activate() Extract all the code that checks if the FBC configuration is valid to its own function, making __intel_fbc_update() much simpler. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-3-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 92 +++++++++++++++++--------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 3993b431b02a..1440bb32b912 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -516,17 +516,6 @@ static bool crtc_can_fbc(struct intel_crtc *crtc) return true; } -static bool crtc_is_valid(struct intel_crtc *crtc) -{ - if (!intel_crtc_active(&crtc->base)) - return false; - - if (!to_intel_plane_state(crtc->base.primary->state)->visible) - return false; - - return true; -} - static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) { enum pipe pipe; @@ -752,48 +741,40 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) return effective_w <= max_w && effective_h <= max_h; } -/** - * __intel_fbc_update - activate/deactivate FBC as needed, unlocked - * @crtc: the CRTC that triggered the update - * - * This function completely reevaluates the status of FBC, then activates, - * deactivates or maintains it on the same state. - */ -static void __intel_fbc_update(struct intel_crtc *crtc) +static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_plane *primary; struct drm_framebuffer *fb; + struct intel_plane_state *plane_state; struct drm_i915_gem_object *obj; const struct drm_display_mode *adjusted_mode; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - - if (!multiple_pipes_ok(dev_priv)) { - set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; - } - - if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) - return; - - if (!crtc_is_valid(crtc)) { - set_no_fbc_reason(dev_priv, "no output"); - goto out_disable; + if (!intel_crtc_active(&crtc->base)) { + set_no_fbc_reason(dev_priv, "CRTC not active"); + return false; } - fb = crtc->base.primary->fb; + primary = crtc->base.primary; + fb = primary->fb; obj = intel_fb_obj(fb); adjusted_mode = &crtc->config->base.adjusted_mode; + plane_state = to_intel_plane_state(primary->state); + + if (!plane_state->visible) { + set_no_fbc_reason(dev_priv, "primary plane not visible"); + return false; + } if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { set_no_fbc_reason(dev_priv, "incompatible mode"); - goto out_disable; + return false; } if (!intel_fbc_hw_tracking_covers_screen(crtc)) { set_no_fbc_reason(dev_priv, "mode too large for compression"); - goto out_disable; + return false; } /* The use of a CPU fence is mandatory in order to detect writes @@ -802,22 +783,22 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (obj->tiling_mode != I915_TILING_X || obj->fence_reg == I915_FENCE_REG_NONE) { set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); - goto out_disable; + return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && - crtc->base.primary->state->rotation != BIT(DRM_ROTATE_0)) { + plane_state->base.rotation != BIT(DRM_ROTATE_0)) { set_no_fbc_reason(dev_priv, "rotation unsupported"); - goto out_disable; + return false; } if (!stride_is_valid(dev_priv, fb->pitches[0])) { set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); - goto out_disable; + return false; } if (!pixel_format_is_valid(fb)) { set_no_fbc_reason(dev_priv, "pixel format is invalid"); - goto out_disable; + return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ @@ -825,7 +806,7 @@ static void __intel_fbc_update(struct intel_crtc *crtc) ilk_pipe_pixel_rate(crtc->config) >= dev_priv->cdclk_freq * 95 / 100) { set_no_fbc_reason(dev_priv, "pixel rate is too big"); - goto out_disable; + return false; } /* It is possible for the required CFB size change without a @@ -841,16 +822,43 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (intel_fbc_calculate_cfb_size(crtc, fb) > dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) { set_no_fbc_reason(dev_priv, "CFB requirements changed"); + return false; + } + + return true; +} + +/** + * __intel_fbc_update - activate/deactivate FBC as needed, unlocked + * @crtc: the CRTC that triggered the update + * + * This function completely reevaluates the status of FBC, then activates, + * deactivates or maintains it on the same state. + */ +static void __intel_fbc_update(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + + WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + + if (!multiple_pipes_ok(dev_priv)) { + set_no_fbc_reason(dev_priv, "more than one pipe active"); goto out_disable; } + if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) + return; + + if (!intel_fbc_can_activate(crtc)) + goto out_disable; + /* If the scanout has not changed, don't modify the FBC settings. * Note that we make the fundamental assumption that the fb->obj * cannot be unpinned (and have its GTT offset and fence revoked) * without first being decoupled from the scanout and FBC disabled. */ if (dev_priv->fbc.crtc == crtc && - dev_priv->fbc.fb_id == fb->base.id && + dev_priv->fbc.fb_id == crtc->base.primary->fb->base.id && dev_priv->fbc.y == crtc->base.y && dev_priv->fbc.active) return; -- GitLab From 44a8a257087bf5deb8c77bbb640cf0a15643b017 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:36 -0200 Subject: [PATCH 0525/5324] drm/i915/fbc: extract intel_fbc_can_enable() Make our enable/activate checking model more explicit, especially since we now have intel_fbc_can_activate(). Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-4-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 46 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 1440bb32b912..f76b158e248f 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -828,6 +828,33 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return true; } +static bool intel_fbc_can_enable(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + + if (intel_vgpu_active(dev_priv->dev)) { + set_no_fbc_reason(dev_priv, "VGPU is active"); + return false; + } + + if (i915.enable_fbc < 0) { + set_no_fbc_reason(dev_priv, "disabled per chip default"); + return false; + } + + if (!i915.enable_fbc) { + set_no_fbc_reason(dev_priv, "disabled per module param"); + return false; + } + + if (!crtc_can_fbc(crtc)) { + set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC"); + return false; + } + + return true; +} + /** * __intel_fbc_update - activate/deactivate FBC as needed, unlocked * @crtc: the CRTC that triggered the update @@ -997,25 +1024,8 @@ void intel_fbc_enable(struct intel_crtc *crtc) WARN_ON(dev_priv->fbc.active); WARN_ON(dev_priv->fbc.crtc != NULL); - if (intel_vgpu_active(dev_priv->dev)) { - set_no_fbc_reason(dev_priv, "VGPU is active"); - goto out; - } - - if (i915.enable_fbc < 0) { - set_no_fbc_reason(dev_priv, "disabled per chip default"); - goto out; - } - - if (!i915.enable_fbc) { - set_no_fbc_reason(dev_priv, "disabled per module param"); + if (!intel_fbc_can_enable(crtc)) goto out; - } - - if (!crtc_can_fbc(crtc)) { - set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC"); - goto out; - } if (intel_fbc_alloc_cfb(crtc)) { set_no_fbc_reason(dev_priv, "not enough stolen memory"); -- GitLab From b183b3f143959b8eea5d0970fd4ffe78df3a0210 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 23 Dec 2015 18:28:11 -0200 Subject: [PATCH 0526/5324] drm/i915/fbc: introduce struct intel_fbc_reg_params The early return inside __intel_fbc_update does not completely check all the parameters that affect the FBC register values. For example, we currently lack looking at crtc->adjusted_y (for the fence Y offset) and all the parameters that affect the CFB size (for i8xx). Instead of just adding the missing parameters to the check and hoping that any changes to the fbc_activate functions also come with a matching change to the __intel_fbc_update check, introduce a new structure where we store these parameters and use the structure at the fbc_activate function. Of course, it's still possible to access everything from dev_priv in those functions, but IMHO the new code will be harder to break. v2: Rebase. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-5-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 22 +++++- drivers/gpu/drm/i915/intel_fbc.c | 131 +++++++++++++++++-------------- 2 files changed, 93 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 83b629b30c61..99bac7e0121e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -905,11 +905,9 @@ struct i915_fbc { * it's the outer lock when overlapping with stolen_lock. */ struct mutex lock; unsigned threshold; - unsigned int fb_id; unsigned int possible_framebuffer_bits; unsigned int busy_bits; struct intel_crtc *crtc; - int y; struct drm_mm_node compressed_fb; struct drm_mm_node *compressed_llb; @@ -919,6 +917,24 @@ struct i915_fbc { bool enabled; bool active; + struct intel_fbc_reg_params { + struct { + enum pipe pipe; + enum plane plane; + unsigned int fence_y_offset; + } crtc; + + struct { + u64 ggtt_offset; + uint32_t id; + uint32_t pixel_format; + unsigned int stride; + int fence_reg; + } fb; + + int cfb_size; + } params; + struct intel_fbc_work { bool scheduled; u32 scheduled_vblank; @@ -929,7 +945,7 @@ struct i915_fbc { const char *no_fbc_reason; bool (*is_active)(struct drm_i915_private *dev_priv); - void (*activate)(struct intel_crtc *crtc); + void (*activate)(struct drm_i915_private *dev_priv); void (*deactivate)(struct drm_i915_private *dev_priv); }; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index f76b158e248f..14200d29383b 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -130,11 +130,9 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) } } -static void i8xx_fbc_activate(struct intel_crtc *crtc) +static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; int cfb_pitch; int i; u32 fbc_ctl; @@ -142,9 +140,9 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) dev_priv->fbc.active = true; /* Note: fbc.threshold == 1 for i8xx */ - cfb_pitch = intel_fbc_calculate_cfb_size(crtc, fb) / FBC_LL_SIZE; - if (fb->pitches[0] < cfb_pitch) - cfb_pitch = fb->pitches[0]; + cfb_pitch = params->cfb_size / FBC_LL_SIZE; + if (params->fb.stride < cfb_pitch) + cfb_pitch = params->fb.stride; /* FBC_CTL wants 32B or 64B units */ if (IS_GEN2(dev_priv)) @@ -161,9 +159,9 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) /* Set it up... */ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; - fbc_ctl2 |= FBC_CTL_PLANE(crtc->plane); + fbc_ctl2 |= FBC_CTL_PLANE(params->crtc.plane); I915_WRITE(FBC_CONTROL2, fbc_ctl2); - I915_WRITE(FBC_FENCE_OFF, get_crtc_fence_y_offset(crtc)); + I915_WRITE(FBC_FENCE_OFF, params->crtc.fence_y_offset); } /* enable it... */ @@ -173,7 +171,7 @@ static void i8xx_fbc_activate(struct intel_crtc *crtc) if (IS_I945GM(dev_priv)) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; - fbc_ctl |= obj->fence_reg; + fbc_ctl |= params->fb.fence_reg; I915_WRITE(FBC_CONTROL, fbc_ctl); } @@ -182,23 +180,21 @@ static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv) return I915_READ(FBC_CONTROL) & FBC_CTL_EN; } -static void g4x_fbc_activate(struct intel_crtc *crtc) +static void g4x_fbc_activate(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; u32 dpfc_ctl; dev_priv->fbc.active = true; - dpfc_ctl = DPFC_CTL_PLANE(crtc->plane) | DPFC_SR_EN; - if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) + dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane) | DPFC_SR_EN; + if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) dpfc_ctl |= DPFC_CTL_LIMIT_2X; else dpfc_ctl |= DPFC_CTL_LIMIT_1X; - dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; + dpfc_ctl |= DPFC_CTL_FENCE_EN | params->fb.fence_reg; - I915_WRITE(DPFC_FENCE_YOFF, get_crtc_fence_y_offset(crtc)); + I915_WRITE(DPFC_FENCE_YOFF, params->crtc.fence_y_offset); /* enable it... */ I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); @@ -230,19 +226,16 @@ static void intel_fbc_recompress(struct drm_i915_private *dev_priv) POSTING_READ(MSG_FBC_REND_STATE); } -static void ilk_fbc_activate(struct intel_crtc *crtc) +static void ilk_fbc_activate(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; u32 dpfc_ctl; int threshold = dev_priv->fbc.threshold; - unsigned int y_offset; dev_priv->fbc.active = true; - dpfc_ctl = DPFC_CTL_PLANE(crtc->plane); - if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) + dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane); + if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) threshold++; switch (threshold) { @@ -259,18 +252,17 @@ static void ilk_fbc_activate(struct intel_crtc *crtc) } dpfc_ctl |= DPFC_CTL_FENCE_EN; if (IS_GEN5(dev_priv)) - dpfc_ctl |= obj->fence_reg; + dpfc_ctl |= params->fb.fence_reg; - y_offset = get_crtc_fence_y_offset(crtc); - I915_WRITE(ILK_DPFC_FENCE_YOFF, y_offset); - I915_WRITE(ILK_FBC_RT_BASE, i915_gem_obj_ggtt_offset(obj) | ILK_FBC_RT_VALID); + I915_WRITE(ILK_DPFC_FENCE_YOFF, params->crtc.fence_y_offset); + I915_WRITE(ILK_FBC_RT_BASE, params->fb.ggtt_offset | ILK_FBC_RT_VALID); /* enable it... */ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); if (IS_GEN6(dev_priv)) { I915_WRITE(SNB_DPFC_CTL_SA, - SNB_CPU_FENCE_ENABLE | obj->fence_reg); - I915_WRITE(DPFC_CPU_FENCE_OFFSET, y_offset); + SNB_CPU_FENCE_ENABLE | params->fb.fence_reg); + I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset); } intel_fbc_recompress(dev_priv); @@ -295,11 +287,9 @@ static bool ilk_fbc_is_active(struct drm_i915_private *dev_priv) return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; } -static void gen7_fbc_activate(struct intel_crtc *crtc) +static void gen7_fbc_activate(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc_reg_params *params = &dev_priv->fbc.params; u32 dpfc_ctl; int threshold = dev_priv->fbc.threshold; @@ -307,9 +297,9 @@ static void gen7_fbc_activate(struct intel_crtc *crtc) dpfc_ctl = 0; if (IS_IVYBRIDGE(dev_priv)) - dpfc_ctl |= IVB_DPFC_CTL_PLANE(crtc->plane); + dpfc_ctl |= IVB_DPFC_CTL_PLANE(params->crtc.plane); - if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) + if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) threshold++; switch (threshold) { @@ -337,16 +327,16 @@ static void gen7_fbc_activate(struct intel_crtc *crtc) ILK_FBCQ_DIS); } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - I915_WRITE(CHICKEN_PIPESL_1(crtc->pipe), - I915_READ(CHICKEN_PIPESL_1(crtc->pipe)) | + I915_WRITE(CHICKEN_PIPESL_1(params->crtc.pipe), + I915_READ(CHICKEN_PIPESL_1(params->crtc.pipe)) | HSW_FBCQ_DIS); } I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); I915_WRITE(SNB_DPFC_CTL_SA, - SNB_CPU_FENCE_ENABLE | obj->fence_reg); - I915_WRITE(DPFC_CPU_FENCE_OFFSET, get_crtc_fence_y_offset(crtc)); + SNB_CPU_FENCE_ENABLE | params->fb.fence_reg); + I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset); intel_fbc_recompress(dev_priv); } @@ -364,17 +354,6 @@ bool intel_fbc_is_active(struct drm_i915_private *dev_priv) return dev_priv->fbc.active; } -static void intel_fbc_activate(const struct drm_framebuffer *fb) -{ - struct drm_i915_private *dev_priv = fb->dev->dev_private; - struct intel_crtc *crtc = dev_priv->fbc.crtc; - - dev_priv->fbc.activate(crtc); - - dev_priv->fbc.fb_id = fb->base.id; - dev_priv->fbc.y = crtc->base.y; -} - static void intel_fbc_work_fn(struct work_struct *__work) { struct drm_i915_private *dev_priv = @@ -424,7 +403,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) } if (crtc->base.primary->fb == work->fb) - intel_fbc_activate(work->fb); + dev_priv->fbc.activate(dev_priv); work->scheduled = false; @@ -855,6 +834,42 @@ static bool intel_fbc_can_enable(struct intel_crtc *crtc) return true; } +static void intel_fbc_get_reg_params(struct intel_crtc *crtc, + struct intel_fbc_reg_params *params) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_framebuffer *fb = crtc->base.primary->fb; + struct drm_i915_gem_object *obj = intel_fb_obj(fb); + + /* Since all our fields are integer types, use memset here so the + * comparison function can rely on memcmp because the padding will be + * zero. */ + memset(params, 0, sizeof(*params)); + + params->crtc.pipe = crtc->pipe; + params->crtc.plane = crtc->plane; + params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); + + params->fb.id = fb->base.id; + params->fb.pixel_format = fb->pixel_format; + params->fb.stride = fb->pitches[0]; + params->fb.fence_reg = obj->fence_reg; + + params->cfb_size = intel_fbc_calculate_cfb_size(crtc, fb); + + /* FIXME: We lack the proper locking here, so only run this on the + * platforms that need. */ + if (dev_priv->fbc.activate == ilk_fbc_activate) + params->fb.ggtt_offset = i915_gem_obj_ggtt_offset(obj); +} + +static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, + struct intel_fbc_reg_params *params2) +{ + /* We can use this since intel_fbc_get_reg_params() does a memset. */ + return memcmp(params1, params2, sizeof(*params1)) == 0; +} + /** * __intel_fbc_update - activate/deactivate FBC as needed, unlocked * @crtc: the CRTC that triggered the update @@ -865,6 +880,7 @@ static bool intel_fbc_can_enable(struct intel_crtc *crtc) static void __intel_fbc_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc_reg_params old_params; WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); @@ -879,15 +895,16 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (!intel_fbc_can_activate(crtc)) goto out_disable; + old_params = dev_priv->fbc.params; + intel_fbc_get_reg_params(crtc, &dev_priv->fbc.params); + /* If the scanout has not changed, don't modify the FBC settings. * Note that we make the fundamental assumption that the fb->obj * cannot be unpinned (and have its GTT offset and fence revoked) * without first being decoupled from the scanout and FBC disabled. */ - if (dev_priv->fbc.crtc == crtc && - dev_priv->fbc.fb_id == crtc->base.primary->fb->base.id && - dev_priv->fbc.y == crtc->base.y && - dev_priv->fbc.active) + if (dev_priv->fbc.active && + intel_fbc_reg_params_equal(&old_params, &dev_priv->fbc.params)) return; if (intel_fbc_is_active(dev_priv)) { -- GitLab From ab34a7e8b55a1cbe3f0ad1bb2d7d24568ce4d018 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 11 Jan 2016 17:44:36 -0200 Subject: [PATCH 0527/5324] drm/i915/fbc: replace frequent dev_priv->fbc.x with fbc->x We say "dev_priv->fbc.something" way too many times in our code while we could be saying just "fbc->something" with a previous declaration of fbc. This has been bothering me for a while but I didn't want to patch it since I wanted to fix the real problems first. But as I add more code I keep thinking about it, especially since it makes the code easier to read and it can make us fit 80 columns easier, so let's just do the change now. While at it, also rename from i915_fbc to intel_fbc because the whole FBC code uses intel_fbc. v2: Rebase after the work_fn changes. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453406763-10400-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/intel_fbc.c | 237 +++++++++++++++++-------------- 2 files changed, 132 insertions(+), 109 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 99bac7e0121e..7b44e988fb4e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -900,7 +900,7 @@ enum fb_op_origin { ORIGIN_DIRTYFB, }; -struct i915_fbc { +struct intel_fbc { /* This is always the inner lock when overlapping with struct_mutex and * it's the outer lock when overlapping with stolen_lock. */ struct mutex lock; @@ -1781,7 +1781,7 @@ struct drm_i915_private { u32 pipestat_irq_mask[I915_MAX_PIPES]; struct i915_hotplug hotplug; - struct i915_fbc fbc; + struct intel_fbc fbc; struct i915_drrs drrs; struct intel_opregion opregion; struct intel_vbt_data vbt; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 14200d29383b..a0bdcef6bf27 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -358,17 +358,18 @@ static void intel_fbc_work_fn(struct work_struct *__work) { struct drm_i915_private *dev_priv = container_of(__work, struct drm_i915_private, fbc.work.work); - struct intel_fbc_work *work = &dev_priv->fbc.work; - struct intel_crtc *crtc = dev_priv->fbc.crtc; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_work *work = &fbc->work; + struct intel_crtc *crtc = fbc->crtc; struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; if (drm_crtc_vblank_get(&crtc->base)) { DRM_ERROR("vblank not available for FBC on pipe %c\n", pipe_name(crtc->pipe)); - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); work->scheduled = false; - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); return; } @@ -390,7 +391,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank, msecs_to_jiffies(50)); - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); /* Were we cancelled? */ if (!work->scheduled) @@ -398,32 +399,35 @@ static void intel_fbc_work_fn(struct work_struct *__work) /* Were we delayed again while this function was sleeping? */ if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) { - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); goto retry; } if (crtc->base.primary->fb == work->fb) - dev_priv->fbc.activate(dev_priv); + fbc->activate(dev_priv); work->scheduled = false; out: - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); drm_crtc_vblank_put(&crtc->base); } static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - dev_priv->fbc.work.scheduled = false; + struct intel_fbc *fbc = &dev_priv->fbc; + + WARN_ON(!mutex_is_locked(&fbc->lock)); + fbc->work.scheduled = false; } static void intel_fbc_schedule_activation(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_fbc_work *work = &dev_priv->fbc.work; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_work *work = &fbc->work; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + WARN_ON(!mutex_is_locked(&fbc->lock)); if (drm_crtc_vblank_get(&crtc->base)) { DRM_ERROR("vblank not available for FBC on pipe %c\n", @@ -445,12 +449,14 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + struct intel_fbc *fbc = &dev_priv->fbc; + + WARN_ON(!mutex_is_locked(&fbc->lock)); intel_fbc_cancel_work(dev_priv); - if (dev_priv->fbc.active) - dev_priv->fbc.deactivate(dev_priv); + if (fbc->active) + fbc->deactivate(dev_priv); } /* @@ -462,23 +468,26 @@ static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) void intel_fbc_deactivate(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); - if (dev_priv->fbc.crtc == crtc) + mutex_lock(&fbc->lock); + if (fbc->crtc == crtc) __intel_fbc_deactivate(dev_priv); - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } static void set_no_fbc_reason(struct drm_i915_private *dev_priv, const char *reason) { - if (dev_priv->fbc.no_fbc_reason == reason) + struct intel_fbc *fbc = &dev_priv->fbc; + + if (fbc->no_fbc_reason == reason) return; - dev_priv->fbc.no_fbc_reason = reason; + fbc->no_fbc_reason = reason; DRM_DEBUG_KMS("Disabling FBC: %s\n", reason); } @@ -568,16 +577,17 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv, static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; struct drm_framebuffer *fb = crtc->base.primary->state->fb; struct drm_mm_node *uninitialized_var(compressed_llb); int size, fb_cpp, ret; - WARN_ON(drm_mm_node_allocated(&dev_priv->fbc.compressed_fb)); + WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb)); size = intel_fbc_calculate_cfb_size(crtc, fb); fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0); - ret = find_compression_threshold(dev_priv, &dev_priv->fbc.compressed_fb, + ret = find_compression_threshold(dev_priv, &fbc->compressed_fb, size, fb_cpp); if (!ret) goto err_llb; @@ -586,12 +596,12 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) } - dev_priv->fbc.threshold = ret; + fbc->threshold = ret; if (INTEL_INFO(dev_priv)->gen >= 5) - I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start); + I915_WRITE(ILK_DPFC_CB_BASE, fbc->compressed_fb.start); else if (IS_GM45(dev_priv)) { - I915_WRITE(DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start); + I915_WRITE(DPFC_CB_BASE, fbc->compressed_fb.start); } else { compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL); if (!compressed_llb) @@ -602,23 +612,22 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) if (ret) goto err_fb; - dev_priv->fbc.compressed_llb = compressed_llb; + fbc->compressed_llb = compressed_llb; I915_WRITE(FBC_CFB_BASE, - dev_priv->mm.stolen_base + dev_priv->fbc.compressed_fb.start); + dev_priv->mm.stolen_base + fbc->compressed_fb.start); I915_WRITE(FBC_LL_BASE, dev_priv->mm.stolen_base + compressed_llb->start); } DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n", - dev_priv->fbc.compressed_fb.size, - dev_priv->fbc.threshold); + fbc->compressed_fb.size, fbc->threshold); return 0; err_fb: kfree(compressed_llb); - i915_gem_stolen_remove_node(dev_priv, &dev_priv->fbc.compressed_fb); + i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb); err_llb: pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); return -ENOSPC; @@ -626,25 +635,27 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) { - if (drm_mm_node_allocated(&dev_priv->fbc.compressed_fb)) - i915_gem_stolen_remove_node(dev_priv, - &dev_priv->fbc.compressed_fb); - - if (dev_priv->fbc.compressed_llb) { - i915_gem_stolen_remove_node(dev_priv, - dev_priv->fbc.compressed_llb); - kfree(dev_priv->fbc.compressed_llb); + struct intel_fbc *fbc = &dev_priv->fbc; + + if (drm_mm_node_allocated(&fbc->compressed_fb)) + i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb); + + if (fbc->compressed_llb) { + i915_gem_stolen_remove_node(dev_priv, fbc->compressed_llb); + kfree(fbc->compressed_llb); } } void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); __intel_fbc_cleanup_cfb(dev_priv); - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } static bool stride_is_valid(struct drm_i915_private *dev_priv, @@ -723,6 +734,7 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) static bool intel_fbc_can_activate(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; struct drm_plane *primary; struct drm_framebuffer *fb; struct intel_plane_state *plane_state; @@ -799,7 +811,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) * a lot of tracking just for a specific case. If we conclude it's an * important case, we can implement it later. */ if (intel_fbc_calculate_cfb_size(crtc, fb) > - dev_priv->fbc.compressed_fb.size * dev_priv->fbc.threshold) { + fbc->compressed_fb.size * fbc->threshold) { set_no_fbc_reason(dev_priv, "CFB requirements changed"); return false; } @@ -880,31 +892,32 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, static void __intel_fbc_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_reg_params old_params; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); + WARN_ON(!mutex_is_locked(&fbc->lock)); if (!multiple_pipes_ok(dev_priv)) { set_no_fbc_reason(dev_priv, "more than one pipe active"); goto out_disable; } - if (!dev_priv->fbc.enabled || dev_priv->fbc.crtc != crtc) + if (!fbc->enabled || fbc->crtc != crtc) return; if (!intel_fbc_can_activate(crtc)) goto out_disable; - old_params = dev_priv->fbc.params; - intel_fbc_get_reg_params(crtc, &dev_priv->fbc.params); + old_params = fbc->params; + intel_fbc_get_reg_params(crtc, &fbc->params); /* If the scanout has not changed, don't modify the FBC settings. * Note that we make the fundamental assumption that the fb->obj * cannot be unpinned (and have its GTT offset and fence revoked) * without first being decoupled from the scanout and FBC disabled. */ - if (dev_priv->fbc.active && - intel_fbc_reg_params_equal(&old_params, &dev_priv->fbc.params)) + if (fbc->active && + intel_fbc_reg_params_equal(&old_params, &fbc->params)) return; if (intel_fbc_is_active(dev_priv)) { @@ -936,7 +949,7 @@ static void __intel_fbc_update(struct intel_crtc *crtc) } intel_fbc_schedule_activation(crtc); - dev_priv->fbc.no_fbc_reason = "FBC enabled (not necessarily active)"; + fbc->no_fbc_reason = "FBC enabled (not necessarily active)"; return; out_disable: @@ -956,19 +969,21 @@ static void __intel_fbc_update(struct intel_crtc *crtc) void intel_fbc_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); __intel_fbc_update(crtc); - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } void intel_fbc_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin) { + struct intel_fbc *fbc = &dev_priv->fbc; unsigned int fbc_bits; if (!fbc_supported(dev_priv)) @@ -977,44 +992,46 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, if (origin == ORIGIN_GTT) return; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); - if (dev_priv->fbc.enabled) - fbc_bits = INTEL_FRONTBUFFER_PRIMARY(dev_priv->fbc.crtc->pipe); + if (fbc->enabled) + fbc_bits = INTEL_FRONTBUFFER_PRIMARY(fbc->crtc->pipe); else - fbc_bits = dev_priv->fbc.possible_framebuffer_bits; + fbc_bits = fbc->possible_framebuffer_bits; - dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits); + fbc->busy_bits |= (fbc_bits & frontbuffer_bits); - if (dev_priv->fbc.busy_bits) + if (fbc->busy_bits) __intel_fbc_deactivate(dev_priv); - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } void intel_fbc_flush(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin) { + struct intel_fbc *fbc = &dev_priv->fbc; + if (!fbc_supported(dev_priv)) return; if (origin == ORIGIN_GTT) return; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); - dev_priv->fbc.busy_bits &= ~frontbuffer_bits; + fbc->busy_bits &= ~frontbuffer_bits; - if (!dev_priv->fbc.busy_bits && dev_priv->fbc.enabled) { - if (origin != ORIGIN_FLIP && dev_priv->fbc.active) { + if (!fbc->busy_bits && fbc->enabled) { + if (origin != ORIGIN_FLIP && fbc->active) { intel_fbc_recompress(dev_priv); } else { __intel_fbc_deactivate(dev_priv); - __intel_fbc_update(dev_priv->fbc.crtc); + __intel_fbc_update(fbc->crtc); } } - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } /** @@ -1027,19 +1044,20 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, void intel_fbc_enable(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); + mutex_lock(&fbc->lock); - if (dev_priv->fbc.enabled) { - WARN_ON(dev_priv->fbc.crtc == crtc); + if (fbc->enabled) { + WARN_ON(fbc->crtc == crtc); goto out; } - WARN_ON(dev_priv->fbc.active); - WARN_ON(dev_priv->fbc.crtc != NULL); + WARN_ON(fbc->active); + WARN_ON(fbc->crtc != NULL); if (!intel_fbc_can_enable(crtc)) goto out; @@ -1050,12 +1068,12 @@ void intel_fbc_enable(struct intel_crtc *crtc) } DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe)); - dev_priv->fbc.no_fbc_reason = "FBC enabled but not active yet\n"; + fbc->no_fbc_reason = "FBC enabled but not active yet\n"; - dev_priv->fbc.enabled = true; - dev_priv->fbc.crtc = crtc; + fbc->enabled = true; + fbc->crtc = crtc; out: - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } /** @@ -1067,19 +1085,20 @@ void intel_fbc_enable(struct intel_crtc *crtc) */ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) { - struct intel_crtc *crtc = dev_priv->fbc.crtc; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_crtc *crtc = fbc->crtc; - WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock)); - WARN_ON(!dev_priv->fbc.enabled); - WARN_ON(dev_priv->fbc.active); + WARN_ON(!mutex_is_locked(&fbc->lock)); + WARN_ON(!fbc->enabled); + WARN_ON(fbc->active); assert_pipe_disabled(dev_priv, crtc->pipe); DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe)); __intel_fbc_cleanup_cfb(dev_priv); - dev_priv->fbc.enabled = false; - dev_priv->fbc.crtc = NULL; + fbc->enabled = false; + fbc->crtc = NULL; } /** @@ -1091,17 +1110,18 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) void intel_fbc_disable_crtc(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); - if (dev_priv->fbc.crtc == crtc) { - WARN_ON(!dev_priv->fbc.enabled); - WARN_ON(dev_priv->fbc.active); + mutex_lock(&fbc->lock); + if (fbc->crtc == crtc) { + WARN_ON(!fbc->enabled); + WARN_ON(fbc->active); __intel_fbc_disable(dev_priv); } - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } /** @@ -1112,13 +1132,15 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc) */ void intel_fbc_disable(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + if (!fbc_supported(dev_priv)) return; - mutex_lock(&dev_priv->fbc.lock); - if (dev_priv->fbc.enabled) + mutex_lock(&fbc->lock); + if (fbc->enabled) __intel_fbc_disable(dev_priv); - mutex_unlock(&dev_priv->fbc.lock); + mutex_unlock(&fbc->lock); } /** @@ -1129,21 +1151,22 @@ void intel_fbc_disable(struct drm_i915_private *dev_priv) */ void intel_fbc_init(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; enum pipe pipe; - INIT_WORK(&dev_priv->fbc.work.work, intel_fbc_work_fn); - mutex_init(&dev_priv->fbc.lock); - dev_priv->fbc.enabled = false; - dev_priv->fbc.active = false; - dev_priv->fbc.work.scheduled = false; + INIT_WORK(&fbc->work.work, intel_fbc_work_fn); + mutex_init(&fbc->lock); + fbc->enabled = false; + fbc->active = false; + fbc->work.scheduled = false; if (!HAS_FBC(dev_priv)) { - dev_priv->fbc.no_fbc_reason = "unsupported by this chipset"; + fbc->no_fbc_reason = "unsupported by this chipset"; return; } for_each_pipe(dev_priv, pipe) { - dev_priv->fbc.possible_framebuffer_bits |= + fbc->possible_framebuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(pipe); if (fbc_on_pipe_a_only(dev_priv)) @@ -1151,21 +1174,21 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) } if (INTEL_INFO(dev_priv)->gen >= 7) { - dev_priv->fbc.is_active = ilk_fbc_is_active; - dev_priv->fbc.activate = gen7_fbc_activate; - dev_priv->fbc.deactivate = ilk_fbc_deactivate; + fbc->is_active = ilk_fbc_is_active; + fbc->activate = gen7_fbc_activate; + fbc->deactivate = ilk_fbc_deactivate; } else if (INTEL_INFO(dev_priv)->gen >= 5) { - dev_priv->fbc.is_active = ilk_fbc_is_active; - dev_priv->fbc.activate = ilk_fbc_activate; - dev_priv->fbc.deactivate = ilk_fbc_deactivate; + fbc->is_active = ilk_fbc_is_active; + fbc->activate = ilk_fbc_activate; + fbc->deactivate = ilk_fbc_deactivate; } else if (IS_GM45(dev_priv)) { - dev_priv->fbc.is_active = g4x_fbc_is_active; - dev_priv->fbc.activate = g4x_fbc_activate; - dev_priv->fbc.deactivate = g4x_fbc_deactivate; + fbc->is_active = g4x_fbc_is_active; + fbc->activate = g4x_fbc_activate; + fbc->deactivate = g4x_fbc_deactivate; } else { - dev_priv->fbc.is_active = i8xx_fbc_is_active; - dev_priv->fbc.activate = i8xx_fbc_activate; - dev_priv->fbc.deactivate = i8xx_fbc_deactivate; + fbc->is_active = i8xx_fbc_is_active; + fbc->activate = i8xx_fbc_activate; + fbc->deactivate = i8xx_fbc_deactivate; /* This value was pulled out of someone's hat */ I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); @@ -1174,6 +1197,6 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) /* We still don't have any sort of hardware state readout for FBC, so * deactivate it in case the BIOS activated it to make sure software * matches the hardware state. */ - if (dev_priv->fbc.is_active(dev_priv)) - dev_priv->fbc.deactivate(dev_priv); + if (fbc->is_active(dev_priv)) + fbc->deactivate(dev_priv); } -- GitLab From 0dd81544c9dd1ba867e7cd2e18d719437b3c97c1 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:39 -0200 Subject: [PATCH 0528/5324] drm/i915/fbc: don't use the frontbuffer tracking subsystem for flips Before this patch, page flips would call intel_frontbuffer_flip() and intel_frontbuffer_flip_complete(), which would call intel_fbc_flush(), which would call intel_fbc_update(). The problem is that drawing operations also trigger intel_fbc_flush() calls, so it's not guaranteed that we have the CRTC and FB locks grabbed when intel_fbc_flush() happens, since the call trace may come from the rendering path. We're trying to make the FBC code grab the appropriate CRTC/FB locks, so split the drawing and the flipping logic in order to achieve that in later patches. So now the frontbuffer tracking code is just going to be used for frontbuffer drawing, and intel_fbc_update() is going to be used directly for actual page flips. As a note, we don't need to call intel_fbc_flip() during the two places where we call intel_frontbuffer_flip() since in one of them we already have an intel_fbc_update() call, and in the other we have the planes disabled. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-7-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_fbc.c | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 304fc9637026..d56b9347543b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10912,6 +10912,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) mutex_unlock(&dev->struct_mutex); intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit); + intel_fbc_update(crtc); drm_framebuffer_unreference(work->old_fb); BUG_ON(atomic_read(&crtc->unpin_work_count) == 0); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a0bdcef6bf27..8c765f699061 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -989,7 +989,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, if (!fbc_supported(dev_priv)) return; - if (origin == ORIGIN_GTT) + if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) return; mutex_lock(&fbc->lock); @@ -1015,7 +1015,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (!fbc_supported(dev_priv)) return; - if (origin == ORIGIN_GTT) + if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) return; mutex_lock(&fbc->lock); @@ -1023,12 +1023,10 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, fbc->busy_bits &= ~frontbuffer_bits; if (!fbc->busy_bits && fbc->enabled) { - if (origin != ORIGIN_FLIP && fbc->active) { + if (fbc->active) intel_fbc_recompress(dev_priv); - } else { - __intel_fbc_deactivate(dev_priv); + else __intel_fbc_update(fbc->crtc); - } } mutex_unlock(&fbc->lock); -- GitLab From 261fe99ac26bde82f44163b0d7f67b9ccf562359 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:40 -0200 Subject: [PATCH 0529/5324] drm/i915/fbc: don't flush for operations on the wrong frontbuffer If frontbuffer_bits doesn't match the current frontbuffer, there's no reason to recompress or update FBC. There was a plan to make the FBC test suite catch this type of problem, but it never got implemented due to being low priority. While at it, also implement Ville's suggestion and use plane->frontbuffer_bit instead of INTEL_FRONTBUFFER_PRIMARY. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-8-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 8c765f699061..a24cb8dc74e2 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -979,12 +979,19 @@ void intel_fbc_update(struct intel_crtc *crtc) mutex_unlock(&fbc->lock); } +static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc) +{ + if (fbc->enabled) + return to_intel_plane(fbc->crtc->base.primary)->frontbuffer_bit; + else + return fbc->possible_framebuffer_bits; +} + void intel_fbc_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin) { struct intel_fbc *fbc = &dev_priv->fbc; - unsigned int fbc_bits; if (!fbc_supported(dev_priv)) return; @@ -994,12 +1001,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, mutex_lock(&fbc->lock); - if (fbc->enabled) - fbc_bits = INTEL_FRONTBUFFER_PRIMARY(fbc->crtc->pipe); - else - fbc_bits = fbc->possible_framebuffer_bits; - - fbc->busy_bits |= (fbc_bits & frontbuffer_bits); + fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; if (fbc->busy_bits) __intel_fbc_deactivate(dev_priv); @@ -1022,7 +1024,8 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, fbc->busy_bits &= ~frontbuffer_bits; - if (!fbc->busy_bits && fbc->enabled) { + if (!fbc->busy_bits && fbc->enabled && + (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { if (fbc->active) intel_fbc_recompress(dev_priv); else -- GitLab From fcf38d134983c1dbc3f426f6e562d93514fde1f1 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 21 Jan 2016 18:07:17 -0200 Subject: [PATCH 0530/5324] drm/i915/fbc: unconditionally update FBC during atomic commits We unconditionally disable/update FBC even during the page flip IOCTLs, and an unconditional disable/update at every atomic commit touching the primary plane shouldn't impact PC state residency noticeably. Besides, the code that checks for rotation is a good hint that we may be forgetting something else, so let's leave all the decisions to intel_fbc.c, making the code much safer. Once we have the code to properly make FBC enable/update decisions based on atomic states, with proper locking, then we'll be able to evaluate whether it will be worth trying to optimize the cases where a disable isn't needed. v2: Upstream moved and now our patch needs to remove dev_priv. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453406837-10511-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d56b9347543b..25af60605e8f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11834,7 +11834,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_plane *plane = plane_state->plane; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_plane_state *old_plane_state = to_intel_plane_state(plane->state); int idx = intel_crtc->base.base.id, ret; @@ -11902,6 +11901,8 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, case DRM_PLANE_TYPE_PRIMARY: intel_crtc->atomic.pre_disable_primary = turn_off; intel_crtc->atomic.post_enable_primary = turn_on; + intel_crtc->atomic.disable_fbc = true; + intel_crtc->atomic.update_fbc = true; if (turn_off) { /* @@ -11913,27 +11914,8 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, * disable. */ intel_crtc->atomic.disable_ips = true; - - intel_crtc->atomic.disable_fbc = true; } - /* - * FBC does not work on some platforms for rotated - * planes, so disable it when rotation is not 0 and - * update it when rotation is set back to 0. - * - * FIXME: This is redundant with the fbc update done in - * the primary plane enable function except that that - * one is done too late. We eventually need to unify - * this. - */ - - if (visible && - INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) && - dev_priv->fbc.crtc == intel_crtc && - plane_state->rotation != BIT(DRM_ROTATE_0)) - intel_crtc->atomic.disable_fbc = true; - /* * BDW signals flip done immediately if the plane * is disabled, even if the plane enable is already @@ -11942,7 +11924,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, if (turn_on && IS_BROADWELL(dev)) intel_crtc->atomic.wait_vblank = true; - intel_crtc->atomic.update_fbc |= visible || mode_changed; break; case DRM_PLANE_TYPE_CURSOR: break; -- GitLab From aaf78d276ba00ad0ab9e51283b3e3e8db8433ead Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:42 -0200 Subject: [PATCH 0531/5324] drm/i915/fbc: introduce struct intel_fbc_state_cache Per the new atomic locking rules, we need to cache the CRTC, plane and FB state structures we use so we can access them later without needing more locks. So do this. Notice that there are some pieces of the FBC code that look at things that are only computed during the modeset, so we can't just can't precompute whether FBC can be activated during the update_state_cache stage. We may be able to do this later. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-10-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 23 ++++++ drivers/gpu/drm/i915/intel_fbc.c | 133 +++++++++++++++++-------------- 2 files changed, 98 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7b44e988fb4e..0df991371001 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -917,6 +917,29 @@ struct intel_fbc { bool enabled; bool active; + struct intel_fbc_state_cache { + struct { + unsigned int mode_flags; + uint32_t hsw_bdw_pixel_rate; + } crtc; + + struct { + unsigned int rotation; + int src_w; + int src_h; + bool visible; + } plane; + + struct { + u64 ilk_ggtt_offset; + uint32_t id; + uint32_t pixel_format; + unsigned int stride; + int fence_reg; + unsigned int tiling_mode; + } fb; + } state_cache; + struct intel_fbc_reg_params { struct { enum pipe pipe; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a24cb8dc74e2..49d445a1854e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -74,19 +74,17 @@ static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc) * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value * we wrote to PIPESRC. */ -static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc, +static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache, int *width, int *height) { - struct intel_plane_state *plane_state = - to_intel_plane_state(crtc->base.primary->state); int w, h; - if (intel_rotation_90_or_270(plane_state->base.rotation)) { - w = drm_rect_height(&plane_state->src) >> 16; - h = drm_rect_width(&plane_state->src) >> 16; + if (intel_rotation_90_or_270(cache->plane.rotation)) { + w = cache->plane.src_h; + h = cache->plane.src_w; } else { - w = drm_rect_width(&plane_state->src) >> 16; - h = drm_rect_height(&plane_state->src) >> 16; + w = cache->plane.src_w; + h = cache->plane.src_h; } if (width) @@ -95,18 +93,17 @@ static void intel_fbc_get_plane_source_size(struct intel_crtc *crtc, *height = h; } -static int intel_fbc_calculate_cfb_size(struct intel_crtc *crtc, - struct drm_framebuffer *fb) +static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv, + struct intel_fbc_state_cache *cache) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; int lines; - intel_fbc_get_plane_source_size(crtc, NULL, &lines); + intel_fbc_get_plane_source_size(cache, NULL, &lines); if (INTEL_INFO(dev_priv)->gen >= 7) lines = min(lines, 2048); /* Hardware needs the full buffer stride, not just the active area. */ - return lines * fb->pitches[0]; + return lines * cache->fb.stride; } static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) @@ -578,14 +575,13 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - struct drm_framebuffer *fb = crtc->base.primary->state->fb; struct drm_mm_node *uninitialized_var(compressed_llb); int size, fb_cpp, ret; WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb)); - size = intel_fbc_calculate_cfb_size(crtc, fb); - fb_cpp = drm_format_plane_cpp(fb->pixel_format, 0); + size = intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache); + fb_cpp = drm_format_plane_cpp(fbc->state_cache.fb.pixel_format, 0); ret = find_compression_threshold(dev_priv, &fbc->compressed_fb, size, fb_cpp); @@ -679,19 +675,17 @@ static bool stride_is_valid(struct drm_i915_private *dev_priv, return true; } -static bool pixel_format_is_valid(struct drm_framebuffer *fb) +static bool pixel_format_is_valid(struct drm_i915_private *dev_priv, + uint32_t pixel_format) { - struct drm_device *dev = fb->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - switch (fb->pixel_format) { + switch (pixel_format) { case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XBGR8888: return true; case DRM_FORMAT_XRGB1555: case DRM_FORMAT_RGB565: /* 16bpp not supported on gen2 */ - if (IS_GEN2(dev)) + if (IS_GEN2(dev_priv)) return false; /* WaFbcOnly1to1Ratio:ctg */ if (IS_G4X(dev_priv)) @@ -711,6 +705,7 @@ static bool pixel_format_is_valid(struct drm_framebuffer *fb) static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; unsigned int effective_w, effective_h, max_w, max_h; if (INTEL_INFO(dev_priv)->gen >= 8 || IS_HASWELL(dev_priv)) { @@ -724,41 +719,64 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) max_h = 1536; } - intel_fbc_get_plane_source_size(crtc, &effective_w, &effective_h); + intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w, + &effective_h); effective_w += crtc->adjusted_x; effective_h += crtc->adjusted_y; return effective_w <= max_w && effective_h <= max_h; } -static bool intel_fbc_can_activate(struct intel_crtc *crtc) +static void intel_fbc_update_state_cache(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - struct drm_plane *primary; - struct drm_framebuffer *fb; - struct intel_plane_state *plane_state; + struct intel_fbc_state_cache *cache = &fbc->state_cache; + struct intel_crtc_state *crtc_state = crtc->config; + struct intel_plane_state *plane_state = + to_intel_plane_state(crtc->base.primary->state); + struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj; - const struct drm_display_mode *adjusted_mode; - if (!intel_crtc_active(&crtc->base)) { - set_no_fbc_reason(dev_priv, "CRTC not active"); - return false; - } + cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags; + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + cache->crtc.hsw_bdw_pixel_rate = + ilk_pipe_pixel_rate(crtc_state); + + cache->plane.rotation = plane_state->base.rotation; + cache->plane.src_w = drm_rect_width(&plane_state->src) >> 16; + cache->plane.src_h = drm_rect_height(&plane_state->src) >> 16; + cache->plane.visible = plane_state->visible; + + if (!cache->plane.visible) + return; - primary = crtc->base.primary; - fb = primary->fb; obj = intel_fb_obj(fb); - adjusted_mode = &crtc->config->base.adjusted_mode; - plane_state = to_intel_plane_state(primary->state); - if (!plane_state->visible) { + /* FIXME: We lack the proper locking here, so only run this on the + * platforms that need. */ + if (dev_priv->fbc.activate == ilk_fbc_activate) + cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); + cache->fb.id = fb->base.id; + cache->fb.pixel_format = fb->pixel_format; + cache->fb.stride = fb->pitches[0]; + cache->fb.fence_reg = obj->fence_reg; + cache->fb.tiling_mode = obj->tiling_mode; +} + +static bool intel_fbc_can_activate(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_state_cache *cache = &fbc->state_cache; + + if (!cache->plane.visible) { set_no_fbc_reason(dev_priv, "primary plane not visible"); return false; } - if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || - (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { + if ((cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) || + (cache->crtc.mode_flags & DRM_MODE_FLAG_DBLSCAN)) { set_no_fbc_reason(dev_priv, "incompatible mode"); return false; } @@ -771,31 +789,30 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) /* The use of a CPU fence is mandatory in order to detect writes * by the CPU to the scanout and trigger updates to the FBC. */ - if (obj->tiling_mode != I915_TILING_X || - obj->fence_reg == I915_FENCE_REG_NONE) { + if (cache->fb.tiling_mode != I915_TILING_X || + cache->fb.fence_reg == I915_FENCE_REG_NONE) { set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && - plane_state->base.rotation != BIT(DRM_ROTATE_0)) { + cache->plane.rotation != BIT(DRM_ROTATE_0)) { set_no_fbc_reason(dev_priv, "rotation unsupported"); return false; } - if (!stride_is_valid(dev_priv, fb->pitches[0])) { + if (!stride_is_valid(dev_priv, cache->fb.stride)) { set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); return false; } - if (!pixel_format_is_valid(fb)) { + if (!pixel_format_is_valid(dev_priv, cache->fb.pixel_format)) { set_no_fbc_reason(dev_priv, "pixel format is invalid"); return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) && - ilk_pipe_pixel_rate(crtc->config) >= - dev_priv->cdclk_freq * 95 / 100) { + cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) { set_no_fbc_reason(dev_priv, "pixel rate is too big"); return false; } @@ -810,7 +827,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) * we didn't get any invalidate/deactivate calls, but this would require * a lot of tracking just for a specific case. If we conclude it's an * important case, we can implement it later. */ - if (intel_fbc_calculate_cfb_size(crtc, fb) > + if (intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) > fbc->compressed_fb.size * fbc->threshold) { set_no_fbc_reason(dev_priv, "CFB requirements changed"); return false; @@ -850,8 +867,8 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, struct intel_fbc_reg_params *params) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct drm_framebuffer *fb = crtc->base.primary->fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_state_cache *cache = &fbc->state_cache; /* Since all our fields are integer types, use memset here so the * comparison function can rely on memcmp because the padding will be @@ -862,17 +879,14 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->crtc.plane = crtc->plane; params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); - params->fb.id = fb->base.id; - params->fb.pixel_format = fb->pixel_format; - params->fb.stride = fb->pitches[0]; - params->fb.fence_reg = obj->fence_reg; + params->fb.id = cache->fb.id; + params->fb.pixel_format = cache->fb.pixel_format; + params->fb.stride = cache->fb.stride; + params->fb.fence_reg = cache->fb.fence_reg; - params->cfb_size = intel_fbc_calculate_cfb_size(crtc, fb); + params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache); - /* FIXME: We lack the proper locking here, so only run this on the - * platforms that need. */ - if (dev_priv->fbc.activate == ilk_fbc_activate) - params->fb.ggtt_offset = i915_gem_obj_ggtt_offset(obj); + params->fb.ggtt_offset = cache->fb.ilk_ggtt_offset; } static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, @@ -905,6 +919,8 @@ static void __intel_fbc_update(struct intel_crtc *crtc) if (!fbc->enabled || fbc->crtc != crtc) return; + intel_fbc_update_state_cache(crtc); + if (!intel_fbc_can_activate(crtc)) goto out_disable; @@ -1063,6 +1079,7 @@ void intel_fbc_enable(struct intel_crtc *crtc) if (!intel_fbc_can_enable(crtc)) goto out; + intel_fbc_update_state_cache(crtc); if (intel_fbc_alloc_cfb(crtc)) { set_no_fbc_reason(dev_priv, "not enough stolen memory"); goto out; -- GitLab From 212890cfcd25b148665585ac3b2ecb65bad0d538 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:43 -0200 Subject: [PATCH 0532/5324] drm/i915/fbc: split intel_fbc_update into pre and post update So now pre_update will be responsible for unconditionally deactivating FBC and updating the state cache, while post_update will be responsible for checking if it can be enabled, then enabling it. This is one more step into proper locking. Notice that intel_fbc_flush now calls post_update directly. The FBC flush can only happen for drawing operations - since we explicitly ignore the flips -, so the FBC state is not expected to have changed at this point. With this we can just run post_update, which will make sure we won't deactivate+reactivate FBC as would be the case now if we called pre_update + post_update. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-11-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 77 +++++++++++--------------------- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 49d445a1854e..61523cd95ac1 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -896,24 +896,16 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, return memcmp(params1, params2, sizeof(*params1)) == 0; } -/** - * __intel_fbc_update - activate/deactivate FBC as needed, unlocked - * @crtc: the CRTC that triggered the update - * - * This function completely reevaluates the status of FBC, then activates, - * deactivates or maintains it on the same state. - */ -static void __intel_fbc_update(struct intel_crtc *crtc) +static void intel_fbc_pre_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - struct intel_fbc_reg_params old_params; WARN_ON(!mutex_is_locked(&fbc->lock)); if (!multiple_pipes_ok(dev_priv)) { set_no_fbc_reason(dev_priv, "more than one pipe active"); - goto out_disable; + goto deactivate; } if (!fbc->enabled || fbc->crtc != crtc) @@ -921,8 +913,25 @@ static void __intel_fbc_update(struct intel_crtc *crtc) intel_fbc_update_state_cache(crtc); - if (!intel_fbc_can_activate(crtc)) - goto out_disable; +deactivate: + __intel_fbc_deactivate(dev_priv); +} + +static void intel_fbc_post_update(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; + struct intel_fbc_reg_params old_params; + + WARN_ON(!mutex_is_locked(&fbc->lock)); + + if (!fbc->enabled || fbc->crtc != crtc) + return; + + if (!intel_fbc_can_activate(crtc)) { + WARN_ON(fbc->active); + return; + } old_params = fbc->params; intel_fbc_get_reg_params(crtc, &fbc->params); @@ -936,44 +945,9 @@ static void __intel_fbc_update(struct intel_crtc *crtc) intel_fbc_reg_params_equal(&old_params, &fbc->params)) return; - if (intel_fbc_is_active(dev_priv)) { - /* We update FBC along two paths, after changing fb/crtc - * configuration (modeswitching) and after page-flipping - * finishes. For the latter, we know that not only did - * we disable the FBC at the start of the page-flip - * sequence, but also more than one vblank has passed. - * - * For the former case of modeswitching, it is possible - * to switch between two FBC valid configurations - * instantaneously so we do need to disable the FBC - * before we can modify its control registers. We also - * have to wait for the next vblank for that to take - * effect. However, since we delay enabling FBC we can - * assume that a vblank has passed since disabling and - * that we can safely alter the registers in the deferred - * callback. - * - * In the scenario that we go from a valid to invalid - * and then back to valid FBC configuration we have - * no strict enforcement that a vblank occurred since - * disabling the FBC. However, along all current pipe - * disabling paths we do need to wait for a vblank at - * some point. And we wait before enabling FBC anyway. - */ - DRM_DEBUG_KMS("deactivating FBC for update\n"); - __intel_fbc_deactivate(dev_priv); - } - + __intel_fbc_deactivate(dev_priv); intel_fbc_schedule_activation(crtc); - fbc->no_fbc_reason = "FBC enabled (not necessarily active)"; - return; - -out_disable: - /* Multiple disables should be harmless */ - if (intel_fbc_is_active(dev_priv)) { - DRM_DEBUG_KMS("unsupported config, deactivating FBC\n"); - __intel_fbc_deactivate(dev_priv); - } + fbc->no_fbc_reason = "FBC enabled (active or scheduled)"; } /* @@ -991,7 +965,8 @@ void intel_fbc_update(struct intel_crtc *crtc) return; mutex_lock(&fbc->lock); - __intel_fbc_update(crtc); + intel_fbc_pre_update(crtc); + intel_fbc_post_update(crtc); mutex_unlock(&fbc->lock); } @@ -1045,7 +1020,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (fbc->active) intel_fbc_recompress(dev_priv); else - __intel_fbc_update(fbc->crtc); + intel_fbc_post_update(fbc->crtc); } mutex_unlock(&fbc->lock); -- GitLab From 1eb52238a5f5b6a3f497b47e6da39ccfebe6b878 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:44 -0200 Subject: [PATCH 0533/5324] drm/i915/fbc: fix the FBC state checking code We'll now call intel_fbc_pre_update instead of intel_fbc_deactivate during atomic commits. This will continue to guarantee that we deactivate FBC and it will also update the state checking structures at the correct time. Then, later, at the point where we were calling intel_fbc_update, we'll only need to call intel_fbc_post_update. Also add the proper warnings in case we don't have the appropriate locks. Daniel mentioned the warnings will have to be removed for async commits, but let's keep them here while we can. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-12-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 11 +++++----- drivers/gpu/drm/i915/intel_drv.h | 8 ++++--- drivers/gpu/drm/i915/intel_fbc.c | 33 +++++++++++++++------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 25af60605e8f..edd0999f61b4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4799,7 +4799,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) intel_update_watermarks(&crtc->base); if (atomic->update_fbc) - intel_fbc_update(crtc); + intel_fbc_post_update(crtc); if (atomic->post_enable_primary) intel_post_enable_primary(&crtc->base); @@ -4815,8 +4815,8 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); - if (atomic->disable_fbc) - intel_fbc_deactivate(crtc); + if (atomic->update_fbc) + intel_fbc_pre_update(crtc); if (crtc->atomic.disable_ips) hsw_disable_ips(crtc); @@ -10912,7 +10912,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) mutex_unlock(&dev->struct_mutex); intel_frontbuffer_flip_complete(dev, to_intel_plane(primary)->frontbuffer_bit); - intel_fbc_update(crtc); + intel_fbc_post_update(crtc); drm_framebuffer_unreference(work->old_fb); BUG_ON(atomic_read(&crtc->unpin_work_count) == 0); @@ -11712,7 +11712,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, to_intel_plane(primary)->frontbuffer_bit); mutex_unlock(&dev->struct_mutex); - intel_fbc_deactivate(intel_crtc); + intel_fbc_pre_update(intel_crtc); intel_frontbuffer_flip_prepare(dev, to_intel_plane(primary)->frontbuffer_bit); @@ -11901,7 +11901,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, case DRM_PLANE_TYPE_PRIMARY: intel_crtc->atomic.pre_disable_primary = turn_off; intel_crtc->atomic.post_enable_primary = turn_on; - intel_crtc->atomic.disable_fbc = true; intel_crtc->atomic.update_fbc = true; if (turn_off) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f620023ed134..b461d7307541 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -542,16 +542,17 @@ struct intel_mmio_flip { */ struct intel_crtc_atomic_commit { /* Sleepable operations to perform before commit */ - bool disable_fbc; bool disable_ips; bool pre_disable_primary; /* Sleepable operations to perform after commit */ unsigned fb_bits; bool wait_vblank; - bool update_fbc; bool post_enable_primary; unsigned update_sprite_watermarks; + + /* Sleepable operations to perform before and after commit */ + bool update_fbc; }; struct intel_crtc { @@ -1330,7 +1331,8 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) /* intel_fbc.c */ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_deactivate(struct intel_crtc *crtc); -void intel_fbc_update(struct intel_crtc *crtc); +void intel_fbc_pre_update(struct intel_crtc *crtc); +void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); void intel_fbc_disable(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 61523cd95ac1..1c26d65cdd33 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -510,6 +510,7 @@ static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) if (INTEL_INFO(dev_priv)->gen > 4) return true; + /* FIXME: we don't have the appropriate state locks to do this here. */ for_each_pipe(dev_priv, pipe) { crtc = dev_priv->pipe_to_crtc_mapping[pipe]; @@ -732,12 +733,16 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc) struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; - struct intel_crtc_state *crtc_state = crtc->config; + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = to_intel_plane_state(crtc->base.primary->state); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj; + WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); + WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex)); + cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags; if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) cache->crtc.hsw_bdw_pixel_rate = @@ -896,12 +901,15 @@ static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, return memcmp(params1, params2, sizeof(*params1)) == 0; } -static void intel_fbc_pre_update(struct intel_crtc *crtc) +void intel_fbc_pre_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - WARN_ON(!mutex_is_locked(&fbc->lock)); + if (!fbc_supported(dev_priv)) + return; + + mutex_lock(&fbc->lock); if (!multiple_pipes_ok(dev_priv)) { set_no_fbc_reason(dev_priv, "more than one pipe active"); @@ -909,15 +917,17 @@ static void intel_fbc_pre_update(struct intel_crtc *crtc) } if (!fbc->enabled || fbc->crtc != crtc) - return; + goto unlock; intel_fbc_update_state_cache(crtc); deactivate: __intel_fbc_deactivate(dev_priv); +unlock: + mutex_unlock(&fbc->lock); } -static void intel_fbc_post_update(struct intel_crtc *crtc) +static void __intel_fbc_post_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; @@ -950,13 +960,7 @@ static void intel_fbc_post_update(struct intel_crtc *crtc) fbc->no_fbc_reason = "FBC enabled (active or scheduled)"; } -/* - * intel_fbc_update - activate/deactivate FBC as needed - * @crtc: the CRTC that triggered the update - * - * This function reevaluates the overall state and activates or deactivates FBC. - */ -void intel_fbc_update(struct intel_crtc *crtc) +void intel_fbc_post_update(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; @@ -965,8 +969,7 @@ void intel_fbc_update(struct intel_crtc *crtc) return; mutex_lock(&fbc->lock); - intel_fbc_pre_update(crtc); - intel_fbc_post_update(crtc); + __intel_fbc_post_update(crtc); mutex_unlock(&fbc->lock); } @@ -1020,7 +1023,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (fbc->active) intel_fbc_recompress(dev_priv); else - intel_fbc_post_update(fbc->crtc); + __intel_fbc_post_update(fbc->crtc); } mutex_unlock(&fbc->lock); -- GitLab From 60eb2cc71c7b581bcd499739f021750c2eb1c8b5 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:45 -0200 Subject: [PATCH 0534/5324] drm/i915/fbc: unexport intel_fbc_deactivate With the addition and usage of intel_fbc_pre_update, intel_fbc_deactivate is not used anymore outside intel_fbc.c, so kill the exported function and rename __intel_fbc_deactivate. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-13-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_drv.h | 1 - drivers/gpu/drm/i915/intel_fbc.c | 28 ++++------------------------ 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b461d7307541..ee07bf9209fa 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1330,7 +1330,6 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) /* intel_fbc.c */ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); -void intel_fbc_deactivate(struct intel_crtc *crtc); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 1c26d65cdd33..74e6bcdc62b4 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -444,7 +444,7 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) schedule_work(&work->work); } -static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) +static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; @@ -456,26 +456,6 @@ static void __intel_fbc_deactivate(struct drm_i915_private *dev_priv) fbc->deactivate(dev_priv); } -/* - * intel_fbc_deactivate - deactivate FBC if it's associated with crtc - * @crtc: the CRTC - * - * This function deactivates FBC if it's associated with the provided CRTC. - */ -void intel_fbc_deactivate(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - struct intel_fbc *fbc = &dev_priv->fbc; - - if (!fbc_supported(dev_priv)) - return; - - mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) - __intel_fbc_deactivate(dev_priv); - mutex_unlock(&fbc->lock); -} - static void set_no_fbc_reason(struct drm_i915_private *dev_priv, const char *reason) { @@ -922,7 +902,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) intel_fbc_update_state_cache(crtc); deactivate: - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); unlock: mutex_unlock(&fbc->lock); } @@ -955,7 +935,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc) intel_fbc_reg_params_equal(&old_params, &fbc->params)) return; - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); intel_fbc_schedule_activation(crtc); fbc->no_fbc_reason = "FBC enabled (active or scheduled)"; } @@ -998,7 +978,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; if (fbc->busy_bits) - __intel_fbc_deactivate(dev_priv); + intel_fbc_deactivate(dev_priv); mutex_unlock(&fbc->lock); } -- GitLab From c937ab3e584ea66433ce743a42c752e31f3acdbe Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:46 -0200 Subject: [PATCH 0535/5324] drm/i915/fbc: rename the FBC disable functions Instead of: - intel_fbc_disable_crtc(crtc) - intel_fbc_disable(dev_priv) we now have: - intel_fbc_disable(crtc) - intel_fbc_global_disable(dev_priv) This is because all the other functions that take a CRTC are called - intel_fbc_something(crtc) Instead of: - intel_fbc_something_crtc(crtc) And I also hope that the word "global" is going to help make it more explicit that "global" is the unusual case, not the opposite. Reported-by: Daniel Vetter Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-14-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_suspend.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_fbc.c | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a2aa09ce3202..6c6bedf3eb37 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -92,7 +92,7 @@ static void i915_restore_display(struct drm_device *dev) } /* only restore FBC info on the platform that supports FBC*/ - intel_fbc_disable(dev_priv); + intel_fbc_global_disable(dev_priv); /* restore FBC interval */ if (HAS_FBC(dev) && INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index edd0999f61b4..60108e69982e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5124,7 +5124,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void haswell_crtc_disable(struct drm_crtc *crtc) @@ -5176,7 +5176,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) true); } - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void i9xx_pfit_enable(struct intel_crtc *crtc) @@ -6352,7 +6352,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (!IS_GEN2(dev)) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - intel_fbc_disable_crtc(intel_crtc); + intel_fbc_disable(intel_crtc); } static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) @@ -16041,7 +16041,7 @@ void intel_modeset_cleanup(struct drm_device *dev) intel_unregister_dsm_handler(); - intel_fbc_disable(dev_priv); + intel_fbc_global_disable(dev_priv); /* flush any delayed tasks or pending work */ flush_scheduled_work(); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ee07bf9209fa..06b04acba3b3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1334,8 +1334,8 @@ void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); -void intel_fbc_disable(struct drm_i915_private *dev_priv); -void intel_fbc_disable_crtc(struct intel_crtc *crtc); +void intel_fbc_disable(struct intel_crtc *crtc); +void intel_fbc_global_disable(struct drm_i915_private *dev_priv); void intel_fbc_invalidate(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits, enum fb_op_origin origin); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 74e6bcdc62b4..04783432d6f7 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1078,12 +1078,12 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) } /** - * intel_fbc_disable_crtc - disable FBC if it's associated with crtc + * intel_fbc_disable - disable FBC if it's associated with crtc * @crtc: the CRTC * * This function disables FBC if it's associated with the provided CRTC. */ -void intel_fbc_disable_crtc(struct intel_crtc *crtc) +void intel_fbc_disable(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; @@ -1101,12 +1101,12 @@ void intel_fbc_disable_crtc(struct intel_crtc *crtc) } /** - * intel_fbc_disable - globally disable FBC + * intel_fbc_global_disable - globally disable FBC * @dev_priv: i915 device instance * * This function disables FBC regardless of which CRTC is associated with it. */ -void intel_fbc_disable(struct drm_i915_private *dev_priv) +void intel_fbc_global_disable(struct drm_i915_private *dev_priv) { struct intel_fbc *fbc = &dev_priv->fbc; -- GitLab From 65c7600f07d4eb372c078dcd7138a9276f5705eb Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:47 -0200 Subject: [PATCH 0536/5324] drm/i915/fbc: make sure we cancel the work function at fbc_disable Just to be sure nothing will survive a module unload. We need to do this after the unlock in order to make sure the function won't get stuck trying to grab the lock we already own while we wait for it to finish. Reported-by: Reported-by: Daniel Vetter Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-15-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 04783432d6f7..35d265092bc1 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1098,6 +1098,8 @@ void intel_fbc_disable(struct intel_crtc *crtc) __intel_fbc_disable(dev_priv); } mutex_unlock(&fbc->lock); + + cancel_work_sync(&fbc->work.work); } /** @@ -1117,6 +1119,8 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv) if (fbc->enabled) __intel_fbc_disable(dev_priv); mutex_unlock(&fbc->lock); + + cancel_work_sync(&fbc->work.work); } /** -- GitLab From 010cf73d4648df35585c0c326123b04ab79e4573 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:48 -0200 Subject: [PATCH 0537/5324] drm/i915/fbc: rewrite the multiple_pipes_ok() code for locking Older FBC platforms have this restriction where FBC can't be enabled if multiple pipes are enabled. In the current code, we disable FBC before the second pipe becomes visible. One of the problems with this code is that the current multiple_pipes_ok() implementation just iterates through all CRTCs looking at their states, but it doesn't make sure that the state locks are grabbed. It also can't just grab the locks for every CRTC since this would kill one of the biggest advantages of atomic modesetting. After the recent FBC changes, we now have the appropriate locks for the given CRTC, so we can just try to maintain the state of each CRTC and update it once intel_fbc_pre_update is called. As a last note, I don't have gen 2/3 machines to test this code. My current plan is to enable FBC on just the newer platforms, so this patch is just an attempt to get the gen 2/3 code at least looking sane, so if one day someone decide to fix FBC on these platforms, they may have less work to do. Not-tested-by: Paulo Zanoni (only on HSW+) Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-16-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 2 + drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_fbc.c | 55 +++++++++++++++++++++------- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0df991371001..e4da97c6ff9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -907,6 +907,7 @@ struct intel_fbc { unsigned threshold; unsigned int possible_framebuffer_bits; unsigned int busy_bits; + unsigned int visible_pipes_mask; struct intel_crtc *crtc; struct drm_mm_node compressed_fb; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 60108e69982e..136668a4e684 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15912,6 +15912,8 @@ intel_modeset_setup_hw_state(struct drm_device *dev) modeset_put_power_domains(dev_priv, put_domains); } intel_display_set_init_power(dev_priv, false); + + intel_fbc_init_pipe_state(dev_priv); } void intel_display_resume(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 06b04acba3b3..00a835990bdb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1333,6 +1333,7 @@ bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); void intel_fbc_init(struct drm_i915_private *dev_priv); +void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); void intel_fbc_enable(struct intel_crtc *crtc); void intel_fbc_disable(struct intel_crtc *crtc); void intel_fbc_global_disable(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 35d265092bc1..c2ef400a9599 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -56,6 +56,11 @@ static inline bool fbc_on_plane_a_only(struct drm_i915_private *dev_priv) return INTEL_INFO(dev_priv)->gen < 4; } +static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) +{ + return INTEL_INFO(dev_priv)->gen <= 3; +} + /* * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's @@ -481,25 +486,25 @@ static bool crtc_can_fbc(struct intel_crtc *crtc) return true; } -static bool multiple_pipes_ok(struct drm_i915_private *dev_priv) +static bool multiple_pipes_ok(struct intel_crtc *crtc) { - enum pipe pipe; - int n_pipes = 0; - struct drm_crtc *crtc; + struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_plane *primary = crtc->base.primary; + struct intel_fbc *fbc = &dev_priv->fbc; + enum pipe pipe = crtc->pipe; - if (INTEL_INFO(dev_priv)->gen > 4) + /* Don't even bother tracking anything we don't need. */ + if (!no_fbc_on_multiple_pipes(dev_priv)) return true; - /* FIXME: we don't have the appropriate state locks to do this here. */ - for_each_pipe(dev_priv, pipe) { - crtc = dev_priv->pipe_to_crtc_mapping[pipe]; + WARN_ON(!drm_modeset_is_locked(&primary->mutex)); - if (intel_crtc_active(crtc) && - to_intel_plane_state(crtc->primary->state)->visible) - n_pipes++; - } + if (to_intel_plane_state(primary->state)->visible) + fbc->visible_pipes_mask |= (1 << pipe); + else + fbc->visible_pipes_mask &= ~(1 << pipe); - return (n_pipes < 2); + return (fbc->visible_pipes_mask & ~(1 << pipe)) != 0; } static int find_compression_threshold(struct drm_i915_private *dev_priv, @@ -891,7 +896,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) mutex_lock(&fbc->lock); - if (!multiple_pipes_ok(dev_priv)) { + if (!multiple_pipes_ok(crtc)) { set_no_fbc_reason(dev_priv, "more than one pipe active"); goto deactivate; } @@ -1123,6 +1128,28 @@ void intel_fbc_global_disable(struct drm_i915_private *dev_priv) cancel_work_sync(&fbc->work.work); } +/** + * intel_fbc_init_pipe_state - initialize FBC's CRTC visibility tracking + * @dev_priv: i915 device instance + * + * The FBC code needs to track CRTC visibility since the older platforms can't + * have FBC enabled while multiple pipes are used. This function does the + * initial setup at driver load to make sure FBC is matching the real hardware. + */ +void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) +{ + struct intel_crtc *crtc; + + /* Don't even bother tracking anything if we don't need. */ + if (!no_fbc_on_multiple_pipes(dev_priv)) + return; + + for_each_intel_crtc(dev_priv->dev, crtc) + if (intel_crtc_active(&crtc->base) && + to_intel_plane_state(crtc->base.primary->state)->visible) + dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); +} + /** * intel_fbc_init - Initialize FBC * @dev_priv: the i915 device -- GitLab From dd8b3bdbdb748e1ae6a7025bf113ab08b09952bb Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:49 -0200 Subject: [PATCH 0538/5324] drm/i915: simplify struct drm_device access at intel_atomic_check() We already have a dev variable, there's no need to access state->dev. Also, I plan to add another dev_priv user here, so declare one for the current user. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-17-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 136668a4e684..189367cea993 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13327,6 +13327,7 @@ static void calc_watermark_data(struct drm_atomic_state *state) static int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) { + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; @@ -13369,7 +13370,7 @@ static int intel_atomic_check(struct drm_device *dev, return ret; if (i915.fastboot && - intel_pipe_config_compare(state->dev, + intel_pipe_config_compare(dev, to_intel_crtc_state(crtc->state), pipe_config, true)) { crtc_state->mode_changed = false; @@ -13395,9 +13396,9 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; } else - intel_state->cdclk = to_i915(state->dev)->cdclk_freq; + intel_state->cdclk = dev_priv->cdclk_freq; - ret = drm_atomic_helper_check_planes(state->dev, state); + ret = drm_atomic_helper_check_planes(dev, state); if (ret) return ret; -- GitLab From f51be2e0e3c54b7146152b39c1b5f569a005ab79 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:50 -0200 Subject: [PATCH 0539/5324] drm/i915/fbc: choose the new FBC CRTC during atomic check This opens the possibility of implementing nicer schemes to choose the CRTC, such as checking the amount of stolen memory available, or choosing the best pipe on platforms that don't die FBC to pipe or plane A. This code was written for another refactor that I ended up discarding, so I don't actually need it, but I figured this patch would be an improvement on its own so I kept it on the series. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-18-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_fbc.c | 77 +++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 189367cea993..cd57613176fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13402,6 +13402,7 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; + intel_fbc_choose_crtc(dev_priv, state); calc_watermark_data(state); return 0; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 00a835990bdb..93ba14a3bb76 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -492,6 +492,8 @@ struct intel_crtc_state { bool ips_enabled; + bool enable_fbc; + bool double_wide; bool dp_encoder_is_mst; @@ -1329,6 +1331,8 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) #endif /* intel_fbc.c */ +void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, + struct drm_atomic_state *state); bool intel_fbc_is_active(struct drm_i915_private *dev_priv); void intel_fbc_pre_update(struct intel_crtc *crtc); void intel_fbc_post_update(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index c2ef400a9599..5bf7f844d827 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -826,7 +826,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) return true; } -static bool intel_fbc_can_enable(struct intel_crtc *crtc) +static bool intel_fbc_can_choose(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -1014,12 +1014,77 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, mutex_unlock(&fbc->lock); } +/** + * intel_fbc_choose_crtc - select a CRTC to enable FBC on + * @dev_priv: i915 device instance + * @state: the atomic state structure + * + * This function looks at the proposed state for CRTCs and planes, then chooses + * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to + * true. + * + * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe + * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc. + */ +void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, + struct drm_atomic_state *state) +{ + struct intel_fbc *fbc = &dev_priv->fbc; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_plane *plane; + struct drm_plane_state *plane_state; + bool fbc_crtc_present = false; + int i, j; + + mutex_lock(&fbc->lock); + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + if (fbc->crtc == to_intel_crtc(crtc)) { + fbc_crtc_present = true; + break; + } + } + /* This atomic commit doesn't involve the CRTC currently tied to FBC. */ + if (!fbc_crtc_present && fbc->crtc != NULL) + goto out; + + /* Simply choose the first CRTC that is compatible and has a visible + * plane. We could go for fancier schemes such as checking the plane + * size, but this would just affect the few platforms that don't tie FBC + * to pipe or plane A. */ + for_each_plane_in_state(state, plane, plane_state, i) { + struct intel_plane_state *intel_plane_state = + to_intel_plane_state(plane_state); + + if (!intel_plane_state->visible) + continue; + + for_each_crtc_in_state(state, crtc, crtc_state, j) { + struct intel_crtc_state *intel_crtc_state = + to_intel_crtc_state(crtc_state); + + if (plane_state->crtc != crtc) + continue; + + if (!intel_fbc_can_choose(to_intel_crtc(crtc))) + break; + + intel_crtc_state->enable_fbc = true; + goto out; + } + } + +out: + mutex_unlock(&fbc->lock); +} + /** * intel_fbc_enable: tries to enable FBC on the CRTC * @crtc: the CRTC * - * This function checks if it's possible to enable FBC on the following CRTC, - * then enables it. Notice that it doesn't activate FBC. + * This function checks if the given CRTC was chosen for FBC, then enables it if + * possible. Notice that it doesn't activate FBC. */ void intel_fbc_enable(struct intel_crtc *crtc) { @@ -1036,12 +1101,12 @@ void intel_fbc_enable(struct intel_crtc *crtc) goto out; } + if (!crtc->config->enable_fbc) + goto out; + WARN_ON(fbc->active); WARN_ON(fbc->crtc != NULL); - if (!intel_fbc_can_enable(crtc)) - goto out; - intel_fbc_update_state_cache(crtc); if (intel_fbc_alloc_cfb(crtc)) { set_no_fbc_reason(dev_priv, "not enough stolen memory"); -- GitLab From 58f9c0bc557588fbe3f54c521dd8c6f20598e64e Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:51 -0200 Subject: [PATCH 0540/5324] drm/i915/fbc: move intel_fbc_{enable, disable} call one level up Instead of duplicating the calls for every platform, let's just put them in the correct places inside intel_atomic_commit. This will also make it easier for us to move the enable call in order to support fasbtoot. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-19-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 15 +++------------ drivers/gpu/drm/i915/intel_fbc.c | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cd57613176fc..69ab07758c7e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4927,8 +4927,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->has_pch_encoder) intel_wait_for_vblank(dev, pipe); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - - intel_fbc_enable(intel_crtc); } /* IPS only exists on ULT machines and is tied to pipe A. */ @@ -5041,8 +5039,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_wait_for_vblank(dev, hsw_workaround_pipe); intel_wait_for_vblank(dev, hsw_workaround_pipe); } - - intel_fbc_enable(intel_crtc); } static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force) @@ -5123,8 +5119,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) } intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); - - intel_fbc_disable(intel_crtc); } static void haswell_crtc_disable(struct drm_crtc *crtc) @@ -5175,8 +5169,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A, true); } - - intel_fbc_disable(intel_crtc); } static void i9xx_pfit_enable(struct intel_crtc *crtc) @@ -6287,8 +6279,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); - - intel_fbc_enable(intel_crtc); } static void i9xx_pfit_disable(struct intel_crtc *crtc) @@ -6351,8 +6341,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (!IS_GEN2(dev)) intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); - - intel_fbc_disable(intel_crtc); } static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) @@ -6376,6 +6364,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc) dev_priv->display.crtc_disable(crtc); intel_crtc->active = false; + intel_fbc_disable(intel_crtc); intel_update_watermarks(crtc); intel_disable_shared_dpll(intel_crtc); @@ -13529,6 +13518,7 @@ static int intel_atomic_commit(struct drm_device *dev, intel_crtc_disable_planes(crtc, crtc_state->plane_mask); dev_priv->display.crtc_disable(crtc); intel_crtc->active = false; + intel_fbc_disable(intel_crtc); intel_disable_shared_dpll(intel_crtc); /* @@ -13568,6 +13558,7 @@ static int intel_atomic_commit(struct drm_device *dev, if (modeset && crtc->state->active) { update_scanline_offset(to_intel_crtc(crtc)); dev_priv->display.crtc_enable(crtc); + intel_fbc_enable(intel_crtc); } if (update_pipe) { diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 5bf7f844d827..60644dd49581 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1137,7 +1137,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) WARN_ON(!mutex_is_locked(&fbc->lock)); WARN_ON(!fbc->enabled); WARN_ON(fbc->active); - assert_pipe_disabled(dev_priv, crtc->pipe); + WARN_ON(crtc->active); DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe)); -- GitLab From 49227c4ae3d2c8ccb6c71bfb5dfac80ad8c73021 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:52 -0200 Subject: [PATCH 0541/5324] drm/i915/fbc: make FBC work with fastboot Move intel_fbc_enable to a place where it is called regardless of the "modeset" variable, and make sure intel_fbc_enable can be called multiple times without intel_fbc_disable being called. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-20-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 4 +++- drivers/gpu/drm/i915/intel_fbc.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 69ab07758c7e..a832ff1c8e32 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13558,7 +13558,6 @@ static int intel_atomic_commit(struct drm_device *dev, if (modeset && crtc->state->active) { update_scanline_offset(to_intel_crtc(crtc)); dev_priv->display.crtc_enable(crtc); - intel_fbc_enable(intel_crtc); } if (update_pipe) { @@ -13571,6 +13570,9 @@ static int intel_atomic_commit(struct drm_device *dev, if (!modeset) intel_pre_plane_update(intel_crtc); + if (crtc->state->active && intel_crtc->atomic.update_fbc) + intel_fbc_enable(intel_crtc); + if (crtc->state->active && (crtc->state->planes_changed || update_pipe)) drm_atomic_helper_commit_planes_on_crtc(crtc_state); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 60644dd49581..912b953ceb50 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -1084,7 +1084,9 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, * @crtc: the CRTC * * This function checks if the given CRTC was chosen for FBC, then enables it if - * possible. Notice that it doesn't activate FBC. + * possible. Notice that it doesn't activate FBC. It is valid to call + * intel_fbc_enable multiple times for the same pipe without an + * intel_fbc_disable in the middle, as long as it is deactivated. */ void intel_fbc_enable(struct intel_crtc *crtc) { @@ -1097,7 +1099,11 @@ void intel_fbc_enable(struct intel_crtc *crtc) mutex_lock(&fbc->lock); if (fbc->enabled) { - WARN_ON(fbc->crtc == crtc); + WARN_ON(fbc->crtc == NULL); + if (fbc->crtc == crtc) { + WARN_ON(!crtc->config->enable_fbc); + WARN_ON(fbc->active); + } goto out; } -- GitLab From 5bc40472dea771260dc6d6946fd09c1ac3c9cd93 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:53 -0200 Subject: [PATCH 0542/5324] drm/i915/fbc: don't try to deactivate FBC if it's not enabled During FBC invalidation, don't call intel_fbc_deactivate if it's not enabled. This doesn't fix any bug, but helps making the interface saner. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-21-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 912b953ceb50..2ed9be2f9f23 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -982,7 +982,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv, fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; - if (fbc->busy_bits) + if (fbc->enabled && fbc->busy_bits) intel_fbc_deactivate(dev_priv); mutex_unlock(&fbc->lock); -- GitLab From 913a3a6acae3c90e07f96c849c2a071b27a0fc1d Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:54 -0200 Subject: [PATCH 0543/5324] drm/i915/fbc: don't print no_fbc_reason to dmesg Our dmesg messages started being misleading after we converted to the enable+activate model: we always print "Disabling FBC", even when we're just deactivating it. So, for example, when I boot my machine and do "dmesg | grep -i fbc", I see: [drm:intel_fbc_enable] Enabling FBC on pipe A [drm:set_no_fbc_reason] Disabling FBC: framebuffer not tiled or fenced but then, if I read the debugfs file, I will see: $ sudo cat i915_fbc_status FBC enabled Compressing: yes so we can conclude that dmesg is misleading, since FBC is actually enabled. What happened is that we deactivated FBC due to fbcon not being tiled, but when we silently reactivated it when the display manager started. We don't print activation messages since there may be way too many of these operations per second during normal desktop usage. One possible solution would be to change set_no_fbc_reason to correctly differentiate between disable and deactivation, but we removed support from printing activation/deactivation messages in the past because they were too frequent. So instead of doing this, let's just not print anything on dmesg, and leave the debugfs file if the user needs to investigate something. We already print when we enable and disable FBC anyway on a given pipe, so this should already help triaging bugs. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-22-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 43 ++++++++++++-------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 2ed9be2f9f23..cdd99cfe211e 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -461,18 +461,6 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) fbc->deactivate(dev_priv); } -static void set_no_fbc_reason(struct drm_i915_private *dev_priv, - const char *reason) -{ - struct intel_fbc *fbc = &dev_priv->fbc; - - if (fbc->no_fbc_reason == reason) - return; - - fbc->no_fbc_reason = reason; - DRM_DEBUG_KMS("Disabling FBC: %s\n", reason); -} - static bool crtc_can_fbc(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -761,18 +749,18 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) struct intel_fbc_state_cache *cache = &fbc->state_cache; if (!cache->plane.visible) { - set_no_fbc_reason(dev_priv, "primary plane not visible"); + fbc->no_fbc_reason = "primary plane not visible"; return false; } if ((cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) || (cache->crtc.mode_flags & DRM_MODE_FLAG_DBLSCAN)) { - set_no_fbc_reason(dev_priv, "incompatible mode"); + fbc->no_fbc_reason = "incompatible mode"; return false; } if (!intel_fbc_hw_tracking_covers_screen(crtc)) { - set_no_fbc_reason(dev_priv, "mode too large for compression"); + fbc->no_fbc_reason = "mode too large for compression"; return false; } @@ -781,29 +769,29 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) */ if (cache->fb.tiling_mode != I915_TILING_X || cache->fb.fence_reg == I915_FENCE_REG_NONE) { - set_no_fbc_reason(dev_priv, "framebuffer not tiled or fenced"); + fbc->no_fbc_reason = "framebuffer not tiled or fenced"; return false; } if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && cache->plane.rotation != BIT(DRM_ROTATE_0)) { - set_no_fbc_reason(dev_priv, "rotation unsupported"); + fbc->no_fbc_reason = "rotation unsupported"; return false; } if (!stride_is_valid(dev_priv, cache->fb.stride)) { - set_no_fbc_reason(dev_priv, "framebuffer stride not supported"); + fbc->no_fbc_reason = "framebuffer stride not supported"; return false; } if (!pixel_format_is_valid(dev_priv, cache->fb.pixel_format)) { - set_no_fbc_reason(dev_priv, "pixel format is invalid"); + fbc->no_fbc_reason = "pixel format is invalid"; return false; } /* WaFbcExceedCdClockThreshold:hsw,bdw */ if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) && cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) { - set_no_fbc_reason(dev_priv, "pixel rate is too big"); + fbc->no_fbc_reason = "pixel rate is too big"; return false; } @@ -819,7 +807,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) * important case, we can implement it later. */ if (intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) > fbc->compressed_fb.size * fbc->threshold) { - set_no_fbc_reason(dev_priv, "CFB requirements changed"); + fbc->no_fbc_reason = "CFB requirements changed"; return false; } @@ -829,24 +817,25 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) static bool intel_fbc_can_choose(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_fbc *fbc = &dev_priv->fbc; if (intel_vgpu_active(dev_priv->dev)) { - set_no_fbc_reason(dev_priv, "VGPU is active"); + fbc->no_fbc_reason = "VGPU is active"; return false; } if (i915.enable_fbc < 0) { - set_no_fbc_reason(dev_priv, "disabled per chip default"); + fbc->no_fbc_reason = "disabled per chip default"; return false; } if (!i915.enable_fbc) { - set_no_fbc_reason(dev_priv, "disabled per module param"); + fbc->no_fbc_reason = "disabled per module param"; return false; } if (!crtc_can_fbc(crtc)) { - set_no_fbc_reason(dev_priv, "no enabled pipes can have FBC"); + fbc->no_fbc_reason = "no enabled pipes can have FBC"; return false; } @@ -897,7 +886,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc) mutex_lock(&fbc->lock); if (!multiple_pipes_ok(crtc)) { - set_no_fbc_reason(dev_priv, "more than one pipe active"); + fbc->no_fbc_reason = "more than one pipe active"; goto deactivate; } @@ -1115,7 +1104,7 @@ void intel_fbc_enable(struct intel_crtc *crtc) intel_fbc_update_state_cache(crtc); if (intel_fbc_alloc_cfb(crtc)) { - set_no_fbc_reason(dev_priv, "not enough stolen memory"); + fbc->no_fbc_reason = "not enough stolen memory"; goto out; } -- GitLab From b20d27526cb0e8dd2b7db3b45ec96aecfc02d610 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:55 -0200 Subject: [PATCH 0544/5324] drm/i915/fbc: don't store the fb_id on reg_params We don't actually use fb_id anywhere. We already compare all parameters that matter to the hardware: pixel format, stride, fence_reg and ggtt_offset. The ID shouldn't make a difference. Besides, we already update the FBC data at every modeset/flip, so this can't change behind our backs. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-23-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_fbc.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e4da97c6ff9c..52cd35230f45 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -933,7 +933,6 @@ struct intel_fbc { struct { u64 ilk_ggtt_offset; - uint32_t id; uint32_t pixel_format; unsigned int stride; int fence_reg; @@ -950,7 +949,6 @@ struct intel_fbc { struct { u64 ggtt_offset; - uint32_t id; uint32_t pixel_format; unsigned int stride; int fence_reg; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index cdd99cfe211e..35e92bc6b9cf 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -735,7 +735,6 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc) * platforms that need. */ if (dev_priv->fbc.activate == ilk_fbc_activate) cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); - cache->fb.id = fb->base.id; cache->fb.pixel_format = fb->pixel_format; cache->fb.stride = fb->pitches[0]; cache->fb.fence_reg = obj->fence_reg; @@ -858,7 +857,6 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc, params->crtc.plane = crtc->plane; params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); - params->fb.id = cache->fb.id; params->fb.pixel_format = cache->fb.pixel_format; params->fb.stride = cache->fb.stride; params->fb.fence_reg = cache->fb.fence_reg; -- GitLab From e8216e502acaad129210c3c8b30cb4ab41e70239 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 19 Jan 2016 11:35:56 -0200 Subject: [PATCH 0545/5324] drm/i915/fbc: call intel_fbc_pre_update earlier during page flips Make sure we do the pre_update - which also deactivates FBC - before we actually schedule the page flip, just to make sure we don't flip to the new FB with FBC still activated for the previous FB. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-24-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a832ff1c8e32..a66220ad2e4a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11617,6 +11617,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; update_state_fb(crtc->primary); + intel_fbc_pre_update(intel_crtc); work->pending_flip_obj = obj; @@ -11701,7 +11702,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, to_intel_plane(primary)->frontbuffer_bit); mutex_unlock(&dev->struct_mutex); - intel_fbc_pre_update(intel_crtc); intel_frontbuffer_flip_prepare(dev, to_intel_plane(primary)->frontbuffer_bit); -- GitLab From 9b42281f9ddafe459e0b0d91ddf1939fbf84d832 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 18 Jan 2016 15:45:56 -0200 Subject: [PATCH 0546/5324] drm/i915/fbc: don't store/check a pointer to the FB We already make sure we run intel_fbc_update_update during modesets and page flips, and this function takes care of deactivating FBC, so it shouldn't be possible for us to reach the condition we check at intel_fbc_work_fn. So instead of grabbing framebuffer references and adding a lot of code to track when we need to free them, just don't track anything at all since we shouldn't need to. v2: Rebase. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-25-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/intel_fbc.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 52cd35230f45..c921ad8e15a7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -961,7 +961,6 @@ struct intel_fbc { bool scheduled; u32 scheduled_vblank; struct work_struct work; - struct drm_framebuffer *fb; } work; const char *no_fbc_reason; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 35e92bc6b9cf..2c896f95d2c3 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -405,8 +405,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) goto retry; } - if (crtc->base.primary->fb == work->fb) - fbc->activate(dev_priv); + fbc->activate(dev_priv); work->scheduled = false; @@ -441,7 +440,6 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) * we're not releasing fbc.lock, so it won't have an opportunity to grab * it to discover that it was cancelled. So we just update the expected * jiffy count. */ - work->fb = crtc->base.primary->fb; work->scheduled = true; work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); drm_crtc_vblank_put(&crtc->base); -- GitLab From e35be23f31c9bd42c342aca519bcedbc34b35da4 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 18 Jan 2016 15:56:58 -0200 Subject: [PATCH 0547/5324] drm/i915/fbc: refactor some small functions called only once The FBC fixes we've been doing in the last months required a lot of refactor, so functions that were once big and called from different spots are now small and called only once. IMHO now it's better to just move the contents of these functions to their only callers since this reduces the number of indirections while reading the code. While at it, also improve the related comments a little bit. Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1453210558-7875-26-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 41 +++++++++++--------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 2c896f95d2c3..5adf6d7620ad 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -414,14 +414,6 @@ static void intel_fbc_work_fn(struct work_struct *__work) drm_crtc_vblank_put(&crtc->base); } -static void intel_fbc_cancel_work(struct drm_i915_private *dev_priv) -{ - struct intel_fbc *fbc = &dev_priv->fbc; - - WARN_ON(!mutex_is_locked(&fbc->lock)); - fbc->work.scheduled = false; -} - static void intel_fbc_schedule_activation(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -436,10 +428,10 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc) return; } - /* It is useless to call intel_fbc_cancel_work() in this function since - * we're not releasing fbc.lock, so it won't have an opportunity to grab - * it to discover that it was cancelled. So we just update the expected - * jiffy count. */ + /* It is useless to call intel_fbc_cancel_work() or cancel_work() in + * this function since we're not releasing fbc.lock, so it won't have an + * opportunity to grab it to discover that it was cancelled. So we just + * update the expected jiffy count. */ work->scheduled = true; work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); drm_crtc_vblank_put(&crtc->base); @@ -453,25 +445,15 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) WARN_ON(!mutex_is_locked(&fbc->lock)); - intel_fbc_cancel_work(dev_priv); + /* Calling cancel_work() here won't help due to the fact that the work + * function grabs fbc->lock. Just set scheduled to false so the work + * function can know it was cancelled. */ + fbc->work.scheduled = false; if (fbc->active) fbc->deactivate(dev_priv); } -static bool crtc_can_fbc(struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; - - if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) - return false; - - if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) - return false; - - return true; -} - static bool multiple_pipes_ok(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; @@ -831,11 +813,16 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) return false; } - if (!crtc_can_fbc(crtc)) { + if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) { fbc->no_fbc_reason = "no enabled pipes can have FBC"; return false; } + if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) { + fbc->no_fbc_reason = "no enabled planes can have FBC"; + return false; + } + return true; } -- GitLab From 50359819794b4a16ae35051cd80f2dab025f6019 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2016 21:53:09 +0100 Subject: [PATCH 0548/5324] clk-divider: make sure read-only dividers do not write to their register Commit e6d5e7d90be9 ("clk-divider: Fix READ_ONLY when divider > 1") removed the special ops struct for read-only clocks and instead opted to handle them inside the regular ops. On the rk3368 this results in breakage as aclkm now gets set a value. While it is the same divider value, the A53 core still doesn't like it, which can result in the cpu ending up in a hang. The reason being that "ACLKENMasserts one clock cycle before the rising edge of ACLKM" and the clock should only be touched when STANDBYWFIL2 is asserted. To fix this, reintroduce the read-only ops but do include the round_rate callback. That way no writes that may be unsafe are done to the divider register in any case. The Rockchip use of the clk_divider_ops is adapted to this split again, as is the nxp, lpc18xx-ccu driver that was included since the original commit. On lpc18xx-ccu the divider seems to always be read-only so only uses the new ops now. Fixes: e6d5e7d90be9 ("clk-divider: Fix READ_ONLY when divider > 1") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Signed-off-by: Stephen Boyd --- drivers/clk/clk-divider.c | 11 ++++++++++- drivers/clk/nxp/clk-lpc18xx-ccu.c | 2 +- drivers/clk/rockchip/clk.c | 4 +++- include/linux/clk-provider.h | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index ded3ff4b91b9..aa1dacdaa39d 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -423,6 +423,12 @@ const struct clk_ops clk_divider_ops = { }; EXPORT_SYMBOL_GPL(clk_divider_ops); +const struct clk_ops clk_divider_ro_ops = { + .recalc_rate = clk_divider_recalc_rate, + .round_rate = clk_divider_round_rate, +}; +EXPORT_SYMBOL_GPL(clk_divider_ro_ops); + static struct clk *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, @@ -446,7 +452,10 @@ static struct clk *_register_divider(struct device *dev, const char *name, return ERR_PTR(-ENOMEM); init.name = name; - init.ops = &clk_divider_ops; + if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) + init.ops = &clk_divider_ro_ops; + else + init.ops = &clk_divider_ops; init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 13aabbb3acbe..558da89555af 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -222,7 +222,7 @@ static void lpc18xx_ccu_register_branch_gate_div(struct lpc18xx_clk_branch *bran div->width = 1; div_hw = &div->hw; - div_ops = &clk_divider_ops; + div_ops = &clk_divider_ro_ops; } branch->gate.reg = branch->offset + reg_base; diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index d9a0b5d4d47f..f7e8693ad28b 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -90,7 +90,9 @@ static struct clk *rockchip_clk_register_branch(const char *name, div->width = div_width; div->lock = lock; div->table = div_table; - div_ops = &clk_divider_ops; + div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) + ? &clk_divider_ro_ops + : &clk_divider_ops; } clk = clk_register_composite(NULL, name, parent_names, num_parents, diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 1143e38555a4..408a60dca353 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -385,6 +385,7 @@ struct clk_divider { #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) extern const struct clk_ops clk_divider_ops; +extern const struct clk_ops clk_divider_ro_ops; unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, unsigned int val, const struct clk_div_table *table, -- GitLab From 26adc5fa276f7cfafda47d27849e6c1c3bff5aba Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Wed, 20 Jan 2016 19:14:21 +0900 Subject: [PATCH 0549/5324] clk: s2mps11: merge two for loops in one The driver already loops once, there is no reason to loop again for a different purpose. Merge the second loop into the first. Signed-off-by: Andi Shyti Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index d266299dfdb1..e7b97f4f53d3 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -244,12 +244,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_reg; } - } - - for (i = 0; i < S2MPS11_CLKS_NUM; i++) { - /* Skip clocks not present on S2MPS14 */ - if (!clks_init[i].name) - continue; clk_table[i] = s2mps11_clks[i].clk; } -- GitLab From 31ad0e2a9ab0667b40a654e5ba412987587229ea Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Wed, 20 Jan 2016 19:14:22 +0900 Subject: [PATCH 0550/5324] clk: s2mps11: allocate only one structure for clock init The driver allocates three structures, s2mpsxx_clk_init, for three different clock types (s2mps11, s2mps13 and s2mps14). They are quite similar but they differ only by the name. Only one of these structures is used, while the others lie unused in the memory. The clock's name, though, is not such a meaningful information and by assigning the same name to the initial data we can avoid over allocation. The common name chosen will be s2mps11, coherently with the device driver name, instead of the clock device. Therefore, remove the structures associated to s2mps13 and s2mps14 and use only the one referred to s2mps11 for all kind of clocks. Signed-off-by: Andi Shyti Suggested-by: Krzysztof Kozlowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 51 ++++++--------------------------------- 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index e7b97f4f53d3..3ff2162b36ff 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -99,6 +99,7 @@ static struct clk_ops s2mps11_clk_ops = { .recalc_rate = s2mps11_clk_recalc_rate, }; +/* This s2mps11_clks_init tructure is common to s2mps11, s2mps13 and s2mps14 */ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { [S2MPS11_CLK_AP] = { .name = "s2mps11_ap", @@ -117,37 +118,6 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { }, }; -static struct clk_init_data s2mps13_clks_init[S2MPS11_CLKS_NUM] = { - [S2MPS11_CLK_AP] = { - .name = "s2mps13_ap", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_CP] = { - .name = "s2mps13_cp", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_BT] = { - .name = "s2mps13_bt", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, -}; - -static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { - [S2MPS11_CLK_AP] = { - .name = "s2mps14_ap", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_BT] = { - .name = "s2mps14_bt", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, -}; - static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, struct clk_init_data *clks_init) { @@ -164,12 +134,9 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, return ERR_PTR(-EINVAL); } - for (i = 0; i < S2MPS11_CLKS_NUM; i++) { - if (!clks_init[i].name) - continue; /* Skip clocks not present in some devices */ + for (i = 0; i < S2MPS11_CLKS_NUM; i++) of_property_read_string_index(clk_np, "clock-output-names", i, &clks_init[i].name); - } return clk_np; } @@ -179,8 +146,8 @@ static int s2mps11_clk_probe(struct platform_device *pdev) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; unsigned int s2mps11_reg; - struct clk_init_data *clks_init; int i, ret = 0; + enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data; s2mps11_clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, sizeof(*s2mps11_clk), GFP_KERNEL); @@ -194,22 +161,18 @@ static int s2mps11_clk_probe(struct platform_device *pdev) if (!clk_table) return -ENOMEM; - switch(platform_get_device_id(pdev)->driver_data) { + switch (hwid) { case S2MPS11X: s2mps11_reg = S2MPS11_REG_RTC_CTRL; - clks_init = s2mps11_clks_init; break; case S2MPS13X: s2mps11_reg = S2MPS13_REG_RTCCTRL; - clks_init = s2mps13_clks_init; break; case S2MPS14X: s2mps11_reg = S2MPS14_REG_RTCCTRL; - clks_init = s2mps14_clks_init; break; case S5M8767X: s2mps11_reg = S5M8767_REG_CTRL1; - clks_init = s2mps11_clks_init; break; default: dev_err(&pdev->dev, "Invalid device type\n"); @@ -217,15 +180,15 @@ static int s2mps11_clk_probe(struct platform_device *pdev) } /* Store clocks of_node in first element of s2mps11_clks array */ - s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); + s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, s2mps11_clks_init); if (IS_ERR(s2mps11_clks->clk_np)) return PTR_ERR(s2mps11_clks->clk_np); for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { - if (!clks_init[i].name) + if (i == S2MPS11_CLK_CP && hwid == S2MPS14X) continue; /* Skip clocks not present in some devices */ s2mps11_clk->iodev = iodev; - s2mps11_clk->hw.init = &clks_init[i]; + s2mps11_clk->hw.init = &s2mps11_clks_init[i]; s2mps11_clk->mask = 1 << i; s2mps11_clk->reg = s2mps11_reg; -- GitLab From 36da4def1ea7a5f698d3096d10316f911e819621 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Wed, 20 Jan 2016 19:14:23 +0900 Subject: [PATCH 0551/5324] clk: s2mps11: remove redundant static variables declaration The clk_table and clk_data are declared static. The clk_table contains the three clock data structures belonging to the s2mps11 driver. In the probe function it gets stored into clk_data. Remove clk_table and refer directly to clk_data. clk_data, itself, is also declared static. Declare locally it and allocate it inside the probe function, as it is not used anywhere else. Signed-off-by: Andi Shyti Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 3ff2162b36ff..fac0e2029adc 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -30,9 +30,6 @@ #define s2mps11_name(a) (a->hw.init->name) -static struct clk **clk_table; -static struct clk_onecell_data clk_data; - enum { S2MPS11_CLK_AP = 0, S2MPS11_CLK_CP, @@ -145,6 +142,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; + struct clk_onecell_data *clk_data; unsigned int s2mps11_reg; int i, ret = 0; enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data; @@ -156,9 +154,13 @@ static int s2mps11_clk_probe(struct platform_device *pdev) s2mps11_clk = s2mps11_clks; - clk_table = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, + clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, sizeof(struct clk *), GFP_KERNEL); - if (!clk_table) + if (!clk_data->clks) return -ENOMEM; switch (hwid) { @@ -207,13 +209,12 @@ static int s2mps11_clk_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_reg; } - clk_table[i] = s2mps11_clks[i].clk; + clk_data->clks[i] = s2mps11_clks[i].clk; } - clk_data.clks = clk_table; - clk_data.clk_num = S2MPS11_CLKS_NUM; + clk_data->clk_num = S2MPS11_CLKS_NUM; of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get, - &clk_data); + clk_data); platform_set_drvdata(pdev, s2mps11_clks); -- GitLab From dedbb2724dca5de4073c261c52fa76bf348f6a0d Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Wed, 20 Jan 2016 19:14:24 +0900 Subject: [PATCH 0552/5324] clk: s2mps11: remove redundant code The definition of s2mps11_name is meant to resolve the name of a given clock. Remove it because the clocks have the same name we can get it directly from the s2mps11_clks_init structure. While in the probe function the s2mps11_clks is used only to iterate through the s2mps11_clks. The naming itself brings confusion and the readability does not improve much. Signed-off-by: Andi Shyti Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index fac0e2029adc..371150aabd15 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -28,8 +28,6 @@ #include #include -#define s2mps11_name(a) (a->hw.init->name) - enum { S2MPS11_CLK_AP = 0, S2MPS11_CLK_CP, @@ -141,19 +139,17 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, static int s2mps11_clk_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; + struct s2mps11_clk *s2mps11_clks; struct clk_onecell_data *clk_data; unsigned int s2mps11_reg; int i, ret = 0; enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data; s2mps11_clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, - sizeof(*s2mps11_clk), GFP_KERNEL); + sizeof(*s2mps11_clks), GFP_KERNEL); if (!s2mps11_clks) return -ENOMEM; - s2mps11_clk = s2mps11_clks; - clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return -ENOMEM; @@ -186,26 +182,26 @@ static int s2mps11_clk_probe(struct platform_device *pdev) if (IS_ERR(s2mps11_clks->clk_np)) return PTR_ERR(s2mps11_clks->clk_np); - for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { + for (i = 0; i < S2MPS11_CLKS_NUM; i++) { if (i == S2MPS11_CLK_CP && hwid == S2MPS14X) continue; /* Skip clocks not present in some devices */ - s2mps11_clk->iodev = iodev; - s2mps11_clk->hw.init = &s2mps11_clks_init[i]; - s2mps11_clk->mask = 1 << i; - s2mps11_clk->reg = s2mps11_reg; - - s2mps11_clk->clk = devm_clk_register(&pdev->dev, - &s2mps11_clk->hw); - if (IS_ERR(s2mps11_clk->clk)) { + s2mps11_clks[i].iodev = iodev; + s2mps11_clks[i].hw.init = &s2mps11_clks_init[i]; + s2mps11_clks[i].mask = 1 << i; + s2mps11_clks[i].reg = s2mps11_reg; + + s2mps11_clks[i].clk = devm_clk_register(&pdev->dev, + &s2mps11_clks[i].hw); + if (IS_ERR(s2mps11_clks[i].clk)) { dev_err(&pdev->dev, "Fail to register : %s\n", - s2mps11_name(s2mps11_clk)); - ret = PTR_ERR(s2mps11_clk->clk); + s2mps11_clks_init[i].name); + ret = PTR_ERR(s2mps11_clks[i].clk); goto err_reg; } - s2mps11_clk->lookup = clkdev_create(s2mps11_clk->clk, - s2mps11_name(s2mps11_clk), NULL); - if (!s2mps11_clk->lookup) { + s2mps11_clks[i].lookup = clkdev_create(s2mps11_clks[i].clk, + s2mps11_clks_init[i].name, NULL); + if (!s2mps11_clks[i].lookup) { ret = -ENOMEM; goto err_reg; } -- GitLab From 7b63c567b5b3b3e366e6555d764318a75073f2c7 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Tue, 19 Jan 2016 19:27:41 -0700 Subject: [PATCH 0553/5324] Documentation: Update APM X-Gene clock binding for v2 hardware Update APM X-Gene clock binding documentation for SoC and PCP PLL for v2 hardware. Signed-off-by: Loc Ho Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/xgene.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt index 1c4ef773feea..82f9638121db 100644 --- a/Documentation/devicetree/bindings/clock/xgene.txt +++ b/Documentation/devicetree/bindings/clock/xgene.txt @@ -9,6 +9,8 @@ Required properties: "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock "apm,xgene-device-clock" - for a X-Gene device clock + "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock + "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock Required properties for SoC or PCP PLL clocks: - reg : shall be the physical PLL register address for the pll clock. -- GitLab From 47727beb26569725f6c200cde2c38bd1e9f6f1b0 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Tue, 19 Jan 2016 19:27:42 -0700 Subject: [PATCH 0554/5324] clk: xgene: Add SoC and PMD PLL clocks with v2 hardware Add X-Gene SoC and PMD PLL clocks support for v2 hardware. X-Gene SoC v2 and above use an slightly different SoC and PMD PLL hardware logic. Signed-off-by: Loc Ho Signed-off-by: Stephen Boyd --- drivers/clk/clk-xgene.c | 103 +++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 37 deletions(-) diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 10224b01b97c..266d573b9134 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -29,7 +29,9 @@ #include /* Register SCU_PCPPLL bit fields */ -#define N_DIV_RD(src) (((src) & 0x000001ff)) +#define N_DIV_RD(src) ((src) & 0x000001ff) +#define SC_N_DIV_RD(src) ((src) & 0x0000007f) +#define SC_OUTDIV2(src) (((src) & 0x00000100) >> 8) /* Register SCU_SOCPLL bit fields */ #define CLKR_RD(src) (((src) & 0x07000000)>>24) @@ -63,6 +65,7 @@ struct xgene_clk_pll { spinlock_t *lock; u32 pll_offset; enum xgene_pll_type type; + int version; }; #define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw) @@ -92,27 +95,37 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw, pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset); - if (pllclk->type == PLL_TYPE_PCP) { - /* - * PLL VCO = Reference clock * NF - * PCP PLL = PLL_VCO / 2 - */ - nout = 2; - fvco = parent_rate * (N_DIV_RD(pll) + 4); + if (pllclk->version <= 1) { + if (pllclk->type == PLL_TYPE_PCP) { + /* + * PLL VCO = Reference clock * NF + * PCP PLL = PLL_VCO / 2 + */ + nout = 2; + fvco = parent_rate * (N_DIV_RD(pll) + 4); + } else { + /* + * Fref = Reference Clock / NREF; + * Fvco = Fref * NFB; + * Fout = Fvco / NOUT; + */ + nref = CLKR_RD(pll) + 1; + nout = CLKOD_RD(pll) + 1; + nfb = CLKF_RD(pll); + fref = parent_rate / nref; + fvco = fref * nfb; + } } else { /* - * Fref = Reference Clock / NREF; - * Fvco = Fref * NFB; - * Fout = Fvco / NOUT; + * fvco = Reference clock * FBDIVC + * PLL freq = fvco / NOUT */ - nref = CLKR_RD(pll) + 1; - nout = CLKOD_RD(pll) + 1; - nfb = CLKF_RD(pll); - fref = parent_rate / nref; - fvco = fref * nfb; + nout = SC_OUTDIV2(pll) ? 2 : 3; + fvco = parent_rate * SC_N_DIV_RD(pll); } - pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw), - fvco / nout, parent_rate); + pr_debug("%s pll recalc rate %ld parent %ld version %d\n", + clk_hw_get_name(hw), fvco / nout, parent_rate, + pllclk->version); return fvco / nout; } @@ -125,7 +138,7 @@ static const struct clk_ops xgene_clk_pll_ops = { static struct clk *xgene_register_clk_pll(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u32 pll_offset, - u32 type, spinlock_t *lock) + u32 type, spinlock_t *lock, int version) { struct xgene_clk_pll *apmclk; struct clk *clk; @@ -144,6 +157,7 @@ static struct clk *xgene_register_clk_pll(struct device *dev, init.parent_names = parent_name ? &parent_name : NULL; init.num_parents = parent_name ? 1 : 0; + apmclk->version = version; apmclk->reg = reg; apmclk->lock = lock; apmclk->pll_offset = pll_offset; @@ -160,26 +174,37 @@ static struct clk *xgene_register_clk_pll(struct device *dev, return clk; } +static int xgene_pllclk_version(struct device_node *np) +{ + if (of_device_is_compatible(np, "apm,xgene-socpll-clock")) + return 1; + if (of_device_is_compatible(np, "apm,xgene-pcppll-clock")) + return 1; + return 2; +} + static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type) { - const char *clk_name = np->full_name; - struct clk *clk; - void __iomem *reg; + const char *clk_name = np->full_name; + struct clk *clk; + void __iomem *reg; + int version = xgene_pllclk_version(np); - reg = of_iomap(np, 0); - if (reg == NULL) { - pr_err("Unable to map CSR register for %s\n", np->full_name); - return; - } - of_property_read_string(np, "clock-output-names", &clk_name); - clk = xgene_register_clk_pll(NULL, - clk_name, of_clk_get_parent_name(np, 0), - CLK_IS_ROOT, reg, 0, pll_type, &clk_lock); - if (!IS_ERR(clk)) { - of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - pr_debug("Add %s clock PLL\n", clk_name); - } + reg = of_iomap(np, 0); + if (reg == NULL) { + pr_err("Unable to map CSR register for %s\n", np->full_name); + return; + } + of_property_read_string(np, "clock-output-names", &clk_name); + clk = xgene_register_clk_pll(NULL, + clk_name, of_clk_get_parent_name(np, 0), + CLK_IS_ROOT, reg, 0, pll_type, &clk_lock, + version); + if (!IS_ERR(clk)) { + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + pr_debug("Add %s clock PLL\n", clk_name); + } } static void xgene_socpllclk_init(struct device_node *np) @@ -460,7 +485,7 @@ static void __init xgene_devclk_init(struct device_node *np) rc = of_address_to_resource(np, i, &res); if (rc != 0) { if (i == 0) { - pr_err("no DTS register for %s\n", + pr_err("no DTS register for %s\n", np->full_name); return; } @@ -518,4 +543,8 @@ static void __init xgene_devclk_init(struct device_node *np) CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init); CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init); +CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock", + xgene_socpllclk_init); +CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock", + xgene_pcppllclk_init); CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init); -- GitLab From f9285b54d657f433746df9232068c32ef138ebc4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 29 Jan 2016 12:57:15 -0800 Subject: [PATCH 0555/5324] clk: xgene: Remove return from void function This function doesn't return anything because it's void. Drop the return statement. Cc: Loc Ho Signed-off-by: Stephen Boyd --- drivers/clk/clk-xgene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 266d573b9134..bd7156baa08b 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -50,7 +50,7 @@ static inline u32 xgene_clk_read(void __iomem *csr) static inline void xgene_clk_write(u32 data, void __iomem *csr) { - return writel_relaxed(data, csr); + writel_relaxed(data, csr); } /* PLL Clock */ -- GitLab From 5fd9c05c846db98319e75496612da24435cee208 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 8 Jan 2016 23:51:46 +0800 Subject: [PATCH 0556/5324] clk: move the common clock's to_clk_*(_hw) macros to clk-provider.h to_clk_*(_hw) macros have been repeatedly defined in many places. This patch moves all the to_clk_*(_hw) definitions in the common clock framework to public header clk-provider.h, and drop the local definitions. Signed-off-by: Geliang Tang Signed-off-by: Stephen Boyd --- drivers/clk/clk-composite.c | 2 -- drivers/clk/clk-divider.c | 2 -- drivers/clk/clk-fixed-factor.c | 2 -- drivers/clk/clk-fixed-rate.c | 2 -- drivers/clk/clk-fractional-divider.c | 2 -- drivers/clk/clk-gate.c | 2 -- drivers/clk/clk-gpio.c | 2 -- drivers/clk/clk-multiplier.c | 2 -- drivers/clk/clk-mux.c | 2 -- drivers/clk/imx/clk-busy.c | 4 ++-- drivers/clk/imx/clk-fixup-div.c | 5 ++--- drivers/clk/imx/clk-fixup-mux.c | 2 -- drivers/clk/imx/clk-gate-exclusive.c | 2 +- drivers/clk/mediatek/clk-gate.c | 8 ++++---- drivers/clk/mediatek/clk-gate.h | 2 +- drivers/clk/mvebu/common.c | 2 -- drivers/clk/mvebu/kirkwood.c | 2 -- drivers/clk/mxs/clk-div.c | 2 +- drivers/clk/nxp/clk-lpc18xx-ccu.c | 2 -- drivers/clk/st/clkgen-mux.c | 9 ++++----- drivers/clk/ti/composite.c | 2 -- drivers/clk/ti/divider.c | 2 -- drivers/clk/ti/gate.c | 2 -- drivers/clk/ti/mux.c | 2 -- include/linux/clk-provider.h | 18 ++++++++++++++++++ 25 files changed, 33 insertions(+), 51 deletions(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 4735de0660cc..1f903e1f86a2 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -19,8 +19,6 @@ #include #include -#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) - static u8 clk_composite_get_parent(struct clk_hw *hw) { struct clk_composite *composite = to_clk_composite(hw); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index aa1dacdaa39d..7d62dc30e969 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -28,8 +28,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(width) ((1 << (width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table, diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 83de57aeceea..f0ddf37d5e15 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -23,8 +23,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) - static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index f85ec8d1711f..e156beb871f0 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) - static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index 5c4955e33f7a..1abcd76b4993 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -16,8 +16,6 @@ #include #include -#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) - static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index de0b322f5f58..d0d8ec8e1f1b 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - /* * It works on following logic: * diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 19fed65587e8..cbbea2985cc9 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -31,8 +31,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) - static int clk_gpio_gate_enable(struct clk_hw *hw) { struct clk_gpio *clk = to_clk_gpio(hw); diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c index fe7806506bf3..9e449c7b751c 100644 --- a/drivers/clk/clk-multiplier.c +++ b/drivers/clk/clk-multiplier.c @@ -14,8 +14,6 @@ #include #include -#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) - static unsigned long __get_mult(struct clk_multiplier *mult, unsigned long rate, unsigned long parent_rate) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 5ed03c8a8df9..252188fd8bcd 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -26,8 +26,6 @@ * parent - parent is adjustable through clk_set_parent */ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index 4bb1bc419b79..5cc99590f9a3 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -38,7 +38,7 @@ struct clk_busy_divider { static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw) { - struct clk_divider *div = container_of(hw, struct clk_divider, hw); + struct clk_divider *div = to_clk_divider(hw); return container_of(div, struct clk_busy_divider, div); } @@ -123,7 +123,7 @@ struct clk_busy_mux { static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw) { - struct clk_mux *mux = container_of(hw, struct clk_mux, hw); + struct clk_mux *mux = to_clk_mux(hw); return container_of(mux, struct clk_busy_mux, mux); } diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 21db020b1f2d..ce5722732715 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -15,7 +15,6 @@ #include #include "clk.h" -#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw) #define div_mask(d) ((1 << (d->width)) - 1) /** @@ -35,7 +34,7 @@ struct clk_fixup_div { static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw) { - struct clk_divider *divider = to_clk_div(hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_fixup_div, divider); } @@ -60,7 +59,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - struct clk_divider *div = to_clk_div(hw); + struct clk_divider *div = to_clk_divider(hw); unsigned int divider, value; unsigned long flags = 0; u32 val; diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 0d40b35c557c..c9b327e0a8dd 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -15,8 +15,6 @@ #include #include "clk.h" -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - /** * struct clk_fixup_mux - imx integer fixup multiplexer clock * @mux: the parent class diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index c12f5f2e04dc..3bd9dee618b2 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -31,7 +31,7 @@ struct clk_gate_exclusive { static int clk_gate_exclusive_enable(struct clk_hw *hw) { - struct clk_gate *gate = container_of(hw, struct clk_gate, hw); + struct clk_gate *gate = to_clk_gate(hw); struct clk_gate_exclusive *exgate = container_of(gate, struct clk_gate_exclusive, gate); u32 val = readl(gate->reg); diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 576bdb7c98b8..2a76901bf04b 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -25,7 +25,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -37,7 +37,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) static int mtk_cg_bit_is_set(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -49,14 +49,14 @@ static int mtk_cg_bit_is_set(struct clk_hw *hw) static void mtk_cg_set_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); } static void mtk_cg_clr_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); } diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index 11e25c992948..b1821603b887 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -29,7 +29,7 @@ struct mtk_clk_gate { u8 bit; }; -static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw) +static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw) { return container_of(hw, struct mtk_clk_gate, hw); } diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 28aac67e7b92..daa6ebdac131 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -199,8 +199,6 @@ struct clk_gating_ctrl { u32 saved_reg; }; -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - static struct clk_gating_ctrl *ctrl; static struct clk *clk_gating_get_src( diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 99550f25975e..a2a8d614039d 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -256,8 +256,6 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { 11, 1, 0 }, }; -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static struct clk *clk_muxing_get_src( struct of_phandle_args *clkspec, void *data) { diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 049ee27d5a22..f75e989c578f 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -33,7 +33,7 @@ struct clk_div { static inline struct clk_div *to_clk_div(struct clk_hw *hw) { - struct clk_divider *divider = container_of(hw, struct clk_divider, hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_div, divider); } diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 558da89555af..f7136b94fd0e 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -28,8 +28,6 @@ #define CCU_BRANCH_IS_BUS BIT(0) #define CCU_BRANCH_HAVE_DIV2 BIT(1) -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - struct lpc18xx_branch_clk_data { const char **name; int num; diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 5dc5ce217960..0d9a74b66ea3 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -822,11 +822,10 @@ static void __init st_of_clkgen_vcc_setup(struct device_node *np) if (!clk_data->clks[i]) continue; - composite = container_of(__clk_get_hw(clk_data->clks[i]), - struct clk_composite, hw); - kfree(container_of(composite->gate_hw, struct clk_gate, hw)); - kfree(container_of(composite->rate_hw, struct clk_divider, hw)); - kfree(container_of(composite->mux_hw, struct clk_mux, hw)); + composite = to_clk_composite(__clk_get_hw(clk_data->clks[i])); + kfree(to_clk_gate(composite->gate_hw)); + kfree(to_clk_divider(composite->rate_hw)); + kfree(to_clk_mux(composite->mux_hw)); } kfree(clk_data->clks); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index dbef218fe5ec..43345c417815 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -28,8 +28,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index df2558350fc1..b4e5de16e561 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(d) ((1 << ((d)->width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table) diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 5429d3534363..bc05f276f32b 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -24,8 +24,6 @@ #include "clock.h" -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index dab9ba88b9d6..618ded96ace3 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 ti_clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 408a60dca353..33dc814d0f43 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -276,6 +276,8 @@ struct clk_fixed_rate { u8 flags; }; +#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) + extern const struct clk_ops clk_fixed_rate_ops; struct clk *clk_register_fixed_rate(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -314,6 +316,8 @@ struct clk_gate { spinlock_t *lock; }; +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + #define CLK_GATE_SET_TO_DISABLE BIT(0) #define CLK_GATE_HIWORD_MASK BIT(1) @@ -376,6 +380,8 @@ struct clk_divider { spinlock_t *lock; }; +#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) + #define CLK_DIVIDER_ONE_BASED BIT(0) #define CLK_DIVIDER_POWER_OF_TWO BIT(1) #define CLK_DIVIDER_ALLOW_ZERO BIT(2) @@ -441,6 +447,8 @@ struct clk_mux { spinlock_t *lock; }; +#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) + #define CLK_MUX_INDEX_ONE BIT(0) #define CLK_MUX_INDEX_BIT BIT(1) #define CLK_MUX_HIWORD_MASK BIT(2) @@ -484,6 +492,8 @@ struct clk_fixed_factor { unsigned int div; }; +#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) + extern const struct clk_ops clk_fixed_factor_ops; struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -515,6 +525,8 @@ struct clk_fractional_divider { spinlock_t *lock; }; +#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) + extern const struct clk_ops clk_fractional_divider_ops; struct clk *clk_register_fractional_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -551,6 +563,8 @@ struct clk_multiplier { spinlock_t *lock; }; +#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) + #define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) #define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) @@ -580,6 +594,8 @@ struct clk_composite { const struct clk_ops *gate_ops; }; +#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) + struct clk *clk_register_composite(struct device *dev, const char *name, const char * const *parent_names, int num_parents, struct clk_hw *mux_hw, const struct clk_ops *mux_ops, @@ -602,6 +618,8 @@ struct clk_gpio { struct gpio_desc *gpiod; }; +#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) + extern const struct clk_ops clk_gpio_gate_ops; struct clk *clk_register_gpio_gate(struct device *dev, const char *name, const char *parent_name, unsigned gpio, bool active_low, -- GitLab From 4974259e18f1fd519d4329babbfefa24852375bb Mon Sep 17 00:00:00 2001 From: James Liao Date: Fri, 8 Jan 2016 16:15:33 +0800 Subject: [PATCH 0557/5324] clk: mediatek: Fix memory leak on clock init fail mtk_clk_register_composite() may leak memory due to some error handling path don't free all allocated memory. This patch free all pointers that may allocate memory before error return. And it's safe because kfree() can handle NULL pointers. Signed-off-by: James Liao Reviewed-by: Daniel Kurtz Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mtk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index cf08db6c130c..352830369e0e 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -209,12 +209,14 @@ struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc, mc->flags); if (IS_ERR(clk)) { - kfree(gate); - kfree(mux); + ret = PTR_ERR(clk); + goto err_out; } return clk; err_out: + kfree(div); + kfree(gate); kfree(mux); return ERR_PTR(ret); -- GitLab From dc5a9037141924c0867eb4a6e5220479dcda84f9 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 29 Jan 2016 14:44:59 -0800 Subject: [PATCH 0558/5324] drm/i915: Sink CRC: tune down error message at stop to debug_kms. When we stop the sink CRC calculation we wait a while until the counter is reset to zero and return -ETIMEDOUT. However the sink crc was calculated already by this point so we just ignore this return at the main function. So, let's also ignore the message and put it as a debug message instead of an error one. The message might still be useful when debuging test failures so we could be able to know something was not going so well with sink crc stop. v2: Improve log message. Reference: https://bugs.freedesktop.org/show_bug.cgi?id=93694 Cc: Daniel Vetter Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1454107499-29678-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e2bea710614f..f44aba1019b8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4008,7 +4008,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) } while (--attempts && count); if (attempts == 0) { - DRM_ERROR("TIMEOUT: Sink CRC counter is not zeroed\n"); + DRM_DEBUG_KMS("TIMEOUT: Sink CRC counter is not zeroed after calculation is stopped\n"); ret = -ETIMEDOUT; } -- GitLab From b9e65ebc654dffeb77d8ef878bd6b2da30c55a94 Mon Sep 17 00:00:00 2001 From: James Liao Date: Thu, 28 Jan 2016 16:58:57 +0800 Subject: [PATCH 0559/5324] clk: Move vendor's Kconfig into CCF menu section Move all vendor's Kconfig into CCF menu section to prevent new drivers putting their Kconfig files in a wrong place. Some Kconfigs need to be modified at the same time to avoid build warnings. Signed-off-by: James Liao Acked-by: Sylwester Nawrocki [sboyd@codeaurora.org: Fix typos in commit message] Acked-by: Arnd Bergmann Signed-off-by: Stephen Boyd --- arch/arm/mach-s3c24xx/Kconfig | 1 + drivers/clk/Kconfig | 8 +++----- drivers/clk/samsung/Kconfig | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index ef68ecb27396..f02495f5ca1f 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -15,6 +15,7 @@ config PLAT_S3C24XX select NO_IOPORT_MAP select S3C_DEV_NAND select IRQ_DOMAIN + select COMMON_CLK help Base platform code for any Samsung S3C24XX device diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index eca8e019e005..de707b2bfb73 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -202,11 +202,9 @@ config COMMON_CLK_CDCE706 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" -source "drivers/clk/qcom/Kconfig" - -endmenu - source "drivers/clk/mvebu/Kconfig" - +source "drivers/clk/qcom/Kconfig" source "drivers/clk/samsung/Kconfig" source "drivers/clk/tegra/Kconfig" + +endmenu diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index 84196ecdaa12..b3fe5cb01afe 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -1,6 +1,5 @@ config COMMON_CLK_SAMSUNG bool - select COMMON_CLK config S3C2410_COMMON_CLK bool -- GitLab From 7eb24279d2094eda074527762629d8146b148a22 Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Tue, 26 Jan 2016 17:18:38 -0800 Subject: [PATCH 0560/5324] Documentation: dt-bindings: Add DT bindings for Cygnus audio clock This patch adds audio clock device tree binding documentation to an existing Cygnus clock DT bindings document. Signed-off-by: Simran Rai Reviewed-by: Ray Jui Reviewed-by: Lori Hikichi Reviewed-by: Scott Branden Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/brcm,iproc-clocks.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt index 0b35e71b39e8..6f66e9aa354c 100644 --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt @@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are: "brcm,cygnus-lcpll0" "brcm,cygnus-mipipll" "brcm,cygnus-asiu-clk" + "brcm,cygnus-audiopll" The following table defines the set of PLL/clock index and ID for Cygnus. These clock IDs are defined in: @@ -131,6 +132,11 @@ These clock IDs are defined in: ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED + audiopll crystal 0 BCM_CYGNUS_AUDIOPLL + ch0_audio audiopll 1 BCM_CYGNUS_AUDIOPLL_CH0 + ch1_audio audiopll 2 BCM_CYGNUS_AUDIOPLL_CH1 + ch2_audio audiopll 3 BCM_CYGNUS_AUDIOPLL_CH2 + Northstar and Northstar Plus ------ PLL and leaf clock compatible strings for Northstar and Northstar Plus are: -- GitLab From bcd8be139803f51834347840349c150bf0e4eb96 Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Tue, 26 Jan 2016 17:18:39 -0800 Subject: [PATCH 0561/5324] clk: iproc: Add support for Cygnus audio clocks This patch adds support for Broadcom Cygnus audio PLL and leaf clocks Signed-off-by: Simran Rai Reviewed-by: Scott Branden Signed-off-by: Ray Jui Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-cygnus.c | 59 ++++++++++++++++++++++++++ drivers/clk/bcm/clk-iproc-pll.c | 41 +++++++++++++++--- drivers/clk/bcm/clk-iproc.h | 21 +++++++++ include/dt-bindings/clock/bcm-cygnus.h | 6 +++ 4 files changed, 122 insertions(+), 5 deletions(-) diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 3a228b6d4fee..464fdc4bc66b 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c @@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node) iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div)); } CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init); + +/* + * AUDIO PLL VCO frequency parameter table + * + * PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) * + * (parent clock rate / pdiv) + * + * On Cygnus, parent is the 25MHz oscillator + */ +static const struct iproc_pll_vco_param audiopll_vco_params[] = { + /* rate (Hz) ndiv_int ndiv_frac pdiv */ + { 1354750204UL, 54, 199238, 1 }, + { 1769470191UL, 70, 816639, 1 }, +}; + +static const struct iproc_pll_ctrl audiopll = { + .flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC | + IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW, + .reset = RESET_VAL(0x5c, 0, 1), + .dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3), + .sw_ctrl = SW_CTRL_VAL(0x4, 0), + .ndiv_int = REG_VAL(0x8, 0, 10), + .ndiv_frac = REG_VAL(0x8, 10, 20), + .pdiv = REG_VAL(0x44, 0, 4), + .vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10), + .status = REG_VAL(0x54, 0, 1), + .macro_mode = REG_VAL(0x0, 0, 3), +}; + +static const struct iproc_clk_ctrl audiopll_clk[] = { + [BCM_CYGNUS_AUDIOPLL_CH0] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH0, + .flags = IPROC_CLK_AON | + IPROC_CLK_MCLK_DIV_BY_2, + .enable = ENABLE_VAL(0x14, 8, 10, 9), + .mdiv = REG_VAL(0x14, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH1] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH1, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x18, 8, 10, 9), + .mdiv = REG_VAL(0x18, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH2] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH2, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x1c, 8, 10, 9), + .mdiv = REG_VAL(0x1c, 0, 8), + }, +}; + +static void __init cygnus_audiopll_clk_init(struct device_node *node) +{ + iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params, + ARRAY_SIZE(audiopll_vco_params), audiopll_clk, + ARRAY_SIZE(audiopll_clk)); +} +CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll", + cygnus_audiopll_clk_init); diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index afd5891ac9e6..fd492a5dad12 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -25,6 +25,12 @@ #define PLL_VCO_HIGH_SHIFT 19 #define PLL_VCO_LOW_SHIFT 30 +/* + * PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies + * from a look-up table. Mode 7 allows user to manipulate PLL clock dividers + */ +#define PLL_USER_MODE 7 + /* number of delay loops waiting for PLL to lock */ #define LOCK_DELAY 100 @@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll) const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; val = readl(pll->control_base + reset->offset); - val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); + else + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, iproc_pll_write(pll, pll->control_base, dig_filter->offset, val); val = readl(pll->control_base + reset->offset); - val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); + else + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, /* put PLL in reset */ __pll_put_in_reset(pll); + /* set PLL in user mode before modifying PLL controls */ + if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) { + val = readl(pll->control_base + ctrl->macro_mode.offset); + val &= ~(bit_mask(ctrl->macro_mode.width) << + ctrl->macro_mode.shift); + val |= PLL_USER_MODE << ctrl->macro_mode.shift; + iproc_pll_write(pll, pll->control_base, + ctrl->macro_mode.offset, val); + } + iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0); val = readl(pll->control_base + ctrl->vco_ctrl.l_offset); @@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, if (mdiv == 0) mdiv = 256; - clk->rate = parent_rate / mdiv; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (mdiv * 2); + else + clk->rate = parent_rate / mdiv; return clk->rate; } @@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (rate == 0 || parent_rate == 0) return -EINVAL; - div = DIV_ROUND_UP(parent_rate, rate); + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + div = DIV_ROUND_UP(parent_rate, rate * 2); + else + div = DIV_ROUND_UP(parent_rate, rate); if (div > 256) return -EINVAL; @@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, val |= div << ctrl->mdiv.shift; } iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val); - clk->rate = parent_rate / div; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (div * 2); + else + clk->rate = parent_rate / div; return 0; } diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index 8988de70a98c..febae119f9ef 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h @@ -60,6 +60,26 @@ */ #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) +/* + * Some PLLs have an additional divide by 2 in master clock calculation; + * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know + * of modified calculations + */ +#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7) + +/* + * Some PLLs provide a look up table for the leaf clock frequencies and + * auto calculates VCO frequency parameters based on the provided leaf + * clock frequencies. They have a user mode that allows the divider + * controls to be determined by the user + */ +#define IPROC_CLK_PLL_USER_MODE_ON BIT(8) + +/* + * Some PLLs have an active low reset + */ +#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9) + /* * Parameters for VCO frequency configuration * @@ -149,6 +169,7 @@ struct iproc_pll_ctrl { struct iproc_clk_reg_op pdiv; struct iproc_pll_vco_ctrl vco_ctrl; struct iproc_clk_reg_op status; + struct iproc_clk_reg_op macro_mode; }; /* diff --git a/include/dt-bindings/clock/bcm-cygnus.h b/include/dt-bindings/clock/bcm-cygnus.h index 32fbc475087a..62ac5d782a00 100644 --- a/include/dt-bindings/clock/bcm-cygnus.h +++ b/include/dt-bindings/clock/bcm-cygnus.h @@ -65,4 +65,10 @@ #define BCM_CYGNUS_ASIU_ADC_CLK 1 #define BCM_CYGNUS_ASIU_PWM_CLK 2 +/* AUDIO clock ID */ +#define BCM_CYGNUS_AUDIOPLL 0 +#define BCM_CYGNUS_AUDIOPLL_CH0 1 +#define BCM_CYGNUS_AUDIOPLL_CH1 2 +#define BCM_CYGNUS_AUDIOPLL_CH2 3 + #endif /* _CLOCK_BCM_CYGNUS_H */ -- GitLab From df416e565d6e1d18cfa3b5e016a667bf51ce6aac Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Tue, 26 Jan 2016 17:18:40 -0800 Subject: [PATCH 0562/5324] clk: iproc: Remove __init from header Remove __init macro from all function prototypes in clk-iproc.h Signed-off-by: Ray Jui Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-iproc.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index febae119f9ef..2148b4ea9f28 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h @@ -204,16 +204,16 @@ struct iproc_asiu_div { unsigned int low_width; }; -void __init iproc_armpll_setup(struct device_node *node); -void __init iproc_pll_clk_setup(struct device_node *node, - const struct iproc_pll_ctrl *pll_ctrl, - const struct iproc_pll_vco_param *vco, - unsigned int num_vco_entries, - const struct iproc_clk_ctrl *clk_ctrl, - unsigned int num_clks); -void __init iproc_asiu_setup(struct device_node *node, - const struct iproc_asiu_div *div, - const struct iproc_asiu_gate *gate, - unsigned int num_clks); +void iproc_armpll_setup(struct device_node *node); +void iproc_pll_clk_setup(struct device_node *node, + const struct iproc_pll_ctrl *pll_ctrl, + const struct iproc_pll_vco_param *vco, + unsigned int num_vco_entries, + const struct iproc_clk_ctrl *clk_ctrl, + unsigned int num_clks); +void iproc_asiu_setup(struct device_node *node, + const struct iproc_asiu_div *div, + const struct iproc_asiu_gate *gate, + unsigned int num_clks); #endif /* _CLK_IPROC_H */ -- GitLab From 5540ac8da18789e567f6d16582f76de7ab196eab Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 4 Jan 2016 11:01:53 +0000 Subject: [PATCH 0563/5324] clk:gcc-msm8916: add missing mss_q6_bimc_axi clock This clock is required for loading the qdsp firmware. Signed-off-by: Srinivas Kandagatla Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-msm8916.c | 18 ++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8916.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index e3bf09d7d0ef..899349b5aa07 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -2590,6 +2590,23 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { }, }; +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x49004, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ + "bimc_ddr_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_oxili_ahb_clk = { .halt_reg = 0x59028, .clkr = { @@ -3227,6 +3244,7 @@ static struct clk_regmap *gcc_msm8916_clocks[] = { [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr, [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr, [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, }; static struct gdsc *gcc_msm8916_gdscs[] = { diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h index 257e2fbedd94..28a27a4ed3c3 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8916.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h @@ -174,6 +174,7 @@ #define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157 #define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158 #define GCC_CODEC_DIGCODEC_CLK 159 +#define GCC_MSS_Q6_BIMC_AXI_CLK 160 /* Indexes for GDSCs */ #define BIMC_GDSC 0 -- GitLab From cbf9591f665d44f40795afe2eee4fcbcd32575d6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 6 Jan 2016 13:25:09 +0900 Subject: [PATCH 0564/5324] clk: add clk_unregister_fixed_factor() Allow to unregister fixed factor clock. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd --- drivers/clk/clk-fixed-factor.c | 13 +++++++++++++ include/linux/clk-provider.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index f0ddf37d5e15..053448e2453d 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -100,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_factor); +void clk_unregister_fixed_factor(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_factor(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor); + #ifdef CONFIG_OF /** * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 33dc814d0f43..3641eecf462a 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -498,6 +498,7 @@ extern const struct clk_ops clk_fixed_factor_ops; struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); +void clk_unregister_fixed_factor(struct clk *clk); /** * struct clk_fractional_divider - adjustable fractional divider clock -- GitLab From 0b225e41e369a7e03411bb67988513302a10382f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 6 Jan 2016 13:25:10 +0900 Subject: [PATCH 0565/5324] clk: add clk_unregister_fixed_rate() Allow to unregister fixed rate clock. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd --- drivers/clk/clk-fixed-rate.c | 13 +++++++++++++ include/linux/clk-provider.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index e156beb871f0..6858bfc548a9 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -104,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_rate); +void clk_unregister_fixed_rate(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_rate(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate); + #ifdef CONFIG_OF /** * of_fixed_clk_setup() - Setup function for simple fixed rate clock diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 3641eecf462a..fabe5bedbba6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -285,7 +285,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned long fixed_rate, unsigned long fixed_accuracy); - +void clk_unregister_fixed_rate(struct clk *clk); void of_fixed_clk_setup(struct device_node *np); /** -- GitLab From 090341b0a95d1f6d762915a75c13b393366f4ab3 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 2 Oct 2015 06:49:53 +0200 Subject: [PATCH 0566/5324] clk: vt8500: fix sign of possible PLL values With unsigned values underflow in loops can occur resulting in theoretically infinite loops. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2038576 Signed-off-by: Andrzej Hajda Signed-off-by: Stephen Boyd --- drivers/clk/clk-vt8500.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 37e928846ec5..98c4492d2c0d 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -384,7 +384,8 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul, div1; + int div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -452,7 +453,8 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -496,7 +498,8 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; -- GitLab From 653d1452b452207999b67ab943c27cd80b7bd430 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Jan 2016 12:43:41 +0900 Subject: [PATCH 0567/5324] clk: optimize the divider walk in clk_divider_bestdiv() Because _next_div() returns a valid divider, there is no need to consult _is_valid_div() for the validity of the divider in every iteration. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd --- drivers/clk/clk-divider.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 7d62dc30e969..00e035b51c69 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -303,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, */ maxdiv = min(ULONG_MAX / rate, maxdiv); - for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) { - if (!_is_valid_div(table, i, flags)) - continue; + for (i = _next_div(table, 0, flags); i <= maxdiv; + i = _next_div(table, i, flags)) { if (rate * i == parent_rate_saved) { /* * It's the most ideal case if the requested rate can be -- GitLab From 93fffbbee11af1ff9658c2822cfd355b4f16243d Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Wed, 25 Nov 2015 13:52:01 +0100 Subject: [PATCH 0568/5324] clk: palmas: constify the palmas_clks_of_match_data structure The palmas_clks_of_match_data structures are never modified. This patch constify them. Signed-off-by: LABBE Corentin Signed-off-by: Stephen Boyd --- drivers/clk/clk-palmas.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 8e3039f0c3f9..c55e7745c9f8 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -44,7 +44,7 @@ struct palmas_clock_info { struct clk *clk; struct clk_hw hw; struct palmas *palmas; - struct palmas_clk32k_desc *clk_desc; + const struct palmas_clk32k_desc *clk_desc; int ext_control_pin; }; @@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = { struct palmas_clks_of_match_data { struct clk_init_data init; - struct palmas_clk32k_desc desc; + const struct palmas_clk32k_desc desc; }; -static struct palmas_clks_of_match_data palmas_of_clk32kg = { +static const struct palmas_clks_of_match_data palmas_of_clk32kg = { .init = { .name = "clk32kg", .ops = &palmas_clks_ops, @@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = { }, }; -static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { +static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { .init = { .name = "clk32kgaudio", .ops = &palmas_clks_ops, @@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct device_node *node = pdev->dev.of_node; - struct palmas_clks_of_match_data *match_data; + const struct palmas_clks_of_match_data *match_data; const struct of_device_id *match; struct palmas_clock_info *cinfo; struct clk *clk; int ret; match = of_match_device(palmas_clks_of_match, &pdev->dev); - match_data = (struct palmas_clks_of_match_data *)match->data; + match_data = match->data; cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) -- GitLab From 8d0a69d735318cbd99c1376d16ed7ff82a7a678e Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Wed, 25 Nov 2015 13:52:02 +0100 Subject: [PATCH 0569/5324] clk: palmas: fix a possible NULL dereference of_match_device could return NULL, and so cause a NULL pointer dereference later. Even if the probability of this case is very low, fixing it made static analyzers happy. Solving this with of_device_get_match_data made also code simplier. Reported-by: coverity (CID 1324137) Signed-off-by: LABBE Corentin Signed-off-by: Stephen Boyd --- drivers/clk/clk-palmas.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index c55e7745c9f8..9c0b8e6b1ab3 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -241,13 +241,13 @@ static int palmas_clks_probe(struct platform_device *pdev) struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct device_node *node = pdev->dev.of_node; const struct palmas_clks_of_match_data *match_data; - const struct of_device_id *match; struct palmas_clock_info *cinfo; struct clk *clk; int ret; - match = of_match_device(palmas_clks_of_match, &pdev->dev); - match_data = match->data; + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) + return 1; cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) -- GitLab From d95b599c0395c0aa831c6199f2e7b404d33841a2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 30 Nov 2015 17:54:55 +0100 Subject: [PATCH 0570/5324] clk: axi-clkgen: Remove version 1 support Version 1 of the axi-clkgen core has not been used in new designs for over two years now. This is a soft peripheral used in FPGAs and anybody who has updated their kernel to the latest version will also have updated the bitstream containing the clock generator. So it should be safe to drop support for this now. Signed-off-by: Lars-Peter Clausen Signed-off-by: Stephen Boyd --- drivers/clk/clk-axi-clkgen.c | 125 ++--------------------------------- 1 file changed, 4 insertions(+), 121 deletions(-) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 3bcd42fbb55e..8dedc600e711 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -16,18 +16,6 @@ #include #include -#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04 -#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08 -#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c -#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10 -#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14 -#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18 -#define AXI_CLKGEN_V1_REG_LOCK1 0x1c -#define AXI_CLKGEN_V1_REG_LOCK2 0x20 -#define AXI_CLKGEN_V1_REG_LOCK3 0x24 -#define AXI_CLKGEN_V1_REG_FILTER1 0x28 -#define AXI_CLKGEN_V1_REG_FILTER2 0x2c - #define AXI_CLKGEN_V2_REG_RESET 0x40 #define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70 #define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74 @@ -51,40 +39,11 @@ #define MMCM_REG_FILTER1 0x4e #define MMCM_REG_FILTER2 0x4f -struct axi_clkgen; - -struct axi_clkgen_mmcm_ops { - void (*enable)(struct axi_clkgen *axi_clkgen, bool enable); - int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int val, unsigned int mask); - int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int *val); -}; - struct axi_clkgen { void __iomem *base; - const struct axi_clkgen_mmcm_ops *mmcm_ops; struct clk_hw clk_hw; }; -static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen->mmcm_ops->enable(axi_clkgen, enable); -} - -static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask); -} - -static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val); -} - static uint32_t axi_clkgen_lookup_filter(unsigned int m) { switch (m) { @@ -207,70 +166,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen, *val = readl(axi_clkgen->base + reg); } -static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg) -{ - switch (reg) { - case MMCM_REG_CLKOUT0_1: - return AXI_CLKGEN_V1_REG_CLK_OUT1; - case MMCM_REG_CLKOUT0_2: - return AXI_CLKGEN_V1_REG_CLK_OUT2; - case MMCM_REG_CLK_FB1: - return AXI_CLKGEN_V1_REG_CLK_FB1; - case MMCM_REG_CLK_FB2: - return AXI_CLKGEN_V1_REG_CLK_FB2; - case MMCM_REG_CLK_DIV: - return AXI_CLKGEN_V1_REG_CLK_DIV; - case MMCM_REG_LOCK1: - return AXI_CLKGEN_V1_REG_LOCK1; - case MMCM_REG_LOCK2: - return AXI_CLKGEN_V1_REG_LOCK2; - case MMCM_REG_LOCK3: - return AXI_CLKGEN_V1_REG_LOCK3; - case MMCM_REG_FILTER1: - return AXI_CLKGEN_V1_REG_FILTER1; - case MMCM_REG_FILTER2: - return AXI_CLKGEN_V1_REG_FILTER2; - default: - return 0; - } -} - -static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_write(axi_clkgen, reg, val); - - return 0; -} - -static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_read(axi_clkgen, reg, val); - - return 0; -} - -static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable); -} - -static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = { - .write = axi_clkgen_v1_mmcm_write, - .read = axi_clkgen_v1_mmcm_read, - .enable = axi_clkgen_v1_mmcm_enable, -}; - static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) { unsigned int timeout = 10000; @@ -286,7 +181,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) return val & 0xffff; } -static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int *val) { unsigned int reg_val; @@ -310,7 +205,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, return 0; } -static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int val, unsigned int mask) { unsigned int reg_val = 0; @@ -321,7 +216,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return ret; if (mask != 0xffff) { - axi_clkgen_v2_mmcm_read(axi_clkgen, reg, ®_val); + axi_clkgen_mmcm_read(axi_clkgen, reg, ®_val); reg_val &= ~mask; } @@ -332,7 +227,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return 0; } -static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, +static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, bool enable) { unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE; @@ -343,12 +238,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val); } -static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = { - .write = axi_clkgen_v2_mmcm_write, - .read = axi_clkgen_v2_mmcm_read, - .enable = axi_clkgen_v2_mmcm_enable, -}; - static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) { return container_of(clk_hw, struct axi_clkgen, clk_hw); @@ -470,11 +359,7 @@ static const struct clk_ops axi_clkgen_ops = { static const struct of_device_id axi_clkgen_ids[] = { { - .compatible = "adi,axi-clkgen-1.00.a", - .data = &axi_clkgen_v1_mmcm_ops - }, { .compatible = "adi,axi-clkgen-2.00.a", - .data = &axi_clkgen_v2_mmcm_ops, }, { }, }; @@ -501,8 +386,6 @@ static int axi_clkgen_probe(struct platform_device *pdev) if (!axi_clkgen) return -ENOMEM; - axi_clkgen->mmcm_ops = id->data; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(axi_clkgen->base)) -- GitLab From 62d1e7823d9c3b454dcbffd58f35c5fa96172644 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 30 Nov 2015 17:54:56 +0100 Subject: [PATCH 0571/5324] clk: axi-clkgen: Add multi-parent support The clock generator has two clock inputs that can be used as the reference clock. Add support for switching between them at runtime. Signed-off-by: Lars-Peter Clausen Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/axi-clkgen.txt | 5 ++- drivers/clk/clk-axi-clkgen.c | 40 ++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt index 20e1704e7df2..fb40da303d25 100644 --- a/Documentation/devicetree/bindings/clock/axi-clkgen.txt +++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt @@ -8,7 +8,10 @@ Required properties: - compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a". - #clock-cells : from common clock binding; Should always be set to 0. - reg : Address and length of the axi-clkgen register set. -- clocks : Phandle and clock specifier for the parent clock. +- clocks : Phandle and clock specifier for the parent clock(s). This must + either reference one clock if only the first clock input is connected or two + if both clock inputs are connected. For the later case the clock connected + to the first input must be specified first. Optional properties: - clock-output-names : From common clock binding. diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 8dedc600e711..9a0744c9947c 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -17,6 +17,7 @@ #include #define AXI_CLKGEN_V2_REG_RESET 0x40 +#define AXI_CLKGEN_V2_REG_CLKSEL 0x44 #define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70 #define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74 @@ -349,12 +350,33 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw) axi_clkgen_mmcm_enable(axi_clkgen, false); } +static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index); + + return 0; +} + +static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + unsigned int parent; + + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent); + + return parent; +} + static const struct clk_ops axi_clkgen_ops = { .recalc_rate = axi_clkgen_recalc_rate, .round_rate = axi_clkgen_round_rate, .set_rate = axi_clkgen_set_rate, .enable = axi_clkgen_enable, .disable = axi_clkgen_disable, + .set_parent = axi_clkgen_set_parent, + .get_parent = axi_clkgen_get_parent, }; static const struct of_device_id axi_clkgen_ids[] = { @@ -370,10 +392,11 @@ static int axi_clkgen_probe(struct platform_device *pdev) const struct of_device_id *id; struct axi_clkgen *axi_clkgen; struct clk_init_data init; - const char *parent_name; + const char *parent_names[2]; const char *clk_name; struct resource *mem; struct clk *clk; + unsigned int i; if (!pdev->dev.of_node) return -ENODEV; @@ -391,19 +414,24 @@ static int axi_clkgen_probe(struct platform_device *pdev) if (IS_ERR(axi_clkgen->base)) return PTR_ERR(axi_clkgen->base); - parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); - if (!parent_name) + init.num_parents = of_clk_get_parent_count(pdev->dev.of_node); + if (init.num_parents < 1 || init.num_parents > 2) return -EINVAL; + for (i = 0; i < init.num_parents; i++) { + parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i); + if (!parent_names[i]) + return -EINVAL; + } + clk_name = pdev->dev.of_node->name; of_property_read_string(pdev->dev.of_node, "clock-output-names", &clk_name); init.name = clk_name; init.ops = &axi_clkgen_ops; - init.flags = CLK_SET_RATE_GATE; - init.parent_names = &parent_name; - init.num_parents = 1; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.parent_names = parent_names; axi_clkgen_mmcm_enable(axi_clkgen, false); -- GitLab From 3d6f1c7212d0823cbc056b1c184c7fe0cfef553a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 29 Jan 2016 17:09:01 -0800 Subject: [PATCH 0572/5324] clk: axi-clkgen: Remove sometimes impossible check The size of unsigned long on 64-bit architectures is equal to the size of u64, so this check is impossible there. This throws off static checkers: drivers/clk/clk-axi-clkgen.c:331 axi_clkgen_recalc_rate() warn: impossible condition '(tmp > (~0)) => (0-u64max > u64max)' Let's change this code to use min_t() instead so that we get the same effect on architectures where sizeof(unsigned long) doesn't equal sizeof(u64). Cc: Lars-Peter Clausen Signed-off-by: Stephen Boyd --- drivers/clk/clk-axi-clkgen.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 9a0744c9947c..3294db3b4e4e 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -328,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, tmp = (unsigned long long)(parent_rate / d) * m; do_div(tmp, dout); - if (tmp > ULONG_MAX) - return ULONG_MAX; - - return tmp; + return min_t(unsigned long long, tmp, ULONG_MAX); } static int axi_clkgen_enable(struct clk_hw *clk_hw) -- GitLab From 9849fadfc07eeb2a3699f1ccb7b61f59d2c3c6b8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 25 Jan 2016 16:54:04 +0100 Subject: [PATCH 0573/5324] clk: st: avoid uninitialized variable use My previous patch fixed some warnings about printing a couple of variables that are always uninitialized in quadfs_pll_fs660c32_set_rate(), but I now got a warning that only shows up in some configurations (i.e. without gcc -Os) about the params.ndiv being used uninitialized in the error case: drivers/clk/st/clkgen-fsyn.c: In function 'quadfs_pll_fs660c32_set_rate': drivers/clk/st/clkgen-fsyn.c:584:75: warning: 'params.ndiv' may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/clk/st/clkgen-fsyn.c:574:16: note: 'params.ndiv' was declared here This changes the error handling so we bail for invalid arguments rather than continuing with uninitialized data. Signed-off-by: Arnd Bergmann Signed-off-by: Stephen Boyd --- drivers/clk/st/clkgen-fsyn.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index ccb324d97160..dec4eaaecc00 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -574,12 +574,16 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, struct stm_fs params; long hwrate = 0; unsigned long flags = 0; + int ret; if (!rate || !parent_rate) return -EINVAL; - if (!clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms)) - clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); + ret = clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms); + if (ret) + return ret; + + clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n", __func__, clk_hw_get_name(hw), -- GitLab From fe253133728cce8793c4390c943b5b46d073d5e4 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Thu, 28 Jan 2016 16:43:30 +0800 Subject: [PATCH 0574/5324] ARM: dts: rockchip: add the leds control for rk3036-kylin board As the kylin schematic drawing, add the needed work led for kylin board. Run: echo 0 > /sys/class/leds/kylin:red:led/brightness echo 1 > /sys/class/leds/kylin:red:led/brightness The led can normal on/off on kylin board. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 190f22cc95ef..3332a7f785c5 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -46,6 +46,17 @@ model = "Rockchip RK3036 KylinBoard"; compatible = "rockchip,rk3036-kylin", "rockchip,rk3036"; + leds: gpio-leds { + compatible = "gpio-leds"; + + work { + gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + label = "kylin:red:led"; + pinctrl-names = "default"; + pinctrl-0 = <&led_ctl>; + }; + }; + sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -359,6 +370,12 @@ }; &pinctrl { + leds { + led_ctl: led-ctl { + rockchip,pins = <2 30 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int: pmic-int { rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_default>; -- GitLab From 3dd3c077b5121ae33329187e677bc86d91fa2ddd Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Sun, 31 Jan 2016 16:19:42 -0800 Subject: [PATCH 0575/5324] ARM: dts: Add audio clock to the existing Broadcom Cygnus clock DT Signed-off-by: Simran Rai Reviewed-by: Ray Jui Reviewed-by: Scott Branden Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm-cygnus-clock.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/bcm-cygnus-clock.dtsi b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi index 32bcd45ef22b..80b6ba4ca50c 100644 --- a/arch/arm/boot/dts/bcm-cygnus-clock.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi @@ -121,4 +121,13 @@ clocks { clocks = <&osc>; clock-output-names = "keypad", "adc/touch", "pwm"; }; + + audiopll: audiopll { + #clock-cells = <1>; + compatible = "brcm,cygnus-audiopll"; + reg = <0x180aeb00 0x68>; + clocks = <&osc>; + clock-output-names = "audiopll", "ch0_audio", + "ch1_audio", "ch2_audio"; + }; }; -- GitLab From bde491fde0d56b56081a2452b08c05cbf3b820d4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:50:33 +0100 Subject: [PATCH 0576/5324] ARM: s3c24xx: don't select EEPROM_AT24 EEPROM_AT24 depends on both I2C and SYSFS. We have in the past added I2C 'select' statements to avoid build problems with the first, but we still get a warning because of the second: warning: (MACH_DAVINCI_EVM && MACH_SFFSDR && MACH_DAVINCI_DM6467_EVM && MACH_DAVINCI_DM365_EVM && MACH_DAVINCI_DA830_EVM && MACH_MITYOMAPL138 && MACH_MINI2440) selects EEPROM_AT24 which has unmet direct dependencies (I2C && SYSFS) This removes the 'select' statements again, and forces users to enable the driver in their configuration files, as we do for most other drivers. Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Kozlowski --- arch/arm/configs/mini2440_defconfig | 1 + arch/arm/configs/s3c2410_defconfig | 1 + arch/arm/mach-s3c24xx/Kconfig | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 9c93f5655248..0b02e4f43c6a 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -158,6 +158,7 @@ CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_S3C2410=y CONFIG_I2C_SIMTEC=y +CONFIG_EEPROM_AT24=y CONFIG_SPI=y CONFIG_SPI_S3C24XX=y CONFIG_SPI_SPIDEV=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f3142369f594..b3ade552a2a5 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -290,6 +290,7 @@ CONFIG_HW_RANDOM=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_S3C2410=y CONFIG_I2C_SIMTEC=y +CONFIG_EEPROM_AT24=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_SPI_S3C24XX=m diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index ef68ecb27396..c94ef77405ed 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -460,7 +460,6 @@ config MACH_AT2440EVB config MACH_MINI2440 bool "MINI2440 development board" - select EEPROM_AT24 if I2C select LEDS_CLASS select LEDS_TRIGGERS select LEDS_TRIGGER_BACKLIGHT -- GitLab From 16560854d06da88de43ddc5df8c0ba3e90328a9d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:50:34 +0100 Subject: [PATCH 0577/5324] ARM: s3c24xx: allow selecting S3C2440_XTAL_16934400 for s3c2442 The S3C2440_XTAL_16934400 and S3C2440_XTAL_12000000 symbols are used for both s3c2442 and s3c2440, but Kconfig only allows it to be selected if CPU_S3C2440 is enabled, which can lead to a warning otherwise: warning: (MACH_RX1950) selects S3C2440_XTAL_16934400 which has unmet direct dependencies (ARCH_S3C24XX && CPU_S3C2440) This changes the dependencies to make it possible also for CPU_S3C2442-only configurations. Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c24xx/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index c94ef77405ed..5884bbb7952e 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -405,7 +405,7 @@ config MACH_S3C2416_DT endif # CPU_S3C2416 -if CPU_S3C2440 +if CPU_S3C2440 || CPU_S3C2442 config S3C2440_XTAL_12000000 bool @@ -432,6 +432,9 @@ config S3C2440_PLL_16934400 default y if S3C24XX_PLL help PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. +endif + +if CPU_S3C2440 comment "S3C2440 Boards" -- GitLab From 8db9a2026db33971dc7e60ffa7d6abee694a3f0c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:50:35 +0100 Subject: [PATCH 0578/5324] ARM: s3c24xx: fix unused gta02_configure_pmu_for_charger warning gta02_configure_pmu_for_charger is only used when CONFIG_PCF50633_ADC is set, and otherwise we get a warning about an unused symbol: arch/arm/mach-s3c24xx/mach-gta02.c:158:1: warning: 'gta02_configure_pmu_for_charger' defined but not used [-Wunused-function] gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) This adds an #ifdef to shut up the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c24xx/mach-gta02.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 6d1e0b9c5b27..27ae6877550f 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -154,6 +154,7 @@ static struct s3c2410_uartcfg gta02_uartcfgs[] = { #define ADC_NOM_CHG_DETECT_1A 6 #define ADC_NOM_CHG_DETECT_USB 43 +#ifdef CONFIG_PCF50633_ADC static void gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) { @@ -174,6 +175,7 @@ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) pcf50633_mbc_usb_curlim_set(pcf, ma); } +#endif static struct delayed_work gta02_charger_work; static int gta02_usb_vbus_draw; -- GitLab From a113b057615b6ea96dd72262fe1d879f864b8fbf Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:50:37 +0100 Subject: [PATCH 0579/5324] ARM: s3c64xx: mark regulator init data as unused The smdk6410 board defines lots of regulator settings, but uses most of them only in certain configurations, and otherwise leaves them without any references, so we get lots of randconfig warnings about them: mach-s3c64xx/mach-smdk6410.c:303:35: error: 'smdk6410_vddarm' defined but not used [-Werror=unused-variable] mach-s3c64xx/mach-smdk6410.c:316:35: error: 'smdk6410_vddint' defined but not used [-Werror=unused-variable] mach-s3c64xx/mach-smdk6410.c:327:35: error: 'smdk6410_vddhi' defined but not used [-Werror=unused-variable] mach-s3c64xx/mach-smdk6410.c:335:35: error: 'smdk6410_vddpll' defined but not used [-Werror=unused-variable] mach-s3c64xx/mach-smdk6410.c:343:35: error: 'smdk6410_vdduh_mmc' defined but not used [-Werror=unused-variable] This marks all regulator_init_data structures in this file as __maybe_unused, indicating that we don't care whether there are any references or not in a given configuration. Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c64xx/mach-smdk6410.c | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 8a894ee3ee76..92ec8c3b42b9 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -216,7 +216,7 @@ static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = { REGULATOR_SUPPLY("AVDD", "0-001b"), }; -static struct regulator_init_data smdk6410_b_pwr_5v_data = { +static struct regulator_init_data __maybe_unused smdk6410_b_pwr_5v_data = { .constraints = { .always_on = 1, }, @@ -300,7 +300,7 @@ static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = { }; /* VDDARM, BUCK1 on J5 */ -static struct regulator_init_data smdk6410_vddarm = { +static struct regulator_init_data __maybe_unused smdk6410_vddarm = { .constraints = { .name = "PVDD_ARM", .min_uV = 1000000, @@ -313,7 +313,7 @@ static struct regulator_init_data smdk6410_vddarm = { }; /* VDD_INT, BUCK2 on J5 */ -static struct regulator_init_data smdk6410_vddint = { +static struct regulator_init_data __maybe_unused smdk6410_vddint = { .constraints = { .name = "PVDD_INT", .min_uV = 1000000, @@ -324,7 +324,7 @@ static struct regulator_init_data smdk6410_vddint = { }; /* VDD_HI, LDO3 on J5 */ -static struct regulator_init_data smdk6410_vddhi = { +static struct regulator_init_data __maybe_unused smdk6410_vddhi = { .constraints = { .name = "PVDD_HI", .always_on = 1, @@ -332,7 +332,7 @@ static struct regulator_init_data smdk6410_vddhi = { }; /* VDD_PLL, LDO2 on J5 */ -static struct regulator_init_data smdk6410_vddpll = { +static struct regulator_init_data __maybe_unused smdk6410_vddpll = { .constraints = { .name = "PVDD_PLL", .always_on = 1, @@ -340,7 +340,7 @@ static struct regulator_init_data smdk6410_vddpll = { }; /* VDD_UH_MMC, LDO5 on J5 */ -static struct regulator_init_data smdk6410_vdduh_mmc = { +static struct regulator_init_data __maybe_unused smdk6410_vdduh_mmc = { .constraints = { .name = "PVDD_UH+PVDD_MMC", .always_on = 1, @@ -348,7 +348,7 @@ static struct regulator_init_data smdk6410_vdduh_mmc = { }; /* VCCM3BT, LDO8 on J5 */ -static struct regulator_init_data smdk6410_vccmc3bt = { +static struct regulator_init_data __maybe_unused smdk6410_vccmc3bt = { .constraints = { .name = "PVCCM3BT", .always_on = 1, @@ -356,7 +356,7 @@ static struct regulator_init_data smdk6410_vccmc3bt = { }; /* VCCM2MTV, LDO11 on J5 */ -static struct regulator_init_data smdk6410_vccm2mtv = { +static struct regulator_init_data __maybe_unused smdk6410_vccm2mtv = { .constraints = { .name = "PVCCM2MTV", .always_on = 1, @@ -364,7 +364,7 @@ static struct regulator_init_data smdk6410_vccm2mtv = { }; /* VDD_LCD, LDO12 on J5 */ -static struct regulator_init_data smdk6410_vddlcd = { +static struct regulator_init_data __maybe_unused smdk6410_vddlcd = { .constraints = { .name = "PVDD_LCD", .always_on = 1, @@ -372,7 +372,7 @@ static struct regulator_init_data smdk6410_vddlcd = { }; /* VDD_OTGI, LDO9 on J5 */ -static struct regulator_init_data smdk6410_vddotgi = { +static struct regulator_init_data __maybe_unused smdk6410_vddotgi = { .constraints = { .name = "PVDD_OTGI", .always_on = 1, @@ -380,7 +380,7 @@ static struct regulator_init_data smdk6410_vddotgi = { }; /* VDD_OTG, LDO14 on J5 */ -static struct regulator_init_data smdk6410_vddotg = { +static struct regulator_init_data __maybe_unused smdk6410_vddotg = { .constraints = { .name = "PVDD_OTG", .always_on = 1, @@ -388,7 +388,7 @@ static struct regulator_init_data smdk6410_vddotg = { }; /* VDD_ALIVE, LDO15 on J5 */ -static struct regulator_init_data smdk6410_vddalive = { +static struct regulator_init_data __maybe_unused smdk6410_vddalive = { .constraints = { .name = "PVDD_ALIVE", .always_on = 1, @@ -396,7 +396,7 @@ static struct regulator_init_data smdk6410_vddalive = { }; /* VDD_AUDIO, VLDO_AUDIO on J5 */ -static struct regulator_init_data smdk6410_vddaudio = { +static struct regulator_init_data __maybe_unused smdk6410_vddaudio = { .constraints = { .name = "PVDD_AUDIO", .always_on = 1, @@ -406,7 +406,7 @@ static struct regulator_init_data smdk6410_vddaudio = { #ifdef CONFIG_SMDK6410_WM1190_EV1 /* S3C64xx internal logic & PLL */ -static struct regulator_init_data wm8350_dcdc1_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc1_data = { .constraints = { .name = "PVDD_INT+PVDD_PLL", .min_uV = 1200000, @@ -417,7 +417,7 @@ static struct regulator_init_data wm8350_dcdc1_data = { }; /* Memory */ -static struct regulator_init_data wm8350_dcdc3_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc3_data = { .constraints = { .name = "PVDD_MEM", .min_uV = 1800000, @@ -437,7 +437,7 @@ static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = { REGULATOR_SUPPLY("DVDD", "0-001b"), }; -static struct regulator_init_data wm8350_dcdc4_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc4_data = { .constraints = { .name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV", .min_uV = 3000000, @@ -449,7 +449,7 @@ static struct regulator_init_data wm8350_dcdc4_data = { }; /* OTGi/1190-EV1 HPVDD & AVDD */ -static struct regulator_init_data wm8350_ldo4_data = { +static struct regulator_init_data __maybe_unused wm8350_ldo4_data = { .constraints = { .name = "PVDD_OTGI+HPVDD+AVDD", .min_uV = 1200000, @@ -537,7 +537,7 @@ static struct wm831x_backlight_pdata wm1192_backlight_pdata = { .max_uA = 27554, }; -static struct regulator_init_data wm1192_dcdc3 = { +static struct regulator_init_data __maybe_unused wm1192_dcdc3 = { .constraints = { .name = "PVDD_MEM+PVDD_GPS", .always_on = 1, @@ -548,7 +548,7 @@ static struct regulator_consumer_supply wm1192_ldo1_consumers[] = { REGULATOR_SUPPLY("DVDD", "0-001b"), /* WM8580 */ }; -static struct regulator_init_data wm1192_ldo1 = { +static struct regulator_init_data __maybe_unused wm1192_ldo1 = { .constraints = { .name = "PVDD_LCD+PVDD_EXT", .always_on = 1, -- GitLab From dc7eb9d589e595954792cc192bcbb92932e5c2ff Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:50:38 +0100 Subject: [PATCH 0580/5324] ARM: EXYNOS: select THERMAL_OF We cannot select a symbol that has disabled dependencies, so we get a warning if we ever enable EXYNOS_THERMAL without also turning on THERMAL_OF: warning: (ARCH_EXYNOS) selects EXYNOS_THERMAL which has unmet direct dependencies (THERMAL && (ARCH_EXYNOS || COMPILE_TEST) && THERMAL_OF) This adds another 'select' in the platform code to avoid that case. Alternatively, we could decide to not select EXYNOS_THERMAL here and instead make it a user option. Signed-off-by: Arnd Bergmann Fixes: f87e6bd3f740 ("thermal: exynos: Add the dependency of CONFIG_THERMAL_OF instead of CONFIG_OF") Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-exynos/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 652a0bb11578..5189bcecad12 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -27,6 +27,7 @@ menuconfig ARCH_EXYNOS select S5P_DEV_MFC select SRAM select THERMAL + select THERMAL_OF select MFD_SYSCON select CLKSRC_EXYNOS_MCT select POWER_RESET -- GitLab From 58f1369216367d27e047bead7221ff977431acaa Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 16:45:47 -0500 Subject: [PATCH 0581/5324] SUNRPC: Remove unused function rpc_task_reset_client Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 1 - net/sunrpc/clnt.c | 8 -------- 2 files changed, 9 deletions(-) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 131032f15cc1..0c5c2cbe96c9 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -139,7 +139,6 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, struct rpc_xprt *xprt); struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, const struct rpc_program *, u32); -void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt); struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); struct rpc_clnt *rpc_clone_client_set_auth(struct rpc_clnt *, rpc_authflavor_t); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b7f21044f4d8..2b4ad7aa40c6 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -900,14 +900,6 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) } } -void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt) -{ - rpc_task_release_client(task); - rpc_task_set_client(task, clnt); -} -EXPORT_SYMBOL_GPL(rpc_task_reset_client); - - static void rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) { -- GitLab From 5edd1051f4f3bd7cddcc91e346fdd22eee639c72 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 25 Feb 2015 14:49:16 -0500 Subject: [PATCH 0582/5324] SUNRPC: Reorder rpc_task to put waitqueue related info in same cachelines Try to group all the data required by the waitqueues, their timers and timer callbacks into the same cachelines for performance. With this reordering, "pahole" reports the following structure on x86_64: struct rpc_task { atomic_t tk_count; /* 0 4 */ int tk_status; /* 4 4 */ struct list_head tk_task; /* 8 16 */ void (*tk_callback)(struct rpc_task *); /* 24 void (*tk_action)(struct rpc_task *); /* 32 long unsigned int tk_timeout; /* 40 8 */ long unsigned int tk_runstate; /* 48 8 */ struct rpc_wait_queue * tk_waitqueue; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ union { struct work_struct tk_work; /* 64 */ struct rpc_wait tk_wait; /* 56 */ } u; /* 64 64 */ /* --- cacheline 2 boundary (128 bytes) --- */ struct rpc_message tk_msg; /* 128 32 */ void * tk_calldata; /* 160 8 */ const struct rpc_call_ops * tk_ops; /* 168 8 */ struct rpc_clnt * tk_client; /* 176 8 */ struct rpc_rqst * tk_rqstp; /* 184 8 */ /* --- cacheline 3 boundary (192 bytes) --- */ struct workqueue_struct * tk_workqueue; /* 192 8 */ ktime_t tk_start; /* 200 8 */ pid_t tk_owner; /* 208 4 */ short unsigned int tk_flags; /* 212 2 */ short unsigned int tk_timeouts; /* 214 2 */ short unsigned int tk_pid; /* 216 2 */ unsigned char tk_priority:2; /* 218: 6 1 */ unsigned char tk_garb_retry:2; /* 218: 4 1 */ unsigned char tk_cred_retry:2; /* 218: 2 1 */ unsigned char tk_rebind_retry:2; /* 218: 0 1 */ /* size: 224, cachelines: 4, members: 24 */ /* padding: 5 */ /* last cacheline: 32 bytes */ }; whereas on i386, it reports everything fitting into the 1st cacheline. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/sched.h | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index d703f0ef37d8..ee0fbcf9b02e 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -42,40 +42,41 @@ struct rpc_wait { */ struct rpc_task { atomic_t tk_count; /* Reference count */ + int tk_status; /* result of last operation */ struct list_head tk_task; /* global list of tasks */ - struct rpc_clnt * tk_client; /* RPC client */ - struct rpc_rqst * tk_rqstp; /* RPC request */ - - /* - * RPC call state - */ - struct rpc_message tk_msg; /* RPC call info */ /* * callback to be executed after waking up * action next procedure for async tasks - * tk_ops caller callbacks */ void (*tk_callback)(struct rpc_task *); void (*tk_action)(struct rpc_task *); - const struct rpc_call_ops *tk_ops; - void * tk_calldata; unsigned long tk_timeout; /* timeout for rpc_sleep() */ unsigned long tk_runstate; /* Task run status */ - struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could - * be any workqueue - */ + struct rpc_wait_queue *tk_waitqueue; /* RPC wait queue we're on */ union { struct work_struct tk_work; /* Async task work queue */ struct rpc_wait tk_wait; /* RPC wait */ } u; + /* + * RPC call state + */ + struct rpc_message tk_msg; /* RPC call info */ + void * tk_calldata; /* Caller private data */ + const struct rpc_call_ops *tk_ops; /* Caller callbacks */ + + struct rpc_clnt * tk_client; /* RPC client */ + struct rpc_rqst * tk_rqstp; /* RPC request */ + + struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could + * be any workqueue + */ ktime_t tk_start; /* RPC task init timestamp */ pid_t tk_owner; /* Process id for batching tasks */ - int tk_status; /* result of last operation */ unsigned short tk_flags; /* misc flags */ unsigned short tk_timeouts; /* maj timeouts */ -- GitLab From 30c5116b113689c87a711a0963753adadd702c04 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 24 Feb 2015 20:31:39 -0500 Subject: [PATCH 0583/5324] SUNRPC: Uninline xprt_get(); It isn't performance critical. Also allow callers to pass NULL arguments to xprt_get() and xprt_put(). Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprt.h | 16 +++------------- net/sunrpc/xprt.c | 24 +++++++++++++++++++++--- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 69ef5b3ab038..1bdb59a2efe8 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -166,7 +167,7 @@ enum xprt_transports { }; struct rpc_xprt { - atomic_t count; /* Reference count */ + struct kref kref; /* Reference count */ struct rpc_xprt_ops * ops; /* transport methods */ const struct rpc_timeout *timeout; /* timeout parms */ @@ -318,24 +319,13 @@ int xprt_adjust_timeout(struct rpc_rqst *req); void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task); void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); void xprt_release(struct rpc_task *task); +struct rpc_xprt * xprt_get(struct rpc_xprt *xprt); void xprt_put(struct rpc_xprt *xprt); struct rpc_xprt * xprt_alloc(struct net *net, size_t size, unsigned int num_prealloc, unsigned int max_req); void xprt_free(struct rpc_xprt *); -/** - * xprt_get - return a reference to an RPC transport. - * @xprt: pointer to the transport - * - */ -static inline struct rpc_xprt *xprt_get(struct rpc_xprt *xprt) -{ - if (atomic_inc_not_zero(&xprt->count)) - return xprt; - return NULL; -} - static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p) { return p + xprt->tsh_size; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 37edea6fa92d..d8fd84c0cbba 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1307,7 +1307,7 @@ void xprt_release(struct rpc_task *task) static void xprt_init(struct rpc_xprt *xprt, struct net *net) { - atomic_set(&xprt->count, 1); + kref_init(&xprt->kref); spin_lock_init(&xprt->transport_lock); spin_lock_init(&xprt->reserve_lock); @@ -1415,6 +1415,24 @@ static void xprt_destroy(struct rpc_xprt *xprt) xprt->ops->destroy(xprt); } +static void xprt_destroy_kref(struct kref *kref) +{ + xprt_destroy(container_of(kref, struct rpc_xprt, kref)); +} + +/** + * xprt_get - return a reference to an RPC transport. + * @xprt: pointer to the transport + * + */ +struct rpc_xprt *xprt_get(struct rpc_xprt *xprt) +{ + if (xprt != NULL && kref_get_unless_zero(&xprt->kref)) + return xprt; + return NULL; +} +EXPORT_SYMBOL_GPL(xprt_get); + /** * xprt_put - release a reference to an RPC transport. * @xprt: pointer to the transport @@ -1422,7 +1440,7 @@ static void xprt_destroy(struct rpc_xprt *xprt) */ void xprt_put(struct rpc_xprt *xprt) { - if (atomic_dec_and_test(&xprt->count)) - xprt_destroy(xprt); + if (xprt != NULL) + kref_put(&xprt->kref, xprt_destroy_kref); } EXPORT_SYMBOL_GPL(xprt_put); -- GitLab From fda1bfef9e465b28260d27cd9e538dd601c4cdc1 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Feb 2015 17:48:49 -0500 Subject: [PATCH 0584/5324] SUNRPC: Make freeing of struct xprt rcu-safe Have it call kfree_rcu() to ensure that we can use it on rcu-protected lists. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprt.h | 1 + net/sunrpc/xprt.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 1bdb59a2efe8..83218129ff28 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -257,6 +257,7 @@ struct rpc_xprt { struct dentry *debugfs; /* debugfs directory */ atomic_t inject_disconnect; #endif + struct rcu_head rcu; }; #if defined(CONFIG_SUNRPC_BACKCHANNEL) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index d8fd84c0cbba..605858699f6c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -1166,7 +1167,7 @@ void xprt_free(struct rpc_xprt *xprt) { put_net(xprt->xprt_net); xprt_free_all_slots(xprt); - kfree(xprt); + kfree_rcu(xprt, rcu); } EXPORT_SYMBOL_GPL(xprt_free); -- GitLab From cc8ed76938b5cf6a54ab3d60edabaf808dc960d1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 22 Jan 2016 13:39:25 +0100 Subject: [PATCH 0585/5324] soc: mediatek: SCPSYS: Fix double enabling of regulators With CONFIG_PM enabled do not call genpd->power_on manually as this will cause the regulators being turned on once in SCPSYS probe and then again when the genpd core turns on the domains. Instead, call genpd->power_on only with CONFIG_PM disabled and tell the genpd core that the domains are disabled when registered. Signed-off-by: Sascha Hauer Tested-by: Daniel Kurtz Reviewed-by: Daniel Kurtz Signed-off-by: Matthias Brugger --- drivers/soc/mediatek/mtk-scpsys.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 837effe19907..57e781c71e67 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -491,14 +491,13 @@ static int scpsys_probe(struct platform_device *pdev) genpd->dev_ops.active_wakeup = scpsys_active_wakeup; /* - * Initially turn on all domains to make the domains usable - * with !CONFIG_PM and to get the hardware in sync with the - * software. The unused domains will be switched off during - * late_init time. + * With CONFIG_PM disabled turn on all domains to make the + * hardware usable. */ - genpd->power_on(genpd); + if (!IS_ENABLED(CONFIG_PM)) + genpd->power_on(genpd); - pm_genpd_init(genpd, NULL, false); + pm_genpd_init(genpd, NULL, true); } /* -- GitLab From 42f9d3c6888bceef6dc7ba72c77acf47347dcf05 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 25 Jan 2016 09:45:47 -0700 Subject: [PATCH 0586/5324] scripts/kconfig: allow building with make 3.80 again Documentation/Changes still lists this as the minimal required version, so it ought to remain usable for the time being. Fixes: d2036f30cf ("scripts/kconfig/Makefile: Allow KBUILD_DEFCONFIG to be a target") Signed-off-by: Jan Beulich Cc: Michael Ellerman Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index d79cba4ce3eb..ebced77deb9c 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -96,13 +96,15 @@ savedefconfig: $(obj)/conf defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) $< $(silent) --defconfig $(Kconfig) -else ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) +else +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),) @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) else @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'" $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG) endif +endif %_defconfig: $(obj)/conf $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) -- GitLab From 6b87b70c5339f30e3c5b32085e69625906513dc2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 14 Jan 2016 18:13:49 +0000 Subject: [PATCH 0587/5324] unbreak allmodconfig KCONFIG_ALLCONFIG=... Prior to 3.13 make allmodconfig KCONFIG_ALLCONFIG=/dev/null used to be equivalent to make allmodconfig; these days it hardwires MODULES to n. In fact, any KCONFIG_ALLCONFIG that doesn't set MODULES explicitly is treated as if it set it to n. Regression had been introduced by commit cfa98f ("kconfig: do not override symbols already set"); what happens is that conf_read_simple() does sym_calc_value(modules_sym) on exit, which leaves SYMBOL_VALID set and has conf_set_all_new_symbols() skip modules_sym. It's pretty easy to fix - simply move that call of sym_calc_value() into the callers, except for the ones in KCONFIG_ALLCONFIG handling. Objections? Signed-off-by: Al Viro Fixes: cfa98f2e0ae9 ("kconfig: do not override symbols already set") Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 0b7dc2fd7bac..dd243d2abd87 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -267,10 +267,8 @@ int conf_read_simple(const char *name, int def) if (in) goto load; sym_add_change_count(1); - if (!sym_defconfig_list) { - sym_calc_value(modules_sym); + if (!sym_defconfig_list) return 1; - } for_all_defaults(sym_defconfig_list, prop) { if (expr_calc_value(prop->visible.expr) == no || @@ -403,7 +401,6 @@ int conf_read_simple(const char *name, int def) } free(line); fclose(in); - sym_calc_value(modules_sym); return 0; } @@ -414,8 +411,12 @@ int conf_read(const char *name) sym_set_change_count(0); - if (conf_read_simple(name, S_DEF_USER)) + if (conf_read_simple(name, S_DEF_USER)) { + sym_calc_value(modules_sym); return 1; + } + + sym_calc_value(modules_sym); for_all_symbols(i, sym) { sym_calc_value(sym); @@ -846,6 +847,7 @@ static int conf_split_config(void) name = conf_get_autoconfig_name(); conf_read_simple(name, S_DEF_AUTO); + sym_calc_value(modules_sym); if (chdir("include/config")) return 1; -- GitLab From a41c8882592fb80458959b10e37632ce030b68ca Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 28 Jan 2016 15:19:23 -0800 Subject: [PATCH 0588/5324] drm/i915/skl: Fix DMC load on Skylake J0 and K0 The driver does not load firmware for unknown steppings, so these new steppings must be added to the list. Cc: Rodrigo Vivi Signed-off-by: Mat Martineau Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1454023163-25469-1-git-send-email-mathew.j.martineau@linux.intel.com --- drivers/gpu/drm/i915/intel_csr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 5c2f9a40c81b..2a7ec3141c8d 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -179,7 +179,8 @@ static const struct stepping_info kbl_stepping_info[] = { static const struct stepping_info skl_stepping_info[] = { {'A', '0'}, {'B', '0'}, {'C', '0'}, {'D', '0'}, {'E', '0'}, {'F', '0'}, - {'G', '0'}, {'H', '0'}, {'I', '0'} + {'G', '0'}, {'H', '0'}, {'I', '0'}, + {'J', '0'}, {'K', '0'} }; static const struct stepping_info bxt_stepping_info[] = { -- GitLab From e5003b2f6a7554713a84401d1f6ac546ab5a110d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 1 Feb 2016 12:01:51 -0500 Subject: [PATCH 0589/5324] NFSv4.x: Fix NFS4ERR_RETRY_UNCACHED_REP in nfs4_callback_sequence We need to initialize cb_sequenceres information when reporting a NFS4ERR_RETRY_UNCACHED_REP error, since that will apply to the next operation, not to the CB_SEQUENCE itself. Reported-by: Kinglong Mee Signed-off-by: Trond Myklebust --- fs/nfs/callback_proc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index efd079d28946..618ced381a14 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -464,6 +464,12 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, tbl = &clp->cl_session->bc_slot_table; slot = tbl->slots + args->csa_slotid; + /* Set up res before grabbing the spinlock */ + memcpy(&res->csr_sessionid, &args->csa_sessionid, + sizeof(res->csr_sessionid)); + res->csr_sequenceid = args->csa_sequenceid; + res->csr_slotid = args->csa_slotid; + spin_lock(&tbl->slot_tbl_lock); /* state manager is resetting the session */ if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { @@ -480,6 +486,10 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, slot = nfs4_lookup_slot(tbl, args->csa_slotid); if (IS_ERR(slot)) goto out_unlock; + + res->csr_highestslotid = tbl->server_highest_slotid; + res->csr_target_highestslotid = tbl->target_highest_slotid; + status = validate_seqid(tbl, slot, args); if (status) goto out_unlock; @@ -489,13 +499,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, } cps->slot = slot; - memcpy(&res->csr_sessionid, &args->csa_sessionid, - sizeof(res->csr_sessionid)); - res->csr_sequenceid = args->csa_sequenceid; - res->csr_slotid = args->csa_slotid; - res->csr_highestslotid = tbl->server_highest_slotid; - res->csr_target_highestslotid = tbl->target_highest_slotid; - /* The ca_maxresponsesize_cached is 0 with no DRC */ if (args->csa_cachethis != 0) return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); -- GitLab From a5b3a80b899bda0f456f1246c4c5a1191ea01519 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 1 Feb 2016 16:43:04 +0000 Subject: [PATCH 0590/5324] CacheFiles: Provide read-and-reset release counters for cachefilesd Provide read-and-reset objects- and blocks-released counters for cachefilesd to use to work out whether there's anything new that can be culled. One of the problems cachefilesd has is that if all the objects in the cache are pinned by inodes lying dormant in the kernel inode cache, there isn't anything for it to cull. In such a case, it just spins around walking the filesystem tree and scanning for something to cull. This eats up a lot of CPU time. By telling cachefilesd if there have been any releases, the daemon can sleep until there is the possibility of something to do. cachefilesd finds this information by the following means: (1) When the control fd is read, the kernel presents a list of values of interest. "freleased=N" and "breleased=N" are added to this list to indicate the number of files released and number of blocks released since the last read call. At this point the counters are reset. (2) POLLIN is signalled if the number of files released becomes greater than 0. Note that by 'released' it just means that the kernel has released its interest in those files for the moment, not necessarily that the files should be deleted from the cache. Signed-off-by: David Howells Reviewed-by: Steve Dickson Signed-off-by: Al Viro --- fs/cachefiles/daemon.c | 13 ++++++++++--- fs/cachefiles/interface.c | 11 ++--------- fs/cachefiles/internal.h | 4 ++++ fs/cachefiles/namei.c | 28 +++++++++++++++++++++++----- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 452e98dd7560..1ee54ffd3a24 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -162,6 +162,8 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, size_t buflen, loff_t *pos) { struct cachefiles_cache *cache = file->private_data; + unsigned long long b_released; + unsigned f_released; char buffer[256]; int n; @@ -174,6 +176,8 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, cachefiles_has_space(cache, 0, 0); /* summarise */ + f_released = atomic_xchg(&cache->f_released, 0); + b_released = atomic_long_xchg(&cache->b_released, 0); clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags); n = snprintf(buffer, sizeof(buffer), @@ -183,15 +187,18 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, " fstop=%llx" " brun=%llx" " bcull=%llx" - " bstop=%llx", + " bstop=%llx" + " freleased=%x" + " breleased=%llx", test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0', (unsigned long long) cache->frun, (unsigned long long) cache->fcull, (unsigned long long) cache->fstop, (unsigned long long) cache->brun, (unsigned long long) cache->bcull, - (unsigned long long) cache->bstop - ); + (unsigned long long) cache->bstop, + f_released, + b_released); if (n > buflen) return -EMSGSIZE; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 675a3332d72f..861d611b8c05 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -291,15 +291,8 @@ static void cachefiles_drop_object(struct fscache_object *_object) } /* note that the object is now inactive */ - if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { - write_lock(&cache->active_lock); - if (!test_and_clear_bit(CACHEFILES_OBJECT_ACTIVE, - &object->flags)) - BUG(); - rb_erase(&object->active_node, &cache->active_nodes); - wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); - write_unlock(&cache->active_lock); - } + if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) + cachefiles_mark_object_inactive(cache, object); dput(object->dentry); object->dentry = NULL; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 9c4b737a54df..2fcde1a34b7c 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -66,6 +66,8 @@ struct cachefiles_cache { struct rb_root active_nodes; /* active nodes (can't be culled) */ rwlock_t active_lock; /* lock for active_nodes */ atomic_t gravecounter; /* graveyard uniquifier */ + atomic_t f_released; /* number of objects released lately */ + atomic_long_t b_released; /* number of blocks released lately */ unsigned frun_percent; /* when to stop culling (% files) */ unsigned fcull_percent; /* when to start culling (% files) */ unsigned fstop_percent; /* when to stop allocating (% files) */ @@ -157,6 +159,8 @@ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type); /* * namei.c */ +extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, + struct cachefiles_object *object); extern int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object); extern int cachefiles_walk_to_object(struct cachefiles_object *parent, diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 1c2334c163dd..4ae75006e73b 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -257,6 +257,28 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache, return -ETIMEDOUT; } +/* + * Mark an object as being inactive. + */ +void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, + struct cachefiles_object *object) +{ + write_lock(&cache->active_lock); + rb_erase(&object->active_node, &cache->active_nodes); + clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); + write_unlock(&cache->active_lock); + + wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); + + /* This object can now be culled, so we need to let the daemon know + * that there is something it can remove if it needs to. + */ + atomic_long_add(d_backing_inode(object->dentry)->i_blocks, + &cache->b_released); + if (atomic_inc_return(&cache->f_released)) + cachefiles_state_changed(cache); +} + /* * delete an object representation from the cache * - file backed objects are unlinked @@ -684,11 +706,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, check_error: _debug("check error %d", ret); - write_lock(&cache->active_lock); - rb_erase(&object->active_node, &cache->active_nodes); - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); - wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); - write_unlock(&cache->active_lock); + cachefiles_mark_object_inactive(cache, object); release_dentry: dput(object->dentry); object->dentry = NULL; -- GitLab From 02c3b0bd69a537557484e46a5937874a2d2ad454 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 25 Jan 2016 23:24:20 +0100 Subject: [PATCH 0591/5324] mtd: cs553x: Fix dependencies for !HAS_IOMEM archs Not every arch has io memory nor can this driver ever work on UML/i386. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger Signed-off-by: Brian Norris --- drivers/mtd/nand/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 545d82b100b6..b253654140d0 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -311,6 +311,7 @@ config MTD_NAND_CAFE config MTD_NAND_CS553X tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" depends on X86_32 + depends on !UML && HAS_IOMEM help The CS553x companion chips for the AMD Geode processor include NAND flash controllers with built-in hardware ECC -- GitLab From 26d072e36c732e6fe7eebdceb5e0497ddf256ded Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Mon, 25 Jan 2016 21:29:45 +0100 Subject: [PATCH 0592/5324] mtd: nand: pxa3xx_nand: add register access debug Add verbose debug for register accesses. This enables easier debugging by following where and how hardware is stimulated, and how it answers. Signed-off-by: Robert Jarzmik Acked-by: Ezequiel Garcia Signed-off-by: Brian Norris --- drivers/mtd/nand/pxa3xx_nand.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 86fc245dc71a..e42496adda8d 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -131,11 +131,23 @@ #define READ_ID_BYTES 7 /* macros for registers read/write */ -#define nand_writel(info, off, val) \ - writel_relaxed((val), (info)->mmio_base + (off)) - -#define nand_readl(info, off) \ - readl_relaxed((info)->mmio_base + (off)) +#define nand_writel(info, off, val) \ + do { \ + dev_vdbg(&info->pdev->dev, \ + "%s():%d nand_writel(0x%x, 0x%04x)\n", \ + __func__, __LINE__, (val), (off)); \ + writel_relaxed((val), (info)->mmio_base + (off)); \ + } while (0) + +#define nand_readl(info, off) \ + ({ \ + unsigned int _v; \ + _v = readl_relaxed((info)->mmio_base + (off)); \ + dev_vdbg(&info->pdev->dev, \ + "%s():%d nand_readl(0x%04x) = 0x%x\n", \ + __func__, __LINE__, (off), _v); \ + _v; \ + }) /* error code and state */ enum { -- GitLab From 2e78c927d79333f299a8ac81c2fd2952caeef335 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:53 +0530 Subject: [PATCH 0593/5324] Btrfs: __btrfs_buffered_write: Reserve/release extents aligned to block size Currently, the code reserves/releases extents in multiples of PAGE_CACHE_SIZE units. Fix this by doing reservation/releases in block size units. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 3 +++ fs/btrfs/file.c | 43 ++++++++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a9496644f47d..ffb3617fad98 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2353,6 +2353,9 @@ struct btrfs_map_token { unsigned long offset; }; +#define BTRFS_BYTES_TO_BLKS(fs_info, bytes) \ + ((bytes) >> (fs_info)->sb->s_blocksize_bits) + static inline void btrfs_init_map_token (struct btrfs_map_token *token) { token->kaddr = NULL; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index af782fdd4fca..9809557213d4 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -498,7 +498,7 @@ int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode, loff_t isize = i_size_read(inode); start_pos = pos & ~((u64)root->sectorsize - 1); - num_bytes = ALIGN(write_bytes + pos - start_pos, root->sectorsize); + num_bytes = round_up(write_bytes + pos - start_pos, root->sectorsize); end_of_last_block = start_pos + num_bytes - 1; err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, @@ -1379,16 +1379,19 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages, static noinline int lock_and_cleanup_extent_if_need(struct inode *inode, struct page **pages, size_t num_pages, loff_t pos, + size_t write_bytes, u64 *lockstart, u64 *lockend, struct extent_state **cached_state) { + struct btrfs_root *root = BTRFS_I(inode)->root; u64 start_pos; u64 last_pos; int i; int ret = 0; - start_pos = pos & ~((u64)PAGE_CACHE_SIZE - 1); - last_pos = start_pos + ((u64)num_pages << PAGE_CACHE_SHIFT) - 1; + start_pos = round_down(pos, root->sectorsize); + last_pos = start_pos + + round_up(pos + write_bytes - start_pos, root->sectorsize) - 1; if (start_pos < inode->i_size) { struct btrfs_ordered_extent *ordered; @@ -1503,6 +1506,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, while (iov_iter_count(i) > 0) { size_t offset = pos & (PAGE_CACHE_SIZE - 1); + size_t sector_offset; size_t write_bytes = min(iov_iter_count(i), nrptrs * (size_t)PAGE_CACHE_SIZE - offset); @@ -1511,6 +1515,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, size_t reserve_bytes; size_t dirty_pages; size_t copied; + size_t dirty_sectors; + size_t num_sectors; WARN_ON(num_pages > nrptrs); @@ -1523,7 +1529,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, break; } - reserve_bytes = num_pages << PAGE_CACHE_SHIFT; + sector_offset = pos & (root->sectorsize - 1); + reserve_bytes = round_up(write_bytes + sector_offset, + root->sectorsize); if (BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | BTRFS_INODE_PREALLOC)) { @@ -1542,7 +1550,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, */ num_pages = DIV_ROUND_UP(write_bytes + offset, PAGE_CACHE_SIZE); - reserve_bytes = num_pages << PAGE_CACHE_SHIFT; + reserve_bytes = round_up(write_bytes + + sector_offset, + root->sectorsize); goto reserve_metadata; } } @@ -1576,8 +1586,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, break; ret = lock_and_cleanup_extent_if_need(inode, pages, num_pages, - pos, &lockstart, &lockend, - &cached_state); + pos, write_bytes, &lockstart, + &lockend, &cached_state); if (ret < 0) { if (ret == -EAGAIN) goto again; @@ -1612,9 +1622,16 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, * we still have an outstanding extent for the chunk we actually * managed to copy. */ - if (num_pages > dirty_pages) { - release_bytes = (num_pages - dirty_pages) << - PAGE_CACHE_SHIFT; + num_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, + reserve_bytes); + dirty_sectors = round_up(copied + sector_offset, + root->sectorsize); + dirty_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, + dirty_sectors); + + if (num_sectors > dirty_sectors) { + release_bytes = (write_bytes - copied) + & ~((u64)root->sectorsize - 1); if (copied > 0) { spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; @@ -1633,7 +1650,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, } } - release_bytes = dirty_pages << PAGE_CACHE_SHIFT; + release_bytes = round_up(copied + sector_offset, + root->sectorsize); if (copied > 0) ret = btrfs_dirty_pages(root, inode, pages, @@ -1654,8 +1672,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (only_release_metadata && copied > 0) { lockstart = round_down(pos, root->sectorsize); - lockend = lockstart + - (dirty_pages << PAGE_CACHE_SHIFT) - 1; + lockend = round_up(pos + copied, root->sectorsize) - 1; set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, EXTENT_NORESERVE, NULL, -- GitLab From c40a3d38aff4e1c832d1692850621be7d5e5308c Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:54 +0530 Subject: [PATCH 0594/5324] Btrfs: Compute and look up csums based on sectorsized blocks Checksums are applicable to sectorsize units. The current code uses bio->bv_len units to compute and look up checksums. This works on machines where sectorsize == PAGE_SIZE. This patch makes the checksum computation and look up code to work with sectorsize units. Reviewed-by: Liu Bo Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/file-item.c | 92 ++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 33 deletions(-) diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index a67e1c828d0f..1c50a7b09b4e 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -172,6 +172,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, u64 item_start_offset = 0; u64 item_last_offset = 0; u64 disk_bytenr; + u64 page_bytes_left; u32 diff; int nblocks; int bio_index = 0; @@ -220,6 +221,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, disk_bytenr = (u64)bio->bi_iter.bi_sector << 9; if (dio) offset = logical_offset; + + page_bytes_left = bvec->bv_len; while (bio_index < bio->bi_vcnt) { if (!dio) offset = page_offset(bvec->bv_page) + bvec->bv_offset; @@ -243,7 +246,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, if (BTRFS_I(inode)->root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) { set_extent_bits(io_tree, offset, - offset + bvec->bv_len - 1, + offset + root->sectorsize - 1, EXTENT_NODATASUM, GFP_NOFS); } else { btrfs_info(BTRFS_I(inode)->root->fs_info, @@ -281,11 +284,17 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, found: csum += count * csum_size; nblocks -= count; - bio_index += count; + while (count--) { - disk_bytenr += bvec->bv_len; - offset += bvec->bv_len; - bvec++; + disk_bytenr += root->sectorsize; + offset += root->sectorsize; + page_bytes_left -= root->sectorsize; + if (!page_bytes_left) { + bio_index++; + bvec++; + page_bytes_left = bvec->bv_len; + } + } } btrfs_free_path(path); @@ -432,6 +441,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, struct bio_vec *bvec = bio->bi_io_vec; int bio_index = 0; int index; + int nr_sectors; + int i; unsigned long total_bytes = 0; unsigned long this_sum_bytes = 0; u64 offset; @@ -459,41 +470,56 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, if (!contig) offset = page_offset(bvec->bv_page) + bvec->bv_offset; - if (offset >= ordered->file_offset + ordered->len || - offset < ordered->file_offset) { - unsigned long bytes_left; - sums->len = this_sum_bytes; - this_sum_bytes = 0; - btrfs_add_ordered_sum(inode, ordered, sums); - btrfs_put_ordered_extent(ordered); + data = kmap_atomic(bvec->bv_page); - bytes_left = bio->bi_iter.bi_size - total_bytes; + nr_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, + bvec->bv_len + root->sectorsize + - 1); + + for (i = 0; i < nr_sectors; i++) { + if (offset >= ordered->file_offset + ordered->len || + offset < ordered->file_offset) { + unsigned long bytes_left; + + kunmap_atomic(data); + sums->len = this_sum_bytes; + this_sum_bytes = 0; + btrfs_add_ordered_sum(inode, ordered, sums); + btrfs_put_ordered_extent(ordered); + + bytes_left = bio->bi_iter.bi_size - total_bytes; + + sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), + GFP_NOFS); + BUG_ON(!sums); /* -ENOMEM */ + sums->len = bytes_left; + ordered = btrfs_lookup_ordered_extent(inode, + offset); + ASSERT(ordered); /* Logic error */ + sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) + + total_bytes; + index = 0; + + data = kmap_atomic(bvec->bv_page); + } - sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), - GFP_NOFS); - BUG_ON(!sums); /* -ENOMEM */ - sums->len = bytes_left; - ordered = btrfs_lookup_ordered_extent(inode, offset); - BUG_ON(!ordered); /* Logic error */ - sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9) + - total_bytes; - index = 0; + sums->sums[index] = ~(u32)0; + sums->sums[index] + = btrfs_csum_data(data + bvec->bv_offset + + (i * root->sectorsize), + sums->sums[index], + root->sectorsize); + btrfs_csum_final(sums->sums[index], + (char *)(sums->sums + index)); + index++; + offset += root->sectorsize; + this_sum_bytes += root->sectorsize; + total_bytes += root->sectorsize; } - data = kmap_atomic(bvec->bv_page); - sums->sums[index] = ~(u32)0; - sums->sums[index] = btrfs_csum_data(data + bvec->bv_offset, - sums->sums[index], - bvec->bv_len); kunmap_atomic(data); - btrfs_csum_final(sums->sums[index], - (char *)(sums->sums + index)); bio_index++; - index++; - total_bytes += bvec->bv_len; - this_sum_bytes += bvec->bv_len; - offset += bvec->bv_len; bvec++; } this_sum_bytes = 0; -- GitLab From 2dabb3248453be9b81906dd028ec6979708de7be Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:55 +0530 Subject: [PATCH 0595/5324] Btrfs: Direct I/O read: Work on sectorsized blocks The direct I/O read's endio and corresponding repair functions work on page sized blocks. This commit adds the ability for direct I/O read to work on subpagesized blocks. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/inode.c | 98 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e4565456eb01..53c9dd1c0f28 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7751,9 +7751,9 @@ static int btrfs_check_dio_repairable(struct inode *inode, } static int dio_read_error(struct inode *inode, struct bio *failed_bio, - struct page *page, u64 start, u64 end, - int failed_mirror, bio_end_io_t *repair_endio, - void *repair_arg) + struct page *page, unsigned int pgoff, + u64 start, u64 end, int failed_mirror, + bio_end_io_t *repair_endio, void *repair_arg) { struct io_failure_record *failrec; struct bio *bio; @@ -7774,7 +7774,9 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, return -EIO; } - if (failed_bio->bi_vcnt > 1) + if ((failed_bio->bi_vcnt > 1) + || (failed_bio->bi_io_vec->bv_len + > BTRFS_I(inode)->root->sectorsize)) read_mode = READ_SYNC | REQ_FAILFAST_DEV; else read_mode = READ_SYNC; @@ -7782,7 +7784,7 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio, isector = start - btrfs_io_bio(failed_bio)->logical; isector >>= inode->i_sb->s_blocksize_bits; bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page, - 0, isector, repair_endio, repair_arg); + pgoff, isector, repair_endio, repair_arg); if (!bio) { free_io_failure(inode, failrec); return -EIO; @@ -7812,12 +7814,17 @@ struct btrfs_retry_complete { static void btrfs_retry_endio_nocsum(struct bio *bio) { struct btrfs_retry_complete *done = bio->bi_private; + struct inode *inode; struct bio_vec *bvec; int i; if (bio->bi_error) goto end; + ASSERT(bio->bi_vcnt == 1); + inode = bio->bi_io_vec->bv_page->mapping->host; + ASSERT(bio->bi_io_vec->bv_len == BTRFS_I(inode)->root->sectorsize); + done->uptodate = 1; bio_for_each_segment_all(bvec, bio, i) clean_io_failure(done->inode, done->start, bvec->bv_page, 0); @@ -7829,25 +7836,35 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) static int __btrfs_correct_data_nocsum(struct inode *inode, struct btrfs_io_bio *io_bio) { + struct btrfs_fs_info *fs_info; struct bio_vec *bvec; struct btrfs_retry_complete done; u64 start; + unsigned int pgoff; + u32 sectorsize; + int nr_sectors; int i; int ret; + fs_info = BTRFS_I(inode)->root->fs_info; + sectorsize = BTRFS_I(inode)->root->sectorsize; + start = io_bio->logical; done.inode = inode; bio_for_each_segment_all(bvec, &io_bio->bio, i) { -try_again: + nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len); + pgoff = bvec->bv_offset; + +next_block_or_try_again: done.uptodate = 0; done.start = start; init_completion(&done.done); - ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, start, - start + bvec->bv_len - 1, - io_bio->mirror_num, - btrfs_retry_endio_nocsum, &done); + ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, + pgoff, start, start + sectorsize - 1, + io_bio->mirror_num, + btrfs_retry_endio_nocsum, &done); if (ret) return ret; @@ -7855,10 +7872,15 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, if (!done.uptodate) { /* We might have another mirror, so try again */ - goto try_again; + goto next_block_or_try_again; } - start += bvec->bv_len; + start += sectorsize; + + if (nr_sectors--) { + pgoff += sectorsize; + goto next_block_or_try_again; + } } return 0; @@ -7868,7 +7890,9 @@ static void btrfs_retry_endio(struct bio *bio) { struct btrfs_retry_complete *done = bio->bi_private; struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); + struct inode *inode; struct bio_vec *bvec; + u64 start; int uptodate; int ret; int i; @@ -7877,13 +7901,20 @@ static void btrfs_retry_endio(struct bio *bio) goto end; uptodate = 1; + + start = done->start; + + ASSERT(bio->bi_vcnt == 1); + inode = bio->bi_io_vec->bv_page->mapping->host; + ASSERT(bio->bi_io_vec->bv_len == BTRFS_I(inode)->root->sectorsize); + bio_for_each_segment_all(bvec, bio, i) { ret = __readpage_endio_check(done->inode, io_bio, i, - bvec->bv_page, 0, - done->start, bvec->bv_len); + bvec->bv_page, bvec->bv_offset, + done->start, bvec->bv_len); if (!ret) clean_io_failure(done->inode, done->start, - bvec->bv_page, 0); + bvec->bv_page, bvec->bv_offset); else uptodate = 0; } @@ -7897,20 +7928,34 @@ static void btrfs_retry_endio(struct bio *bio) static int __btrfs_subio_endio_read(struct inode *inode, struct btrfs_io_bio *io_bio, int err) { + struct btrfs_fs_info *fs_info; struct bio_vec *bvec; struct btrfs_retry_complete done; u64 start; u64 offset = 0; + u32 sectorsize; + int nr_sectors; + unsigned int pgoff; + int csum_pos; int i; int ret; + fs_info = BTRFS_I(inode)->root->fs_info; + sectorsize = BTRFS_I(inode)->root->sectorsize; + err = 0; start = io_bio->logical; done.inode = inode; bio_for_each_segment_all(bvec, &io_bio->bio, i) { - ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page, - 0, start, bvec->bv_len); + nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec->bv_len); + + pgoff = bvec->bv_offset; +next_block: + csum_pos = BTRFS_BYTES_TO_BLKS(fs_info, offset); + ret = __readpage_endio_check(inode, io_bio, csum_pos, + bvec->bv_page, pgoff, start, + sectorsize); if (likely(!ret)) goto next; try_again: @@ -7918,10 +7963,10 @@ static int __btrfs_subio_endio_read(struct inode *inode, done.start = start; init_completion(&done.done); - ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, start, - start + bvec->bv_len - 1, - io_bio->mirror_num, - btrfs_retry_endio, &done); + ret = dio_read_error(inode, &io_bio->bio, bvec->bv_page, + pgoff, start, start + sectorsize - 1, + io_bio->mirror_num, + btrfs_retry_endio, &done); if (ret) { err = ret; goto next; @@ -7934,8 +7979,15 @@ static int __btrfs_subio_endio_read(struct inode *inode, goto try_again; } next: - offset += bvec->bv_len; - start += bvec->bv_len; + offset += sectorsize; + start += sectorsize; + + ASSERT(nr_sectors); + + if (--nr_sectors) { + pgoff += sectorsize; + goto next_block; + } } return err; -- GitLab From 9703fefe0b137bb4475187b5d82ec5823445616b Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:56 +0530 Subject: [PATCH 0596/5324] Btrfs: fallocate: Work with sectorsized blocks While at it, this commit changes btrfs_truncate_page() to truncate sectorsized blocks instead of pages. Hence the function has been renamed to btrfs_truncate_block(). Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 2 +- fs/btrfs/file.c | 44 +++++++++++++++++------------------ fs/btrfs/inode.c | 60 ++++++++++++++++++++++++++---------------------- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ffb3617fad98..42ab58250d9e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -4030,7 +4030,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *dir, u64 objectid, const char *name, int name_len); -int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, +int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, int front); int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9809557213d4..58bb29788f5f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2310,10 +2310,10 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) int ret = 0; int err = 0; unsigned int rsv_count; - bool same_page; + bool same_block; bool no_holes = btrfs_fs_incompat(root->fs_info, NO_HOLES); u64 ino_size; - bool truncated_page = false; + bool truncated_block = false; bool updated_inode = false; ret = btrfs_wait_ordered_range(inode, offset, len); @@ -2321,7 +2321,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) return ret; mutex_lock(&inode->i_mutex); - ino_size = round_up(inode->i_size, PAGE_CACHE_SIZE); + ino_size = round_up(inode->i_size, root->sectorsize); ret = find_first_non_hole(inode, &offset, &len); if (ret < 0) goto out_only_mutex; @@ -2334,31 +2334,30 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) lockstart = round_up(offset, BTRFS_I(inode)->root->sectorsize); lockend = round_down(offset + len, BTRFS_I(inode)->root->sectorsize) - 1; - same_page = ((offset >> PAGE_CACHE_SHIFT) == - ((offset + len - 1) >> PAGE_CACHE_SHIFT)); - + same_block = (BTRFS_BYTES_TO_BLKS(root->fs_info, offset)) + == (BTRFS_BYTES_TO_BLKS(root->fs_info, offset + len - 1)); /* - * We needn't truncate any page which is beyond the end of the file + * We needn't truncate any block which is beyond the end of the file * because we are sure there is no data there. */ /* - * Only do this if we are in the same page and we aren't doing the - * entire page. + * Only do this if we are in the same block and we aren't doing the + * entire block. */ - if (same_page && len < PAGE_CACHE_SIZE) { + if (same_block && len < root->sectorsize) { if (offset < ino_size) { - truncated_page = true; - ret = btrfs_truncate_page(inode, offset, len, 0); + truncated_block = true; + ret = btrfs_truncate_block(inode, offset, len, 0); } else { ret = 0; } goto out_only_mutex; } - /* zero back part of the first page */ + /* zero back part of the first block */ if (offset < ino_size) { - truncated_page = true; - ret = btrfs_truncate_page(inode, offset, 0, 0); + truncated_block = true; + ret = btrfs_truncate_block(inode, offset, 0, 0); if (ret) { mutex_unlock(&inode->i_mutex); return ret; @@ -2393,9 +2392,10 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) if (!ret) { /* zero the front end of the last page */ if (tail_start + tail_len < ino_size) { - truncated_page = true; - ret = btrfs_truncate_page(inode, - tail_start + tail_len, 0, 1); + truncated_block = true; + ret = btrfs_truncate_block(inode, + tail_start + tail_len, + 0, 1); if (ret) goto out_only_mutex; } @@ -2575,7 +2575,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, &cached_state, GFP_NOFS); out_only_mutex: - if (!updated_inode && truncated_page && !ret && !err) { + if (!updated_inode && truncated_block && !ret && !err) { /* * If we only end up zeroing part of a page, we still need to * update the inode item, so that all the time fields are @@ -2695,10 +2695,10 @@ static long btrfs_fallocate(struct file *file, int mode, } else if (offset + len > inode->i_size) { /* * If we are fallocating from the end of the file onward we - * need to zero out the end of the page if i_size lands in the - * middle of a page. + * need to zero out the end of the block if i_size lands in the + * middle of a block. */ - ret = btrfs_truncate_page(inode, inode->i_size, 0, 0); + ret = btrfs_truncate_block(inode, inode->i_size, 0, 0); if (ret) goto out; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 53c9dd1c0f28..0bfd7fb2e83c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4247,7 +4247,8 @@ static int truncate_inline_extent(struct inode *inode, * read the extent item from disk (data not in the page cache). */ btrfs_release_path(path); - return btrfs_truncate_page(inode, offset, page_end - offset, 0); + return btrfs_truncate_block(inode, offset, page_end - offset, + 0); } btrfs_set_file_extent_ram_bytes(leaf, fi, size); @@ -4600,17 +4601,17 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, } /* - * btrfs_truncate_page - read, zero a chunk and write a page + * btrfs_truncate_block - read, zero a chunk and write a block * @inode - inode that we're zeroing * @from - the offset to start zeroing * @len - the length to zero, 0 to zero the entire range respective to the * offset * @front - zero up to the offset instead of from the offset on * - * This will find the page for the "from" offset and cow the page and zero the + * This will find the block for the "from" offset and cow the block and zero the * part we want to zero. This is used with truncate and hole punching. */ -int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, +int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, int front) { struct address_space *mapping = inode->i_mapping; @@ -4621,18 +4622,19 @@ int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, char *kaddr; u32 blocksize = root->sectorsize; pgoff_t index = from >> PAGE_CACHE_SHIFT; - unsigned offset = from & (PAGE_CACHE_SIZE-1); + unsigned offset = from & (blocksize - 1); struct page *page; gfp_t mask = btrfs_alloc_write_mask(mapping); int ret = 0; - u64 page_start; - u64 page_end; + u64 block_start; + u64 block_end; if ((offset & (blocksize - 1)) == 0 && (!len || ((len & (blocksize - 1)) == 0))) goto out; + ret = btrfs_delalloc_reserve_space(inode, - round_down(from, PAGE_CACHE_SIZE), PAGE_CACHE_SIZE); + round_down(from, blocksize), blocksize); if (ret) goto out; @@ -4640,14 +4642,14 @@ int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, page = find_or_create_page(mapping, index, mask); if (!page) { btrfs_delalloc_release_space(inode, - round_down(from, PAGE_CACHE_SIZE), - PAGE_CACHE_SIZE); + round_down(from, blocksize), + blocksize); ret = -ENOMEM; goto out; } - page_start = page_offset(page); - page_end = page_start + PAGE_CACHE_SIZE - 1; + block_start = round_down(from, blocksize); + block_end = block_start + blocksize - 1; if (!PageUptodate(page)) { ret = btrfs_readpage(NULL, page); @@ -4664,12 +4666,12 @@ int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, } wait_on_page_writeback(page); - lock_extent_bits(io_tree, page_start, page_end, &cached_state); + lock_extent_bits(io_tree, block_start, block_end, &cached_state); set_page_extent_mapped(page); - ordered = btrfs_lookup_ordered_extent(inode, page_start); + ordered = btrfs_lookup_ordered_extent(inode, block_start); if (ordered) { - unlock_extent_cached(io_tree, page_start, page_end, + unlock_extent_cached(io_tree, block_start, block_end, &cached_state, GFP_NOFS); unlock_page(page); page_cache_release(page); @@ -4678,39 +4680,41 @@ int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len, goto again; } - clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, + clear_extent_bit(&BTRFS_I(inode)->io_tree, block_start, block_end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0, &cached_state, GFP_NOFS); - ret = btrfs_set_extent_delalloc(inode, page_start, page_end, + ret = btrfs_set_extent_delalloc(inode, block_start, block_end, &cached_state); if (ret) { - unlock_extent_cached(io_tree, page_start, page_end, + unlock_extent_cached(io_tree, block_start, block_end, &cached_state, GFP_NOFS); goto out_unlock; } - if (offset != PAGE_CACHE_SIZE) { + if (offset != blocksize) { if (!len) - len = PAGE_CACHE_SIZE - offset; + len = blocksize - offset; kaddr = kmap(page); if (front) - memset(kaddr, 0, offset); + memset(kaddr + (block_start - page_offset(page)), + 0, offset); else - memset(kaddr + offset, 0, len); + memset(kaddr + (block_start - page_offset(page)) + offset, + 0, len); flush_dcache_page(page); kunmap(page); } ClearPageChecked(page); set_page_dirty(page); - unlock_extent_cached(io_tree, page_start, page_end, &cached_state, + unlock_extent_cached(io_tree, block_start, block_end, &cached_state, GFP_NOFS); out_unlock: if (ret) - btrfs_delalloc_release_space(inode, page_start, - PAGE_CACHE_SIZE); + btrfs_delalloc_release_space(inode, block_start, + blocksize); unlock_page(page); page_cache_release(page); out: @@ -4781,11 +4785,11 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) int err = 0; /* - * If our size started in the middle of a page we need to zero out the - * rest of the page before we expand the i_size, otherwise we could + * If our size started in the middle of a block we need to zero out the + * rest of the block before we expand the i_size, otherwise we could * expose stale data. */ - err = btrfs_truncate_page(inode, oldsize, 0, 0); + err = btrfs_truncate_block(inode, oldsize, 0, 0); if (err) return err; -- GitLab From d0b7da88f6409c740435712b092a8e2c7d2a8f74 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:57 +0530 Subject: [PATCH 0597/5324] Btrfs: btrfs_page_mkwrite: Reserve space in sectorsized units In subpagesize-blocksize scenario, if i_size occurs in a block which is not the last block in the page, then the space to be reserved should be calculated appropriately. Reviewed-by: Liu Bo Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/inode.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0bfd7fb2e83c..ad27f5d1a4a1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8802,15 +8802,28 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) loff_t size; int ret; int reserved = 0; + u64 reserved_space; u64 page_start; u64 page_end; + u64 end; + + reserved_space = PAGE_CACHE_SIZE; sb_start_pagefault(inode->i_sb); page_start = page_offset(page); page_end = page_start + PAGE_CACHE_SIZE - 1; + end = page_end; + /* + * Reserving delalloc space after obtaining the page lock can lead to + * deadlock. For example, if a dirty page is locked by this function + * and the call to btrfs_delalloc_reserve_space() ends up triggering + * dirty page write out, then the btrfs_writepage() function could + * end up waiting indefinitely to get a lock on the page currently + * being processed by btrfs_page_mkwrite() function. + */ ret = btrfs_delalloc_reserve_space(inode, page_start, - PAGE_CACHE_SIZE); + reserved_space); if (!ret) { ret = file_update_time(vma->vm_file); reserved = 1; @@ -8844,7 +8857,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) * we can't set the delalloc bits if there are pending ordered * extents. Drop our locks and wait for them to finish */ - ordered = btrfs_lookup_ordered_extent(inode, page_start); + ordered = btrfs_lookup_ordered_range(inode, page_start, page_end); if (ordered) { unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS); @@ -8854,6 +8867,18 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) goto again; } + if (page->index == ((size - 1) >> PAGE_CACHE_SHIFT)) { + reserved_space = round_up(size - page_start, root->sectorsize); + if (reserved_space < PAGE_CACHE_SIZE) { + end = page_start + reserved_space - 1; + spin_lock(&BTRFS_I(inode)->lock); + BTRFS_I(inode)->outstanding_extents++; + spin_unlock(&BTRFS_I(inode)->lock); + btrfs_delalloc_release_space(inode, page_start, + PAGE_CACHE_SIZE - reserved_space); + } + } + /* * XXX - page_mkwrite gets called every time the page is dirtied, even * if it was already dirty, so for space accounting reasons we need to @@ -8861,12 +8886,12 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) * is probably a better way to do this, but for now keep consistent with * prepare_pages in the normal write path. */ - clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, + clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0, &cached_state, GFP_NOFS); - ret = btrfs_set_extent_delalloc(inode, page_start, page_end, + ret = btrfs_set_extent_delalloc(inode, page_start, end, &cached_state); if (ret) { unlock_extent_cached(io_tree, page_start, page_end, @@ -8905,7 +8930,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) } unlock_page(page); out: - btrfs_delalloc_release_space(inode, page_start, PAGE_CACHE_SIZE); + btrfs_delalloc_release_space(inode, page_start, reserved_space); out_noreserve: sb_end_pagefault(inode->i_sb); return ret; -- GitLab From dbfdb6d1b369b88253af1cd71723437d152b0b50 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:58 +0530 Subject: [PATCH 0598/5324] Btrfs: Search for all ordered extents that could span across a page In subpagesize-blocksize scenario it is not sufficient to search using the first byte of the page to make sure that there are no ordered extents present across the page. Fix this. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/extent_io.c | 3 ++- fs/btrfs/inode.c | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2e7c97a3f344..1b2073389dc2 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3186,7 +3186,8 @@ static int __extent_read_full_page(struct extent_io_tree *tree, while (1) { lock_extent(tree, start, end); - ordered = btrfs_lookup_ordered_extent(inode, start); + ordered = btrfs_lookup_ordered_range(inode, start, + PAGE_CACHE_SIZE); if (!ordered) break; unlock_extent(tree, start, end); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ad27f5d1a4a1..917ab6b6c277 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2002,7 +2002,8 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) if (PagePrivate2(page)) goto out; - ordered = btrfs_lookup_ordered_extent(inode, page_start); + ordered = btrfs_lookup_ordered_range(inode, page_start, + PAGE_CACHE_SIZE); if (ordered) { unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, &cached_state, GFP_NOFS); @@ -8683,6 +8684,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset, struct extent_state *cached_state = NULL; u64 page_start = page_offset(page); u64 page_end = page_start + PAGE_CACHE_SIZE - 1; + u64 start; + u64 end; int inode_evicting = inode->i_state & I_FREEING; /* @@ -8702,14 +8705,18 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset, if (!inode_evicting) lock_extent_bits(tree, page_start, page_end, &cached_state); - ordered = btrfs_lookup_ordered_extent(inode, page_start); +again: + start = page_start; + ordered = btrfs_lookup_ordered_range(inode, start, + page_end - start + 1); if (ordered) { + end = min(page_end, ordered->file_offset + ordered->len - 1); /* * IO on this page will never be started, so we need * to account for any ordered extents now */ if (!inode_evicting) - clear_extent_bit(tree, page_start, page_end, + clear_extent_bit(tree, start, end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 0, &cached_state, @@ -8726,22 +8733,26 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset, spin_lock_irq(&tree->lock); set_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags); - new_len = page_start - ordered->file_offset; + new_len = start - ordered->file_offset; if (new_len < ordered->truncated_len) ordered->truncated_len = new_len; spin_unlock_irq(&tree->lock); if (btrfs_dec_test_ordered_pending(inode, &ordered, - page_start, - PAGE_CACHE_SIZE, 1)) + start, + end - start + 1, 1)) btrfs_finish_ordered_io(ordered); } btrfs_put_ordered_extent(ordered); if (!inode_evicting) { cached_state = NULL; - lock_extent_bits(tree, page_start, page_end, + lock_extent_bits(tree, start, end, &cached_state); } + + start = end + 1; + if (start < page_end) + goto again; } /* -- GitLab From 298cfd368364912076fd84fbceb0df864da42a67 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:55:59 +0530 Subject: [PATCH 0599/5324] Btrfs: Use (eb->start, seq) as search key for tree modification log In subpagesize-blocksize a page can map multiple extent buffers and hence using (page index, seq) as the search key is incorrect. For example, searching through tree modification log tree can return an entry associated with the first extent buffer mapped by the page (if such an entry exists), when we are actually searching for entries associated with extent buffers that are mapped at position 2 or more in the page. Reviewed-by: Liu Bo Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/ctree.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 769e0ff1b4ce..f5ef7d171bb8 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -311,7 +311,7 @@ struct tree_mod_root { struct tree_mod_elem { struct rb_node node; - u64 index; /* shifted logical */ + u64 logical; u64 seq; enum mod_log_op op; @@ -435,11 +435,11 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, /* * key order of the log: - * index -> sequence + * node/leaf start address -> sequence * - * the index is the shifted logical of the *new* root node for root replace - * operations, or the shifted logical of the affected block for all other - * operations. + * The 'start address' is the logical address of the *new* root node + * for root replace operations, or the logical address of the affected + * block for all other operations. * * Note: must be called with write lock (tree_mod_log_write_lock). */ @@ -460,9 +460,9 @@ __tree_mod_log_insert(struct btrfs_fs_info *fs_info, struct tree_mod_elem *tm) while (*new) { cur = container_of(*new, struct tree_mod_elem, node); parent = *new; - if (cur->index < tm->index) + if (cur->logical < tm->logical) new = &((*new)->rb_left); - else if (cur->index > tm->index) + else if (cur->logical > tm->logical) new = &((*new)->rb_right); else if (cur->seq < tm->seq) new = &((*new)->rb_left); @@ -523,7 +523,7 @@ alloc_tree_mod_elem(struct extent_buffer *eb, int slot, if (!tm) return NULL; - tm->index = eb->start >> PAGE_CACHE_SHIFT; + tm->logical = eb->start; if (op != MOD_LOG_KEY_ADD) { btrfs_node_key(eb, &tm->key, slot); tm->blockptr = btrfs_node_blockptr(eb, slot); @@ -588,7 +588,7 @@ tree_mod_log_insert_move(struct btrfs_fs_info *fs_info, goto free_tms; } - tm->index = eb->start >> PAGE_CACHE_SHIFT; + tm->logical = eb->start; tm->slot = src_slot; tm->move.dst_slot = dst_slot; tm->move.nr_items = nr_items; @@ -699,7 +699,7 @@ tree_mod_log_insert_root(struct btrfs_fs_info *fs_info, goto free_tms; } - tm->index = new_root->start >> PAGE_CACHE_SHIFT; + tm->logical = new_root->start; tm->old_root.logical = old_root->start; tm->old_root.level = btrfs_header_level(old_root); tm->generation = btrfs_header_generation(old_root); @@ -739,16 +739,15 @@ __tree_mod_log_search(struct btrfs_fs_info *fs_info, u64 start, u64 min_seq, struct rb_node *node; struct tree_mod_elem *cur = NULL; struct tree_mod_elem *found = NULL; - u64 index = start >> PAGE_CACHE_SHIFT; tree_mod_log_read_lock(fs_info); tm_root = &fs_info->tree_mod_log; node = tm_root->rb_node; while (node) { cur = container_of(node, struct tree_mod_elem, node); - if (cur->index < index) { + if (cur->logical < start) { node = node->rb_left; - } else if (cur->index > index) { + } else if (cur->logical > start) { node = node->rb_right; } else if (cur->seq < min_seq) { node = node->rb_left; @@ -1230,9 +1229,10 @@ __tree_mod_log_oldest_root(struct btrfs_fs_info *fs_info, return NULL; /* - * the very last operation that's logged for a root is the replacement - * operation (if it is replaced at all). this has the index of the *new* - * root, making it the very first operation that's logged for this root. + * the very last operation that's logged for a root is the + * replacement operation (if it is replaced at all). this has + * the logical address of the *new* root, making it the very + * first operation that's logged for this root. */ while (1) { tm = tree_mod_log_search_oldest(fs_info, root_logical, @@ -1336,7 +1336,7 @@ __tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, if (!next) break; tm = container_of(next, struct tree_mod_elem, node); - if (tm->index != first_tm->index) + if (tm->logical != first_tm->logical) break; } tree_mod_log_read_unlock(fs_info); -- GitLab From 5f4dc8fc835bbb902f5c2aa3de3978f3f518aa73 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:56:00 +0530 Subject: [PATCH 0600/5324] Btrfs: btrfs_submit_direct_hook: Handle map_length < bio vector length In subpagesize-blocksize scenario, map_length can be less than the length of a bio vector. Such a condition may cause btrfs_submit_direct_hook() to submit a zero length bio. Fix this by comparing map_length against block size rather than with bv_len. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/inode.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 917ab6b6c277..9dd4fb4afce9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8244,9 +8244,11 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, u64 file_offset = dip->logical_offset; u64 submit_len = 0; u64 map_length; - int nr_pages = 0; - int ret; + u32 blocksize = root->sectorsize; int async_submit = 0; + int nr_sectors; + int ret; + int i; map_length = orig_bio->bi_iter.bi_size; ret = btrfs_map_block(root->fs_info, rw, start_sector << 9, @@ -8276,9 +8278,12 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, atomic_inc(&dip->pending_bios); while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { - if (map_length < submit_len + bvec->bv_len || - bio_add_page(bio, bvec->bv_page, bvec->bv_len, - bvec->bv_offset) < bvec->bv_len) { + nr_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info, bvec->bv_len); + i = 0; +next_block: + if (unlikely(map_length < submit_len + blocksize || + bio_add_page(bio, bvec->bv_page, blocksize, + bvec->bv_offset + (i * blocksize)) < blocksize)) { /* * inc the count before we submit the bio so * we know the end IO handler won't happen before @@ -8299,7 +8304,6 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, file_offset += submit_len; submit_len = 0; - nr_pages = 0; bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); @@ -8317,9 +8321,14 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, bio_put(bio); goto out_err; } + + goto next_block; } else { - submit_len += bvec->bv_len; - nr_pages++; + submit_len += blocksize; + if (--nr_sectors) { + i++; + goto next_block; + } bvec++; } } -- GitLab From 0c29ba993e4b08771deb20f8717a4b57cc7e678b Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:56:01 +0530 Subject: [PATCH 0601/5324] Btrfs: Limit inline extents to root->sectorsize cow_file_range_inline() limits the size of an inline extent to PAGE_CACHE_SIZE. This breaks in subpagesize-blocksize scenarios. Fix this by comparing against root->sectorsize. Reviewed-by: Josef Bacik Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9dd4fb4afce9..7cda82006de9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -263,7 +263,7 @@ static noinline int cow_file_range_inline(struct btrfs_root *root, data_len = compressed_size; if (start > 0 || - actual_end > PAGE_CACHE_SIZE || + actual_end > root->sectorsize || data_len > BTRFS_MAX_INLINE_DATA_SIZE(root) || (!compressed_size && (actual_end & (root->sectorsize - 1)) == 0) || -- GitLab From 5a2834f808fd71d056f810b832a5f8869420e3ea Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:56:02 +0530 Subject: [PATCH 0602/5324] Btrfs: Fix block size returned to user space btrfs_getattr() returns PAGE_CACHE_SIZE as the block size. Since generic_fillattr() already does the right thing (by obtaining block size from inode->i_blkbits), just remove the statement from btrfs_getattr. Reviewed-by: Josef Bacik Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7cda82006de9..8a7c68f1bcdf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9335,7 +9335,6 @@ static int btrfs_getattr(struct vfsmount *mnt, generic_fillattr(inode, stat); stat->dev = BTRFS_I(inode)->root->anon_dev; - stat->blksize = PAGE_CACHE_SIZE; spin_lock(&BTRFS_I(inode)->lock); delalloc_bytes = BTRFS_I(inode)->delalloc_bytes; -- GitLab From 27772b68f6994f0011690899c31717b7cbec51c9 Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:56:03 +0530 Subject: [PATCH 0603/5324] Btrfs: Clean pte corresponding to page straddling i_size When extending a file by either "truncate up" or by writing beyond i_size, the page which had i_size needs to be marked "read only" so that future writes to the page via mmap interface causes btrfs_page_mkwrite() to be invoked. If not, a write performed after extending the file via the mmap interface will find the page to be writaeable and continue writing to the page without invoking btrfs_page_mkwrite() i.e. we end up writing to a file without reserving disk space. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/file.c | 12 ++++++++++-- fs/btrfs/inode.c | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 58bb29788f5f..953f0ad17802 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1778,6 +1778,8 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, ssize_t err; loff_t pos; size_t count; + loff_t oldsize; + int clean_page = 0; mutex_lock(&inode->i_mutex); err = generic_write_checks(iocb, from); @@ -1816,14 +1818,17 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, pos = iocb->ki_pos; count = iov_iter_count(from); start_pos = round_down(pos, root->sectorsize); - if (start_pos > i_size_read(inode)) { + oldsize = i_size_read(inode); + if (start_pos > oldsize) { /* Expand hole size to cover write data, preventing empty gap */ end_pos = round_up(pos + count, root->sectorsize); - err = btrfs_cont_expand(inode, i_size_read(inode), end_pos); + err = btrfs_cont_expand(inode, oldsize, end_pos); if (err) { mutex_unlock(&inode->i_mutex); goto out; } + if (start_pos > round_up(oldsize, root->sectorsize)) + clean_page = 1; } if (sync) @@ -1835,6 +1840,9 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, num_written = __btrfs_buffered_write(file, from, pos); if (num_written > 0) iocb->ki_pos = pos + num_written; + if (clean_page) + pagecache_isize_extended(inode, oldsize, + i_size_read(inode)); } mutex_unlock(&inode->i_mutex); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8a7c68f1bcdf..7d4b2bf2f44f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4899,7 +4899,6 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) } if (newsize > oldsize) { - truncate_pagecache(inode, newsize); /* * Don't do an expanding truncate while snapshoting is ongoing. * This is to ensure the snapshot captures a fully consistent @@ -4922,6 +4921,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) i_size_write(inode, newsize); btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); + pagecache_isize_extended(inode, oldsize, newsize); ret = btrfs_update_inode(trans, root, inode); btrfs_end_write_no_snapshoting(root); btrfs_end_transaction(trans, root); -- GitLab From 65bfa6580791f8c01fbc9cd8bd73d92aea53723f Mon Sep 17 00:00:00 2001 From: Chandan Rajendra Date: Thu, 21 Jan 2016 15:56:04 +0530 Subject: [PATCH 0604/5324] Btrfs: btrfs_ioctl_clone: Truncate complete page after performing clone operation In subpagesize-blocksize scenario, the "destination offset" argument passed to the btrfs_ioctl_clone() can be aligned to sectorsize but may not be necessarily aligned to the machine's page size. In such cases, truncate_inode_pages_range() ends up zeroing out the partial page and future read operations will return incorrect data. Hence this commit explicitly rounds down the "destination offset" to the machine's page size. Signed-off-by: Chandan Rajendra Signed-off-by: David Sterba --- fs/btrfs/ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 83c9ad3f2621..709419c98ca5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3926,8 +3926,9 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, * Truncate page cache pages so that future reads will see the cloned * data immediately and not the previous data. */ - truncate_inode_pages_range(&inode->i_data, destoff, - PAGE_CACHE_ALIGN(destoff + len) - 1); + truncate_inode_pages_range(&inode->i_data, + round_down(destoff, PAGE_CACHE_SIZE), + round_up(destoff + len, PAGE_CACHE_SIZE) - 1); out_unlock: if (!same_inode) btrfs_double_inode_unlock(src, inode); -- GitLab From ed4eeba7338bb123090f1c8b208f64d8184a896d Mon Sep 17 00:00:00 2001 From: Raghav Dogra Date: Wed, 16 Dec 2015 16:11:31 +0530 Subject: [PATCH 0605/5324] driver/memory: Removal of deprecated NO_IRQ Replacing the NO_IRQ macro with 0. If there is no interrupt, returned value will be 0 regardless of what NO_IRQ is defined. Signed-off-by: Raghav Dogra Signed-off-by: Brian Norris --- drivers/memory/fsl_ifc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index acd1460cf787..2a691da8c1c7 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -260,7 +260,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) /* get the Controller level irq */ fsl_ifc_ctrl_dev->irq = irq_of_parse_and_map(dev->dev.of_node, 0); - if (fsl_ifc_ctrl_dev->irq == NO_IRQ) { + if (fsl_ifc_ctrl_dev->irq == 0) { dev_err(&dev->dev, "failed to get irq resource " "for IFC\n"); ret = -ENODEV; -- GitLab From dc9b5a0c631115118267255837ac9df682fb79d1 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 1 Feb 2016 12:02:06 -0800 Subject: [PATCH 0606/5324] drm/i915: PSR simplify port and link standby checks. Current code not just block link_standby for non DDI platforms but also block PSR from work on other ports B/C/D/E. So, besides change any behaviour let's just fix the mess a bit here and reuse HSW check to block the other ports and reduce the second if only to link stadnby request. Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_psr.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 9ccff3011523..3c80b86e45f8 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -304,8 +304,15 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) dev_priv->psr.source_ok = false; - if (IS_HASWELL(dev) && dig_port->port != PORT_A) { - DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n"); + /* + * HSW spec explicitly says PSR is tied to port A. + * BDW+ platforms with DDI implementation of PSR have different + * PSR registers per transcoder and we only implement transcoder EDP + * ones. Since by Display design transcoder EDP is tied to port A + * we can safely escape based on the port A. + */ + if (HAS_DDI(dev) && dig_port->port != PORT_A) { + DRM_DEBUG_KMS("PSR condition failed: Port not supported\n"); return false; } @@ -328,7 +335,7 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) } if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && - ((dev_priv->vbt.psr.full_link) || (dig_port->port != PORT_A))) { + dev_priv->vbt.psr.full_link) { DRM_DEBUG_KMS("PSR condition failed: Link Standby requested/needed but not supported on this platform\n"); return false; } -- GitLab From 60e5ffe329b090155ec860e2f31dc8d505ec7acd Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 1 Feb 2016 12:02:07 -0800 Subject: [PATCH 0607/5324] drm/i915: Add PSR main link standby support back Link standby support has been deprecated with 'commit 89251b177 ("drm/i915: PSR: deprecate link_standby support for core platforms.")' The reason for that is that main link in full off offers more power savings and on HSW and BDW implementations on source side had known bugs with link standby. However that same HSD report only mentions BDW and HSW and tells that a fix was going to new platforms. Since on Skylake link standby didn't cause the bad blank flickering screens seen on HSW and BDW let's respect VBT again for this and future platforms. Cc: Paulo Zanoni Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni --- drivers/gpu/drm/i915/i915_debugfs.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_psr.c | 26 +++++++++++++++++++------- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 863012a2602e..ec0c2a05eed6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2583,6 +2583,10 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) enabled = true; } } + + seq_printf(m, "Main link in standby mode: %s\n", + yesno(dev_priv->psr.link_standby)); + seq_printf(m, "HW Enabled & Active bit: %s", yesno(enabled)); if (!HAS_DDI(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c921ad8e15a7..65a2cd04bc8f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1007,6 +1007,7 @@ struct i915_psr { unsigned busy_frontbuffer_bits; bool psr2_support; bool aux_frame_sync; + bool link_standby; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 3c80b86e45f8..b99a105ae58b 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -225,7 +225,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); } - drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, DP_PSR_ENABLE); + if (dev_priv->psr.link_standby) + drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, + DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); + else + drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, + DP_PSR_ENABLE); } static void vlv_psr_enable_source(struct intel_dp *intel_dp) @@ -280,6 +285,9 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) if (IS_HASWELL(dev)) val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; + if (dev_priv->psr.link_standby) + val |= EDP_PSR_LINK_STANDBY; + I915_WRITE(EDP_PSR_CTL, val | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | @@ -334,12 +342,6 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) return false; } - if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && - dev_priv->vbt.psr.full_link) { - DRM_DEBUG_KMS("PSR condition failed: Link Standby requested/needed but not supported on this platform\n"); - return false; - } - dev_priv->psr.source_ok = true; return true; } @@ -770,6 +772,16 @@ void intel_psr_init(struct drm_device *dev) dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + /* HSW and BDW require workarounds that we don't implement. */ + dev_priv->psr.link_standby = false; + else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) + /* On VLV and CHV only standby mode is supported. */ + dev_priv->psr.link_standby = true; + else + /* For new platforms let's respect VBT back again */ + dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; + INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); mutex_init(&dev_priv->psr.lock); } -- GitLab From 65f61b426ddba160699fd64bf94f14eff339616c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Mon, 1 Feb 2016 12:02:08 -0800 Subject: [PATCH 0608/5324] drm/i915: Instrument PSR parameter for debuging with link standby x link off. Unfortunately we don't know all panels and platforms out there and we found internal prototypes without VBT proper set but where only link in standby worked well. So, before enable PSR by default let's instrument the PSR parameter in a way that we can identify different panels out there that might require or work better with link standby mode. It is also useful to say that for backward compatibility I'm not changing the meaning of this flag. So "0" still means disabled and "1" means enabled with full support and maximum power savings. v2: Use positive value instead of negative for different operation mode as suggested by Daniel. v3: As Paulo suggested use 2 to force link standby and 3 to force link fully on. Also split the link_standby introduction in a separated patch. v4: Use DRM_ERROR for link off request on platforms that don't support and Remove the quirk promise. Cc: Jani Nikula Cc: Paulo Zanoni Cc: Daniel Vetter Signed-off-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1454356928-19779-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/i915_params.c | 3 ++- drivers/gpu/drm/i915/intel_psr.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 8d90c256520a..8b9f36814165 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -127,7 +127,8 @@ MODULE_PARM_DESC(enable_execlists, "(-1=auto [default], 0=disabled, 1=enabled)"); module_param_named_unsafe(enable_psr, i915.enable_psr, int, 0600); -MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)"); +MODULE_PARM_DESC(enable_psr, "Enable PSR " + "(0=disabled [default], 1=enabled - link mode chosen per-platform, 2=force link-standby mode, 3=force link-off mode)"); module_param_named_unsafe(preliminary_hw_support, i915.preliminary_hw_support, int, 0600); MODULE_PARM_DESC(preliminary_hw_support, diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b99a105ae58b..4ab757947f15 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -329,6 +329,12 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) return false; } + if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) && + !dev_priv->psr.link_standby) { + DRM_ERROR("PSR condition failed: Link off requested but not supported on this platform\n"); + return false; + } + if (IS_HASWELL(dev) && I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) & S3D_ENABLE) { @@ -772,6 +778,7 @@ void intel_psr_init(struct drm_device *dev) dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; + /* Set link_standby x link_off defaults */ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) /* HSW and BDW require workarounds that we don't implement. */ dev_priv->psr.link_standby = false; @@ -782,6 +789,16 @@ void intel_psr_init(struct drm_device *dev) /* For new platforms let's respect VBT back again */ dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; + /* Override link_standby x link_off defaults */ + if (i915.enable_psr == 2 && !dev_priv->psr.link_standby) { + DRM_DEBUG_KMS("PSR: Forcing link standby\n"); + dev_priv->psr.link_standby = true; + } + if (i915.enable_psr == 3 && dev_priv->psr.link_standby) { + DRM_DEBUG_KMS("PSR: Forcing main link off\n"); + dev_priv->psr.link_standby = false; + } + INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); mutex_init(&dev_priv->psr.lock); } -- GitLab From ea7743e2719d34eacb4cb206ae227120029d06c6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:25 +0100 Subject: [PATCH 0609/5324] ARM: pxa: define clock registers as __iomem We should not dereference registers as pointers, so use readl/writel instead for these registers. The clock registers are accessed in multiple files, so we have to change them all at once. I stumbled over these registers while looking at something unrelated. There are in fact other registers with the same problem, but I did not try to address those at this point. Signed-off-by: Arnd Bergmann Acked-by: Stephen Boyd Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/gumstix.c | 6 ++-- arch/arm/mach-pxa/include/mach/pxa2xx-regs.h | 8 ++--- arch/arm/mach-pxa/include/mach/pxa3xx-regs.h | 2 +- arch/arm/mach-pxa/zeus.c | 2 +- drivers/clk/pxa/clk-pxa25x.c | 12 +++---- drivers/clk/pxa/clk-pxa27x.c | 34 ++++++++++---------- drivers/clk/pxa/clk-pxa3xx.c | 3 +- drivers/cpufreq/pxa2xx-cpufreq.c | 2 +- 8 files changed, 34 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 6815a9357774..9c5b2fb054f9 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -139,14 +139,14 @@ static void gumstix_setup_bt_clock(void) { int timeout = 500; - if (!(OSCC & OSCC_OOK)) + if (!(readl(OSCC) & OSCC_OOK)) pr_warn("32kHz clock was not on. Bootloader may need to be updated\n"); else return; - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); do { - if (OSCC & OSCC_OOK) + if (readl(OSCC) & OSCC_OOK) break; udelay(1); } while (--timeout); diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index f1dd62946b36..5537d5601d70 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h @@ -134,10 +134,10 @@ /* * PXA2xx specific Core clock definitions */ -#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ -#define CKEN __REG(0x41300004) /* Clock Enable Register */ -#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ +#define CCCR io_p2v(0x41300000) /* Core Clock Configuration Register */ +#define CCSR io_p2v(0x4130000C) /* Core Clock Status Register */ +#define CKEN io_p2v(0x41300004) /* Clock Enable Register */ +#define OSCC io_p2v(0x41300008) /* Oscillator Configuration Register */ #define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index f4d48d20754e..888bf7ade15a 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h @@ -18,7 +18,7 @@ /* * Oscillator Configuration Register (OSCC) */ -#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ +#define OSCC io_p2v(0x41350000) /* Oscillator Configuration Register */ #define OSCC_PEN (1 << 11) /* 13MHz POUT */ diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 515b7ddda8aa..3b94ecfb9426 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -910,7 +910,7 @@ static void __init zeus_map_io(void) PMCR = PSPR = 0; /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */ - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...). * float chip selects and PCMCIA */ diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c index b7747229db9a..a9353cd4ce17 100644 --- a/drivers/clk/pxa/clk-pxa25x.c +++ b/drivers/clk/pxa/clk-pxa25x.c @@ -84,7 +84,7 @@ unsigned int pxa25x_get_clk_frequency_khz(int info) static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long cccr = CCCR; + unsigned long cccr = readl(CCCR); unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; return parent_rate / m; @@ -99,7 +99,7 @@ PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; #define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \ bit, is_lp, flags) \ PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \ - is_lp, &CKEN, CKEN_ ## bit, flags) + is_lp, CKEN, CKEN_ ## bit, flags) #define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \ div_hp, bit, NULL, 0) @@ -112,10 +112,10 @@ PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; #define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, 0) + CKEN, CKEN_ ## bit, 0) #define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) static struct desc_clk_cken pxa25x_clocks[] __initdata = { PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0), @@ -162,7 +162,7 @@ MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core"); static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long cccr = CCCR; + unsigned long cccr = readl(CCCR); unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; return (parent_rate / n2) * 2; @@ -173,7 +173,7 @@ RATE_RO_OPS(clk_pxa25x_run, "run"); static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long clkcfg, cccr = CCCR; + unsigned long clkcfg, cccr = readl(CCCR); unsigned int l, m, n2, t; asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 5b82d30baf9f..fc2abf97edd7 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -85,7 +85,7 @@ unsigned int pxa27x_get_clk_frequency_khz(int info) bool pxa27x_is_ppll_disabled(void) { - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); return ccsr & (1 << CCCR_PPDIS_BIT); } @@ -93,7 +93,7 @@ bool pxa27x_is_ppll_disabled(void) #define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \ bit, is_lp, flags) \ PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \ - is_lp, &CKEN, CKEN_ ## bit, flags) + is_lp, CKEN, CKEN_ ## bit, flags) #define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \ div_hp, bit, pxa27x_is_ppll_disabled, 0) @@ -106,10 +106,10 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; #define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, 0) + CKEN, CKEN_ ## bit, 0) #define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) static struct desc_clk_cken pxa27x_clocks[] __initdata = { PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), @@ -151,7 +151,7 @@ static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw, unsigned long clkcfg; unsigned int t, ht; unsigned int l, L, n2, N; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); t = clkcfg & (1 << 0); @@ -171,8 +171,8 @@ static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, unsigned long parent_rate) { unsigned int l, osc_forced; - unsigned long ccsr = CCSR; - unsigned long cccr = CCCR; + unsigned long ccsr = readl(CCSR); + unsigned long cccr = readl(CCCR); l = ccsr & CCSR_L_MASK; osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); @@ -193,7 +193,7 @@ static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_lcd_base_get_parent(struct clk_hw *hw) { unsigned int osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -222,7 +222,7 @@ static unsigned long clk_pxa27x_core_get_rate(struct clk_hw *hw, { unsigned long clkcfg; unsigned int t, ht, b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); @@ -242,7 +242,7 @@ static u8 clk_pxa27x_core_get_parent(struct clk_hw *hw) { unsigned long clkcfg; unsigned int t, ht, b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -263,7 +263,7 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_core, "core"); static unsigned long clk_pxa27x_run_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); unsigned int n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; return (parent_rate / n2) * 2; @@ -285,7 +285,7 @@ static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, { unsigned long clkcfg; unsigned int b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); @@ -302,7 +302,7 @@ static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_system_bus_get_parent(struct clk_hw *hw) { unsigned int osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -318,8 +318,8 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, unsigned long parent_rate) { unsigned int a, l, osc_forced; - unsigned long cccr = CCCR; - unsigned long ccsr = CCSR; + unsigned long cccr = readl(CCCR); + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); a = cccr & (1 << CCCR_A_BIT); @@ -337,8 +337,8 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) { unsigned int osc_forced, a; - unsigned long cccr = CCCR; - unsigned long ccsr = CCSR; + unsigned long cccr = readl(CCCR); + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); a = cccr & (1 << CCCR_A_BIT); diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c index 4af4eed5f89f..ea679718601c 100644 --- a/drivers/clk/pxa/clk-pxa3xx.c +++ b/drivers/clk/pxa/clk-pxa3xx.c @@ -334,8 +334,7 @@ static void __init pxa3xx_base_clocks_init(void) clk_register_clk_pxa3xx_system_bus(); clk_register_clk_pxa3xx_ac97(); clk_register_clk_pxa3xx_smemc(); - clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0, - (void __iomem *)&OSCC, 11, 0, NULL); + clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0, OSCC, 11, 0, NULL); clkdev_pxa_register(CLK_OSTIMER, "OSTIMER0", NULL, clk_register_fixed_factor(NULL, "os-timer0", "osc_13mhz", 0, 1, 4)); diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 1d99c97defa9..efe3b215fd34 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -319,7 +319,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx) local_irq_save(flags); /* Set new the CCCR and prepare CCLKCFG */ - CCCR = pxa_freq_settings[idx].cccr; + writel(pxa_freq_settings[idx].cccr, CCCR); cclkcfg = pxa_freq_settings[idx].cclkcfg; asm volatile(" \n\ -- GitLab From 289873476efd0aeda64e84075285f04b0d1e8a89 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:26 +0100 Subject: [PATCH 0610/5324] ARM: pxa: mark spitz_card_pwr_ctrl as __maybe_unused This function is only used when CONFIG_PCMCIA is enabled, otherwise we get a harmless warning: arch/arm/mach-pxa/spitz.c:204:13: warning: 'spitz_card_pwr_ctrl' defined but not used [-Wunused-function] Marking it as __maybe_unused keeps the logic simple and avoids the warning on randconfig builds. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/spitz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 825f903ab77e..d9578bc49fdc 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -201,7 +201,7 @@ static void __init spitz_scoop_init(void) } /* Power control is shared with between one of the CF slots and SD */ -static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) +static void __maybe_unused spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) { unsigned short cpr; unsigned long flags; -- GitLab From 0a137a1a38c64dbd4c61df7a4f3bce4dc12beecd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:27 +0100 Subject: [PATCH 0611/5324] ARM: pxa: mark unused eseries code as __maybe_unused Two variables in eseries.c are used on multiple platforms, but are not referenced when those are all disabled: eseries.c:60:31: warning: 'e7xx_gpio_vbus' defined but not used [-Wunused-variable] eseries.c:129:20: warning: 'eseries_register_clks' defined but not used [-Wunused-function] Marking them __maybe_unused is the nicest way to ensure that we never get the warning or end up with missing symbols if we get it wrong. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/eseries.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 0b00b226f54b..e838b11fb8c7 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -57,7 +57,7 @@ struct gpio_vbus_mach_info e7xx_udc_info = { .gpio_pullup_inverted = 1 }; -static struct platform_device e7xx_gpio_vbus = { +static struct platform_device e7xx_gpio_vbus __maybe_unused = { .name = "gpio-vbus", .id = -1, .dev = { @@ -126,7 +126,7 @@ struct resource eseries_tmio_resources[] = { }; /* Some e-series hardware cannot control the 32K clock */ -static void __init eseries_register_clks(void) +static void __init __maybe_unused eseries_register_clks(void) { clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, CLK_IS_ROOT, 32768); } -- GitLab From 55e70147e789d0ded8c673acea292bb5a09eb974 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:28 +0100 Subject: [PATCH 0612/5324] ARM: pxa: don't select GPIO_SYSFS for MIOA701 GPIO_SYSFS is a common kernel functionality, not something that a board specific Kconfig should have to worry about. In MIOA701, we get a warning about the select when CONFIG_SYSFS is disabled: warning: (MACH_MIOA701) selects GPIO_SYSFS which has unmet direct dependencies (GPIOLIB && SYSFS) This just removes the select and instead enables the symbol in the defconfig file. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/configs/pxa_defconfig | 1 + arch/arm/mach-pxa/Kconfig | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 0cb724b5c639..dc5517eaf09f 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -378,6 +378,7 @@ CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY_DEBUG=y CONFIG_PDA_POWER=m CONFIG_BATTERY_SBS=m diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index f09683687963..01066cff16e4 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -297,7 +297,6 @@ config MACH_MAGICIAN config MACH_MIOA701 bool "Mitac Mio A701 Support" - select GPIO_SYSFS select IWMMXT select PXA27x help -- GitLab From 2f2028615924b953d9b00a06119c14c3dac9247e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:29 +0100 Subject: [PATCH 0613/5324] ARM: pxa: always select one of the two CPU types When all boards are disabled on PXA, we cannot build a kernel because no CPU gets selected: arch/arm/include/uapi/asm/swab.h:26:29: error: "__LINUX_ARM_ARCH__" is not defined [-Werror=undef] This is a bit annoying for compile-testing, so I'm adding a line that ensures that at all times, at least one of CPU_XSCALE or CPU_XSC3 is set and we can at least continue building. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4f799e567fc8..8e7f534e950d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -547,6 +547,7 @@ config ARCH_PXA select CLKSRC_PXA select CLKSRC_MMIO select CLKSRC_OF + select CPU_XSCALE if !CPU_XSC3 select GENERIC_CLOCKEVENTS select GPIO_PXA select HAVE_IDE -- GitLab From a9a54caed96561d01f1d923df61bd11b71df4b93 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:30 +0100 Subject: [PATCH 0614/5324] ARM: pxa: move extern declarations to pm.h When CONFIG_IWMMXT is disabled, we get a warning in pxa3xx.c: arch/arm/mach-pxa/pxa3xx.c: In function 'pxa3xx_cpu_pm_suspend': arch/arm/mach-pxa/pxa3xx.c:109:2: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement] It turns out that there is an 'extern' declaration in the middle of a function. For consistency, this moves the declaration and two others from the same file into pm.h. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/pm.h | 3 +++ arch/arm/mach-pxa/pxa3xx.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-pxa/pm.h b/arch/arm/mach-pxa/pm.h index 51558bcee999..3aab90d8d2b7 100644 --- a/arch/arm/mach-pxa/pm.h +++ b/arch/arm/mach-pxa/pm.h @@ -29,6 +29,9 @@ extern int pxa_pm_enter(suspend_state_t state); extern int pxa_pm_prepare(void); extern void pxa_pm_finish(void); +extern const char pm_enter_standby_start[], pm_enter_standby_end[]; +extern int pxa3xx_finish_suspend(unsigned long); + /* NOTE: this is for PM debugging on Lubbock, it's really a big * ugly, but let's keep the crap minimum here, instead of direct * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index a1c4c888f246..1ba62be65f7c 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -68,7 +68,6 @@ static unsigned long wakeup_src; */ static void pxa3xx_cpu_standby(unsigned int pwrmode) { - extern const char pm_enter_standby_start[], pm_enter_standby_end[]; void (*fn)(unsigned int) = (void __force *)(sram + 0x8000); memcpy_toio(sram + 0x8000, pm_enter_standby_start, @@ -106,8 +105,6 @@ static void pxa3xx_cpu_pm_suspend(void) asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); #endif - extern int pxa3xx_finish_suspend(unsigned long); - /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); CKENB |= 1 << (CKEN_HSIO2 & 0x1f); -- GitLab From 343c1cdbc81c0c7bef05380b10e5c880faf8fb4c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:31 +0100 Subject: [PATCH 0615/5324] ARM: pxa: fix building without IWMMXT When CONFIG_IWMMXT, the pxa3xx and pxa27x suspend/resume code emits some xscale specific instructions, which are rejected by the assembler, because gcc is built with -march=armv5 -mtune=xscale and passes that option to the assembler: /tmp/cciHumzr.s:553: Error: selected processor does not support ARM mode `mra r2,r3,acc0' /tmp/cciHumzr.s:605: Error: selected processor does not support ARM mode `mar acc0,r2,r3' make[3]: *** [arch/arm/mach-pxa/pxa3xx.o] Error 1 /tmp/cci5MUNu.s:326: Error: selected processor does not support ARM mode `mra r2,r3,acc0' /tmp/cci5MUNu.s:367: Error: selected processor does not support ARM mode `mar acc0,r2,r3' make[3]: *** [arch/arm/mach-pxa/pxa27x.o] Error 1 Overriding with -Wa,-march=xscale no longer works, so instead I'm adding an explict ".arch_extension" directive in all four inline assembly statements, which should work even if they end up in a different order in the assembly output. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/pxa27x.c | 6 ++++-- arch/arm/mach-pxa/pxa3xx.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 8dfd1755c659..49c735962148 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -132,7 +132,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif /* ensure voltage-change sequencer not initiated, which hangs */ @@ -151,7 +152,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: cpu_suspend(pwrmode, pxa27x_finish_suspend); #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif break; } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 1ba62be65f7c..126c265691f5 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -102,7 +102,8 @@ static void pxa3xx_cpu_pm_suspend(void) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ @@ -130,7 +131,8 @@ static void pxa3xx_cpu_pm_suspend(void) AD3ER = 0; #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif } -- GitLab From f29327d9086ea9126a8f320943fb8b7cc20f9dca Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 29 Jan 2016 15:06:32 +0100 Subject: [PATCH 0616/5324] ARM: pxa: don't select RFKILL if CONFIG_NET is disabled Bluetooth is only supported when network support is part of the kernel, so it is a bit pointless to build the tosa-bt support without networking. If we try anyway, we get a Kconfig warning: warning: (TOSA_BT && H1940BT) selects RFKILL which has unmet direct dependencies (NET) This adds a dependency on CONFIG_NET to avoid that case. Signed-off-by: Arnd Bergmann Signed-off-by: Robert Jarzmik --- arch/arm/mach-pxa/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 01066cff16e4..7ee4652b4c61 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -528,7 +528,7 @@ config MACH_TOSA config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" - depends on MACH_TOSA + depends on MACH_TOSA && NET select RFKILL help This is a simple driver that is able to control -- GitLab From 9480e085c3737e0638112fcce5cfeedb7909348c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 25 Jan 2016 20:31:15 +0900 Subject: [PATCH 0617/5324] ARM: bcm: use const and __initconst for smp_operations This newly added code missed the global fixup by commit 75305275a721 ("ARM: use const and __initconst for smp_operations"). So fix it now. Also, add missing "static" qualifier. Signed-off-by: Masahiro Yamada Reviewed-by: Ray Jui Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c index 575defcc53f9..cfae9c71fb74 100644 --- a/arch/arm/mach-bcm/platsmp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -283,7 +283,7 @@ static const struct smp_operations bcm_smp_ops __initconst = { CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); -struct smp_operations nsp_smp_ops __initdata = { +static const struct smp_operations nsp_smp_ops __initconst = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = nsp_boot_secondary, }; -- GitLab From d9e743408ecd468974cd233623ed19253fa2a7b0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:55 +0900 Subject: [PATCH 0618/5324] clk: remove unused first argument of __clk_init() The "struct device *dev" is not used at all in this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b4db67a446c8..4bb7d09dfcf2 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2304,13 +2304,12 @@ static inline void clk_debug_unregister(struct clk_core *core) /** * __clk_init - initialize the data structures in a struct clk - * @dev: device initializing this clk, placeholder for now * @clk: clk being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct device *dev, struct clk *clk_user) +static int __clk_init(struct clk *clk_user) { int i, ret = 0; struct clk_core *orphan; @@ -2593,7 +2592,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(dev, hw->clk); + ret = __clk_init(hw->clk); if (!ret) return hw->clk; -- GitLab From d35c80c248c7a97458b075225b1bf3e41c8a6d50 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:56 +0900 Subject: [PATCH 0619/5324] clk: change the argument of __clk_init() into pointer to clk_core The argument clk_user is used only for the clk_user->core. The rest of this function only takes care of clk_core. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4bb7d09dfcf2..b8cd6bbdbbc0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2303,25 +2303,22 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_init - initialize the data structures in a struct clk - * @clk: clk being initialized + * __clk_init - initialize the data structures in a struct clk_core + * @core: clk_core being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct clk *clk_user) +static int __clk_init(struct clk_core *core) { int i, ret = 0; struct clk_core *orphan; struct hlist_node *tmp2; - struct clk_core *core; unsigned long rate; - if (!clk_user) + if (!core) return -EINVAL; - core = clk_user->core; - clk_prepare_lock(); /* check to see if a clock with this name is already registered */ @@ -2592,7 +2589,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(hw->clk); + ret = __clk_init(core); if (!ret) return hw->clk; -- GitLab From be45ebf25fc8866675f4822c74c9d0eb3dd96103 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:57 +0900 Subject: [PATCH 0620/5324] clk: rename __clk_init() into __clk_core_init() Now this function takes clk_core as its argument. __clk_core_init() would be more suitable for the name of this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b8cd6bbdbbc0..e7701d6029b3 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2303,13 +2303,13 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_init - initialize the data structures in a struct clk_core + * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct clk_core *core) +static int __clk_core_init(struct clk_core *core) { int i, ret = 0; struct clk_core *orphan; @@ -2589,7 +2589,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(core); + ret = __clk_core_init(core); if (!ret) return hw->clk; -- GitLab From 027f942ce44131bc3a11aaae6dbb227f461845b6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:58 +0900 Subject: [PATCH 0621/5324] clk: remove unnecessary !core->parents conditional This if-block has been here since the introduction of the common clock framework. Now no clock drivers are statically initialized. core->parent is always NULL at this point. Drop the redundant check and the confusing comment. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e7701d6029b3..735828d55c00 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2366,11 +2366,8 @@ static int __clk_core_init(struct clk_core *core) * in to clk_init during early boot; thus any access to core->parents[] * must always check for a NULL pointer and try to populate it if * necessary. - * - * If core->parents is not NULL we skip this entire block. This allows - * for clock drivers to statically initialize core->parents. */ - if (core->num_parents > 1 && !core->parents) { + if (core->num_parents > 1) { core->parents = kcalloc(core->num_parents, sizeof(struct clk *), GFP_KERNEL); /* -- GitLab From 3a6e84545129913613dc1a97bbe8e4f2378696ee Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:59 +0900 Subject: [PATCH 0622/5324] clk: change sizeof(struct clk *) to sizeof(*core->parents) Now, the clock parent is not "struct clk *", but "struct clk_core *". Of course, the size of a pointer is always same, but strictly speaking, sizeof(struct clk *) should be sizeof(struct clk_core *) here. This mismatch happened when we split the structure into struct clk and struct clk_core. For the potential possibility of future renaming, sizeof(*core->parents) would be better. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 735828d55c00..f9cab0919bb4 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1069,7 +1069,7 @@ static int clk_fetch_parent_index(struct clk_core *core, if (!core->parents) { core->parents = kcalloc(core->num_parents, - sizeof(struct clk *), GFP_KERNEL); + sizeof(*core->parents), GFP_KERNEL); if (!core->parents) return -ENOMEM; } @@ -1720,7 +1720,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) if (!core->parents) core->parents = - kcalloc(core->num_parents, sizeof(struct clk *), + kcalloc(core->num_parents, sizeof(*core->parents), GFP_KERNEL); ret = clk_core_get_parent_by_index(core, index); @@ -2368,8 +2368,8 @@ static int __clk_core_init(struct clk_core *core) * necessary. */ if (core->num_parents > 1) { - core->parents = kcalloc(core->num_parents, sizeof(struct clk *), - GFP_KERNEL); + core->parents = kcalloc(core->num_parents, + sizeof(*core->parents), GFP_KERNEL); /* * clk_core_lookup returns NULL for parents that have not been * clk_init'd; thus any access to clk->parents[] must check -- GitLab From 176d11690ba2c8ad59f99734d692f19f451c408b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:00 +0900 Subject: [PATCH 0623/5324] clk: move core->parents allocation to clk_register() Currently, __clk_core_init() allows failure of the kcalloc() for the core->parents. So, clk_fetch_parent_index() and __clk_init_parent() also try to allocate core->parents in case it has not been allocated yet. Scattering memory allocation here and there makes things complicated. Like other clk_core members, allocate core->parents in clk_register() and let it fail in case of memory shortage. If we cannot allocate such a small piece of memory, the system is already insane. There is no point to postpone the memory allocation. Also, allocate core->parents regardless of core->num_parents. We want it even if core->num_parents == 1 because clk_fetch_parent_index() might be called against the clk_core with a single parent. If core->num_parents == 0, core->parents is set to ZERO_SIZE_PTR. It is harmless because no access happens to core->parents in such a case. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 51 ++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f9cab0919bb4..a92feedda592 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1067,13 +1067,6 @@ static int clk_fetch_parent_index(struct clk_core *core, { int i; - if (!core->parents) { - core->parents = kcalloc(core->num_parents, - sizeof(*core->parents), GFP_KERNEL); - if (!core->parents) - return -ENOMEM; - } - /* * find index of new parent clock using cached parent ptrs, * or if not yet cached, use string name comparison and cache @@ -1718,11 +1711,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) index = core->ops->get_parent(core->hw); - if (!core->parents) - core->parents = - kcalloc(core->num_parents, sizeof(*core->parents), - GFP_KERNEL); - ret = clk_core_get_parent_by_index(core, index); out: @@ -2361,26 +2349,15 @@ static int __clk_core_init(struct clk_core *core) __func__, core->name); /* - * Allocate an array of struct clk *'s to avoid unnecessary string - * look-ups of clk's possible parents. This can fail for clocks passed - * in to clk_init during early boot; thus any access to core->parents[] - * must always check for a NULL pointer and try to populate it if - * necessary. + * clk_core_lookup returns NULL for parents that have not been + * clk_init'd; thus any access to clk->parents[] must check + * for a NULL pointer. We can always perform lazy lookups for + * missing parents later on. */ - if (core->num_parents > 1) { - core->parents = kcalloc(core->num_parents, - sizeof(*core->parents), GFP_KERNEL); - /* - * clk_core_lookup returns NULL for parents that have not been - * clk_init'd; thus any access to clk->parents[] must check - * for a NULL pointer. We can always perform lazy lookups for - * missing parents later on. - */ - if (core->parents) - for (i = 0; i < core->num_parents; i++) - core->parents[i] = - clk_core_lookup(core->parent_names[i]); - } + if (core->parents) + for (i = 0; i < core->num_parents; i++) + core->parents[i] = + clk_core_lookup(core->parent_names[i]); core->parent = __clk_init_parent(core); @@ -2578,12 +2555,20 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) } } + /* avoid unnecessary string look-ups of clk_core's possible parents. */ + core->parents = kcalloc(core->num_parents, sizeof(*core->parents), + GFP_KERNEL); + if (!core->parents) { + ret = -ENOMEM; + goto fail_parents; + }; + INIT_HLIST_HEAD(&core->clks); hw->clk = __clk_create_clk(hw, NULL, NULL); if (IS_ERR(hw->clk)) { ret = PTR_ERR(hw->clk); - goto fail_parent_names_copy; + goto fail_parents; } ret = __clk_core_init(core); @@ -2593,6 +2578,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) __clk_free_clk(hw->clk); hw->clk = NULL; +fail_parents: + kfree(core->parents); fail_parent_names_copy: while (--i >= 0) kfree_const(core->parent_names[i]); -- GitLab From 88cfbef2acd38443c3eed780263b5f5e95a8dc1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:01 +0900 Subject: [PATCH 0624/5324] clk: simplify clk_core_get_parent_by_index() Drop the "if (!core->parents)" case and refactor the function a bit because core->parents is always allocated. (Strictly speaking, it is ZERO_SIZE_PTR if core->num_parents == 0, but such a case is omitted by the if-conditional above.) Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index a92feedda592..c2e993db0cfd 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, { if (!core || index >= core->num_parents) return NULL; - else if (!core->parents) - return clk_core_lookup(core->parent_names[index]); - else if (!core->parents[index]) - return core->parents[index] = - clk_core_lookup(core->parent_names[index]); - else - return core->parents[index]; + + if (!core->parents[index]) + core->parents[index] = + clk_core_lookup(core->parent_names[index]); + + return core->parents[index]; } struct clk_hw * -- GitLab From 3c436bf95a1df22fa501be7134bccd29f8387dfe Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:02 +0900 Subject: [PATCH 0625/5324] clk: drop the initial core->parents look-ups from __clk_core_init() The core->parents is a cache to save expensive clock parent look-ups. It will be filled as needed later. We do not have to do it here. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c2e993db0cfd..98c68e99d5f6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2347,17 +2347,6 @@ static int __clk_core_init(struct clk_core *core) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); - /* - * clk_core_lookup returns NULL for parents that have not been - * clk_init'd; thus any access to clk->parents[] must check - * for a NULL pointer. We can always perform lazy lookups for - * missing parents later on. - */ - if (core->parents) - for (i = 0; i < core->num_parents; i++) - core->parents[i] = - clk_core_lookup(core->parent_names[i]); - core->parent = __clk_init_parent(core); /* -- GitLab From c44fccb5f7b071d36cac3962799ba5a571429c28 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:03 +0900 Subject: [PATCH 0626/5324] clk: replace pr_warn() with pr_err() for fatal cases These three cases let clk_register() fail. They should be considered as error messages. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 98c68e99d5f6..09d84453ea3a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2320,22 +2320,22 @@ static int __clk_core_init(struct clk_core *core) if (core->ops->set_rate && !((core->ops->round_rate || core->ops->determine_rate) && core->ops->recalc_rate)) { - pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", - __func__, core->name); + pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_parent && !core->ops->get_parent) { - pr_warning("%s: %s must implement .get_parent & .set_parent\n", - __func__, core->name); + pr_err("%s: %s must implement .get_parent & .set_parent\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_rate_and_parent && !(core->ops->set_parent && core->ops->set_rate)) { - pr_warn("%s: %s must implement .set_parent & .set_rate\n", + pr_err("%s: %s must implement .set_parent & .set_rate\n", __func__, core->name); ret = -EINVAL; goto out; -- GitLab From c553138fbd1ee193a19101a36fb0814607ab4e7b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Jan 2016 17:59:35 +0100 Subject: [PATCH 0627/5324] ARM: imx: use endian-safe readl/readw/writel/writew Instead of __raw_*, define imx_* to *_relaxed and use those. Using imx_* was requested by Arnd because *_relaxed tends to indicate that the code was carefully reviewed to not require any synchronisation and otherwise be safe, which isn't the case here with the automatic conversion. The conversion itself was done using the following spatch (since that automatically adjusts the coding style unlike a simple search&replace). @@ expression E1, E2; @@ -__raw_writel(E1, E2) +imx_writel(E1, E2) @@ expression E1, E2; @@ -__raw_writew(E1, E2) +imx_writew(E1, E2) @@ expression E1; @@ -__raw_readl(E1) +imx_readl(E1) @@ expression E1; @@ -__raw_readw(E1) +imx_readw(E1) Signed-off-by: Johannes Berg Signed-off-by: Shawn Guo --- arch/arm/mach-imx/3ds_debugboard.c | 30 +++++++++++------------ arch/arm/mach-imx/avic.c | 30 +++++++++++------------ arch/arm/mach-imx/cpu-imx27.c | 3 +-- arch/arm/mach-imx/cpu-imx31.c | 2 +- arch/arm/mach-imx/cpu-imx35.c | 2 +- arch/arm/mach-imx/cpu.c | 16 ++++++------- arch/arm/mach-imx/epit.c | 22 ++++++++--------- arch/arm/mach-imx/iomux-imx31.c | 12 +++++----- arch/arm/mach-imx/iomux-v1.c | 4 ++-- arch/arm/mach-imx/iomux-v3.c | 6 ++--- arch/arm/mach-imx/mach-armadillo5x0.c | 4 ++-- arch/arm/mach-imx/mach-imx51.c | 5 ++-- arch/arm/mach-imx/mach-mx27ads.c | 6 ++--- arch/arm/mach-imx/mach-mx31ads.c | 16 ++++++------- arch/arm/mach-imx/mach-mx31moboard.c | 2 +- arch/arm/mach-imx/mach-qong.c | 6 ++--- arch/arm/mach-imx/mxc.h | 5 ++++ arch/arm/mach-imx/pm-imx27.c | 4 ++-- arch/arm/mach-imx/pm-imx3.c | 4 ++-- arch/arm/mach-imx/pm-imx5.c | 26 ++++++++++---------- arch/arm/mach-imx/system.c | 6 ++--- arch/arm/mach-imx/tzic.c | 34 +++++++++++++-------------- 22 files changed, 124 insertions(+), 121 deletions(-) diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c index 16496a071ecb..cda330c93d61 100644 --- a/arch/arm/mach-imx/3ds_debugboard.c +++ b/arch/arm/mach-imx/3ds_debugboard.c @@ -94,8 +94,8 @@ static void mxc_expio_irq_handler(struct irq_desc *desc) /* irq = gpio irq number */ desc->irq_data.chip->irq_mask(&desc->irq_data); - imr_val = __raw_readw(brd_io + INTR_MASK_REG); - int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + imr_val = imx_readw(brd_io + INTR_MASK_REG); + int_valid = imx_readw(brd_io + INTR_STATUS_REG) & ~imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -117,17 +117,17 @@ static void expio_mask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg |= (1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; - __raw_writew(1 << expio, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); + imx_writew(1 << expio, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); expio_mask_irq(d); } @@ -136,9 +136,9 @@ static void expio_unmask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg &= ~(1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static struct irq_chip expio_irq_chip = { @@ -162,9 +162,9 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) if (brd_io == NULL) return -ENOMEM; - if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || - (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || - (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + if ((imx_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (imx_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (imx_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { pr_info("3-Stack Debug board not detected\n"); iounmap(brd_io); brd_io = NULL; @@ -181,10 +181,10 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) gpio_direction_input(intr_gpio); /* disable the interrupt and clear the status */ - __raw_writew(0, brd_io + INTR_MASK_REG); - __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); - __raw_writew(0x1F, brd_io + INTR_MASK_REG); + imx_writew(0, brd_io + INTR_MASK_REG); + imx_writew(0xFFFF, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); + imx_writew(0x1F, brd_io + INTR_MASK_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 1a8932335b21..7fa176e792bd 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -66,12 +66,12 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; if (irq < AVIC_NUM_IRQS / 2) { - irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); + irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); } else { irq -= AVIC_NUM_IRQS / 2; - irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); + irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); } return 0; @@ -94,8 +94,8 @@ static void avic_irq_suspend(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); - __raw_writel(gc->wake_active, avic_base + ct->regs.mask); + avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); + imx_writel(gc->wake_active, avic_base + ct->regs.mask); } static void avic_irq_resume(struct irq_data *d) @@ -104,7 +104,7 @@ static void avic_irq_resume(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); + imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); } #else @@ -140,7 +140,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) u32 nivector; do { - nivector = __raw_readl(avic_base + AVIC_NIVECSR) >> 16; + nivector = imx_readl(avic_base + AVIC_NIVECSR) >> 16; if (nivector == 0xffff) break; @@ -164,16 +164,16 @@ void __init mxc_init_irq(void __iomem *irqbase) /* put the AVIC into the reset value with * all interrupts disabled */ - __raw_writel(0, avic_base + AVIC_INTCNTL); - __raw_writel(0x1f, avic_base + AVIC_NIMASK); + imx_writel(0, avic_base + AVIC_INTCNTL); + imx_writel(0x1f, avic_base + AVIC_NIMASK); /* disable all interrupts */ - __raw_writel(0, avic_base + AVIC_INTENABLEH); - __raw_writel(0, avic_base + AVIC_INTENABLEL); + imx_writel(0, avic_base + AVIC_INTENABLEH); + imx_writel(0, avic_base + AVIC_INTENABLEL); /* all IRQ no FIQ */ - __raw_writel(0, avic_base + AVIC_INTTYPEH); - __raw_writel(0, avic_base + AVIC_INTTYPEL); + imx_writel(0, avic_base + AVIC_INTTYPEH); + imx_writel(0, avic_base + AVIC_INTTYPEL); irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id()); WARN_ON(irq_base < 0); @@ -188,7 +188,7 @@ void __init mxc_init_irq(void __iomem *irqbase) /* Set default priority value (0) for all IRQ's */ for (i = 0; i < 8; i++) - __raw_writel(0, avic_base + AVIC_NIPRIORITY(i)); + imx_writel(0, avic_base + AVIC_NIPRIORITY(i)); set_handle_irq(avic_handle_irq); diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index fe8d36f7e30e..8d2ae4091465 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -39,8 +39,7 @@ static int mx27_read_cpu_rev(void) * the silicon revision very early we read it here to * avoid any further hooks */ - val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR - + SYS_CHIP_ID)); + val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index fde1860a2521..3daf1959a2f0 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -39,7 +39,7 @@ static int mx31_read_cpu_rev(void) u32 i, srev; /* read SREV register from IIM module */ - srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index ec3aaa098c17..8a54234df23b 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -20,7 +20,7 @@ static int mx35_read_cpu_rev(void) { u32 rev; - rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 5b0f752d5507..6a96b7cf468f 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -45,20 +45,20 @@ void __init imx_set_aips(void __iomem *base) * Set all MPROTx to be non-bufferable, trusted for R/W, * not forced to user-mode. */ - __raw_writel(0x77777777, base + 0x0); - __raw_writel(0x77777777, base + 0x4); + imx_writel(0x77777777, base + 0x0); + imx_writel(0x77777777, base + 0x4); /* * Set all OPACRx to be non-bufferable, to not require * supervisor privilege level for access, allow for * write access and untrusted master access. */ - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); + imx_writel(0x0, base + 0x40); + imx_writel(0x0, base + 0x44); + imx_writel(0x0, base + 0x48); + imx_writel(0x0, base + 0x4C); + reg = imx_readl(base + 0x50) & 0x00FFFFFF; + imx_writel(reg, base + 0x50); } void __init imx_aips_allow_unprivileged_access( diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c index 08ce20771bb3..fb9a73a57d00 100644 --- a/arch/arm/mach-imx/epit.c +++ b/arch/arm/mach-imx/epit.c @@ -64,23 +64,23 @@ static inline void epit_irq_disable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val &= ~EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static inline void epit_irq_enable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val |= EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static void epit_irq_acknowledge(void) { - __raw_writel(EPITSR_OCIF, timer_base + EPITSR); + imx_writel(EPITSR_OCIF, timer_base + EPITSR); } static int __init epit_clocksource_init(struct clk *timer_clk) @@ -98,9 +98,9 @@ static int epit_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + EPITCNR); + tcmp = imx_readl(timer_base + EPITCNR); - __raw_writel(tcmp - evt, timer_base + EPITCMPR); + imx_writel(tcmp - evt, timer_base + EPITCMPR); return 0; } @@ -213,11 +213,11 @@ void __init epit_timer_init(void __iomem *base, int irq) /* * Initialise to a known state (all timers off, and timing reset) */ - __raw_writel(0x0, timer_base + EPITCR); + imx_writel(0x0, timer_base + EPITCR); - __raw_writel(0xffffffff, timer_base + EPITLR); - __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, - timer_base + EPITCR); + imx_writel(0xffffffff, timer_base + EPITLR); + imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, + timer_base + EPITCR); /* init and register the timer to the framework */ epit_clocksource_init(timer_clk); diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index 0b5ba4bf572a..3982e91b2f3e 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -57,10 +57,10 @@ void mxc_iomux_mode(unsigned int pin_mode) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0xff << (field * 8)); l |= mode << (field * 8); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -82,10 +82,10 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0x1ff << (field * 10)); l |= config << (field * 10); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -163,12 +163,12 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) u32 l; spin_lock(&gpio_mux_lock); - l = __raw_readl(IOMUXGPR); + l = imx_readl(IOMUXGPR); if (en) l |= gp; else l &= ~gp; - __raw_writel(l, IOMUXGPR); + imx_writel(l, IOMUXGPR); spin_unlock(&gpio_mux_lock); } diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c index ecd543664644..7aa90c863ad9 100644 --- a/arch/arm/mach-imx/iomux-v1.c +++ b/arch/arm/mach-imx/iomux-v1.c @@ -38,12 +38,12 @@ static unsigned imx_iomuxv1_numports; static inline unsigned long imx_iomuxv1_readl(unsigned offset) { - return __raw_readl(imx_iomuxv1_baseaddr + offset); + return imx_readl(imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) { - __raw_writel(val, imx_iomuxv1_baseaddr + offset); + imx_writel(val, imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_rmwl(unsigned offset, diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c index a53b2e64f98d..ca59d5f2ec92 100644 --- a/arch/arm/mach-imx/iomux-v3.c +++ b/arch/arm/mach-imx/iomux-v3.c @@ -45,13 +45,13 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; if (mux_ctrl_ofs) - __raw_writel(mux_mode, base + mux_ctrl_ofs); + imx_writel(mux_mode, base + mux_ctrl_ofs); if (sel_input_ofs) - __raw_writel(sel_input, base + sel_input_ofs); + imx_writel(sel_input, base + sel_input_ofs); if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - __raw_writel(pad_ctrl, base + pad_ctrl_ofs); + imx_writel(pad_ctrl, base + pad_ctrl_ofs); return 0; } diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index f2060523ba48..eaee47a2fcc0 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -525,8 +525,8 @@ static void __init armadillo5x0_init(void) imx31_add_mxc_nand(&armadillo5x0_nand_board_info); /* set NAND page size to 2k if not configured via boot mode pins */ - __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) | - (1 << 30), mx3_ccm_base + MXC_CCM_RCSR); + imx_writel(imx_readl(mx3_ccm_base + MXC_CCM_RCSR) | (1 << 30), + mx3_ccm_base + MXC_CCM_RCSR); /* RTC */ /* Get RTC IRQ and register the chip */ diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c index b015129e4045..6883fbaf9484 100644 --- a/arch/arm/mach-imx/mach-imx51.c +++ b/arch/arm/mach-imx/mach-imx51.c @@ -40,11 +40,10 @@ static void __init imx51_ipu_mipi_setup(void) WARN_ON(!hsc_addr); /* setup MIPI module to legacy mode */ - __raw_writel(0xf00, hsc_addr); + imx_writel(0xf00, hsc_addr); /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */ - __raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff, - hsc_addr + 0x800); + imx_writel(imx_readl(hsc_addr + 0x800) | 0x30ff, hsc_addr + 0x800); iounmap(hsc_addr); } diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index eb1c3477c48a..267fad23b225 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -202,9 +202,9 @@ static struct i2c_board_info mx27ads_i2c_devices[] = { static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value) { if (value) - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); else - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); } static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) @@ -364,7 +364,7 @@ static void __init mx27ads_timer_init(void) { unsigned long fref = 26000000; - if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) fref = 27000000; mx27_clocks_init(fref); diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 2b147e4bf9c9..4f2c56d44ba1 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -160,8 +160,8 @@ static void mx31ads_expio_irq_handler(struct irq_desc *desc) u32 int_valid; u32 expio_irq; - imr_val = __raw_readw(PBC_INTMASK_SET_REG); - int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; + imr_val = imx_readw(PBC_INTMASK_SET_REG); + int_valid = imx_readw(PBC_INTSTATUS_REG) & imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -180,8 +180,8 @@ static void expio_mask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* mask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); - __raw_readw(PBC_INTMASK_CLEAR_REG); + imx_writew(1 << expio, PBC_INTMASK_CLEAR_REG); + imx_readw(PBC_INTMASK_CLEAR_REG); } /* @@ -192,7 +192,7 @@ static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; /* clear the interrupt status */ - __raw_writew(1 << expio, PBC_INTSTATUS_REG); + imx_writew(1 << expio, PBC_INTSTATUS_REG); } /* @@ -203,7 +203,7 @@ static void expio_unmask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* unmask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_SET_REG); + imx_writew(1 << expio, PBC_INTMASK_SET_REG); } static struct irq_chip expio_irq_chip = { @@ -226,8 +226,8 @@ static void __init mx31ads_init_expio(void) mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); /* disable the interrupt and clear the status */ - __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); - __raw_writew(0xFFFF, PBC_INTSTATUS_REG); + imx_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); + imx_writew(0xFFFF, PBC_INTSTATUS_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bb6f8a52a6b8..4f2d99888afd 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -509,7 +509,7 @@ static void mx31moboard_poweroff(void) mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); - __raw_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); + imx_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); } static int mx31moboard_baseboard; diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 5c2764604727..34df64f133ed 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -190,9 +190,9 @@ static struct platform_device qong_nand_device = { static void __init qong_init_nand_mtd(void) { /* init CS */ - __raw_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); - __raw_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); - __raw_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); + imx_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); + imx_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); + imx_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index a5b1af6d7441..d32704256781 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -193,4 +193,9 @@ extern struct cpu_op *(*get_cpu_op)(int *op); #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) +#define imx_readl readl_relaxed +#define imx_readw readw_relaxed +#define imx_writel writel_relaxed +#define imx_writew writew_relaxed + #endif /* __ASM_ARCH_MXC_H__ */ diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index 56d02d064fbf..43096c8990d4 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -19,9 +19,9 @@ static int mx27_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: /* Clear MPEN and SPEN to disable MPLL/SPLL */ - cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + cscr = imx_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); cscr &= 0xFFFFFFFC; - __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + imx_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ cpu_do_idle(); break; diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c index 6a07006ff0f4..94c0898751d8 100644 --- a/arch/arm/mach-imx/pm-imx3.c +++ b/arch/arm/mach-imx/pm-imx3.c @@ -22,14 +22,14 @@ */ void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) { - int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR); + int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR); reg &= ~MXC_CCM_CCMR_LPM_MASK; switch (mode) { case MX3_WAIT: if (cpu_is_mx35()) reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; - __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); + imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); break; default: pr_err("Unknown cpu power mode: %d\n", mode); diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 532d4b08276d..868781fd460c 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -153,15 +153,15 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) int stop_mode = 0; /* always allow platform to issue a deep sleep mode request */ - plat_lpc = __raw_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & + plat_lpc = imx_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & ~(MXC_CORTEXA8_PLAT_LPC_DSM); - ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & + ccm_clpcr = imx_readl(ccm_base + MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); - arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & + arm_srpgcr = imx_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & + empgc0 = imx_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc1 = __raw_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & + empgc1 = imx_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); switch (mode) { @@ -196,17 +196,17 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) return; } - __raw_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); - __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); + imx_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); + imx_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); if (stop_mode) { empgc0 |= MXC_SRPGCR_PCR; empgc1 |= MXC_SRPGCR_PCR; - __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); } } @@ -228,8 +228,8 @@ static int mx5_suspend_enter(suspend_state_t state) flush_cache_all(); /*clear the EMPGC0/1 bits */ - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); if (imx5_suspend_in_ocram_fn) imx5_suspend_in_ocram_fn(suspend_ocram_base); diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 51c35013b673..93d4a9a39353 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -54,7 +54,7 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) wcr_enable = (1 << 2); /* Assert SRS signal */ - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be * written twice), we add another two writes to ensure there must be at @@ -62,8 +62,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) * the target check here, since the writes shouldn't be a huge burden * for other platforms. */ - __raw_writew(wcr_enable, wdog_base); - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500); diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 4de65eeda1eb..ae23d50f7861 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -65,10 +65,10 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; mask = 1U << (irq & 0x1F); - value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask; + value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; if (type) value &= ~mask; - __raw_writel(value, tzic_base + TZIC_INTSEC0(index)); + imx_writel(value, tzic_base + TZIC_INTSEC0(index)); return 0; } @@ -82,15 +82,15 @@ static void tzic_irq_suspend(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); int idx = d->hwirq >> 5; - __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); } static void tzic_irq_resume(struct irq_data *d) { int idx = d->hwirq >> 5; - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), - tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(idx)), + tzic_base + TZIC_WAKEUP0(idx)); } #else @@ -135,8 +135,8 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) handled = 0; for (i = 0; i < 4; i++) { - stat = __raw_readl(tzic_base + TZIC_HIPND(i)) & - __raw_readl(tzic_base + TZIC_INTSEC0(i)); + stat = imx_readl(tzic_base + TZIC_HIPND(i)) & + imx_readl(tzic_base + TZIC_INTSEC0(i)); while (stat) { handled = 1; @@ -166,18 +166,18 @@ void __init tzic_init_irq(void) /* put the TZIC into the reset value with * all interrupts disabled */ - i = __raw_readl(tzic_base + TZIC_INTCNTL); + i = imx_readl(tzic_base + TZIC_INTCNTL); - __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL); - __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK); - __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL); + imx_writel(0x80010001, tzic_base + TZIC_INTCNTL); + imx_writel(0x1f, tzic_base + TZIC_PRIOMASK); + imx_writel(0x02, tzic_base + TZIC_SYNCCTRL); for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); /* disable all interrupts */ for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); /* all IRQ no FIQ Warning :: No selection */ @@ -214,13 +214,13 @@ int tzic_enable_wake(void) { unsigned int i; - __raw_writel(1, tzic_base + TZIC_DSMINT); - if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) + imx_writel(1, tzic_base + TZIC_DSMINT); + if (unlikely(imx_readl(tzic_base + TZIC_DSMINT) == 0)) return -EAGAIN; for (i = 0; i < 4; i++) - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)), - tzic_base + TZIC_WAKEUP0(i)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(i)), + tzic_base + TZIC_WAKEUP0(i)); return 0; } -- GitLab From 26e30c6489f4774492c168c7b953e575a16765f7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Jan 2016 17:59:36 +0100 Subject: [PATCH 0628/5324] ARM: imx: enable big endian mode Enable ARM big-endian mode on mach-imx. This requires adding some byte swapping in the debug functions (which otherwise hang forever) and of course the secondary core bringup. Tested (on top of 4.4) on i.MX6 HummingBoard quad-core (IMX6Q). The patch is pretty much as suggested by Arnd Bergmann, thanks! Signed-off-by: Johannes Berg Signed-off-by: Shawn Guo --- arch/arm/include/debug/imx.S | 3 +++ arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/headsmp.S | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 619d8cc1ac12..92c44760d656 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -11,6 +11,7 @@ * */ +#include #include "imx-uart.h" /* @@ -34,6 +35,7 @@ .endm .macro senduart,rd,rx + ARM_BE8(rev \rd, \rd) str \rd, [\rx, #0x40] @ TXDATA .endm @@ -42,6 +44,7 @@ .macro busyuart,rd,rx 1002: ldr \rd, [\rx, #0x98] @ SR2 + ARM_BE8(rev \rd, \rd) tst \rd, #1 << 3 @ TXDC beq 1002b @ wait until transmit done .endm diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index da42fdf7470b..ecc374060c27 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -2,6 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M select ARCH_REQUIRE_GPIOLIB + select ARCH_SUPPORTS_BIG_ENDIAN select ARM_CPU_SUSPEND if PM select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index b5e976816b63..6c28d28b3c64 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -12,6 +12,7 @@ #include #include +#include diag_reg_offset: .word g_diag_reg - . @@ -25,6 +26,7 @@ diag_reg_offset: .endm ENTRY(v7_secondary_startup) +ARM_BE8(setend be) @ go BE8 if entered LE set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) -- GitLab From 007270f136858ec880e2f2c6bfbdd489aae2bf56 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 30 Jan 2016 12:35:07 -0200 Subject: [PATCH 0629/5324] ARM: imx_v6_v7_defconfig: Select CONFIG_NVMEM_IMX_OCOTP Select the i.mx ocotp driver. Signed-off-by: Fabio Estevam Acked-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/configs/imx_v6_v7_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 1e792efe139b..25a6066493e4 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -321,6 +321,8 @@ CONFIG_IIO=y CONFIG_VF610_ADC=y CONFIG_PWM=y CONFIG_PWM_IMX=y +CONFIG_NVMEM=y +CONFIG_NVMEM_IMX_OCOTP=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -- GitLab From f9e37c683c8a0a2a200181dab2b784a126e0b106 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 30 Jan 2016 12:35:08 -0200 Subject: [PATCH 0630/5324] ARM: mxs_defconfig: Select CONFIG_NVMEM_MXS_OCOTP Select the mxs ocotp driver. Signed-off-by: Fabio Estevam Acked-by: Stefan Wahren Signed-off-by: Shawn Guo --- arch/arm/configs/mxs_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index b47e7c6628c9..1b2d9b377976 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -141,6 +141,8 @@ CONFIG_IIO=y CONFIG_IIO_SYSFS_TRIGGER=y CONFIG_PWM=y CONFIG_PWM_MXS=y +CONFIG_NVMEM=y +CONFIG_NVMEM_MXS_OCOTP=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y -- GitLab From 6b279560dd38ac66f3e65fd586cef37f5c2ae624 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 1 Feb 2016 22:59:58 +0800 Subject: [PATCH 0631/5324] ARM: dts: sun9i: a80-optimus: Remove i2c3 and uart4 i2c3 and uart4 are available on the GPIO header. Though these pins only have this one special function, the user may choose to use them as GPIOs instead. Since our policy is not to choose what function to present on the GPIO headers of development boards, remove them. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun9i-a80-optimus.dts | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts index 958160e40fd0..d7a20d92b114 100644 --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts @@ -109,17 +109,6 @@ status = "okay"; }; -&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c3_pins_a>; - status = "okay"; -}; - -&i2c3_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &ohci0 { status = "okay"; }; @@ -212,17 +201,6 @@ status = "okay"; }; -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_a>; - status = "okay"; -}; - -&uart4_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &usbphy1 { phy-supply = <®_usb1_vbus>; status = "okay"; -- GitLab From 856ea9eddbf46dc401f426da4eb3339a6baaed7b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 22 Jan 2016 19:03:23 +0900 Subject: [PATCH 0632/5324] arm64: dts: salvator-x: enable usb3.0 host channel 0 Signed-off-by: Yoshihiro Shimoda Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 265d12ff6022..9af1e3fdc468 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -249,3 +249,7 @@ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; + +&xhci0 { + status = "okay"; +}; -- GitLab From 652a4306be7684d4009e83f5028b3147c6f1c735 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 1 Feb 2016 19:29:00 +0900 Subject: [PATCH 0633/5324] arm64: dts: r8a7795: Add USB-DMAC device nodes Signed-off-by: Yoshihiro Shimoda Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 119549e6502d..95967b72db35 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -880,5 +880,31 @@ power-domains = <&cpg>; status = "disabled"; }; + + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; }; }; -- GitLab From 653f502d779e9ef90daa32443d0c60ebf67d5da9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:08 +0100 Subject: [PATCH 0634/5324] arm64: dts: r8a7795: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 38 +++++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 95967b72db35..013df449fc30 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -474,7 +474,9 @@ }; hscif0: serial@e6540000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6540000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 520>; @@ -486,7 +488,9 @@ }; hscif1: serial@e6550000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6550000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 519>; @@ -498,7 +502,9 @@ }; hscif2: serial@e6560000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6560000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 518>; @@ -510,7 +516,9 @@ }; hscif3: serial@e66a0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66a0000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 517>; @@ -522,7 +530,9 @@ }; hscif4: serial@e66b0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66b0000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 516>; @@ -534,7 +544,8 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 207>; @@ -546,7 +557,8 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 206>; @@ -558,7 +570,8 @@ }; scif2: serial@e6e88000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e88000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 310>; @@ -570,7 +583,8 @@ }; scif3: serial@e6c50000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 204>; @@ -582,7 +596,8 @@ }; scif4: serial@e6c40000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 203>; @@ -594,7 +609,8 @@ }; scif5: serial@e6f30000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6f30000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 202>; -- GitLab From 2d6f5f0cf6bfb17b8f0102cabe0665098ce0a865 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Sun, 31 Jan 2016 09:20:54 +0800 Subject: [PATCH 0635/5324] clk: sunxi: Add apb0 gates for A83T APB0 is part of PRCM, and is compatible with earlier SOCs. apb0 gates controls R_PIO, R_UART, R_RSB, etc clocks. This patch adds support for APB0 gates for A83T. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/clock/sunxi.txt | 1 + drivers/clk/sunxi/clk-simple-gates.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index e59f57b24777..7f19ef55d61f 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -39,6 +39,7 @@ Required properties: "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 + "allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index f4da52b5ca0e..2cfc5a8a5534 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -130,6 +130,8 @@ CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk", sunxi_simple_gates_init); +CLK_OF_DECLARE(sun8i_a83t_apb0, "allwinner,sun8i-a83t-apb0-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", -- GitLab From be338e4c589935a95f09022566ec6c511c07bb8c Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Sun, 31 Jan 2016 09:20:55 +0800 Subject: [PATCH 0636/5324] clk: sunxi: add bus gates for A83T A83T has similar bus gates that of H3, including single gating register has different clock parent. As per H3 and A83T datasheet, usbhost is under AHB2. However,below shows allwinner source code assignment: bits: 26 (ehci0), 27 (ehci1), 29 (ohci0) => AHB1 for A83T. bits: 26 (ehci0), 27 (ehci1) => AHB1 for H3 bits 29, 30, 31(ohci0,1,2) => AHB2 for H3. until, this confusion is cleared keep it H3 way. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Documentation/devicetree/bindings/clock/sunxi.txt | 1 + drivers/clk/sunxi/clk-sun8i-bus-gates.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 7f19ef55d61f..c09f59b1747c 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -58,6 +58,7 @@ Required properties: "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 + "allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3 "allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80 "allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10 diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index 1113eb98c9b4..63fdb790df29 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -109,3 +109,5 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk", sun8i_h3_bus_gates_init); +CLK_OF_DECLARE(sun8i_a83t_bus_gates, "allwinner,sun8i-a83t-bus-gates-clk", + sun8i_h3_bus_gates_init); -- GitLab From bf4f2fb05f89ac50de024b1a5dd0cd0db4a8f845 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Wed, 20 Jan 2016 15:31:20 +0100 Subject: [PATCH 0637/5324] drm/i915/skl/kbl: Add support for pipe fusing On SKL and KBL we can have pipe A/B/C disabled by fuse settings. The pipes must be fused in descending order (e.g. C, B+C, A+B+C). We simply decrease info->num_pipes if we find a valid fused out config. v2: Don't store the pipe disabled mask in device info (Damien) v3: Don't check FUSE_STRAP register for pipe c disabled Cc: Damien Lespiau Signed-off-by: Patrik Jakobsson Reviewed-by: Damien Lespiau [Jani: fixed some checkpatch indentation complaints] Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1453300280-10661-1-git-send-email-patrik.jakobsson@linux.intel.com --- drivers/gpu/drm/i915/i915_dma.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index db9b0c6840a0..4e3c7418729f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -809,6 +809,37 @@ static void intel_device_info_runtime_init(struct drm_device *dev) DRM_INFO("Display fused off, disabling\n"); info->num_pipes = 0; } + } else if (info->num_pipes > 0 && INTEL_INFO(dev)->gen == 9) { + u32 dfsm = I915_READ(SKL_DFSM); + u8 disabled_mask = 0; + bool invalid; + int num_bits; + + if (dfsm & SKL_DFSM_PIPE_A_DISABLE) + disabled_mask |= BIT(PIPE_A); + if (dfsm & SKL_DFSM_PIPE_B_DISABLE) + disabled_mask |= BIT(PIPE_B); + if (dfsm & SKL_DFSM_PIPE_C_DISABLE) + disabled_mask |= BIT(PIPE_C); + + num_bits = hweight8(disabled_mask); + + switch (disabled_mask) { + case BIT(PIPE_A): + case BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_C): + invalid = true; + break; + default: + invalid = false; + } + + if (num_bits > info->num_pipes || invalid) + DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", + disabled_mask); + else + info->num_pipes -= num_bits; } /* Initialize slice/subslice/EU info */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 65e32a317d63..c0bd691b41f8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5994,6 +5994,9 @@ enum skl_disp_power_wells { #define SKL_DFSM_CDCLK_LIMIT_540 (1 << 23) #define SKL_DFSM_CDCLK_LIMIT_450 (2 << 23) #define SKL_DFSM_CDCLK_LIMIT_337_5 (3 << 23) +#define SKL_DFSM_PIPE_A_DISABLE (1 << 30) +#define SKL_DFSM_PIPE_B_DISABLE (1 << 21) +#define SKL_DFSM_PIPE_C_DISABLE (1 << 28) #define GEN7_FF_SLICE_CS_CHICKEN1 _MMIO(0x20e0) #define GEN9_FFSC_PERCTX_PREEMPT_CTRL (1<<14) -- GitLab From 985dd4360fdf2533fe48a33a4a2094f2e4718dc0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 28 Jan 2016 16:04:12 +0200 Subject: [PATCH 0638/5324] drm/i915/bxt: update list of PCIIDs Add PCIIDs for new versions of the SOC, based on BSpec. Also add the name of the versions as code comment where this is available. The new versions don't have any changes visible to the kernel driver. Signed-off-by: Imre Deak Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1453989852-13569-1-git-send-email-imre.deak@intel.com --- include/drm/i915_pciids.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index f97020904717..9b48ac1d8543 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -296,7 +296,9 @@ #define INTEL_BXT_IDS(info) \ INTEL_VGA_DEVICE(0x0A84, info), \ INTEL_VGA_DEVICE(0x1A84, info), \ - INTEL_VGA_DEVICE(0x5A84, info) + INTEL_VGA_DEVICE(0x1A85, info), \ + INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \ + INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */ #define INTEL_KBL_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \ -- GitLab From d81a67cc1bfdc3efed8590ee4e07a40b198908ba Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 29 Jan 2016 14:52:26 +0200 Subject: [PATCH 0639/5324] drm/i915: Sanity check DP AUX message buffer and size While we are calling intel_dp_aux_transfer() with msg->size=0 whenever msg->buffer is NULL, passing NULL to memcpy() is undefined according to the ISO C standard. I haven't found any notes about this in the GNU C's or the kernel's documentation of the function and can't imagine what it would do with the NULL ptr. To better document this use of the parameters it still make sense to add an explicit check for this to the code. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1454071949-24677-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f44aba1019b8..a073f04a5330 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -979,7 +979,10 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) if (WARN_ON(txsize > 20)) return -E2BIG; - memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size); + if (msg->buffer) + memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size); + else + WARN_ON(msg->size); ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize); if (ret > 0) { -- GitLab From 9c06f6744d663205395f88d98aef87edcd3ce5bd Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 29 Jan 2016 14:52:27 +0200 Subject: [PATCH 0640/5324] drm/i915/chv: Fix error path in GPU freq helpers Atm we wouldn't catch these errors or on the error path we would end up with a division-by-zero, fix this up. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1454071949-24677-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 31bc4ea395ac..a47b8f219357 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7185,9 +7185,10 @@ static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) { int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); - div = vlv_gpu_freq_div(czclk_freq) / 2; + div = vlv_gpu_freq_div(czclk_freq); if (div < 0) return div; + div /= 2; return DIV_ROUND_CLOSEST(czclk_freq * val, 2 * div) / 2; } @@ -7196,9 +7197,10 @@ static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) { int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000); - mul = vlv_gpu_freq_div(czclk_freq) / 2; + mul = vlv_gpu_freq_div(czclk_freq); if (mul < 0) return mul; + mul /= 2; /* CHV needs even values */ return DIV_ROUND_CLOSEST(val * 2 * mul, czclk_freq) * 2; -- GitLab From b074eae12f1e9f8eb1aafa3d7b922427f9b8e68a Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 29 Jan 2016 14:52:28 +0200 Subject: [PATCH 0641/5324] drm/i915: Add debug info for failed MSI enabling While not being able to enable MSI interrupts may be a normal circumstance, for debugging it may still be a useful information, so emit an info about this. Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1454071949-24677-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4e3c7418729f..a42eb58f7c41 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1109,8 +1109,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) * be lost or delayed, but we use them anyways to avoid * stuck interrupts on some machines. */ - if (!IS_I945G(dev) && !IS_I945GM(dev)) - pci_enable_msi(dev->pdev); + if (!IS_I945G(dev) && !IS_I945GM(dev)) { + if (pci_enable_msi(dev->pdev) < 0) + DRM_DEBUG_DRIVER("can't enable MSI"); + } intel_device_info_runtime_init(dev); -- GitLab From 05d25214c4d1cab99d1056f99b7e7d95e9e31ed0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 29 Jan 2016 14:52:29 +0200 Subject: [PATCH 0642/5324] drm/i915: Properly terminate KMS mode name string during tv init Signed-off-by: Imre Deak Reviewed-by: David Weinehall Link: http://patchwork.freedesktop.org/patch/msgid/1454071949-24677-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_tv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 948cbff6c62e..5034b0055169 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1420,6 +1420,7 @@ intel_tv_get_modes(struct drm_connector *connector) if (!mode_ptr) continue; strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN); + mode_ptr->name[DRM_DISPLAY_MODE_LEN - 1] = '\0'; mode_ptr->hdisplay = hactive_s; mode_ptr->hsync_start = hactive_s + 1; -- GitLab From 771120761fe026170f910f4e591b1e0861de0523 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sun, 17 Jan 2016 16:49:05 +0100 Subject: [PATCH 0643/5324] ARM: OMAP2+: hwmod data: Add SSI data for omap36xx This patch enables Synchronous Serial Interface (SSI) hwmod support for OMAP36xx SoCs (used by Nokia N950/N9). Signed-off-by: Sebastian Reichel Tested-by: Aaro Koskinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0a985325cd64..9869a75c5d96 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3583,14 +3583,14 @@ static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { +static struct omap_hwmod_class omap3xxx_ssi_hwmod_class = { .name = "ssi", .sysc = &omap34xx_ssi_sysc, }; -static struct omap_hwmod omap34xx_ssi_hwmod = { +static struct omap_hwmod omap3xxx_ssi_hwmod = { .name = "ssi", - .class = &omap34xx_ssi_hwmod_class, + .class = &omap3xxx_ssi_hwmod_class, .clkdm_name = "core_l4_clkdm", .main_clk = "ssi_ssr_fck", .prcm = { @@ -3605,9 +3605,9 @@ static struct omap_hwmod omap34xx_ssi_hwmod = { }; /* L4 CORE -> SSI */ -static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { +static struct omap_hwmod_ocp_if omap3xxx_l4_core__ssi = { .master = &omap3xxx_l4_core_hwmod, - .slave = &omap34xx_ssi_hwmod, + .slave = &omap3xxx_ssi_hwmod, .clk = "ssi_ick", .user = OCP_USER_MPU | OCP_USER_SDMA, }; @@ -3760,7 +3760,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, - &omap34xx_l4_core__ssi, + &omap3xxx_l4_core__ssi, NULL }; @@ -3784,6 +3784,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, + &omap3xxx_l4_core__ssi, NULL }; -- GitLab From 14b5a4bf7acd3c803c9bde857ae054ba19c4a04c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 2 Feb 2016 16:55:30 +0100 Subject: [PATCH 0644/5324] clk: sunxi: don't mark sun6i_ar100_data __initconst The clk-sun6i-ar100 clk driver is a platform driver that may use deferred probing, so its probe function must not access __init symbols. Kbuild warns about this: WARNING: drivers/clk/sunxi/built-in.o(.text+0x15f0): Section mismatch in reference from the function sun6i_a31_ar100_clk_probe() to the (unknown reference) .init.rodata:(unknown) The function sun6i_a31_ar100_clk_probe() references the (unknown reference) __initconst (unknown). This is often because sun6i_a31_ar100_clk_probe lacks a __initconst annotation or the annotation of (unknown) is wrong. Removing the __initconst annotation avoids the warning and makes deferred probing work. Signed-off-by: Arnd Bergmann Fixes: 3ca2377b6fed ("clk: sunxi: rewrite sun6i-ar100 using factors clk") Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sun6i-ar100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index a7f5777834eb..84a187e55360 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -60,7 +60,7 @@ static const struct clk_factors_config sun6i_ar100_config = { .pshift = 4, }; -static const struct factors_data sun6i_ar100_data __initconst = { +static const struct factors_data sun6i_ar100_data = { .mux = 16, .muxmask = GENMASK(1, 0), .table = &sun6i_ar100_config, -- GitLab From d221b7a8781ce594249cb44644ec9fecd893957d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 1 Feb 2016 17:39:27 +0000 Subject: [PATCH 0645/5324] clk: sunxi: improve error reporting for the mux clock clk_register_mux returns a pointer wrapped error value in case of failure, so a simple NULL check is not sufficient to catch errors. Fix that and elaborate on the failure reason on the way. The whole function does not return any error value, so silently failing may leave users scratching their heads because the kernel does not provide any clues on what's wrong. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard --- drivers/clk/sunxi/clk-sunxi.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index da15f2b12ab2..2524d6f41b3b 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -627,17 +627,29 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, reg = of_iomap(node, 0); i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_warn("%s: could not read clock-output-names for \"%s\"\n", + __func__, clk_name); + goto out_unmap; + } clk = clk_register_mux(NULL, clk_name, parents, i, CLK_SET_RATE_PARENT, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_warn("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); + goto out_unmap; } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + return; + +out_unmap: + iounmap(reg); } -- GitLab From e1ea07542352be468e901173c7a1beeee404d696 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Wed, 6 Jan 2016 09:53:41 -0800 Subject: [PATCH 0646/5324] drm/i915/bxt: Don't save/restore eDP panel power during suspend (v3) Our attempts save/restore panel power state in i915_suspend.c are causing unclaimed register warnings on BXT since the registers for this platform differ from older platforms. The big hammer suspend/resume shouldn't be necessary for PP since the connector/encoder hooks should already handle this. In theory we could remove this for all platforms, but in practice it's likely that would cause some regressions since older platforms with LVDS may have incomplete PP handling. For now we'll leave the PCH save/restore alone and change the non-PCH branch to only operate on gen <= 4 so that BXT and future platforms aren't included. v2: Typo fix: s/||/&&/ v3: Change non-PCH condition to a gen <= 4 test rather than listing VLV/CHV/BXT as specific platforms to exclude; should be more future-proof as we add new platforms. (Daniel) Cc: Vandana Kannan Cc: Jani Nikula Cc: Daniel Vetter Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Matt Roper Reviewed-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1452102821-17190-1-git-send-email-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/i915_suspend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 6c6bedf3eb37..34e061a9ef06 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -49,7 +49,7 @@ static void i915_save_display(struct drm_device *dev) dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); - } else if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { + } else if (INTEL_INFO(dev)->gen <= 4) { dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); @@ -84,7 +84,7 @@ static void i915_restore_display(struct drm_device *dev) I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL); - } else if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) { + } else if (INTEL_INFO(dev)->gen <= 4) { I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); I915_WRITE(PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); -- GitLab From 6580566e10016c1ec00aa5e0e62af3c4b3498019 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 31 Jan 2016 16:32:48 -0800 Subject: [PATCH 0647/5324] ARM: BCM63xx: Remove unused pmb_dn variable Introduced in commit 3f2a43c98d72b ("ARM: BCM63xx: Add secondary CPU PMB initialization sequence"), but not used by the code. Reported-by: David Binderman Signed-off-by: Florian Fainelli --- arch/arm/mach-bcm/bcm63xx_pmb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-bcm/bcm63xx_pmb.c b/arch/arm/mach-bcm/bcm63xx_pmb.c index de061ec5a479..41dcf5d65630 100644 --- a/arch/arm/mach-bcm/bcm63xx_pmb.c +++ b/arch/arm/mach-bcm/bcm63xx_pmb.c @@ -92,7 +92,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, unsigned int *cpu, unsigned int *addr) { - struct device_node *pmb_dn; struct of_phandle_args args; int ret; @@ -109,7 +108,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, return ret; } - pmb_dn = args.np; if (args.args_count != 2) { pr_err("reset-controller does not conform to reset-cells\n"); return -EINVAL; -- GitLab From 20de823e8b38119d8106aa85e0bd8b47eb295889 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 31 Jan 2016 17:41:13 -0800 Subject: [PATCH 0648/5324] MAINTAINERS: ARM: BCM63xx: Update git and mailing-lists arm-bcm63xx.git has not been used for development, instead, all patches have been added to stblinux.git, so reflect that. While at it, add bcm-kernel-feedback-list@broadcom.com as a secondary list to include submissions, and finally update LAKML to reflect that it is moderated. Signed-off-by: Florian Fainelli --- MAINTAINERS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 30aca4aa5467..7f579c835476 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2383,8 +2383,9 @@ F: arch/arm/boot/dts/bcm470* BROADCOM BCM63XX ARM ARCHITECTURE M: Florian Fainelli -L: linux-arm-kernel@lists.infradead.org -T: git git://github.com/broadcom/arm-bcm63xx.git +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: bcm-kernel-feedback-list@broadcom.com +T: git git://github.com/broadcom/stblinux.git S: Maintained F: arch/arm/mach-bcm/bcm63xx.c F: arch/arm/include/debug/bcm63xx.S -- GitLab From 3c8e77dd20ab733f855e66bb6197ce84eb33e480 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:04 +0900 Subject: [PATCH 0649/5324] clk: move checking .get_parent to __clk_core_init() The .get_parent is mandatory for multi-parent clocks. Move the check to __clk_core_init(), like other callback checkings. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy [sboyd@codeaurora.org: Squashed in error path handling, fix typos in commit message] Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 09d84453ea3a..7fe94a5c6b4a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1695,13 +1695,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) goto out; } - if (!core->ops->get_parent) { - WARN(!core->ops->get_parent, - "%s: multi-parent clocks must implement .get_parent\n", - __func__); - goto out; - } - /* * Do our best to cache parent clocks in core->parents. This prevents * unnecessary and expensive lookups. We don't set core->parent here; @@ -2333,6 +2326,13 @@ static int __clk_core_init(struct clk_core *core) goto out; } + if (core->num_parents > 1 && !core->ops->get_parent) { + pr_err("%s: %s must implement .get_parent as it has multi parents\n", + __func__, core->name); + ret = -EINVAL; + goto out; + } + if (core->ops->set_rate_and_parent && !(core->ops->set_parent && core->ops->set_rate)) { pr_err("%s: %s must implement .set_parent & .set_rate\n", -- GitLab From 5146e0b05963f75347c9f4e18996da245f859e32 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:04 +0900 Subject: [PATCH 0650/5324] clk: simplify __clk_init_parent() The translation from the index into clk_core is done by clk_core_get_parent_by_index(). The if-block for num_parents == 1 case is duplicating the code in the clk_core_get_parent_by_index(). Drop the "if (num_parents == 1)" from the special case. Instead, set the index to zero if .get_parent() is missing. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 7fe94a5c6b4a..dee9c528ea83 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1669,44 +1669,14 @@ struct clk *clk_get_parent(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_get_parent); -/* - * .get_parent is mandatory for clocks with multiple possible parents. It is - * optional for single-parent clocks. Always call .get_parent if it is - * available and WARN if it is missing for multi-parent clocks. - * - * For single-parent clocks without .get_parent, first check to see if the - * .parents array exists, and if so use it to avoid an expensive tree - * traversal. If .parents does not exist then walk the tree. - */ static struct clk_core *__clk_init_parent(struct clk_core *core) { - struct clk_core *ret = NULL; - u8 index; - - /* handle the trivial cases */ + u8 index = 0; - if (!core->num_parents) - goto out; - - if (core->num_parents == 1) { - if (IS_ERR_OR_NULL(core->parent)) - core->parent = clk_core_lookup(core->parent_names[0]); - ret = core->parent; - goto out; - } + if (core->ops->get_parent) + index = core->ops->get_parent(core->hw); - /* - * Do our best to cache parent clocks in core->parents. This prevents - * unnecessary and expensive lookups. We don't set core->parent here; - * that is done by the calling function. - */ - - index = core->ops->get_parent(core->hw); - - ret = clk_core_get_parent_by_index(core, index); - -out: - return ret; + return clk_core_get_parent_by_index(core, index); } static void clk_core_reparent(struct clk_core *core, -- GitLab From 858d5881564026cbc4e6f5e25ae878a27df5d4c9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:06 +0900 Subject: [PATCH 0651/5324] clk: avoid circular clock topology Currently, clk_register() never checks a circular parent looping, but clock providers could register such an insane clock topology. For example, "clk_a" could have "clk_b" as a parent, and vice versa. In this case, clk_core_reparent() creates a circular parent list and __clk_recalc_accuracies() calls itself recursively forever. The core infrastructure should be kind enough to bail out, showing an appropriate error message in such a case. This helps to easily find a bug in clock providers. (uh, I made such a silly mistake when I was implementing my clock providers first. I was upset because the kernel did not respond, without any error message.) This commit adds a new helper function, __clk_is_ancestor(). It returns true if the second argument is a possible ancestor of the first one. If a clock core is a possible ancestor of itself, it would make a loop when it were registered. That should be detected as an error. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index dee9c528ea83..5a1507498e05 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2252,6 +2252,38 @@ static inline void clk_debug_unregister(struct clk_core *core) } #endif +/** + * __clk_is_ancestor - check if a clk_core is a possible ancestor of another + * @core: clock core + * @ancestor: ancestor clock core + * + * Returns true if there is a possibility that @ancestor can be an ancestor + * of @core, false otherwise. + * + * This function can be used against @core or @ancestor that has not been + * registered yet. + */ +static bool __clk_is_ancestor(struct clk_core *core, struct clk_core *ancestor) +{ + struct clk_core *parent; + int i; + + for (i = 0; i < core->num_parents; i++) { + parent = clk_core_get_parent_by_index(core, i); + /* + * If ancestor has not been added to clk_{root,orphan}_list + * yet, clk_core_lookup() cannot find it. If parent is NULL, + * compare the name strings, too. + */ + if ((parent && (parent == ancestor || + __clk_is_ancestor(parent, ancestor))) || + (!parent && !strcmp(core->parent_names[i], ancestor->name))) + return true; + } + + return false; +} + /** * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized @@ -2317,6 +2349,14 @@ static int __clk_core_init(struct clk_core *core) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); + /* If core is an ancestor of itself, it would make a loop. */ + if (__clk_is_ancestor(core, core)) { + pr_err("%s: %s would create circular parent\n", __func__, + core->name); + ret = -EINVAL; + goto out; + } + core->parent = __clk_init_parent(core); /* -- GitLab From 0e8f6e499ebfd3617c81a89778f55fa6c54623e8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:07 +0900 Subject: [PATCH 0652/5324] clk: walk the orphan clock list more simply This loop can be much simpler. If a new parent is available for orphan clocks, __clk_init_parent(orphan) can detect it. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 5a1507498e05..03820467fbba 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2422,24 +2422,15 @@ static int __clk_core_init(struct clk_core *core) core->rate = core->req_rate = rate; /* - * walk the list of orphan clocks and reparent any that are children of - * this clock + * walk the list of orphan clocks and reparent any that newly finds a + * parent. */ hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { - if (orphan->num_parents && orphan->ops->get_parent) { - i = orphan->ops->get_parent(orphan->hw); - if (i >= 0 && i < orphan->num_parents && - !strcmp(core->name, orphan->parent_names[i])) - clk_core_reparent(orphan, core); - continue; - } + struct clk_core *parent = __clk_init_parent(orphan); - for (i = 0; i < orphan->num_parents; i++) - if (!strcmp(core->name, orphan->parent_names[i])) { - clk_core_reparent(orphan, core); - break; - } - } + if (parent) + clk_core_reparent(orphan, parent); + } /* * optional platform-specific magic -- GitLab From 508f884a66abb61f22fcc2b36ab1e68492f1d295 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:08 +0900 Subject: [PATCH 0653/5324] clk: make sure parent is not NULL in clk_fetch_parent_index() If parent is given with NULL, clk_fetch_parent_index() could return a positive index value. Currently, parent is checked by the callers of this function, but it would be safer to do it in this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 03820467fbba..da7c9a523f02 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1066,6 +1066,9 @@ static int clk_fetch_parent_index(struct clk_core *core, { int i; + if (!parent) + return -EINVAL; + /* * find index of new parent clock using cached parent ptrs, * or if not yet cached, use string name comparison and cache -- GitLab From 470b5e2f97cf8fb6a8375cc59e86314c9dd354c2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:09 +0900 Subject: [PATCH 0654/5324] clk: simplify clk_fetch_parent_index() function The clk_core_get_parent_by_index can be used as a helper function to simplify the implementation of clk_fetch_parent_index(). Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index da7c9a523f02..82b79a6ec0ec 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1069,23 +1069,9 @@ static int clk_fetch_parent_index(struct clk_core *core, if (!parent) return -EINVAL; - /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to clk_core_lookup. - */ - for (i = 0; i < core->num_parents; i++) { - if (core->parents[i] == parent) - return i; - - if (core->parents[i]) - continue; - - if (!strcmp(core->parent_names[i], parent->name)) { - core->parents[i] = clk_core_lookup(parent->name); + for (i = 0; i < core->num_parents; i++) + if (clk_core_get_parent_by_index(core, i) == parent) return i; - } - } return -EINVAL; } -- GitLab From e8f0e68ec0802dc840e29e0fabdcfdc39aa2a8fb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:10 +0900 Subject: [PATCH 0655/5324] clk: slightly optimize clk_core_set_parent() If clk_fetch_parent_index() fails, p_rate is unused. Move the assignment after the error checking. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 82b79a6ec0ec..d31ed95d27a4 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1748,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) /* try finding the new parent index */ if (parent) { p_index = clk_fetch_parent_index(core, parent); - p_rate = parent->rate; if (p_index < 0) { pr_debug("%s: clk %s can not be parent of clk %s\n", __func__, parent->name, core->name); ret = p_index; goto out; } + p_rate = parent->rate; } /* propagate PRE_RATE_CHANGE notifications */ -- GitLab From 7001ec560a82d1cc2ba5c0c9ac1f7fcca820b27e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 1 Feb 2016 11:19:10 +0100 Subject: [PATCH 0656/5324] clk: vt8500: don't return possibly uninitialized data The clk-vt8500.c driver would previously enter an endless loop when invalid settings got requested, this was now fixed. However, the driver will now return uninitialized data for a subset of those cases instead, as the gcc correctly warns: clk/clk-vt8500.c: In function 'wm8650_find_pll_bits': clk/clk-vt8500.c:423:12: error: 'best_div2' may be used uninitialized in this function [-Werror=maybe-uninitialized] *divisor2 = best_div2; ^ clk/clk-vt8500.c:422:12: error: 'best_div1' may be used uninitialized in this function [-Werror=maybe-uninitialized] *divisor1 = best_div1; ^ clk/clk-vt8500.c:421:14: error: 'best_mul' may be used uninitialized in this function [-Werror=maybe-uninitialized] *multiplier = best_mul; This reworks the error handling in the driver so we now return -EINVAL from clk_round_rate() and clk_set_rate() when we get impossible inputs. Signed-off-by: Arnd Bergmann Fixes: 090341b0a95d ("clk: vt8500: fix sign of possible PLL values") Signed-off-by: Stephen Boyd --- drivers/clk/clk-vt8500.c | 91 ++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 98c4492d2c0d..b0f76a84f1e9 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); #define WM8850_BITS_TO_VAL(m, d1, d2) \ ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2) -static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *prediv) { unsigned long tclk; @@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, pr_err("%s: requested rate out of range\n", __func__); *multiplier = 0; *prediv = 1; - return; + return -EINVAL; } if (rate <= parent_rate * 31) /* use the prediv to double the resolution */ @@ -379,9 +379,11 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, if (tclk != rate) pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, tclk); + + return 0; } -static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul, div1; @@ -404,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -415,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) @@ -450,7 +459,7 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) return 0; } -static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul; @@ -474,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -485,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -493,9 +507,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } -static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul; @@ -519,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -530,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -537,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -546,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, u32 filter, mul, div1, div2; u32 pll_val; unsigned long flags = 0; + int ret; /* sanity check */ switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); - pll_val = VT8500_BITS_TO_VAL(mul, div1); + ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); + if (!ret) + pll_val = VT8500_BITS_TO_VAL(mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); + ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); - pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); + if (!ret) + pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); + ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); break; default: pr_err("%s: invalid pll type\n", __func__); - return 0; + ret = -EINVAL; } + if (ret) + return ret; + spin_lock_irqsave(pll->lock, flags); vt8500_pmc_wait_busy(); @@ -588,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct clk_pll *pll = to_clk_pll(hw); u32 filter, mul, div1, div2; long round_rate; + int ret; switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, *prate, &mul, &div1); - round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); + ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1); + if (!ret) + round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); - round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); + if (!ret) + round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); break; default: - round_rate = 0; + ret = -EINVAL; } + if (ret) + return ret; + return round_rate; } -- GitLab From 4106a3d9ebb9839a8e93b0116c0f94dc4f10e4b2 Mon Sep 17 00:00:00 2001 From: Insu Yun Date: Sat, 30 Jan 2016 10:12:04 -0500 Subject: [PATCH 0657/5324] clk: unlock for handling unregistered clock If clock is already unregistered, it returns with holding lock. It needs to be unlocked. Signed-off-by: Insu Yun [sboyd@codeaurora.org: Use goto instead] Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d31ed95d27a4..bb01ed6cc63e 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2641,7 +2641,7 @@ void clk_unregister(struct clk *clk) if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - return; + goto unlock; } /* * Assign empty clock ops for consumers that might still hold @@ -2667,7 +2667,7 @@ void clk_unregister(struct clk *clk) pr_warn("%s: unregistering prepared clock: %s\n", __func__, clk->core->name); kref_put(&clk->core->ref, __clk_release); - +unlock: clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister); -- GitLab From 2467b6745e0ae9c6cdccff24c4cceeb14b1cce3f Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 2 Feb 2016 11:37:50 +0800 Subject: [PATCH 0658/5324] clk: rockchip: free memory in error cases when registering clock branches Add free memeory if rockchip_clk_register_branch fails. Fixes: a245fecbb806 ("clk: rockchip: add basic infrastructure...") Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index d9a0b5d4d47f..62fbe2c6eaaf 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (gate_offset >= 0) { gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) - return ERR_PTR(-ENOMEM); + goto err_gate; gate->flags = gate_flags; gate->reg = base + gate_offset; @@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (div_width > 0) { div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) - return ERR_PTR(-ENOMEM); + goto err_div; div->flags = div_flags; div->reg = base + muxdiv_offset; @@ -100,6 +100,11 @@ static struct clk *rockchip_clk_register_branch(const char *name, flags); return clk; +err_div: + kfree(gate); +err_gate: + kfree(mux); + return ERR_PTR(-ENOMEM); } struct rockchip_clk_frac { -- GitLab From 1d961f11a108af9f7fbe89cc950a8d16ddbdbb28 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 1 Feb 2016 16:18:40 +0800 Subject: [PATCH 0659/5324] soc: rockchip: power-domain: fix err handle while probing If we fail to probe the driver, we should not directly break from the for_each_available_child_of_node since it calls of_node_get while iterating. This patch add of_node_put to fix the unbalanced call pair. Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain driver") Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/pm_domains.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 6cdffb13c862..43155e1f97b9 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -423,6 +423,7 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev) if (error) { dev_err(dev, "failed to handle node %s: %d\n", node->name, error); + of_node_put(node); goto err_out; } } -- GitLab From 8f338ecf0cd47d94303d9b4d9b2f9a99944ef0e2 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 2 Feb 2016 11:40:52 +0800 Subject: [PATCH 0660/5324] ARM: dts: rockchip: add mclk for rt5616 on rk3036 kylin board The I2S block that provide the output clock as the mclk for rt5616, That will be the master clock input. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 3332a7f785c5..b754613b9a9a 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -313,6 +313,8 @@ rt5616: rt5616@1b { compatible = "rt5616"; reg = <0x1b>; + clocks = <&cru SCLK_I2S_OUT>; + clock-names = "mclk"; #sound-dai-cells = <0>; }; }; -- GitLab From f629fcfab2cd8a2f1a571fbc83e76a81ee3470db Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 2 Feb 2016 11:40:53 +0800 Subject: [PATCH 0661/5324] ARM: dts: rockchip: support the spi for rk3036 This patch adds the needed spi node for rk3036 dts. We have to use the 4 bus emmc to work if someone want to support the spi devices, since the pins are re-used by emmc data[5-8] and spi. In some caseswe need to support the spi devices, that will waste the emmc performance. Moment, the kylin/evb hasn't the spi devices to work, so maybe we need wait the new required to enable in kylin/evb board. Anyway, the spi should be needed land in rk3036 dts. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036.dtsi | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index 78974492cb11..28fa2f848df8 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -60,6 +60,7 @@ serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; + spi = &spi; }; memory { @@ -407,6 +408,21 @@ status = "disabled"; }; + spi: spi@20074000 { + compatible = "rockchip,rockchip-spi"; + reg = <0x20074000 0x1000>; + interrupts = ; + clocks =<&cru PCLK_SPI>, <&cru SCLK_SPI>; + clock-names = "apb-pclk","spi_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_txd &spi_rxd &spi_clk &spi_cs0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pinctrl: pinctrl { compatible = "rockchip,rk3036-pinctrl"; rockchip,grf = <&grf>; @@ -618,5 +634,29 @@ }; /* no rts / cts for uart2 */ }; + + spi { + spi_txd:spi-txd { + rockchip,pins = <1 29 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_rxd:spi-rxd { + rockchip,pins = <1 28 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_clk:spi-clk { + rockchip,pins = <2 0 RK_FUNC_2 &pcfg_pull_default>; + }; + + spi_cs0:spi-cs0 { + rockchip,pins = <1 30 RK_FUNC_3 &pcfg_pull_default>; + + }; + + spi_cs1:spi-cs1 { + rockchip,pins = <1 31 RK_FUNC_3 &pcfg_pull_default>; + + }; + }; }; }; -- GitLab From f6bb9d5f30d6986c4fdce1ed5a36088a0c30c544 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Fri, 29 Jan 2016 16:49:21 +0800 Subject: [PATCH 0662/5324] ARM: dts: rockchip: increase the mclk_fs to 512 for kylin board If we playback the 8KHz FS audio with the 256 mclk_fs, we need the mclk = 256 * 8000 = 2.048MHz, the frac div is 594 / 2.048 = 290, the frac div value 0x00809015 set to the CRU_CLKSEL7_CON will cause to hang. We increase the mclk_fs to 512, will get the mclk = 512 * 8000 = 4.096MHz, use 0x01009015 instead of 0x00809015 to work around this issue. We will keep tracking it. Signed-off-by: Xing Zheng Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036-kylin.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index b754613b9a9a..d5913fe128ee 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -78,7 +78,7 @@ compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,name = "rockchip,rt5616-codec"; - simple-audio-card,mclk-fs = <256>; + simple-audio-card,mclk-fs = <512>; simple-audio-card,widgets = "Microphone", "Microphone Jack", "Headphone", "Headphone Jack"; -- GitLab From cef687d05f9ff8a022a23ded6d5f6ac82d40ddf3 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 26 Jan 2016 10:34:14 +0800 Subject: [PATCH 0663/5324] dt-bindings: rockchip-dw-mshc: add RK3036 dw-mshc description rk3036 dtsi file add dw-mshc compatible "rockchip,rk3036-dw-mshc" but didn't add it into rockchip-dw-mshc.txt. Signed-off-by: Shawn Lin Acked-by: Rob Herring Signed-off-by: Heiko Stuebner --- Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 634e2490795e..ea5614b6f613 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -13,6 +13,7 @@ Required Properties: - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following, before RK3288 - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 + - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036 - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 Optional Properties: -- GitLab From ed8d60f450d3db4c4dbb25eddc8f106cbab4bd1c Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 28 Jan 2016 15:09:37 -0800 Subject: [PATCH 0664/5324] drm/i915: Check DDI max lanes after applying BXT workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit bfb9faab8 we added a workaround for some BXT BIOS that fail to properly initialize the DDI_A_4_LANES bit of the control register (4 lanes is the only valid configuration on BXT since there is no DDI E to share with). A recent patch added some additional checks on this register bit before the workaround gets applied; this breaks eDP on BXT in some settings. Some minor code shuffling is all we need to restore the workaround. Cc: Ville Syrjälä Fixes: 7cd87cb80 ("drm/i915: Check max number of lanes when registering DDI ports") Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1454022577-834-1-git-send-email-matthew.d.roper@intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_ddi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 1f9a3687b540..6d5b09f2a8a6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3281,7 +3281,6 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); - intel_dig_port->max_lanes = max_lanes; /* * Bspec says that DDI_A_4_LANES is the only supported configuration @@ -3294,9 +3293,12 @@ void intel_ddi_init(struct drm_device *dev, enum port port) if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) { DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n"); intel_dig_port->saved_port_bits |= DDI_A_4_LANES; + max_lanes = 4; } } + intel_dig_port->max_lanes = max_lanes; + intel_encoder->type = INTEL_OUTPUT_UNKNOWN; intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); intel_encoder->cloneable = 0; -- GitLab From f974d685d27fd1898e25390fbbdd3bf620d15082 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 11 Sep 2015 11:22:05 +0000 Subject: [PATCH 0665/5324] ARM: bcm2835: add the auxiliary spi1 and spi2 to the device tree This enables the use of the auxiliary spi1 and spi2 devices on the bcm2835 SOC. Note that this requires the use of the new clk-bcm2835-aux to work. Signed-off-by: Martin Sperl Acked-by: Stephen Warren [anholt: Rebased on 2835.dtsi -> 283x.dtsi change] Signed-off-by: Eric Anholt --- arch/arm/boot/dts/bcm283x.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 971e741e5467..f0d457312746 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include "skeleton.dtsi" /* This include file covers the common peripherals and configuration between @@ -159,6 +160,26 @@ clocks = <&clocks BCM2835_CLOCK_VPU>; }; + spi1: spi@7e215080 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e215080 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@7e2150c0 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e2150c0 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + sdhci: sdhci@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; -- GitLab From 40ad4499bafa0202f3a1880fc43718ae3a3e2c24 Mon Sep 17 00:00:00 2001 From: Remi Pommarel Date: Mon, 21 Dec 2015 21:12:59 +0100 Subject: [PATCH 0666/5324] ARM: bcm2835: Add PWM clock support to the device tree Signed-off-by: Remi Pommarel [anholt: Rebased on 2835.dtsi -> 283x.dtsi change] Signed-off-by: Eric Anholt --- arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ++++ arch/arm/boot/dts/bcm283x.dtsi | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index 3afb9fefe2d1..a584a93f631d 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -58,3 +58,7 @@ status = "okay"; bus-width = <4>; }; + +&pwm { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index f0d457312746..e4a279261d72 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -180,6 +180,16 @@ status = "disabled"; }; + pwm: pwm@7e20c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c000 0x28>; + clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clock-rates = <10000000>; + #pwm-cells = <2>; + status = "disabled"; + }; + sdhci: sdhci@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; -- GitLab From 68e2ef17a54401603c927e2bccf5e8ac8d5da9d3 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Sun, 17 Jan 2016 12:15:28 +0000 Subject: [PATCH 0667/5324] ARM: bcm2835: follow dt uart node-naming convention This patch fixes the naming of the device tree node: uart@7e201000 to conform to the standard of: serial@7e201000 Signed-off-by: Martin Sperl [anholt: Rebased on 2835.dtsi -> 283x.dtsi change] Signed-off-by: Eric Anholt --- arch/arm/boot/dts/bcm283x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index e4a279261d72..c003f2d77de5 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -112,7 +112,7 @@ #interrupt-cells = <2>; }; - uart0: uart@7e201000 { + uart0: serial@7e201000 { compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; reg = <0x7e201000 0x1000>; interrupts = <2 25>; -- GitLab From 7a1298e339249f25f4ef97fed332c70e1d1507e4 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 25 Jan 2016 21:40:06 +0100 Subject: [PATCH 0668/5324] ARM: bcm2835: dt: Add Raspberry Pi Model A This one is essentially the same as revision 2 B board (with the I2S on P5 header). Signed-off-by: Lubomir Rintel Acked-by: Stephen Warren [anholt: Rebased on bcm2835.dtsi -> bcm283x.dtsi change] Signed-off-by: Eric Anholt --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/bcm2835-rpi-a.dts | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 arch/arm/boot/dts/bcm2835-rpi-a.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26..d00081447c32 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -60,6 +60,7 @@ dtb-$(CONFIG_ARCH_AXXIA) += \ axm5516-amarillo.dtb dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-b.dtb \ + bcm2835-rpi-a.dtb \ bcm2835-rpi-b-rev2.dtb \ bcm2835-rpi-b-plus.dtb \ bcm2835-rpi-a-plus.dtb \ diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts new file mode 100644 index 000000000000..ddbbbbd42dda --- /dev/null +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -0,0 +1,24 @@ +/dts-v1/; +#include "bcm2835.dtsi" +#include "bcm2835-rpi.dtsi" + +/ { + compatible = "raspberrypi,model-a", "brcm,bcm2835"; + model = "Raspberry Pi Model A"; + + leds { + act { + gpios = <&gpio 16 1>; + }; + }; +}; + +&gpio { + pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; + + /* I2S interface */ + i2s_alt2: i2s_alt2 { + brcm,pins = <28 29 30 31>; + brcm,function = ; + }; +}; -- GitLab From 5ec6f2cd8ec4bcd38ba199ea8711a5ec906d85e7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 16 Dec 2015 16:26:49 -0800 Subject: [PATCH 0669/5324] ARM: bcm2835: Add the Raspberry Pi power domain driver to the DT. This connects the USB driver to the USB power domain, so that USB can actually be turned on at boot if the bootloader didn't do it for us. Signed-off-by: Alexander Aring Signed-off-by: Eric Anholt Reviewed-by: Kevin Hilman --- arch/arm/boot/dts/bcm2835-rpi.dtsi | 12 ++++++++++++ arch/arm/boot/dts/bcm283x.dtsi | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index a584a93f631d..76bdbcafab18 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -1,3 +1,5 @@ +#include + / { memory { reg = <0 0x10000000>; @@ -18,6 +20,12 @@ compatible = "raspberrypi,bcm2835-firmware"; mboxes = <&mailbox>; }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; }; }; @@ -62,3 +70,7 @@ &pwm { status = "okay"; }; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +}; diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index c003f2d77de5..05ff5ce91c95 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -218,7 +218,7 @@ status = "disabled"; }; - usb@7e980000 { + usb: usb@7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>; -- GitLab From 69e359ca8811582cf7433f3fa894a7d6cbba4905 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:47:41 +0100 Subject: [PATCH 0670/5324] arm64: dts: r8a7795: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 013df449fc30..ddeec7d7b6eb 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -480,7 +480,7 @@ reg = <0 0xe6540000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 520>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x31>, <&dmac1 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -494,7 +494,7 @@ reg = <0 0xe6550000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 519>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x33>, <&dmac1 0x32>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -508,7 +508,7 @@ reg = <0 0xe6560000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 518>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x35>, <&dmac1 0x34>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -522,7 +522,7 @@ reg = <0 0xe66a0000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 517>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x37>, <&dmac0 0x36>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -536,7 +536,7 @@ reg = <0 0xe66b0000 0 96>; interrupts = ; clocks = <&cpg CPG_MOD 516>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x39>, <&dmac0 0x38>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -549,7 +549,7 @@ reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 207>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x51>, <&dmac1 0x50>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -562,7 +562,7 @@ reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 206>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x53>, <&dmac1 0x52>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -575,7 +575,7 @@ reg = <0 0xe6e88000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -588,7 +588,7 @@ reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 204>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x57>, <&dmac0 0x56>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -601,7 +601,7 @@ reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 203>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x59>, <&dmac0 0x58>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -614,7 +614,7 @@ reg = <0 0xe6f30000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 202>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x5b>, <&dmac1 0x5a>; dma-names = "tx", "rx"; power-domains = <&cpg>; -- GitLab From 3da41e4cf65a322937db48ce0d55c6f6a68032b0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:43 +0100 Subject: [PATCH 0671/5324] arm64: dts: r8a7795: Add BRG support for (H)SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depend on the actual board. Add the two optional clock sources (S3D1 and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF and HSCIF device nodes. This increases the range and accuracy of supported baud rates on (H)SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 74 +++++++++++++++++------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index ddeec7d7b6eb..9634e3a4858e 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -99,6 +99,14 @@ clock-frequency = <0>; }; + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + status = "disabled"; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -479,8 +487,10 @@ "renesas,hscif"; reg = <0 0xe6540000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 520>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 520>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x31>, <&dmac1 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -493,8 +503,10 @@ "renesas,hscif"; reg = <0 0xe6550000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 519>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 519>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x33>, <&dmac1 0x32>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -507,8 +519,10 @@ "renesas,hscif"; reg = <0 0xe6560000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 518>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 518>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x35>, <&dmac1 0x34>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -521,8 +535,10 @@ "renesas,hscif"; reg = <0 0xe66a0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 517>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 517>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x37>, <&dmac0 0x36>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -535,8 +551,10 @@ "renesas,hscif"; reg = <0 0xe66b0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 516>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 516>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x38>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -548,8 +566,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 207>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 207>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x51>, <&dmac1 0x50>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -561,8 +581,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 206>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 206>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x53>, <&dmac1 0x52>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -574,8 +596,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e88000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 310>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -587,8 +611,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c50000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 204>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 204>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x57>, <&dmac0 0x56>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -600,8 +626,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c40000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 203>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 203>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x59>, <&dmac0 0x58>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -613,8 +641,10 @@ "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6f30000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 202>; - clock-names = "fck"; + clocks = <&cpg CPG_MOD 202>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x5b>, <&dmac1 0x5a>; dma-names = "tx", "rx"; power-domains = <&cpg>; -- GitLab From a3fc85e27b7e3c29b30909929bc64737a19fd251 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:26 +0100 Subject: [PATCH 0672/5324] arm64: dts: salvator-x: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates: - SCIF: - Supports now 50, 230400, 460800, 500000, and 921600 bps, - Perfect match for standard 50-460800, and 9216000 bps. - HSCIF: - Supports now 50, 75, and 110 bps, - Perfect match for standard 50-460800, and 9216000 bps. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 9af1e3fdc468..31ace9c1f79d 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -93,6 +93,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif1_pins: scif1 { renesas,groups = "scif1_data_a", "scif1_ctrl"; renesas,function = "scif1"; @@ -101,6 +104,10 @@ renesas,groups = "scif2_data_a"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_a"; + renesas,function = "scif_clk"; + }; i2c2_pins: i2c2 { renesas,groups = "i2c2_a"; @@ -138,6 +145,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; -- GitLab From 68b2206a57c22d5b7c5bb16308a4afafe04d416d Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 20 Oct 2015 11:22:32 +0200 Subject: [PATCH 0673/5324] clk/samsung: exynos5433: add definitions of HDMI-PHY output clocks HDMI driver must re-parent respective muxes during HDMI-PHY on/off to HDMI-PHY output clocks. To reference those clocks their definitions should be added. Signed-off-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 6 ++++-- include/dt-bindings/clock/exynos5433.h | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index cee062c588de..55300142188b 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -2614,8 +2614,10 @@ static struct samsung_fixed_rate_clock disp_fixed_clks[] __initdata = { FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT, 100000000), /* PHY clocks from HDMI_PHY */ - FRATE(0, "phyclk_hdmiphy_tmds_clko_phy", NULL, CLK_IS_ROOT, 300000000), - FRATE(0, "phyclk_hdmiphy_pixel_clko_phy", NULL, CLK_IS_ROOT, 166000000), + FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy", + NULL, CLK_IS_ROOT, 300000000), + FRATE(CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY, "phyclk_hdmiphy_pixel_clko_phy", + NULL, CLK_IS_ROOT, 166000000), }; static struct samsung_mux_clock disp_mux_clks[] __initdata = { diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 5bd80d5ecd0f..4f0d5667ee9d 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -765,7 +765,10 @@ #define CLK_SCLK_RGB_VCLK 109 #define CLK_SCLK_RGB_TV_VCLK 110 -#define DISP_NR_CLK 111 +#define CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY 111 +#define CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY 112 + +#define DISP_NR_CLK 113 /* CMU_AUD */ #define CLK_MOUT_AUD_PLL_USER 1 -- GitLab From 02ed910cb4e1c3d03ef70efa94c08f5f580c7ff8 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 20 Oct 2015 11:22:33 +0200 Subject: [PATCH 0674/5324] clk/samsung: exynos5433: add pclk_decon clock This undocumented gate clock is used by DECON IP. Signed-off-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 2 ++ include/dt-bindings/clock/exynos5433.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 55300142188b..b7f1fb702e05 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -2822,6 +2822,8 @@ static struct samsung_gate_clock disp_gate_clks[] __initdata = { ENABLE_PCLK_DISP, 2, 0, 0), GATE(CLK_PCLK_DECON_TV, "pclk_decon_tv", "div_pclk_disp", ENABLE_PCLK_DISP, 1, 0, 0), + GATE(CLK_PCLK_DECON, "pclk_decon", "div_pclk_disp", + ENABLE_PCLK_DISP, 0, 0, 0), /* ENABLE_SCLK_DISP */ GATE(CLK_PHYCLK_MIPIDPHY1_BITCLKDIV8, "phyclk_mipidphy1_bitclkdiv8", diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 4f0d5667ee9d..5c2636cb9576 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -768,7 +768,9 @@ #define CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY 111 #define CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY 112 -#define DISP_NR_CLK 113 +#define CLK_PCLK_DECON 113 + +#define DISP_NR_CLK 114 /* CMU_AUD */ #define CLK_MOUT_AUD_PLL_USER 1 -- GitLab From 9c6672ac9c91f7eb1ec436be1442b8c26d098e55 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:06:55 +0000 Subject: [PATCH 0675/5324] efi: Expose non-blocking set_variable() wrapper to efivars Commit 6d80dba1c9fe ("efi: Provide a non-blocking SetVariable() operation") implemented a non-blocking alternative for the UEFI SetVariable() invocation performed by efivars, since it may occur in atomic context. However, this version of the function was never exposed via the efivars struct, so the non-blocking versions was not actually callable. Fix that. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Fixes: 6d80dba1c9fe ("efi: Provide a non-blocking SetVariable() operation") Link: http://lkml.kernel.org/r/1454364428-494-2-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/efi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 9b815c813687..20451c290233 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -182,6 +182,7 @@ static int generic_ops_register(void) { generic_ops.get_variable = efi.get_variable; generic_ops.set_variable = efi.set_variable; + generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; generic_ops.get_next_variable = efi.get_next_variable; generic_ops.query_variable_store = efi_query_variable_store; -- GitLab From 70d2a3cf2f4ae2e93b7a661842d84c2b5132cee7 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:06:56 +0000 Subject: [PATCH 0676/5324] efi: Remove redundant efi_set_variable_nonblocking() prototype There is no need for a separate nonblocking prototype definition for the SetVariable() UEFI Runtime Service, since it is identical to the blocking version. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-3-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- include/linux/efi.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/linux/efi.h b/include/linux/efi.h index 569b5a866bb1..8706e0aabedc 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -507,10 +507,6 @@ typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data); -typedef efi_status_t -efi_set_variable_nonblocking_t(efi_char16_t *name, efi_guid_t *vendor, - u32 attr, unsigned long data_size, void *data); - typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); typedef void efi_reset_system_t (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data); @@ -851,7 +847,7 @@ extern struct efi { efi_get_variable_t *get_variable; efi_get_next_variable_t *get_next_variable; efi_set_variable_t *set_variable; - efi_set_variable_nonblocking_t *set_variable_nonblocking; + efi_set_variable_t *set_variable_nonblocking; efi_query_variable_info_t *query_variable_info; efi_update_capsule_t *update_capsule; efi_query_capsule_caps_t *query_capsule_caps; @@ -1091,7 +1087,7 @@ struct efivar_operations { efi_get_variable_t *get_variable; efi_get_next_variable_t *get_next_variable; efi_set_variable_t *set_variable; - efi_set_variable_nonblocking_t *set_variable_nonblocking; + efi_set_variable_t *set_variable_nonblocking; efi_query_variable_store_t *query_variable_store; }; -- GitLab From d3cac1f83c631b9fe5edaebcba49f6989bfff089 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:06:57 +0000 Subject: [PATCH 0677/5324] efi/runtime-wrappers: Add a nonblocking version of QueryVariableInfo() This introduces a new runtime wrapper for the QueryVariableInfo() UEFI Runtime Service, which gives up immediately rather than spins on failure to grab the efi_runtime spinlock. This is required in the non-blocking path of the efi-pstore code. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-4-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/runtime-wrappers.c | 22 ++++++++++++++++++++++ include/linux/efi.h | 1 + 2 files changed, 23 insertions(+) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 228bbf910461..e9f2867f0d91 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -230,6 +230,27 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, return status; } +static efi_status_t +virt_efi_query_variable_info_nonblocking(u32 attr, + u64 *storage_space, + u64 *remaining_space, + u64 *max_variable_size) +{ + unsigned long flags; + efi_status_t status; + + if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) + return EFI_UNSUPPORTED; + + if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) + return EFI_NOT_READY; + + status = efi_call_virt(query_variable_info, attr, storage_space, + remaining_space, max_variable_size); + spin_unlock_irqrestore(&efi_runtime_lock, flags); + return status; +} + static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) { unsigned long flags; @@ -300,6 +321,7 @@ void efi_native_runtime_setup(void) efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; efi.reset_system = virt_efi_reset_system; efi.query_variable_info = virt_efi_query_variable_info; + efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking; efi.update_capsule = virt_efi_update_capsule; efi.query_capsule_caps = virt_efi_query_capsule_caps; } diff --git a/include/linux/efi.h b/include/linux/efi.h index 8706e0aabedc..ad1e177ba48e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -849,6 +849,7 @@ extern struct efi { efi_set_variable_t *set_variable; efi_set_variable_t *set_variable_nonblocking; efi_query_variable_info_t *query_variable_info; + efi_query_variable_info_t *query_variable_info_nonblocking; efi_update_capsule_t *update_capsule; efi_query_capsule_caps_t *query_capsule_caps; efi_get_next_high_mono_count_t *get_next_high_mono_count; -- GitLab From ca0e30dcaa53a3fcb2dfdf74252d30bc40603eea Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:06:58 +0000 Subject: [PATCH 0678/5324] efi: Add nonblocking option to efi_query_variable_store() The function efi_query_variable_store() may be invoked by efivar_entry_set_nonblocking(), which itself takes care to only call a non-blocking version of the SetVariable() runtime wrapper. However, efi_query_variable_store() may call the SetVariable() wrapper directly, as well as the wrapper for QueryVariableInfo(), both of which could deadlock in the same way we are trying to prevent by calling efivar_entry_set_nonblocking() in the first place. So instead, modify efi_query_variable_store() to use the non-blocking variants of QueryVariableInfo() (and give up rather than free up space if the available space is below EFI_MIN_RESERVE) if invoked with the 'nonblocking' argument set to true. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-5-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/quirks.c | 33 ++++++++++++++++++++++++++++++++- drivers/firmware/efi/vars.c | 16 ++++++++++++++-- include/linux/efi.h | 12 +++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 453504662a33..2326bf51978f 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -56,6 +56,33 @@ void efi_delete_dummy_variable(void) 0, NULL); } +/* + * In the nonblocking case we do not attempt to perform garbage + * collection if we do not have enough free space. Rather, we do the + * bare minimum check and give up immediately if the available space + * is below EFI_MIN_RESERVE. + * + * This function is intended to be small and simple because it is + * invoked from crash handler paths. + */ +static efi_status_t +query_variable_store_nonblocking(u32 attributes, unsigned long size) +{ + efi_status_t status; + u64 storage_size, remaining_size, max_size; + + status = efi.query_variable_info_nonblocking(attributes, &storage_size, + &remaining_size, + &max_size); + if (status != EFI_SUCCESS) + return status; + + if (remaining_size - size < EFI_MIN_RESERVE) + return EFI_OUT_OF_RESOURCES; + + return EFI_SUCCESS; +} + /* * Some firmware implementations refuse to boot if there's insufficient space * in the variable store. Ensure that we never use more than a safe limit. @@ -63,7 +90,8 @@ void efi_delete_dummy_variable(void) * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable * store. */ -efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +efi_status_t efi_query_variable_store(u32 attributes, unsigned long size, + bool nonblocking) { efi_status_t status; u64 storage_size, remaining_size, max_size; @@ -71,6 +99,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) return 0; + if (nonblocking) + return query_variable_store_nonblocking(attributes, size); + status = efi.query_variable_info(attributes, &storage_size, &remaining_size, &max_size); if (status != EFI_SUCCESS) diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 70a0fb10517f..d2a49626a335 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -234,7 +234,18 @@ check_var_size(u32 attributes, unsigned long size) if (!fops->query_variable_store) return EFI_UNSUPPORTED; - return fops->query_variable_store(attributes, size); + return fops->query_variable_store(attributes, size, false); +} + +static efi_status_t +check_var_size_nonblocking(u32 attributes, unsigned long size) +{ + const struct efivar_operations *fops = __efivars->ops; + + if (!fops->query_variable_store) + return EFI_UNSUPPORTED; + + return fops->query_variable_store(attributes, size, true); } static int efi_status_to_err(efi_status_t status) @@ -615,7 +626,8 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor, if (!spin_trylock_irqsave(&__efivars->lock, flags)) return -EBUSY; - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); + status = check_var_size_nonblocking(attributes, + size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { spin_unlock_irqrestore(&__efivars->lock, flags); return -ENOSPC; diff --git a/include/linux/efi.h b/include/linux/efi.h index ad1e177ba48e..09f1559e7525 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -525,7 +525,9 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, unsigned long count, u64 *max_size, int *reset_type); -typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size); +typedef efi_status_t efi_query_variable_store_t(u32 attributes, + unsigned long size, + bool nonblocking); void efi_native_runtime_setup(void); @@ -881,13 +883,17 @@ extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if pos #ifdef CONFIG_X86 extern void efi_late_init(void); extern void efi_free_boot_services(void); -extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size); +extern efi_status_t efi_query_variable_store(u32 attributes, + unsigned long size, + bool nonblocking); extern void efi_find_mirror(void); #else static inline void efi_late_init(void) {} static inline void efi_free_boot_services(void) {} -static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +static inline efi_status_t efi_query_variable_store(u32 attributes, + unsigned long size, + bool nonblocking) { return EFI_SUCCESS; } -- GitLab From 774846defceb16dcab2f0215cfc467f7c93f1c26 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:06:59 +0000 Subject: [PATCH 0679/5324] efi/runtime-wrappers: Remove out of date comment regarding in_nmi() This code is long gone, so remove the comment as well. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-6-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/runtime-wrappers.c | 26 ------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index e9f2867f0d91..311f415bff51 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -61,32 +61,6 @@ */ static DEFINE_SPINLOCK(efi_runtime_lock); -/* - * Some runtime services calls can be reentrant under NMI, even if the table - * above says they are not. (source: UEFI Specification v2.4A) - * - * Table 32. Functions that may be called after Machine Check, INIT and NMI - * +----------------------------+------------------------------------------+ - * | Function | Called after Machine Check, INIT and NMI | - * +----------------------------+------------------------------------------+ - * | GetTime() | Yes, even if previously busy. | - * | GetVariable() | Yes, even if previously busy | - * | GetNextVariableName() | Yes, even if previously busy | - * | QueryVariableInfo() | Yes, even if previously busy | - * | SetVariable() | Yes, even if previously busy | - * | UpdateCapsule() | Yes, even if previously busy | - * | QueryCapsuleCapabilities() | Yes, even if previously busy | - * | ResetSystem() | Yes, even if previously busy | - * +----------------------------+------------------------------------------+ - * - * In order to prevent deadlocks under NMI, the wrappers for these functions - * may only grab the efi_runtime_lock or rtc_lock spinlocks if !efi_in_nmi(). - * However, not all of the services listed are reachable through NMI code paths, - * so the the special handling as suggested by the UEFI spec is only implemented - * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI - * context through efi_pstore_write(). - */ - /* * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), * the EFI specification requires that callers of the time related runtime -- GitLab From 1bb6936473c07b5a7c8daced1000893b7145bb14 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 1 Feb 2016 22:07:00 +0000 Subject: [PATCH 0680/5324] efi: Runtime-wrapper: Get rid of the rtc_lock spinlock The rtc_lock spinlock aims to serialize access to the CMOS RTC between the UEFI firmware and the kernel drivers that use it directly. However, x86 is the only arch that performs such direct accesses, and that never uses the time related UEFI runtime services. Since no other UEFI enlightened architectures have a legcay CMOS RTC anyway, we can remove the rtc_lock spinlock entirely. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-7-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/runtime-wrappers.c | 32 +++++++------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 311f415bff51..7b8b2f2702ca 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -61,24 +61,14 @@ */ static DEFINE_SPINLOCK(efi_runtime_lock); -/* - * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), - * the EFI specification requires that callers of the time related runtime - * functions serialize with other CMOS accesses in the kernel, as the EFI time - * functions may choose to also use the legacy CMOS RTC. - */ -__weak DEFINE_SPINLOCK(rtc_lock); - static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(get_time, tm, tc); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -87,11 +77,9 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm) unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(set_time, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -102,11 +90,9 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(get_wakeup_time, enabled, pending, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } @@ -115,11 +101,9 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); - spin_lock(&efi_runtime_lock); + spin_lock_irqsave(&efi_runtime_lock, flags); status = efi_call_virt(set_wakeup_time, enabled, tm); - spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); + spin_unlock_irqrestore(&efi_runtime_lock, flags); return status; } -- GitLab From 9c09a342eb27902955ca939bd6ba29d875bd8b6b Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Mon, 1 Feb 2016 22:07:02 +0000 Subject: [PATCH 0681/5324] efivars: Use to_efivar_entry Use to_efivar_entry() instead of open-coding it. Signed-off-by: Geliang Tang Signed-off-by: Matt Fleming Link: http://lkml.kernel.org/r/1454364428-494-9-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/efivars.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 756eca8c4cf8..c5b0d2bc1111 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -386,7 +386,7 @@ static const struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { - struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); + struct efivar_entry *var = to_efivar_entry(kobj); kfree(var); } -- GitLab From 66dbe99cfe30e113d2e571e68b9b6a1a8985a157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=B4she=20van=20der=20Sterre?= Date: Mon, 1 Feb 2016 22:07:03 +0000 Subject: [PATCH 0682/5324] x86/efi/bgrt: Don't ignore the BGRT if the 'valid' bit is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unintuitively, the BGRT graphic is apparently meant to be usable if the valid bit in not set. The valid bit only conveys uncertainty about the validity in relation to the screen state. Windows 10 actually uses the BGRT image for its boot screen even if not 'valid', for example when the user triggered the boot menu. Because it is unclear if all firmwares will provide a usable graphic in this case, we now look at the BMP magic number as an additional check. Reviewed-by: Josh Triplett Signed-off-by: Môshe van der Sterre Signed-off-by: Matt Fleming Cc: =?UTF-8?q?M=C3=B4she=20van=20der=20Sterre?= Link: http://lkml.kernel.org/r/1454364428-494-10-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi-bgrt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index b0970661870a..a2433817c987 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -57,11 +57,6 @@ void __init efi_bgrt_init(void) bgrt_tab->status); return; } - if (bgrt_tab->status != 1) { - pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n", - bgrt_tab->status); - return; - } if (bgrt_tab->image_type != 0) { pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", bgrt_tab->image_type); @@ -80,6 +75,11 @@ void __init efi_bgrt_init(void) memcpy(&bmp_header, image, sizeof(bmp_header)); memunmap(image); + if (bmp_header.id != 0x4d42) { + pr_err("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", + bmp_header.id); + return; + } bgrt_image_size = bmp_header.size; bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); -- GitLab From 1e82b94790709fb2a22d16d53bb04d751fb3878d Mon Sep 17 00:00:00 2001 From: Robert Elliott Date: Mon, 1 Feb 2016 22:07:05 +0000 Subject: [PATCH 0683/5324] x86/efi: Show actual ending addresses in efi_print_memmap Adjust efi_print_memmap to print the real end address of each range, not 1 byte beyond. This matches other prints like those for SRAT and nosave memory. While investigating grub persistent memory corruption issues, it was helpful to make this table match the ending address convention used by: * the kernel's e820 table prints BIOS-e820: [mem 0x0000001680000000-0x0000001c7fffffff] reserved * the kernel's nosave memory prints PM: Registered nosave memory: [mem 0x880000000-0xc7fffffff] * the kernel's ACPI System Resource Affinity Table prints SRAT: Node 1 PXM 1 [mem 0x480000000-0x87fffffff] * grub's lsmmap and lsefimmap commands reserved 0000001680000000-0000001c7fffffff 00600000 24GiB UC WC WT WB NV * the UEFI shell's memmap command Reserved 000000007FC00000-000000007FFFFFFF 0000000000000400 0000000000000001 For example, if you grep all the various logs for c7fffffff, you won't find the kernel's line if it uses c80000000. Also, change the closing ) to ] to match the opening [. old: efi: mem61: [Persistent Memory | | | | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c80000000) (16384MB) new: efi: mem61: [Persistent Memory | | | | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c7fffffff] (16384MB) Signed-off-by: Robert Elliott Signed-off-by: Matt Fleming Reviewed-by: Laszlo Ersek Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Leif Lindholm Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-12-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- arch/x86/platform/efi/efi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index bdd9477f937c..e80826e6f3a9 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -235,10 +235,10 @@ void __init efi_print_memmap(void) char buf[64]; md = p; - pr_info("mem%02u: %s range=[0x%016llx-0x%016llx) (%lluMB)\n", + pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n", i, efi_md_typeattr_format(buf, sizeof(buf), md), md->phys_addr, - md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1, (md->num_pages >> (20 - EFI_PAGE_SHIFT))); } #endif /* EFI_DEBUG */ -- GitLab From c016ca08f89c6c78ed815f025262bdb87aba3f4c Mon Sep 17 00:00:00 2001 From: Robert Elliott Date: Mon, 1 Feb 2016 22:07:06 +0000 Subject: [PATCH 0684/5324] efi: Add NV memory attribute Add the NV memory attribute introduced in UEFI 2.5 and add a column for it in the types and attributes string used when printing the UEFI memory map. old: efi: mem61: [type=14 | | | | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c7fffffff) (16384MB) new: efi: mem61: [type=14 | | |NV| | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c7fffffff) (16384MB) Signed-off-by: Robert Elliott Signed-off-by: Matt Fleming Reviewed-by: Laszlo Ersek Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dan Williams Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Ross Zwisler Cc: Taku Izumi Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-13-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/efi.c | 5 ++++- include/linux/efi.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 20451c290233..f4370485c26a 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -582,13 +582,16 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else - snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + snprintf(pos, size, + "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", attr & EFI_MEMORY_RUNTIME ? "RUN" : "", attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_NV ? "NV" : "", attr & EFI_MEMORY_XP ? "XP" : "", attr & EFI_MEMORY_RP ? "RP" : "", attr & EFI_MEMORY_WP ? "WP" : "", diff --git a/include/linux/efi.h b/include/linux/efi.h index 09f1559e7525..3c6cbbdae4aa 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -97,6 +97,7 @@ typedef struct { #define EFI_MEMORY_WP ((u64)0x0000000000001000ULL) /* write-protect */ #define EFI_MEMORY_RP ((u64)0x0000000000002000ULL) /* read-protect */ #define EFI_MEMORY_XP ((u64)0x0000000000004000ULL) /* execute-protect */ +#define EFI_MEMORY_NV ((u64)0x0000000000008000ULL) /* non-volatile */ #define EFI_MEMORY_MORE_RELIABLE \ ((u64)0x0000000000010000ULL) /* higher reliability */ #define EFI_MEMORY_RO ((u64)0x0000000000020000ULL) /* read-only */ -- GitLab From 35575e0e8ba633fc8276509a21f89b599b4f9006 Mon Sep 17 00:00:00 2001 From: Robert Elliott Date: Mon, 1 Feb 2016 22:07:07 +0000 Subject: [PATCH 0685/5324] efi: Add Persistent Memory type name Add the "Persistent Memory" string for type 14 introduced in UEFI 2.5. This is used when printing the UEFI memory map. old: efi: mem61: [type=14 | | | | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c7fffffff) (16384MB) new: efi: mem61: [Persistent Memory | | | | | | | |WB|WT|WC|UC] range=[0x0000000880000000-0x0000000c7fffffff) (16384MB) Signed-off-by: Robert Elliott Signed-off-by: Matt Fleming Reviewed-by: Laszlo Ersek Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Borislav Petkov Cc: Brian Gerst Cc: Dan Williams Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Ross Zwisler Cc: Taku Izumi Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1454364428-494-14-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/efi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index f4370485c26a..3a69ed5ecfcb 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -555,7 +555,8 @@ static __initdata char memory_type_name[][20] = { "ACPI Memory NVS", "Memory Mapped I/O", "MMIO Port Space", - "PAL Code" + "PAL Code", + "Persistent Memory", }; char * __init efi_md_typeattr_format(char *buf, size_t size, -- GitLab From b2435692dbb709d4c8ff3b2f2815c9b8423b72bb Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Tue, 2 Feb 2016 22:06:51 -0800 Subject: [PATCH 0686/5324] drm/i915: Pretend cursor is always on for ILK-style WM calculations (v2) Due to our lack of two-step watermark programming, our driver has historically pretended that the cursor plane is always on for the purpose of watermark calculations; this helps avoid serious flickering when the cursor turns off/on (e.g., when the user moves the mouse pointer to a different screen). That workaround was accidentally dropped as we started working toward atomic watermark updates. Since we still aren't quite there yet with two-stage updates, we need to resurrect the workaround and treat the cursor as always active. v2: Tweak cursor width calculations slightly to more closely match the logic we used before the atomic overhaul began. (Ville) Cc: simdev11@outlook.com Cc: manfred.kitzbichler@gmail.com Cc: drm-intel-fixes@lists.freedesktop.org Reported-by: simdev11@outlook.com Reported-by: manfred.kitzbichler@gmail.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93892 Fixes: 43d59eda1 ("drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code (v2)") Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1454479611-6804-1-git-send-email-matthew.d.roper@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a47b8f219357..3da7935c1665 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1799,16 +1799,20 @@ static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate, const struct intel_plane_state *pstate, uint32_t mem_value) { - int cpp = pstate->base.fb ? - drm_format_plane_cpp(pstate->base.fb->pixel_format, 0) : 0; + /* + * We treat the cursor plane as always-on for the purposes of watermark + * calculation. Until we have two-stage watermark programming merged, + * this is necessary to avoid flickering. + */ + int cpp = 4; + int width = pstate->visible ? pstate->base.crtc_w : 64; - if (!cstate->base.active || !pstate->visible) + if (!cstate->base.active) return 0; return ilk_wm_method2(ilk_pipe_pixel_rate(cstate), cstate->base.adjusted_mode.crtc_htotal, - drm_rect_width(&pstate->dst), - cpp, mem_value); + width, cpp, mem_value); } /* Only for WM_LP. */ -- GitLab From de4726649b6b1d7f3f02b2031ee99e067cb71e2d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 Jan 2016 18:32:31 +0000 Subject: [PATCH 0687/5324] drm/i915: Allow i915_gem_object_get_page() on userptr as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 033908aed5a596f6202c848c6bbc8a40fb1a8490 Author: Dave Gordon Date: Thu Dec 10 18:51:23 2015 +0000 drm/i915: mark GEM object pages dirty when mapped & written by the CPU introduced a check into i915_gem_object_get_dirty_pages() that returned a NULL pointer when called with a bad object, one that was not backed by shmemfs. This WARN was too strict as we can work on all struct page backed objects, and resulted in a WARN + GPF for existing userspace. In order to differentiate the various types of objects, add a new flags field to the i915_gem_object_ops struct to describe their capabilities, with the first flag being whether the object has struct pages. v2: Drop silly const before an integer in the structure declaration. Testcase: igt/gem_userptr_blits/relocations Reported-and-tested-by: Kristian Høgsberg Kristensen Signed-off-by: Chris Wilson Cc: Dave Gordon Cc: Kristian Høgsberg Kristensen Cc: Daniel Vetter Reviewed-by: Dave Gordon Reviewed-by: Kristian Høgsberg Kristensen Tested-by: Michal Winiarski Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1453487551-16799-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/i915_gem.c | 3 ++- drivers/gpu/drm/i915/i915_gem_userptr.c | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65a2cd04bc8f..77227a39f3d5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2038,6 +2038,9 @@ enum hdmi_force_audio { #define I915_GTT_OFFSET_NONE ((u32)-1) struct drm_i915_gem_object_ops { + unsigned int flags; +#define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1 + /* Interface between the GEM object and its backing storage. * get_pages() is called once prior to the use of the associated set * of pages before to binding them into the GTT, and put_pages() is @@ -2053,6 +2056,7 @@ struct drm_i915_gem_object_ops { */ int (*get_pages)(struct drm_i915_gem_object *); void (*put_pages)(struct drm_i915_gem_object *); + int (*dmabuf_export)(struct drm_i915_gem_object *); void (*release)(struct drm_i915_gem_object *); }; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a928823507c5..e9b19bca1383 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4465,6 +4465,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, } static const struct drm_i915_gem_object_ops i915_gem_object_ops = { + .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE, .get_pages = i915_gem_object_get_pages_gtt, .put_pages = i915_gem_object_put_pages_gtt, }; @@ -5309,7 +5310,7 @@ i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n) struct page *page; /* Only default objects have per-page dirty tracking */ - if (WARN_ON(obj->ops != &i915_gem_object_ops)) + if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0)) return NULL; page = i915_gem_object_get_page(obj, n); diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 74a4d1714879..7107f2fd38f5 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -708,9 +708,10 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) } static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { - .dmabuf_export = i915_gem_userptr_dmabuf_export, + .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE, .get_pages = i915_gem_userptr_get_pages, .put_pages = i915_gem_userptr_put_pages, + .dmabuf_export = i915_gem_userptr_dmabuf_export, .release = i915_gem_userptr_release, }; -- GitLab From 58d4d32f431a560baff5fbb6deae8ad324552dde Mon Sep 17 00:00:00 2001 From: Ramalingam C Date: Wed, 3 Feb 2016 18:20:46 +0530 Subject: [PATCH 0688/5324] drm/i915/dsi: Configure DSI after enabling DSI pll We need to enable DSI PLL before configuring the DSI registers. This has worked before on BYT/CHV, but BXT is more fussy. Signed-off-by: Ramalingam C Reviewed-by: Mika Kahola Tested-by: Mika Kahola # BXT Tested-by: Jani Nikula # BYT Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454503846-12103-1-git-send-email-ramalingam.c@intel.com --- drivers/gpu/drm/i915/intel_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 91cef3525c93..378f879f4015 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -478,8 +478,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) DRM_DEBUG_KMS("\n"); - intel_dsi_prepare(encoder); intel_enable_dsi_pll(encoder); + intel_dsi_prepare(encoder); /* Panel Enable over CRC PMIC */ if (intel_dsi->gpio_panel) -- GitLab From c5dee34e5c124381d3c2c5052c1c891e914543b3 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 31 Jan 2016 09:20:58 +0800 Subject: [PATCH 0689/5324] ARM: dts: sun8i-a83t: Correct low speed oscillator clocks The A83T does not have a 32.768 kHz low speed oscillator, either as an external crystal or input. It has a 16 MHz RC-based (inaccurate) internal oscillator, which is then divided by 512 for a clock close to 32 kHz. Signed-off-by: Chen-Yu Tsai Signed-off-by: Vishnu Patekar Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a83t.dtsi | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 8d27b6381257..d3473f81b12f 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -118,6 +118,7 @@ #size-cells = <1>; ranges; + /* TODO: PRCM block has a mux for this. */ osc24M: osc24M_clk { #clock-cells = <0>; compatible = "fixed-clock"; @@ -125,11 +126,25 @@ clock-output-names = "osc24M"; }; - osc32k: osc32k_clk { + /* + * This is called "internal OSC" in some places. + * It is an internal RC-based oscillator. + * TODO: Its controls are in the PRCM block. + */ + osc16M: osc16M_clk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "osc32k"; + clock-frequency = <16000000>; + clock-output-names = "osc16M"; + }; + + osc16Md512: osc16Md512_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <512>; + clock-mult = <1>; + clocks = <&osc16M>; + clock-output-names = "osc16M-d512"; }; }; -- GitLab From aebe3ad801ebbcd90b3649c24ae0e90d2db8bde8 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 27 Jan 2016 21:38:37 +0100 Subject: [PATCH 0690/5324] clk: rockchip: fix parent of hclk_vcodec on rk3036 hclk_vcodec is a child of aclk_vcodec with the fixed factor clock hclk_vcodec_pre in between and not a child of hclk_disp_pre. Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 9c317a3b81e5..38139dce9f7e 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -380,7 +380,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), -- GitLab From 0c1690705417ac1b33f01125552349e3cfc9766d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Jan 2016 16:20:47 +0100 Subject: [PATCH 0691/5324] ARM: shmobile: rcar-gen2: Make rcar_gen2_dma_contiguous static make C=1: arch/arm/mach-shmobile/setup-rcar-gen2.c:186:12: warning: symbol 'rcar_gen2_dma_contiguous' was not declared. Should it be static? Make it static, and move it inside the function to avoid a "defined but not used" warning if CONFIG_DMA_CMA=n. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-rcar-gen2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 9eccde3c7b13..6d0ebdfb03a2 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -182,8 +182,6 @@ static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, return 0; } -struct cma *rcar_gen2_dma_contiguous; - void __init rcar_gen2_reserve(void) { struct memory_reserve_config mrc; @@ -194,8 +192,11 @@ void __init rcar_gen2_reserve(void) of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); #ifdef CONFIG_DMA_CMA - if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) + if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) { + static struct cma *rcar_gen2_dma_contiguous; + dma_contiguous_reserve_area(mrc.size, mrc.base, 0, &rcar_gen2_dma_contiguous, true); + } #endif } -- GitLab From 2e41e5fe88f99c03a77c4325870f160378b42268 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Jan 2016 16:20:48 +0100 Subject: [PATCH 0692/5324] ARM: shmobile: Add includes providing forward declarations make C=1: arch/arm/mach-shmobile/timer.c:38:13: warning: symbol 'shmobile_init_delay' was not declared. Should it be static? arch/arm/mach-shmobile/suspend.c:37:29: warning: symbol 'shmobile_suspend_ops' was not declared. Should it be static? arch/arm/mach-shmobile/suspend.c:44:12: warning: symbol 'shmobile_suspend_init' was not declared. Should it be static? arch/arm/mach-shmobile/cpufreq.c:13:12: warning: symbol 'shmobile_cpufreq_init' was not declared. Should it be static? Include "common.h" to fix these. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/cpufreq.c | 2 ++ arch/arm/mach-shmobile/suspend.c | 2 ++ arch/arm/mach-shmobile/timer.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/mach-shmobile/cpufreq.c b/arch/arm/mach-shmobile/cpufreq.c index 57fbff024dcd..634d701c56a7 100644 --- a/arch/arm/mach-shmobile/cpufreq.c +++ b/arch/arm/mach-shmobile/cpufreq.c @@ -10,6 +10,8 @@ #include +#include "common.h" + int __init shmobile_cpufreq_init(void) { platform_device_register_simple("cpufreq-dt", -1, NULL, 0); diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index 5d92b5dd486b..74b30bade2c1 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -17,6 +17,8 @@ #include #include +#include "common.h" + static int shmobile_suspend_default_enter(suspend_state_t suspend_state) { cpu_do_idle(); diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index c17d4d3881ff..ad008e4b0c49 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -18,6 +18,8 @@ #include #include +#include "common.h" + static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, unsigned int mult, unsigned int div) { -- GitLab From e24f317c859f2d904d1eb87cbb503c309e6dead7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Jan 2016 16:13:30 +0100 Subject: [PATCH 0693/5324] ARM: shmobile: Typo s/MIPDR/MPIDR/ The ARM Multiprocessor Affinity Register is called "MPIDR". Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/headsmp-scu.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S index fa5248c52399..c0008a5aa4ca 100644 --- a/arch/arm/mach-shmobile/headsmp-scu.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -27,7 +27,7 @@ */ ENTRY(shmobile_boot_scu) @ r0 = SCU base address - mrc p15, 0, r1, c0, c0, 5 @ read MIPDR + mrc p15, 0, r1, c0, c0, 5 @ read MPIDR and r1, r1, #3 @ mask out cpu ID lsl r1, r1, #3 @ we will shift by cpu_id * 8 bits ldr r2, [r0, #8] @ SCU Power Status Register -- GitLab From cdef6b0b6ff40da9a55c8175206c45635428d9fe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 28 Jan 2016 16:13:31 +0100 Subject: [PATCH 0694/5324] ARM: shmobile: r8a7779: Remove remainings of removed SCU boot setup code Commit 0ca2894b5a900709 ("ARM: shmobile: Use shared SCU SMP boot code on r8a7779") obsoleted the r8a7779-specific SCU boot code, but forgot to remove the setup of shmobile_boot_fn and shmobile_boot_arg, which is overwritten by shmobile_smp_scu_prepare_cpus(). Note that shmobile_scu_base wasn't initialized at that point yet anyway. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/smp-r8a7779.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index b854fe2095ad..0b024a9dbd43 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -92,8 +92,6 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ __raw_writel(__pa(shmobile_boot_vector), AVECR); - shmobile_boot_fn = virt_to_phys(shmobile_boot_scu); - shmobile_boot_arg = (unsigned long)shmobile_scu_base; /* setup r8a7779 specific SCU bits */ shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); -- GitLab From d5165ebd527c54bbe3761fd5810dede32b5246a3 Mon Sep 17 00:00:00 2001 From: Tim Gore Date: Thu, 4 Feb 2016 11:49:34 +0000 Subject: [PATCH 0695/5324] drm/i915: implement WaIncreaseDefaultTLBEntries WaIncreaseDefaultTLBEntries increases the number of TLB entries available for GPGPU workloads and gives significant ( > 10% ) performance gain for some OCL benchmarks. Put this in a new function that can be a place for workarounds that are GT related but not required per ring. This function is called on driver load and also after a reset and on resume, so it is safe for workarounds that get clobbered in these situations. This function currently has just this one workaround. v2: This was originally split into 3 patches but following review feedback was squashed into 1. I have not incorporated some style comments from Chris Wilson as I felt that after defining and intialising a temporary variable and then adding an additional if block to only write the register if the temporary variable had been set, this didn't really give a net gain. v3: Resending in the hope that BAT will run v4: Change subject line to trigger BAT (please!) Signed-off-by: Tim Gore Reviewed-by: Mika Kuoppala Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1454586574-2343-1-git-send-email-tim.gore@intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 21 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 715a771f0b31..9127f8f3561c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2132,6 +2132,25 @@ static void i915_address_space_init(struct i915_address_space *vm, list_add_tail(&vm->global_link, &dev_priv->vm_list); } +static void gtt_write_workarounds(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + /* This function is for gtt related workarounds. This function is + * called on driver load and after a GPU reset, so you can place + * workarounds here even if they get overwritten by GPU reset. + */ + /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt */ + if (IS_BROADWELL(dev)) + I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW); + else if (IS_CHERRYVIEW(dev)) + I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV); + else if (IS_SKYLAKE(dev)) + I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL); + else if (IS_BROXTON(dev)) + I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT); +} + int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -2148,6 +2167,8 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) int i915_ppgtt_init_hw(struct drm_device *dev) { + gtt_write_workarounds(dev); + /* In the case of execlists, PPGTT is enabled by the context descriptor * and the PDPs are contained within the context itself. We don't * need to do anything here. */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c0bd691b41f8..ec6444ae6e2f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8173,4 +8173,11 @@ enum skl_disp_power_wells { #define GEN9_VEBOX_MOCS(i) _MMIO(0xcb00 + (i) * 4) /* Video MOCS registers */ #define GEN9_BLT_MOCS(i) _MMIO(0xcc00 + (i) * 4) /* Blitter MOCS registers */ +/* gamt regs */ +#define GEN8_L3_LRA_1_GPGPU _MMIO(0x4dd4) +#define GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW 0x67F1427F /* max/min for LRA1/2 */ +#define GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV 0x5FF101FF /* max/min for LRA1/2 */ +#define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL 0x67F1427F /* " " */ +#define GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT 0x5FF101FF /* " " */ + #endif /* _I915_REG_H_ */ -- GitLab From 29a30c269aba4223e2a8b443f443d7def1e43fea Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 20 Jun 2015 13:08:57 +0200 Subject: [PATCH 0696/5324] clk: rockchip: add a factor clock type Add a clock type for fixed factor clocks. This allows us to define fixed factor clocks where they appear in the clock hierarchy instead of in the init function. The additional factor_gate type, finally allows us to model some last parts of the clock tree correctly. Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk.c | 55 ++++++++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h | 28 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 62fbe2c6eaaf..ab5052478870 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -265,6 +265,53 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, return clk; } +static struct clk *rockchip_clk_register_factor_branch(const char *name, + const char *const *parent_names, u8 num_parents, + void __iomem *base, unsigned int mult, unsigned int div, + int gate_offset, u8 gate_shift, u8 gate_flags, + unsigned long flags, spinlock_t *lock) +{ + struct clk *clk; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix = NULL; + + /* without gate, register a simple factor clock */ + if (gate_offset == 0) { + return clk_register_fixed_factor(NULL, name, + parent_names[0], flags, mult, + div); + } + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->flags = gate_flags; + gate->reg = base + gate_offset; + gate->bit_idx = gate_shift; + gate->lock = lock; + + fix = kzalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) { + kfree(gate); + return ERR_PTR(-ENOMEM); + } + + fix->mult = mult; + fix->div = div; + + clk = clk_register_composite(NULL, name, parent_names, num_parents, + NULL, NULL, + &fix->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + kfree(fix); + kfree(gate); + } + + return clk; +} + static DEFINE_SPINLOCK(clk_lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -400,6 +447,14 @@ void __init rockchip_clk_register_branches( reg_base + list->muxdiv_offset, list->div_shift, list->div_flags, &clk_lock); break; + case branch_factor: + clk = rockchip_clk_register_factor_branch( + list->name, list->parent_names, + list->num_parents, reg_base, + list->div_shift, list->div_width, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ff8bd23a93ec..39c198bbcbee 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -254,6 +254,7 @@ enum rockchip_clk_branch_type { branch_gate, branch_mmc, branch_inverter, + branch_factor, }; struct rockchip_clk_branch { @@ -508,6 +509,33 @@ struct rockchip_clk_branch { .div_flags = if, \ } +#define FACTOR(_id, cname, pname, f, fm, fd) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + } + +#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + .gate_offset = go, \ + .gate_shift = gb, \ + .gate_flags = gf, \ + } + void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); struct regmap *rockchip_clk_get_grf(void); -- GitLab From 36714529f8bbd4f8eaf93b50f4a64c52a24879aa Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 20 Jun 2015 16:06:02 +0200 Subject: [PATCH 0697/5324] clk: rockchip: convert manually created factor clocks to the new type Clean up the init code and move the creation of factor clocks to the appropriate positions coming from the clock architecture diagrams. This also unifies the artificial separation of the hclk_vcodec etc clocks again. We do keep the separate definition of some watchdog and usb480m pseudo clocks for now, as they're not real factor clocks from the clock-tree but placeholders for fixes to come (usb480m gets supplied by the missing driver for the new usbphy type and the watchdog-gate is sitting somewhere else together which we cannot model currently). Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 31 ++++++------------------------ drivers/clk/rockchip/clk-rk3188.c | 9 ++------- drivers/clk/rockchip/clk-rk3228.c | 32 +++++-------------------------- drivers/clk/rockchip/clk-rk3288.c | 22 +++++---------------- drivers/clk/rockchip/clk-rk3368.c | 28 ++++++--------------------- 5 files changed, 24 insertions(+), 98 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 38139dce9f7e..5759d75780cf 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -177,6 +177,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 6, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * Clock-Architecture Diagram 2 */ @@ -187,6 +189,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 8, GFLAGS), COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + FACTOR(0, "ddrphy", "ddrphy2x", 0, 1, 2), COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, @@ -263,6 +266,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), + FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, + RK2928_CLKGATE_CON(3), 12, GFLAGS), COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS, @@ -351,6 +356,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0, RK2928_CLKSEL_CON(21), 9, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), + FACTOR(0, "sclk_macref_out", "hclk_peri_src", 0, 1, 2), MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0, RK2928_CLKSEL_CON(31), 0, 1, MFLAGS), @@ -379,8 +385,6 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), - /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), @@ -444,34 +448,11 @@ static void __init rk3036_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); if (IS_ERR(clk)) pr_warn("%s: could not register clock usb480m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "aclk_vcodec", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "sclk_macref_out", - "hclk_peri_src", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock sclk_macref_out: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3036_pll_clks, ARRAY_SIZE(rk3036_pll_clks), RK3036_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 629c65df1f2d..40bab3901491 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -339,6 +339,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { INVERTER(0, "pclk_cif0", "pclkin_cif0", RK2928_CLKSEL_CON(30), 8, IFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. @@ -754,7 +756,6 @@ static const char *const rk3188_critical_clocks[] __initconst = { static void __init rk3188_common_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -764,12 +765,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 97f49aab8d42..c515915850a1 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -187,7 +187,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(7), 1, GFLAGS), GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 5, GFLAGS), - GATE(0, "ddrphy", "ddrphy_pre", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, RK2928_CLKGATE_CON(7), 0, GFLAGS), /* PD_CORE */ @@ -240,13 +240,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - GATE(0, "hclk_vpu_src", "aclk_vpu_pre", 0, + FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - GATE(0, "hclk_rkvdec_src", "aclk_rkvdec_pre", 0, + FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, @@ -371,6 +371,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { MUX(0, "dclk_vop", mux_dclk_vop_p, 0, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 3, GFLAGS), @@ -624,7 +626,6 @@ static const char *const rk3228_critical_clocks[] __initconst = { static void __init rk3228_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -634,29 +635,6 @@ static void __init rk3228_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "ddrphy_pre", "ddrphy4x", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vpu_pre", - "hclk_vpu_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vpu_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_rkvdec_pre", - "hclk_rkvdec_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_rkvdec_pre: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3228_pll_clks, ARRAY_SIZE(rk3228_pll_clks), RK3228_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 0d23937c594a..3cb72163a512 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -333,6 +333,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 1, GFLAGS), @@ -399,12 +401,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, RK3288_CLKGATE_CON(9), 0, GFLAGS), - /* - * We introduce a virtul node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. - */ - GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, + + FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vdpu", 0, 1, 4, RK3288_CLKGATE_CON(3), 10, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), @@ -888,18 +888,6 @@ static void __init rk3288_clk_init(struct device_node *np) rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "hclk_vcodec_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index e90abe8bf7c0..31facd8426f7 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -248,6 +248,8 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + MUX(SCLK_USBPHY480M, "usbphy_480m", mux_usbphy480m_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(13), 8, 1, MFLAGS), @@ -299,7 +301,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_NOGATE_DIVTBL(0, "ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(13), 4, 1, MFLAGS, 0, 2, DFLAGS, div_ddrphy_t), - GATE(0, "sclk_ddr", "ddrphy_div4", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "sclk_ddr", "ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, RK3368_CLKGATE_CON(6), 14, GFLAGS), GATE(0, "sclk_ddr4x", "ddrphy_src", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(6), 15, GFLAGS), @@ -392,10 +394,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { RK3368_CLKGATE_CON(4), 7, GFLAGS), /* - * We introduce a virtual node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. + * We use aclk_vdpu by default ---GRF_SOC_CON0[7] setting in system, + * so we ignore the mux and make clocks nodes as following, */ - GATE(0, "hclk_video_pre_v", "aclk_vdpu", 0, + FACTOR_GATE(0, "hclk_video_pre", "aclk_vdpu", 0, 1, 4, RK3368_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE(0, "sclk_hevc_cabac_src", mux_pll_src_cpll_gpll_npll_usb_p, 0, @@ -842,24 +844,6 @@ static void __init rk3368_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - /* ddrphy_div4 is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "ddrphy_div4", "ddrphy_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_video_pre", - "hclk_video_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) -- GitLab From 3eb7c38bfed5dc6ea0e24c8bc2fd249760bdde8c Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 29 Jan 2016 18:57:38 -0200 Subject: [PATCH 0698/5324] drm/i915: don't deactivate FBC at skylake_disable_primary_plane FBC is already deactivated at this point. Besides, nothing should be calling these lower-level function pointers. A few months ago, the only caller of dev_priv->fbc.deactivate was intel_pipe_set_base_atomic(), which was the kgdboc function. But the following commit added it to the SKL function: commit a8d201af68506b375b701d0d8dbe8487034256f2 Author: Maarten Lankhorst Date: Thu Jan 7 11:54:11 2016 +0100 drm/i915: Use plane state for primary plane updates. Cc: Maarten Lankhorst Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1454101060-23198-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_display.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a66220ad2e4a..186d6cadba84 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3156,9 +3156,6 @@ static void skylake_disable_primary_plane(struct drm_plane *primary, struct drm_i915_private *dev_priv = dev->dev_private; int pipe = to_intel_crtc(crtc)->pipe; - if (dev_priv->fbc.deactivate) - dev_priv->fbc.deactivate(dev_priv); - I915_WRITE(PLANE_CTL(pipe, 0), 0); I915_WRITE(PLANE_SURF(pipe, 0), 0); POSTING_READ(PLANE_SURF(pipe, 0)); -- GitLab From 8c40074cb219f8e5e6122d17fad869bc43c3e9df Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 29 Jan 2016 18:57:39 -0200 Subject: [PATCH 0699/5324] drm/i915/fbc: unexport the HW level activation functions The recent introduction of a new caller of dev_priv->fbc.deactivate() is a good example of why we need unexport those functions. Anything outside intel_fbc.c should only call the functions exported by intel_fbc.c, so in order to enforce that, kill the function pointers stored inside dev_priv->fbc and replace them with functions that can't be called from outside intel_fbc.c. This should make it much harder for new code to call these functions from outside intel_fbc.c. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1454101060-23198-2-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 -- drivers/gpu/drm/i915/intel_fbc.c | 65 ++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 77227a39f3d5..856bfe8d1f42 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -964,10 +964,6 @@ struct intel_fbc { } work; const char *no_fbc_reason; - - bool (*is_active)(struct drm_i915_private *dev_priv); - void (*activate)(struct drm_i915_private *dev_priv); - void (*deactivate)(struct drm_i915_private *dev_priv); }; /** diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 5adf6d7620ad..8d3caf26fc53 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -43,7 +43,7 @@ static inline bool fbc_supported(struct drm_i915_private *dev_priv) { - return dev_priv->fbc.activate != NULL; + return HAS_FBC(dev_priv); } static inline bool fbc_on_pipe_a_only(struct drm_i915_private *dev_priv) @@ -343,6 +343,38 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) intel_fbc_recompress(dev_priv); } +static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv) +{ + if (INTEL_INFO(dev_priv)->gen >= 5) + return ilk_fbc_is_active(dev_priv); + else if (IS_GM45(dev_priv)) + return g4x_fbc_is_active(dev_priv); + else + return i8xx_fbc_is_active(dev_priv); +} + +static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv) +{ + if (INTEL_INFO(dev_priv)->gen >= 7) + gen7_fbc_activate(dev_priv); + else if (INTEL_INFO(dev_priv)->gen >= 5) + ilk_fbc_activate(dev_priv); + else if (IS_GM45(dev_priv)) + g4x_fbc_activate(dev_priv); + else + i8xx_fbc_activate(dev_priv); +} + +static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv) +{ + if (INTEL_INFO(dev_priv)->gen >= 5) + ilk_fbc_deactivate(dev_priv); + else if (IS_GM45(dev_priv)) + g4x_fbc_deactivate(dev_priv); + else + i8xx_fbc_deactivate(dev_priv); +} + /** * intel_fbc_is_active - Is FBC active? * @dev_priv: i915 device instance @@ -405,7 +437,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) goto retry; } - fbc->activate(dev_priv); + intel_fbc_hw_activate(dev_priv); work->scheduled = false; @@ -451,7 +483,7 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) fbc->work.scheduled = false; if (fbc->active) - fbc->deactivate(dev_priv); + intel_fbc_hw_deactivate(dev_priv); } static bool multiple_pipes_ok(struct intel_crtc *crtc) @@ -713,7 +745,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc) /* FIXME: We lack the proper locking here, so only run this on the * platforms that need. */ - if (dev_priv->fbc.activate == ilk_fbc_activate) + if (INTEL_INFO(dev_priv)->gen >= 5 && INTEL_INFO(dev_priv)->gen < 7) cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); cache->fb.pixel_format = fb->pixel_format; cache->fb.stride = fb->pitches[0]; @@ -1223,30 +1255,13 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) break; } - if (INTEL_INFO(dev_priv)->gen >= 7) { - fbc->is_active = ilk_fbc_is_active; - fbc->activate = gen7_fbc_activate; - fbc->deactivate = ilk_fbc_deactivate; - } else if (INTEL_INFO(dev_priv)->gen >= 5) { - fbc->is_active = ilk_fbc_is_active; - fbc->activate = ilk_fbc_activate; - fbc->deactivate = ilk_fbc_deactivate; - } else if (IS_GM45(dev_priv)) { - fbc->is_active = g4x_fbc_is_active; - fbc->activate = g4x_fbc_activate; - fbc->deactivate = g4x_fbc_deactivate; - } else { - fbc->is_active = i8xx_fbc_is_active; - fbc->activate = i8xx_fbc_activate; - fbc->deactivate = i8xx_fbc_deactivate; - - /* This value was pulled out of someone's hat */ + /* This value was pulled out of someone's hat */ + if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_GM45(dev_priv)) I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); - } /* We still don't have any sort of hardware state readout for FBC, so * deactivate it in case the BIOS activated it to make sure software * matches the hardware state. */ - if (fbc->is_active(dev_priv)) - fbc->deactivate(dev_priv); + if (intel_fbc_hw_is_active(dev_priv)) + intel_fbc_hw_deactivate(dev_priv); } -- GitLab From 5375ce9f38291c1d725db40519465dfe89c60ea9 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 29 Jan 2016 18:57:40 -0200 Subject: [PATCH 0700/5324] drm/i915/fbc: set fbc->active from the new activation functions Now that we have top-level gen-independent hw_activate and hw_deactivate functions, set fbc->active directly from them, removing the duplicated code. Reviewed-by: Maarten Lankhorst Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1454101060-23198-3-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 8d3caf26fc53..3614a951736b 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -115,8 +115,6 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) { u32 fbc_ctl; - dev_priv->fbc.active = false; - /* Disable compression */ fbc_ctl = I915_READ(FBC_CONTROL); if ((fbc_ctl & FBC_CTL_EN) == 0) @@ -139,8 +137,6 @@ static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) int i; u32 fbc_ctl; - dev_priv->fbc.active = true; - /* Note: fbc.threshold == 1 for i8xx */ cfb_pitch = params->cfb_size / FBC_LL_SIZE; if (params->fb.stride < cfb_pitch) @@ -187,8 +183,6 @@ static void g4x_fbc_activate(struct drm_i915_private *dev_priv) struct intel_fbc_reg_params *params = &dev_priv->fbc.params; u32 dpfc_ctl; - dev_priv->fbc.active = true; - dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane) | DPFC_SR_EN; if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) dpfc_ctl |= DPFC_CTL_LIMIT_2X; @@ -206,8 +200,6 @@ static void g4x_fbc_deactivate(struct drm_i915_private *dev_priv) { u32 dpfc_ctl; - dev_priv->fbc.active = false; - /* Disable compression */ dpfc_ctl = I915_READ(DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { @@ -234,8 +226,6 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv) u32 dpfc_ctl; int threshold = dev_priv->fbc.threshold; - dev_priv->fbc.active = true; - dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane); if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) threshold++; @@ -274,8 +264,6 @@ static void ilk_fbc_deactivate(struct drm_i915_private *dev_priv) { u32 dpfc_ctl; - dev_priv->fbc.active = false; - /* Disable compression */ dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { @@ -295,8 +283,6 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv) u32 dpfc_ctl; int threshold = dev_priv->fbc.threshold; - dev_priv->fbc.active = true; - dpfc_ctl = 0; if (IS_IVYBRIDGE(dev_priv)) dpfc_ctl |= IVB_DPFC_CTL_PLANE(params->crtc.plane); @@ -355,6 +341,10 @@ static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv) static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + + fbc->active = true; + if (INTEL_INFO(dev_priv)->gen >= 7) gen7_fbc_activate(dev_priv); else if (INTEL_INFO(dev_priv)->gen >= 5) @@ -367,6 +357,10 @@ static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv) static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv) { + struct intel_fbc *fbc = &dev_priv->fbc; + + fbc->active = false; + if (INTEL_INFO(dev_priv)->gen >= 5) ilk_fbc_deactivate(dev_priv); else if (IS_GM45(dev_priv)) -- GitLab From 5d2d0a12d3d08bf50434f0b5947bb73bac04b941 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 4 Feb 2016 12:50:49 +0200 Subject: [PATCH 0701/5324] drm/i915/dsi: defend gpio table against out of bounds access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not blindly trust the VBT data used for indexing. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/cc32d40c2b47f2d2151811855ac2c3dabab1d57d.1454582914.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 1d43e6f37fc1..4775aa5462e8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -209,6 +209,11 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) /* pull up/down */ action = *data++; + if (gpio >= ARRAY_SIZE(gtable)) { + DRM_DEBUG_KMS("unknown gpio %u\n", gpio); + goto out; + } + function = gtable[gpio].function_reg; pad = gtable[gpio].pad_reg; @@ -226,6 +231,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) vlv_gpio_nc_write(dev_priv, pad, val); mutex_unlock(&dev_priv->sb_lock); +out: return data; } -- GitLab From 4e1c63e3761b84ec7d87c75b58bbc8bcf18e98ee Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 4 Feb 2016 12:50:50 +0200 Subject: [PATCH 0702/5324] drm/i915/dsi: don't pass arbitrary data to sideband MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since sequence block v2 the second byte contains flags other than just pull up/down. Don't pass arbitrary data to the sideband interface. The rest may or may not work for sequence block v2, but there should be no harm done. Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/ebe3c2eee623afc4b3a134533b01f8d591d13f32.1454582914.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 4775aa5462e8..6f013efba45b 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -207,7 +207,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) gpio = *data++; /* pull up/down */ - action = *data++; + action = *data++ & 1; if (gpio >= ARRAY_SIZE(gtable)) { DRM_DEBUG_KMS("unknown gpio %u\n", gpio); -- GitLab From 4688d45f97f215447d552ff5bc960072e865e0ff Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 4 Feb 2016 12:50:53 +0200 Subject: [PATCH 0703/5324] drm/i915: put the IOSF port defines in numerical order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it easier to spot duplicates. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/a89f10d2d1954ac1b9a278534cb5209973354caa.1454582914.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ec6444ae6e2f..85d56ad29516 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -610,16 +610,16 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define IOSF_BYTE_ENABLES_SHIFT 4 #define IOSF_BAR_SHIFT 1 #define IOSF_SB_BUSY (1<<0) -#define IOSF_PORT_BUNIT 0x3 -#define IOSF_PORT_PUNIT 0x4 +#define IOSF_PORT_BUNIT 0x03 +#define IOSF_PORT_PUNIT 0x04 #define IOSF_PORT_NC 0x11 #define IOSF_PORT_DPIO 0x12 -#define IOSF_PORT_DPIO_2 0x1a #define IOSF_PORT_GPIO_NC 0x13 #define IOSF_PORT_CCK 0x14 -#define IOSF_PORT_CCU 0xA9 +#define IOSF_PORT_DPIO_2 0x1a +#define IOSF_PORT_FLISDSI 0x1b #define IOSF_PORT_GPS_CORE 0x48 -#define IOSF_PORT_FLISDSI 0x1B +#define IOSF_PORT_CCU 0xa9 #define VLV_IOSF_DATA _MMIO(VLV_DISPLAY_BASE + 0x2104) #define VLV_IOSF_ADDR _MMIO(VLV_DISPLAY_BASE + 0x2108) -- GitLab From 10182e77f52f1f703c9e5fea3656446aa850ebda Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 4 Feb 2016 12:50:54 +0200 Subject: [PATCH 0704/5324] drm/i915/vlv: drop unused vlv_gps_core_read/write functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not needed. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/532150999335216b1374c606e1b3c253a6c9fe9d.1454582914.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_reg.h | 1 - drivers/gpu/drm/i915/intel_sideband.c | 14 -------------- 3 files changed, 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 856bfe8d1f42..bd126ff3a6e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3479,8 +3479,6 @@ u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg); void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg); void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); -u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg); -void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg); void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val); u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 85d56ad29516..6867295dbdc1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -618,7 +618,6 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define IOSF_PORT_CCK 0x14 #define IOSF_PORT_DPIO_2 0x1a #define IOSF_PORT_FLISDSI 0x1b -#define IOSF_PORT_GPS_CORE 0x48 #define IOSF_PORT_CCU 0xa9 #define VLV_IOSF_DATA _MMIO(VLV_DISPLAY_BASE + 0x2104) #define VLV_IOSF_ADDR _MMIO(VLV_DISPLAY_BASE + 0x2108) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 8831fc579ade..f5b0ab6f5942 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -171,20 +171,6 @@ void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) SB_CRWRDA_NP, reg, &val); } -u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg) -{ - u32 val = 0; - vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE, - SB_CRRDDA_NP, reg, &val); - return val; -} - -void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) -{ - vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPS_CORE, - SB_CRWRDA_NP, reg, &val); -} - u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) { u32 val = 0; -- GitLab From dfb19ed20c322616a73b212c96f2e0309e35cd1a Mon Sep 17 00:00:00 2001 From: Deepak M Date: Thu, 4 Feb 2016 18:55:15 +0200 Subject: [PATCH 0705/5324] drm/i915: Extend gpio read/write to other cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the gpio read/write functions more generic iosf sideband read/write functions, taking the iosf port as argument. v2: rebase v3: rebase v4 by Jani: address Ville's review v5 by Jani: drop the PCI_DEVFN change (Ville) Signed-off-by: Deepak M Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454604915-17142-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 5 +++-- drivers/gpu/drm/i915/intel_sideband.c | 9 +++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bd126ff3a6e2..8216665405eb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3471,8 +3471,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr); void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val); u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr); -u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg); -void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); +u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg); +void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val); u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg); void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val); u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6867295dbdc1..6732fc139196 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -618,6 +618,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define IOSF_PORT_CCK 0x14 #define IOSF_PORT_DPIO_2 0x1a #define IOSF_PORT_FLISDSI 0x1b +#define IOSF_PORT_GPIO_SC 0x48 +#define IOSF_PORT_GPIO_SUS 0xa8 #define IOSF_PORT_CCU 0xa9 #define VLV_IOSF_DATA _MMIO(VLV_DISPLAY_BASE + 0x2104) #define VLV_IOSF_ADDR _MMIO(VLV_DISPLAY_BASE + 0x2108) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 6f013efba45b..76dbd1a36c57 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -221,14 +221,15 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) if (!gtable[gpio].init) { /* program the function */ /* FIXME: remove constant below */ - vlv_gpio_nc_write(dev_priv, function, 0x2000CC00); + vlv_iosf_sb_write(dev_priv, IOSF_PORT_GPIO_NC, function, + 0x2000CC00); gtable[gpio].init = 1; } val = 0x4 | action; /* pull up/down */ - vlv_gpio_nc_write(dev_priv, pad, val); + vlv_iosf_sb_write(dev_priv, IOSF_PORT_GPIO_NC, pad, val); mutex_unlock(&dev_priv->sb_lock); out: diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index f5b0ab6f5942..c3998188cf35 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -129,17 +129,18 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr) return val; } -u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg) +u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg) { u32 val = 0; - vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC, + vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port, SB_CRRDDA_NP, reg, &val); return val; } -void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val) +void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, + u8 port, u32 reg, u32 val) { - vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_GPIO_NC, + vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), port, SB_CRWRDA_NP, reg, &val); } -- GitLab From 5090c9670de03511834bc894cfc9737e3d61a414 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 4 Feb 2016 13:29:27 -0500 Subject: [PATCH 0706/5324] Orangefs: improve gossip statement There were two just alike, making it hard maybe to tell which one you were looking at in syslog... so I changed it a little by adding some extra interesting tidbits to it... Signed-off-by: Mike Marshall --- fs/orangefs/devorangefs-req.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 812844faa7f5..37278f5878b3 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c @@ -145,8 +145,11 @@ static ssize_t orangefs_devreq_read(struct file *file, ret = fs_mount_pending(fsid); if (ret == 1) { gossip_debug(GOSSIP_DEV_DEBUG, - "orangefs: skipping op tag %llu %s\n", - llu(op->tag), get_opname_string(op)); + "%s: mount pending, skipping op tag " + "%llu %s\n", + __func__, + llu(op->tag), + get_opname_string(op)); spin_unlock(&op->lock); continue; /* -- GitLab From 96afef1d5adee8722549c8c2b788d656ea2ecf21 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 4 Feb 2016 18:52:47 +0200 Subject: [PATCH 0707/5324] drm/i915/dsi: skip gpio element execution when not supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip v3 gpio element because the support is not there, and skip gpio element on non-vlv because the sideband code is vlv specific. v2: the gpio stuff is currently only supported on vlv (Ville) Cc: drm-intel-fixes@lists.freedesktop.org Fixes: 2a33d93486f2 ("drm/i915/bios: add support for MIPI sequence block v3") Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454604767-2440-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 76dbd1a36c57..787f01c63984 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -204,6 +204,9 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + if (dev_priv->vbt.dsi.seq_version >= 3) + data++; + gpio = *data++; /* pull up/down */ @@ -214,6 +217,16 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) goto out; } + if (!IS_VALLEYVIEW(dev_priv)) { + DRM_DEBUG_KMS("GPIO element not supported on this platform\n"); + goto out; + } + + if (dev_priv->vbt.dsi.seq_version >= 3) { + DRM_DEBUG_KMS("GPIO element v3 not supported\n"); + goto out; + } + function = gtable[gpio].function_reg; pad = gtable[gpio].pad_reg; -- GitLab From 2d4cae0d175acae2ea2efbc17b52b71d4ffd886d Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 4 Feb 2016 13:48:16 -0500 Subject: [PATCH 0708/5324] Orangefs: clean up slab allocation. A couple of caches were no longer needed: - iov_iter improvements to orangefs_devreq_write_iter eliminated the need for the dev_req_cache. - removal (months ago) of the old AIO code eliminated the need for the kiocb_cache. Also, deobfuscation of use of GFP_KERNEL when calling kmem_cache_(z)alloc for remaining caches. Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-cache.c | 92 +---------------------------------- fs/orangefs/orangefs-kernel.h | 15 +----- fs/orangefs/orangefs-mod.c | 20 +------- fs/orangefs/super.c | 3 +- 4 files changed, 6 insertions(+), 124 deletions(-) diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index e72ac2083ac0..3b3de91406ca 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c @@ -16,12 +16,6 @@ static DEFINE_SPINLOCK(next_tag_value_lock); /* a cache for orangefs upcall/downcall operations */ static struct kmem_cache *op_cache; -/* a cache for device (/dev/pvfs2-req) communication */ -static struct kmem_cache *dev_req_cache; - -/* a cache for orangefs_kiocb objects (i.e orangefs iocb structures ) */ -static struct kmem_cache *orangefs_kiocb_cache; - int op_cache_initialize(void) { op_cache = kmem_cache_create("orangefs_op_cache", @@ -111,7 +105,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) { struct orangefs_kernel_op_s *new_op = NULL; - new_op = kmem_cache_zalloc(op_cache, ORANGEFS_CACHE_ALLOC_FLAGS); + new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL); if (new_op) { INIT_LIST_HEAD(&new_op->list); spin_lock_init(&new_op->lock); @@ -148,7 +142,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type) new_op->upcall.gid = from_kgid(current_user_ns(), current_fsgid()); } else { - gossip_err("op_alloc: kmem_cache_alloc failed!\n"); + gossip_err("op_alloc: kmem_cache_zalloc failed!\n"); } return new_op; } @@ -165,85 +159,3 @@ void __op_release(struct orangefs_kernel_op_s *orangefs_op) gossip_err("NULL pointer in op_release\n"); } } - -int dev_req_cache_initialize(void) -{ - dev_req_cache = kmem_cache_create("orangefs_devreqcache", - MAX_DEV_REQ_DOWNSIZE, - 0, - ORANGEFS_CACHE_CREATE_FLAGS, - NULL); - - if (!dev_req_cache) { - gossip_err("Cannot create orangefs_dev_req_cache\n"); - return -ENOMEM; - } - return 0; -} - -int dev_req_cache_finalize(void) -{ - kmem_cache_destroy(dev_req_cache); - return 0; -} - -void *dev_req_alloc(void) -{ - void *buffer; - - buffer = kmem_cache_alloc(dev_req_cache, ORANGEFS_CACHE_ALLOC_FLAGS); - if (buffer == NULL) - gossip_err("Failed to allocate from dev_req_cache\n"); - else - memset(buffer, 0, sizeof(MAX_DEV_REQ_DOWNSIZE)); - return buffer; -} - -void dev_req_release(void *buffer) -{ - if (buffer) - kmem_cache_free(dev_req_cache, buffer); - else - gossip_err("NULL pointer passed to dev_req_release\n"); -} - -int kiocb_cache_initialize(void) -{ - orangefs_kiocb_cache = kmem_cache_create("orangefs_kiocbcache", - sizeof(struct orangefs_kiocb_s), - 0, - ORANGEFS_CACHE_CREATE_FLAGS, - NULL); - - if (!orangefs_kiocb_cache) { - gossip_err("Cannot create orangefs_kiocb_cache!\n"); - return -ENOMEM; - } - return 0; -} - -int kiocb_cache_finalize(void) -{ - kmem_cache_destroy(orangefs_kiocb_cache); - return 0; -} - -struct orangefs_kiocb_s *kiocb_alloc(void) -{ - struct orangefs_kiocb_s *x = NULL; - - x = kmem_cache_alloc(orangefs_kiocb_cache, ORANGEFS_CACHE_ALLOC_FLAGS); - if (x == NULL) - gossip_err("kiocb_alloc: kmem_cache_alloc failed!\n"); - else - memset(x, 0, sizeof(struct orangefs_kiocb_s)); - return x; -} - -void kiocb_release(struct orangefs_kiocb_s *x) -{ - if (x) - kmem_cache_free(orangefs_kiocb_cache, x); - else - gossip_err("kiocb_release: kmem_cache_free NULL pointer!\n"); -} diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 3e258554688d..d4db96223dac 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -128,7 +128,6 @@ struct client_debug_mask { #define ORANGEFS_CACHE_CREATE_FLAGS 0 #endif /* ((defined ORANGEFS_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */ -#define ORANGEFS_CACHE_ALLOC_FLAGS (GFP_KERNEL) #define ORANGEFS_GFP_FLAGS (GFP_KERNEL) #define ORANGEFS_BUFMAP_GFP_FLAGS (GFP_KERNEL) @@ -207,9 +206,6 @@ struct orangefs_kernel_op_s { /* VFS aio fields */ - /* used by the async I/O code to stash the orangefs_kiocb_s structure */ - void *priv; - int attempts; struct list_head list; @@ -217,6 +213,7 @@ struct orangefs_kernel_op_s { #define set_op_state_waiting(op) ((op)->op_state = OP_VFS_STATE_WAITING) #define set_op_state_inprogress(op) ((op)->op_state = OP_VFS_STATE_INPROGR) +#define set_op_state_given_up(op) ((op)->op_state = OP_VFS_STATE_GIVEN_UP) static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op) { op->op_state = OP_VFS_STATE_SERVICED; @@ -453,19 +450,9 @@ int op_cache_finalize(void); struct orangefs_kernel_op_s *op_alloc(__s32 type); char *get_opname_string(struct orangefs_kernel_op_s *new_op); -int dev_req_cache_initialize(void); -int dev_req_cache_finalize(void); -void *dev_req_alloc(void); -void dev_req_release(void *); - int orangefs_inode_cache_initialize(void); int orangefs_inode_cache_finalize(void); -int kiocb_cache_initialize(void); -int kiocb_cache_finalize(void); -struct orangefs_kiocb_s *kiocb_alloc(void); -void kiocb_release(struct orangefs_kiocb_s *ptr); - /* * defined in orangefs-mod.c */ diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index e07874e26372..7639ab2df711 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -140,24 +140,16 @@ static int __init orangefs_init(void) if (ret < 0) goto err; - ret = dev_req_cache_initialize(); - if (ret < 0) - goto cleanup_op; - ret = orangefs_inode_cache_initialize(); if (ret < 0) - goto cleanup_req; - - ret = kiocb_cache_initialize(); - if (ret < 0) - goto cleanup_inode; + goto cleanup_op; /* Initialize the orangefsdev subsystem. */ ret = orangefs_dev_init(); if (ret < 0) { gossip_err("orangefs: could not initialize device subsystem %d!\n", ret); - goto cleanup_kiocb; + goto cleanup_inode; } htable_ops_in_progress = @@ -214,15 +206,9 @@ static int __init orangefs_init(void) cleanup_device: orangefs_dev_cleanup(); -cleanup_kiocb: - kiocb_cache_finalize(); - cleanup_inode: orangefs_inode_cache_finalize(); -cleanup_req: - dev_req_cache_finalize(); - cleanup_op: op_cache_finalize(); @@ -247,9 +233,7 @@ static void __exit orangefs_exit(void) for (i = 0; i < hash_table_size; i++) BUG_ON(!list_empty(&htable_ops_in_progress[i])); - kiocb_cache_finalize(); orangefs_inode_cache_finalize(); - dev_req_cache_finalize(); op_cache_finalize(); kfree(htable_ops_in_progress); diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index a32981239ea6..93cc352be360 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -92,8 +92,7 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb) { struct orangefs_inode_s *orangefs_inode; - orangefs_inode = kmem_cache_alloc(orangefs_inode_cache, - ORANGEFS_CACHE_ALLOC_FLAGS); + orangefs_inode = kmem_cache_alloc(orangefs_inode_cache, GFP_KERNEL); if (orangefs_inode == NULL) { gossip_err("Failed to allocate orangefs_inode\n"); return NULL; -- GitLab From fe88adc3661ff9eb2a9777277f9c3abf5909449f Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Sat, 30 Jan 2016 13:46:11 -0500 Subject: [PATCH 0709/5324] orangefs: Only compare attributes specified in orangefs_inode_getattr. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/orangefs-utils.c | 62 +++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 6cf29a439211..fa3ed8ad35be 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -355,26 +355,37 @@ static inline int copy_attributes_from_inode(struct inode *inode, static int compare_attributes_to_inode(struct inode *inode, struct ORANGEFS_sys_attr_s *attrs, - char *symname) + char *symname, + int mask) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); loff_t inode_size, rounded_up_size; + /* Much of what happens below relies on the type being around. */ + if (!(mask & ORANGEFS_ATTR_SYS_TYPE)) + return 0; + + if (attrs->objtype == ORANGEFS_TYPE_METAFILE && + inode->i_flags != orangefs_inode_flags(attrs)) + return 0; + /* Compare file size. */ switch (attrs->objtype) { case ORANGEFS_TYPE_METAFILE: - if(inode->i_flags != orangefs_inode_flags(attrs)) - return 0; - inode_size = attrs->size; - rounded_up_size = inode_size + (4096 - (inode_size % 4096)); - if (inode->i_bytes != inode_size || - inode->i_blocks != rounded_up_size/512) - return 0; + if (mask & ORANGEFS_ATTR_SYS_SIZE) { + inode_size = attrs->size; + rounded_up_size = inode_size + + (4096 - (inode_size % 4096)); + if (inode->i_bytes != inode_size || + inode->i_blocks != rounded_up_size/512) + return 0; + } break; case ORANGEFS_TYPE_SYMLINK: - if (symname && strlen(symname) != inode->i_size) - return 0; + if (mask & ORANGEFS_ATTR_SYS_SIZE) + if (symname && strlen(symname) != inode->i_size) + return 0; break; default: if (inode->i_size != PAGE_CACHE_SIZE && @@ -384,17 +395,28 @@ static int compare_attributes_to_inode(struct inode *inode, /* Compare general attributes. */ - if (!uid_eq(inode->i_uid, make_kuid(&init_user_ns, attrs->owner)) || - !gid_eq(inode->i_gid, make_kgid(&init_user_ns, attrs->group)) || - inode->i_atime.tv_sec != attrs->atime || - inode->i_mtime.tv_sec != attrs->mtime || - inode->i_ctime.tv_sec != attrs->ctime || - inode->i_atime.tv_nsec != 0 || + if (mask & ORANGEFS_ATTR_SYS_UID && + !uid_eq(inode->i_uid, make_kuid(&init_user_ns, attrs->owner))) + return 0; + if (mask & ORANGEFS_ATTR_SYS_GID && + !gid_eq(inode->i_gid, make_kgid(&init_user_ns, attrs->group))) + return 0; + if (mask & ORANGEFS_ATTR_SYS_ATIME && + inode->i_atime.tv_sec != attrs->atime) + return 0; + if (mask & ORANGEFS_ATTR_SYS_MTIME && + inode->i_atime.tv_sec != attrs->mtime) + return 0; + if (mask & ORANGEFS_ATTR_SYS_CTIME && + inode->i_atime.tv_sec != attrs->ctime) + return 0; + if (inode->i_atime.tv_nsec != 0 || inode->i_mtime.tv_nsec != 0 || inode->i_ctime.tv_nsec != 0) return 0; - if ((inode->i_mode & ~(S_ISVTX|S_IFREG|S_IFDIR|S_IFLNK)) != + if (mask & ORANGEFS_ATTR_SYS_PERM && + (inode->i_mode & ~(S_ISVTX|S_IFREG|S_IFDIR|S_IFLNK)) != orangefs_inode_perms(attrs)) return 0; @@ -418,7 +440,8 @@ static int compare_attributes_to_inode(struct inode *inode, case ORANGEFS_TYPE_SYMLINK: if (!(inode->i_mode & S_IFLNK)) return 0; - if (orangefs_inode && symname) + if (orangefs_inode && symname && + mask & ORANGEFS_ATTR_SYS_LNK_TARGET) if (strcmp(orangefs_inode->link_target, symname)) return 0; break; @@ -462,7 +485,8 @@ int orangefs_inode_getattr(struct inode *inode, __u32 getattr_mask, int check) if (check) { ret = compare_attributes_to_inode(inode, &new_op->downcall.resp.getattr.attributes, - new_op->downcall.resp.getattr.link_target); + new_op->downcall.resp.getattr.link_target, + getattr_mask); if (new_op->downcall.resp.getattr.attributes.objtype == ORANGEFS_TYPE_METAFILE) { -- GitLab From 933287da750edefbf0f449750fd67b4fc6c10013 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Sat, 30 Jan 2016 13:46:54 -0500 Subject: [PATCH 0710/5324] orangefs: Implement inode_operations->permission(). Thus d_revalidate is not obliged to check on as much, which will eventually lead the way to hammering the filesystem servers much less. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/dcache.c | 3 ++- fs/orangefs/inode.c | 19 +++++++++++++++++++ fs/orangefs/namei.c | 1 + fs/orangefs/orangefs-kernel.h | 2 ++ fs/orangefs/protocol.h | 9 +++++++++ fs/orangefs/symlink.c | 1 + 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index e8fb79de37c6..a6911dbbf3e5 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -119,8 +119,9 @@ static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags) goto out; /* Now we must perform a getattr to validate the inode contents. */ + ret = orangefs_inode_getattr(dentry->d_inode, - ORANGEFS_ATTR_SYS_ALL_NOHINT, 1); + ORANGEFS_ATTR_SYS_TYPE|ORANGEFS_ATTR_SYS_LNK_TARGET, 1); if (ret < 0) { gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.\n", __FILE__, __func__, __LINE__); diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 040cd95b51c2..e9688f0b99d7 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -291,6 +291,24 @@ int orangefs_getattr(struct vfsmount *mnt, return ret; } +int orangefs_permission(struct inode *inode, int mask) +{ + int ret; + + if (mask & MAY_NOT_BLOCK) + return -ECHILD; + + gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__); + + /* Make sure the permission (and other common attrs) are up to date. */ + ret = orangefs_inode_getattr(inode, + ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0); + if (ret < 0) + return ret; + + return generic_permission(inode, mask); +} + /* ORANGEDS2 implementation of VFS inode operations for files */ struct inode_operations orangefs_file_inode_operations = { .get_acl = orangefs_get_acl, @@ -301,6 +319,7 @@ struct inode_operations orangefs_file_inode_operations = { .getxattr = generic_getxattr, .listxattr = orangefs_listxattr, .removexattr = generic_removexattr, + .permission = orangefs_permission, }; static int orangefs_init_iops(struct inode *inode) diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 50bc45d02009..8fc55c6f58db 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -443,4 +443,5 @@ struct inode_operations orangefs_dir_inode_operations = { .getxattr = generic_getxattr, .removexattr = generic_removexattr, .listxattr = orangefs_listxattr, + .permission = orangefs_permission, }; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index d4db96223dac..a8cde9019efe 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -493,6 +493,8 @@ int orangefs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat); +int orangefs_permission(struct inode *inode, int mask); + /* * defined in xattr.c */ diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 56dd65abb908..6ac0c60c9f5e 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h @@ -205,6 +205,15 @@ typedef __s64 ORANGEFS_offset; ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ ORANGEFS_ATTR_SYS_BLKSIZE) + +#define ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE \ + (ORANGEFS_ATTR_SYS_COMMON_ALL | \ + ORANGEFS_ATTR_SYS_LNK_TARGET | \ + ORANGEFS_ATTR_SYS_DFILE_COUNT | \ + ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ + ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ + ORANGEFS_ATTR_SYS_BLKSIZE) + #define ORANGEFS_XATTR_REPLACE 0x2 #define ORANGEFS_XATTR_CREATE 0x1 #define ORANGEFS_MAX_SERVER_ADDR_LEN 256 diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c index 1b3ae63463dc..2b8541a7fc43 100644 --- a/fs/orangefs/symlink.c +++ b/fs/orangefs/symlink.c @@ -28,4 +28,5 @@ struct inode_operations orangefs_symlink_inode_operations = { .getattr = orangefs_getattr, .listxattr = orangefs_listxattr, .setxattr = generic_setxattr, + .permission = orangefs_permission, }; -- GitLab From 237f8282c04ba81926f4dfc33cd2ca20bb0c50e7 Mon Sep 17 00:00:00 2001 From: Martin Brandenburg Date: Wed, 3 Feb 2016 16:56:24 -0500 Subject: [PATCH 0711/5324] orangefs: Do not retrieve size from servers unless it it necessary. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/inode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index e9688f0b99d7..d2923dc91388 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -411,7 +411,8 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref if (!inode || !(inode->i_state & I_NEW)) return inode; - error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0); + error = orangefs_inode_getattr(inode, + ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0); if (error) { iget_failed(inode); return ERR_PTR(error); @@ -456,7 +457,8 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ - error = orangefs_inode_getattr(inode, ORANGEFS_ATTR_SYS_ALL_NOHINT, 0); + error = orangefs_inode_getattr(inode, + ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE, 0); if (error) goto out_iput; -- GitLab From 6ebcc3fcdac1f70078a02ab11f2aa5a88a4fdaee Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Thu, 4 Feb 2016 16:28:31 -0500 Subject: [PATCH 0712/5324] Orangefs: added a couple of WARN_ONs, perhaps just temporarily. Signed-off-by: Mike Marshall --- fs/orangefs/file.c | 1 + fs/orangefs/waitqueue.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 7e6fe8d8ab2b..d865b58fb1fc 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -250,6 +250,7 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod * put error codes in downcall so that handle_io_error() * preserves it properly */ + WARN_ON(!op_state_serviced(new_op)); new_op->downcall.status = ret; handle_io_error(); goto out; diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index cdbf57bef3eb..191d886ccc57 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -205,6 +205,7 @@ int service_operation(struct orangefs_kernel_op_s *op, /* op uses shared memory */ if (orangefs_get_bufmap_init() == 0) { + WARN_ON(1); /* * This operation uses the shared memory system AND * the system is not yet ready. This situation occurs -- GitLab From 7633f8fb66c6de562b6299a0c888319de9aaf494 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 27 Jan 2016 00:36:45 -0300 Subject: [PATCH 0713/5324] ARM: exynos_defconfig: Remove MAX77802 RTC Kconfig symbol The driver has been removed so the Kconfig symbol is not valid anymore. Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Reviewed-by: Andi Shyti Signed-off-by: Krzysztof Kozlowski --- arch/arm/configs/exynos_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index c47c7e069873..6ffd7e76f3ce 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -195,7 +195,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX8997=y CONFIG_RTC_DRV_MAX77686=y -CONFIG_RTC_DRV_MAX77802=y CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_S3C=y CONFIG_DMADEVICES=y -- GitLab From 5d51f1dde207f2d5d43158da75c6608f7bfcec03 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 27 Jan 2016 00:36:46 -0300 Subject: [PATCH 0714/5324] ARM: multi_v7_defconfig: Remove MAX77802 RTC Kconfig symbol The driver has been removed so the Kconfig symbol is not valid anymore. Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Reviewed-by: Andi Shyti Signed-off-by: Krzysztof Kozlowski --- arch/arm/configs/multi_v7_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 314f6be2dca2..bdb42c09332c 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -664,7 +664,6 @@ CONFIG_RTC_DRV_MAX8907=y CONFIG_RTC_DRV_MAX8997=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m -CONFIG_RTC_DRV_MAX77802=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_PALMAS=y CONFIG_RTC_DRV_ST_LPC=y -- GitLab From 1425ec0f1ce46c95838c797a721bf9c6e0be14e2 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Wed, 6 Jan 2016 21:11:52 +0800 Subject: [PATCH 0715/5324] ARM: sunxi: Introduce Allwinner for A83T support Allwinner A83T is octa-core cortex-a7 based SoC. It's clock control unit and prcm, pinmux are different from previous sun8i series. Its processor cores are arragned in two clusters 4 cores each, similar to A80. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai [maxime: Removed the clock protection code] Signed-off-by: Maxime Ripard --- Documentation/arm/sunxi/README | 1 - Documentation/devicetree/bindings/arm/sunxi.txt | 1 + arch/arm/mach-sunxi/sunxi.c | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README index 430d279a8df3..e5a115f24471 100644 --- a/Documentation/arm/sunxi/README +++ b/Documentation/arm/sunxi/README @@ -72,6 +72,5 @@ SunXi family * Octa ARM Cortex-A7 based SoCs - Allwinner A83T - + Not Supported + Datasheet http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index bb9b0faa919d..7e79fcc36b0d 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -11,5 +11,6 @@ using one of the following compatible strings: allwinner,sun7i-a20 allwinner,sun8i-a23 allwinner,sun8i-a33 + allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index c2be98f38e73..3c156190a1d4 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -69,6 +69,7 @@ MACHINE_END static const char * const sun8i_board_dt_compat[] = { "allwinner,sun8i-a23", "allwinner,sun8i-a33", + "allwinner,sun8i-a83t", "allwinner,sun8i-h3", NULL, }; -- GitLab From 7b337e61a4104d5a0abde1e733916de2208800e6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 16 Jan 2016 15:17:36 +0100 Subject: [PATCH 0716/5324] arm64: dts: r8a7795: Add L2 cache-controller nodes Add device nodes for the L2 caches, and link the CPU node to its L2 cache node. The L2 cache for the Cortex-A57 CPU cores is 2 MiB large (organized as 128 KiB x 16 ways). Signed-off-by: Geert Uytterhoeven Signed-off-by: Dirk Behme Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 9634e3a4858e..3f00e85641a8 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -39,6 +39,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x0>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; @@ -46,22 +47,29 @@ compatible = "arm,cortex-a57","arm,armv8"; reg = <0x1>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x2>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x3>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; }; + L2_CA57: cache-controller@0 { + compatible = "cache"; + }; + extal_clk: extal { compatible = "fixed-clock"; #clock-cells = <0>; -- GitLab From 23a5110dc619073b57d90c36eae383f51df03aac Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Feb 2016 12:16:09 +0200 Subject: [PATCH 0717/5324] drm/i915/dp: abstract training pattern selection Make it cleaner to add more checks in the function. No functional changes. Cc: Ander Conselvan de Oliveira Cc: Sivakumar Thulasimani Reviewed-by: Sivakumar Thulasimani Cc: drm-intel-fixes@lists.freedesktop.org # dependency on the next patch Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454667370-8001-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp_link_training.c | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 88887938e0bf..83e667b92fda 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -215,16 +215,15 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) } } -static void -intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) +/* + * Pick training pattern for channel equalization. Training Pattern 3 for HBR2 + * or 1.2 devices that support it, Training Pattern 2 otherwise. + */ +static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) { - bool channel_eq = false; - int tries, cr_tries; - uint32_t training_pattern = DP_TRAINING_PATTERN_2; + u32 training_pattern = DP_TRAINING_PATTERN_2; /* - * Training Pattern 3 for HBR2 or 1.2 devices that support it. - * * Intel platforms that support HBR2 also support TPS3. TPS3 support is * also mandatory for downstream devices that support HBR2. * @@ -237,6 +236,18 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) else if (intel_dp->link_rate == 540000) DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n"); + return training_pattern; +} + +static void +intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) +{ + bool channel_eq = false; + int tries, cr_tries; + u32 training_pattern; + + training_pattern = intel_dp_training_pattern(intel_dp); + /* channel equalization */ if (!intel_dp_set_link_train(intel_dp, training_pattern | -- GitLab From bfcef5d2135ea1200ac1ea44661619ab8785c9f0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Feb 2016 12:16:10 +0200 Subject: [PATCH 0718/5324] drm/i915/dp: reduce missing TPS3 support errors to debug logging Per spec, TPS3 support is mandatory for downstream devices that support HBR2. We've therefore logged errors on HBR2 without TPS3 since commit 1da7d7131c35cde83f1bab8ec732b57b69bef814 Author: Jani Nikula Date: Thu Sep 3 11:16:08 2015 +0300 drm/i915: ignore link rate in TPS3 selection However, it seems there are real world devices out there that just aren't spec compliant, and still work at HBR2 using TPS2. So reduce the error message to debug logging. Cc: Ander Conselvan de Oliveira Cc: Sivakumar Thulasimani Reviewed-by: Sivakumar Thulasimani Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92932 Fixes: 1da7d7131c35 ("drm/i915: ignore link rate in TPS3 selection") Cc: drm-intel-fixes@lists.freedesktop.org Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454667370-8001-2-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp_link_training.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 83e667b92fda..0b8eefc2acc5 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -222,19 +222,27 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) { u32 training_pattern = DP_TRAINING_PATTERN_2; + bool source_tps3, sink_tps3; /* * Intel platforms that support HBR2 also support TPS3. TPS3 support is - * also mandatory for downstream devices that support HBR2. + * also mandatory for downstream devices that support HBR2. However, not + * all sinks follow the spec. * * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is - * supported but still not enabled. + * supported in source but still not enabled. */ - if (intel_dp_source_supports_hbr2(intel_dp) && - drm_dp_tps3_supported(intel_dp->dpcd)) + source_tps3 = intel_dp_source_supports_hbr2(intel_dp); + sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd); + + if (source_tps3 && sink_tps3) { training_pattern = DP_TRAINING_PATTERN_3; - else if (intel_dp->link_rate == 540000) - DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n"); + } else if (intel_dp->link_rate == 540000) { + if (!source_tps3) + DRM_DEBUG_KMS("5.4 Gbps link rate without source HBR2/TPS3 support\n"); + if (!sink_tps3) + DRM_DEBUG_KMS("5.4 Gbps link rate without sink TPS3 support\n"); + } return training_pattern; } -- GitLab From 8859b90162bc4fb0c515f92c28ad126173188156 Mon Sep 17 00:00:00 2001 From: Damien Horsley Date: Mon, 18 Jan 2016 13:12:37 +0000 Subject: [PATCH 0719/5324] reset: img: Add pistachio reset controller binding document Add binding document for the Pistachio SoC reset controller Signed-off-by: Damien Horsley Signed-off-by: James Hartley Signed-off-by: Philipp Zabel --- .../bindings/reset/img,pistachio-reset.txt | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/img,pistachio-reset.txt diff --git a/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt new file mode 100644 index 000000000000..8c05d16367df --- /dev/null +++ b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt @@ -0,0 +1,55 @@ +Pistachio Reset Controller +============================================================================= + +This binding describes a reset controller device that is used to enable and +disable individual IP blocks within the Pistachio SoC using "soft reset" +control bits found in the Pistachio SoC top level registers. + +The actual action taken when soft reset is asserted is hardware dependent. +However, when asserted it may not be possible to access the hardware's +registers, and following an assert/deassert sequence the hardware's previous +state may no longer be valid. + +Please refer to Documentation/devicetree/bindings/reset/reset.txt +for common reset controller binding usage. + +Required properties: + +- compatible: Contains "img,pistachio-reset" + +- #reset-cells: Contains 1 + +Example: + + cr_periph: clk@18148000 { + compatible = "img,pistachio-cr-periph", "syscon", "simple-mfd"; + reg = <0x18148000 0x1000>; + clocks = <&clk_periph PERIPH_CLK_SYS>; + clock-names = "sys"; + #clock-cells = <1>; + + pistachio_reset: reset-controller { + compatible = "img,pistachio-reset"; + #reset-cells = <1>; + }; + }; + +Specifying reset control of devices +======================================= + +Device nodes should specify the reset channel required in their "resets" +property, containing a phandle to the pistachio reset device node and an +index specifying which reset to use, as described in +Documentation/devicetree/bindings/reset/reset.txt. + +Example: + + spdif_out: spdif-out@18100d00 { + ... + resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>; + reset-names = "rst"; + ... + }; + +Macro definitions for the supported resets can be found in: +include/dt-bindings/reset/pistachio-resets.h -- GitLab From 8a56736a2f53abe6edd1c67acc4f6161d5c16c07 Mon Sep 17 00:00:00 2001 From: Damien Horsley Date: Mon, 18 Jan 2016 13:12:38 +0000 Subject: [PATCH 0720/5324] reset: img: Add Pistachio reset controller driver Add reset controller driver for Pistachio SoC Signed-off-by: Damien Horsley Signed-off-by: James Hartley Signed-off-by: Philipp Zabel --- drivers/reset/Makefile | 1 + drivers/reset/reset-pistachio.c | 154 +++++++++++++++++++ include/dt-bindings/reset/pistachio-resets.h | 36 +++++ 3 files changed, 191 insertions(+) create mode 100644 drivers/reset/reset-pistachio.c create mode 100644 include/dt-bindings/reset/pistachio-resets.h diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 4d7178e46afa..a1fc8eda79f3 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -2,6 +2,7 @@ obj-y += core.o obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o +obj-$(CONFIG_MACH_PISTACHIO) += reset-pistachio.o obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o obj-$(CONFIG_ARCH_STI) += sti/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ diff --git a/drivers/reset/reset-pistachio.c b/drivers/reset/reset-pistachio.c new file mode 100644 index 000000000000..b31cdb0570fc --- /dev/null +++ b/drivers/reset/reset-pistachio.c @@ -0,0 +1,154 @@ +/* + * Pistachio SoC Reset Controller driver + * + * Copyright (C) 2015 Imagination Technologies Ltd. + * + * Author: Damien Horsley + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PISTACHIO_SOFT_RESET 0 + +struct pistachio_reset_data { + struct reset_controller_dev rcdev; + struct regmap *periph_regs; +}; + +static inline int pistachio_reset_shift(unsigned long id) +{ + switch (id) { + case PISTACHIO_RESET_I2C0: + case PISTACHIO_RESET_I2C1: + case PISTACHIO_RESET_I2C2: + case PISTACHIO_RESET_I2C3: + case PISTACHIO_RESET_I2S_IN: + case PISTACHIO_RESET_PRL_OUT: + case PISTACHIO_RESET_SPDIF_OUT: + case PISTACHIO_RESET_SPI: + case PISTACHIO_RESET_PWM_PDM: + case PISTACHIO_RESET_UART0: + case PISTACHIO_RESET_UART1: + case PISTACHIO_RESET_QSPI: + case PISTACHIO_RESET_MDC: + case PISTACHIO_RESET_SDHOST: + case PISTACHIO_RESET_ETHERNET: + case PISTACHIO_RESET_IR: + case PISTACHIO_RESET_HASH: + case PISTACHIO_RESET_TIMER: + return id; + case PISTACHIO_RESET_I2S_OUT: + case PISTACHIO_RESET_SPDIF_IN: + case PISTACHIO_RESET_EVT: + return id + 6; + case PISTACHIO_RESET_USB_H: + case PISTACHIO_RESET_USB_PR: + case PISTACHIO_RESET_USB_PHY_PR: + case PISTACHIO_RESET_USB_PHY_PON: + return id + 7; + default: + return -EINVAL; + } +} + +static int pistachio_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct pistachio_reset_data *rd; + u32 mask; + int shift; + + rd = container_of(rcdev, struct pistachio_reset_data, rcdev); + shift = pistachio_reset_shift(id); + if (shift < 0) + return shift; + mask = BIT(shift); + + return regmap_update_bits(rd->periph_regs, PISTACHIO_SOFT_RESET, + mask, mask); +} + +static int pistachio_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct pistachio_reset_data *rd; + u32 mask; + int shift; + + rd = container_of(rcdev, struct pistachio_reset_data, rcdev); + shift = pistachio_reset_shift(id); + if (shift < 0) + return shift; + mask = BIT(shift); + + return regmap_update_bits(rd->periph_regs, PISTACHIO_SOFT_RESET, + mask, 0); +} + +static struct reset_control_ops pistachio_reset_ops = { + .assert = pistachio_reset_assert, + .deassert = pistachio_reset_deassert, +}; + +static int pistachio_reset_probe(struct platform_device *pdev) +{ + struct pistachio_reset_data *rd; + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + + rd = devm_kzalloc(dev, sizeof(*rd), GFP_KERNEL); + if (!rd) + return -ENOMEM; + + rd->periph_regs = syscon_node_to_regmap(np->parent); + if (IS_ERR(rd->periph_regs)) + return PTR_ERR(rd->periph_regs); + + rd->rcdev.owner = THIS_MODULE; + rd->rcdev.nr_resets = PISTACHIO_RESET_MAX + 1; + rd->rcdev.ops = &pistachio_reset_ops; + rd->rcdev.of_node = np; + + return reset_controller_register(&rd->rcdev); +} + +static int pistachio_reset_remove(struct platform_device *pdev) +{ + struct pistachio_reset_data *data = platform_get_drvdata(pdev); + + reset_controller_unregister(&data->rcdev); + + return 0; +} + +static const struct of_device_id pistachio_reset_dt_ids[] = { + { .compatible = "img,pistachio-reset", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, pistachio_reset_dt_ids); + +static struct platform_driver pistachio_reset_driver = { + .probe = pistachio_reset_probe, + .remove = pistachio_reset_remove, + .driver = { + .name = "pistachio-reset", + .of_match_table = pistachio_reset_dt_ids, + }, +}; +module_platform_driver(pistachio_reset_driver); + +MODULE_AUTHOR("Damien Horsley "); +MODULE_DESCRIPTION("Pistacho Reset Controller Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/reset/pistachio-resets.h b/include/dt-bindings/reset/pistachio-resets.h new file mode 100644 index 000000000000..60a189b1faef --- /dev/null +++ b/include/dt-bindings/reset/pistachio-resets.h @@ -0,0 +1,36 @@ +/* + * This header provides constants for the reset controller + * present in the Pistachio SoC + */ + +#ifndef _PISTACHIO_RESETS_H +#define _PISTACHIO_RESETS_H + +#define PISTACHIO_RESET_I2C0 0 +#define PISTACHIO_RESET_I2C1 1 +#define PISTACHIO_RESET_I2C2 2 +#define PISTACHIO_RESET_I2C3 3 +#define PISTACHIO_RESET_I2S_IN 4 +#define PISTACHIO_RESET_PRL_OUT 5 +#define PISTACHIO_RESET_SPDIF_OUT 6 +#define PISTACHIO_RESET_SPI 7 +#define PISTACHIO_RESET_PWM_PDM 8 +#define PISTACHIO_RESET_UART0 9 +#define PISTACHIO_RESET_UART1 10 +#define PISTACHIO_RESET_QSPI 11 +#define PISTACHIO_RESET_MDC 12 +#define PISTACHIO_RESET_SDHOST 13 +#define PISTACHIO_RESET_ETHERNET 14 +#define PISTACHIO_RESET_IR 15 +#define PISTACHIO_RESET_HASH 16 +#define PISTACHIO_RESET_TIMER 17 +#define PISTACHIO_RESET_I2S_OUT 18 +#define PISTACHIO_RESET_SPDIF_IN 19 +#define PISTACHIO_RESET_EVT 20 +#define PISTACHIO_RESET_USB_H 21 +#define PISTACHIO_RESET_USB_PR 22 +#define PISTACHIO_RESET_USB_PHY_PR 23 +#define PISTACHIO_RESET_USB_PHY_PON 24 +#define PISTACHIO_RESET_MAX 24 + +#endif -- GitLab From 27ca5aaa3676a135d3767e8ffe1ba1f5ee9ec0bb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:08:19 +0100 Subject: [PATCH 0721/5324] reset: berlin: drop DT cell size check Now that the DT cell size check has been moved to the core, there is no need to check again. Signed-off-by: Philipp Zabel --- drivers/reset/reset-berlin.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c index 970b1ad60293..ac017df8858c 100644 --- a/drivers/reset/reset-berlin.c +++ b/drivers/reset/reset-berlin.c @@ -55,9 +55,6 @@ static int berlin_reset_xlate(struct reset_controller_dev *rcdev, { unsigned offset, bit; - if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) - return -EINVAL; - offset = reset_spec->args[0]; bit = reset_spec->args[1]; -- GitLab From 274008e89d78ded4324c7d81d9d106f62f5d5727 Mon Sep 17 00:00:00 2001 From: Sagar Arun Kamble Date: Sat, 6 Feb 2016 00:13:29 +0530 Subject: [PATCH 0722/5324] drm/i915/bxt: Check BIOS RC6 setup before enabling RC6 RC6 setup is shared between BIOS and Driver. BIOS sets up subset of RC6 setup registers. If those are not setup Driver should not enable RC6. For implementing this, driver can check RC_CTRL0 and RC_CTRL1 values to know if BIOS has enabled HW/SW RC6. This will also enable user to control RC6 using BIOS settings alone. RC6 related instability can be avoided by disabling via BIOS settings till driver fixes it. v2: Had placed logic in gen8 function by mistake. Fixed it. Ensuring RPM is not enabled in case BIOS disabled RC6. v3: Need to disable RPM if RC6 is disabled due to BIOS settings. (Daniel) Runtime PM enabling happens before gen9_enable_rc6. Moved the updation of enable_rc6 parameter in intel_uncore_sanitize. v4: Added elaborate check for BIOS RC6 setup. Prepared check_pctx for bxt. (Imre) v5: Caching reserved stolen base and size in the driver private data. Reorganized RC6 setup check. Moved from gen9_enable_rc6 to intel_uncore_sanitize. (Imre) v6: Rebasing on the patch submitted by Imre that moves gem_init_stolen earlier in the load. v7: Removed PWRCTX_MAXCNT_VCSUNIT1 check as it applies to SKL. (Imre) v8: Fixed formatting and checkpatch issues. Fixed functional issue where RC6 ctx size check was missing. (Imre) Cc: Imre Deak Signed-off-by: Sagar Arun Kamble Signed-off-by: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1454697809-22113-1-git-send-email-sagar.a.kamble@intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 + drivers/gpu/drm/i915/i915_gem_stolen.c | 3 ++ drivers/gpu/drm/i915/i915_reg.h | 11 ++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 53 +++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_uncore.c | 2 + 6 files changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index f520c90e5377..66a6da2396a2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -342,6 +342,8 @@ struct i915_gtt { size_t stolen_size; /* Total size of stolen memory */ size_t stolen_usable_size; /* Total size minus BIOS reserved */ + size_t stolen_reserved_base; + size_t stolen_reserved_size; u64 mappable_end; /* End offset that we can CPU map */ struct io_mapping *mappable; /* Mapping to our CPU mappable region */ phys_addr_t mappable_base; /* PA of our GMADR */ diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index c384dc9c8a63..ba1a00d815d3 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -458,6 +458,9 @@ int i915_gem_init_stolen(struct drm_device *dev) return 0; } + dev_priv->gtt.stolen_reserved_base = reserved_base; + dev_priv->gtt.stolen_reserved_size = reserved_size; + /* It is possible for the reserved area to end before the end of stolen * memory, so just consider the start. */ reserved_total = stolen_top - reserved_base; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6732fc139196..188ad5de020f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6785,6 +6785,16 @@ enum skl_disp_power_wells { #define VLV_PMWGICZ _MMIO(0x1300a4) +#define RC6_LOCATION _MMIO(0xD40) +#define RC6_CTX_IN_DRAM (1 << 0) +#define RC6_CTX_BASE _MMIO(0xD48) +#define RC6_CTX_BASE_MASK 0xFFFFFFF0 +#define PWRCTX_MAXCNT_RCSUNIT _MMIO(0x2054) +#define PWRCTX_MAXCNT_VCSUNIT0 _MMIO(0x12054) +#define PWRCTX_MAXCNT_BCSUNIT _MMIO(0x22054) +#define PWRCTX_MAXCNT_VECSUNIT _MMIO(0x1A054) +#define PWRCTX_MAXCNT_VCSUNIT1 _MMIO(0x1C054) +#define IDLE_TIME_MASK 0xFFFFF #define FORCEWAKE _MMIO(0xA18C) #define FORCEWAKE_VLV _MMIO(0x1300b0) #define FORCEWAKE_ACK_VLV _MMIO(0x1300b4) @@ -6923,6 +6933,7 @@ enum skl_disp_power_wells { #define GEN6_RPDEUC _MMIO(0xA084) #define GEN6_RPDEUCSW _MMIO(0xA088) #define GEN6_RC_STATE _MMIO(0xA094) +#define RC6_STATE (1 << 18) #define GEN6_RC1_WAKE_RATE_LIMIT _MMIO(0xA098) #define GEN6_RC6_WAKE_RATE_LIMIT _MMIO(0xA09C) #define GEN6_RC6pp_WAKE_RATE_LIMIT _MMIO(0xA0A0) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 93ba14a3bb76..1251a7ae4a6a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1566,6 +1566,7 @@ void skl_wm_get_hw_state(struct drm_device *dev); void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, struct skl_ddb_allocation *ddb /* out */); uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config); +int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6); /* intel_sdvo.c */ bool intel_sdvo_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3da7935c1665..379eabe093cb 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4562,12 +4562,62 @@ static void intel_print_rc6_info(struct drm_device *dev, u32 mode) onoff(mode & GEN6_RC_CTL_RC6_ENABLE)); } -static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) +static bool bxt_check_bios_rc6_setup(const struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + bool enable_rc6 = true; + unsigned long rc6_ctx_base; + + if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) { + DRM_DEBUG_KMS("RC6 Base location not set properly.\n"); + enable_rc6 = false; + } + + /* + * The exact context size is not known for BXT, so assume a page size + * for this check. + */ + rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK; + if (!((rc6_ctx_base >= dev_priv->gtt.stolen_reserved_base) && + (rc6_ctx_base + PAGE_SIZE <= dev_priv->gtt.stolen_reserved_base + + dev_priv->gtt.stolen_reserved_size))) { + DRM_DEBUG_KMS("RC6 Base address not as expected.\n"); + enable_rc6 = false; + } + + if (!(((I915_READ(PWRCTX_MAXCNT_RCSUNIT) & IDLE_TIME_MASK) > 1) && + ((I915_READ(PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1) && + ((I915_READ(PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1) && + ((I915_READ(PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1))) { + DRM_DEBUG_KMS("Engine Idle wait time not set properly.\n"); + enable_rc6 = false; + } + + if (!(I915_READ(GEN6_RC_CONTROL) & (GEN6_RC_CTL_RC6_ENABLE | + GEN6_RC_CTL_HW_ENABLE)) && + ((I915_READ(GEN6_RC_CONTROL) & GEN6_RC_CTL_HW_ENABLE) || + !(I915_READ(GEN6_RC_STATE) & RC6_STATE))) { + DRM_DEBUG_KMS("HW/SW RC6 is not enabled by BIOS.\n"); + enable_rc6 = false; + } + + return enable_rc6; +} + +int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6) { /* No RC6 before Ironlake and code is gone for ilk. */ if (INTEL_INFO(dev)->gen < 6) return 0; + if (!enable_rc6) + return 0; + + if (IS_BROXTON(dev) && !bxt_check_bios_rc6_setup(dev)) { + DRM_INFO("RC6 disabled by BIOS\n"); + return 0; + } + /* Respect the kernel parameter if it is set */ if (enable_rc6 >= 0) { int mask; @@ -6057,7 +6107,6 @@ void intel_init_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6); /* * RPM depends on RC6 to save restore the GT HW context, so make RC6 a * requirement. diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index bfa79e5c214e..436d8f2b8682 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -400,6 +400,8 @@ void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake) void intel_uncore_sanitize(struct drm_device *dev) { + i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6); + /* BIOS often leaves RC6 enabled, but disable it for hw init */ intel_disable_gt_powersave(dev); } -- GitLab From 80b14d5e61ca6d08e46b4fc72baf6e4f738b30ce Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Feb 2015 20:31:59 -0500 Subject: [PATCH 0723/5324] SUNRPC: Add a structure to track multiple transports In order to support multipathing/trunking we will need the ability to track multiple transports. This patch sets up a basic structure for doing so. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprt.h | 5 + include/linux/sunrpc/xprtmultipath.h | 69 ++++ net/sunrpc/Makefile | 3 +- net/sunrpc/xprt.c | 1 + net/sunrpc/xprtmultipath.c | 475 +++++++++++++++++++++++++++ 5 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 include/linux/sunrpc/xprtmultipath.h create mode 100644 net/sunrpc/xprtmultipath.c diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 83218129ff28..fb0d212e0d3a 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -197,6 +197,11 @@ struct rpc_xprt { transport */ unsigned int bind_index; /* bind function index */ + /* + * Multipath + */ + struct list_head xprt_switch; + /* * Connection of transports */ diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h new file mode 100644 index 000000000000..5a9acffa41be --- /dev/null +++ b/include/linux/sunrpc/xprtmultipath.h @@ -0,0 +1,69 @@ +/* + * RPC client multipathing definitions + * + * Copyright (c) 2015, 2016, Primary Data, Inc. All rights reserved. + * + * Trond Myklebust + */ +#ifndef _NET_SUNRPC_XPRTMULTIPATH_H +#define _NET_SUNRPC_XPRTMULTIPATH_H + +struct rpc_xprt_iter_ops; +struct rpc_xprt_switch { + spinlock_t xps_lock; + struct kref xps_kref; + + unsigned int xps_nxprts; + struct list_head xps_xprt_list; + + struct net * xps_net; + + const struct rpc_xprt_iter_ops *xps_iter_ops; + + struct rcu_head xps_rcu; +}; + +struct rpc_xprt_iter { + struct rpc_xprt_switch __rcu *xpi_xpswitch; + struct rpc_xprt * xpi_cursor; + + const struct rpc_xprt_iter_ops *xpi_ops; +}; + + +struct rpc_xprt_iter_ops { + void (*xpi_rewind)(struct rpc_xprt_iter *); + struct rpc_xprt *(*xpi_xprt)(struct rpc_xprt_iter *); + struct rpc_xprt *(*xpi_next)(struct rpc_xprt_iter *); +}; + +extern struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt, + gfp_t gfp_flags); + +extern struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps); +extern void xprt_switch_put(struct rpc_xprt_switch *xps); + +extern void rpc_xprt_switch_set_roundrobin(struct rpc_xprt_switch *xps); + +extern void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt); +extern void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt); + +extern void xprt_iter_init(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *xps); + +extern void xprt_iter_init_listall(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *xps); + +extern void xprt_iter_destroy(struct rpc_xprt_iter *xpi); + +extern struct rpc_xprt_switch *xprt_iter_xchg_switch( + struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *newswitch); + +extern struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi); +extern struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi); +extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi); + +#endif diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index b512fbd9d79a..ea7ffa12e0f9 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile @@ -12,7 +12,8 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ svc.o svcsock.o svcauth.o svcauth_unix.o \ addr.o rpcb_clnt.o timer.o xdr.o \ sunrpc_syms.o cache.o rpc_pipe.o \ - svc_xprt.o + svc_xprt.o \ + xprtmultipath.o sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o sunrpc-$(CONFIG_PROC_FS) += stats.o diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 605858699f6c..323b332f8f7c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1319,6 +1319,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net) spin_lock_init(&xprt->bc_pa_lock); INIT_LIST_HEAD(&xprt->bc_pa_list); #endif /* CONFIG_SUNRPC_BACKCHANNEL */ + INIT_LIST_HEAD(&xprt->xprt_switch); xprt->last_used = jiffies; xprt->cwnd = RPC_INITCWND; diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c new file mode 100644 index 000000000000..e7fd76975d86 --- /dev/null +++ b/net/sunrpc/xprtmultipath.c @@ -0,0 +1,475 @@ +/* + * Multipath support for RPC + * + * Copyright (c) 2015, 2016, Primary Data, Inc. All rights reserved. + * + * Trond Myklebust + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct list_head *head, + const struct rpc_xprt *cur); + +static const struct rpc_xprt_iter_ops rpc_xprt_iter_singular; +static const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin; +static const struct rpc_xprt_iter_ops rpc_xprt_iter_listall; + +static void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt) +{ + if (unlikely(xprt_get(xprt) == NULL)) + return; + list_add_tail_rcu(&xprt->xprt_switch, &xps->xps_xprt_list); + smp_wmb(); + if (xps->xps_nxprts == 0) + xps->xps_net = xprt->xprt_net; + xps->xps_nxprts++; +} + +/** + * rpc_xprt_switch_add_xprt - Add a new rpc_xprt to an rpc_xprt_switch + * @xps: pointer to struct rpc_xprt_switch + * @xprt: pointer to struct rpc_xprt + * + * Adds xprt to the end of the list of struct rpc_xprt in xps. + */ +void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt) +{ + if (xprt == NULL) + return; + spin_lock(&xps->xps_lock); + if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) + xprt_switch_add_xprt_locked(xps, xprt); + spin_unlock(&xps->xps_lock); +} + +static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt) +{ + if (unlikely(xprt == NULL)) + return; + xps->xps_nxprts--; + if (xps->xps_nxprts == 0) + xps->xps_net = NULL; + smp_wmb(); + list_del_rcu(&xprt->xprt_switch); +} + +/** + * rpc_xprt_switch_remove_xprt - Removes an rpc_xprt from a rpc_xprt_switch + * @xps: pointer to struct rpc_xprt_switch + * @xprt: pointer to struct rpc_xprt + * + * Removes xprt from the list of struct rpc_xprt in xps. + */ +void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt) +{ + spin_lock(&xps->xps_lock); + xprt_switch_remove_xprt_locked(xps, xprt); + spin_unlock(&xps->xps_lock); + xprt_put(xprt); +} + +/** + * xprt_switch_alloc - Allocate a new struct rpc_xprt_switch + * @xprt: pointer to struct rpc_xprt + * @gfp_flags: allocation flags + * + * On success, returns an initialised struct rpc_xprt_switch, containing + * the entry xprt. Returns NULL on failure. + */ +struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt, + gfp_t gfp_flags) +{ + struct rpc_xprt_switch *xps; + + xps = kmalloc(sizeof(*xps), gfp_flags); + if (xps != NULL) { + spin_lock_init(&xps->xps_lock); + kref_init(&xps->xps_kref); + xps->xps_nxprts = 0; + INIT_LIST_HEAD(&xps->xps_xprt_list); + xps->xps_iter_ops = &rpc_xprt_iter_singular; + xprt_switch_add_xprt_locked(xps, xprt); + } + + return xps; +} + +static void xprt_switch_free_entries(struct rpc_xprt_switch *xps) +{ + spin_lock(&xps->xps_lock); + while (!list_empty(&xps->xps_xprt_list)) { + struct rpc_xprt *xprt; + + xprt = list_first_entry(&xps->xps_xprt_list, + struct rpc_xprt, xprt_switch); + xprt_switch_remove_xprt_locked(xps, xprt); + spin_unlock(&xps->xps_lock); + xprt_put(xprt); + spin_lock(&xps->xps_lock); + } + spin_unlock(&xps->xps_lock); +} + +static void xprt_switch_free(struct kref *kref) +{ + struct rpc_xprt_switch *xps = container_of(kref, + struct rpc_xprt_switch, xps_kref); + + xprt_switch_free_entries(xps); + kfree_rcu(xps, xps_rcu); +} + +/** + * xprt_switch_get - Return a reference to a rpc_xprt_switch + * @xps: pointer to struct rpc_xprt_switch + * + * Returns a reference to xps unless the refcount is already zero. + */ +struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps) +{ + if (xps != NULL && kref_get_unless_zero(&xps->xps_kref)) + return xps; + return NULL; +} + +/** + * xprt_switch_put - Release a reference to a rpc_xprt_switch + * @xps: pointer to struct rpc_xprt_switch + * + * Release the reference to xps, and free it once the refcount is zero. + */ +void xprt_switch_put(struct rpc_xprt_switch *xps) +{ + if (xps != NULL) + kref_put(&xps->xps_kref, xprt_switch_free); +} + +/** + * rpc_xprt_switch_set_roundrobin - Set a round-robin policy on rpc_xprt_switch + * @xps: pointer to struct rpc_xprt_switch + * + * Sets a round-robin default policy for iterators acting on xps. + */ +void rpc_xprt_switch_set_roundrobin(struct rpc_xprt_switch *xps) +{ + if (READ_ONCE(xps->xps_iter_ops) != &rpc_xprt_iter_roundrobin) + WRITE_ONCE(xps->xps_iter_ops, &rpc_xprt_iter_roundrobin); +} + +static +const struct rpc_xprt_iter_ops *xprt_iter_ops(const struct rpc_xprt_iter *xpi) +{ + if (xpi->xpi_ops != NULL) + return xpi->xpi_ops; + return rcu_dereference(xpi->xpi_xpswitch)->xps_iter_ops; +} + +static +void xprt_iter_no_rewind(struct rpc_xprt_iter *xpi) +{ +} + +static +void xprt_iter_default_rewind(struct rpc_xprt_iter *xpi) +{ + WRITE_ONCE(xpi->xpi_cursor, NULL); +} + +static +struct rpc_xprt *xprt_switch_find_first_entry(struct list_head *head) +{ + return list_first_or_null_rcu(head, struct rpc_xprt, xprt_switch); +} + +static +struct rpc_xprt *xprt_iter_first_entry(struct rpc_xprt_iter *xpi) +{ + struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch); + + if (xps == NULL) + return NULL; + return xprt_switch_find_first_entry(&xps->xps_xprt_list); +} + +static +struct rpc_xprt *xprt_switch_find_current_entry(struct list_head *head, + const struct rpc_xprt *cur) +{ + struct rpc_xprt *pos; + + list_for_each_entry_rcu(pos, head, xprt_switch) { + if (cur == pos) + return pos; + } + return NULL; +} + +static +struct rpc_xprt *xprt_iter_current_entry(struct rpc_xprt_iter *xpi) +{ + struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch); + struct list_head *head; + + if (xps == NULL) + return NULL; + head = &xps->xps_xprt_list; + if (xpi->xpi_cursor == NULL || xps->xps_nxprts < 2) + return xprt_switch_find_first_entry(head); + return xprt_switch_find_current_entry(head, xpi->xpi_cursor); +} + +static +struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head, + const struct rpc_xprt *cur) +{ + struct rpc_xprt *pos, *prev = NULL; + + list_for_each_entry_rcu(pos, head, xprt_switch) { + if (cur == prev) + return pos; + prev = pos; + } + return NULL; +} + +static +struct rpc_xprt *xprt_switch_set_next_cursor(struct list_head *head, + struct rpc_xprt **cursor, + xprt_switch_find_xprt_t find_next) +{ + struct rpc_xprt *cur, *pos, *old; + + cur = READ_ONCE(*cursor); + for (;;) { + old = cur; + pos = find_next(head, old); + if (pos == NULL) + break; + cur = cmpxchg_relaxed(cursor, old, pos); + if (cur == old) + break; + } + return pos; +} + +static +struct rpc_xprt *xprt_iter_next_entry_multiple(struct rpc_xprt_iter *xpi, + xprt_switch_find_xprt_t find_next) +{ + struct rpc_xprt_switch *xps = rcu_dereference(xpi->xpi_xpswitch); + struct list_head *head; + + if (xps == NULL) + return NULL; + head = &xps->xps_xprt_list; + if (xps->xps_nxprts < 2) + return xprt_switch_find_first_entry(head); + return xprt_switch_set_next_cursor(head, &xpi->xpi_cursor, find_next); +} + +static +struct rpc_xprt *xprt_switch_find_next_entry_roundrobin(struct list_head *head, + const struct rpc_xprt *cur) +{ + struct rpc_xprt *ret; + + ret = xprt_switch_find_next_entry(head, cur); + if (ret != NULL) + return ret; + return xprt_switch_find_first_entry(head); +} + +static +struct rpc_xprt *xprt_iter_next_entry_roundrobin(struct rpc_xprt_iter *xpi) +{ + return xprt_iter_next_entry_multiple(xpi, + xprt_switch_find_next_entry_roundrobin); +} + +static +struct rpc_xprt *xprt_iter_next_entry_all(struct rpc_xprt_iter *xpi) +{ + return xprt_iter_next_entry_multiple(xpi, xprt_switch_find_next_entry); +} + +/* + * xprt_iter_rewind - Resets the xprt iterator + * @xpi: pointer to rpc_xprt_iter + * + * Resets xpi to ensure that it points to the first entry in the list + * of transports. + */ +static +void xprt_iter_rewind(struct rpc_xprt_iter *xpi) +{ + rcu_read_lock(); + xprt_iter_ops(xpi)->xpi_rewind(xpi); + rcu_read_unlock(); +} + +static void __xprt_iter_init(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *xps, + const struct rpc_xprt_iter_ops *ops) +{ + rcu_assign_pointer(xpi->xpi_xpswitch, xprt_switch_get(xps)); + xpi->xpi_cursor = NULL; + xpi->xpi_ops = ops; +} + +/** + * xprt_iter_init - Initialise an xprt iterator + * @xpi: pointer to rpc_xprt_iter + * @xps: pointer to rpc_xprt_switch + * + * Initialises the iterator to use the default iterator ops + * as set in xps. This function is mainly intended for internal + * use in the rpc_client. + */ +void xprt_iter_init(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *xps) +{ + __xprt_iter_init(xpi, xps, NULL); +} + +/** + * xprt_iter_init_listall - Initialise an xprt iterator + * @xpi: pointer to rpc_xprt_iter + * @xps: pointer to rpc_xprt_switch + * + * Initialises the iterator to iterate once through the entire list + * of entries in xps. + */ +void xprt_iter_init_listall(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *xps) +{ + __xprt_iter_init(xpi, xps, &rpc_xprt_iter_listall); +} + +/** + * xprt_iter_xchg_switch - Atomically swap out the rpc_xprt_switch + * @xpi: pointer to rpc_xprt_iter + * @xps: pointer to a new rpc_xprt_switch or NULL + * + * Swaps out the existing xpi->xpi_xpswitch with a new value. + */ +struct rpc_xprt_switch *xprt_iter_xchg_switch(struct rpc_xprt_iter *xpi, + struct rpc_xprt_switch *newswitch) +{ + struct rpc_xprt_switch __rcu *oldswitch; + + /* Atomically swap out the old xpswitch */ + oldswitch = xchg(&xpi->xpi_xpswitch, RCU_INITIALIZER(newswitch)); + if (newswitch != NULL) + xprt_iter_rewind(xpi); + return rcu_dereference_protected(oldswitch, true); +} + +/** + * xprt_iter_destroy - Destroys the xprt iterator + * @xpi pointer to rpc_xprt_iter + */ +void xprt_iter_destroy(struct rpc_xprt_iter *xpi) +{ + xprt_switch_put(xprt_iter_xchg_switch(xpi, NULL)); +} + +/** + * xprt_iter_xprt - Returns the rpc_xprt pointed to by the cursor + * @xpi: pointer to rpc_xprt_iter + * + * Returns a pointer to the struct rpc_xprt that is currently + * pointed to by the cursor. + * Caller must be holding rcu_read_lock(). + */ +struct rpc_xprt *xprt_iter_xprt(struct rpc_xprt_iter *xpi) +{ + WARN_ON_ONCE(!rcu_read_lock_held()); + return xprt_iter_ops(xpi)->xpi_xprt(xpi); +} + +static +struct rpc_xprt *xprt_iter_get_helper(struct rpc_xprt_iter *xpi, + struct rpc_xprt *(*fn)(struct rpc_xprt_iter *)) +{ + struct rpc_xprt *ret; + + do { + ret = fn(xpi); + if (ret == NULL) + break; + ret = xprt_get(ret); + } while (ret == NULL); + return ret; +} + +/** + * xprt_iter_get_xprt - Returns the rpc_xprt pointed to by the cursor + * @xpi: pointer to rpc_xprt_iter + * + * Returns a reference to the struct rpc_xprt that is currently + * pointed to by the cursor. + */ +struct rpc_xprt *xprt_iter_get_xprt(struct rpc_xprt_iter *xpi) +{ + struct rpc_xprt *xprt; + + rcu_read_lock(); + xprt = xprt_iter_get_helper(xpi, xprt_iter_ops(xpi)->xpi_xprt); + rcu_read_unlock(); + return xprt; +} + +/** + * xprt_iter_get_next - Returns the next rpc_xprt following the cursor + * @xpi: pointer to rpc_xprt_iter + * + * Returns a reference to the struct rpc_xprt that immediately follows the + * entry pointed to by the cursor. + */ +struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi) +{ + struct rpc_xprt *xprt; + + rcu_read_lock(); + xprt = xprt_iter_get_helper(xpi, xprt_iter_ops(xpi)->xpi_next); + rcu_read_unlock(); + return xprt; +} + +/* Policy for always returning the first entry in the rpc_xprt_switch */ +static +const struct rpc_xprt_iter_ops rpc_xprt_iter_singular = { + .xpi_rewind = xprt_iter_no_rewind, + .xpi_xprt = xprt_iter_first_entry, + .xpi_next = xprt_iter_first_entry, +}; + +/* Policy for round-robin iteration of entries in the rpc_xprt_switch */ +static +const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin = { + .xpi_rewind = xprt_iter_default_rewind, + .xpi_xprt = xprt_iter_current_entry, + .xpi_next = xprt_iter_next_entry_roundrobin, +}; + +/* Policy for once-through iteration of entries in the rpc_xprt_switch */ +static +const struct rpc_xprt_iter_ops rpc_xprt_iter_listall = { + .xpi_rewind = xprt_iter_default_rewind, + .xpi_xprt = xprt_iter_current_entry, + .xpi_next = xprt_iter_next_entry_all, +}; -- GitLab From ad01b2c68d0ac5f3d4a3f807bec77b720b1c62a0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 14:17:26 -0500 Subject: [PATCH 0724/5324] SUNRPC: Make rpc_clnt store the multipath iterators This is a pre-patch for the RPC multipath code. It sets up the storage in struct rpc_clnt for the multipath code. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 2 ++ net/sunrpc/auth_gss/auth_gss.c | 4 ++-- net/sunrpc/clnt.c | 32 +++++++++++++++++++++++++++++--- net/sunrpc/rpcb_clnt.c | 4 ++-- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 0c5c2cbe96c9..1713e41d65ae 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -25,6 +25,7 @@ #include #include #include +#include struct rpc_inode; @@ -67,6 +68,7 @@ struct rpc_clnt { #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) struct dentry *cl_debugfs; /* debugfs directory */ #endif + struct rpc_xprt_iter cl_xpi; }; /* diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 799e65b944b9..3ce391cb80c4 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1181,12 +1181,12 @@ static struct rpc_auth * gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) { struct gss_auth *gss_auth; - struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt); + struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch); while (clnt != clnt->cl_parent) { struct rpc_clnt *parent = clnt->cl_parent; /* Find the original parent for this transport */ - if (rcu_access_pointer(parent->cl_xprt) != xprt) + if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps) break; clnt = parent; } diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2b4ad7aa40c6..625fb8a184c6 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -354,6 +354,7 @@ static void rpc_free_clid(struct rpc_clnt *clnt) } static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, + struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, struct rpc_clnt *parent) { @@ -411,6 +412,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, } rpc_clnt_set_transport(clnt, xprt, timeout); + xprt_iter_init(&clnt->cl_xpi, xps); + xprt_switch_put(xps); clnt->cl_rtt = &clnt->cl_rtt_default; rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); @@ -438,6 +441,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, out_err: rpciod_down(); out_no_rpciod: + xprt_switch_put(xps); xprt_put(xprt); return ERR_PTR(err); } @@ -446,8 +450,13 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, struct rpc_xprt *xprt) { struct rpc_clnt *clnt = NULL; + struct rpc_xprt_switch *xps; - clnt = rpc_new_client(args, xprt, NULL); + xps = xprt_switch_alloc(xprt, GFP_KERNEL); + if (xps == NULL) + return ERR_PTR(-ENOMEM); + + clnt = rpc_new_client(args, xps, xprt, NULL); if (IS_ERR(clnt)) return clnt; @@ -564,6 +573,7 @@ EXPORT_SYMBOL_GPL(rpc_create); static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, struct rpc_clnt *clnt) { + struct rpc_xprt_switch *xps; struct rpc_xprt *xprt; struct rpc_clnt *new; int err; @@ -571,13 +581,17 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, err = -ENOMEM; rcu_read_lock(); xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); + xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); rcu_read_unlock(); - if (xprt == NULL) + if (xprt == NULL || xps == NULL) { + xprt_put(xprt); + xprt_switch_put(xps); goto out_err; + } args->servername = xprt->servername; args->nodename = clnt->cl_nodename; - new = rpc_new_client(args, xprt, clnt); + new = rpc_new_client(args, xps, xprt, clnt); if (IS_ERR(new)) { err = PTR_ERR(new); goto out_err; @@ -657,6 +671,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt, { const struct rpc_timeout *old_timeo; rpc_authflavor_t pseudoflavor; + struct rpc_xprt_switch *xps, *oldxps; struct rpc_xprt *xprt, *old; struct rpc_clnt *parent; int err; @@ -668,10 +683,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt, return PTR_ERR(xprt); } + xps = xprt_switch_alloc(xprt, GFP_KERNEL); + if (xps == NULL) { + xprt_put(xprt); + return -ENOMEM; + } + pseudoflavor = clnt->cl_auth->au_flavor; old_timeo = clnt->cl_timeout; old = rpc_clnt_set_transport(clnt, xprt, timeout); + oldxps = xprt_iter_xchg_switch(&clnt->cl_xpi, xps); rpc_unregister_client(clnt); __rpc_clnt_remove_pipedir(clnt); @@ -697,14 +719,17 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt, synchronize_rcu(); if (parent != clnt) rpc_release_client(parent); + xprt_switch_put(oldxps); xprt_put(old); dprintk("RPC: replaced xprt for clnt %p\n", clnt); return 0; out_revert: + xps = xprt_iter_xchg_switch(&clnt->cl_xpi, oldxps); rpc_clnt_set_transport(clnt, old, old_timeo); clnt->cl_parent = parent; rpc_client_register(clnt, pseudoflavor, NULL); + xprt_switch_put(xps); xprt_put(xprt); dprintk("RPC: failed to switch xprt for clnt %p\n", clnt); return err; @@ -783,6 +808,7 @@ rpc_free_client(struct rpc_clnt *clnt) rpc_free_iostats(clnt->cl_metrics); clnt->cl_metrics = NULL; xprt_put(rcu_dereference_raw(clnt->cl_xprt)); + xprt_iter_destroy(&clnt->cl_xpi); rpciod_down(); rpc_free_clid(clnt); kfree(clnt); diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index cf5770d8f49a..44f025c150d8 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -648,10 +648,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt) { struct rpc_clnt *parent = clnt->cl_parent; - struct rpc_xprt *xprt = rcu_dereference(clnt->cl_xprt); + struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch); while (parent != clnt) { - if (rcu_dereference(parent->cl_xprt) != xprt) + if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps) break; if (clnt->cl_autobind) break; -- GitLab From fb43d17210baa538e58fc83d2d0f8a32399db73b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 16:39:26 -0500 Subject: [PATCH 0725/5324] SUNRPC: Use the multipath iterator to assign a transport to each task Signed-off-by: Trond Myklebust --- include/linux/sunrpc/sched.h | 2 ++ net/sunrpc/clnt.c | 38 +++++++++++++++++++----------------- net/sunrpc/rpcb_clnt.c | 6 ++---- net/sunrpc/xprt.c | 14 +++---------- net/sunrpc/xprtsock.c | 4 +--- 5 files changed, 28 insertions(+), 36 deletions(-) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index ee0fbcf9b02e..0b248e98ee3b 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -69,6 +69,8 @@ struct rpc_task { const struct rpc_call_ops *tk_ops; /* Caller callbacks */ struct rpc_clnt * tk_client; /* RPC client */ + struct rpc_xprt * tk_xprt; /* Transport */ + struct rpc_rqst * tk_rqstp; /* RPC request */ struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 625fb8a184c6..8e46fa5a2ab1 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -894,6 +894,7 @@ EXPORT_SYMBOL_GPL(rpc_bind_new_program); void rpc_task_release_client(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; + struct rpc_xprt *xprt = task->tk_xprt; if (clnt != NULL) { /* Remove from client task list */ @@ -904,13 +905,22 @@ void rpc_task_release_client(struct rpc_task *task) rpc_release_client(clnt); } + + if (xprt != NULL) { + task->tk_xprt = NULL; + + xprt_put(xprt); + } } static void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) { + if (clnt != NULL) { rpc_task_release_client(task); + if (task->tk_xprt == NULL) + task->tk_xprt = xprt_iter_get_next(&clnt->cl_xpi); task->tk_client = clnt; atomic_inc(&clnt->cl_count); if (clnt->cl_softrtry) @@ -2122,11 +2132,9 @@ call_timeout(struct rpc_task *task) } if (RPC_IS_SOFT(task)) { if (clnt->cl_chatty) { - rcu_read_lock(); printk(KERN_NOTICE "%s: server %s not responding, timed out\n", clnt->cl_program->name, - rcu_dereference(clnt->cl_xprt)->servername); - rcu_read_unlock(); + task->tk_xprt->servername); } if (task->tk_flags & RPC_TASK_TIMEOUT) rpc_exit(task, -ETIMEDOUT); @@ -2138,11 +2146,9 @@ call_timeout(struct rpc_task *task) if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { task->tk_flags |= RPC_CALL_MAJORSEEN; if (clnt->cl_chatty) { - rcu_read_lock(); printk(KERN_NOTICE "%s: server %s not responding, still trying\n", clnt->cl_program->name, - rcu_dereference(clnt->cl_xprt)->servername); - rcu_read_unlock(); + task->tk_xprt->servername); } } rpc_force_rebind(clnt); @@ -2172,11 +2178,9 @@ call_decode(struct rpc_task *task) if (task->tk_flags & RPC_CALL_MAJORSEEN) { if (clnt->cl_chatty) { - rcu_read_lock(); printk(KERN_NOTICE "%s: server %s OK\n", clnt->cl_program->name, - rcu_dereference(clnt->cl_xprt)->servername); - rcu_read_unlock(); + task->tk_xprt->servername); } task->tk_flags &= ~RPC_CALL_MAJORSEEN; } @@ -2330,11 +2334,9 @@ rpc_verify_header(struct rpc_task *task) task->tk_action = call_bind; goto out_retry; case RPC_AUTH_TOOWEAK: - rcu_read_lock(); printk(KERN_NOTICE "RPC: server %s requires stronger " "authentication.\n", - rcu_dereference(clnt->cl_xprt)->servername); - rcu_read_unlock(); + task->tk_xprt->servername); break; default: dprintk("RPC: %5u %s: unknown auth error: %x\n", @@ -2359,27 +2361,27 @@ rpc_verify_header(struct rpc_task *task) case RPC_SUCCESS: return p; case RPC_PROG_UNAVAIL: - dprintk_rcu("RPC: %5u %s: program %u is unsupported " + dprintk("RPC: %5u %s: program %u is unsupported " "by server %s\n", task->tk_pid, __func__, (unsigned int)clnt->cl_prog, - rcu_dereference(clnt->cl_xprt)->servername); + task->tk_xprt->servername); error = -EPFNOSUPPORT; goto out_err; case RPC_PROG_MISMATCH: - dprintk_rcu("RPC: %5u %s: program %u, version %u unsupported " + dprintk("RPC: %5u %s: program %u, version %u unsupported " "by server %s\n", task->tk_pid, __func__, (unsigned int)clnt->cl_prog, (unsigned int)clnt->cl_vers, - rcu_dereference(clnt->cl_xprt)->servername); + task->tk_xprt->servername); error = -EPROTONOSUPPORT; goto out_err; case RPC_PROC_UNAVAIL: - dprintk_rcu("RPC: %5u %s: proc %s unsupported by program %u, " + dprintk("RPC: %5u %s: proc %s unsupported by program %u, " "version %u on server %s\n", task->tk_pid, __func__, rpc_proc_name(task), clnt->cl_prog, clnt->cl_vers, - rcu_dereference(clnt->cl_xprt)->servername); + task->tk_xprt->servername); error = -EOPNOTSUPP; goto out_err; case RPC_GARBAGE_ARGS: diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 44f025c150d8..5b30603596d0 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -683,11 +683,9 @@ void rpcb_getport_async(struct rpc_task *task) int status; rcu_read_lock(); - do { - clnt = rpcb_find_transport_owner(task->tk_client); - xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); - } while (xprt == NULL); + clnt = rpcb_find_transport_owner(task->tk_client); rcu_read_unlock(); + xprt = xprt_get(task->tk_xprt); dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", task->tk_pid, __func__, diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 323b332f8f7c..216a1385718a 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1181,7 +1181,7 @@ EXPORT_SYMBOL_GPL(xprt_free); */ void xprt_reserve(struct rpc_task *task) { - struct rpc_xprt *xprt; + struct rpc_xprt *xprt = task->tk_xprt; task->tk_status = 0; if (task->tk_rqstp != NULL) @@ -1189,11 +1189,8 @@ void xprt_reserve(struct rpc_task *task) task->tk_timeout = 0; task->tk_status = -EAGAIN; - rcu_read_lock(); - xprt = rcu_dereference(task->tk_client->cl_xprt); if (!xprt_throttle_congested(xprt, task)) xprt->ops->alloc_slot(xprt, task); - rcu_read_unlock(); } /** @@ -1207,7 +1204,7 @@ void xprt_reserve(struct rpc_task *task) */ void xprt_retry_reserve(struct rpc_task *task) { - struct rpc_xprt *xprt; + struct rpc_xprt *xprt = task->tk_xprt; task->tk_status = 0; if (task->tk_rqstp != NULL) @@ -1215,10 +1212,7 @@ void xprt_retry_reserve(struct rpc_task *task) task->tk_timeout = 0; task->tk_status = -EAGAIN; - rcu_read_lock(); - xprt = rcu_dereference(task->tk_client->cl_xprt); xprt->ops->alloc_slot(xprt, task); - rcu_read_unlock(); } static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) @@ -1265,11 +1259,9 @@ void xprt_release(struct rpc_task *task) if (req == NULL) { if (task->tk_client) { - rcu_read_lock(); - xprt = rcu_dereference(task->tk_client->cl_xprt); + xprt = task->tk_xprt; if (xprt->snd_task == task) xprt_release_write(xprt, task); - rcu_read_unlock(); } return; } diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index fde2138b81e7..65e759569e48 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1844,9 +1844,7 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) */ static void xs_local_rpcbind(struct rpc_task *task) { - rcu_read_lock(); - xprt_set_bound(rcu_dereference(task->tk_client->cl_xprt)); - rcu_read_unlock(); + xprt_set_bound(task->tk_xprt); } static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port) -- GitLab From 9d61498d5f6cde68a708781bf2cd33cae21121dc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 18:13:05 -0500 Subject: [PATCH 0726/5324] SUNRPC: Allow caller to specify the transport to use This is needed in order to allow the NFSv4.1 backchannel and BIND_CONN_TO_SESSION function to work. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/sched.h | 1 + net/sunrpc/sched.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 0b248e98ee3b..05a1809c44d9 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -103,6 +103,7 @@ struct rpc_call_ops { struct rpc_task_setup { struct rpc_task *task; struct rpc_clnt *rpc_client; + struct rpc_xprt *rpc_xprt; const struct rpc_message *rpc_message; const struct rpc_call_ops *callback_ops; void *callback_data; diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 73ad57a59989..fcfd48d263f6 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -909,6 +909,8 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta /* Initialize workqueue for async tasks */ task->tk_workqueue = task_setup_data->workqueue; + task->tk_xprt = xprt_get(task_setup_data->rpc_xprt); + if (task->tk_ops->rpc_call_prepare != NULL) task->tk_action = rpc_prepare_task; -- GitLab From 3227886c6500e76c17f3b864ff9b7dd84f636a99 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 20:39:19 -0500 Subject: [PATCH 0727/5324] SUNRPC: Add a helper to apply a function to all the rpc_clnt's transports Add a helper for tasks that require us to apply a function to all the transports in an rpc_clnt. An example of a usecase would be BIND_CONN_TO_SESSION, where we want to send one RPC call down each transport. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 4 +++ net/sunrpc/clnt.c | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 1713e41d65ae..d6510f64a361 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -182,6 +182,10 @@ size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); +int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt, + int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *), + void *data); + const char *rpc_proc_name(const struct rpc_task *task); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8e46fa5a2ab1..19feb4d5d796 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -736,6 +736,57 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt, } EXPORT_SYMBOL_GPL(rpc_switch_client_transport); +static +int rpc_clnt_xprt_iter_init(struct rpc_clnt *clnt, struct rpc_xprt_iter *xpi) +{ + struct rpc_xprt_switch *xps; + + rcu_read_lock(); + xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); + rcu_read_unlock(); + if (xps == NULL) + return -EAGAIN; + xprt_iter_init_listall(xpi, xps); + xprt_switch_put(xps); + return 0; +} + +/** + * rpc_clnt_iterate_for_each_xprt - Apply a function to all transports + * @clnt: pointer to client + * @fn: function to apply + * @data: void pointer to function data + * + * Iterates through the list of RPC transports currently attached to the + * client and applies the function fn(clnt, xprt, data). + * + * On error, the iteration stops, and the function returns the error value. + */ +int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt, + int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *), + void *data) +{ + struct rpc_xprt_iter xpi; + int ret; + + ret = rpc_clnt_xprt_iter_init(clnt, &xpi); + if (ret) + return ret; + for (;;) { + struct rpc_xprt *xprt = xprt_iter_get_next(&xpi); + + if (!xprt) + break; + ret = fn(clnt, xprt, data); + xprt_put(xprt); + if (ret < 0) + break; + } + xprt_iter_destroy(&xpi); + return ret; +} +EXPORT_SYMBOL_GPL(rpc_clnt_iterate_for_each_xprt); + /* * Kill all tasks for the given client. * XXX: kill their descendants as well? -- GitLab From 15001e5a7e1e207b6bd258cd8f187814cd15b6dc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 20:05:34 -0500 Subject: [PATCH 0728/5324] SUNRPC: Make NFS swap work with multipath Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 66 +++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 19feb4d5d796..4b6ceb7c5e1d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2554,57 +2554,39 @@ void rpc_show_tasks(struct net *net) #endif #if IS_ENABLED(CONFIG_SUNRPC_SWAP) +static int +rpc_clnt_swap_activate_callback(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + void *dummy) +{ + return xprt_enable_swap(xprt); +} + int rpc_clnt_swap_activate(struct rpc_clnt *clnt) { - int ret = 0; - struct rpc_xprt *xprt; - - if (atomic_inc_return(&clnt->cl_swapper) == 1) { -retry: - rcu_read_lock(); - xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); - rcu_read_unlock(); - if (!xprt) { - /* - * If we didn't get a reference, then we likely are - * racing with a migration event. Wait for a grace - * period and try again. - */ - synchronize_rcu(); - goto retry; - } - - ret = xprt_enable_swap(xprt); - xprt_put(xprt); - } - return ret; + if (atomic_inc_return(&clnt->cl_swapper) == 1) + return rpc_clnt_iterate_for_each_xprt(clnt, + rpc_clnt_swap_activate_callback, NULL); + return 0; } EXPORT_SYMBOL_GPL(rpc_clnt_swap_activate); +static int +rpc_clnt_swap_deactivate_callback(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + void *dummy) +{ + xprt_disable_swap(xprt); + return 0; +} + void rpc_clnt_swap_deactivate(struct rpc_clnt *clnt) { - struct rpc_xprt *xprt; - - if (atomic_dec_if_positive(&clnt->cl_swapper) == 0) { -retry: - rcu_read_lock(); - xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); - rcu_read_unlock(); - if (!xprt) { - /* - * If we didn't get a reference, then we likely are - * racing with a migration event. Wait for a grace - * period and try again. - */ - synchronize_rcu(); - goto retry; - } - - xprt_disable_swap(xprt); - xprt_put(xprt); - } + if (atomic_dec_if_positive(&clnt->cl_swapper) == 0) + rpc_clnt_iterate_for_each_xprt(clnt, + rpc_clnt_swap_deactivate_callback, NULL); } EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate); #endif /* CONFIG_SUNRPC_SWAP */ -- GitLab From d9ddbf5d9225a417076e89ef650dd276165dfd07 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 22:58:24 -0500 Subject: [PATCH 0729/5324] NFSv4.1: nfs4_proc_bind_conn_to_session must iterate over all connections Use the new helper to ensure that nfs4_proc_bind_conn_to_session() is called for all connections. However ensure that we only set the backchannel flag for the connection pointed to by rpc_clnt->cl_xprt. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4bfc33ad0563..36471e013a73 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6783,12 +6783,16 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, } /* - * nfs4_proc_bind_conn_to_session() + * nfs4_proc_bind_one_conn_to_session() * * The 4.1 client currently uses the same TCP connection for the * fore and backchannel. */ -int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) +static +int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + struct nfs_client *clp, + struct rpc_cred *cred) { int status; struct nfs41_bind_conn_to_session_args args = { @@ -6803,6 +6807,13 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred .rpc_resp = &res, .rpc_cred = cred, }; + struct rpc_task_setup task_setup_data = { + .rpc_client = clnt, + .rpc_xprt = xprt, + .rpc_message = &msg, + .flags = RPC_TASK_TIMEOUT, + }; + struct rpc_task *task; dprintk("--> %s\n", __func__); @@ -6810,7 +6821,16 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred if (!(clp->cl_session->flags & SESSION4_BACK_CHAN)) args.dir = NFS4_CDFC4_FORE; - status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); + /* Do not set the backchannel flag unless this is clnt->cl_xprt */ + if (xprt != rcu_access_pointer(clnt->cl_xprt)) + args.dir = NFS4_CDFC4_FORE; + + task = rpc_run_task(&task_setup_data); + if (!IS_ERR(task)) { + status = task->tk_status; + rpc_put_task(task); + } else + status = PTR_ERR(task); trace_nfs4_bind_conn_to_session(clp, status); if (status == 0) { if (memcmp(res.sessionid.data, @@ -6837,6 +6857,31 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred return status; } +struct rpc_bind_conn_calldata { + struct nfs_client *clp; + struct rpc_cred *cred; +}; + +static int +nfs4_proc_bind_conn_to_session_callback(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + void *calldata) +{ + struct rpc_bind_conn_calldata *p = calldata; + + return nfs4_proc_bind_one_conn_to_session(clnt, xprt, p->clp, p->cred); +} + +int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred) +{ + struct rpc_bind_conn_calldata data = { + .clp = clp, + .cred = cred, + }; + return rpc_clnt_iterate_for_each_xprt(clp->cl_rpcclient, + nfs4_proc_bind_conn_to_session_callback, &data); +} + /* * Minimum set of SP4_MACH_CRED operations from RFC 5661 in the enforce map * and operations we'd like to see to enable certain features in the allow map -- GitLab From 7f554890587c63ca4c087d6bcc4a9fe368e57484 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 30 Jan 2016 23:43:35 -0500 Subject: [PATCH 0730/5324] SUNRPC: Allow addition of new transports to a struct rpc_clnt Add a function to allow creation and addition of a new transport to an existing rpc_clnt Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 11 +++ net/sunrpc/clnt.c | 133 +++++++++++++++++++++++++++++++++++- 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index d6510f64a361..9a7ddbaf116e 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -186,6 +186,17 @@ int rpc_clnt_iterate_for_each_xprt(struct rpc_clnt *clnt, int (*fn)(struct rpc_clnt *, struct rpc_xprt *, void *), void *data); +int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, + struct rpc_xprt_switch *xps, + struct rpc_xprt *xprt, + void *dummy); +int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *, + int (*setup)(struct rpc_clnt *, + struct rpc_xprt_switch *, + struct rpc_xprt *, + void *), + void *data); + const char *rpc_proc_name(const struct rpc_task *task); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 4b6ceb7c5e1d..7e0c9bf22df8 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2492,7 +2492,10 @@ static int rpc_ping(struct rpc_clnt *clnt) return err; } -struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags) +static +struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, struct rpc_cred *cred, int flags, + const struct rpc_call_ops *ops, void *data) { struct rpc_message msg = { .rpc_proc = &rpcproc_null, @@ -2500,14 +2503,140 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int }; struct rpc_task_setup task_setup_data = { .rpc_client = clnt, + .rpc_xprt = xprt, .rpc_message = &msg, - .callback_ops = &rpc_default_ops, + .callback_ops = (ops != NULL) ? ops : &rpc_default_ops, + .callback_data = data, .flags = flags, }; + return rpc_run_task(&task_setup_data); } + +struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags) +{ + return rpc_call_null_helper(clnt, NULL, cred, flags, NULL, NULL); +} EXPORT_SYMBOL_GPL(rpc_call_null); +struct rpc_cb_add_xprt_calldata { + struct rpc_xprt_switch *xps; + struct rpc_xprt *xprt; +}; + +static void rpc_cb_add_xprt_done(struct rpc_task *task, void *calldata) +{ + struct rpc_cb_add_xprt_calldata *data = calldata; + + if (task->tk_status == 0) + rpc_xprt_switch_add_xprt(data->xps, data->xprt); +} + +static void rpc_cb_add_xprt_release(void *calldata) +{ + struct rpc_cb_add_xprt_calldata *data = calldata; + + xprt_put(data->xprt); + xprt_switch_put(data->xps); + kfree(data); +} + +const static struct rpc_call_ops rpc_cb_add_xprt_call_ops = { + .rpc_call_done = rpc_cb_add_xprt_done, + .rpc_release = rpc_cb_add_xprt_release, +}; + +/** + * rpc_clnt_test_and_add_xprt - Test and add a new transport to a rpc_clnt + * @clnt: pointer to struct rpc_clnt + * @xps: pointer to struct rpc_xprt_switch, + * @xprt: pointer struct rpc_xprt + * @dummy: unused + */ +int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, + struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, + void *dummy) +{ + struct rpc_cb_add_xprt_calldata *data; + struct rpc_cred *cred; + struct rpc_task *task; + + data = kmalloc(sizeof(*data), GFP_NOFS); + if (!data) + return -ENOMEM; + data->xps = xprt_switch_get(xps); + data->xprt = xprt_get(xprt); + + cred = authnull_ops.lookup_cred(NULL, NULL, 0); + task = rpc_call_null_helper(clnt, xprt, cred, + RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC, + &rpc_cb_add_xprt_call_ops, data); + put_rpccred(cred); + if (IS_ERR(task)) + return PTR_ERR(task); + rpc_put_task(task); + return 1; +} +EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt); + +/** + * rpc_clnt_add_xprt - Add a new transport to a rpc_clnt + * @clnt: pointer to struct rpc_clnt + * @xprtargs: pointer to struct xprt_create + * @setup: callback to test and/or set up the connection + * @data: pointer to setup function data + * + * Creates a new transport using the parameters set in args and + * adds it to clnt. + * If ping is set, then test that connectivity succeeds before + * adding the new transport. + * + */ +int rpc_clnt_add_xprt(struct rpc_clnt *clnt, + struct xprt_create *xprtargs, + int (*setup)(struct rpc_clnt *, + struct rpc_xprt_switch *, + struct rpc_xprt *, + void *), + void *data) +{ + struct rpc_xprt_switch *xps; + struct rpc_xprt *xprt; + unsigned char resvport; + int ret = 0; + + rcu_read_lock(); + xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); + xprt = xprt_iter_xprt(&clnt->cl_xpi); + if (xps == NULL || xprt == NULL) { + rcu_read_unlock(); + return -EAGAIN; + } + resvport = xprt->resvport; + rcu_read_unlock(); + + xprt = xprt_create_transport(xprtargs); + if (IS_ERR(xprt)) { + ret = PTR_ERR(xprt); + goto out_put_switch; + } + xprt->resvport = resvport; + + rpc_xprt_switch_set_roundrobin(xps); + if (setup) { + ret = setup(clnt, xps, xprt, data); + if (ret != 0) + goto out_put_xprt; + } + rpc_xprt_switch_add_xprt(xps, xprt); +out_put_xprt: + xprt_put(xprt); +out_put_switch: + xprt_switch_put(xps); + return ret; +} +EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static void rpc_show_header(void) { -- GitLab From fc821d59209d96e80f30f670a3acac9582dfdefd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 31 Jan 2016 14:53:08 -0500 Subject: [PATCH 0731/5324] pnfs/NFSv4.1: Add multipath capabilities to pNFS flexfiles servers over NFSv3 This adds multipathing to pNFS over NFSv3 as described in the flexfiles draft spec. Ideally, we'd like to do the same for pNFS files, but the NFSv4.1 protocol requires a call to EXCHANGE_ID in order to test that the connection can do session trunking. Signed-off-by: Trond Myklebust --- fs/nfs/pnfs_nfs.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 81ac6480f9e7..4aaed890048f 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -606,12 +606,22 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, dprintk("%s: DS %s: trying address %s\n", __func__, ds->ds_remotestr, da->da_remotestr); - clp = get_v3_ds_connect(mds_srv->nfs_client, + if (!IS_ERR(clp)) { + struct xprt_create xprt_args = { + .ident = XPRT_TRANSPORT_TCP, + .net = clp->cl_net, + .dstaddr = (struct sockaddr *)&da->da_addr, + .addrlen = da->da_addrlen, + .servername = clp->cl_hostname, + }; + /* Add this address as an alias */ + rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, + rpc_clnt_test_and_add_xprt, NULL); + } else + clp = get_v3_ds_connect(mds_srv->nfs_client, (struct sockaddr *)&da->da_addr, da->da_addrlen, IPPROTO_TCP, timeo, retrans, au_flavor); - if (!IS_ERR(clp)) - break; } if (IS_ERR(clp)) { -- GitLab From 02a95dee8cf03a73982f9cabf549c04ae354bed7 Mon Sep 17 00:00:00 2001 From: Andy Adamson Date: Fri, 5 Feb 2016 16:08:37 -0500 Subject: [PATCH 0732/5324] NFS add callback_ops to nfs4_proc_bind_conn_to_session_callback Fix oops when NULL callback_ops pointer accessed in rpc_init_task Signed-off-by: Andy Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 36471e013a73..dbc3dc2f65cd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6782,6 +6782,15 @@ nfs41_same_server_scope(struct nfs41_server_scope *a, return false; } +static void +nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) +{ +} + +static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { + .rpc_call_done = &nfs4_bind_one_conn_to_session_done, +}; + /* * nfs4_proc_bind_one_conn_to_session() * @@ -6810,6 +6819,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt, struct rpc_task_setup task_setup_data = { .rpc_client = clnt, .rpc_xprt = xprt, + .callback_ops = &nfs4_bind_one_conn_to_session_ops, .rpc_message = &msg, .flags = RPC_TASK_TIMEOUT, }; -- GitLab From 14b04f28a0a1a5903221fc55c61d231b76abd440 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 2 Feb 2016 17:09:26 -0800 Subject: [PATCH 0733/5324] clk: gpio: Make into a platform driver clk_get() for DT based clks already returns EPROBE_DEFER when the OF clk provider is not present. So having all this code in the clk provider to return EPROBE_DEFER when the gpio isn't ready yet can be replaced with a platform driver that doesn't add the clk provider until the gpio can be requested. Get rid of the OF_CLK_DECLARE and convert this to a platform driver instead. Tested-by: Jyri Sarha Cc: Sergej Sawazki Cc: Russell King Cc: Fabio Estevam Cc: Jon Nettleton Cc: Shawn Guo Signed-off-by: Stephen Boyd --- drivers/clk/clk-gpio.c | 165 +++++++++++++---------------------------- 1 file changed, 52 insertions(+), 113 deletions(-) diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index cbbea2985cc9..fb32a7366ef6 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /** * DOC: basic gpio gated clock which can be enabled and disabled @@ -199,134 +201,71 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_gpio_mux); -#ifdef CONFIG_OF -/** - * clk_register_get() has to be delayed, because -EPROBE_DEFER - * can not be handled properly at of_clk_init() call time. - */ - -struct clk_gpio_delayed_register_data { - const char *gpio_name; - int num_parents; - const char **parent_names; - struct device_node *node; - struct mutex lock; - struct clk *clk; - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low); -}; - -static struct clk *of_clk_gpio_delayed_register_get( - struct of_phandle_args *clkspec, void *_data) +static int gpio_clk_driver_probe(struct platform_device *pdev) { - struct clk_gpio_delayed_register_data *data = _data; - struct clk *clk; - int gpio; + struct device_node *node = pdev->dev.of_node; + const char **parent_names, *gpio_name; + int num_parents, gpio; enum of_gpio_flags of_flags; + struct clk *clk; + bool active_low, is_mux; + + num_parents = of_clk_get_parent_count(node); + if (num_parents < 0) + return -EINVAL; - mutex_lock(&data->lock); + if (num_parents) { + parent_names = devm_kcalloc(&pdev->dev, num_parents, + sizeof(char *), GFP_KERNEL); + if (!parent_names) + return -ENOMEM; - if (data->clk) { - mutex_unlock(&data->lock); - return data->clk; + of_clk_parent_fill(node, parent_names, num_parents); + } else { + parent_names = NULL; } - gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0, - &of_flags); + is_mux = of_device_is_compatible(node, "gpio-mux-clock"); + + gpio_name = is_mux ? "select-gpios" : "enable-gpios"; + gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags); if (gpio < 0) { - mutex_unlock(&data->lock); if (gpio == -EPROBE_DEFER) pr_debug("%s: %s: GPIOs not yet available, retry later\n", - data->node->name, __func__); + node->name, __func__); else pr_err("%s: %s: Can't get '%s' DT property\n", - data->node->name, __func__, - data->gpio_name); - return ERR_PTR(gpio); + node->name, __func__, + gpio_name); + return gpio; } - clk = data->clk_register_get(data->node->name, data->parent_names, - data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); - if (IS_ERR(clk)) - goto out; - - data->clk = clk; -out: - mutex_unlock(&data->lock); - - return clk; -} - -static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low) -{ - return clk_register_gpio_gate(NULL, name, parent_names ? - parent_names[0] : NULL, gpio, active_low, 0); -} - -static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, unsigned gpio, - bool active_low) -{ - return clk_register_gpio_mux(NULL, name, parent_names, num_parents, - gpio, active_low, 0); -} - -static void __init of_gpio_clk_setup(struct device_node *node, - const char *gpio_name, - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, - u8 num_parents, - unsigned gpio, bool active_low)) -{ - struct clk_gpio_delayed_register_data *data; - const char **parent_names; - int i, num_parents; - - num_parents = of_clk_get_parent_count(node); - if (num_parents < 0) - return; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return; + active_low = of_flags & OF_GPIO_ACTIVE_LOW; - if (num_parents) { - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) { - kfree(data); - return; - } - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(node, i); - } else { - parent_names = NULL; - } - - data->num_parents = num_parents; - data->parent_names = parent_names; - data->node = node; - data->gpio_name = gpio_name; - data->clk_register_get = clk_register_get; - mutex_init(&data->lock); + if (is_mux) + clk = clk_register_gpio_mux(&pdev->dev, node->name, + parent_names, num_parents, gpio, active_low, 0); + else + clk = clk_register_gpio_gate(&pdev->dev, node->name, + parent_names ? parent_names[0] : NULL, gpio, + active_low, 0); + if (IS_ERR(clk)) + return PTR_ERR(clk); - of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data); + return of_clk_add_provider(node, of_clk_src_simple_get, clk); } -static void __init of_gpio_gate_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "enable-gpios", - of_clk_gpio_gate_delayed_register_get); -} -CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); +static const struct of_device_id gpio_clk_match_table[] = { + { .compatible = "gpio-mux-clock" }, + { .compatible = "gpio-gate-clock" }, + { } +}; -void __init of_gpio_mux_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "select-gpios", - of_clk_gpio_mux_delayed_register_get); -} -CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup); -#endif +static struct platform_driver gpio_clk_driver = { + .probe = gpio_clk_driver_probe, + .driver = { + .name = "gpio-clk", + .of_match_table = gpio_clk_match_table, + }, +}; +builtin_platform_driver(gpio_clk_driver); -- GitLab From 47b0eeb3dc8a01848ad62908000b1051d1833eaf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 2 Feb 2016 17:24:56 -0800 Subject: [PATCH 0734/5324] clk: Deprecate CLK_IS_ROOT We don't use CLK_IS_ROOT but in a few places in the common clk framework core. Let's replace those checks with a check for the number of parents a clk has instead of the flag, freeing up one flag for something else. We don't remove the flag yet so that things keep building, but we'll remove it once all drivers have removed their flag usage. Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 6 +++--- include/linux/clk-provider.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index bb01ed6cc63e..cd8382c83f48 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -385,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core) ret = core->rate; - if (core->flags & CLK_IS_ROOT) + if (!core->num_parents) goto out; if (!core->parent) @@ -2351,7 +2351,7 @@ static int __clk_core_init(struct clk_core *core) /* * Populate core->parent if parent has already been __clk_init'd. If * parent has not yet been __clk_init'd then place clk in the orphan - * list. If clk has set the CLK_IS_ROOT flag then place it in the root + * list. If clk doesn't have any parents then place it in the root * clk list. * * Every time a new clk is clk_init'd then we walk the list of orphan @@ -2362,7 +2362,7 @@ static int __clk_core_init(struct clk_core *core) hlist_add_head(&core->child_node, &core->parent->children); core->orphan = core->parent->orphan; - } else if (core->flags & CLK_IS_ROOT) { + } else if (!core->num_parents) { hlist_add_head(&core->child_node, &clk_root_list); core->orphan = false; } else { diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index fabe5bedbba6..9c3a18c1a984 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -25,7 +25,7 @@ #define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ #define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ #define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ -#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ +#define CLK_IS_ROOT BIT(4) /* Deprecated: Don't use */ #define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ -- GitLab From 1e42754eacdb1c8632c3af47263c56967e04cbd1 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 6 Feb 2016 23:34:55 -0800 Subject: [PATCH 0735/5324] clk: provider: Remove of_gpio_{gate,mux}_clk_setup() prototypes These functions either never existed or were only used in OF_CLK_DECLARE() macros. Remove the dead prototypes. Cc: Jyri Sarha Signed-off-by: Stephen Boyd --- include/linux/clk-provider.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 9c3a18c1a984..fce7f027f8a7 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -626,8 +626,6 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name, const char *parent_name, unsigned gpio, bool active_low, unsigned long flags); -void of_gpio_clk_gate_setup(struct device_node *node); - /** * struct clk_gpio_mux - gpio controlled clock multiplexer * @@ -643,8 +641,6 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, unsigned gpio, bool active_low, unsigned long flags); -void of_gpio_mux_clk_setup(struct device_node *node); - /** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock -- GitLab From 66ad0dd30285e14529566a2f816a0d463f63cf81 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:52 -0600 Subject: [PATCH 0736/5324] alienware-wmi: Clean up whitespace for ASM100 platform This brings them more in line with the usage of whitespace in other platforms. Signed-off-by: Mario Limonciello Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index 1e1e59423889..a8750ed720b8 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -105,14 +105,14 @@ static const struct dmi_system_id alienware_quirks[] __initconst = { .driver_data = &quirk_x51_family, }, { - .callback = dmi_matched, - .ident = "Alienware ASM100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"), - }, - .driver_data = &quirk_asm100, - }, + .callback = dmi_matched, + .ident = "Alienware ASM100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), + DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"), + }, + .driver_data = &quirk_asm100, + }, {} }; -- GitLab From 9e503a9d0c18b277f902570a3dfd74a7c86ec9a7 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:53 -0600 Subject: [PATCH 0737/5324] alienware-wmi: Add support for new platform: X51-R3 The X51-R3 is in the X51 family. It includes 3 internal lighting zones as well as is the first AW desktop that includes support for a graphics amplifier. Signed-off-by: Mario Limonciello Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index a8750ed720b8..8e8ea4f2d59f 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -69,11 +69,16 @@ static struct quirk_entry quirk_unknown = { .hdmi_mux = 0, }; -static struct quirk_entry quirk_x51_family = { +static struct quirk_entry quirk_x51_r1_r2 = { .num_zones = 3, .hdmi_mux = 0. }; +static struct quirk_entry quirk_x51_r3 = { + .num_zones = 4, + .hdmi_mux = 0, +}; + static struct quirk_entry quirk_asm100 = { .num_zones = 2, .hdmi_mux = 1, @@ -88,12 +93,12 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) static const struct dmi_system_id alienware_quirks[] __initconst = { { .callback = dmi_matched, - .ident = "Alienware X51 R1", + .ident = "Alienware X51 R3", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), - DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"), }, - .driver_data = &quirk_x51_family, + .driver_data = &quirk_x51_r3, }, { .callback = dmi_matched, @@ -102,7 +107,16 @@ static const struct dmi_system_id alienware_quirks[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"), }, - .driver_data = &quirk_x51_family, + .driver_data = &quirk_x51_r1_r2, + }, + { + .callback = dmi_matched, + .ident = "Alienware X51 R1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"), + }, + .driver_data = &quirk_x51_r1_r2, }, { .callback = dmi_matched, -- GitLab From cbbb50d6038bc093154fb6e209729bbf8bebd614 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:54 -0600 Subject: [PATCH 0738/5324] alienware-wmi: Add initial support for alienware graphics amplifier. The alienware graphics amplifier is a device that provides external access to a full PCIe slot, USB hub, and additional control zone. This patch enables support for reading status whether the cable is plugged in as well as for setting the colors in the new zone on the amplifier. Signed-off-by: Mario Limonciello [dvhart: minor comment formatting fixes] Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 107 ++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 19 deletions(-) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index 8e8ea4f2d59f..fa86b7d5d6b5 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -33,6 +33,7 @@ #define WMAX_METHOD_BRIGHTNESS 0x3 #define WMAX_METHOD_ZONE_CONTROL 0x4 #define WMAX_METHOD_HDMI_CABLE 0x5 +#define WMAX_METHOD_AMPLIFIER_CABLE 0x6 MODULE_AUTHOR("Mario Limonciello "); MODULE_DESCRIPTION("Alienware special feature control"); @@ -60,6 +61,7 @@ enum WMAX_CONTROL_STATES { struct quirk_entry { u8 num_zones; u8 hdmi_mux; + u8 amplifier; }; static struct quirk_entry *quirks; @@ -67,21 +69,25 @@ static struct quirk_entry *quirks; static struct quirk_entry quirk_unknown = { .num_zones = 2, .hdmi_mux = 0, + .amplifier = 0, }; static struct quirk_entry quirk_x51_r1_r2 = { .num_zones = 3, - .hdmi_mux = 0. + .hdmi_mux = 0, + .amplifier = 0, }; static struct quirk_entry quirk_x51_r3 = { .num_zones = 4, .hdmi_mux = 0, + .amplifier = 1, }; static struct quirk_entry quirk_asm100 = { .num_zones = 2, .hdmi_mux = 1, + .amplifier = 0, }; static int __init dmi_matched(const struct dmi_system_id *dmi) @@ -147,7 +153,7 @@ struct wmax_brightness_args { u32 percentage; }; -struct hdmi_args { +struct wmax_basic_args { u8 arg; }; @@ -232,16 +238,16 @@ static int alienware_update_led(struct platform_zone *zone) char *guid; struct acpi_buffer input; struct legacy_led_args legacy_args; - struct wmax_led_args wmax_args; + struct wmax_led_args wmax_basic_args; if (interface == WMAX) { - wmax_args.led_mask = 1 << zone->location; - wmax_args.colors = zone->colors; - wmax_args.state = lighting_control_state; + wmax_basic_args.led_mask = 1 << zone->location; + wmax_basic_args.colors = zone->colors; + wmax_basic_args.state = lighting_control_state; guid = WMAX_CONTROL_GUID; method_id = WMAX_METHOD_ZONE_CONTROL; - input.length = (acpi_size) sizeof(wmax_args); - input.pointer = &wmax_args; + input.length = (acpi_size) sizeof(wmax_basic_args); + input.pointer = &wmax_basic_args; } else { legacy_args.colors = zone->colors; legacy_args.brightness = global_brightness; @@ -449,11 +455,7 @@ static void alienware_zone_exit(struct platform_device *dev) kfree(zone_attrs); } -/* - The HDMI mux sysfs node indicates the status of the HDMI input mux. - It can toggle between standard system GPU output and HDMI input. -*/ -static acpi_status alienware_hdmi_command(struct hdmi_args *in_args, +static acpi_status alienware_wmax_command(struct wmax_basic_args *in_args, u32 command, int *out_data) { acpi_status status; @@ -481,16 +483,20 @@ static acpi_status alienware_hdmi_command(struct hdmi_args *in_args, } +/* + * The HDMI mux sysfs node indicates the status of the HDMI input mux. + * It can toggle between standard system GPU output and HDMI input. + */ static ssize_t show_hdmi_cable(struct device *dev, struct device_attribute *attr, char *buf) { acpi_status status; u32 out_data; - struct hdmi_args in_args = { + struct wmax_basic_args in_args = { .arg = 0, }; status = - alienware_hdmi_command(&in_args, WMAX_METHOD_HDMI_CABLE, + alienware_wmax_command(&in_args, WMAX_METHOD_HDMI_CABLE, (u32 *) &out_data); if (ACPI_SUCCESS(status)) { if (out_data == 0) @@ -509,11 +515,11 @@ static ssize_t show_hdmi_source(struct device *dev, { acpi_status status; u32 out_data; - struct hdmi_args in_args = { + struct wmax_basic_args in_args = { .arg = 0, }; status = - alienware_hdmi_command(&in_args, WMAX_METHOD_HDMI_STATUS, + alienware_wmax_command(&in_args, WMAX_METHOD_HDMI_STATUS, (u32 *) &out_data); if (ACPI_SUCCESS(status)) { @@ -533,7 +539,7 @@ static ssize_t toggle_hdmi_source(struct device *dev, const char *buf, size_t count) { acpi_status status; - struct hdmi_args args; + struct wmax_basic_args args; if (strcmp(buf, "gpu\n") == 0) args.arg = 1; else if (strcmp(buf, "input\n") == 0) @@ -542,7 +548,7 @@ static ssize_t toggle_hdmi_source(struct device *dev, args.arg = 3; pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf); - status = alienware_hdmi_command(&args, WMAX_METHOD_HDMI_SOURCE, NULL); + status = alienware_wmax_command(&args, WMAX_METHOD_HDMI_SOURCE, NULL); if (ACPI_FAILURE(status)) pr_err("alienware-wmi: HDMI toggle failed: results: %u\n", @@ -585,6 +591,62 @@ static int create_hdmi(struct platform_device *dev) return ret; } +/* + * Alienware GFX amplifier support + * - Currently supports reading cable status + * - Leaving expansion room to possibly support dock/undock events later + */ +static ssize_t show_amplifier_status(struct device *dev, + struct device_attribute *attr, char *buf) +{ + acpi_status status; + u32 out_data; + struct wmax_basic_args in_args = { + .arg = 0, + }; + status = + alienware_wmax_command(&in_args, WMAX_METHOD_AMPLIFIER_CABLE, + (u32 *) &out_data); + if (ACPI_SUCCESS(status)) { + if (out_data == 0) + return scnprintf(buf, PAGE_SIZE, + "[unconnected] connected unknown\n"); + else if (out_data == 1) + return scnprintf(buf, PAGE_SIZE, + "unconnected [connected] unknown\n"); + } + pr_err("alienware-wmi: unknown amplifier cable status: %d\n", status); + return scnprintf(buf, PAGE_SIZE, "unconnected connected [unknown]\n"); +} + +static DEVICE_ATTR(status, S_IRUGO, show_amplifier_status, NULL); + +static struct attribute *amplifier_attrs[] = { + &dev_attr_status.attr, + NULL, +}; + +static struct attribute_group amplifier_attribute_group = { + .name = "amplifier", + .attrs = amplifier_attrs, +}; + +static void remove_amplifier(struct platform_device *dev) +{ + if (quirks->amplifier > 0) + sysfs_remove_group(&dev->dev.kobj, &lifier_attribute_group); +} + +static int create_amplifier(struct platform_device *dev) +{ + int ret; + + ret = sysfs_create_group(&dev->dev.kobj, &lifier_attribute_group); + if (ret) + remove_amplifier(dev); + return ret; +} + static int __init alienware_wmi_init(void) { int ret; @@ -620,6 +682,12 @@ static int __init alienware_wmi_init(void) goto fail_prep_hdmi; } + if (quirks->amplifier > 0) { + ret = create_amplifier(platform_device); + if (ret) + goto fail_prep_amplifier; + } + ret = alienware_zone_init(platform_device); if (ret) goto fail_prep_zones; @@ -628,6 +696,7 @@ static int __init alienware_wmi_init(void) fail_prep_zones: alienware_zone_exit(platform_device); +fail_prep_amplifier: fail_prep_hdmi: platform_device_del(platform_device); fail_platform_device2: -- GitLab From 8ea81ec67b82fd35e389c3eef395206bac8e2259 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:55 -0600 Subject: [PATCH 0739/5324] alienware-wmi: Add support for deep sleep control. Allow for user configuration of BIOS settings that allow the system to be turned on via HID devices. The feature requires hardware architectural modifications and can not be supported on existing systems. Signed-off-by: Mario Limonciello [dvhart: comment formatting and line length fixes] Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index fa86b7d5d6b5..a9f8d3044cd3 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -34,6 +34,8 @@ #define WMAX_METHOD_ZONE_CONTROL 0x4 #define WMAX_METHOD_HDMI_CABLE 0x5 #define WMAX_METHOD_AMPLIFIER_CABLE 0x6 +#define WMAX_METHOD_DEEP_SLEEP_CONTROL 0x0B +#define WMAX_METHOD_DEEP_SLEEP_STATUS 0x0C MODULE_AUTHOR("Mario Limonciello "); MODULE_DESCRIPTION("Alienware special feature control"); @@ -62,6 +64,7 @@ struct quirk_entry { u8 num_zones; u8 hdmi_mux; u8 amplifier; + u8 deepslp; }; static struct quirk_entry *quirks; @@ -70,24 +73,28 @@ static struct quirk_entry quirk_unknown = { .num_zones = 2, .hdmi_mux = 0, .amplifier = 0, + .deepslp = 0, }; static struct quirk_entry quirk_x51_r1_r2 = { .num_zones = 3, .hdmi_mux = 0, .amplifier = 0, + .deepslp = 0, }; static struct quirk_entry quirk_x51_r3 = { .num_zones = 4, .hdmi_mux = 0, .amplifier = 1, + .deepslp = 0, }; static struct quirk_entry quirk_asm100 = { .num_zones = 2, .hdmi_mux = 1, .amplifier = 0, + .deepslp = 0, }; static int __init dmi_matched(const struct dmi_system_id *dmi) @@ -647,6 +654,87 @@ static int create_amplifier(struct platform_device *dev) return ret; } +/* + * Deep Sleep Control support + * - Modifies BIOS setting for deep sleep control allowing extra wakeup events + */ +static ssize_t show_deepsleep_status(struct device *dev, + struct device_attribute *attr, char *buf) +{ + acpi_status status; + u32 out_data; + struct wmax_basic_args in_args = { + .arg = 0, + }; + status = alienware_wmax_command(&in_args, WMAX_METHOD_DEEP_SLEEP_STATUS, + (u32 *) &out_data); + if (ACPI_SUCCESS(status)) { + if (out_data == 0) + return scnprintf(buf, PAGE_SIZE, + "[disabled] s5 s5_s4\n"); + else if (out_data == 1) + return scnprintf(buf, PAGE_SIZE, + "disabled [s5] s5_s4\n"); + else if (out_data == 2) + return scnprintf(buf, PAGE_SIZE, + "disabled s5 [s5_s4]\n"); + } + pr_err("alienware-wmi: unknown deep sleep status: %d\n", status); + return scnprintf(buf, PAGE_SIZE, "disabled s5 s5_s4 [unknown]\n"); +} + +static ssize_t toggle_deepsleep(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + acpi_status status; + struct wmax_basic_args args; + + if (strcmp(buf, "disabled\n") == 0) + args.arg = 0; + else if (strcmp(buf, "s5\n") == 0) + args.arg = 1; + else + args.arg = 2; + pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf); + + status = alienware_wmax_command(&args, WMAX_METHOD_DEEP_SLEEP_CONTROL, + NULL); + + if (ACPI_FAILURE(status)) + pr_err("alienware-wmi: deep sleep control failed: results: %u\n", + status); + return count; +} + +static DEVICE_ATTR(deepsleep, S_IRUGO | S_IWUSR, show_deepsleep_status, toggle_deepsleep); + +static struct attribute *deepsleep_attrs[] = { + &dev_attr_deepsleep.attr, + NULL, +}; + +static struct attribute_group deepsleep_attribute_group = { + .name = "deepsleep", + .attrs = deepsleep_attrs, +}; + +static void remove_deepsleep(struct platform_device *dev) +{ + if (quirks->deepslp > 0) + sysfs_remove_group(&dev->dev.kobj, &deepsleep_attribute_group); +} + +static int create_deepsleep(struct platform_device *dev) +{ + int ret; + + ret = sysfs_create_group(&dev->dev.kobj, &deepsleep_attribute_group); + if (ret) + remove_deepsleep(dev); + return ret; +} + static int __init alienware_wmi_init(void) { int ret; @@ -688,6 +776,12 @@ static int __init alienware_wmi_init(void) goto fail_prep_amplifier; } + if (quirks->deepslp > 0) { + ret = create_deepsleep(platform_device); + if (ret) + goto fail_prep_deepsleep; + } + ret = alienware_zone_init(platform_device); if (ret) goto fail_prep_zones; @@ -696,6 +790,7 @@ static int __init alienware_wmi_init(void) fail_prep_zones: alienware_zone_exit(platform_device); +fail_prep_deepsleep: fail_prep_amplifier: fail_prep_hdmi: platform_device_del(platform_device); -- GitLab From b332f82e3868bc191914adfb1caadcc77c076df2 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:56 -0600 Subject: [PATCH 0740/5324] alienware-wmi: Add support for two new systems: ASM200 and ASM201. Both of these systems support: * 2 lighting control zones * HDMI mux control * deep sleep control (to enable wakup from controller) The ASM201 also supports the external graphics amplifier. Signed-off-by: Mario Limonciello Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index a9f8d3044cd3..275a56d47e56 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -97,6 +97,20 @@ static struct quirk_entry quirk_asm100 = { .deepslp = 0, }; +static struct quirk_entry quirk_asm200 = { + .num_zones = 2, + .hdmi_mux = 1, + .amplifier = 0, + .deepslp = 1, +}; + +static struct quirk_entry quirk_asm201 = { + .num_zones = 2, + .hdmi_mux = 1, + .amplifier = 1, + .deepslp = 1, +}; + static int __init dmi_matched(const struct dmi_system_id *dmi) { quirks = dmi->driver_data; @@ -140,6 +154,24 @@ static const struct dmi_system_id alienware_quirks[] __initconst = { }, .driver_data = &quirk_asm100, }, + { + .callback = dmi_matched, + .ident = "Alienware ASM200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), + DMI_MATCH(DMI_PRODUCT_NAME, "ASM200"), + }, + .driver_data = &quirk_asm200, + }, + { + .callback = dmi_matched, + .ident = "Alienware ASM201", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), + DMI_MATCH(DMI_PRODUCT_NAME, "ASM201"), + }, + .driver_data = &quirk_asm201, + }, {} }; -- GitLab From ec5eeadc44bf05a8619627d6882fdf5775c19396 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 2 Feb 2016 15:38:57 -0600 Subject: [PATCH 0741/5324] alienware-wmi: whitespace improvements These were some items that were pointed out in previous patches that weren't caught be previous reviewers, but should be applied to other parts of the driver as well. Signed-off-by: Mario Limonciello [dvhart: reverted a couple incorrect line wrapping changes] Signed-off-by: Darren Hart --- drivers/platform/x86/alienware-wmi.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c index 275a56d47e56..005629447b0c 100644 --- a/drivers/platform/x86/alienware-wmi.c +++ b/drivers/platform/x86/alienware-wmi.c @@ -229,7 +229,7 @@ static u8 global_brightness; /* * Helpers used for zone control -*/ + */ static int parse_rgb(const char *buf, struct platform_zone *zone) { long unsigned int rgb; @@ -269,7 +269,7 @@ static struct platform_zone *match_zone(struct device_attribute *attr) /* * Individual RGB zone control -*/ + */ static int alienware_update_led(struct platform_zone *zone) { int method_id; @@ -342,7 +342,7 @@ static ssize_t zone_set(struct device *dev, struct device_attribute *attr, /* * LED Brightness (Global) -*/ + */ static int wmax_brightness(int brightness) { acpi_status status; @@ -386,7 +386,7 @@ static struct led_classdev global_led = { /* * Lighting control state device attribute (Global) -*/ + */ static ssize_t show_control_state(struct device *dev, struct device_attribute *attr, char *buf) { @@ -622,11 +622,7 @@ static int create_hdmi(struct platform_device *dev) ret = sysfs_create_group(&dev->dev.kobj, &hdmi_attribute_group); if (ret) - goto error_create_hdmi; - return 0; - -error_create_hdmi: - remove_hdmi(dev); + remove_hdmi(dev); return ret; } -- GitLab From 4b680afb42b9e1b504444583098401a00e63ed3c Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 8 Feb 2016 10:46:51 +1100 Subject: [PATCH 0742/5324] xfs: lock rt summary inode on allocation RT allocation can fail on a debug kernel with: XFS: Assertion failed: xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL), file: fs/xfs/libxfs/xfs_bmap.c, line: 4039 When modifying the summary inode during allocation. This occurs because the summary inode is never locked, and xfs_bmapi_* operations expect it to be locked. The summary inode is effectively protected byt he lock on the bitmap inode, so this really is only a debug kernel issue. Signed-off-by: Dave Chinner Tested-by: Ross Zwisler Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 45ec9e40150c..07ef29b9b464 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -202,10 +202,12 @@ xfs_bmap_rtalloc( ralen = MAXEXTLEN / mp->m_sb.sb_rextsize; /* - * Lock out other modifications to the RT bitmap inode. + * Lock out modifications to both the RT bitmap and summary inodes */ xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL); xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL); + xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL); /* * If it's an allocation to an empty file at offset 0, -- GitLab From 3218a3ec87f7d0063b48b10cf3d649ce75966223 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:21:24 +1100 Subject: [PATCH 0743/5324] quota: remove unused cmd argument from quota_quotaon() The cmd argument to quota_quotaon() via Q_QUOTAON quotactl is not used, so remove it. Signed-off-by: Eric Sandeen Reviewed-by: Jan Kara Signed-off-by: Dave Chinner --- fs/quota/quota.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 3746367098fd..ea6667083b3e 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -79,7 +79,7 @@ unsigned int qtype_enforce_flag(int type) return 0; } -static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, +static int quota_quotaon(struct super_block *sb, int type, qid_t id, struct path *path) { if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_enable) @@ -659,7 +659,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, switch (cmd) { case Q_QUOTAON: - return quota_quotaon(sb, type, cmd, id, path); + return quota_quotaon(sb, type, id, path); case Q_QUOTAOFF: return quota_quotaoff(sb, type); case Q_GETFMT: -- GitLab From 8b37524962b9c54423374717786198f5c0820a28 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:21:50 +1100 Subject: [PATCH 0744/5324] quota: add new quotactl Q_XGETNEXTQUOTA Q_XGETNEXTQUOTA is exactly like Q_XGETQUOTA, except that it will return quota information for the id equal to or greater than the id requested. In other words, if the requested id has no quota, the command will return quota information for the next higher id which does have a quota set. If no higher id has an active quota, -ESRCH is returned. This allows filesystems to do efficient iteration in kernelspace, much like extN filesystems do in userspace when asked to report all active quotas. The patch adds a d_id field to struct qc_dqblk so that we can pass back the id of the quota which was found, and return it to userspace. Today, filesystems such as XFS require getpwent-style iterations, and for systems which have i.e. LDAP backends, this can be very slow, or even impossible if iteration is not allowed in the configuration. Signed-off-by: Eric Sandeen Reviewed-by: Jan Kara Signed-off-by: Dave Chinner --- fs/quota/quota.c | 31 +++++++++++++++++++++++++++++++ include/linux/quota.h | 2 ++ include/uapi/linux/dqblk_xfs.h | 1 + 3 files changed, 34 insertions(+) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index ea6667083b3e..0a6dd71ea309 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -625,6 +625,34 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id, return ret; } +/* + * Return quota for next active quota >= this id, if any exists, + * otherwise return -ESRCH via ->get_nextdqblk. + */ +static int quota_getnextxquota(struct super_block *sb, int type, qid_t id, + void __user *addr) +{ + struct fs_disk_quota fdq; + struct qc_dqblk qdq; + struct kqid qid; + qid_t id_out; + int ret; + + if (!sb->s_qcop->get_nextdqblk) + return -ENOSYS; + qid = make_kqid(current_user_ns(), type, id); + if (!qid_valid(qid)) + return -EINVAL; + ret = sb->s_qcop->get_nextdqblk(sb, &qid, &qdq); + if (ret) + return ret; + id_out = from_kqid(current_user_ns(), qid); + copy_to_xfs_dqblk(&fdq, &qdq, type, id_out); + if (copy_to_user(addr, &fdq, sizeof(fdq))) + return -EFAULT; + return ret; +} + static int quota_rmxquota(struct super_block *sb, void __user *addr) { __u32 flags; @@ -690,6 +718,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, return quota_setxquota(sb, type, id, addr); case Q_XGETQUOTA: return quota_getxquota(sb, type, id, addr); + case Q_XGETNEXTQUOTA: + return quota_getnextxquota(sb, type, id, addr); case Q_XQUOTASYNC: if (sb->s_flags & MS_RDONLY) return -EROFS; @@ -712,6 +742,7 @@ static int quotactl_cmd_write(int cmd) case Q_XGETQSTAT: case Q_XGETQSTATV: case Q_XGETQUOTA: + case Q_XGETNEXTQUOTA: case Q_XQUOTASYNC: return 0; } diff --git a/include/linux/quota.h b/include/linux/quota.h index b2505acfd3c0..fba92f5c1a63 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -425,6 +425,8 @@ struct quotactl_ops { int (*quota_sync)(struct super_block *, int); int (*set_info)(struct super_block *, int, struct qc_info *); int (*get_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); + int (*get_nextdqblk)(struct super_block *, struct kqid *, + struct qc_dqblk *); int (*set_dqblk)(struct super_block *, struct kqid, struct qc_dqblk *); int (*get_state)(struct super_block *, struct qc_state *); int (*rm_xquota)(struct super_block *, unsigned int); diff --git a/include/uapi/linux/dqblk_xfs.h b/include/uapi/linux/dqblk_xfs.h index dcd75cc26196..11b3b31faf14 100644 --- a/include/uapi/linux/dqblk_xfs.h +++ b/include/uapi/linux/dqblk_xfs.h @@ -39,6 +39,7 @@ #define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */ #define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */ #define Q_XGETQSTATV XQM_CMD(8) /* newer version of get quota */ +#define Q_XGETNEXTQUOTA XQM_CMD(9) /* get disk limits and usage >= ID */ /* * fs_disk_quota structure: -- GitLab From 926132c0257a5a8d149a6a395cc3405e55420566 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:22:21 +1100 Subject: [PATCH 0745/5324] quota: add new quotactl Q_GETNEXTQUOTA Q_GETNEXTQUOTA is exactly like Q_GETQUOTA, except that it will return quota information for the id equal to or greater than the id requested. In other words, if the requested id has no quota, the command will return quota information for the next higher id which does have a quota set. If no higher id has an active quota, -ESRCH is returned. This allows filesystems to do efficient iteration in kernelspace, much like extN filesystems do in userspace when asked to report all active quotas. This does require a new data structure for userspace, as the current structure does not include an ID for the returned quota information. Today, Ext4 with a hidden quota inode requires getpwent-style iterations, and for systems which have i.e. LDAP backends, this can be very slow, or even impossible if iteration is not allowed in the configuration. Signed-off-by: Eric Sandeen Reviewed-by: Jan Kara Signed-off-by: Dave Chinner --- fs/quota/quota.c | 31 +++++++++++++++++++++++++++++++ include/uapi/linux/quota.h | 14 ++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 0a6dd71ea309..0ebc90496525 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -222,6 +222,34 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, return 0; } +/* + * Return quota for next active quota >= this id, if any exists, + * otherwise return -ESRCH via ->get_nextdqblk + */ +static int quota_getnextquota(struct super_block *sb, int type, qid_t id, + void __user *addr) +{ + struct kqid qid; + struct qc_dqblk fdq; + struct if_nextdqblk idq; + int ret; + + if (!sb->s_qcop->get_nextdqblk) + return -ENOSYS; + qid = make_kqid(current_user_ns(), type, id); + if (!qid_valid(qid)) + return -EINVAL; + ret = sb->s_qcop->get_nextdqblk(sb, &qid, &fdq); + if (ret) + return ret; + /* struct if_nextdqblk is a superset of struct if_dqblk */ + copy_to_if_dqblk((struct if_dqblk *)&idq, &fdq); + idq.dqb_id = from_kqid(current_user_ns(), qid); + if (copy_to_user(addr, &idq, sizeof(idq))) + return -EFAULT; + return 0; +} + static void copy_from_if_dqblk(struct qc_dqblk *dst, struct if_dqblk *src) { dst->d_spc_hardlimit = qbtos(src->dqb_bhardlimit); @@ -698,6 +726,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, return quota_setinfo(sb, type, addr); case Q_GETQUOTA: return quota_getquota(sb, type, id, addr); + case Q_GETNEXTQUOTA: + return quota_getnextquota(sb, type, id, addr); case Q_SETQUOTA: return quota_setquota(sb, type, id, addr); case Q_SYNC: @@ -738,6 +768,7 @@ static int quotactl_cmd_write(int cmd) switch (cmd) { case Q_GETFMT: case Q_GETINFO: + case Q_GETNEXTQUOTA: case Q_SYNC: case Q_XGETQSTAT: case Q_XGETQSTATV: diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h index 9c95b2c1c88a..38baddb807f5 100644 --- a/include/uapi/linux/quota.h +++ b/include/uapi/linux/quota.h @@ -71,6 +71,7 @@ #define Q_SETINFO 0x800006 /* set information about quota files */ #define Q_GETQUOTA 0x800007 /* get user quota structure */ #define Q_SETQUOTA 0x800008 /* set user quota structure */ +#define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */ /* Quota format type IDs */ #define QFMT_VFS_OLD 1 @@ -119,6 +120,19 @@ struct if_dqblk { __u32 dqb_valid; }; +struct if_nextdqblk { + __u64 dqb_bhardlimit; + __u64 dqb_bsoftlimit; + __u64 dqb_curspace; + __u64 dqb_ihardlimit; + __u64 dqb_isoftlimit; + __u64 dqb_curinodes; + __u64 dqb_btime; + __u64 dqb_itime; + __u32 dqb_valid; + __u32 dqb_id; +}; + /* * Structure used for setting quota information about file via quotactl * Following flags are used to specify which fields are valid -- GitLab From a484bcdd1321b86de29a2969399da1fa6e9c7648 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:22:58 +1100 Subject: [PATCH 0746/5324] xfs: don't overflow quota ID when initializing dqblk Quota IDs are unsigned, and so we can pass in values up to 2^32-1. But if we try to initialize a block containing values over MAX_INT, curid will overflow and assert. curid holds a quota ID, so give it the proper xfs_dqid_t type (and remove the now-impossible ASSERT). Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_dquot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 9c44d38dcd1f..c9c7c2d89245 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -232,7 +232,8 @@ xfs_qm_init_dquot_blk( { struct xfs_quotainfo *q = mp->m_quotainfo; xfs_dqblk_t *d; - int curid, i; + xfs_dqid_t curid; + int i; ASSERT(tp); ASSERT(xfs_buf_islocked(bp)); @@ -243,7 +244,6 @@ xfs_qm_init_dquot_blk( * ID of the first dquot in the block - id's are zero based. */ curid = id - (id % q->qi_dqperchunk); - ASSERT(curid >= 0); memset(d, 0, BBTOB(q->qi_dqchunklen)); for (i = 0; i < q->qi_dqperchunk; i++, d++, curid++) { d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); -- GitLab From 4d4d9523b4ebbd5d97c8b2557c6ee2a3f90b6b3a Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:23:23 +1100 Subject: [PATCH 0747/5324] xfs: get quota inode from mp & flags rather than dqp Allow us to get the appropriate quota inode from any mp & quota flags, not necessarily associated with a particular dqp. Needed for when we are searching for the next active ID with quotas and we want to examine the quota inode. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_dquot.c | 3 ++- fs/xfs/xfs_qm.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index c9c7c2d89245..5dbde0d65f37 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -464,12 +464,13 @@ xfs_qm_dqtobp( struct xfs_bmbt_irec map; int nmaps = 1, error; struct xfs_buf *bp; - struct xfs_inode *quotip = xfs_dq_to_quota_inode(dqp); + struct xfs_inode *quotip; struct xfs_mount *mp = dqp->q_mount; xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id); struct xfs_trans *tp = (tpp ? *tpp : NULL); uint lock_mode; + quotip = xfs_quota_inode(dqp->q_mount, dqp->dq_flags); dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; lock_mode = xfs_ilock_data_map_shared(quotip); diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 996a04064894..8901a01bc354 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -104,15 +104,15 @@ xfs_dquot_tree( } static inline struct xfs_inode * -xfs_dq_to_quota_inode(struct xfs_dquot *dqp) +xfs_quota_inode(xfs_mount_t *mp, uint dq_flags) { - switch (dqp->dq_flags & XFS_DQ_ALLTYPES) { + switch (dq_flags & XFS_DQ_ALLTYPES) { case XFS_DQ_USER: - return dqp->q_mount->m_quotainfo->qi_uquotaip; + return mp->m_quotainfo->qi_uquotaip; case XFS_DQ_GROUP: - return dqp->q_mount->m_quotainfo->qi_gquotaip; + return mp->m_quotainfo->qi_gquotaip; case XFS_DQ_PROJ: - return dqp->q_mount->m_quotainfo->qi_pquotaip; + return mp->m_quotainfo->qi_pquotaip; default: ASSERT(0); } -- GitLab From 8aa7d37ebf2f0cfba1411acb34e7b40e73f653e7 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:25:16 +1100 Subject: [PATCH 0748/5324] xfs: Factor xfs_seek_hole_data into helper Factor xfs_seek_hole_data into an unlocked helper which takes an xfs inode rather than a file for internal use. Also allow specification of "end" - the vfs lseek interface is defined such that any offset past eof/i_size shall return -ENXIO, but we will use this for quota code which does not maintain i_size, and we want to be able to SEEK_DATA past i_size as well. So the lseek path can send in i_size, and the quota code can determine its own ending offset. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 82 ++++++++++++++++++++++++++++++++-------------- fs/xfs/xfs_inode.h | 2 ++ 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 52883ac3cf84..70a4b5a2802e 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1337,31 +1337,31 @@ xfs_find_get_desired_pgoff( return found; } -STATIC loff_t -xfs_seek_hole_data( - struct file *file, +/* + * caller must lock inode with xfs_ilock_data_map_shared, + * can we craft an appropriate ASSERT? + * + * end is because the VFS-level lseek interface is defined such that any + * offset past i_size shall return -ENXIO, but we use this for quota code + * which does not maintain i_size, and we want to SEEK_DATA past i_size. + */ +loff_t +__xfs_seek_hole_data( + struct inode *inode, loff_t start, + loff_t end, int whence) { - struct inode *inode = file->f_mapping->host; struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; loff_t uninitialized_var(offset); - xfs_fsize_t isize; xfs_fileoff_t fsbno; - xfs_filblks_t end; - uint lock; + xfs_filblks_t lastbno; int error; - if (XFS_FORCED_SHUTDOWN(mp)) - return -EIO; - - lock = xfs_ilock_data_map_shared(ip); - - isize = i_size_read(inode); - if (start >= isize) { + if (start >= end) { error = -ENXIO; - goto out_unlock; + goto out_error; } /* @@ -1369,22 +1369,22 @@ xfs_seek_hole_data( * by fsbno to the end block of the file. */ fsbno = XFS_B_TO_FSBT(mp, start); - end = XFS_B_TO_FSB(mp, isize); + lastbno = XFS_B_TO_FSB(mp, end); for (;;) { struct xfs_bmbt_irec map[2]; int nmap = 2; unsigned int i; - error = xfs_bmapi_read(ip, fsbno, end - fsbno, map, &nmap, + error = xfs_bmapi_read(ip, fsbno, lastbno - fsbno, map, &nmap, XFS_BMAPI_ENTIRE); if (error) - goto out_unlock; + goto out_error; /* No extents at given offset, must be beyond EOF */ if (nmap == 0) { error = -ENXIO; - goto out_unlock; + goto out_error; } for (i = 0; i < nmap; i++) { @@ -1426,7 +1426,7 @@ xfs_seek_hole_data( * hole at the end of any file). */ if (whence == SEEK_HOLE) { - offset = isize; + offset = end; break; } /* @@ -1434,7 +1434,7 @@ xfs_seek_hole_data( */ ASSERT(whence == SEEK_DATA); error = -ENXIO; - goto out_unlock; + goto out_error; } ASSERT(i > 1); @@ -1445,14 +1445,14 @@ xfs_seek_hole_data( */ fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount; start = XFS_FSB_TO_B(mp, fsbno); - if (start >= isize) { + if (start >= end) { if (whence == SEEK_HOLE) { - offset = isize; + offset = end; break; } ASSERT(whence == SEEK_DATA); error = -ENXIO; - goto out_unlock; + goto out_error; } } @@ -1464,7 +1464,39 @@ xfs_seek_hole_data( * situation in particular. */ if (whence == SEEK_HOLE) - offset = min_t(loff_t, offset, isize); + offset = min_t(loff_t, offset, end); + + return offset; + +out_error: + return error; +} + +STATIC loff_t +xfs_seek_hole_data( + struct file *file, + loff_t start, + int whence) +{ + struct inode *inode = file->f_mapping->host; + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + uint lock; + loff_t offset, end; + int error = 0; + + if (XFS_FORCED_SHUTDOWN(mp)) + return -EIO; + + lock = xfs_ilock_data_map_shared(ip); + + end = i_size_read(inode); + offset = __xfs_seek_hole_data(inode, start, end, whence); + if (offset < 0) { + error = offset; + goto out_unlock; + } + offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes); out_unlock: diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e11989cbd..ed7e9339c7e9 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -437,6 +437,8 @@ int xfs_update_prealloc_flags(struct xfs_inode *ip, int xfs_zero_eof(struct xfs_inode *ip, xfs_off_t offset, xfs_fsize_t isize, bool *did_zeroing); int xfs_iozero(struct xfs_inode *ip, loff_t pos, size_t count); +loff_t __xfs_seek_hole_data(struct inode *inode, loff_t start, + loff_t eof, int whence); /* from xfs_iops.c */ -- GitLab From 296c24e26ee3af2dbfecb482e6bc9560bd34c455 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 11:27:38 +1100 Subject: [PATCH 0749/5324] xfs: wire up Q_XGETNEXTQUOTA / get_nextdqblk Add code to allow the Q_XGETNEXTQUOTA quotactl to quickly find all active quotas by examining the quota inode, and skipping over unallocated or uninitialized regions. Userspace can then use this interface rather than i.e. a getpwent() loop when asked to report all active quotas. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_quota_defs.h | 3 +- fs/xfs/xfs_dquot.c | 96 ++++++++++++++++++++++++++++++++++ fs/xfs/xfs_qm.h | 4 +- fs/xfs/xfs_qm_syscalls.c | 12 +++-- fs/xfs/xfs_quotaops.c | 36 ++++++++++++- 5 files changed, 142 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index f51078f1e92a..8eed51275bb3 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -37,7 +37,7 @@ typedef __uint16_t xfs_qwarncnt_t; #define XFS_DQ_PROJ 0x0002 /* project quota */ #define XFS_DQ_GROUP 0x0004 /* a group quota */ #define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */ -#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */ +#define XFS_DQ_FREEING 0x0010 /* dquot is being torn down */ #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) @@ -116,6 +116,7 @@ typedef __uint16_t xfs_qwarncnt_t; #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */ #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ #define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */ +#define XFS_QMOPT_DQNEXT 0x0008000 /* return next dquot >= this ID */ /* * flags to xfs_trans_mod_dquot to indicate which field needs to be diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 5dbde0d65f37..2f0502f0f214 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -685,6 +685,56 @@ xfs_qm_dqread( return error; } +/* + * Advance to the next id in the current chunk, or if at the + * end of the chunk, skip ahead to first id in next allocated chunk + * using the SEEK_DATA interface. + */ +int +xfs_dq_get_next_id( + xfs_mount_t *mp, + uint type, + xfs_dqid_t *id, + loff_t eof) +{ + struct xfs_inode *quotip; + xfs_fsblock_t start; + loff_t offset; + uint lock; + xfs_dqid_t next_id; + int error = 0; + + /* Simple advance */ + next_id = *id + 1; + + /* If new ID is within the current chunk, advancing it sufficed */ + if (next_id % mp->m_quotainfo->qi_dqperchunk) { + *id = next_id; + return 0; + } + + /* Nope, next_id is now past the current chunk, so find the next one */ + start = (xfs_fsblock_t)next_id / mp->m_quotainfo->qi_dqperchunk; + + quotip = xfs_quota_inode(mp, type); + lock = xfs_ilock_data_map_shared(quotip); + + offset = __xfs_seek_hole_data(VFS_I(quotip), XFS_FSB_TO_B(mp, start), + eof, SEEK_DATA); + if (offset < 0) + error = offset; + + xfs_iunlock(quotip, lock); + + /* -ENXIO is essentially "no more data" */ + if (error) + return (error == -ENXIO ? -ENOENT: error); + + /* Convert next data offset back to a quota id */ + *id = XFS_B_TO_FSB(mp, offset) * mp->m_quotainfo->qi_dqperchunk; + return 0; +} + /* * Given the file system, inode OR id, and type (UDQUOT/GDQUOT), return a * a locked dquot, doing an allocation (if requested) as needed. @@ -705,6 +755,7 @@ xfs_qm_dqget( struct xfs_quotainfo *qi = mp->m_quotainfo; struct radix_tree_root *tree = xfs_dquot_tree(qi, type); struct xfs_dquot *dqp; + loff_t eof = 0; int error; ASSERT(XFS_IS_QUOTA_RUNNING(mp)); @@ -732,6 +783,21 @@ xfs_qm_dqget( } #endif + /* Get the end of the quota file if we need it */ + if (flags & XFS_QMOPT_DQNEXT) { + struct xfs_inode *quotip; + xfs_fileoff_t last; + uint lock_mode; + + quotip = xfs_quota_inode(mp, type); + lock_mode = xfs_ilock_data_map_shared(quotip); + error = xfs_bmap_last_offset(quotip, &last, XFS_DATA_FORK); + xfs_iunlock(quotip, lock_mode); + if (error) + return error; + eof = XFS_FSB_TO_B(mp, last); + } + restart: mutex_lock(&qi->qi_tree_lock); dqp = radix_tree_lookup(tree, id); @@ -745,6 +811,18 @@ xfs_qm_dqget( goto restart; } + /* uninit / unused quota found in radix tree, keep looking */ + if (flags & XFS_QMOPT_DQNEXT) { + if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { + xfs_dqunlock(dqp); + mutex_unlock(&qi->qi_tree_lock); + error = xfs_dq_get_next_id(mp, type, &id, eof); + if (error) + return error; + goto restart; + } + } + dqp->q_nrefs++; mutex_unlock(&qi->qi_tree_lock); @@ -771,6 +849,13 @@ xfs_qm_dqget( if (ip) xfs_ilock(ip, XFS_ILOCK_EXCL); + /* If we are asked to find next active id, keep looking */ + if (error == -ENOENT && (flags & XFS_QMOPT_DQNEXT)) { + error = xfs_dq_get_next_id(mp, type, &id, eof); + if (!error) + goto restart; + } + if (error) return error; @@ -821,6 +906,17 @@ xfs_qm_dqget( qi->qi_dquots++; mutex_unlock(&qi->qi_tree_lock); + /* If we are asked to find next active id, keep looking */ + if (flags & XFS_QMOPT_DQNEXT) { + if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { + xfs_qm_dqput(dqp); + error = xfs_dq_get_next_id(mp, type, &id, eof); + if (error) + return error; + goto restart; + } + } + dqret: ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); trace_xfs_dqget_miss(dqp); diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 8901a01bc354..c68a38f528ba 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -164,8 +164,8 @@ extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint); /* quota ops */ extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); -extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, - uint, struct qc_dqblk *); +extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t *, + uint, struct qc_dqblk *, uint); extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, struct qc_dqblk *); extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 3640c6e896af..0a252863f82b 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -635,9 +635,10 @@ xfs_qm_log_quotaoff( int xfs_qm_scall_getquota( struct xfs_mount *mp, - xfs_dqid_t id, + xfs_dqid_t *id, uint type, - struct qc_dqblk *dst) + struct qc_dqblk *dst, + uint dqget_flags) { struct xfs_dquot *dqp; int error; @@ -647,7 +648,7 @@ xfs_qm_scall_getquota( * we aren't passing the XFS_QMOPT_DOALLOC flag. If it doesn't * exist, we'll get ENOENT back. */ - error = xfs_qm_dqget(mp, NULL, id, type, 0, &dqp); + error = xfs_qm_dqget(mp, NULL, *id, type, dqget_flags, &dqp); if (error) return error; @@ -660,6 +661,9 @@ xfs_qm_scall_getquota( goto out_put; } + /* Fill in the ID we actually read from disk */ + *id = be32_to_cpu(dqp->q_core.d_id); + memset(dst, 0, sizeof(*dst)); dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); @@ -701,7 +705,7 @@ xfs_qm_scall_getquota( if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && - id != 0) { + *id != 0) { if ((dst->d_space > dst->d_spc_softlimit) && (dst->d_spc_softlimit > 0)) { ASSERT(dst->d_spc_timer != 0); diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 7795e0d01382..f82d79a8c694 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -231,14 +231,45 @@ xfs_fs_get_dqblk( struct qc_dqblk *qdq) { struct xfs_mount *mp = XFS_M(sb); + xfs_dqid_t id; if (!XFS_IS_QUOTA_RUNNING(mp)) return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) return -ESRCH; - return xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid), - xfs_quota_type(qid.type), qdq); + id = from_kqid(&init_user_ns, qid); + return xfs_qm_scall_getquota(mp, &id, + xfs_quota_type(qid.type), qdq, 0); +} + +/* Return quota info for active quota >= this qid */ +STATIC int +xfs_fs_get_nextdqblk( + struct super_block *sb, + struct kqid *qid, + struct qc_dqblk *qdq) +{ + int ret; + struct xfs_mount *mp = XFS_M(sb); + xfs_dqid_t id; + + if (!XFS_IS_QUOTA_RUNNING(mp)) + return -ENOSYS; + if (!XFS_IS_QUOTA_ON(mp)) + return -ESRCH; + + id = from_kqid(&init_user_ns, *qid); + ret = xfs_qm_scall_getquota(mp, &id, + xfs_quota_type(qid->type), qdq, + XFS_QMOPT_DQNEXT); + if (ret) + return ret; + + /* ID may be different, so convert back what we got */ + *qid = make_kqid(current_user_ns(), qid->type, id); + return 0; + } STATIC int @@ -267,5 +298,6 @@ const struct quotactl_ops xfs_quotactl_operations = { .quota_disable = xfs_quota_disable, .rm_xquota = xfs_fs_rm_xquota, .get_dqblk = xfs_fs_get_dqblk, + .get_nextdqblk = xfs_fs_get_nextdqblk, .set_dqblk = xfs_fs_set_dqblk, }; -- GitLab From be6079461abf796e29d02b450a16908f4bf58f6c Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Mon, 8 Feb 2016 11:27:55 +1100 Subject: [PATCH 0750/5324] xfs: Split default quota limits by quota type Default quotas are globally set due historical reasons. IRIX only supported user and project quotas, and default quota was only applied to user quotas. In Linux, when a default quota is set, all different quota types inherits the same default value. An user with a quota limit larger than the default quota value, will still be limited to the default value because the group quotas also inherits the default quotas. Unless the group which the user belongs to have a custom quota limit set. This patch aims to split the default quota value by quota type. Allowing each quota type having different default values. Default time limits are still set globally. XFS does not set a per-user/group timer, but a single global timer. For changing this behavior, some changes should be made in user-space tools another bugs being fixed. Signed-off-by: Carlos Maiolino Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/xfs_dquot.c | 26 ++++++++++--------- fs/xfs/xfs_qm.c | 55 +++++++++++++++++++++++++++++++--------- fs/xfs/xfs_qm.h | 34 ++++++++++++++++++++----- fs/xfs/xfs_qm_syscalls.c | 15 ++++++----- fs/xfs/xfs_trans_dquot.c | 15 ++++++----- 5 files changed, 103 insertions(+), 42 deletions(-) diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 2f0502f0f214..316b2a1bdba5 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -92,26 +92,28 @@ xfs_qm_adjust_dqlimits( { struct xfs_quotainfo *q = mp->m_quotainfo; struct xfs_disk_dquot *d = &dq->q_core; + struct xfs_def_quota *defq; int prealloc = 0; ASSERT(d->d_id); + defq = xfs_get_defquota(dq, q); - if (q->qi_bsoftlimit && !d->d_blk_softlimit) { - d->d_blk_softlimit = cpu_to_be64(q->qi_bsoftlimit); + if (defq->bsoftlimit && !d->d_blk_softlimit) { + d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit); prealloc = 1; } - if (q->qi_bhardlimit && !d->d_blk_hardlimit) { - d->d_blk_hardlimit = cpu_to_be64(q->qi_bhardlimit); + if (defq->bhardlimit && !d->d_blk_hardlimit) { + d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit); prealloc = 1; } - if (q->qi_isoftlimit && !d->d_ino_softlimit) - d->d_ino_softlimit = cpu_to_be64(q->qi_isoftlimit); - if (q->qi_ihardlimit && !d->d_ino_hardlimit) - d->d_ino_hardlimit = cpu_to_be64(q->qi_ihardlimit); - if (q->qi_rtbsoftlimit && !d->d_rtb_softlimit) - d->d_rtb_softlimit = cpu_to_be64(q->qi_rtbsoftlimit); - if (q->qi_rtbhardlimit && !d->d_rtb_hardlimit) - d->d_rtb_hardlimit = cpu_to_be64(q->qi_rtbhardlimit); + if (defq->isoftlimit && !d->d_ino_softlimit) + d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit); + if (defq->ihardlimit && !d->d_ino_hardlimit) + d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit); + if (defq->rtbsoftlimit && !d->d_rtb_softlimit) + d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit); + if (defq->rtbhardlimit && !d->d_rtb_hardlimit) + d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit); if (prealloc) xfs_dquot_set_prealloc_limits(dq); diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 532ab79d38fe..be125e1758c1 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -560,6 +560,37 @@ xfs_qm_shrink_count( return list_lru_shrink_count(&qi->qi_lru, sc); } +STATIC void +xfs_qm_set_defquota( + xfs_mount_t *mp, + uint type, + xfs_quotainfo_t *qinf) +{ + xfs_dquot_t *dqp; + struct xfs_def_quota *defq; + int error; + + error = xfs_qm_dqread(mp, 0, type, XFS_QMOPT_DOWARN, &dqp); + + if (!error) { + xfs_disk_dquot_t *ddqp = &dqp->q_core; + + defq = xfs_get_defquota(dqp, qinf); + + /* + * Timers and warnings have been already set, let's just set the + * default limits for this quota type + */ + defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit); + defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit); + defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit); + defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); + defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); + defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); + xfs_qm_dqdestroy(dqp); + } +} + /* * This initializes all the quota information that's kept in the * mount structure @@ -606,19 +637,19 @@ xfs_qm_init_quotainfo( * We try to get the limits from the superuser's limits fields. * This is quite hacky, but it is standard quota practice. * - * We look at the USR dquot with id == 0 first, but if user quotas - * are not enabled we goto the GRP dquot with id == 0. - * We don't really care to keep separate default limits for user - * and group quotas, at least not at this point. - * * Since we may not have done a quotacheck by this point, just read * the dquot without attaching it to any hashtables or lists. + * + * Timers and warnings are globally set by the first timer found in + * user/group/proj quota types, otherwise a default value is used. + * This should be split into different fields per quota type. */ error = xfs_qm_dqread(mp, 0, XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER : (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP : XFS_DQ_PROJ), XFS_QMOPT_DOWARN, &dqp); + if (!error) { xfs_disk_dquot_t *ddqp = &dqp->q_core; @@ -639,13 +670,6 @@ xfs_qm_init_quotainfo( be16_to_cpu(ddqp->d_iwarns) : XFS_QM_IWARNLIMIT; qinf->qi_rtbwarnlimit = ddqp->d_rtbwarns ? be16_to_cpu(ddqp->d_rtbwarns) : XFS_QM_RTBWARNLIMIT; - qinf->qi_bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit); - qinf->qi_bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit); - qinf->qi_ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit); - qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); - qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); - qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); - xfs_qm_dqdestroy(dqp); } else { qinf->qi_btimelimit = XFS_QM_BTIMELIMIT; @@ -656,6 +680,13 @@ xfs_qm_init_quotainfo( qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT; } + if (XFS_IS_UQUOTA_RUNNING(mp)) + xfs_qm_set_defquota(mp, XFS_DQ_USER, qinf); + if (XFS_IS_GQUOTA_RUNNING(mp)) + xfs_qm_set_defquota(mp, XFS_DQ_GROUP, qinf); + if (XFS_IS_PQUOTA_RUNNING(mp)) + xfs_qm_set_defquota(mp, XFS_DQ_PROJ, qinf); + qinf->qi_shrinker.count_objects = xfs_qm_shrink_count; qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan; qinf->qi_shrinker.seeks = DEFAULT_SEEKS; diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index c68a38f528ba..2975a822e9f0 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -53,6 +53,15 @@ extern struct kmem_zone *xfs_qm_dqtrxzone; */ #define XFS_DQUOT_CLUSTER_SIZE_FSB (xfs_filblks_t)1 +struct xfs_def_quota { + xfs_qcnt_t bhardlimit; /* default data blk hard limit */ + xfs_qcnt_t bsoftlimit; /* default data blk soft limit */ + xfs_qcnt_t ihardlimit; /* default inode count hard limit */ + xfs_qcnt_t isoftlimit; /* default inode count soft limit */ + xfs_qcnt_t rtbhardlimit; /* default realtime blk hard limit */ + xfs_qcnt_t rtbsoftlimit; /* default realtime blk soft limit */ +}; + /* * Various quota information for individual filesystems. * The mount structure keeps a pointer to this. @@ -76,12 +85,9 @@ typedef struct xfs_quotainfo { struct mutex qi_quotaofflock;/* to serialize quotaoff */ xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ uint qi_dqperchunk; /* # ondisk dqs in above chunk */ - xfs_qcnt_t qi_bhardlimit; /* default data blk hard limit */ - xfs_qcnt_t qi_bsoftlimit; /* default data blk soft limit */ - xfs_qcnt_t qi_ihardlimit; /* default inode count hard limit */ - xfs_qcnt_t qi_isoftlimit; /* default inode count soft limit */ - xfs_qcnt_t qi_rtbhardlimit;/* default realtime blk hard limit */ - xfs_qcnt_t qi_rtbsoftlimit;/* default realtime blk soft limit */ + struct xfs_def_quota qi_usr_default; + struct xfs_def_quota qi_grp_default; + struct xfs_def_quota qi_prj_default; struct shrinker qi_shrinker; } xfs_quotainfo_t; @@ -171,4 +177,20 @@ extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); +static inline struct xfs_def_quota * +xfs_get_defquota(struct xfs_dquot *dqp, struct xfs_quotainfo *qi) +{ + struct xfs_def_quota *defq; + + if (XFS_QM_ISUDQ(dqp)) + defq = &qi->qi_usr_default; + else if (XFS_QM_ISGDQ(dqp)) + defq = &qi->qi_grp_default; + else { + ASSERT(XFS_QM_ISPDQ(dqp)); + defq = &qi->qi_prj_default; + } + return defq; +} + #endif /* __XFS_QM_H__ */ diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 0a252863f82b..f4d0e0a8f517 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -404,6 +404,7 @@ xfs_qm_scall_setqlim( struct xfs_disk_dquot *ddq; struct xfs_dquot *dqp; struct xfs_trans *tp; + struct xfs_def_quota *defq; int error; xfs_qcnt_t hard, soft; @@ -431,6 +432,8 @@ xfs_qm_scall_setqlim( ASSERT(error != -ENOENT); goto out_unlock; } + + defq = xfs_get_defquota(dqp, q); xfs_dqunlock(dqp); tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); @@ -458,8 +461,8 @@ xfs_qm_scall_setqlim( ddq->d_blk_softlimit = cpu_to_be64(soft); xfs_dquot_set_prealloc_limits(dqp); if (id == 0) { - q->qi_bhardlimit = hard; - q->qi_bsoftlimit = soft; + defq->bhardlimit = hard; + defq->bsoftlimit = soft; } } else { xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); @@ -474,8 +477,8 @@ xfs_qm_scall_setqlim( ddq->d_rtb_hardlimit = cpu_to_be64(hard); ddq->d_rtb_softlimit = cpu_to_be64(soft); if (id == 0) { - q->qi_rtbhardlimit = hard; - q->qi_rtbsoftlimit = soft; + defq->rtbhardlimit = hard; + defq->rtbsoftlimit = soft; } } else { xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); @@ -491,8 +494,8 @@ xfs_qm_scall_setqlim( ddq->d_ino_hardlimit = cpu_to_be64(hard); ddq->d_ino_softlimit = cpu_to_be64(soft); if (id == 0) { - q->qi_ihardlimit = hard; - q->qi_isoftlimit = soft; + defq->ihardlimit = hard; + defq->isoftlimit = soft; } } else { xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 995170194df0..c3d547211d16 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -609,17 +609,20 @@ xfs_trans_dqresv( xfs_qcnt_t total_count; xfs_qcnt_t *resbcountp; xfs_quotainfo_t *q = mp->m_quotainfo; + struct xfs_def_quota *defq; xfs_dqlock(dqp); + defq = xfs_get_defquota(dqp, q); + if (flags & XFS_TRANS_DQ_RES_BLKS) { hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit); if (!hardlimit) - hardlimit = q->qi_bhardlimit; + hardlimit = defq->bhardlimit; softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit); if (!softlimit) - softlimit = q->qi_bsoftlimit; + softlimit = defq->bsoftlimit; timer = be32_to_cpu(dqp->q_core.d_btimer); warns = be16_to_cpu(dqp->q_core.d_bwarns); warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit; @@ -628,10 +631,10 @@ xfs_trans_dqresv( ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit); if (!hardlimit) - hardlimit = q->qi_rtbhardlimit; + hardlimit = defq->rtbhardlimit; softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit); if (!softlimit) - softlimit = q->qi_rtbsoftlimit; + softlimit = defq->rtbsoftlimit; timer = be32_to_cpu(dqp->q_core.d_rtbtimer); warns = be16_to_cpu(dqp->q_core.d_rtbwarns); warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit; @@ -672,10 +675,10 @@ xfs_trans_dqresv( warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit; hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); if (!hardlimit) - hardlimit = q->qi_ihardlimit; + hardlimit = defq->ihardlimit; softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); if (!softlimit) - softlimit = q->qi_isoftlimit; + softlimit = defq->isoftlimit; if (hardlimit && total_count > hardlimit) { xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); -- GitLab From 187372a3b9faff68ed61c291d0135e6739e0dbdf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:40:51 +1100 Subject: [PATCH 0751/5324] direct-io: always call ->end_io if non-NULL This way we can pass back errors to the file system, and allow for cleanup required for all direct I/O invocations. Also allow the ->end_io handlers to return errors on their own, so that I/O completion errors can be passed on to the callers. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/dax.c | 9 +++++++-- fs/direct-io.c | 9 +++++++-- fs/ext4/inode.c | 9 +++++++-- fs/ocfs2/aops.c | 7 ++++++- fs/xfs/xfs_aops.c | 13 +++++++------ include/linux/fs.h | 2 +- 6 files changed, 35 insertions(+), 14 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 4fd6b0c5c6b5..e38b2c589b54 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -267,8 +267,13 @@ ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode, if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) inode_unlock(inode); - if ((retval > 0) && end_io) - end_io(iocb, pos, retval, bh.b_private); + if (end_io) { + int err; + + err = end_io(iocb, pos, retval, bh.b_private); + if (err) + retval = err; + } if (!(flags & DIO_SKIP_DIO_COUNT)) inode_dio_end(inode); diff --git a/fs/direct-io.c b/fs/direct-io.c index 1b2f7ffc8b84..9c6f885cc518 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -253,8 +253,13 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, if (ret == 0) ret = transferred; - if (dio->end_io && dio->result) - dio->end_io(dio->iocb, offset, transferred, dio->private); + if (dio->end_io) { + int err; + + err = dio->end_io(dio->iocb, offset, ret, dio->private); + if (err) + ret = err; + } if (!(dio->flags & DIO_SKIP_DIO_COUNT)) inode_dio_end(dio->inode); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 83bc8bfb3bea..9db04dd9b88a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3161,14 +3161,17 @@ int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock, } #endif -static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, +static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset, ssize_t size, void *private) { ext4_io_end_t *io_end = iocb->private; + if (size <= 0) + return 0; + /* if not async direct IO just return */ if (!io_end) - return; + return 0; ext_debug("ext4_end_io_dio(): io_end 0x%p " "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", @@ -3179,6 +3182,8 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, io_end->offset = offset; io_end->size = size; ext4_put_io_end(io_end); + + return 0; } /* diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 794fd1587f34..5dcc5f5a842e 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -620,7 +620,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, * particularly interested in the aio/dio case. We use the rw_lock DLM lock * to protect io on one node from truncation on another. */ -static void ocfs2_dio_end_io(struct kiocb *iocb, +static int ocfs2_dio_end_io(struct kiocb *iocb, loff_t offset, ssize_t bytes, void *private) @@ -628,6 +628,9 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, struct inode *inode = file_inode(iocb->ki_filp); int level; + if (bytes <= 0) + return 0; + /* this io's submitter should not have unlocked this before we could */ BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); @@ -644,6 +647,8 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, level = ocfs2_iocb_rw_locked_level(iocb); ocfs2_rw_unlock(inode, level); } + + return 0; } static int ocfs2_releasepage(struct page *page, gfp_t wait) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 379c089fb051..295aaffea78e 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1645,7 +1645,7 @@ __xfs_end_io_direct_write( * case the completion can be called in interrupt context, whereas if we have an * ioend we will always be called in task context (i.e. from a workqueue). */ -STATIC void +STATIC int xfs_end_io_direct_write( struct kiocb *iocb, loff_t offset, @@ -1655,15 +1655,19 @@ xfs_end_io_direct_write( struct inode *inode = file_inode(iocb->ki_filp); struct xfs_ioend *ioend = private; + if (size <= 0) + return 0; + trace_xfs_gbmap_direct_endio(XFS_I(inode), offset, size, ioend ? ioend->io_type : 0, NULL); if (!ioend) { ASSERT(offset + size <= i_size_read(inode)); - return; + return 0; } __xfs_end_io_direct_write(inode, ioend, offset, size); + return 0; } static inline ssize_t @@ -1672,10 +1676,7 @@ xfs_vm_do_dio( struct kiocb *iocb, struct iov_iter *iter, loff_t offset, - void (*endio)(struct kiocb *iocb, - loff_t offset, - ssize_t size, - void *private), + dio_iodone_t endio, int flags) { struct block_device *bdev; diff --git a/include/linux/fs.h b/include/linux/fs.h index 1a2046275cdf..d7f37bfcbdce 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -70,7 +70,7 @@ extern int sysctl_protected_hardlinks; struct buffer_head; typedef int (get_block_t)(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create); -typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, +typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, ssize_t bytes, void *private); typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); -- GitLab From 273dda76f757108bc2b29d30a9595b6dd3bdf3a1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:40:51 +1100 Subject: [PATCH 0752/5324] xfs: don't use ioends for direct write completions We only need to communicate two bits of information to the direct I/O completion handler: (1) do we need to convert any unwritten extents in the range (2) do we need to check if we need to update the inode size based on the range passed to the completion handler We can use the private data passed to the get_block handler and the completion handler as a simple bitmask to communicate this information instead of the current complicated infrastructure reusing the ioends from the buffer I/O path, and thus avoiding a memory allocation and a context switch for any non-trivial direct write. As a nice side effect we also decouple the direct I/O path implementation from that of the buffered I/O path. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster --- fs/xfs/xfs_aops.c | 216 +++++++++++++++------------------------------ fs/xfs/xfs_trace.h | 9 +- 2 files changed, 75 insertions(+), 150 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 295aaffea78e..f008a4f9dcea 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -36,6 +36,10 @@ #include #include +/* flags for direct write completions */ +#define XFS_DIO_FLAG_UNWRITTEN (1 << 0) +#define XFS_DIO_FLAG_APPEND (1 << 1) + void xfs_count_page_state( struct page *page, @@ -1238,27 +1242,8 @@ xfs_vm_releasepage( } /* - * When we map a DIO buffer, we may need to attach an ioend that describes the - * type of write IO we are doing. This passes to the completion function the - * operations it needs to perform. If the mapping is for an overwrite wholly - * within the EOF then we don't need an ioend and so we don't allocate one. - * This avoids the unnecessary overhead of allocating and freeing ioends for - * workloads that don't require transactions on IO completion. - * - * If we get multiple mappings in a single IO, we might be mapping different - * types. But because the direct IO can only have a single private pointer, we - * need to ensure that: - * - * a) i) the ioend spans the entire region of unwritten mappings; or - * ii) the ioend spans all the mappings that cross or are beyond EOF; and - * b) if it contains unwritten extents, it is *permanently* marked as such - * - * We could do this by chaining ioends like buffered IO does, but we only - * actually get one IO completion callback from the direct IO, and that spans - * the entire IO regardless of how many mappings and IOs are needed to complete - * the DIO. There is only going to be one reference to the ioend and its life - * cycle is constrained by the DIO completion code. hence we don't need - * reference counting here. + * When we map a DIO buffer, we may need to pass flags to + * xfs_end_io_direct_write to tell it what kind of write IO we are doing. * * Note that for DIO, an IO to the highest supported file block offset (i.e. * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64 @@ -1266,68 +1251,26 @@ xfs_vm_releasepage( * extending the file size. We won't know for sure until IO completion is run * and the actual max write offset is communicated to the IO completion * routine. - * - * For DAX page faults, we are preparing to never see unwritten extents here, - * nor should we ever extend the inode size. Hence we will soon have nothing to - * do here for this case, ensuring we don't have to provide an IO completion - * callback to free an ioend that we don't actually need for a fault into the - * page at offset (2^63 - 1FSB) bytes. */ - static void xfs_map_direct( struct inode *inode, struct buffer_head *bh_result, struct xfs_bmbt_irec *imap, - xfs_off_t offset, - bool dax_fault) + xfs_off_t offset) { - struct xfs_ioend *ioend; + uintptr_t *flags = (uintptr_t *)&bh_result->b_private; xfs_off_t size = bh_result->b_size; - int type; - - if (ISUNWRITTEN(imap)) - type = XFS_IO_UNWRITTEN; - else - type = XFS_IO_OVERWRITE; - - trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); - - if (dax_fault) { - ASSERT(type == XFS_IO_OVERWRITE); - trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, - imap); - return; - } - if (bh_result->b_private) { - ioend = bh_result->b_private; - ASSERT(ioend->io_size > 0); - ASSERT(offset >= ioend->io_offset); - if (offset + size > ioend->io_offset + ioend->io_size) - ioend->io_size = offset - ioend->io_offset + size; - - if (type == XFS_IO_UNWRITTEN && type != ioend->io_type) - ioend->io_type = XFS_IO_UNWRITTEN; - - trace_xfs_gbmap_direct_update(XFS_I(inode), ioend->io_offset, - ioend->io_size, ioend->io_type, - imap); - } else if (type == XFS_IO_UNWRITTEN || - offset + size > i_size_read(inode) || - offset + size < 0) { - ioend = xfs_alloc_ioend(inode, type); - ioend->io_offset = offset; - ioend->io_size = size; + trace_xfs_get_blocks_map_direct(XFS_I(inode), offset, size, + ISUNWRITTEN(imap) ? XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, imap); - bh_result->b_private = ioend; + if (ISUNWRITTEN(imap)) { + *flags |= XFS_DIO_FLAG_UNWRITTEN; + set_buffer_defer_completion(bh_result); + } else if (offset + size > i_size_read(inode) || offset + size < 0) { + *flags |= XFS_DIO_FLAG_APPEND; set_buffer_defer_completion(bh_result); - - trace_xfs_gbmap_direct_new(XFS_I(inode), offset, size, type, - imap); - } else { - trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, - imap); } } @@ -1498,9 +1441,12 @@ __xfs_get_blocks( if (ISUNWRITTEN(&imap)) set_buffer_unwritten(bh_result); /* direct IO needs special help */ - if (create && direct) - xfs_map_direct(inode, bh_result, &imap, offset, - dax_fault); + if (create && direct) { + if (dax_fault) + ASSERT(!ISUNWRITTEN(&imap)); + else + xfs_map_direct(inode, bh_result, &imap, offset); + } } /* @@ -1570,42 +1516,50 @@ xfs_get_blocks_dax_fault( return __xfs_get_blocks(inode, iblock, bh_result, create, true, true); } -static void -__xfs_end_io_direct_write( - struct inode *inode, - struct xfs_ioend *ioend, +/* + * Complete a direct I/O write request. + * + * xfs_map_direct passes us some flags in the private data to tell us what to + * do. If no flags are set, then the write IO is an overwrite wholly within + * the existing allocated file size and so there is nothing for us to do. + * + * Note that in this case the completion can be called in interrupt context, + * whereas if we have flags set we will always be called in task context + * (i.e. from a workqueue). + */ +STATIC int +xfs_end_io_direct_write( + struct kiocb *iocb, loff_t offset, - ssize_t size) + ssize_t size, + void *private) { - struct xfs_mount *mp = XFS_I(inode)->i_mount; + struct inode *inode = file_inode(iocb->ki_filp); + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + uintptr_t flags = (uintptr_t)private; + int error = 0; - if (XFS_FORCED_SHUTDOWN(mp) || ioend->io_error) - goto out_end_io; + trace_xfs_end_io_direct_write(ip, offset, size); - /* - * dio completion end_io functions are only called on writes if more - * than 0 bytes was written. - */ - ASSERT(size > 0); + if (XFS_FORCED_SHUTDOWN(mp)) + return -EIO; - /* - * The ioend only maps whole blocks, while the IO may be sector aligned. - * Hence the ioend offset/size may not match the IO offset/size exactly. - * Because we don't map overwrites within EOF into the ioend, the offset - * may not match, but only if the endio spans EOF. Either way, write - * the IO sizes into the ioend so that completion processing does the - * right thing. - */ - ASSERT(offset + size <= ioend->io_offset + ioend->io_size); - ioend->io_size = size; - ioend->io_offset = offset; + if (size <= 0) + return size; /* - * The ioend tells us whether we are doing unwritten extent conversion + * The flags tell us whether we are doing unwritten extent conversions * or an append transaction that updates the on-disk file size. These * cases are the only cases where we should *potentially* be needing * to update the VFS inode size. - * + */ + if (flags == 0) { + ASSERT(offset + size <= i_size_read(inode)); + return 0; + } + + /* * We need to update the in-core inode size here so that we don't end up * with the on-disk inode size being outside the in-core inode size. We * have no other method of updating EOF for AIO, so always do it here @@ -1616,58 +1570,30 @@ __xfs_end_io_direct_write( * here can result in EOF moving backwards and Bad Things Happen when * that occurs. */ - spin_lock(&XFS_I(inode)->i_flags_lock); + spin_lock(&ip->i_flags_lock); if (offset + size > i_size_read(inode)) i_size_write(inode, offset + size); - spin_unlock(&XFS_I(inode)->i_flags_lock); + spin_unlock(&ip->i_flags_lock); - /* - * If we are doing an append IO that needs to update the EOF on disk, - * do the transaction reserve now so we can use common end io - * processing. Stashing the error (if there is one) in the ioend will - * result in the ioend processing passing on the error if it is - * possible as we can't return it from here. - */ - if (ioend->io_type == XFS_IO_OVERWRITE) - ioend->io_error = xfs_setfilesize_trans_alloc(ioend); + if (flags & XFS_DIO_FLAG_UNWRITTEN) { + trace_xfs_end_io_direct_write_unwritten(ip, offset, size); -out_end_io: - xfs_end_io(&ioend->io_work); - return; -} + error = xfs_iomap_write_unwritten(ip, offset, size); + } else if (flags & XFS_DIO_FLAG_APPEND) { + struct xfs_trans *tp; -/* - * Complete a direct I/O write request. - * - * The ioend structure is passed from __xfs_get_blocks() to tell us what to do. - * If no ioend exists (i.e. @private == NULL) then the write IO is an overwrite - * wholly within the EOF and so there is nothing for us to do. Note that in this - * case the completion can be called in interrupt context, whereas if we have an - * ioend we will always be called in task context (i.e. from a workqueue). - */ -STATIC int -xfs_end_io_direct_write( - struct kiocb *iocb, - loff_t offset, - ssize_t size, - void *private) -{ - struct inode *inode = file_inode(iocb->ki_filp); - struct xfs_ioend *ioend = private; + trace_xfs_end_io_direct_write_append(ip, offset, size); - if (size <= 0) - return 0; - - trace_xfs_gbmap_direct_endio(XFS_I(inode), offset, size, - ioend ? ioend->io_type : 0, NULL); - - if (!ioend) { - ASSERT(offset + size <= i_size_read(inode)); - return 0; + tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0); + if (error) { + xfs_trans_cancel(tp); + return error; + } + error = xfs_setfilesize(ip, tp, offset, size); } - __xfs_end_io_direct_write(inode, ioend, offset, size); - return 0; + return error; } static inline ssize_t diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 391d797cb53f..c8d58426008e 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1296,11 +1296,7 @@ DEFINE_IOMAP_EVENT(xfs_map_blocks_found); DEFINE_IOMAP_EVENT(xfs_map_blocks_alloc); DEFINE_IOMAP_EVENT(xfs_get_blocks_found); DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); -DEFINE_IOMAP_EVENT(xfs_gbmap_direct); -DEFINE_IOMAP_EVENT(xfs_gbmap_direct_new); -DEFINE_IOMAP_EVENT(xfs_gbmap_direct_update); -DEFINE_IOMAP_EVENT(xfs_gbmap_direct_none); -DEFINE_IOMAP_EVENT(xfs_gbmap_direct_endio); +DEFINE_IOMAP_EVENT(xfs_get_blocks_map_direct); DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), @@ -1340,6 +1336,9 @@ DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); DEFINE_SIMPLE_IO_EVENT(xfs_setfilesize); DEFINE_SIMPLE_IO_EVENT(xfs_zero_eof); +DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write); +DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write_unwritten); +DEFINE_SIMPLE_IO_EVENT(xfs_end_io_direct_write_append); DECLARE_EVENT_CLASS(xfs_itrunc_class, TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), -- GitLab From c19b104a67b3bb1ac48275a8a1c9df666e676c25 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:40:51 +1100 Subject: [PATCH 0753/5324] xfs: fold xfs_vm_do_dio into xfs_vm_direct_IO Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index f008a4f9dcea..8163910bc49f 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1596,38 +1596,30 @@ xfs_end_io_direct_write( return error; } -static inline ssize_t -xfs_vm_do_dio( - struct inode *inode, +STATIC ssize_t +xfs_vm_direct_IO( struct kiocb *iocb, struct iov_iter *iter, - loff_t offset, - dio_iodone_t endio, - int flags) + loff_t offset) { + struct inode *inode = iocb->ki_filp->f_mapping->host; + dio_iodone_t *endio = NULL; + int flags = 0; struct block_device *bdev; - if (IS_DAX(inode)) + if (iov_iter_rw(iter) == WRITE) { + endio = xfs_end_io_direct_write; + flags = DIO_ASYNC_EXTEND; + } + + if (IS_DAX(inode)) { return dax_do_io(iocb, inode, iter, offset, xfs_get_blocks_direct, endio, 0); + } bdev = xfs_find_bdev_for_inode(inode); return __blockdev_direct_IO(iocb, inode, bdev, iter, offset, - xfs_get_blocks_direct, endio, NULL, flags); -} - -STATIC ssize_t -xfs_vm_direct_IO( - struct kiocb *iocb, - struct iov_iter *iter, - loff_t offset) -{ - struct inode *inode = iocb->ki_filp->f_mapping->host; - - if (iov_iter_rw(iter) == WRITE) - return xfs_vm_do_dio(inode, iocb, iter, offset, - xfs_end_io_direct_write, DIO_ASYNC_EXTEND); - return xfs_vm_do_dio(inode, iocb, iter, offset, NULL, 0); + xfs_get_blocks_direct, endio, NULL, flags); } /* -- GitLab From 196328ec973a74ee52cc282824e72c3824dc1cf5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:58:07 +1100 Subject: [PATCH 0754/5324] xfs: handle errors from ->free_blocks in xfs_btree_kill_iroot Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index a0eb18ce3ad3..3143577930bd 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -3209,6 +3209,7 @@ xfs_btree_kill_iroot( int level; int index; int numrecs; + int error; #ifdef DEBUG union xfs_btree_ptr ptr; int i; @@ -3272,8 +3273,6 @@ xfs_btree_kill_iroot( cpp = xfs_btree_ptr_addr(cur, 1, cblock); #ifdef DEBUG for (i = 0; i < numrecs; i++) { - int error; - error = xfs_btree_check_ptr(cur, cpp, i, level - 1); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); @@ -3283,7 +3282,11 @@ xfs_btree_kill_iroot( #endif xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); - cur->bc_ops->free_block(cur, cbp); + error = cur->bc_ops->free_block(cur, cbp); + if (error) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); + return error; + } XFS_BTREE_STATS_INC(cur, free); cur->bc_bufs[level - 1] = NULL; -- GitLab From c46ee8ad7856b58eeb383c30ce847897f85c4103 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:58:07 +1100 Subject: [PATCH 0755/5324] xfs: factor btree block freeing into a helper Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 3143577930bd..77afb4a899b9 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -294,6 +294,19 @@ xfs_btree_sblock_verify_crc( return true; } +static int +xfs_btree_free_block( + struct xfs_btree_cur *cur, + struct xfs_buf *bp) +{ + int error; + + error = cur->bc_ops->free_block(cur, bp); + if (!error) + XFS_BTREE_STATS_INC(cur, free); + return error; +} + /* * Delete the btree cursor. */ @@ -3282,12 +3295,11 @@ xfs_btree_kill_iroot( #endif xfs_btree_copy_ptrs(cur, pp, cpp, numrecs); - error = cur->bc_ops->free_block(cur, cbp); + error = xfs_btree_free_block(cur, cbp); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } - XFS_BTREE_STATS_INC(cur, free); cur->bc_bufs[level - 1] = NULL; be16_add_cpu(&block->bb_level, -1); @@ -3320,14 +3332,12 @@ xfs_btree_kill_root( */ cur->bc_ops->set_root(cur, newroot, -1); - error = cur->bc_ops->free_block(cur, bp); + error = xfs_btree_free_block(cur, bp); if (error) { XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); return error; } - XFS_BTREE_STATS_INC(cur, free); - cur->bc_bufs[level] = NULL; cur->bc_ra[level] = 0; cur->bc_nlevels--; @@ -3833,10 +3843,9 @@ xfs_btree_delrec( } /* Free the deleted block. */ - error = cur->bc_ops->free_block(cur, rbp); + error = xfs_btree_free_block(cur, rbp); if (error) goto error0; - XFS_BTREE_STATS_INC(cur, free); /* * If we joined with the left neighbor, set the buffer in the -- GitLab From edfd9dd549212a0923c9b5b142275dc88912abfa Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 8 Feb 2016 14:58:07 +1100 Subject: [PATCH 0756/5324] xfs: move buffer invalidation to xfs_btree_free_block ... instead of leaving it in the methods. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc_btree.c | 2 -- fs/xfs/libxfs/xfs_bmap_btree.c | 1 - fs/xfs/libxfs/xfs_btree.c | 4 +++- fs/xfs/libxfs/xfs_ialloc_btree.c | 12 ++---------- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 444626ddbd1b..d9b42425291e 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -118,8 +118,6 @@ xfs_allocbt_free_block( xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, XFS_EXTENT_BUSY_SKIP_DISCARD); xfs_trans_agbtree_delta(cur->bc_tp, -1); - - xfs_trans_binval(cur->bc_tp, bp); return 0; } diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 1637c37bfbaa..e37508ae589b 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -531,7 +531,6 @@ xfs_bmbt_free_block( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); - xfs_trans_binval(tp, bp); return 0; } diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 77afb4a899b9..1f88e1ce770f 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -302,8 +302,10 @@ xfs_btree_free_block( int error; error = cur->bc_ops->free_block(cur, bp); - if (!error) + if (!error) { + xfs_trans_binval(cur->bc_tp, bp); XFS_BTREE_STATS_INC(cur, free); + } return error; } diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index c679f3c05b63..89c21d771e35 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -125,16 +125,8 @@ xfs_inobt_free_block( struct xfs_btree_cur *cur, struct xfs_buf *bp) { - xfs_fsblock_t fsbno; - int error; - - fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); - error = xfs_free_extent(cur->bc_tp, fsbno, 1); - if (error) - return error; - - xfs_trans_binval(cur->bc_tp, bp); - return error; + return xfs_free_extent(cur->bc_tp, + XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1); } STATIC int -- GitLab From de0b85a8cf24f8c535b7f719c454e3951298d17a Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 8 Feb 2016 14:58:07 +1100 Subject: [PATCH 0757/5324] xfs: remove unused function definitions Old leftovers. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_sb.h | 1 - fs/xfs/xfs_fsops.h | 1 - fs/xfs/xfs_mount.h | 1 - 3 files changed, 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index b25bb9a343f3..961e6475a309 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -27,7 +27,6 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t, extern void xfs_perag_put(struct xfs_perag *pag); extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); -extern void xfs_sb_calc_crc(struct xfs_buf *bp); extern void xfs_log_sb(struct xfs_trans *tp); extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h index 1b6a98b66886..f32713f14f9a 100644 --- a/fs/xfs/xfs_fsops.h +++ b/fs/xfs/xfs_fsops.h @@ -25,6 +25,5 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt); extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, xfs_fsop_resblks_t *outval); extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); -extern int xfs_fs_log_dummy(struct xfs_mount *mp); #endif /* __XFS_FSOPS_H__ */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index b57098481c10..a4e03ab50342 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -327,7 +327,6 @@ extern int xfs_mod_fdblocks(struct xfs_mount *mp, int64_t delta, bool reserved); extern int xfs_mod_frextents(struct xfs_mount *mp, int64_t delta); -extern int xfs_mount_log_sb(xfs_mount_t *); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); -- GitLab From 18f1df4e00cea2eae41f3e5515b94d1e7127b2b6 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Mon, 8 Feb 2016 14:59:07 +1100 Subject: [PATCH 0758/5324] xfs: Make xfsaild freezeable again Hendik has reported suspend failures due to xfsaild blocking the freezer to settle down. Jan 17 19:59:56 linux-6380 kernel: PM: Syncing filesystems ... done. Jan 17 19:59:56 linux-6380 kernel: PM: Preparing system for sleep (mem) Jan 17 19:59:56 linux-6380 kernel: Freezing user space processes ... (elapsed 0.001 seconds) done. Jan 17 19:59:56 linux-6380 kernel: Freezing remaining freezable tasks ... Jan 17 19:59:56 linux-6380 kernel: Freezing of tasks failed after 20.002 seconds (1 tasks refusing to freeze, wq_busy=0): Jan 17 19:59:56 linux-6380 kernel: xfsaild/dm-5 S 00000000 0 1293 2 0x00000080 Jan 17 19:59:56 linux-6380 kernel: f0ef5f00 00000046 00000200 00000000 ffff9022 c02d3800 00000000 00000032 Jan 17 19:59:56 linux-6380 kernel: ee0b2400 00000032 f71e0d00 f36fabc0 f0ef2d00 f0ef6000 f0ef2d00 f12f90c0 Jan 17 19:59:56 linux-6380 kernel: f0ef5f0c c0844e44 00000000 f0ef5f6c f811e0be 00000000 00000000 f0ef2d00 Jan 17 19:59:56 linux-6380 kernel: Call Trace: Jan 17 19:59:56 linux-6380 kernel: [] schedule+0x34/0x90 Jan 17 19:59:56 linux-6380 kernel: [] xfsaild+0x5de/0x600 [xfs] Jan 17 19:59:56 linux-6380 kernel: [] kthread+0x9b/0xb0 Jan 17 19:59:56 linux-6380 kernel: [] ret_from_kernel_thread+0x21/0x38 The issue has been there for quite some time but it has been made visible by only by 24ba16bb3d49 ("xfs: clear PF_NOFREEZE for xfsaild kthread") because the suspend started seeing xfsaild. The above commit has missed that the !xfs_ail_min branch might call schedule with TASK_INTERRUPTIBLE without calling try_to_freeze so the pm suspend would wake up the kernel thread over and over again without any progress. What we want here is to use freezable_schedule instead to hide the thread from the suspend. While we are here also change schedule_timeout to freezable variant to prevent from spurious wakeups by suspend. [dchinner: re-add set_freezeable call so the freezer will account properly for this kthread. ] Reported-by: Hendrik Woltersdorf Signed-off-by: Michal Hocko Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_trans_ail.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 4f18fd92ca13..d6c9c3e9e02b 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -497,6 +497,7 @@ xfsaild( long tout = 0; /* milliseconds */ current->flags |= PF_MEMALLOC; + set_freezable(); while (!kthread_should_stop()) { if (tout && tout <= 20) @@ -519,14 +520,14 @@ xfsaild( if (!xfs_ail_min(ailp) && ailp->xa_target == ailp->xa_target_prev) { spin_unlock(&ailp->xa_lock); - schedule(); + freezable_schedule(); tout = 0; continue; } spin_unlock(&ailp->xa_lock); if (tout) - schedule_timeout(msecs_to_jiffies(tout)); + freezable_schedule_timeout(msecs_to_jiffies(tout)); __set_current_state(TASK_RUNNING); -- GitLab From 244efeafb65ad4d98cd0c9463631e3931d813a6e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 8 Feb 2016 15:00:01 +1100 Subject: [PATCH 0759/5324] xfs: move struct xfs_attr_shortform to xfs_da_format.h Move the shortform attr structure definition to the same place as the other attribute structure definitions for consistency and also so that xfs/122 verifies the structure size. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_attr_sf.h | 16 ---------------- fs/xfs/libxfs/xfs_da_format.h | 16 ++++++++++++++++ fs/xfs/libxfs/xfs_inode_fork.c | 1 + 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_sf.h b/fs/xfs/libxfs/xfs_attr_sf.h index 919756e3ba53..90928bbe693c 100644 --- a/fs/xfs/libxfs/xfs_attr_sf.h +++ b/fs/xfs/libxfs/xfs_attr_sf.h @@ -24,22 +24,6 @@ * Small attribute lists are packed as tightly as possible so as * to fit into the literal area of the inode. */ - -/* - * Entries are packed toward the top as tight as possible. - */ -typedef struct xfs_attr_shortform { - struct xfs_attr_sf_hdr { /* constant-structure header block */ - __be16 totsize; /* total bytes in shortform list */ - __u8 count; /* count of active entries */ - } hdr; - struct xfs_attr_sf_entry { - __uint8_t namelen; /* actual length of name (no NULL) */ - __uint8_t valuelen; /* actual length of value (no NULL) */ - __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ - __uint8_t nameval[1]; /* name & value bytes concatenated */ - } list[1]; /* variable sized array */ -} xfs_attr_shortform_t; typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index b14bbd6bb05f..8d4d8bce41bf 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h @@ -641,6 +641,22 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp) */ #define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */ +/* + * Entries are packed toward the top as tight as possible. + */ +typedef struct xfs_attr_shortform { + struct xfs_attr_sf_hdr { /* constant-structure header block */ + __be16 totsize; /* total bytes in shortform list */ + __u8 count; /* count of active entries */ + } hdr; + struct xfs_attr_sf_entry { + __uint8_t namelen; /* actual length of name (no NULL) */ + __uint8_t valuelen; /* actual length of value (no NULL) */ + __uint8_t flags; /* flags bits (see xfs_attr_leaf.h) */ + __uint8_t nameval[1]; /* name & value bytes concatenated */ + } list[1]; /* variable sized array */ +} xfs_attr_shortform_t; + typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */ __be16 base; /* base of free region */ __be16 size; /* length of free region */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0defbd02f62d..ef22a78fb569 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -31,6 +31,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_attr_sf.h" +#include "xfs_da_format.h" kmem_zone_t *xfs_ifork_zone; -- GitLab From 60630fe66ed28d43379382645ed349f7d3457330 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 8 Feb 2016 15:00:02 +1100 Subject: [PATCH 0760/5324] xfs: clean up unwritten buffers on write failure The xfs_vm_write_failed() handler is currently responsible for cleaning up any delalloc blocks over the range of a failed write beyond EOF. Failure to do so results in warning messages and other inconsistencies between buffer and extent state. The ->releasepage() handler currently warns in the event of a page being released with either unwritten or delalloc buffers, as neither is ever expected by the time a page is released. As has been reproduced by generic/083 on a -bsize=1k fs, it is currently possible to trigger the ->releasepage() warning for a page with unwritten buffers when a filesystem is near ENOSPC. This is reproduced by the following sequence: $ mkfs.xfs -f -b size=1k -d size=100m $ mount /mnt/ $ $ xfs_io -fc "falloc -k 0 1k" /mnt/file $ dd if=/dev/zero of=/mnt/enospc conv=notrunc oflag=append $ $ xfs_io -c "pwrite 512 1k" /mnt/file $ xfs_io -d -c "pwrite 16k 1k" /mnt/file The first pwrite command attempts a block unaligned write across an unwritten block and a hole. The delalloc for the hole fails with ENOSPC and the subsequent error handling does not clean up the unwritten buffer that was instantiated during the first ->get_block() call. The second pwrite triggers a warning as part of the inode mapping invalidation that occurs prior to direct I/O. The releasepage() handler detects the unwritten buffer at this time, warns and prevents the release of the page. To deal with this problem, update xfs_vm_write_failed() to clean up unwritten as well as delalloc buffers that are beyond EOF and within the range of the failed write. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 379c089fb051..4a13f5311a41 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1783,14 +1783,22 @@ xfs_vm_write_failed( if (block_start >= to) break; - if (!buffer_delay(bh)) + /* + * Process delalloc and unwritten buffers beyond EOF. We can + * encounter unwritten buffers in the event that a file has + * post-EOF unwritten extents and an extending write happens to + * fail (e.g., an unaligned write that also involves a delalloc + * to the same page). + */ + if (!buffer_delay(bh) && !buffer_unwritten(bh)) continue; if (!buffer_new(bh) && block_offset < i_size_read(inode)) continue; - xfs_vm_kill_delalloc_range(inode, block_offset, - block_offset + bh->b_size); + if (buffer_delay(bh)) + xfs_vm_kill_delalloc_range(inode, block_offset, + block_offset + bh->b_size); /* * This buffer does not contain data anymore. make sure anyone @@ -1801,6 +1809,7 @@ xfs_vm_write_failed( clear_buffer_mapped(bh); clear_buffer_new(bh); clear_buffer_dirty(bh); + clear_buffer_unwritten(bh); } } -- GitLab From af055e37a91d215d7174d0b84c86795ca81086a7 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 8 Feb 2016 15:00:02 +1100 Subject: [PATCH 0761/5324] xfs: fix xfs_log_ticket leak in xfs_end_io() after fs shutdown If the filesystem has shut down, xfs_end_io() currently sets an error on the ioend and proceeds to ioend destruction. The ioend might contain a truncate transaction if the I/O extended the size of the file. This transaction is only cleaned up in xfs_setfilesize_ioend(), however, which is skipped in this case. This results in an xfs_log_ticket leak message when the associate cache slab is destroyed (e.g., on rmmod). This was originally reproduced by xfs/141 on a distro kernel. The problem is reproducible on an upstream kernel, but not easily detected in current upstream if the xfs_log_ticket cache happens to be merged with another cache. This can be reproduced more deterministically with the 'slab_nomerge' kernel boot option. Update xfs_end_io() to proceed with normal end I/O processing after an error is set on an ioend due to fs shutdown. The I/O type-based processing is already designed to handle an I/O error and ensure that the ioend is cleaned up correctly. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 4a13f5311a41..0c8dacea411e 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -214,10 +214,12 @@ xfs_end_io( struct xfs_inode *ip = XFS_I(ioend->io_inode); int error = 0; - if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { + /* + * Set an error if the mount has shut down and proceed with end I/O + * processing so it can perform whatever cleanups are necessary. + */ + if (XFS_FORCED_SHUTDOWN(ip->i_mount)) ioend->io_error = -EIO; - goto done; - } /* * For unwritten extents we need to issue transactions to convert a -- GitLab From 4020b220edb3419975c0d9322ee0e0c07e09f6bf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Jan 2016 12:01:04 +0100 Subject: [PATCH 0762/5324] drm/vblank: Use drm_event_reserve_init Well we can't use that directly since that code must hold dev->event_lock already. Extract an _unlocked version. Embarrassingly I've totally forgotten about this patch and any kind of event-based vblank wait totally blew up, killing the kernel. v2: Pick the right base struct, someone didn't noticed that gcc was unhappy. No bug since the addresses at least matched (Daniel Stone) Cc: Alex Deucher Cc: Daniel Stone Cc: Laurent Pinchart Reviewed-by: Daniel Stone Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453978864-1513-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fops.c | 64 +++++++++++++++++++++++++++++--------- drivers/gpu/drm/drm_irq.c | 11 +++---- include/drm/drmP.h | 4 +++ 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index e13501e3606e..eb6a02f78697 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -678,7 +678,7 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) EXPORT_SYMBOL(drm_poll); /** - * drm_event_reserve_init - init a DRM event and reserve space for it + * drm_event_reserve_init_locked - init a DRM event and reserve space for it * @dev: DRM device * @file_priv: DRM file private data * @p: tracking structure for the pending event @@ -694,24 +694,20 @@ EXPORT_SYMBOL(drm_poll); * If callers embedded @p into a larger structure it must be allocated with * kmalloc and @p must be the first member element. * + * This is the locked version of drm_event_reserve_init() for callers which + * already hold dev->event_lock. + * * RETURNS: * * 0 on success or a negative error code on failure. */ -int drm_event_reserve_init(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_pending_event *p, - struct drm_event *e) +int drm_event_reserve_init_locked(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_pending_event *p, + struct drm_event *e) { - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&dev->event_lock, flags); - - if (file_priv->event_space < e->length) { - ret = -ENOMEM; - goto out; - } + if (file_priv->event_space < e->length) + return -ENOMEM; file_priv->event_space -= e->length; @@ -721,8 +717,46 @@ int drm_event_reserve_init(struct drm_device *dev, /* we *could* pass this in as arg, but everyone uses kfree: */ p->destroy = (void (*) (struct drm_pending_event *)) kfree; -out: + return 0; +} +EXPORT_SYMBOL(drm_event_reserve_init_locked); + +/** + * drm_event_reserve_init - init a DRM event and reserve space for it + * @dev: DRM device + * @file_priv: DRM file private data + * @p: tracking structure for the pending event + * @e: actual event data to deliver to userspace + * + * This function prepares the passed in event for eventual delivery. If the event + * doesn't get delivered (because the IOCTL fails later on, before queuing up + * anything) then the even must be cancelled and freed using + * drm_event_cancel_free(). Successfully initialized events should be sent out + * using drm_send_event() or drm_send_event_locked() to signal completion of the + * asynchronous event to userspace. + * + * If callers embedded @p into a larger structure it must be allocated with + * kmalloc and @p must be the first member element. + * + * Callers which already hold dev->event_lock should use + * drm_event_reserve_init() instead. + * + * RETURNS: + * + * 0 on success or a negative error code on failure. + */ +int drm_event_reserve_init(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_pending_event *p, + struct drm_event *e) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&dev->event_lock, flags); + ret = drm_event_reserve_init_locked(dev, file_priv, p, e); spin_unlock_irqrestore(&dev->event_lock, flags); + return ret; } EXPORT_SYMBOL(drm_event_reserve_init); diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4ec8bca643ac..96d03ac38ef7 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1598,9 +1598,6 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, e->event.base.type = DRM_EVENT_VBLANK; e->event.base.length = sizeof(e->event); e->event.user_data = vblwait->request.signal; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; spin_lock_irqsave(&dev->event_lock, flags); @@ -1616,12 +1613,12 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, goto err_unlock; } - if (file_priv->event_space < sizeof(e->event)) { - ret = -EBUSY; + ret = drm_event_reserve_init_locked(dev, file_priv, &e->base, + &e->event.base); + + if (ret) goto err_unlock; - } - file_priv->event_space -= sizeof(e->event); seq = drm_vblank_count_and_time(dev, pipe, &now); if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 306ef32ec086..1b71852d0a55 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -926,6 +926,10 @@ ssize_t drm_read(struct file *filp, char __user *buffer, int drm_release(struct inode *inode, struct file *filp); int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv); unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); +int drm_event_reserve_init_locked(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_pending_event *p, + struct drm_event *e); int drm_event_reserve_init(struct drm_device *dev, struct drm_file *file_priv, struct drm_pending_event *p, -- GitLab From 681047b48601841c8380abd406301648c3590592 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:43 +0100 Subject: [PATCH 0763/5324] drm: Clean up pending events in the core There's really no reason to not do so, instead of replicating this for every use-case and every driver. Now we can't just nuke the events, since that would still mean that all drm_event users would need to know when that has happened, since calling e.g. drm_send_event isn't allowed any more. Instead just unlink them from the file, and detect this case and handle it appropriately in all functions. v2: Adjust existing kerneldoc too. v3: Improve wording of the kerneldoc and split out vblank cleanup (Laurent). Cc: Alex Deucher Cc: Laurent Pinchart Acked-by: Daniel Stone Reviewed-by: Alex Deucher (v1) Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-2-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fops.c | 30 +++++++++++++++++++++++++++++- include/drm/drmP.h | 2 ++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index eb6a02f78697..afe8c53e5aad 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -264,6 +264,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) INIT_LIST_HEAD(&priv->fbs); mutex_init(&priv->fbs_lock); INIT_LIST_HEAD(&priv->blobs); + INIT_LIST_HEAD(&priv->pending_event_list); INIT_LIST_HEAD(&priv->event_list); init_waitqueue_head(&priv->event_wait); priv->event_space = 4096; /* set aside 4k for event buffer */ @@ -366,6 +367,13 @@ static void drm_events_release(struct drm_file *file_priv) v->base.destroy(&v->base); } + /* Unlink pending events */ + list_for_each_entry_safe(e, et, &file_priv->pending_event_list, + pending_link) { + list_del(&e->pending_link); + e->file_priv = NULL; + } + /* Remove unconsumed events */ list_for_each_entry_safe(e, et, &file_priv->event_list, link) { list_del(&e->link); @@ -712,6 +720,7 @@ int drm_event_reserve_init_locked(struct drm_device *dev, file_priv->event_space -= e->length; p->event = e; + list_add(&p->pending_link, &file_priv->pending_event_list); p->file_priv = file_priv; /* we *could* pass this in as arg, but everyone uses kfree: */ @@ -774,7 +783,10 @@ void drm_event_cancel_free(struct drm_device *dev, { unsigned long flags; spin_lock_irqsave(&dev->event_lock, flags); - p->file_priv->event_space += p->event->length; + if (p->file_priv) { + p->file_priv->event_space += p->event->length; + list_del(&p->pending_link); + } spin_unlock_irqrestore(&dev->event_lock, flags); p->destroy(p); } @@ -788,11 +800,22 @@ EXPORT_SYMBOL(drm_event_cancel_free); * This function sends the event @e, initialized with drm_event_reserve_init(), * to its associated userspace DRM file. Callers must already hold * dev->event_lock, see drm_send_event() for the unlocked version. + * + * Note that the core will take care of unlinking and disarming events when the + * corresponding DRM file is closed. Drivers need not worry about whether the + * DRM file for this event still exists and can call this function upon + * completion of the asynchronous work unconditionally. */ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) { assert_spin_locked(&dev->event_lock); + if (!e->file_priv) { + e->destroy(e); + return; + } + + list_del(&e->pending_link); list_add_tail(&e->link, &e->file_priv->event_list); wake_up_interruptible(&e->file_priv->event_wait); @@ -807,6 +830,11 @@ EXPORT_SYMBOL(drm_send_event_locked); * This function sends the event @e, initialized with drm_event_reserve_init(), * to its associated userspace DRM file. This function acquires dev->event_lock, * see drm_send_event_locked() for callers which already hold this lock. + * + * Note that the core will take care of unlinking and disarming events when the + * corresponding DRM file is closed. Drivers need not worry about whether the + * DRM file for this event still exists and can call this function upon + * completion of the asynchronous work unconditionally. */ void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) { diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 1b71852d0a55..3c8422c69572 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -283,6 +283,7 @@ struct drm_ioctl_desc { struct drm_pending_event { struct drm_event *event; struct list_head link; + struct list_head pending_link; struct drm_file *file_priv; pid_t pid; /* pid of requester, no guarantee it's valid by the time we deliver the event, for tracing only */ @@ -346,6 +347,7 @@ struct drm_file { struct list_head blobs; wait_queue_head_t event_wait; + struct list_head pending_event_list; struct list_head event_list; int event_space; -- GitLab From 7eb98020b73e20ce18d3ed704d7b7988ddad5dfd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:44 +0100 Subject: [PATCH 0764/5324] drm: Nuke vblank event file cleanup code The core code now takes care of unlinking drm_events from the file in a generic way, so this code isn't needed any more. For those wondering where the drm_vblank_put went to: With the new logic events only get unlinked, but still exist. Hence any resources (like vblank counters) don't need to be released since the event user will still process the event normally. In this case this is the callsites of send_vblank_event, which of course already have a drm_vblank_put. Cc: Laurent Pinchart Acked-by: Daniel Stone Reviewed-by: Alex Deucher Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-3-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_fops.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index afe8c53e5aad..aeef58ed359b 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -354,19 +354,10 @@ static void drm_events_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; struct drm_pending_event *e, *et; - struct drm_pending_vblank_event *v, *vt; unsigned long flags; spin_lock_irqsave(&dev->event_lock, flags); - /* Remove pending flips */ - list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link) - if (v->base.file_priv == file_priv) { - list_del(&v->base.link); - drm_vblank_put(dev, v->pipe); - v->base.destroy(&v->base); - } - /* Unlink pending events */ list_for_each_entry_safe(e, et, &file_priv->pending_event_list, pending_link) { -- GitLab From 00648f18e0fd48b2452200659ce8610d4d2f8060 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:45 +0100 Subject: [PATCH 0765/5324] drm/i915: Nuke intel_modeset_preclose Now that the drm core unlinks/disarms events there's no need to do so ourselves anymore. Nuke the code. Acked-by: Daniel Stone Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-4-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 2 -- drivers/gpu/drm/i915/intel_display.c | 21 --------------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 3 files changed, 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d70d96fe553b..1c3d2544fec4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1261,8 +1261,6 @@ void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) i915_gem_context_close(dev, file); i915_gem_release(dev, file); mutex_unlock(&dev->struct_mutex); - - intel_modeset_preclose(dev, file); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 580d094bfc1e..8816ba1d6d53 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -16140,24 +16140,3 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, err_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync); } } - -void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct intel_crtc *crtc; - - for_each_intel_crtc(dev, crtc) { - struct intel_unpin_work *work; - - spin_lock_irq(&dev->event_lock); - - work = crtc->unpin_work; - - if (work && work->event && - work->event->base.file_priv == file) { - kfree(work->event); - work->event = NULL; - } - - spin_unlock_irq(&dev->event_lock); - } -} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ea5415851c6e..98e434537dd2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1207,7 +1207,6 @@ enum intel_display_power_domain intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder); void intel_mode_from_pipe_config(struct drm_display_mode *mode, struct intel_crtc_state *pipe_config); -void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file); int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); -- GitLab From 9c333c28838f9ceaa0fdb66747da3bdc1fcec53c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:46 +0100 Subject: [PATCH 0766/5324] drm/atmel: Nuke preclose The only thing this did was cancle pending flip events, and the core takes care of that now. Cc: Boris Brezillon Acked-by: Daniel Stone Reviewed-by: Alex Deucher Acked-by: Boris Brezillon Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-5-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 18 ------------------ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 10 ---------- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 3 --- 3 files changed, 31 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 468a14f266a7..9863291a9a54 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -280,24 +280,6 @@ static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c) kfree(crtc); } -void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *c, - struct drm_file *file) -{ - struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); - struct drm_pending_vblank_event *event; - struct drm_device *dev = c->dev; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - event = crtc->event; - if (event && event->base.file_priv == file) { - event->base.destroy(&event->base); - drm_vblank_put(dev, crtc->id); - crtc->event = NULL; - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc) { struct drm_device *dev = crtc->base.dev; diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index a45b32ba029e..3d8d16402d07 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -619,15 +619,6 @@ static void atmel_hlcdc_dc_connector_unplug_all(struct drm_device *dev) mutex_unlock(&dev->mode_config.mutex); } -static void atmel_hlcdc_dc_preclose(struct drm_device *dev, - struct drm_file *file) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - atmel_hlcdc_crtc_cancel_page_flip(crtc, file); -} - static void atmel_hlcdc_dc_lastclose(struct drm_device *dev) { struct atmel_hlcdc_dc *dc = dev->dev_private; @@ -698,7 +689,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, - .preclose = atmel_hlcdc_dc_preclose, .lastclose = atmel_hlcdc_dc_lastclose, .irq_handler = atmel_hlcdc_dc_irq_handler, .irq_preinstall = atmel_hlcdc_dc_irq_uninstall, diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h index cf6b375bc38d..fed517f297da 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @@ -152,9 +152,6 @@ int atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state); void atmel_hlcdc_crtc_irq(struct drm_crtc *c); -void atmel_hlcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, - struct drm_file *file); - void atmel_hlcdc_crtc_suspend(struct drm_crtc *crtc); void atmel_hlcdc_crtc_resume(struct drm_crtc *crtc); -- GitLab From 84b29a553e90d7933d9ada64302ae30d4a9084fd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:47 +0100 Subject: [PATCH 0767/5324] drm/exynos: Remove event cancelling from postclose The core takes care of this now. And since kfree(NULL) is ok we can simplify the function even further now. Note: There's another spin on this patch, but for different reasons, in-flight already: http://www.spinics.net/lists/dri-devel/msg97922.html Cc: Inki Dae Acked-by: Daniel Stone Reviewed-by: Alex Deucher Acked-by: Inki Dae Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-6-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 68f0f36f6e7e..1e535f981240 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -340,20 +340,6 @@ static void exynos_drm_preclose(struct drm_device *dev, static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) { - struct drm_pending_event *e, *et; - unsigned long flags; - - if (!file->driver_priv) - return; - - spin_lock_irqsave(&dev->event_lock, flags); - /* Release all events handled by page flip handler but not freed. */ - list_for_each_entry_safe(e, et, &file->event_list, link) { - list_del(&e->link); - e->destroy(e); - } - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(file->driver_priv); file->driver_priv = NULL; } -- GitLab From 4eced321bf3d2f45b9dd221ba806a9b3c7d3a67a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:48 +0100 Subject: [PATCH 0768/5324] drm/imx: Unconfuse preclose logic So this one is special, since it tries to prevent races when userspace crashes simply by disabling the vblank machinery. Well except that imx always has vblanks enabled, and the disable_vblank hook actually just tries to cancel a pending pageflip. Without any locking whatsoever. Of course this is wrong, since it'll result in the hw not actually displaying what drm thinks is the current frontbuffer. Well since the core takes care of the disappearing DRM fd now. So we can nuke all this confused code without ill side-effects. Someone else needs to audit the locking for ->newfb and ->page_flip_event and fix it up. Common approach is to reuse dev->event_lock for this. Cc: Sascha Hauer Cc: Philipp Zabel Acked-by: Daniel Stone Reviewed-by: Alex Deucher Acked-by: Philipp Zabel Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-7-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/imx/imx-drm-core.c | 13 ------------- drivers/gpu/drm/imx/ipuv3-crtc.c | 4 ---- 2 files changed, 17 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 2f57d7967417..7c4d1250e071 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -171,18 +171,6 @@ static void imx_drm_disable_vblank(struct drm_device *drm, unsigned int pipe) imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc); } -static void imx_drm_driver_preclose(struct drm_device *drm, - struct drm_file *file) -{ - int i; - - if (!file->is_master) - return; - - for (i = 0; i < MAX_CRTC; i++) - imx_drm_disable_vblank(drm, i); -} - static const struct file_operations imx_drm_driver_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -463,7 +451,6 @@ static struct drm_driver imx_drm_driver = { .load = imx_drm_driver_load, .unload = imx_drm_driver_unload, .lastclose = imx_drm_driver_lastclose, - .preclose = imx_drm_driver_preclose, .set_busid = drm_platform_set_busid, .gem_free_object = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 30a57185bdb4..846b5f558897 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -285,10 +285,6 @@ static int ipu_enable_vblank(struct drm_crtc *crtc) static void ipu_disable_vblank(struct drm_crtc *crtc) { - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - - ipu_crtc->page_flip_event = NULL; - ipu_crtc->newfb = NULL; } static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, -- GitLab From 53190c7194d9a8337fe419134e44c30eb63ebd08 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:49 +0100 Subject: [PATCH 0769/5324] drm/msm: Nuke preclose hooks They only complete the page flip events to avoid oops when the drm file closes. The core takes care of that now and we can remove this code. Cc: Rob Clark Acked-by: Daniel Stone Reviewed-by: Alex Deucher Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-8-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 7 ------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 11 ----------- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 1 - drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 6 ------ drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 11 ----------- drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 1 - 6 files changed, 37 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 28df397c3b04..909d74250de7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -575,13 +575,6 @@ uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc) return mdp4_crtc->vblank.irqmask; } -void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file) -{ - struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); - DBG("%s: cancel: %p", mdp4_crtc->name, file); - complete_flip(crtc, file); -} - /* set dma config, ie. the format the encoder wants. */ void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config) { diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 5a8e3d6bcbff..1c8e330f8d98 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -179,16 +179,6 @@ static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, } } -static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file) -{ - struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); - struct msm_drm_private *priv = mdp4_kms->dev->dev_private; - unsigned i; - - for (i = 0; i < priv->num_crtcs; i++) - mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file); -} - static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); @@ -213,7 +203,6 @@ static const struct mdp_kms_funcs kms_funcs = { .wait_for_crtc_commit_done = mdp4_wait_for_crtc_commit_done, .get_format = mdp_get_format, .round_pixclk = mdp4_round_pixclk, - .preclose = mdp4_preclose, .destroy = mdp4_destroy, }, .set_irqmask = mdp4_set_irqmask, diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index d2c96ef431f4..9ec53b464662 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -199,7 +199,6 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, enum mdp4_pipe pipe_id, bool private_plane); uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); -void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer); void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 20cee5ce4071..46682aa8870c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -721,12 +721,6 @@ uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc) return mdp5_crtc->vblank.irqmask; } -void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file) -{ - DBG("cancel: %p", file); - complete_flip(crtc, file); -} - void mdp5_crtc_set_pipeline(struct drm_crtc *crtc, struct mdp5_interface *intf, struct mdp5_ctl *ctl) { diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index e115318402bd..5e4d16b399c7 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -117,16 +117,6 @@ static int mdp5_set_split_display(struct msm_kms *kms, return mdp5_encoder_set_split_display(encoder, slave_encoder); } -static void mdp5_preclose(struct msm_kms *kms, struct drm_file *file) -{ - struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - struct msm_drm_private *priv = mdp5_kms->dev->dev_private; - unsigned i; - - for (i = 0; i < priv->num_crtcs; i++) - mdp5_crtc_cancel_pending_flip(priv->crtcs[i], file); -} - static void mdp5_destroy(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); @@ -164,7 +154,6 @@ static const struct mdp_kms_funcs kms_funcs = { .get_format = mdp_get_format, .round_pixclk = mdp5_round_pixclk, .set_split_display = mdp5_set_split_display, - .preclose = mdp5_preclose, .destroy = mdp5_destroy, }, .set_irqmask = mdp5_set_irqmask, diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 00730ba08a60..9a25898239d3 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -211,7 +211,6 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); int mdp5_crtc_get_lm(struct drm_crtc *crtc); -void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); void mdp5_crtc_set_pipeline(struct drm_crtc *crtc, struct mdp5_interface *intf, struct mdp5_ctl *ctl); void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc); -- GitLab From 8c04fdeef343a18617968b672f212d1634add14d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:50 +0100 Subject: [PATCH 0770/5324] drm/omap: Nuke close hooks Again since the core takes care of this we can remove them. While at it also remove the postclose hook, it's empty. v2: Laurent pointed me at even more code to delete. v3: Remove unused flags (Tomi). Cc: Laurent Pinchart Cc: Tomi Valkeinen Acked-by: Daniel Stone Reviewed-by: Alex Deucher Reviewed-by: Laurent Pinchart Acked-by: Tomi Valkeinen Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-9-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/omapdrm/omap_crtc.c | 13 +-------- drivers/gpu/drm/omapdrm/omap_drv.c | 42 ----------------------------- drivers/gpu/drm/omapdrm/omap_drv.h | 1 - 3 files changed, 1 insertion(+), 55 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 2ed0754ed19e..d38fcbcc43a8 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -269,18 +269,7 @@ static void omap_crtc_complete_page_flip(struct drm_crtc *crtc) return; spin_lock_irqsave(&dev->event_lock, flags); - - list_del(&event->base.link); - - /* - * Queue the event for delivery if it's still linked to a file - * handle, otherwise just destroy it. - */ - if (event->base.file_priv) - drm_crtc_send_vblank_event(crtc, event); - else - event->base.destroy(&event->base); - + drm_crtc_send_vblank_event(crtc, event); spin_unlock_irqrestore(&dev->event_lock, flags); } diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index dfafdb602ad2..33370f42e4d7 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -142,7 +142,6 @@ static int omap_atomic_commit(struct drm_device *dev, { struct omap_drm_private *priv = dev->dev_private; struct omap_atomic_state_commit *commit; - unsigned long flags; unsigned int i; int ret; @@ -175,17 +174,6 @@ static int omap_atomic_commit(struct drm_device *dev, priv->commit.pending |= commit->crtcs; spin_unlock(&priv->commit.lock); - /* Keep track of all CRTC events to unlink them in preclose(). */ - spin_lock_irqsave(&dev->event_lock, flags); - for (i = 0; i < dev->mode_config.num_crtc; ++i) { - struct drm_crtc_state *cstate = state->crtc_states[i]; - - if (cstate && cstate->event) - list_add_tail(&cstate->event->base.link, - &priv->commit.events); - } - spin_unlock_irqrestore(&dev->event_lock, flags); - /* Swap the state, this is the point of no return. */ drm_atomic_helper_swap_state(dev, state); @@ -673,7 +661,6 @@ static int dev_load(struct drm_device *dev, unsigned long flags) priv->wq = alloc_ordered_workqueue("omapdrm", 0); init_waitqueue_head(&priv->commit.wait); spin_lock_init(&priv->commit.lock); - INIT_LIST_HEAD(&priv->commit.events); spin_lock_init(&priv->list_lock); INIT_LIST_HEAD(&priv->obj_list); @@ -787,33 +774,6 @@ static void dev_lastclose(struct drm_device *dev) } } -static void dev_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct omap_drm_private *priv = dev->dev_private; - struct drm_pending_event *event; - unsigned long flags; - - DBG("preclose: dev=%p", dev); - - /* - * Unlink all pending CRTC events to make sure they won't be queued up - * by a pending asynchronous commit. - */ - spin_lock_irqsave(&dev->event_lock, flags); - list_for_each_entry(event, &priv->commit.events, link) { - if (event->file_priv == file) { - file->event_space += event->event->length; - event->file_priv = NULL; - } - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - -static void dev_postclose(struct drm_device *dev, struct drm_file *file) -{ - DBG("postclose: dev=%p, file=%p", dev, file); -} - static const struct vm_operations_struct omap_gem_vm_ops = { .fault = omap_gem_fault, .open = drm_gem_vm_open, @@ -838,8 +798,6 @@ static struct drm_driver omap_drm_driver = { .unload = dev_unload, .open = dev_open, .lastclose = dev_lastclose, - .preclose = dev_preclose, - .postclose = dev_postclose, .set_busid = drm_platform_set_busid, .get_vblank_counter = drm_vblank_no_hw_counter, .enable_vblank = omap_irq_enable_vblank, diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 9e0030731c37..c23cbe6fe9e4 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -106,7 +106,6 @@ struct omap_drm_private { /* atomic commit */ struct { - struct list_head events; wait_queue_head_t wait; u32 pending; spinlock_t lock; /* Protects commit.pending */ -- GitLab From 0a346629f5304a8390004a91e8d4f1206b87792b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:51 +0100 Subject: [PATCH 0771/5324] drm/rcar: Nuke preclose hook Again since the drm core takes care of event unlinking/disarming this is now just needless code. Cc: Laurent Pinchart Acked-by: Daniel Stone Reviewed-by: Alex Deucher Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-10-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 20 -------------------- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 -- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 10 ---------- 3 files changed, 32 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 88a4b706be16..4ec80ae1fa99 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -282,26 +282,6 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc) * Page Flip */ -void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, - struct drm_file *file) -{ - struct drm_pending_vblank_event *event; - struct drm_device *dev = rcrtc->crtc.dev; - unsigned long flags; - - /* Destroy the pending vertical blanking event associated with the - * pending page flip, if any, and disable vertical blanking interrupts. - */ - spin_lock_irqsave(&dev->event_lock, flags); - event = rcrtc->event; - if (event && event->base.file_priv == file) { - rcrtc->event = NULL; - event->base.destroy(&event->base); - drm_crtc_vblank_put(&rcrtc->crtc); - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc) { struct drm_pending_vblank_event *event; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 4b95d9d08c49..2bbe3f5aab65 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h @@ -67,8 +67,6 @@ enum rcar_du_output { int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); -void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, - struct drm_file *file); void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 40422f6b645e..0bb2b31555bf 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -220,15 +220,6 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) return ret; } -static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct rcar_du_device *rcdu = dev->dev_private; - unsigned int i; - - for (i = 0; i < rcdu->num_crtcs; ++i) - rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); -} - static void rcar_du_lastclose(struct drm_device *dev) { struct rcar_du_device *rcdu = dev->dev_private; @@ -271,7 +262,6 @@ static struct drm_driver rcar_du_driver = { | DRIVER_ATOMIC, .load = rcar_du_load, .unload = rcar_du_unload, - .preclose = rcar_du_preclose, .lastclose = rcar_du_lastclose, .set_busid = drm_platform_set_busid, .get_vblank_counter = drm_vblank_no_hw_counter, -- GitLab From e37fb79db7b989d08f52ab2b25daa9e3aaa3830f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:52 +0100 Subject: [PATCH 0772/5324] drm/shmob: Nuke preclose hook Again since the drm core takes care of event unlinking/disarming this is now just needless code. v2: Fixup misplaced hunk. Cc: Laurent Pinchart Acked-by: Daniel Stone Reviewed-by: Alex Deucher (v1) Reviewed-by: Laurent Pinchart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-11-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 20 -------------------- drivers/gpu/drm/shmobile/shmob_drm_crtc.h | 2 -- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 8 -------- 3 files changed, 30 deletions(-) diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c index db0763794edc..27342fd76e90 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c @@ -438,26 +438,6 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = { .mode_set_base = shmob_drm_crtc_mode_set_base, }; -void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc, - struct drm_file *file) -{ - struct drm_pending_vblank_event *event; - struct drm_device *dev = scrtc->crtc.dev; - unsigned long flags; - - /* Destroy the pending vertical blanking event associated with the - * pending page flip, if any, and disable vertical blanking interrupts. - */ - spin_lock_irqsave(&dev->event_lock, flags); - event = scrtc->event; - if (event && event->base.file_priv == file) { - scrtc->event = NULL; - event->base.destroy(&event->base); - drm_vblank_put(dev, 0); - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) { struct drm_pending_vblank_event *event; diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h index eddad6dcc88a..38ed4ff8aaf2 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.h +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.h @@ -47,8 +47,6 @@ struct shmob_drm_connector { int shmob_drm_crtc_create(struct shmob_drm_device *sdev); void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev, bool enable); -void shmob_drm_crtc_cancel_page_flip(struct shmob_drm_crtc *scrtc, - struct drm_file *file); void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc); void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc); void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc); diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c index 04e66e3751b4..7700ff172079 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c @@ -200,13 +200,6 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags) return ret; } -static void shmob_drm_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct shmob_drm_device *sdev = dev->dev_private; - - shmob_drm_crtc_cancel_page_flip(&sdev->crtc, file); -} - static irqreturn_t shmob_drm_irq(int irq, void *arg) { struct drm_device *dev = arg; @@ -266,7 +259,6 @@ static struct drm_driver shmob_drm_driver = { | DRIVER_PRIME, .load = shmob_drm_load, .unload = shmob_drm_unload, - .preclose = shmob_drm_preclose, .set_busid = drm_platform_set_busid, .irq_handler = shmob_drm_irq, .get_vblank_counter = drm_vblank_no_hw_counter, -- GitLab From 0417d424ac0db7095c3c43bd06d7d27b6bb97ced Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:53 +0100 Subject: [PATCH 0773/5324] drm/tegra: Stop cancelling page flip events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core takes care of that now. v2: Fixup misplaced hunk. Cc: Thierry Reding Cc: Terje Bergström Acked-by: Daniel Stone Reviewed-by: Alex Deucher Acked-by: Thierry Reding Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-12-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tegra/dc.c | 17 ----------------- drivers/gpu/drm/tegra/drm.c | 3 --- drivers/gpu/drm/tegra/drm.h | 1 - 3 files changed, 21 deletions(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index dde6f208c347..fb2b4b0271a2 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -988,23 +988,6 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) spin_unlock_irqrestore(&drm->event_lock, flags); } -void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) -{ - struct tegra_dc *dc = to_tegra_dc(crtc); - struct drm_device *drm = crtc->dev; - unsigned long flags; - - spin_lock_irqsave(&drm->event_lock, flags); - - if (dc->event && dc->event->base.file_priv == file) { - dc->event->base.destroy(&dc->event->base); - drm_crtc_vblank_put(crtc); - dc->event = NULL; - } - - spin_unlock_irqrestore(&drm->event_lock, flags); -} - static void tegra_dc_destroy(struct drm_crtc *crtc) { drm_crtc_cleanup(crtc); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index c5c856a0879d..021d0e1398fb 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -860,9 +860,6 @@ static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file) struct tegra_drm_context *context, *tmp; struct drm_crtc *crtc; - list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) - tegra_dc_cancel_page_flip(crtc, file); - list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) tegra_drm_context_free(context); diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index c088f2f67eda..8a10f5b7d9dc 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -195,7 +195,6 @@ struct tegra_dc_window { u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc); void tegra_dc_enable_vblank(struct tegra_dc *dc); void tegra_dc_disable_vblank(struct tegra_dc *dc); -void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); void tegra_dc_commit(struct tegra_dc *dc); int tegra_dc_state_setup_clock(struct tegra_dc *dc, struct drm_crtc_state *crtc_state, -- GitLab From b19ac0b05d7229d89d9846a5c2e6725113624702 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:54 +0100 Subject: [PATCH 0774/5324] drm/tilcdc: Nuke preclose hook Again since the drm core takes care of event unlinking/disarming this is now just needless code. v2: Fixup misplaced hunks. Cc: Rob Clark Acked-by: Daniel Stone Reviewed-by: Alex Deucher (v1) Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-13-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 20 -------------------- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 8 -------- drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 - 3 files changed, 29 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 7d07733bdc86..4802da8e6d6f 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -662,26 +662,6 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) return IRQ_HANDLED; } -void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) -{ - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_pending_vblank_event *event; - struct drm_device *dev = crtc->dev; - unsigned long flags; - - /* Destroy the pending vertical blanking event associated with the - * pending page flip, if any, and disable vertical blanking interrupts. - */ - spin_lock_irqsave(&dev->event_lock, flags); - event = tilcdc_crtc->event; - if (event && event->base.file_priv == file) { - tilcdc_crtc->event = NULL; - event->base.destroy(&event->base); - drm_vblank_put(dev, 0); - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) { struct tilcdc_crtc *tilcdc_crtc; diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index d7f5b897c6c5..8190ac3b1b32 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -350,13 +350,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) return ret; } -static void tilcdc_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct tilcdc_drm_private *priv = dev->dev_private; - - tilcdc_crtc_cancel_page_flip(priv->crtc, file); -} - static void tilcdc_lastclose(struct drm_device *dev) { struct tilcdc_drm_private *priv = dev->dev_private; @@ -557,7 +550,6 @@ static struct drm_driver tilcdc_driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, .load = tilcdc_load, .unload = tilcdc_unload, - .preclose = tilcdc_preclose, .lastclose = tilcdc_lastclose, .set_busid = drm_platform_set_busid, .irq_handler = tilcdc_irq, diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index e863ad0d26fe..66105d8dc620 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h @@ -163,7 +163,6 @@ struct tilcdc_panel_info { #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev); -void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc); void tilcdc_crtc_update_clk(struct drm_crtc *crtc); void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, -- GitLab From 32a3dbeb2b951044111042ce6ccb2dcd7bca35de Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:55 +0100 Subject: [PATCH 0775/5324] drm/vc4: Nuke preclose hook Again since the drm core takes care of event unlinking/disarming this is now just needless code. v2: Fixup misplaced hunk. Cc: Eric Anholt Acked-by: Daniel Stone Reviewed-by: Alex Deucher (v1) Acked-by: Eric Anholt Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453756616-28942-14-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vc4/vc4_crtc.c | 20 -------------------- drivers/gpu/drm/vc4/vc4_drv.c | 10 ---------- drivers/gpu/drm/vc4/vc4_drv.h | 1 - 3 files changed, 31 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 018145e0b87d..937409792b97 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -593,26 +593,6 @@ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { .atomic_flush = vc4_crtc_atomic_flush, }; -/* Frees the page flip event when the DRM device is closed with the - * event still outstanding. - */ -void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) -{ - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct drm_device *dev = crtc->dev; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - - if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) { - vc4_crtc->event->base.destroy(&vc4_crtc->event->base); - drm_crtc_vblank_put(crtc); - vc4_crtc->event = NULL; - } - - spin_unlock_irqrestore(&dev->event_lock, flags); -} - static const struct vc4_crtc_data pv0_data = { .hvs_channel = 0, .encoder0_type = VC4_ENCODER_TYPE_DSI0, diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index f1655fff8425..b7d2ff0e6e1f 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -43,14 +43,6 @@ void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index) return map; } -static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - vc4_cancel_page_flip(crtc, file); -} - static void vc4_lastclose(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); @@ -91,8 +83,6 @@ static struct drm_driver vc4_drm_driver = { DRIVER_HAVE_IRQ | DRIVER_PRIME), .lastclose = vc4_lastclose, - .preclose = vc4_drm_preclose, - .irq_handler = vc4_irq, .irq_preinstall = vc4_irq_preinstall, .irq_postinstall = vc4_irq_postinstall, diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 080865ec2bae..4c734d087d7f 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -376,7 +376,6 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); extern struct platform_driver vc4_crtc_driver; int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id); void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id); -void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); /* vc4_debugfs.c */ -- GitLab From 1c0230de6dd096e46c46294e93ba68cc16f70331 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Jan 2016 22:16:56 +0100 Subject: [PATCH 0776/5324] drm/vmwgfx: Nuke preclose hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Again since the drm core takes care of event unlinking/disarming this is now just needless code. v2: I've completely missed eaction->fpriv_head and all the related code. We need to nuke that too to avoid accidentally deferencing the freed-up vmwgfx-private fpriv. v3: Also remove vmw_fpriv->fence_events and unused variables I missed. Cc: Thomas Hellström Acked-by: Daniel Stone Reviewed-by: Alex Deucher Reviewed-by: Thomas Hellstrom Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-23-git-send-email-daniel.vetter@ffwll.ch Signed-off-by: Daniel Vetter --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 11 ------ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 52 --------------------------- drivers/gpu/drm/vmwgfx/vmwgfx_fence.h | 2 -- 4 files changed, 66 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index c49812b80dd0..c96a2d2d5107 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -971,15 +971,6 @@ static int vmw_driver_unload(struct drm_device *dev) return 0; } -static void vmw_preclose(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); - struct vmw_private *dev_priv = vmw_priv(dev); - - vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events); -} - static void vmw_postclose(struct drm_device *dev, struct drm_file *file_priv) { @@ -1010,7 +1001,6 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) if (unlikely(vmw_fp == NULL)) return ret; - INIT_LIST_HEAD(&vmw_fp->fence_events); vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); if (unlikely(vmw_fp->tfile == NULL)) goto out_no_tfile; @@ -1500,7 +1490,6 @@ static struct drm_driver driver = { .master_set = vmw_master_set, .master_drop = vmw_master_drop, .open = vmw_driver_open, - .preclose = vmw_preclose, .postclose = vmw_postclose, .set_busid = drm_pci_set_busid, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 469cdd520615..5cb1b1687cd4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -80,7 +80,6 @@ struct vmw_fpriv { struct drm_master *locked_master; struct ttm_object_file *tfile; - struct list_head fence_events; bool gb_aware; }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 37c305b62608..e959df6ede83 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -71,7 +71,6 @@ struct vmw_user_fence { */ struct vmw_event_fence_action { struct vmw_fence_action action; - struct list_head fpriv_head; struct drm_pending_event *event; struct vmw_fence_obj *fence; @@ -807,44 +806,6 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data, TTM_REF_USAGE); } -/** - * vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects - * - * @fman: Pointer to a struct vmw_fence_manager - * @event_list: Pointer to linked list of struct vmw_event_fence_action objects - * with pointers to a struct drm_file object about to be closed. - * - * This function removes all pending fence events with references to a - * specific struct drm_file object about to be closed. The caller is required - * to pass a list of all struct vmw_event_fence_action objects with such - * events attached. This function is typically called before the - * struct drm_file object's event management is taken down. - */ -void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman, - struct list_head *event_list) -{ - struct vmw_event_fence_action *eaction; - struct drm_pending_event *event; - unsigned long irq_flags; - - while (1) { - spin_lock_irqsave(&fman->lock, irq_flags); - if (list_empty(event_list)) - goto out_unlock; - eaction = list_first_entry(event_list, - struct vmw_event_fence_action, - fpriv_head); - list_del_init(&eaction->fpriv_head); - event = eaction->event; - eaction->event = NULL; - spin_unlock_irqrestore(&fman->lock, irq_flags); - event->destroy(event); - } -out_unlock: - spin_unlock_irqrestore(&fman->lock, irq_flags); -} - - /** * vmw_event_fence_action_seq_passed * @@ -879,7 +840,6 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) *eaction->tv_usec = tv.tv_usec; } - list_del_init(&eaction->fpriv_head); drm_send_event_locked(dev, eaction->event); eaction->event = NULL; spin_unlock_irqrestore(&dev->event_lock, irq_flags); @@ -898,12 +858,6 @@ static void vmw_event_fence_action_cleanup(struct vmw_fence_action *action) { struct vmw_event_fence_action *eaction = container_of(action, struct vmw_event_fence_action, action); - struct vmw_fence_manager *fman = fman_from_fence(eaction->fence); - unsigned long irq_flags; - - spin_lock_irqsave(&fman->lock, irq_flags); - list_del(&eaction->fpriv_head); - spin_unlock_irqrestore(&fman->lock, irq_flags); vmw_fence_obj_unreference(&eaction->fence); kfree(eaction); @@ -983,8 +937,6 @@ int vmw_event_fence_action_queue(struct drm_file *file_priv, { struct vmw_event_fence_action *eaction; struct vmw_fence_manager *fman = fman_from_fence(fence); - struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); - unsigned long irq_flags; eaction = kzalloc(sizeof(*eaction), GFP_KERNEL); if (unlikely(eaction == NULL)) @@ -1001,10 +953,6 @@ int vmw_event_fence_action_queue(struct drm_file *file_priv, eaction->tv_sec = tv_sec; eaction->tv_usec = tv_usec; - spin_lock_irqsave(&fman->lock, irq_flags); - list_add_tail(&eaction->fpriv_head, &vmw_fp->fence_events); - spin_unlock_irqrestore(&fman->lock, irq_flags); - vmw_fence_obj_add_action(fence, &eaction->action); return 0; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h index 8be6c29f5eb5..83ae301ee141 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h @@ -116,8 +116,6 @@ extern int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman, - struct list_head *event_list); extern int vmw_event_fence_action_queue(struct drm_file *filee_priv, struct vmw_fence_obj *fence, struct drm_pending_event *event, -- GitLab From db9b60400f9253c25ae639797df2d0ff7a35d9d8 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 2 Feb 2016 11:35:55 +0530 Subject: [PATCH 0777/5324] drm/gma500: remove helper function We were getting build warning about: drivers/gpu/drm/gma500/mdfld_dsi_output.c:407:2: warning: initialization from incompatible pointer type The callback to dpms was pointing to a helper function which had a return type of void, whereas the callback should point to a function which has a return type of int. On closer look it turned out that we do not need the helper function since if we call drm_helper_connector_dpms() directly, the first check that drm_helper_connector_dpms() does is: if (mode == connector->dpms) Signed-off-by: Sudip Mukherjee Link: http://patchwork.freedesktop.org/patch/msgid/1454393155-13142-1-git-send-email-sudipm.mukherjee@gmail.com Acked-by: Patrik Jakobsson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/gma500/mdfld_dsi_output.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c index d758f4cc6805..907cb51795c3 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c @@ -382,16 +382,6 @@ static int mdfld_dsi_connector_mode_valid(struct drm_connector *connector, return MODE_OK; } -static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) -{ - if (mode == connector->dpms) - return; - - /*first, execute dpms*/ - - drm_helper_connector_dpms(connector, mode); -} - static struct drm_encoder *mdfld_dsi_connector_best_encoder( struct drm_connector *connector) { @@ -404,7 +394,7 @@ static struct drm_encoder *mdfld_dsi_connector_best_encoder( /*DSI connector funcs*/ static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { - .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms, + .dpms = drm_helper_connector_dpms, .detect = mdfld_dsi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .set_property = mdfld_dsi_connector_set_property, -- GitLab From 13619ce570ee57bb509394b896b21eba41fa4392 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 29 Jan 2016 19:37:48 +0000 Subject: [PATCH 0778/5324] gma500: clean up an excessive and confusing helper This is a left over from the great clean ups in the past. It's confusing as it returns an int, yet has one caller that never uses it. The caller already has all the right private variables local so the entire function can be replaced by a simple if call. Signed-off-by: Alan Cox Link: http://patchwork.freedesktop.org/patch/msgid/20160129193731.8475.47809.stgit@localhost.localdomain Acked-by: Patrik Jakobsson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/gma500/framebuffer.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index ee95c03a8c54..f93654076af0 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -672,29 +672,17 @@ static const struct drm_mode_config_funcs psb_mode_funcs = { .output_poll_changed = psbfb_output_poll_changed, }; -static int psb_create_backlight_property(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_property *backlight; - - if (dev_priv->backlight_property) - return 0; - - backlight = drm_property_create_range(dev, 0, "backlight", 0, 100); - - dev_priv->backlight_property = backlight; - - return 0; -} - static void psb_setup_outputs(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct drm_connector *connector; drm_mode_create_scaling_mode_property(dev); - psb_create_backlight_property(dev); + /* It is ok for this to fail - we just don't get backlight control */ + if (!dev_priv->backlight_property) + dev_priv->backlight_property = drm_property_create_range(dev, 0, + "backlight", 0, 100); dev_priv->ops->output_init(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, -- GitLab From 3d0cd46889e0a57ce63dba1f34156b54dfdf0ad2 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Sat, 16 Jan 2016 15:13:56 +0100 Subject: [PATCH 0779/5324] arm64: dts: r8a7795: pmu: switch to Cortex specific device nodes Instead of using the generic armv8-pmuv3 compatibility use the more specific Cortex A57 compatibility. Signed-off-by: Dirk Behme Signed-off-by: Simon Horman --- arch/arm64/boot/dts/renesas/r8a7795.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index 3f00e85641a8..b5e46e4ff72a 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -246,8 +246,8 @@ power-domains = <&cpg>; }; - pmu { - compatible = "arm,armv8-pmuv3"; + pmu_a57 { + compatible = "arm,cortex-a57-pmu"; interrupts = , , , -- GitLab From 2de50e9674fc4ca3c6174b04477f69eb26b4ee31 Mon Sep 17 00:00:00 2001 From: Russell Currey Date: Mon, 8 Feb 2016 15:08:20 +1100 Subject: [PATCH 0780/5324] powerpc/powernv: Remove support for p5ioc2 "p5ioc2 is used by approximately 2 machines in the world, and has never ever been a supported configuration." The code for p5ioc2 is essentially unused and complicates what is already a very complicated codebase. Its removal is essentially a "free win" in the effort to simplify the powernv PCI code. In addition, support for p5ioc2 has been dropped from skiboot. There's no reason to keep it around in the kernel. Signed-off-by: Russell Currey Acked-by: Gavin Shan Acked-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/pci-p5ioc2.c | 271 -------------------- arch/powerpc/platforms/powernv/pci.c | 17 +- arch/powerpc/platforms/powernv/pci.h | 152 +++++------ 4 files changed, 74 insertions(+), 368 deletions(-) delete mode 100644 arch/powerpc/platforms/powernv/pci-p5ioc2.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index f1516b5ecec9..cd9711e72df6 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o obj-y += opal-kmsg.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o -obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o +obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o obj-$(CONFIG_EEH) += eeh-powernv.o obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c deleted file mode 100644 index f2bdfea3b68d..000000000000 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Support PCI/PCIe on PowerNV platforms - * - * Currently supports only P5IOC2 - * - * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "powernv.h" -#include "pci.h" - -/* For now, use a fixed amount of TCE memory for each p5ioc2 - * hub, 16M will do - */ -#define P5IOC2_TCE_MEMORY 0x01000000 - -#ifdef CONFIG_PCI_MSI -static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int virq, - unsigned int is_64, struct msi_msg *msg) -{ - if (WARN_ON(!is_64)) - return -ENXIO; - msg->data = hwirq - phb->msi_base; - msg->address_hi = 0x10000000; - msg->address_lo = 0; - - return 0; -} - -static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) -{ - unsigned int count; - const __be32 *prop = of_get_property(phb->hose->dn, - "ibm,opal-msi-ranges", NULL); - if (!prop) - return; - - /* Don't do MSI's on p5ioc2 PCI-X are they are not properly - * verified in HW - */ - if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) - return; - phb->msi_base = be32_to_cpup(prop); - count = be32_to_cpup(prop + 1); - if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) { - pr_err("PCI %d: Failed to allocate MSI bitmap !\n", - phb->hose->global_number); - return; - } - phb->msi_setup = pnv_pci_p5ioc2_msi_setup; - phb->msi32_support = 0; - pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", - count, phb->msi_base); -} -#else -static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } -#endif /* CONFIG_PCI_MSI */ - -static struct iommu_table_ops pnv_p5ioc2_iommu_ops = { - .set = pnv_tce_build, -#ifdef CONFIG_IOMMU_API - .exchange = pnv_tce_xchg, -#endif - .clear = pnv_tce_free, - .get = pnv_tce_get, -}; - -static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb, - struct pci_dev *pdev) -{ - struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0]; - - if (!tbl->it_map) { - tbl->it_ops = &pnv_p5ioc2_iommu_ops; - iommu_init_table(tbl, phb->hose->node); - iommu_register_group(&phb->p5ioc2.table_group, - pci_domain_nr(phb->hose->bus), phb->opal_id); - INIT_LIST_HEAD_RCU(&tbl->it_group_list); - pnv_pci_link_table_and_group(phb->hose->node, 0, - tbl, &phb->p5ioc2.table_group); - } - - set_iommu_table_base(&pdev->dev, tbl); - iommu_add_device(&pdev->dev); -} - -static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = { - .dma_dev_setup = pnv_pci_dma_dev_setup, -#ifdef CONFIG_PCI_MSI - .setup_msi_irqs = pnv_setup_msi_irqs, - .teardown_msi_irqs = pnv_teardown_msi_irqs, -#endif -}; - -static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, - void *tce_mem, u64 tce_size) -{ - struct pnv_phb *phb; - const __be64 *prop64; - u64 phb_id; - int64_t rc; - static int primary = 1; - struct iommu_table_group *table_group; - struct iommu_table *tbl; - - pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); - - prop64 = of_get_property(np, "ibm,opal-phbid", NULL); - if (!prop64) { - pr_err(" Missing \"ibm,opal-phbid\" property !\n"); - return; - } - phb_id = be64_to_cpup(prop64); - pr_devel(" PHB-ID : 0x%016llx\n", phb_id); - pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); - pr_devel(" TCE SZ : 0x%016llx\n", tce_size); - - rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); - if (rc != OPAL_SUCCESS) { - pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); - return; - } - - phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); - phb->hose = pcibios_alloc_controller(np); - if (!phb->hose) { - pr_err(" Failed to allocate PCI controller\n"); - return; - } - - spin_lock_init(&phb->lock); - phb->hose->first_busno = 0; - phb->hose->last_busno = 0xff; - phb->hose->private_data = phb; - phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops; - phb->hub_id = hub_id; - phb->opal_id = phb_id; - phb->type = PNV_PHB_P5IOC2; - phb->model = PNV_PHB_MODEL_P5IOC2; - - phb->regs = of_iomap(np, 0); - - if (phb->regs == NULL) - pr_err(" Failed to map registers !\n"); - else { - pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); - pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); - pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); - pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); - pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); - pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); - pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); - pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); - pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); - pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); - pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); - } - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(phb->hose, np, primary); - primary = 0; - - phb->hose->ops = &pnv_pci_ops; - - /* Setup MSI support */ - pnv_pci_init_p5ioc2_msis(phb); - - /* Setup TCEs */ - phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; - pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, - tce_mem, tce_size, 0, - IOMMU_PAGE_SHIFT_4K); - /* - * We do not allocate iommu_table as we do not support - * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table() - * should not be called for phb->p5ioc2.table_group.tables[0] ever. - */ - tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table; - table_group = &phb->p5ioc2.table_group; - table_group->tce32_start = tbl->it_offset << tbl->it_page_shift; - table_group->tce32_size = tbl->it_size << tbl->it_page_shift; -} - -void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) -{ - struct device_node *phbn; - const __be64 *prop64; - u64 hub_id; - void *tce_mem; - uint64_t tce_per_phb; - int64_t rc; - int phb_count = 0; - - pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name); - - prop64 = of_get_property(np, "ibm,opal-hubid", NULL); - if (!prop64) { - pr_err(" Missing \"ibm,opal-hubid\" property !\n"); - return; - } - hub_id = be64_to_cpup(prop64); - pr_info(" HUB-ID : 0x%016llx\n", hub_id); - - /* Count child PHBs and calculate TCE space per PHB */ - for_each_child_of_node(np, phbn) { - if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || - of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) - phb_count++; - } - - if (phb_count <= 0) { - pr_info(" No PHBs for Hub %s\n", np->full_name); - return; - } - - tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); - pr_info(" Allocating %lld MB of TCE memory per PHB\n", - tce_per_phb >> 20); - - /* Currently allocate 16M of TCE memory for every Hub - * - * XXX TODO: Make it chip local if possible - */ - tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY); - pr_debug(" TCE : 0x%016lx..0x%016lx\n", - __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); - rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), - P5IOC2_TCE_MEMORY); - if (rc != OPAL_SUCCESS) { - pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc); - return; - } - - /* Initialize PHBs */ - for_each_child_of_node(np, phbn) { - if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || - of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) { - pnv_pci_init_p5ioc2_phb(phbn, hub_id, - tce_mem, tce_per_phb); - tce_mem += tce_per_phb; - } - } -} diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 2f55c86df703..8de0140332b2 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -380,10 +380,7 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn) */ pe_no = pdn->pe_number; if (pe_no == IODA_INVALID_PE) { - if (phb->type == PNV_PHB_P5IOC2) - pe_no = 0; - else - pe_no = phb->ioda.reserved_pe; + pe_no = phb->ioda.reserved_pe; } /* @@ -779,7 +776,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); void __init pnv_pci_init(void) { struct device_node *np; - bool found_ioda = false; pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); @@ -787,20 +783,11 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; - /* Look for IODA IO-Hubs. We don't support mixing IODA - * and p5ioc2 due to the need to change some global - * probing flags - */ + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); - found_ioda = true; } - /* Look for p5ioc2 IO-Hubs */ - if (!found_ioda) - for_each_compatible_node(np, NULL, "ibm,p5ioc2") - pnv_pci_init_p5ioc2_hub(np); - /* Look for ioda2 built-in PHB3's */ for_each_compatible_node(np, NULL, "ibm,ioda2-phb") pnv_pci_init_ioda2_phb(np); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 7f56313e8d72..32cae3d8e011 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -4,16 +4,14 @@ struct pci_dn; enum pnv_phb_type { - PNV_PHB_P5IOC2 = 0, - PNV_PHB_IODA1 = 1, - PNV_PHB_IODA2 = 2, - PNV_PHB_NPU = 3, + PNV_PHB_IODA1 = 0, + PNV_PHB_IODA2 = 1, + PNV_PHB_NPU = 2, }; /* Precise PHB model for error management */ enum pnv_phb_model { PNV_PHB_MODEL_UNKNOWN, - PNV_PHB_MODEL_P5IOC2, PNV_PHB_MODEL_P7IOC, PNV_PHB_MODEL_PHB3, PNV_PHB_MODEL_NPU, @@ -121,81 +119,74 @@ struct pnv_phb { void (*freeze_pe)(struct pnv_phb *phb, int pe_no); int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); - union { - struct { - struct iommu_table iommu_table; - struct iommu_table_group table_group; - } p5ioc2; - - struct { - /* Global bridge info */ - unsigned int total_pe; - unsigned int reserved_pe; - - /* 32-bit MMIO window */ - unsigned int m32_size; - unsigned int m32_segsize; - unsigned int m32_pci_base; - - /* 64-bit MMIO window */ - unsigned int m64_bar_idx; - unsigned long m64_size; - unsigned long m64_segsize; - unsigned long m64_base; - unsigned long m64_bar_alloc; - - /* IO ports */ - unsigned int io_size; - unsigned int io_segsize; - unsigned int io_pci_base; - - /* PE allocation bitmap */ - unsigned long *pe_alloc; - /* PE allocation mutex */ - struct mutex pe_alloc_mutex; - - /* M32 & IO segment maps */ - unsigned int *m32_segmap; - unsigned int *io_segmap; - struct pnv_ioda_pe *pe_array; - - /* IRQ chip */ - int irq_chip_init; - struct irq_chip irq_chip; - - /* Sorted list of used PE's based - * on the sequence of creation - */ - struct list_head pe_list; - struct mutex pe_list_mutex; - - /* Reverse map of PEs, will have to extend if - * we are to support more than 256 PEs, indexed - * bus { bus, devfn } - */ - unsigned char pe_rmap[0x10000]; - - /* 32-bit TCE tables allocation */ - unsigned long tce32_count; - - /* Total "weight" for the sake of DMA resources - * allocation - */ - unsigned int dma_weight; - unsigned int dma_pe_count; - - /* Sorted list of used PE's, sorted at - * boot for resource allocation purposes - */ - struct list_head pe_dma_list; - - /* TCE cache invalidate registers (physical and - * remapped) - */ - phys_addr_t tce_inval_reg_phys; - __be64 __iomem *tce_inval_reg; - } ioda; - }; + struct { + /* Global bridge info */ + unsigned int total_pe; + unsigned int reserved_pe; + + /* 32-bit MMIO window */ + unsigned int m32_size; + unsigned int m32_segsize; + unsigned int m32_pci_base; + + /* 64-bit MMIO window */ + unsigned int m64_bar_idx; + unsigned long m64_size; + unsigned long m64_segsize; + unsigned long m64_base; + unsigned long m64_bar_alloc; + + /* IO ports */ + unsigned int io_size; + unsigned int io_segsize; + unsigned int io_pci_base; + + /* PE allocation bitmap */ + unsigned long *pe_alloc; + /* PE allocation mutex */ + struct mutex pe_alloc_mutex; + + /* M32 & IO segment maps */ + unsigned int *m32_segmap; + unsigned int *io_segmap; + struct pnv_ioda_pe *pe_array; + + /* IRQ chip */ + int irq_chip_init; + struct irq_chip irq_chip; + + /* Sorted list of used PE's based + * on the sequence of creation + */ + struct list_head pe_list; + struct mutex pe_list_mutex; + + /* Reverse map of PEs, will have to extend if + * we are to support more than 256 PEs, indexed + * bus { bus, devfn } + */ + unsigned char pe_rmap[0x10000]; + + /* 32-bit TCE tables allocation */ + unsigned long tce32_count; + + /* Total "weight" for the sake of DMA resources + * allocation + */ + unsigned int dma_weight; + unsigned int dma_pe_count; + + /* Sorted list of used PE's, sorted at + * boot for resource allocation purposes + */ + struct list_head pe_dma_list; + + /* TCE cache invalidate registers (physical and + * remapped) + */ + phys_addr_t tce_inval_reg_phys; + __be64 __iomem *tce_inval_reg; + } ioda; /* PHB and hub status structure */ union { @@ -232,7 +223,6 @@ extern void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, void *tce_mem, u64 tce_size, u64 dma_offset, unsigned page_shift); -extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); extern void pnv_pci_init_ioda_hub(struct device_node *np); extern void pnv_pci_init_ioda2_phb(struct device_node *np); extern void pnv_pci_init_npu_phb(struct device_node *np); -- GitLab From 2e34057929cad8a90b775581216886d22b642e0a Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Wed, 27 Jan 2016 11:29:44 +1100 Subject: [PATCH 0781/5324] powerpc/xmon: fix typo in usage message Signed-off-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 07a8508cb7fa..d5c8a156f63c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -233,7 +233,7 @@ Commands:\n\ " S print special registers\n\ t print backtrace\n\ x exit monitor and recover\n\ - X exit monitor and dont recover\n" + X exit monitor and don't recover\n" #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) " u dump segment table or SLB\n" #elif defined(CONFIG_PPC_STD_MMU_32) -- GitLab From 31f6a4ada14de04ee6cd7ff03c8b6b5e282a13f0 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Mon, 8 Feb 2016 14:39:19 +1100 Subject: [PATCH 0782/5324] powerpc/eeh: fix incorrect function name in comment The comment block above pcibios_set_pcie_reset_state() incorrectly refers to pcibios_set_pcie_slot_reset(). Fix the comment accordingly. Signed-off-by: Andrew Donnellan Acked-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/eeh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 40e4d4a27663..8c6005cf1583 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -739,7 +739,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata) } /** - * pcibios_set_pcie_slot_reset - Set PCI-E reset state + * pcibios_set_pcie_reset_state - Set PCI-E reset state * @dev: pci device struct * @state: reset state to enter * -- GitLab From db168f117779b23097487548b4f4999b0a66835c Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 3 Feb 2016 16:53:23 +0100 Subject: [PATCH 0783/5324] drm/i915: Remove intel_crtc->atomic.disable_ips. This is a revert of commit 066cf55b9ce3 "drm/i915: Fix IPS related flicker". intel_pre_disable_primary already handles this, and now everything goes through the atomic path there's no need to try to disable ips twice. Signed-off-by: Maarten Lankhorst Reviewed-by: Ander Conselvan de Oliveira Link: http://patchwork.freedesktop.org/patch/msgid/1454514805-10595-2-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 15 --------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 186d6cadba84..4760ecb6ae06 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4815,9 +4815,6 @@ static void intel_pre_plane_update(struct intel_crtc *crtc) if (atomic->update_fbc) intel_fbc_pre_update(crtc); - if (crtc->atomic.disable_ips) - hsw_disable_ips(crtc); - if (atomic->pre_disable_primary) intel_pre_disable_primary(&crtc->base); @@ -11889,18 +11886,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, intel_crtc->atomic.post_enable_primary = turn_on; intel_crtc->atomic.update_fbc = true; - if (turn_off) { - /* - * FIXME: Actually if we will still have any other - * plane enabled on the pipe we could let IPS enabled - * still, but for now lets consider that when we make - * primary invisible by setting DSPCNTR to 0 on - * update_primary_plane function IPS needs to be - * disable. - */ - intel_crtc->atomic.disable_ips = true; - } - /* * BDW signals flip done immediately if the plane * is disabled, even if the plane enable is already diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1251a7ae4a6a..5fd3e13936e4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -544,7 +544,6 @@ struct intel_mmio_flip { */ struct intel_crtc_atomic_commit { /* Sleepable operations to perform before commit */ - bool disable_ips; bool pre_disable_primary; /* Sleepable operations to perform after commit */ -- GitLab From 5c74cd730807a6f0c4a2066bdb92c2b6fc3e5775 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 3 Feb 2016 16:53:24 +0100 Subject: [PATCH 0784/5324] drm/i915: Remove atomic.pre_disable_primary. This can be derived from the atomic state in pre_plane_update, which makes it more clear when it's supposed to be called. Reviewed-by: Ander Conselvan de Oliveira Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1454514805-10595-3-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 1 - 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4760ecb6ae06..a7fa627f4c05 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4804,19 +4804,33 @@ static void intel_post_plane_update(struct intel_crtc *crtc) memset(atomic, 0, sizeof(*atomic)); } -static void intel_pre_plane_update(struct intel_crtc *crtc) +static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) { + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); + struct drm_atomic_state *old_state = old_crtc_state->base.state; + struct drm_plane *primary = crtc->base.primary; + struct drm_plane_state *old_pri_state = + drm_atomic_get_existing_plane_state(old_state, primary); + bool modeset = needs_modeset(&pipe_config->base); if (atomic->update_fbc) intel_fbc_pre_update(crtc); - if (atomic->pre_disable_primary) - intel_pre_disable_primary(&crtc->base); + if (old_pri_state) { + struct intel_plane_state *primary_state = + to_intel_plane_state(primary->state); + struct intel_plane_state *old_primary_state = + to_intel_plane_state(old_pri_state); + + if (old_primary_state->visible && + (modeset || !primary_state->visible)) + intel_pre_disable_primary(&crtc->base); + } if (pipe_config->disable_cxsr) { crtc->wm.cxsr_allowed = false; @@ -11882,7 +11896,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: - intel_crtc->atomic.pre_disable_primary = turn_off; intel_crtc->atomic.post_enable_primary = turn_on; intel_crtc->atomic.update_fbc = true; @@ -13494,7 +13507,7 @@ static int intel_atomic_commit(struct drm_device *dev, if (!needs_modeset(crtc->state)) continue; - intel_pre_plane_update(intel_crtc); + intel_pre_plane_update(to_intel_crtc_state(crtc_state)); if (crtc_state->active) { intel_crtc_disable_planes(crtc, crtc_state->plane_mask); @@ -13550,7 +13563,7 @@ static int intel_atomic_commit(struct drm_device *dev, } if (!modeset) - intel_pre_plane_update(intel_crtc); + intel_pre_plane_update(to_intel_crtc_state(crtc_state)); if (crtc->state->active && intel_crtc->atomic.update_fbc) intel_fbc_enable(intel_crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5fd3e13936e4..d0921ba9a65a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -544,7 +544,6 @@ struct intel_mmio_flip { */ struct intel_crtc_atomic_commit { /* Sleepable operations to perform before commit */ - bool pre_disable_primary; /* Sleepable operations to perform after commit */ unsigned fb_bits; -- GitLab From 2dfd178dc05164d6d730f4b3649accc1ee1ee585 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 3 Feb 2016 16:53:25 +0100 Subject: [PATCH 0785/5324] drm/i915: Do not disable cxsr when crtc is disabled. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's safe to assume cxsr is already disabled when the crtc is off. This prevents an unclaimed register warning when the required power wells are not enabled. [ 262.864984] ------------[ cut here ]------------ [ 262.865025] WARNING: CPU: 1 PID: 6799 at drivers/gpu/drm/i915/intel_uncore.c:638 __unclaimed_reg_debug+0x68/0x80 [i915]() [ 262.865029] Unclaimed register detected before reading register 0x186500 [ 262.865032] Modules linked in: i915 intel_powerclamp [ 262.865057] CPU: 1 PID: 6799 Comm: kms_pipe_crc_ba Tainted: G U W 4.4.0-gfxbench+ #1 [ 262.865060] Hardware name: DN2820FYK, BIOS FYBYT10H.86A.0038.2014.0717.1455 07/17/2014 [ 262.865064] ffffffffa0338cf8 ffff88007448ba78 ffffffff813df90c ffff88007448bac0 [ 262.865071] ffff88007448bab0 ffffffff810746e1 0000000000186500 0000000000000001 [ 262.865077] 0000000000000001 ffff880074420000 0000000000000000 ffff88007448bb10 [ 262.865083] Call Trace: [ 262.865092] [] dump_stack+0x4e/0x82 [ 262.865098] [] warn_slowpath_common+0x81/0xc0 [ 262.865102] [] warn_slowpath_fmt+0x47/0x50 [ 262.865128] [] __unclaimed_reg_debug+0x68/0x80 [i915] [ 262.865154] [] vlv_read32+0x2de/0x370 [i915] [ 262.865173] [] intel_set_memory_cxsr+0x87/0x1a0 [i915] [ 262.865200] [] intel_pre_plane_update+0xb3/0xf0 [i915] [ 262.865228] [] intel_atomic_commit+0x3b5/0x17c0 [i915] [ 262.865234] [] ? drm_atomic_check_only+0x145/0x660 [ 262.865239] [] ? drm_atomic_set_crtc_for_connector+0x6a/0xe0 [ 262.865243] [] drm_atomic_commit+0x32/0x50 [ 262.865249] [] drm_atomic_helper_set_config+0x75/0xb0 [ 262.865253] [] drm_mode_set_config_internal+0x60/0x110 [ 262.865258] [] drm_mode_setcrtc+0x186/0x4f0 [ 262.865263] [] drm_ioctl+0x13d/0x590 [ 262.865267] [] ? drm_mode_setplane+0x1b0/0x1b0 [ 262.865273] [] do_vfs_ioctl+0x2fc/0x550 [ 262.865278] [] ? vm_munmap+0x4a/0x60 [ 262.865283] [] ? __fget_light+0x6a/0x90 [ 262.865287] [] SyS_ioctl+0x3c/0x70 [ 262.865292] [] entry_SYSCALL_64_fastpath+0x16/0x73 [ 262.865296] ---[ end trace 6387a0ad001bb39f ]--- Testcase: kms_flip.basic-flip-vs-wf_vblank Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93698 Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1454514805-10595-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a7fa627f4c05..5bc9a364b04a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4834,7 +4834,9 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) if (pipe_config->disable_cxsr) { crtc->wm.cxsr_allowed = false; - intel_set_memory_cxsr(dev_priv, false); + + if (old_crtc_state->base.active) + intel_set_memory_cxsr(dev_priv, false); } if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed) -- GitLab From 7157bb27e79875db5603aa1e30f56e873a8300f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Winiarski?= Date: Fri, 5 Feb 2016 13:21:42 +0100 Subject: [PATCH 0786/5324] drm/i915/skl: Add missing SKL ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Used by production devices: Intel(R) Iris Graphics 540 (Skylake GT3e) Intel(R) Iris Graphics 550 (Skylake GT3e) v2: More ids v3: Less ids (GT1 got duplicated) Cc: Mika Kuoppala Signed-off-by: Michał Winiarski Reviewed-by: Mika Kuoppala Signed-off-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1454674902-26207-1-git-send-email-michal.winiarski@intel.com --- include/drm/i915_pciids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 9b48ac1d8543..9094599a1150 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -277,7 +277,9 @@ INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ #define INTEL_SKL_GT3_IDS(info) \ + INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ -- GitLab From 2c92c04b6f1f06c3e9752abb02e62b6ee188109d Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 28 Dec 2015 14:39:20 +0100 Subject: [PATCH 0787/5324] memory: omap-gpmc: Add support for AAD timings In order to support extended timings parameters on hardware supporting the "AAD" mode like the AM335x or DM816x, add these entries into the GPMC driver if the hardware is capable. Tested on DM816x and AM335x. Signed-off-by: Neil Armstrong Acked-by: Tony Lindgren Signed-off-by: Roger Quadros --- drivers/memory/omap-gpmc.c | 30 ++++++++++++++++++++++++++++++ include/linux/omap-gpmc.h | 5 +++++ 2 files changed, 35 insertions(+) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 6515dfc2b805..21825ddce4a3 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -541,9 +541,20 @@ static void gpmc_cs_show_timings(int cs, const char *desc) GPMC_GET_TICKS(GPMC_CS_CONFIG3, 0, 3, "adv-on-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG3, 8, 12, "adv-rd-off-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG3, 16, 20, "adv-wr-off-ns"); + if (gpmc_capability & GPMC_HAS_MUX_AAD) { + GPMC_GET_TICKS(GPMC_CS_CONFIG3, 4, 6, "adv-aad-mux-on-ns"); + GPMC_GET_TICKS(GPMC_CS_CONFIG3, 24, 26, + "adv-aad-mux-rd-off-ns"); + GPMC_GET_TICKS(GPMC_CS_CONFIG3, 28, 30, + "adv-aad-mux-wr-off-ns"); + } GPMC_GET_TICKS(GPMC_CS_CONFIG4, 0, 3, "oe-on-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG4, 8, 12, "oe-off-ns"); + if (gpmc_capability & GPMC_HAS_MUX_AAD) { + GPMC_GET_TICKS(GPMC_CS_CONFIG4, 4, 6, "oe-aad-mux-on-ns"); + GPMC_GET_TICKS(GPMC_CS_CONFIG4, 13, 15, "oe-aad-mux-off-ns"); + } GPMC_GET_TICKS(GPMC_CS_CONFIG4, 16, 19, "we-on-ns"); GPMC_GET_TICKS(GPMC_CS_CONFIG4, 24, 28, "we-off-ns"); @@ -734,9 +745,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t, GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on); GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off); GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off); + if (gpmc_capability & GPMC_HAS_MUX_AAD) { + GPMC_SET_ONE(GPMC_CS_CONFIG3, 4, 6, adv_aad_mux_on); + GPMC_SET_ONE(GPMC_CS_CONFIG3, 24, 26, adv_aad_mux_rd_off); + GPMC_SET_ONE(GPMC_CS_CONFIG3, 28, 30, adv_aad_mux_wr_off); + } GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on); GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off); + if (gpmc_capability & GPMC_HAS_MUX_AAD) { + GPMC_SET_ONE(GPMC_CS_CONFIG4, 4, 6, oe_aad_mux_on); + GPMC_SET_ONE(GPMC_CS_CONFIG4, 13, 15, oe_aad_mux_off); + } GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on); GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off); @@ -1722,6 +1742,12 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); + of_property_read_u32(np, "gpmc,adv-aad-mux-on-ns", + &gpmc_t->adv_aad_mux_on); + of_property_read_u32(np, "gpmc,adv-aad-mux-rd-off-ns", + &gpmc_t->adv_aad_mux_rd_off); + of_property_read_u32(np, "gpmc,adv-aad-mux-wr-off-ns", + &gpmc_t->adv_aad_mux_wr_off); /* WE signal timings */ of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); @@ -1730,6 +1756,10 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, /* OE signal timings */ of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); + of_property_read_u32(np, "gpmc,oe-aad-mux-on-ns", + &gpmc_t->oe_aad_mux_on); + of_property_read_u32(np, "gpmc,oe-aad-mux-off-ns", + &gpmc_t->oe_aad_mux_off); /* access and cycle timings */ of_property_read_u32(np, "gpmc,page-burst-access-ns", diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h index 7dee00143afd..d833eb4dd446 100644 --- a/include/linux/omap-gpmc.h +++ b/include/linux/omap-gpmc.h @@ -51,6 +51,9 @@ struct gpmc_timings { u32 adv_on; /* Assertion time */ u32 adv_rd_off; /* Read deassertion time */ u32 adv_wr_off; /* Write deassertion time */ + u32 adv_aad_mux_on; /* ADV assertion time for AAD */ + u32 adv_aad_mux_rd_off; /* ADV read deassertion time for AAD */ + u32 adv_aad_mux_wr_off; /* ADV write deassertion time for AAD */ /* WE signals timings corresponding to GPMC_CONFIG4 */ u32 we_on; /* WE assertion time */ @@ -59,6 +62,8 @@ struct gpmc_timings { /* OE signals timings corresponding to GPMC_CONFIG4 */ u32 oe_on; /* OE assertion time */ u32 oe_off; /* OE deassertion time */ + u32 oe_aad_mux_on; /* OE assertion time for AAD */ + u32 oe_aad_mux_off; /* OE deassertion time for AAD */ /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */ u32 page_burst_access; /* Multiple access word delay */ -- GitLab From e116c0545d17be6cc95a559aa5a68c221330501b Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 28 Dec 2015 14:39:21 +0100 Subject: [PATCH 0788/5324] dt-bindings: bus: ti-gpmc: Add AAD timings properties In order to support advanced AAD timings, add these properties to the DT GPMC bindings. Signed-off-by: Neil Armstrong Acked-by: Tony Lindgren Acked-by: Rob Herring Signed-off-by: Roger Quadros --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 704be9306c9f..01683707060b 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -46,6 +46,9 @@ Timing properties for child nodes. All are optional and default to 0. - gpmc,adv-on-ns: Assertion time - gpmc,adv-rd-off-ns: Read deassertion time - gpmc,adv-wr-off-ns: Write deassertion time + - gpmc,adv-aad-mux-on-ns: Assertion time for AAD + - gpmc,adv-aad-mux-rd-off-ns: Read deassertion time for AAD + - gpmc,adv-aad-mux-wr-off-ns: Write deassertion time for AAD WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: - gpmc,we-on-ns Assertion time @@ -54,6 +57,8 @@ Timing properties for child nodes. All are optional and default to 0. OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: - gpmc,oe-on-ns: Assertion time - gpmc,oe-off-ns: Deassertion time + - gpmc,oe-aad-mux-on-ns: Assertion time for AAD + - gpmc,oe-aad-mux-off-ns: Deassertion time for AAD Access time and cycle time timings (in nanoseconds) corresponding to GPMC_CONFIG5: -- GitLab From b7a90075656716d9e674bcb73cfac379e66ce409 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:12:48 +0100 Subject: [PATCH 0789/5324] reset: berlin: Make reset_control_ops const The berlin_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel Acked-by: Antoine Tenart --- drivers/reset/reset-berlin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c index ac017df8858c..369f3917fd8e 100644 --- a/drivers/reset/reset-berlin.c +++ b/drivers/reset/reset-berlin.c @@ -46,7 +46,7 @@ static int berlin_reset_reset(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops berlin_reset_ops = { +static const struct reset_control_ops berlin_reset_ops = { .reset = berlin_reset_reset, }; -- GitLab From 90c073e53909da856f9d3d05dc7e6b93ed05232d Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Sat, 30 Jan 2016 07:33:59 +0100 Subject: [PATCH 0790/5324] clk: shmobile: r8a7795: Add SD divider support This patch adds SD[0..3] clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Dirk Behme Tested-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven --- drivers/clk/shmobile/r8a7795-cpg-mssr.c | 230 ++++++++++++++++++++++++ drivers/clk/shmobile/renesas-cpg-mssr.h | 2 + 2 files changed, 232 insertions(+) diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index fc260b3306aa..0ff3b25a7d8d 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -61,6 +62,7 @@ enum r8a7795_clk_types { CLK_TYPE_GEN3_PLL2, CLK_TYPE_GEN3_PLL3, CLK_TYPE_GEN3_PLL4, + CLK_TYPE_GEN3_SD, }; static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { @@ -99,6 +101,12 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), + + DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), + DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), + DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), + DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), + DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), @@ -120,6 +128,10 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), + DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), + DEF_MOD("sdif1", 313, R8A7795_CLK_SD1), + DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), @@ -200,6 +212,221 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { MOD_CLK_ID(408), /* INTC-AP (GIC) */ }; +/* ----------------------------------------------------------------------------- + * SDn Clock + * + */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) + +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) + +#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((stp_ck) ? CPG_SD_STP_CK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ +} + +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + void __iomem *reg; + const struct sd_div_table *div_table; + unsigned int div_num; + unsigned int div_min; + unsigned int div_max; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc + *------------------------------------------------------------------- + * 0 0 0 (1) 1 (4) 4 + * 0 0 1 (2) 1 (4) 8 + * 1 0 2 (4) 1 (4) 16 + * 1 0 3 (8) 1 (4) 32 + * 1 0 4 (16) 1 (4) 64 + * 0 0 0 (1) 0 (2) 2 + * 0 0 1 (2) 0 (2) 4 + * 1 0 2 (4) 0 (2) 8 + * 1 0 3 (8) 0 (2) 16 + * 1 0 4 (16) 0 (2) 32 + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val &= ~(CPG_SD_STP_MASK); + val |= clock->div_table[i].val & CPG_SD_STP_MASK; + + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned long rate = parent_rate; + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); +} + +static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + return clamp_t(unsigned int, div, clock->div_min, clock->div_max); +} + +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + + return DIV_ROUND_CLOSEST(*parent_rate, div); +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); + u32 val; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (div == clock->div_table[i].div) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val = clk_readl(clock->reg); + val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); + val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); + clk_writel(val, clock->reg); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .round_rate = cpg_sd_clock_round_rate, + .set_rate = cpg_sd_clock_set_rate, +}; + +static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct sd_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->reg = base + core->offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + + clock->div_max = clock->div_table[0].div; + clock->div_min = clock->div_max; + for (i = 1; i < clock->div_num; i++) { + clock->div_max = max(clock->div_max, clock->div_table[i].div); + clock->div_min = min(clock->div_min, clock->div_table[i].div); + } + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} #define CPG_PLL0CR 0x00d8 #define CPG_PLL2CR 0x002c @@ -325,6 +552,9 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev, mult = (((value >> 24) & 0x7f) + 1) * 2; break; + case CLK_TYPE_GEN3_SD: + return cpg_sd_clk_register(core, base, __clk_get_name(parent)); + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.h b/drivers/clk/shmobile/renesas-cpg-mssr.h index e09f03cbf086..952b6957233b 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.h +++ b/drivers/clk/shmobile/renesas-cpg-mssr.h @@ -53,6 +53,8 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) #define DEF_DIV6P1(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) +#define DEF_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) /* -- GitLab From 7826c61138ef7dbc4ab0c3053003ef4988fd01e3 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 1 Feb 2016 20:29:05 +0900 Subject: [PATCH 0791/5324] clk: shmobile: r8a7795: Add USB-DMAC clocks Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven --- drivers/clk/shmobile/r8a7795-cpg-mssr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 0ff3b25a7d8d..24ff38c2c28c 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -136,6 +136,8 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), -- GitLab From 2841029393fad551b49b6de34d44bfa9ef256441 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 11 Jan 2016 17:15:58 +0000 Subject: [PATCH 0792/5324] ARM: make virt_to_idmap() return unsigned long Make virt_to_idmap() return an unsigned long rather than phys_addr_t. Returning phys_addr_t here makes no sense, because the definition of virt_to_idmap() is that it shall return a physical address which maps identically with the virtual address. Since virtual addresses are limited to 32-bit, identity mapped physical addresses are as well. Almost all users already had an implicit narrowing cast to unsigned long so let's make this official and part of this interface. Tested-by: Grygorii Strashko Signed-off-by: Russell King --- arch/arm/include/asm/memory.h | 6 +++--- arch/arm/kernel/reboot.c | 2 +- arch/arm/mach-keystone/keystone.c | 2 +- arch/arm/mm/idmap.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index c79b57bf71c4..49bf6b1e2177 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -273,14 +273,14 @@ static inline void *phys_to_virt(phys_addr_t x) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) -extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); +extern unsigned long (*arch_virt_to_idmap)(unsigned long x); /* * These are for systems that have a hardware interconnect supported alias of * physical memory for idmap purposes. Most cases should leave these - * untouched. + * untouched. Note: this can only return addresses less than 4GiB. */ -static inline phys_addr_t __virt_to_idmap(unsigned long x) +static inline unsigned long __virt_to_idmap(unsigned long x) { if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) return arch_virt_to_idmap(x); diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c index 38269358fd25..71a2ff9ec490 100644 --- a/arch/arm/kernel/reboot.c +++ b/arch/arm/kernel/reboot.c @@ -50,7 +50,7 @@ static void __soft_restart(void *addr) flush_cache_all(); /* Switch to the identity mapping. */ - phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset); + phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset); phys_reset((unsigned long)addr); /* Should never get here. */ diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index c279293f084c..d80879ce4963 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -63,7 +63,7 @@ static void __init keystone_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static phys_addr_t keystone_virt_to_idmap(unsigned long x) +static unsigned long keystone_virt_to_idmap(unsigned long x) { return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; } diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index d65909697165..bd274a05b8ff 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -15,7 +15,7 @@ * page tables. */ pgd_t *idmap_pgd; -phys_addr_t (*arch_virt_to_idmap) (unsigned long x); +unsigned long (*arch_virt_to_idmap)(unsigned long x); #ifdef CONFIG_ARM_LPAE static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, -- GitLab From 4138323eac0b485316e54ad9ce241bac24ddd175 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 11 Jan 2016 17:03:54 +0000 Subject: [PATCH 0793/5324] ARM: use virt_to_idmap() for soft_restart() Code run via soft_restart() is run with the MMU disabled, so we need to pass the identity map physical address rather than the address obtained from virt_to_phys(). Therefore, replace virt_to_phys() with virt_to_idmap() for all callers of soft_restart(). Signed-off-by: Russell King --- arch/arm/kernel/hibernate.c | 4 ++-- arch/arm/kernel/machine_kexec.c | 16 ++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c index a71501ff6f18..b09561a6d06a 100644 --- a/arch/arm/kernel/hibernate.c +++ b/arch/arm/kernel/hibernate.c @@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused) ret = swsusp_save(); if (ret == 0) - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); return ret; } @@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused) for (pbe = restore_pblist; pbe; pbe = pbe->next) copy_page(pbe->orig_address, pbe->address); - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); } static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8bf3b7c09888..59fd0e24c56b 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -143,10 +143,8 @@ void (*kexec_reinit)(void); void machine_kexec(struct kimage *image) { - unsigned long page_list; - unsigned long reboot_code_buffer_phys; - unsigned long reboot_entry = (unsigned long)relocate_new_kernel; - unsigned long reboot_entry_phys; + unsigned long page_list, reboot_entry_phys; + void (*reboot_entry)(void); void *reboot_code_buffer; /* @@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image) page_list = image->head & PAGE_MASK; - /* we need both effective and real address here */ - reboot_code_buffer_phys = - page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ @@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image) /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, - reboot_entry, + &relocate_new_kernel, relocate_new_kernel_size); - reboot_entry_phys = (unsigned long)reboot_entry + - (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); + + /* get the identity mapping physical address for the reboot code */ + reboot_entry_phys = virt_to_idmap(reboot_entry); pr_info("Bye!\n"); -- GitLab From 25362dc496edaf17f714c0fecd8b3eb79670207b Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 26 Jan 2016 01:19:36 +0100 Subject: [PATCH 0794/5324] ARM: 8501/1: mm: flip priority of CONFIG_DEBUG_RODATA The use of CONFIG_DEBUG_RODATA is generally seen as an essential part of kernel self-protection: http://www.openwall.com/lists/kernel-hardening/2015/11/30/13 Additionally, its name has grown to mean things beyond just rodata. To get ARM closer to this, we ought to rearrange the names of the configs that control how the kernel protects its memory. What was called CONFIG_ARM_KERNMEM_PERMS is realy doing the work that other architectures call CONFIG_DEBUG_RODATA. This redefines CONFIG_DEBUG_RODATA to actually do the bulk of the ROing (and NXing). In the place of the old CONFIG_DEBUG_RODATA, use CONFIG_DEBUG_ALIGN_RODATA, since that's what the option does: adds section alignment for making rodata explicitly NX, as arm does not split the page tables like arm64 does without _ALIGN_RODATA. Also adds human readable names to the sections so I could more easily debug my typos, and makes CONFIG_DEBUG_RODATA default "y" for CPU_V7. Results in /sys/kernel/debug/kernel_page_tables for each config state: # CONFIG_DEBUG_RODATA is not set # CONFIG_DEBUG_ALIGN_RODATA is not set ---[ Kernel Mapping ]--- 0x80000000-0x80900000 9M RW x SHD 0x80900000-0xa0000000 503M RW NX SHD CONFIG_DEBUG_RODATA=y CONFIG_DEBUG_ALIGN_RODATA=y ---[ Kernel Mapping ]--- 0x80000000-0x80100000 1M RW NX SHD 0x80100000-0x80700000 6M ro x SHD 0x80700000-0x80a00000 3M ro NX SHD 0x80a00000-0xa0000000 502M RW NX SHD CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_ALIGN_RODATA is not set ---[ Kernel Mapping ]--- 0x80000000-0x80100000 1M RW NX SHD 0x80100000-0x80a00000 9M ro x SHD 0x80a00000-0xa0000000 502M RW NX SHD Signed-off-by: Kees Cook Reviewed-by: Laura Abbott Signed-off-by: Russell King --- arch/arm/kernel/vmlinux.lds.S | 10 +++++----- arch/arm/mm/Kconfig | 34 ++++++++++++++++++---------------- arch/arm/mm/init.c | 19 ++++++++++--------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 8b60fde5ce48..a6e395c53a48 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -8,7 +8,7 @@ #include #include #include -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA #include #endif @@ -94,7 +94,7 @@ SECTIONS HEAD_TEXT } -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA . = ALIGN(1<active_mm); } -#endif /* CONFIG_DEBUG_RODATA */ #else static inline void fix_kernmem_perms(void) { } -#endif /* CONFIG_ARM_KERNMEM_PERMS */ +#endif /* CONFIG_DEBUG_RODATA */ void free_tcmmem(void) { -- GitLab From c0cc2609bc0705d03d2317fba5ef2824d0ec5ee1 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 5 Feb 2016 16:49:34 +0100 Subject: [PATCH 0795/5324] reset: img: Make reset_control_ops const The pistachio_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel Acked-by: James Hartley --- drivers/reset/reset-pistachio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-pistachio.c b/drivers/reset/reset-pistachio.c index b31cdb0570fc..72a97a15a4c8 100644 --- a/drivers/reset/reset-pistachio.c +++ b/drivers/reset/reset-pistachio.c @@ -97,7 +97,7 @@ static int pistachio_reset_deassert(struct reset_controller_dev *rcdev, mask, 0); } -static struct reset_control_ops pistachio_reset_ops = { +static const struct reset_control_ops pistachio_reset_ops = { .assert = pistachio_reset_assert, .deassert = pistachio_reset_deassert, }; -- GitLab From 01501d57302a39b46a308b6499a7095f9096a104 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:14:32 +0100 Subject: [PATCH 0796/5324] reset: sunxi: Make reset_control_ops const The sunxi_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel Acked-by: Maxime Ripard --- drivers/reset/reset-sunxi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index 8d41a18da17f..677f86555212 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -70,7 +70,7 @@ static int sunxi_reset_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops sunxi_reset_ops = { +static const struct reset_control_ops sunxi_reset_ops = { .assert = sunxi_reset_assert, .deassert = sunxi_reset_deassert, }; -- GitLab From 1a55cad19f0ad42f3acc32be5199fd9a4802508b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:13:20 +0100 Subject: [PATCH 0797/5324] reset: lpc18xx: Make reset_control_ops const The lpc18xx_rgu_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel Acked-by: Joachim Eastwood --- drivers/reset/reset-lpc18xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-lpc18xx.c b/drivers/reset/reset-lpc18xx.c index 70922e9ac27f..3b8a4f5a1ff6 100644 --- a/drivers/reset/reset-lpc18xx.c +++ b/drivers/reset/reset-lpc18xx.c @@ -136,7 +136,7 @@ static int lpc18xx_rgu_status(struct reset_controller_dev *rcdev, return !(readl(rc->base + offset) & bit); } -static struct reset_control_ops lpc18xx_rgu_ops = { +static const struct reset_control_ops lpc18xx_rgu_ops = { .reset = lpc18xx_rgu_reset, .assert = lpc18xx_rgu_assert, .deassert = lpc18xx_rgu_deassert, -- GitLab From fd97646b05957348e01be3d9de5c3d979b25c819 Mon Sep 17 00:00:00 2001 From: Wei Yuan Date: Sat, 6 Feb 2016 15:39:47 +0800 Subject: [PATCH 0798/5324] audit: Fix typo in comment Signed-off-by: Weiyuan Signed-off-by: Paul Moore --- kernel/audit_watch.c | 2 +- kernel/auditfilter.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 656c7e93ac0d..0348b12b5a4d 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -185,7 +185,7 @@ static struct audit_watch *audit_init_watch(char *path) return watch; } -/* Translate a watch string to kernel respresentation. */ +/* Translate a watch string to kernel representation. */ int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op) { struct audit_watch *watch; diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index b8ff9e193753..94ca7b1e5e7e 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -158,7 +158,7 @@ char *audit_unpack_string(void **bufp, size_t *remain, size_t len) return str; } -/* Translate an inode field to kernel respresentation. */ +/* Translate an inode field to kernel representation. */ static inline int audit_to_inode(struct audit_krule *krule, struct audit_field *f) { @@ -415,7 +415,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) return 0; } -/* Translate struct audit_rule_data to kernel's rule respresentation. */ +/* Translate struct audit_rule_data to kernel's rule representation. */ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, size_t datasz) { @@ -593,7 +593,7 @@ static inline size_t audit_pack_string(void **bufp, const char *str) return len; } -/* Translate kernel rule respresentation to struct audit_rule_data. */ +/* Translate kernel rule representation to struct audit_rule_data. */ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) { struct audit_rule_data *data; -- GitLab From 7d8f9ac16223cf14f199a96355b0add4ca286662 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 8 Feb 2016 15:17:12 +0900 Subject: [PATCH 0799/5324] ARM: mvebu: add missing of_node_put() This node pointer is returned by of_find_compatible_node() in this function. It should be put before exitting this function. Signed-off-by: Masahiro Yamada Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mvebu/platsmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index f9597b701028..46c742d3bd41 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -140,6 +140,7 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) panic("Cannot find 'marvell,bootrom' compatible node"); err = of_address_to_resource(node, 0, &res); + of_node_put(node); if (err < 0) panic("Cannot get 'bootrom' node address"); -- GitLab From 5bcaf95c26194d1d504f9d0bbd3bf08db2ff7ef6 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamski Date: Mon, 8 Feb 2016 10:31:14 +0100 Subject: [PATCH 0800/5324] ARM: dts: sunxi: Fix #interrupt-cells for PIO in H3 pinctrl-sunxi uses 3 cells to describe interrupt, not 2. It's bank number, pin number and flags. Signed-off-by: Krzysztof Adamski Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-h3.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi index 1524130e43c9..3ba65c2b53e5 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi @@ -359,7 +359,7 @@ gpio-controller; #gpio-cells = <3>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <3>; uart0_pins_a: uart0@0 { allwinner,pins = "PA4", "PA5"; -- GitLab From b41c29b0527c7fd6a95d0f71274abb79933bf960 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 8 Feb 2016 15:38:32 +0100 Subject: [PATCH 0801/5324] Kbuild: provide a __UNIQUE_ID for clang The default __UNIQUE_ID macro in compiler.h fails to work for some drivers: drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:615:1: error: redefinition of '__UNIQUE_ID_firmware615' BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt"); This adds a copy of the version we use for gcc-4.3 and higher, as the same one works with all versions of clang that I could find in svn (2.6 and higher). Signed-off-by: Arnd Bergmann Signed-off-by: Michal Marek --- include/linux/compiler-clang.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index d1e49d52b640..de179993e039 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -10,3 +10,8 @@ #undef uninitialized_var #define uninitialized_var(x) x = *(&(x)) #endif + +/* same as gcc, this was present in clang-2.6 so we can assume it works + * with any version that can compile the kernel + */ +#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -- GitLab From a043934207c5eb271deeaed2e9bd019c3be92cad Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 5 Feb 2016 11:25:05 +0100 Subject: [PATCH 0802/5324] scripts/link-vmlinux.sh: force error on kallsyms failure Since the output of the invocation of scripts/kallsyms is piped directly into the assembler, error messages it emits are visible on stderr, but a non-zero return code is ignored, and the build simply proceeds in that case. However, the resulting kernel is most likely broken, and will crash at boot. So instead, capture the output of kallsyms in a separate .S file, and pass that to the assembler in a separate step. Signed-off-by: Ard Biesheuvel Signed-off-by: Michal Marek --- scripts/link-vmlinux.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index ba6c34ea5429..8f22654c71b4 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -93,9 +93,10 @@ kallsyms() local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" - ${NM} -n ${1} | \ - scripts/kallsyms ${kallsymopt} | \ - ${CC} ${aflags} -c -o ${2} -x assembler-with-cpp - + local afile="`basename ${2} .o`.S" + + ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${afile} + ${CC} ${aflags} -c -o ${2} ${afile} } # Create map file with all symbols from ${1} -- GitLab From efdda175c07f34d4c8dd38bf23be8d15ef37e32e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Sat, 6 Feb 2016 07:07:33 +0000 Subject: [PATCH 0803/5324] arm64: defconfig: add spmi and usb related configs This patch adds kconfigs for spmi bus support, pinctrl drivers and usb related to get USB working on Qualcomm DB410C board. Signed-off-by: Srinivas Kandagatla Signed-off-by: Olof Johansson --- arch/arm64/configs/defconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 86581f793e39..91ae2634cae9 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -144,16 +144,20 @@ CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPMI=y CONFIG_PINCTRL_MSM8916=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_XGENE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set +CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -166,13 +170,21 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_RCAR=y CONFIG_SND_SOC_AK4613=y CONFIG_USB=y +CONFIG_USB_OTG=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y @@ -213,6 +225,7 @@ CONFIG_QCOM_SMD_RPM=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_HISILICON_IRQ_MBIGEN=y +CONFIG_EXTCON_USB_GPIO=y CONFIG_PHY_XGENE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y -- GitLab From 9dfb81efbbddf8258ff9c10f9649553608975e02 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 6 Feb 2016 02:36:48 +0900 Subject: [PATCH 0804/5324] ARM: drop unused Makefile.boot of Multiplatform SoCs The variable "MACHINE" is empty if CONFIG_ARCH_MULTIPLATFORM=y, so these Makefile.boot files are never included. Signed-off-by: Masahiro Yamada Acked-by: Michal Simek (for Zynq) Acked-by: Tony Lindgren Signed-off-by: Olof Johansson --- arch/arm/mach-cns3xxx/Makefile.boot | 3 --- arch/arm/mach-exynos/Makefile.boot | 2 -- arch/arm/mach-integrator/Makefile.boot | 4 ---- arch/arm/mach-keystone/Makefile.boot | 1 - arch/arm/mach-mmp/Makefile.boot | 1 - arch/arm/mach-mv78xx0/Makefile.boot | 3 --- arch/arm/mach-nspire/Makefile.boot | 0 arch/arm/mach-omap2/Makefile.boot | 3 --- arch/arm/mach-orion5x/Makefile.boot | 3 --- arch/arm/mach-prima2/Makefile.boot | 3 --- arch/arm/mach-realview/Makefile.boot | 9 --------- arch/arm/mach-s3c64xx/Makefile.boot | 2 -- arch/arm/mach-spear/Makefile.boot | 3 --- arch/arm/mach-u300/Makefile.boot | 4 ---- arch/arm/mach-ux500/Makefile.boot | 3 --- arch/arm/mach-zynq/Makefile.boot | 3 --- 16 files changed, 47 deletions(-) delete mode 100644 arch/arm/mach-cns3xxx/Makefile.boot delete mode 100644 arch/arm/mach-exynos/Makefile.boot delete mode 100644 arch/arm/mach-integrator/Makefile.boot delete mode 100644 arch/arm/mach-keystone/Makefile.boot delete mode 100644 arch/arm/mach-mmp/Makefile.boot delete mode 100644 arch/arm/mach-mv78xx0/Makefile.boot delete mode 100644 arch/arm/mach-nspire/Makefile.boot delete mode 100644 arch/arm/mach-omap2/Makefile.boot delete mode 100644 arch/arm/mach-orion5x/Makefile.boot delete mode 100644 arch/arm/mach-prima2/Makefile.boot delete mode 100644 arch/arm/mach-realview/Makefile.boot delete mode 100644 arch/arm/mach-s3c64xx/Makefile.boot delete mode 100644 arch/arm/mach-spear/Makefile.boot delete mode 100644 arch/arm/mach-u300/Makefile.boot delete mode 100644 arch/arm/mach-ux500/Makefile.boot delete mode 100644 arch/arm/mach-zynq/Makefile.boot diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot deleted file mode 100644 index d079de0b6e3b..000000000000 --- a/arch/arm/mach-cns3xxx/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00C00000 diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot deleted file mode 100644 index b9862e22bf10..000000000000 --- a/arch/arm/mach-exynos/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x40008000 -params_phys-y := 0x40000100 diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot deleted file mode 100644 index ff0a4b5b0a82..000000000000 --- a/arch/arm/mach-integrator/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 - diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot deleted file mode 100644 index f3835c43af61..000000000000 --- a/arch/arm/mach-keystone/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ -zreladdr-y := 0x80008000 diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot deleted file mode 100644 index 5edf03e2beed..000000000000 --- a/arch/arm/mach-mmp/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ - zreladdr-y += 0x00008000 diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-mv78xx0/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-nspire/Makefile.boot b/arch/arm/mach-nspire/Makefile.boot deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot deleted file mode 100644 index b03e562acc60..000000000000 --- a/arch/arm/mach-omap2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x80008000 -params_phys-y := 0x80000100 -initrd_phys-y := 0x80800000 diff --git a/arch/arm/mach-orion5x/Makefile.boot b/arch/arm/mach-orion5x/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-orion5x/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot deleted file mode 100644 index c77a4883a4ee..000000000000 --- a/arch/arm/mach-prima2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot deleted file mode 100644 index d2c3d788f688..000000000000 --- a/arch/arm/mach-realview/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70800000 -else - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -endif diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot deleted file mode 100644 index c642333af3ed..000000000000 --- a/arch/arm/mach-s3c64xx/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x50008000 -params_phys-y := 0x50000100 diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot deleted file mode 100644 index 4674a4c221db..000000000000 --- a/arch/arm/mach-spear/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-u300/Makefile.boot b/arch/arm/mach-u300/Makefile.boot deleted file mode 100644 index 87811de0bd94..000000000000 --- a/arch/arm/mach-u300/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x48008000 -params_phys-y := 0x48000100 -# This isn't used. -#initrd_phys-y := 0x48800000 diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-ux500/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot deleted file mode 100644 index 760a0efe7580..000000000000 --- a/arch/arm/mach-zynq/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -- GitLab From ea503fb63dae6adaf1fef688a44a02f8e79e5ae2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 6 Feb 2016 02:38:40 +0900 Subject: [PATCH 0805/5324] ARM: integrator: remove redundant select in Kconfig All of these are already select'ed by ARCH_MULTIPLATFORM. Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson --- arch/arm/mach-integrator/Kconfig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index b01bdc9baf89..b2a85ba13f08 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -2,22 +2,16 @@ menuconfig ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 select ARM_AMBA - select ARM_PATCH_PHYS_VIRT if MMU - select AUTO_ZRELADDR - select COMMON_CLK select COMMON_CLK_VERSATILE - select GENERIC_CLOCKEVENTS select HAVE_TCM select ICST select MFD_SYSCON - select MULTI_IRQ_HANDLER select PLAT_VERSATILE select POWER_RESET select POWER_RESET_VERSATILE select POWER_SUPPLY select SOC_INTEGRATOR_CM select SPARSE_IRQ - select USE_OF select VERSATILE_FPGA_IRQ help Support for ARM's Integrator platform. -- GitLab From 95650655f7a1a1a93e24dcca45514f17ecf8cee7 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 6 Feb 2016 02:43:17 +0900 Subject: [PATCH 0806/5324] ARM: netx: remove redundant "depends on ARCH_NETX" These options already reside inside the ARCH_NETX-dependent menu. Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson --- arch/arm/mach-netx/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig index 3d90ef19be2b..2da8e5dfcf24 100644 --- a/arch/arm/mach-netx/Kconfig +++ b/arch/arm/mach-netx/Kconfig @@ -3,20 +3,17 @@ menu "NetX Implementations" config MACH_NXDKN bool "Enable Hilscher nxdkn Eval Board support" - depends on ARCH_NETX help Board support for the Hilscher NetX Eval Board config MACH_NXDB500 bool "Enable Hilscher nxdb500 Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxdb500 Eval Board config MACH_NXEB500HMI bool "Enable Hilscher nxeb500hmi Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxeb500hmi Eval Board -- GitLab From 2510eb74abbbdeb9101f0f717f6bd997a3dde9fa Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:06 -0600 Subject: [PATCH 0807/5324] MAINTAINERS: Adding Maintainers for AMD Seattle Device Tree Adding maintainers for AMD Seattle device tree. Signed-off-by: Brijesh Singh Signed-off-by: Suravee Suthikulpanit Signed-off-by: Tom Lendacky Signed-off-by: Olof Johansson --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7f1fa4ff300a..e349a32022cf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -673,6 +673,13 @@ F: drivers/gpu/drm/radeon/radeon_kfd.c F: drivers/gpu/drm/radeon/radeon_kfd.h F: include/uapi/linux/kfd_ioctl.h +AMD SEATTLE DEVICE TREE SUPPORT +M: Brijesh Singh +M: Suravee Suthikulpanit +M: Tom Lendacky +S: Supported +F: arch/arm64/boot/dts/amd/ + AMD XGBE DRIVER M: Tom Lendacky L: netdev@vger.kernel.org -- GitLab From 4852773806867374e6e1f941410ac72141fc689d Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Mon, 8 Feb 2016 11:59:07 -0600 Subject: [PATCH 0808/5324] dtb: amd: Fix GICv2 hypervisor and virtual interface sizes This patch fixes incorrect sizes of the GICv2 device tree node. This has triggered error message when booting Xen hypervisor. Signed-off-by: Brijesh Singh Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 2874d92881fd..fdd0c967138e 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -18,8 +18,8 @@ #size-cells = <2>; reg = <0x0 0xe1110000 0 0x1000>, <0x0 0xe112f000 0 0x2000>, - <0x0 0xe1140000 0 0x10000>, - <0x0 0xe1160000 0 0x10000>; + <0x0 0xe1140000 0 0x2000>, + <0x0 0xe1160000 0 0x2000>; interrupts = <1 9 0xf04>; ranges = <0 0 0 0xe1100000 0 0x100000>; v2m0: v2m@e0080000 { -- GitLab From c91cb9123cdd5f965ed177620611b06df21eef23 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:08 -0600 Subject: [PATCH 0809/5324] dtb: amd: Fix DMA ranges in device tree Fix DMA ranges of smb0 and pcie0 nodes in AMD Seattle SOC. Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index fdd0c967138e..5c73117f5c7b 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -55,8 +55,12 @@ #size-cells = <2>; ranges; - /* DDR range is 40-bit addressing */ - dma-ranges = <0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + /* + * dma-ranges is 40-bit address space containing: + * - GICv2m MSI register is at 0xe0080000 + * - DRAM range [0x8000000000 to 0xffffffffff] + */ + dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; /include/ "amd-seattle-clks.dtsi" @@ -159,7 +163,7 @@ <0x1000 0x0 0x0 0x4 &gic0 0x0 0x0 0x0 0x123 0x1>; dma-coherent; - dma-ranges = <0x43000000 0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + dma-ranges = <0x43000000 0x0 0x0 0x0 0x0 0x100 0x0>; ranges = /* I/O Memory (size=64K) */ <0x01000000 0x00 0x00000000 0x00 0xefff0000 0x00 0x00010000>, -- GitLab From 4bc529e182576d4082d022d89a0915995205ad7e Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:09 -0600 Subject: [PATCH 0810/5324] dtb: amd: Fix typo in SPI device nodes Remove invalid entry in the SPI device nodes. Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 5c73117f5c7b..c7c759a7a0fe 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -91,7 +91,6 @@ spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1020000 0 0x1000>; spi-controller; interrupts = <0 330 4>; @@ -102,7 +101,6 @@ spi1: ssp@e1030000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1030000 0 0x1000>; spi-controller; interrupts = <0 329 4>; -- GitLab From 1584fd1373f97b84d81d903580dd5cc25b43fc1c Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:10 -0600 Subject: [PATCH 0811/5324] dtb: amd: Misc changes for I2C device nodes Add new i2c1 device node, and fix the incorrect clock frequency. Signed-off-by: Tom Lendacky Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index c7c759a7a0fe..4be36fdd7478 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -77,7 +77,15 @@ compatible = "snps,designware-i2c"; reg = <0 0xe1000000 0 0x1000>; interrupts = <0 357 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + }; + + i2c1: i2c@e0050000 { + status = "disabled"; + compatible = "snps,designware-i2c"; + reg = <0 0xe0050000 0 0x1000>; + interrupts = <0 340 4>; + clocks = <&miscclk_250mhz>; }; serial0: serial@e1010000 { -- GitLab From 7973a3fbbb86292e1d01313ae2277b3060ebf1d0 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:11 -0600 Subject: [PATCH 0812/5324] dtb: amd: Misc changes for SATA device tree nodes Add new SATA1 device node, and fix the register range size of SATA0. Signed-off-by: Tom Lendacky Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 4be36fdd7478..9f5938161b56 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -66,12 +66,22 @@ sata0: sata@e0300000 { compatible = "snps,dwc-ahci"; - reg = <0 0xe0300000 0 0x800>; + reg = <0 0xe0300000 0 0xf0000>; interrupts = <0 355 4>; clocks = <&sataclk_333mhz>; dma-coherent; }; + /* This is for Rev B only */ + sata1: sata@e0d00000 { + status = "disabled"; + compatible = "snps,dwc-ahci"; + reg = <0 0xe0d00000 0 0xf0000>; + interrupts = <0 354 4>; + clocks = <&sataclk_333mhz>; + dma-coherent; + }; + i2c0: i2c@e1000000 { status = "disabled"; compatible = "snps,designware-i2c"; -- GitLab From ce00c22fc1d32d43c12d10ec372b043e056527d9 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:12 -0600 Subject: [PATCH 0813/5324] dtb: amd: Misc changes for GPIO devices Add new GPIO device nodes and fix clock on gpio0. Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 49 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 9f5938161b56..ba455d12971d 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -129,7 +129,7 @@ #size-cells = <0>; }; - gpio0: gpio@e1040000 { + gpio0: gpio@e1040000 { /* Not available to OS for B0 */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; @@ -138,18 +138,59 @@ interrupts = <0 359 4>; interrupt-controller; #interrupt-cells = <2>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; - gpio1: gpio@e1050000 { + gpio1: gpio@e1050000 { /* [0:7] */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; reg = <0 0xe1050000 0 0x1000>; gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; interrupts = <0 358 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio2: gpio@e0020000 { /* [8:15] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0020000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 366 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio3: gpio@e0030000 { /* [16:23] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0030000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 365 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio4: gpio@e0080000 { /* [24] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0080000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 361 4>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; -- GitLab From fb8d5e09832fdb2a7c1a62f6f7a550aeffa2fb1c Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:13 -0600 Subject: [PATCH 0814/5324] dtb: amd: Add PERF CCN-504 device tree node Add PERF CCN-504 device tree node. Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index ba455d12971d..c5461b2bd162 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -229,5 +229,12 @@ /* 64-bit MMIO (size= 124G) */ <0x03000000 0x01 0x00000000 0x01 0x00000000 0x7f 0x00000000>; }; + + /* Perf CCN504 PMU */ + ccn: ccn@0xe8000000 { + compatible = "arm,ccn-504"; + reg = <0x0 0xe8000000 0 0x1000000>; + interrupts = <0 380 4>; + }; }; }; -- GitLab From 71edbebb12f461b92e227e542cdac11773e661ef Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Mon, 8 Feb 2016 11:59:14 -0600 Subject: [PATCH 0815/5324] dtb: amd: Add KCS device tree node Add KCS device node to support IPMI solution on Overdrive system. Signed-off-by: Brijesh Singh Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index c5461b2bd162..a7fc059a7cd9 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -236,5 +236,16 @@ reg = <0x0 0xe8000000 0 0x1000000>; interrupts = <0 380 4>; }; + + ipmi_kcs: kcs@e0010000 { + status = "disabled"; + compatible = "ipmi-kcs"; + device_type = "ipmi"; + reg = <0x0 0xe0010000 0 0x8>; + interrupts = <0 389 4>; + interrupt-names = "ipmi_kcs"; + reg-size = <1>; + reg-spacing = <4>; + }; }; }; -- GitLab From 08b8940efc88b86c0ad71f2d6085bb24a0979755 Mon Sep 17 00:00:00 2001 From: Tom Lendacky Date: Mon, 8 Feb 2016 11:59:15 -0600 Subject: [PATCH 0816/5324] dtb: amd: Add AMD XGBE device tree file Add AMD XGBE device tree file, which is available in AMD Seattle RevB. Signed-off-by: Tom Lendacky Signed-off-by: Olof Johansson --- MAINTAINERS | 1 + .../boot/dts/amd/amd-seattle-xgbe-b.dtsi | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi diff --git a/MAINTAINERS b/MAINTAINERS index e349a32022cf..9547a6894468 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -685,6 +685,7 @@ M: Tom Lendacky L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/amd/xgbe/ +F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi AMS (Apple Motion Sensor) DRIVER M: Michael Hanselmann diff --git a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi new file mode 100644 index 000000000000..8e8631952497 --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi @@ -0,0 +1,117 @@ +/* + * DTS file for AMD Seattle XGBE (RevB) + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + + xgmacclk0_dma_250mhz: clk250mhz_0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_dma_250mhz"; + }; + + xgmacclk0_ptp_250mhz: clk250mhz_1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_ptp_250mhz"; + }; + + xgmacclk1_dma_250mhz: clk250mhz_2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_dma_250mhz"; + }; + + xgmacclk1_ptp_250mhz: clk250mhz_3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_ptp_250mhz"; + }; + + xgmac0: xgmac@e0700000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0700000 0 0x80000>, + <0 0xe0780000 0 0x80000>, + <0 0xe1240800 0 0x00400>, /* SERDES RX/TX0 */ + <0 0xe1250000 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500f8 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 325 4>, + <0 346 1>, <0 347 1>, <0 348 1>, <0 349 1>, + <0 323 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 A1 A2 A3 A4 A5 ]; + clocks = <&xgmacclk0_dma_250mhz>, <&xgmacclk0_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac1: xgmac@e0900000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0900000 0 0x80000>, + <0 0xe0980000 0 0x80000>, + <0 0xe1240c00 0 0x00400>, /* SERDES RX/TX1 */ + <0 0xe1250080 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500fc 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 324 4>, + <0 341 1>, <0 342 1>, <0 343 1>, <0 344 1>, + <0 322 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 B1 B2 B3 B4 B5 ]; + clocks = <&xgmacclk1_dma_250mhz>, <&xgmacclk1_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac0_smmu: smmu@e0600000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0600000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 336 4>, + <0 336 4>; + + mmu-masters = <&xgmac0 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; + + xgmac1_smmu: smmu@e0800000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0800000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 335 4>, + <0 335 4>; + + mmu-masters = <&xgmac1 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; -- GitLab From 49449828ba861a5e6553e24ec493b24e0dc40376 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:16 -0600 Subject: [PATCH 0817/5324] dtb: amd: Add support for new AMD Overdrive boards Add device tree files for AMD Overdrive boards which comes with AMD Seattle Revision B0 and B1 SOCs. Signed-off-by: Tom Lendacky Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/Makefile | 3 +- .../boot/dts/amd/amd-overdrive-rev-b0.dts | 87 ++++++++++++++++++ .../boot/dts/amd/amd-overdrive-rev-b1.dts | 91 +++++++++++++++++++ 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts create mode 100644 arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index cfdf701e05df..db03293cbdd7 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,4 +1,5 @@ -dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb +dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ + amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts new file mode 100644 index 000000000000..8e3074a4947d --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts @@ -0,0 +1,87 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B0) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts new file mode 100644 index 000000000000..ed5e043f37aa --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts @@ -0,0 +1,91 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B1 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B1) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&sata1 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; -- GitLab From 4a6e0a771eaafc0c3dab2ca942f15af17d89f127 Mon Sep 17 00:00:00 2001 From: Suravee Suthikulpanit Date: Mon, 8 Feb 2016 11:59:17 -0600 Subject: [PATCH 0818/5324] dtb: amd: Add support for AMD/Linaro 96Boards Enterprise Edition Server board Add device tree file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board. This is based on the AMD Seattle Rev.B0 system Signed-off-by: Leo Duran Signed-off-by: Suravee Suthikulpanit Signed-off-by: Olof Johansson --- arch/arm64/boot/dts/amd/Makefile | 3 +- arch/arm64/boot/dts/amd/husky.dts | 83 +++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/amd/husky.dts diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index db03293cbdd7..ba84770f789f 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,5 +1,6 @@ dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ - amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb + amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ + husky.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amd/husky.dts b/arch/arm64/boot/dts/amd/husky.dts new file mode 100644 index 000000000000..1381d4b2bf1b --- /dev/null +++ b/arch/arm64/boot/dts/amd/husky.dts @@ -0,0 +1,83 @@ +/* + * DTS file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board + * Note: Based-on AMD Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "Linaro 96Boards Enterprise Edition Server (Husky) Board"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; -- GitLab From 0c5325466d5d4816c9bd13c56746aa26ed66231d Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 5 Feb 2016 10:49:22 +0100 Subject: [PATCH 0819/5324] ARM: debug: add support for Palmchip BK-310x UART Some SoCs use a Palmchip BK-310x UART which is mostly 16550 compatible but with a different register layout. While this UART has previously only been supported in MIPS based chips (Alchemy, Ralink), the ARM based SMP87xx series from Sigma Designs also uses it. This patch allows the debug console to work with this type of UART. Signed-off-by: Mans Rullgard Signed-off-by: Marc Gonzalez Acked-by: Arnd Bergmann Acked-by: Kevin Hilman Signed-off-by: Olof Johansson --- arch/arm/Kconfig.debug | 9 +++++++++ arch/arm/include/debug/palmchip.S | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 arch/arm/include/debug/palmchip.S diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c6b6175d0203..1098e91d6d3f 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1368,6 +1368,7 @@ config DEBUG_SIRFSOC_UART config DEBUG_LL_INCLUDE string default "debug/sa1100.S" if DEBUG_SA1100 + default "debug/palmchip.S" if DEBUG_UART_8250_PALMCHIP default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/at91.S" if DEBUG_AT91_UART default "debug/asm9260.S" if DEBUG_ASM9260_UART @@ -1656,6 +1657,14 @@ config DEBUG_UART_8250_WORD DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ DEBUG_BRCMSTB_UART +config DEBUG_UART_8250_PALMCHIP + bool "8250 UART is Palmchip BK-310x" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + help + Palmchip provides a UART implementation compatible with 16550 + except for having a different register layout. Say Y here if + the debug UART is of this type. + config DEBUG_UART_8250_FLOW_CONTROL bool "Enable flow control for 8250 UART" depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 diff --git a/arch/arm/include/debug/palmchip.S b/arch/arm/include/debug/palmchip.S new file mode 100644 index 000000000000..6824b2d1c38e --- /dev/null +++ b/arch/arm/include/debug/palmchip.S @@ -0,0 +1,11 @@ +#include + +#undef UART_TX +#undef UART_LSR +#undef UART_MSR + +#define UART_TX 1 +#define UART_LSR 7 +#define UART_MSR 8 + +#include -- GitLab From 048c58b4e167b1cdd766ddc32c68f4a154fcbbad Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Tue, 3 Nov 2015 12:55:53 +0100 Subject: [PATCH 0820/5324] drivers/clk/Kconfig: Fix typo "Sypport" instead of "Support" Simple cosmetic fix. Signed-off-by: Mike Looijmans Signed-off-by: Stephen Boyd --- drivers/clk/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index de707b2bfb73..8401b7ec9770 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -190,7 +190,7 @@ config COMMON_CLK_PWM config COMMON_CLK_PXA def_bool COMMON_CLK && ARCH_PXA ---help--- - Sypport for the Marvell PXA SoC. + Support for the Marvell PXA SoC. config COMMON_CLK_CDCE706 tristate "Clock driver for TI CDCE706 clock synthesizer" -- GitLab From c7d5a46b10012e897b6b5a86fddf31674b32d081 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Tue, 3 Nov 2015 12:55:54 +0100 Subject: [PATCH 0821/5324] drivers/clk/Kconfig: Move the TI CDCE chips close together There are two TI CDCE clock chips in this file. Move them close together so they're easier to find. No functional change, just cosmetic. Signed-off-by: Mike Looijmans [sboyd@codeaurora.org: Alphabetize] Signed-off-by: Stephen Boyd --- drivers/clk/Kconfig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 8401b7ec9770..a8c2c882ed1f 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -99,6 +99,14 @@ config COMMON_CLK_SI570 This driver supports Silicon Labs 570/571/598/599 programmable clock generators. +config COMMON_CLK_CDCE706 + tristate "Clock driver for TI CDCE706 clock synthesizer" + depends on I2C + select REGMAP_I2C + select RATIONAL + ---help--- + This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. + config COMMON_CLK_CDCE925 tristate "Clock driver for TI CDCE925 devices" depends on I2C @@ -192,14 +200,6 @@ config COMMON_CLK_PXA ---help--- Support for the Marvell PXA SoC. -config COMMON_CLK_CDCE706 - tristate "Clock driver for TI CDCE706 clock synthesizer" - depends on I2C - select REGMAP_I2C - select RATIONAL - ---help--- - This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. - source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/mvebu/Kconfig" -- GitLab From 60ea57a4338e9a43741e8136510f63cdb3b8a678 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 8 Feb 2016 15:39:09 +0100 Subject: [PATCH 0822/5324] clk: socfpga: fix __init annotation clang found a bug with the __socfpga_pll_init definition: drivers/clk/socfpga/clk-pll-a10.c:77:15: error: '__section__' attribute only applies to functions and global variables This moves the __init annotation to the right place so the function actually gets discarded. Signed-off-by: Arnd Bergmann Signed-off-by: Stephen Boyd --- drivers/clk/socfpga/clk-pll-a10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c index 402d630bd531..35fabe1a32c3 100644 --- a/drivers/clk/socfpga/clk-pll-a10.c +++ b/drivers/clk/socfpga/clk-pll-a10.c @@ -74,7 +74,7 @@ static struct clk_ops clk_pll_ops = { .get_parent = clk_pll_get_parent, }; -static struct __init clk * __socfpga_pll_init(struct device_node *node, +static struct clk * __init __socfpga_pll_init(struct device_node *node, const struct clk_ops *ops) { u32 reg; -- GitLab From bb473593c8099302bfd7befc23de67df907e3a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Feb 2016 22:13:03 +0100 Subject: [PATCH 0823/5324] clk: meson: Fix meson_clk_register_clks() signature type mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As preparation for arm64 based mesongxbb, which pulls in this code once enabling ARCH_MESON, fix a size_t vs. unsigned int type mismatch. The loop uses a local unsigned int variable, so adopt that type, matching the header. Fixes: 7a29a869434e ("clk: meson: Add support for Meson clock controller") Signed-off-by: Andreas Färber Acked-by: Carlo Caione Signed-off-by: Stephen Boyd --- drivers/clk/meson/clkc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae1367abc..d920d410b51d 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, } void __init meson_clk_register_clks(const struct clk_conf *clk_confs, - size_t nr_confs, + unsigned int nr_confs, void __iomem *clk_base) { unsigned int i; -- GitLab From a3499e9bf0feeea593a9daae855986c685561893 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 23 Dec 2015 17:57:19 +0530 Subject: [PATCH 0824/5324] devm: add helper devm_add_action_or_reset() Add a helper function devm_add_action_or_reset() which will internally call devm_add_action(). But if devm_add_action() fails then it will execute the action mentioned and return the error code. Signed-off-by: Sudip Mukherjee Acked-by: Greg Kroah-Hartman Signed-off-by: Stephen Boyd --- include/linux/device.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 6d6f1fec092f..74674e098315 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -682,6 +682,18 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); +static inline int devm_add_action_or_reset(struct device *dev, + void (*action)(void *), void *data) +{ + int ret; + + ret = devm_add_action(dev, action, data); + if (ret) + action(data); + + return ret; +} + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about -- GitLab From 66f5ce2538e06dd6d628e37bbd38c79631274c9f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 23 Dec 2015 17:57:20 +0530 Subject: [PATCH 0825/5324] clk: qcom: common: check for failure We were not checking the return from devm_add_action() which can fail. Start using the helper and devm_add_action_or_reset() and return directly as we know that the cleanup has been done by this helper. Signed-off-by: Sudip Mukherjee Signed-off-by: Stephen Boyd --- drivers/clk/qcom/common.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index c112ebaba70d..65809f1a1f2b 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node); + ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider, + pdev->dev.of_node); + + if (ret) + return ret; reset = &cc->reset; reset->rcdev.of_node = dev->of_node; @@ -227,7 +231,11 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev); + ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister, + &reset->rcdev); + + if (ret) + return ret; if (desc->gdscs && desc->num_gdscs) { ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, @@ -236,10 +244,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; } - devm_add_action(dev, qcom_cc_gdsc_unregister, dev); - - - return 0; + return devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, dev); } EXPORT_SYMBOL_GPL(qcom_cc_really_probe); -- GitLab From 10c1b6183a163aca59ba92b88f2b4c4cecd20d4c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 9 Feb 2016 11:17:37 +1000 Subject: [PATCH 0826/5324] drm/tegra: drop unused variable. Fixes: 0417d424a (drm/tegra: Stop cancelling page flip events) Signed-off-by: Dave Airlie --- drivers/gpu/drm/tegra/drm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 021d0e1398fb..8e6b18caa706 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -858,7 +858,6 @@ static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file) { struct tegra_drm_file *fpriv = file->driver_priv; struct tegra_drm_context *context, *tmp; - struct drm_crtc *crtc; list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) tegra_drm_context_free(context); -- GitLab From f67ca6eca89cddd355c83639a90109e245f9d5a7 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:41:31 +1100 Subject: [PATCH 0827/5324] xfs: RT bitmap and summary buffers are not typed When logging buffers, we attach a type to them that follows the buffer all the way into the log and is used to identify the buffer contents in log recovery. Both the realtime summary buffers and the bitmap buffers do not have types defined or set, so when we try to log them we see assert failure: XFS: Assertion failed: (bip->bli_flags & XFS_BLI_STALE) || (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF), file: fs/xfs/xfs_buf_item.c, line: 294 Fix this by adding buffer log format types for these buffers, and add identification support into log recovery for them. Only build the log recovery support if CONFIG_XFS_RT=y - we can't get into log recovery for real time filesystems if support is not built into the kernel, and this avoids potential build problems. Signed-off-by: Dave Chinner Tested-by: Ross Zwisler Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_log_format.h | 2 ++ fs/xfs/libxfs/xfs_rtbitmap.c | 3 +++ fs/xfs/xfs_log_recover.c | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index 265314690415..1be26ecdbebf 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -495,6 +495,8 @@ enum xfs_blft { XFS_BLFT_ATTR_LEAF_BUF, XFS_BLFT_ATTR_RMT_BUF, XFS_BLFT_SB_BUF, + XFS_BLFT_RTBITMAP_BUF, + XFS_BLFT_RTSUMMARY_BUF, XFS_BLFT_MAX_BUF = (1 << XFS_BLFT_BITS), }; diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9b59ffa1fc19..377a2e6552f3 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -71,6 +71,9 @@ xfs_rtbuf_get( mp->m_bsize, 0, &bp, NULL); if (error) return error; + + xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF + : XFS_BLFT_RTBITMAP_BUF); *bpp = bp; return 0; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index da37beb76f6e..afdd326df923 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2473,6 +2473,13 @@ xlog_recover_validate_buf_type( } bp->b_ops = &xfs_sb_buf_ops; break; +#ifdef CONFIG_XFS_RT + case XFS_BLFT_RTBITMAP_BUF: + case XFS_BLFT_RTSUMMARY_BUF: + /* no verification of RT buffers is done */ + bp->b_ops = NULL; + break; +#endif /* CONFIG_XFS_RT */ default: xfs_warn(mp, "Unknown buffer type %d!", xfs_blft_from_flags(buf_f)); -- GitLab From bf85e0998ae8bafc1e0863d914df3be2b1bc372a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:41:45 +1100 Subject: [PATCH 0828/5324] xfs: RT bitmap and summary buffers need verifiers Buffers without verifiers issue runtime warnings on XFS. We don't have anything we can actually verify in the RT buffers (no CRCs, not magic numbers, etc), but we still need verifiers to avoid the warnings. Add a set of dummy verifier operations for the realtime buffers and apply them in the appropriate places. Signed-off-by: Dave Chinner Tested-by: Ross Zwisler Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_rtbitmap.c | 27 ++++++++++++++++++++++++++- fs/xfs/libxfs/xfs_shared.h | 1 + fs/xfs/xfs_log_recover.c | 4 ++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 377a2e6552f3..33806e0c2bc6 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -41,6 +41,31 @@ * Realtime allocator bitmap functions shared with userspace. */ +/* + * Real time buffers need verifiers to avoid runtime warnings during IO. + * We don't have anything to verify, however, so these are just dummy + * operations. + */ +static void +xfs_rtbuf_verify_read( + struct xfs_buf *bp) +{ + return; +} + +static void +xfs_rtbuf_verify_write( + struct xfs_buf *bp) +{ + return; +} + +const struct xfs_buf_ops xfs_rtbuf_ops = { + .name = "rtbuf", + .verify_read = xfs_rtbuf_verify_read, + .verify_write = xfs_rtbuf_verify_write, +}; + /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. @@ -68,7 +93,7 @@ xfs_rtbuf_get( ASSERT(map.br_startblock != NULLFSBLOCK); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, map.br_startblock), - mp->m_bsize, 0, &bp, NULL); + mp->m_bsize, 0, &bp, &xfs_rtbuf_ops); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 15c3ceb845b9..81ac870834da 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -53,6 +53,7 @@ extern const struct xfs_buf_ops xfs_dquot_buf_ra_ops; extern const struct xfs_buf_ops xfs_sb_buf_ops; extern const struct xfs_buf_ops xfs_sb_quiet_buf_ops; extern const struct xfs_buf_ops xfs_symlink_buf_ops; +extern const struct xfs_buf_ops xfs_rtbuf_ops; /* * Transaction types. Used to distinguish types of buffers. These never reach diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index afdd326df923..ed8c88917300 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2476,8 +2476,8 @@ xlog_recover_validate_buf_type( #ifdef CONFIG_XFS_RT case XFS_BLFT_RTBITMAP_BUF: case XFS_BLFT_RTSUMMARY_BUF: - /* no verification of RT buffers is done */ - bp->b_ops = NULL; + /* no magic numbers for verification of RT buffers */ + bp->b_ops = &xfs_rtbuf_ops; break; #endif /* CONFIG_XFS_RT */ default: -- GitLab From f8d55aa0523ad0f78979c222ed18b78ea7be793a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0829/5324] xfs: introduce inode log format object We currently carry around and log an entire inode core in the struct xfs_inode. A lot of the information in the inode core is duplicated in the VFS inode, but we cannot remove this duplication of infomration because the inode core is logged directly in xfs_inode_item_format(). Add a new function xfs_inode_item_format_core() that copies the inode core data into a struct xfs_icdinode that is pulled directly from the log vector buffer. This means we no longer directly copy the inode core, but copy the structures one member at a time. This will be slightly less efficient than copying, but will allow us to remove duplicate and unnecessary items from the struct xfs_inode. To enable us to do this, call the new structure a xfs_log_dinode, so that we know it's different to the physical xfs_dinode and the in-core xfs_icdinode. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 8 +-- fs/xfs/libxfs/xfs_inode_buf.h | 53 +++++++++++++- fs/xfs/libxfs/xfs_log_format.h | 15 ++-- fs/xfs/xfs_icache.c | 2 +- fs/xfs/xfs_inode.h | 2 +- fs/xfs/xfs_inode_item.c | 128 +++++++++++++++++++++++++++++++-- fs/xfs/xfs_inode_item.h | 2 + fs/xfs/xfs_log_recover.c | 52 +++++++------- 8 files changed, 218 insertions(+), 44 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 1aabfda669b0..63d46bf65540 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -196,8 +196,8 @@ xfs_imap_to_bp( void xfs_dinode_from_disk( - xfs_icdinode_t *to, - xfs_dinode_t *from) + struct xfs_icdinode *to, + struct xfs_dinode *from) { to->di_magic = be16_to_cpu(from->di_magic); to->di_mode = be16_to_cpu(from->di_mode); @@ -243,8 +243,8 @@ xfs_dinode_from_disk( void xfs_dinode_to_disk( - xfs_dinode_t *to, - xfs_icdinode_t *from) + struct xfs_dinode *to, + struct xfs_icdinode *from) { to->di_magic = cpu_to_be16(from->di_magic); to->di_mode = cpu_to_be16(from->di_mode); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 9308c47f2a52..642f2a297c26 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -20,7 +20,58 @@ struct xfs_inode; struct xfs_dinode; -struct xfs_icdinode; + +/* + * In memory representation of the XFS inode. This is held in the in-core + * struct xfs_inode to represent the on disk values, but no longer needs to be + * identical to the on-disk structure as it is always translated to on-disk + * format specific structures at the appropriate time. + */ +struct xfs_icdinode { + __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ + __uint16_t di_mode; /* mode and type of file */ + __int8_t di_version; /* inode version */ + __int8_t di_format; /* format of di_c data */ + __uint16_t di_onlink; /* old number of links to file */ + __uint32_t di_uid; /* owner's user id */ + __uint32_t di_gid; /* owner's group id */ + __uint32_t di_nlink; /* number of links to file */ + __uint16_t di_projid_lo; /* lower part of owner's project id */ + __uint16_t di_projid_hi; /* higher part of owner's project id */ + __uint8_t di_pad[6]; /* unused, zeroed space */ + __uint16_t di_flushiter; /* incremented on flush */ + xfs_ictimestamp_t di_atime; /* time last accessed */ + xfs_ictimestamp_t di_mtime; /* time last modified */ + xfs_ictimestamp_t di_ctime; /* time created/inode modified */ + xfs_fsize_t di_size; /* number of bytes in file */ + xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ + xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ + xfs_extnum_t di_nextents; /* number of extents in data fork */ + xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ + __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ + __int8_t di_aformat; /* format of attr fork's data */ + __uint32_t di_dmevmask; /* DMIG event mask */ + __uint16_t di_dmstate; /* DMIG state info */ + __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ + __uint32_t di_gen; /* generation number */ + + /* di_next_unlinked is the only non-core field in the old dinode */ + xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ + + /* start of the extended dinode, writable fields */ + __uint32_t di_crc; /* CRC of the inode */ + __uint64_t di_changecount; /* number of attribute changes */ + xfs_lsn_t di_lsn; /* flush sequence */ + __uint64_t di_flags2; /* more random flags */ + __uint8_t di_pad2[16]; /* more padding for future expansion */ + + /* fields only written to during inode creation */ + xfs_ictimestamp_t di_crtime; /* time created */ + xfs_ino_t di_ino; /* inode number */ + uuid_t di_uuid; /* UUID of the filesystem */ + + /* structure must be padded to 64 bit alignment */ +}; /* * Inode location information. Stored in the inode and passed to diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index 265314690415..d00ed639e0bc 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -290,6 +290,7 @@ typedef struct xfs_inode_log_format_64 { __int32_t ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_64_t; + /* * Flags for xfs_trans_log_inode flags field. */ @@ -360,10 +361,10 @@ typedef struct xfs_ictimestamp { } xfs_ictimestamp_t; /* - * NOTE: This structure must be kept identical to struct xfs_dinode - * except for the endianness annotations. + * Define the format of the inode core that is logged. This structure must be + * kept identical to struct xfs_dinode except for the endianness annotations. */ -typedef struct xfs_icdinode { +struct xfs_log_dinode { __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ @@ -407,13 +408,13 @@ typedef struct xfs_icdinode { uuid_t di_uuid; /* UUID of the filesystem */ /* structure must be padded to 64 bit alignment */ -} xfs_icdinode_t; +}; -static inline uint xfs_icdinode_size(int version) +static inline uint xfs_log_dinode_size(int version) { if (version == 3) - return sizeof(struct xfs_icdinode); - return offsetof(struct xfs_icdinode, di_next_unlinked); + return sizeof(struct xfs_log_dinode); + return offsetof(struct xfs_log_dinode, di_next_unlinked); } /* diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index d7a490f24ead..7c26f8611891 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -79,7 +79,7 @@ xfs_inode_alloc( memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); ip->i_flags = 0; ip->i_delayed_blks = 0; - memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); + memset(&ip->i_d, 0, sizeof(ip->i_d)); return ip; } diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e11989cbd..aef5452b1a90 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -63,7 +63,7 @@ typedef struct xfs_inode { unsigned long i_flags; /* see defined flags below */ unsigned int i_delayed_blks; /* count of delay alloc blks */ - xfs_icdinode_t i_d; /* most of ondisk inode */ + struct xfs_icdinode i_d; /* most of ondisk inode */ /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index d14b12b8cfef..3ad997278869 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -135,7 +135,7 @@ xfs_inode_item_size( *nvecs += 2; *nbytes += sizeof(struct xfs_inode_log_format) + - xfs_icdinode_size(ip->i_d.di_version); + xfs_log_dinode_size(ip->i_d.di_version); xfs_inode_item_data_fork_size(iip, nvecs, nbytes); if (XFS_IFORK_Q(ip)) @@ -322,6 +322,127 @@ xfs_inode_item_format_attr_fork( } } +static void +xfs_icdinode_to_log_dinode( + struct xfs_icdinode *from, + struct xfs_log_dinode *to) +{ + to->di_magic = from->di_magic; + to->di_mode = from->di_mode; + to->di_version = from->di_version; + to->di_format = from->di_format; + to->di_onlink = from->di_onlink; + to->di_uid = from->di_uid; + to->di_gid = from->di_gid; + to->di_nlink = from->di_nlink; + to->di_projid_lo = from->di_projid_lo; + to->di_projid_hi = from->di_projid_hi; + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_atime.t_sec = from->di_atime.t_sec; + to->di_atime.t_nsec = from->di_atime.t_nsec; + to->di_mtime.t_sec = from->di_mtime.t_sec; + to->di_mtime.t_nsec = from->di_mtime.t_nsec; + to->di_ctime.t_sec = from->di_ctime.t_sec; + to->di_ctime.t_nsec = from->di_ctime.t_nsec; + to->di_size = from->di_size; + to->di_nblocks = from->di_nblocks; + to->di_extsize = from->di_extsize; + to->di_nextents = from->di_nextents; + to->di_anextents = from->di_anextents; + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = from->di_dmevmask; + to->di_dmstate = from->di_dmstate; + to->di_flags = from->di_flags; + to->di_gen = from->di_gen; + + if (from->di_version == 3) { + to->di_changecount = from->di_changecount; + to->di_crtime.t_sec = from->di_crtime.t_sec; + to->di_crtime.t_nsec = from->di_crtime.t_nsec; + to->di_flags2 = from->di_flags2; + to->di_ino = from->di_ino; + to->di_lsn = from->di_lsn; + memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &from->di_uuid); + to->di_flushiter = 0; + } else { + to->di_flushiter = from->di_flushiter; + } +} + +/* + * Recovery needs to be able to convert a log dinode back to a real dinode + * for writeback we do that by converting a log dinode to a icdinode, and + * then passing that to the formatting function. + */ +void +xfs_log_dinode_to_icdinode( + struct xfs_log_dinode *from, + struct xfs_icdinode *to) +{ + to->di_magic = from->di_magic; + to->di_mode = from->di_mode; + to->di_version = from->di_version; + to->di_format = from->di_format; + to->di_onlink = from->di_onlink; + to->di_uid = from->di_uid; + to->di_gid = from->di_gid; + to->di_nlink = from->di_nlink; + to->di_projid_lo = from->di_projid_lo; + to->di_projid_hi = from->di_projid_hi; + memset(to->di_pad, 0, sizeof(to->di_pad)); + to->di_atime.t_sec = from->di_atime.t_sec; + to->di_atime.t_nsec = from->di_atime.t_nsec; + to->di_mtime.t_sec = from->di_mtime.t_sec; + to->di_mtime.t_nsec = from->di_mtime.t_nsec; + to->di_ctime.t_sec = from->di_ctime.t_sec; + to->di_ctime.t_nsec = from->di_ctime.t_nsec; + to->di_size = from->di_size; + to->di_nblocks = from->di_nblocks; + to->di_extsize = from->di_extsize; + to->di_nextents = from->di_nextents; + to->di_anextents = from->di_anextents; + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = from->di_dmevmask; + to->di_dmstate = from->di_dmstate; + to->di_flags = from->di_flags; + to->di_gen = from->di_gen; + + if (from->di_version == 3) { + to->di_changecount = from->di_changecount; + to->di_crtime.t_sec = from->di_crtime.t_sec; + to->di_crtime.t_nsec = from->di_crtime.t_nsec; + to->di_flags2 = from->di_flags2; + to->di_ino = from->di_ino; + to->di_lsn = from->di_lsn; + memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &from->di_uuid); + to->di_flushiter = 0; + } else { + to->di_flushiter = from->di_flushiter; + } +} + +/* + * Format the inode core. Current timestamp data is only in the VFS inode + * fields, so we need to grab them from there. Hence rather than just copying + * the XFS inode core structure, format the fields directly into the iovec. + */ +static void +xfs_inode_item_format_core( + struct xfs_inode *ip, + struct xfs_log_vec *lv, + struct xfs_log_iovec **vecp) +{ + struct xfs_log_dinode *dic; + + dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE); + xfs_icdinode_to_log_dinode(&ip->i_d, dic); + xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version)); +} + /* * This is called to fill in the vector of log iovecs for the given inode * log item. It fills the first item with an inode log format structure, @@ -351,10 +472,7 @@ xfs_inode_item_format( ilf->ilf_size = 2; /* format + core */ xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); - xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, - &ip->i_d, - xfs_icdinode_size(ip->i_d.di_version)); - + xfs_inode_item_format_core(ip, lv, &vecp); xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); if (XFS_IFORK_Q(ip)) { xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp); diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 4c7722e325b3..24261180ba66 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -49,6 +49,8 @@ extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *); extern void xfs_iflush_abort(struct xfs_inode *, bool); extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, xfs_inode_log_format_t *); +extern void xfs_log_dinode_to_icdinode(struct xfs_log_dinode *from, + struct xfs_icdinode *to); extern struct kmem_zone *xfs_ili_zone; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index da37beb76f6e..3120f7bbb180 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2839,7 +2839,8 @@ xlog_recover_inode_pass2( int error; int attr_index; uint fields; - xfs_icdinode_t *dicp; + struct xfs_log_dinode *ldip; + struct xfs_icdinode icic; uint isize; int need_free = 0; @@ -2892,8 +2893,8 @@ xlog_recover_inode_pass2( error = -EFSCORRUPTED; goto out_release; } - dicp = item->ri_buf[1].i_addr; - if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { + ldip = item->ri_buf[1].i_addr; + if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) { xfs_alert(mp, "%s: Bad inode log record, rec ptr 0x%p, ino %Ld", __func__, item, in_f->ilf_ino); @@ -2929,13 +2930,13 @@ xlog_recover_inode_pass2( * to skip replay when the on disk inode is newer than the log one */ if (!xfs_sb_version_hascrc(&mp->m_sb) && - dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { + ldip->di_flushiter < be16_to_cpu(dip->di_flushiter)) { /* * Deal with the wrap case, DI_MAX_FLUSH is less * than smaller numbers */ if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH && - dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) { + ldip->di_flushiter < (DI_MAX_FLUSH >> 1)) { /* do nothing */ } else { trace_xfs_log_recover_inode_skip(log, in_f); @@ -2945,13 +2946,13 @@ xlog_recover_inode_pass2( } /* Take the opportunity to reset the flush iteration count */ - dicp->di_flushiter = 0; + ldip->di_flushiter = 0; - if (unlikely(S_ISREG(dicp->di_mode))) { - if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && - (dicp->di_format != XFS_DINODE_FMT_BTREE)) { + if (unlikely(S_ISREG(ldip->di_mode))) { + if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) && + (ldip->di_format != XFS_DINODE_FMT_BTREE)) { XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", - XFS_ERRLEVEL_LOW, mp, dicp); + XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, "%s: Bad regular inode log record, rec ptr 0x%p, " "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", @@ -2959,12 +2960,12 @@ xlog_recover_inode_pass2( error = -EFSCORRUPTED; goto out_release; } - } else if (unlikely(S_ISDIR(dicp->di_mode))) { - if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && - (dicp->di_format != XFS_DINODE_FMT_BTREE) && - (dicp->di_format != XFS_DINODE_FMT_LOCAL)) { + } else if (unlikely(S_ISDIR(ldip->di_mode))) { + if ((ldip->di_format != XFS_DINODE_FMT_EXTENTS) && + (ldip->di_format != XFS_DINODE_FMT_BTREE) && + (ldip->di_format != XFS_DINODE_FMT_LOCAL)) { XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", - XFS_ERRLEVEL_LOW, mp, dicp); + XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, "%s: Bad dir inode log record, rec ptr 0x%p, " "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", @@ -2973,32 +2974,32 @@ xlog_recover_inode_pass2( goto out_release; } } - if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ + if (unlikely(ldip->di_nextents + ldip->di_anextents > ldip->di_nblocks)){ XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", - XFS_ERRLEVEL_LOW, mp, dicp); + XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld", __func__, item, dip, bp, in_f->ilf_ino, - dicp->di_nextents + dicp->di_anextents, - dicp->di_nblocks); + ldip->di_nextents + ldip->di_anextents, + ldip->di_nblocks); error = -EFSCORRUPTED; goto out_release; } - if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { + if (unlikely(ldip->di_forkoff > mp->m_sb.sb_inodesize)) { XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", - XFS_ERRLEVEL_LOW, mp, dicp); + XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__, - item, dip, bp, in_f->ilf_ino, dicp->di_forkoff); + item, dip, bp, in_f->ilf_ino, ldip->di_forkoff); error = -EFSCORRUPTED; goto out_release; } - isize = xfs_icdinode_size(dicp->di_version); + isize = xfs_log_dinode_size(ldip->di_version); if (unlikely(item->ri_buf[1].i_len > isize)) { XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", - XFS_ERRLEVEL_LOW, mp, dicp); + XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, "%s: Bad inode log record length %d, rec ptr 0x%p", __func__, item->ri_buf[1].i_len, item); @@ -3007,7 +3008,8 @@ xlog_recover_inode_pass2( } /* The core is in in-core format */ - xfs_dinode_to_disk(dip, dicp); + xfs_log_dinode_to_icdinode(ldip, &icic); + xfs_dinode_to_disk(dip, &icic); /* the rest is in on-disk format */ if (item->ri_buf[1].i_len > isize) { -- GitLab From 3987848c7c2be112e03c82d03821b044f1c0edec Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0830/5324] xfs: remove timestamps from incore inode The struct xfs_inode has two copies of the current timestamps in it, one in the vfs inode and one in the struct xfs_icdinode. Now that we no longer log the struct xfs_icdinode directly, we don't need to keep the timestamps in this structure. instead we can copy them straight out of the VFS inode when formatting the inode log item or the on-disk inode. This reduces the struct xfs_inode in size by 24 bytes. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 91 ++++++++++++++++++++++++++++++----- fs/xfs/libxfs/xfs_inode_buf.h | 9 ++-- fs/xfs/libxfs/xfs_rtbitmap.c | 2 +- fs/xfs/xfs_inode.c | 21 ++++---- fs/xfs/xfs_inode_item.c | 73 +++++----------------------- fs/xfs/xfs_inode_item.h | 2 - fs/xfs/xfs_iops.c | 37 +++----------- fs/xfs/xfs_itable.c | 16 +++--- fs/xfs/xfs_log_recover.c | 8 ++- fs/xfs/xfs_rtalloc.c | 2 +- fs/xfs/xfs_trans_inode.c | 12 +---- 11 files changed, 130 insertions(+), 143 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 63d46bf65540..e832bb2ab4f9 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -195,10 +195,13 @@ xfs_imap_to_bp( } void -xfs_dinode_from_disk( - struct xfs_icdinode *to, +xfs_inode_from_disk( + struct xfs_inode *ip, struct xfs_dinode *from) { + struct xfs_icdinode *to = &ip->i_d; + struct inode *inode = VFS_I(ip); + to->di_magic = be16_to_cpu(from->di_magic); to->di_mode = be16_to_cpu(from->di_mode); to->di_version = from ->di_version; @@ -211,12 +214,20 @@ xfs_dinode_from_disk( to->di_projid_hi = be16_to_cpu(from->di_projid_hi); memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); to->di_flushiter = be16_to_cpu(from->di_flushiter); - to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); - to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); - to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); - to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); - to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); - to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); + + /* + * Time is signed, so need to convert to signed 32 bit before + * storing in inode timestamp which may be 64 bit. Otherwise + * a time before epoch is converted to a time long after epoch + * on 64 bit systems. + */ + inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec); + inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec); + inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec); + inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec); + inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec); + inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec); + to->di_size = be64_to_cpu(from->di_size); to->di_nblocks = be64_to_cpu(from->di_nblocks); to->di_extsize = be32_to_cpu(from->di_extsize); @@ -242,9 +253,63 @@ xfs_dinode_from_disk( } void -xfs_dinode_to_disk( - struct xfs_dinode *to, - struct xfs_icdinode *from) +xfs_inode_to_disk( + struct xfs_inode *ip, + struct xfs_dinode *to) +{ + struct xfs_icdinode *from = &ip->i_d; + struct inode *inode = VFS_I(ip); + + to->di_magic = cpu_to_be16(from->di_magic); + to->di_mode = cpu_to_be16(from->di_mode); + to->di_version = from ->di_version; + to->di_format = from->di_format; + to->di_onlink = cpu_to_be16(from->di_onlink); + to->di_uid = cpu_to_be32(from->di_uid); + to->di_gid = cpu_to_be32(from->di_gid); + to->di_nlink = cpu_to_be32(from->di_nlink); + to->di_projid_lo = cpu_to_be16(from->di_projid_lo); + to->di_projid_hi = cpu_to_be16(from->di_projid_hi); + memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + + to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec); + to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec); + to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec); + to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec); + to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec); + to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); + + to->di_size = cpu_to_be64(from->di_size); + to->di_nblocks = cpu_to_be64(from->di_nblocks); + to->di_extsize = cpu_to_be32(from->di_extsize); + to->di_nextents = cpu_to_be32(from->di_nextents); + to->di_anextents = cpu_to_be16(from->di_anextents); + to->di_forkoff = from->di_forkoff; + to->di_aformat = from->di_aformat; + to->di_dmevmask = cpu_to_be32(from->di_dmevmask); + to->di_dmstate = cpu_to_be16(from->di_dmstate); + to->di_flags = cpu_to_be16(from->di_flags); + to->di_gen = cpu_to_be32(from->di_gen); + + if (from->di_version == 3) { + to->di_changecount = cpu_to_be64(from->di_changecount); + to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); + to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); + to->di_flags2 = cpu_to_be64(from->di_flags2); + to->di_ino = cpu_to_be64(from->di_ino); + to->di_lsn = cpu_to_be64(from->di_lsn); + memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &from->di_uuid); + to->di_flushiter = 0; + } else { + to->di_flushiter = cpu_to_be16(from->di_flushiter); + } +} + +void +xfs_log_dinode_to_disk( + struct xfs_log_dinode *from, + struct xfs_dinode *to) { to->di_magic = cpu_to_be16(from->di_magic); to->di_mode = cpu_to_be16(from->di_mode); @@ -257,12 +322,14 @@ xfs_dinode_to_disk( to->di_projid_lo = cpu_to_be16(from->di_projid_lo); to->di_projid_hi = cpu_to_be16(from->di_projid_hi); memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); + to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); to->di_extsize = cpu_to_be32(from->di_extsize); @@ -403,7 +470,7 @@ xfs_iread( * Otherwise, just get the truly permanent information. */ if (dip->di_mode) { - xfs_dinode_from_disk(&ip->i_d, dip); + xfs_inode_from_disk(ip, dip); error = xfs_iformat_fork(ip, dip); if (error) { #ifdef DEBUG diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 642f2a297c26..adcc9bfe02e9 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -40,9 +40,6 @@ struct xfs_icdinode { __uint16_t di_projid_hi; /* higher part of owner's project id */ __uint8_t di_pad[6]; /* unused, zeroed space */ __uint16_t di_flushiter; /* incremented on flush */ - xfs_ictimestamp_t di_atime; /* time last accessed */ - xfs_ictimestamp_t di_mtime; /* time last modified */ - xfs_ictimestamp_t di_ctime; /* time created/inode modified */ xfs_fsize_t di_size; /* number of bytes in file */ xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ @@ -89,8 +86,10 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, int xfs_iread(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, uint); void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); -void xfs_dinode_to_disk(struct xfs_dinode *to, struct xfs_icdinode *from); -void xfs_dinode_from_disk(struct xfs_icdinode *to, struct xfs_dinode *from); +void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to); +void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from); +void xfs_log_dinode_to_disk(struct xfs_log_dinode *from, + struct xfs_dinode *to); #if defined(DEBUG) void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 9b59ffa1fc19..acc71dd36a2b 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -983,7 +983,7 @@ xfs_rtfree_extent( mp->m_sb.sb_rextents) { if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; - *(__uint64_t *)&mp->m_rbmip->i_d.di_atime = 0; + *(__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0; xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); } return 0; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ceba1a83cacc..9ad9e355a1c0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -766,6 +766,7 @@ xfs_ialloc( uint flags; int error; struct timespec tv; + struct inode *inode; /* * Call the space management code to pick @@ -791,6 +792,7 @@ xfs_ialloc( if (error) return error; ASSERT(ip != NULL); + inode = VFS_I(ip); /* * We always convert v1 inodes to v2 now - we only support filesystems @@ -832,10 +834,9 @@ xfs_ialloc( ASSERT(ip->i_d.di_nblocks == 0); tv = current_fs_time(mp->m_super); - ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; - ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; - ip->i_d.di_atime = ip->i_d.di_mtime; - ip->i_d.di_ctime = ip->i_d.di_mtime; + inode->i_mtime = tv; + inode->i_atime = tv; + inode->i_ctime = tv; /* * di_gen will have been taken care of in xfs_iread. @@ -853,7 +854,8 @@ xfs_ialloc( ip->i_d.di_lsn = 0; ip->i_d.di_flags2 = 0; memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); - ip->i_d.di_crtime = ip->i_d.di_mtime; + ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec; + ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec; } @@ -3523,12 +3525,11 @@ xfs_iflush_int( ip->i_d.di_flushiter++; /* - * Copy the dirty parts of the inode into the on-disk - * inode. We always copy out the core of the inode, - * because if the inode is dirty at all the core must - * be. + * Copy the dirty parts of the inode into the on-disk inode. We always + * copy out the core of the inode, because if the inode is dirty at all + * the core must be. */ - xfs_dinode_to_disk(dip, &ip->i_d); + xfs_inode_to_disk(ip, dip); /* Wrap, we never let the log put out DI_MAX_FLUSH */ if (ip->i_d.di_flushiter == DI_MAX_FLUSH) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 3ad997278869..9dcbf584a336 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -323,10 +323,13 @@ xfs_inode_item_format_attr_fork( } static void -xfs_icdinode_to_log_dinode( - struct xfs_icdinode *from, +xfs_inode_to_log_dinode( + struct xfs_inode *ip, struct xfs_log_dinode *to) { + struct xfs_icdinode *from = &ip->i_d; + struct inode *inode = VFS_I(ip); + to->di_magic = from->di_magic; to->di_mode = from->di_mode; to->di_version = from->di_version; @@ -338,66 +341,14 @@ xfs_icdinode_to_log_dinode( to->di_projid_lo = from->di_projid_lo; to->di_projid_hi = from->di_projid_hi; memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); - to->di_atime.t_sec = from->di_atime.t_sec; - to->di_atime.t_nsec = from->di_atime.t_nsec; - to->di_mtime.t_sec = from->di_mtime.t_sec; - to->di_mtime.t_nsec = from->di_mtime.t_nsec; - to->di_ctime.t_sec = from->di_ctime.t_sec; - to->di_ctime.t_nsec = from->di_ctime.t_nsec; - to->di_size = from->di_size; - to->di_nblocks = from->di_nblocks; - to->di_extsize = from->di_extsize; - to->di_nextents = from->di_nextents; - to->di_anextents = from->di_anextents; - to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; - to->di_dmevmask = from->di_dmevmask; - to->di_dmstate = from->di_dmstate; - to->di_flags = from->di_flags; - to->di_gen = from->di_gen; - if (from->di_version == 3) { - to->di_changecount = from->di_changecount; - to->di_crtime.t_sec = from->di_crtime.t_sec; - to->di_crtime.t_nsec = from->di_crtime.t_nsec; - to->di_flags2 = from->di_flags2; - to->di_ino = from->di_ino; - to->di_lsn = from->di_lsn; - memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - uuid_copy(&to->di_uuid, &from->di_uuid); - to->di_flushiter = 0; - } else { - to->di_flushiter = from->di_flushiter; - } -} + to->di_atime.t_sec = inode->i_atime.tv_sec; + to->di_atime.t_nsec = inode->i_atime.tv_nsec; + to->di_mtime.t_sec = inode->i_mtime.tv_sec; + to->di_mtime.t_nsec = inode->i_mtime.tv_nsec; + to->di_ctime.t_sec = inode->i_ctime.tv_sec; + to->di_ctime.t_nsec = inode->i_ctime.tv_nsec; -/* - * Recovery needs to be able to convert a log dinode back to a real dinode - * for writeback we do that by converting a log dinode to a icdinode, and - * then passing that to the formatting function. - */ -void -xfs_log_dinode_to_icdinode( - struct xfs_log_dinode *from, - struct xfs_icdinode *to) -{ - to->di_magic = from->di_magic; - to->di_mode = from->di_mode; - to->di_version = from->di_version; - to->di_format = from->di_format; - to->di_onlink = from->di_onlink; - to->di_uid = from->di_uid; - to->di_gid = from->di_gid; - to->di_nlink = from->di_nlink; - to->di_projid_lo = from->di_projid_lo; - to->di_projid_hi = from->di_projid_hi; - memset(to->di_pad, 0, sizeof(to->di_pad)); - to->di_atime.t_sec = from->di_atime.t_sec; - to->di_atime.t_nsec = from->di_atime.t_nsec; - to->di_mtime.t_sec = from->di_mtime.t_sec; - to->di_mtime.t_nsec = from->di_mtime.t_nsec; - to->di_ctime.t_sec = from->di_ctime.t_sec; - to->di_ctime.t_nsec = from->di_ctime.t_nsec; to->di_size = from->di_size; to->di_nblocks = from->di_nblocks; to->di_extsize = from->di_extsize; @@ -439,7 +390,7 @@ xfs_inode_item_format_core( struct xfs_log_dinode *dic; dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE); - xfs_icdinode_to_log_dinode(&ip->i_d, dic); + xfs_inode_to_log_dinode(ip, dic); xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version)); } diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 24261180ba66..4c7722e325b3 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -49,8 +49,6 @@ extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *); extern void xfs_iflush_abort(struct xfs_inode *, bool); extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, xfs_inode_log_format_t *); -extern void xfs_log_dinode_to_icdinode(struct xfs_log_dinode *from, - struct xfs_icdinode *to); extern struct kmem_zone *xfs_ili_zone; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 76b71a1c6c32..cd27c6d56dfc 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -522,21 +522,12 @@ xfs_setattr_time( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - if (iattr->ia_valid & ATTR_ATIME) { + if (iattr->ia_valid & ATTR_ATIME) inode->i_atime = iattr->ia_atime; - ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; - ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; - } - if (iattr->ia_valid & ATTR_CTIME) { + if (iattr->ia_valid & ATTR_CTIME) inode->i_ctime = iattr->ia_ctime; - ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; - ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; - } - if (iattr->ia_valid & ATTR_MTIME) { + if (iattr->ia_valid & ATTR_MTIME) inode->i_mtime = iattr->ia_mtime; - ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; - ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; - } } int @@ -991,21 +982,13 @@ xfs_vn_update_time( } xfs_ilock(ip, XFS_ILOCK_EXCL); - if (flags & S_CTIME) { + if (flags & S_CTIME) inode->i_ctime = *now; - ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec; - ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec; - } - if (flags & S_MTIME) { + if (flags & S_MTIME) inode->i_mtime = *now; - ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec; - ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec; - } - if (flags & S_ATIME) { + if (flags & S_ATIME) inode->i_atime = *now; - ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec; - ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec; - } + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP); return xfs_trans_commit(tp); @@ -1251,12 +1234,6 @@ xfs_setup_inode( inode->i_generation = ip->i_d.di_gen; i_size_write(inode, ip->i_d.di_size); - inode->i_atime.tv_sec = ip->i_d.di_atime.t_sec; - inode->i_atime.tv_nsec = ip->i_d.di_atime.t_nsec; - inode->i_mtime.tv_sec = ip->i_d.di_mtime.t_sec; - inode->i_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; - inode->i_ctime.tv_sec = ip->i_d.di_ctime.t_sec; - inode->i_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; xfs_diflags_to_iflags(inode, ip); ip->d_ops = ip->i_mount->m_nondir_inode_ops; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 930ebd86beba..2acda42319f5 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -57,6 +57,7 @@ xfs_bulkstat_one_int( { struct xfs_icdinode *dic; /* dinode core info pointer */ struct xfs_inode *ip; /* incore inode pointer */ + struct inode *inode; struct xfs_bstat *buf; /* return buffer */ int error = 0; /* error value */ @@ -77,6 +78,7 @@ xfs_bulkstat_one_int( ASSERT(ip != NULL); ASSERT(ip->i_imap.im_blkno != 0); + inode = VFS_I(ip); dic = &ip->i_d; @@ -91,12 +93,14 @@ xfs_bulkstat_one_int( buf->bs_uid = dic->di_uid; buf->bs_gid = dic->di_gid; buf->bs_size = dic->di_size; - buf->bs_atime.tv_sec = dic->di_atime.t_sec; - buf->bs_atime.tv_nsec = dic->di_atime.t_nsec; - buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; - buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; - buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; - buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec; + + buf->bs_atime.tv_sec = inode->i_atime.tv_sec; + buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec; + buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec; + buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec; + buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; + buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; + buf->bs_xflags = xfs_ip2xflags(ip); buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; buf->bs_extents = dic->di_nextents; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 3120f7bbb180..4b79cf006589 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2793,7 +2793,7 @@ xfs_recover_inode_owner_change( return -ENOMEM; /* instantiate the inode */ - xfs_dinode_from_disk(&ip->i_d, dip); + xfs_inode_from_disk(ip, dip); ASSERT(ip->i_d.di_version >= 3); error = xfs_iformat_fork(ip, dip); @@ -2840,7 +2840,6 @@ xlog_recover_inode_pass2( int attr_index; uint fields; struct xfs_log_dinode *ldip; - struct xfs_icdinode icic; uint isize; int need_free = 0; @@ -3007,9 +3006,8 @@ xlog_recover_inode_pass2( goto out_release; } - /* The core is in in-core format */ - xfs_log_dinode_to_icdinode(ldip, &icic); - xfs_dinode_to_disk(dip, &icic); + /* recover the log dinode inode into the on disk inode */ + xfs_log_dinode_to_disk(ldip, dip); /* the rest is in on-disk format */ if (item->ri_buf[1].i_len > isize) { diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index be02a68b2fe2..abf44435d04a 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1272,7 +1272,7 @@ xfs_rtpick_extent( ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); - seqp = (__uint64_t *)&mp->m_rbmip->i_d.di_atime; + seqp = (__uint64_t *)&VFS_I(mp->m_rbmip)->i_atime; if (!(mp->m_rbmip->i_d.di_flags & XFS_DIFLAG_NEWRTBM)) { mp->m_rbmip->i_d.di_flags |= XFS_DIFLAG_NEWRTBM; *seqp = 0; diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index b97f1df910ab..3f0d46655ce5 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -75,18 +75,10 @@ xfs_trans_ichgtime( tv = current_fs_time(inode->i_sb); - if ((flags & XFS_ICHGTIME_MOD) && - !timespec_equal(&inode->i_mtime, &tv)) { + if (flags & XFS_ICHGTIME_MOD) inode->i_mtime = tv; - ip->i_d.di_mtime.t_sec = tv.tv_sec; - ip->i_d.di_mtime.t_nsec = tv.tv_nsec; - } - if ((flags & XFS_ICHGTIME_CHG) && - !timespec_equal(&inode->i_ctime, &tv)) { + if (flags & XFS_ICHGTIME_CHG) inode->i_ctime = tv; - ip->i_d.di_ctime.t_sec = tv.tv_sec; - ip->i_d.di_ctime.t_nsec = tv.tv_nsec; - } } /* -- GitLab From 93f958f9c41f0bfd10627a2279457df64004d957 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0831/5324] xfs: cull unnecessary icdinode fields Now that the struct xfs_icdinode is not directly related to the on-disk format, we can cull things in it we really don't need to store: - magic number never changes - padding is not necessary - next_unlinked is never used - inode number is redundant - uuid is redundant - lsn is accessed directly from dinode - inode CRC is only accessed directly from dinode Hence we can remove these from the struct xfs_icdinode and redirect the code that uses them to the xfs_dinode appripriately. This reduces the size of the struct icdinode from 152 bytes to 88 bytes, and removes a fair chunk of unnecessary code, too. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 39 ++++++++++++----------------------- fs/xfs/libxfs/xfs_inode_buf.h | 25 ++++++---------------- fs/xfs/xfs_inode.c | 19 +---------------- fs/xfs/xfs_inode_item.c | 19 ++++++++++------- 4 files changed, 31 insertions(+), 71 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index e832bb2ab4f9..c0fe062b567a 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -202,7 +202,6 @@ xfs_inode_from_disk( struct xfs_icdinode *to = &ip->i_d; struct inode *inode = VFS_I(ip); - to->di_magic = be16_to_cpu(from->di_magic); to->di_mode = be16_to_cpu(from->di_mode); to->di_version = from ->di_version; to->di_format = from->di_format; @@ -212,7 +211,6 @@ xfs_inode_from_disk( to->di_nlink = be32_to_cpu(from->di_nlink); to->di_projid_lo = be16_to_cpu(from->di_projid_lo); to->di_projid_hi = be16_to_cpu(from->di_projid_hi); - memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); to->di_flushiter = be16_to_cpu(from->di_flushiter); /* @@ -245,24 +243,22 @@ xfs_inode_from_disk( to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); to->di_flags2 = be64_to_cpu(from->di_flags2); - to->di_ino = be64_to_cpu(from->di_ino); - to->di_lsn = be64_to_cpu(from->di_lsn); - memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - uuid_copy(&to->di_uuid, &from->di_uuid); } } void xfs_inode_to_disk( struct xfs_inode *ip, - struct xfs_dinode *to) + struct xfs_dinode *to, + xfs_lsn_t lsn) { struct xfs_icdinode *from = &ip->i_d; struct inode *inode = VFS_I(ip); - to->di_magic = cpu_to_be16(from->di_magic); + to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); + to->di_mode = cpu_to_be16(from->di_mode); - to->di_version = from ->di_version; + to->di_version = from->di_version; to->di_format = from->di_format; to->di_onlink = cpu_to_be16(from->di_onlink); to->di_uid = cpu_to_be32(from->di_uid); @@ -270,8 +266,8 @@ xfs_inode_to_disk( to->di_nlink = cpu_to_be32(from->di_nlink); to->di_projid_lo = cpu_to_be16(from->di_projid_lo); to->di_projid_hi = cpu_to_be16(from->di_projid_hi); - memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + memset(to->di_pad, 0, sizeof(to->di_pad)); to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec); to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec); to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec); @@ -296,10 +292,11 @@ xfs_inode_to_disk( to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); to->di_flags2 = cpu_to_be64(from->di_flags2); - to->di_ino = cpu_to_be64(from->di_ino); - to->di_lsn = cpu_to_be64(from->di_lsn); - memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - uuid_copy(&to->di_uuid, &from->di_uuid); + + to->di_ino = cpu_to_be64(ip->i_ino); + to->di_lsn = cpu_to_be64(lsn); + memset(to->di_pad2, 0, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid); to->di_flushiter = 0; } else { to->di_flushiter = cpu_to_be16(from->di_flushiter); @@ -434,13 +431,10 @@ xfs_iread( !(mp->m_flags & XFS_MOUNT_IKEEP)) { /* initialise the on-disk inode core */ memset(&ip->i_d, 0, sizeof(ip->i_d)); - ip->i_d.di_magic = XFS_DINODE_MAGIC; ip->i_d.di_gen = prandom_u32(); - if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (xfs_sb_version_hascrc(&mp->m_sb)) ip->i_d.di_version = 3; - ip->i_d.di_ino = ip->i_ino; - uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid); - } else + else ip->i_d.di_version = 2; return 0; } @@ -484,16 +478,10 @@ xfs_iread( * Partial initialisation of the in-core inode. Just the bits * that xfs_ialloc won't overwrite or relies on being correct. */ - ip->i_d.di_magic = be16_to_cpu(dip->di_magic); ip->i_d.di_version = dip->di_version; ip->i_d.di_gen = be32_to_cpu(dip->di_gen); ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); - if (dip->di_version == 3) { - ip->i_d.di_ino = be64_to_cpu(dip->di_ino); - uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid); - } - /* * Make sure to pull in the mode here as well in * case the inode is released without being used. @@ -514,7 +502,6 @@ xfs_iread( */ if (ip->i_d.di_version == 1) { ip->i_d.di_version = 2; - memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); ip->i_d.di_nlink = ip->i_d.di_onlink; ip->i_d.di_onlink = 0; xfs_set_projid(ip, 0); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index adcc9bfe02e9..7b8b1b97918b 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -22,24 +22,22 @@ struct xfs_inode; struct xfs_dinode; /* - * In memory representation of the XFS inode. This is held in the in-core - * struct xfs_inode to represent the on disk values, but no longer needs to be - * identical to the on-disk structure as it is always translated to on-disk + * In memory representation of the XFS inode. This is held in the in-core struct + * xfs_inode and represents the current on disk values but the structure is not + * in on-disk format. That is, this structure is always translated to on-disk * format specific structures at the appropriate time. */ struct xfs_icdinode { - __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ __int8_t di_format; /* format of di_c data */ __uint16_t di_onlink; /* old number of links to file */ + __uint16_t di_flushiter; /* incremented on flush */ __uint32_t di_uid; /* owner's user id */ __uint32_t di_gid; /* owner's group id */ __uint32_t di_nlink; /* number of links to file */ __uint16_t di_projid_lo; /* lower part of owner's project id */ __uint16_t di_projid_hi; /* higher part of owner's project id */ - __uint8_t di_pad[6]; /* unused, zeroed space */ - __uint16_t di_flushiter; /* incremented on flush */ xfs_fsize_t di_size; /* number of bytes in file */ xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ @@ -52,22 +50,10 @@ struct xfs_icdinode { __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ __uint32_t di_gen; /* generation number */ - /* di_next_unlinked is the only non-core field in the old dinode */ - xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ - - /* start of the extended dinode, writable fields */ - __uint32_t di_crc; /* CRC of the inode */ __uint64_t di_changecount; /* number of attribute changes */ - xfs_lsn_t di_lsn; /* flush sequence */ __uint64_t di_flags2; /* more random flags */ - __uint8_t di_pad2[16]; /* more padding for future expansion */ - /* fields only written to during inode creation */ xfs_ictimestamp_t di_crtime; /* time created */ - xfs_ino_t di_ino; /* inode number */ - uuid_t di_uuid; /* UUID of the filesystem */ - - /* structure must be padded to 64 bit alignment */ }; /* @@ -86,7 +72,8 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, int xfs_iread(struct xfs_mount *, struct xfs_trans *, struct xfs_inode *, uint); void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); -void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to); +void xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to, + xfs_lsn_t lsn); void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from); void xfs_log_dinode_to_disk(struct xfs_log_dinode *from, struct xfs_dinode *to); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9ad9e355a1c0..45acdee98983 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -809,7 +809,6 @@ xfs_ialloc( ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); xfs_set_projid(ip, prid); - memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); if (pip && XFS_INHERIT_GID(pip)) { ip->i_d.di_gid = pip->i_d.di_gid; @@ -847,13 +846,8 @@ xfs_ialloc( ip->i_d.di_flags = 0; if (ip->i_d.di_version == 3) { - ASSERT(ip->i_d.di_ino == ino); - ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid)); - ip->i_d.di_crc = 0; ip->i_d.di_changecount = 1; - ip->i_d.di_lsn = 0; ip->i_d.di_flags2 = 0; - memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec; } @@ -3464,13 +3458,6 @@ xfs_iflush_int( __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); goto corrupt_out; } - if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, - mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) { - xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x", - __func__, ip->i_ino, ip, ip->i_d.di_magic); - goto corrupt_out; - } if (S_ISREG(ip->i_d.di_mode)) { if (XFS_TEST_ERROR( (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && @@ -3529,7 +3516,7 @@ xfs_iflush_int( * copy out the core of the inode, because if the inode is dirty at all * the core must be. */ - xfs_inode_to_disk(ip, dip); + xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn); /* Wrap, we never let the log put out DI_MAX_FLUSH */ if (ip->i_d.di_flushiter == DI_MAX_FLUSH) @@ -3581,10 +3568,6 @@ xfs_iflush_int( */ xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); - /* update the lsn in the on disk inode if required */ - if (ip->i_d.di_version == 3) - dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn); - /* generate the checksum. */ xfs_dinode_calc_crc(mp, dip); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 9dcbf584a336..588d1b4523cb 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -325,12 +325,14 @@ xfs_inode_item_format_attr_fork( static void xfs_inode_to_log_dinode( struct xfs_inode *ip, - struct xfs_log_dinode *to) + struct xfs_log_dinode *to, + xfs_lsn_t lsn) { struct xfs_icdinode *from = &ip->i_d; struct inode *inode = VFS_I(ip); - to->di_magic = from->di_magic; + to->di_magic = XFS_DINODE_MAGIC; + to->di_mode = from->di_mode; to->di_version = from->di_version; to->di_format = from->di_format; @@ -340,8 +342,8 @@ xfs_inode_to_log_dinode( to->di_nlink = from->di_nlink; to->di_projid_lo = from->di_projid_lo; to->di_projid_hi = from->di_projid_hi; - memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); + memset(to->di_pad, 0, sizeof(to->di_pad)); to->di_atime.t_sec = inode->i_atime.tv_sec; to->di_atime.t_nsec = inode->i_atime.tv_nsec; to->di_mtime.t_sec = inode->i_mtime.tv_sec; @@ -366,10 +368,11 @@ xfs_inode_to_log_dinode( to->di_crtime.t_sec = from->di_crtime.t_sec; to->di_crtime.t_nsec = from->di_crtime.t_nsec; to->di_flags2 = from->di_flags2; - to->di_ino = from->di_ino; - to->di_lsn = from->di_lsn; - memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); - uuid_copy(&to->di_uuid, &from->di_uuid); + + to->di_ino = ip->i_ino; + to->di_lsn = lsn; + memset(to->di_pad2, 0, sizeof(to->di_pad2)); + uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid); to->di_flushiter = 0; } else { to->di_flushiter = from->di_flushiter; @@ -390,7 +393,7 @@ xfs_inode_item_format_core( struct xfs_log_dinode *dic; dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE); - xfs_inode_to_log_dinode(ip, dic); + xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn); xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version)); } -- GitLab From faeb4e4715be017e88e630bda84477afc1dff38b Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0832/5324] xfs: move v1 inode conversion to xfs_inode_from_disk So we don't have to carry an di_onlink variable around anymore, move the inode conversion from v1 inode format to v2 inode format into xfs_inode_from_disk(). This means we can remove the di_onlink fields from the struct xfs_icdinode. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 42 ++++++++++++++++------------------ fs/xfs/libxfs/xfs_inode_buf.h | 1 - fs/xfs/libxfs/xfs_log_format.h | 2 +- fs/xfs/xfs_inode.c | 2 -- fs/xfs/xfs_inode_item.c | 2 +- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index c0fe062b567a..fe8f4f349b37 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -204,13 +204,25 @@ xfs_inode_from_disk( to->di_mode = be16_to_cpu(from->di_mode); to->di_version = from ->di_version; + + /* + * Convert v1 inodes immediately to v2 inode format as this is the + * minimum inode version format we support in the rest of the code. + */ + if (to->di_version == 1) { + to->di_nlink = be16_to_cpu(from->di_onlink); + to->di_projid_lo = 0; + to->di_projid_hi = 0; + to->di_version = 2; + } else { + to->di_nlink = be32_to_cpu(from->di_nlink); + to->di_projid_lo = be16_to_cpu(from->di_projid_lo); + to->di_projid_hi = be16_to_cpu(from->di_projid_hi); + } + to->di_format = from->di_format; - to->di_onlink = be16_to_cpu(from->di_onlink); to->di_uid = be32_to_cpu(from->di_uid); to->di_gid = be32_to_cpu(from->di_gid); - to->di_nlink = be32_to_cpu(from->di_nlink); - to->di_projid_lo = be16_to_cpu(from->di_projid_lo); - to->di_projid_hi = be16_to_cpu(from->di_projid_hi); to->di_flushiter = be16_to_cpu(from->di_flushiter); /* @@ -256,11 +268,11 @@ xfs_inode_to_disk( struct inode *inode = VFS_I(ip); to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); + to->di_onlink = 0; to->di_mode = cpu_to_be16(from->di_mode); to->di_version = from->di_version; to->di_format = from->di_format; - to->di_onlink = cpu_to_be16(from->di_onlink); to->di_uid = cpu_to_be32(from->di_uid); to->di_gid = cpu_to_be32(from->di_gid); to->di_nlink = cpu_to_be32(from->di_nlink); @@ -310,9 +322,9 @@ xfs_log_dinode_to_disk( { to->di_magic = cpu_to_be16(from->di_magic); to->di_mode = cpu_to_be16(from->di_mode); - to->di_version = from ->di_version; + to->di_version = from->di_version; to->di_format = from->di_format; - to->di_onlink = cpu_to_be16(from->di_onlink); + to->di_onlink = 0; to->di_uid = cpu_to_be32(from->di_uid); to->di_gid = cpu_to_be32(from->di_gid); to->di_nlink = cpu_to_be32(from->di_nlink); @@ -492,21 +504,7 @@ xfs_iread( ip->i_d.di_mode = 0; } - /* - * Automatically convert version 1 inode formats in memory to version 2 - * inode format. If the inode is modified, it will get logged and - * rewritten as a version 2 inode. We can do this because we set the - * superblock feature bit for v2 inodes unconditionally during mount - * and it means the reast of the code can assume the inode version is 2 - * or higher. - */ - if (ip->i_d.di_version == 1) { - ip->i_d.di_version = 2; - ip->i_d.di_nlink = ip->i_d.di_onlink; - ip->i_d.di_onlink = 0; - xfs_set_projid(ip, 0); - } - + ASSERT(ip->i_d.di_version >= 2); ip->i_delayed_blks = 0; /* diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 7b8b1b97918b..73ba1d8ffac2 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -31,7 +31,6 @@ struct xfs_icdinode { __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ __int8_t di_format; /* format of di_c data */ - __uint16_t di_onlink; /* old number of links to file */ __uint16_t di_flushiter; /* incremented on flush */ __uint32_t di_uid; /* owner's user id */ __uint32_t di_gid; /* owner's group id */ diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index d00ed639e0bc..03f90b99b8c8 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -369,7 +369,7 @@ struct xfs_log_dinode { __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ __int8_t di_format; /* format of di_c data */ - __uint16_t di_onlink; /* old number of links to file */ + __uint8_t di_pad3[2]; /* unused in v2/3 inodes */ __uint32_t di_uid; /* owner's user id */ __uint32_t di_gid; /* owner's group id */ __uint32_t di_nlink; /* number of links to file */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 45acdee98983..7d9c514fd231 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -803,9 +803,7 @@ xfs_ialloc( ip->i_d.di_version = 2; ip->i_d.di_mode = mode; - ip->i_d.di_onlink = 0; ip->i_d.di_nlink = nlink; - ASSERT(ip->i_d.di_nlink == nlink); ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); xfs_set_projid(ip, prid); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 588d1b4523cb..1e5ecbc45459 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -336,7 +336,6 @@ xfs_inode_to_log_dinode( to->di_mode = from->di_mode; to->di_version = from->di_version; to->di_format = from->di_format; - to->di_onlink = from->di_onlink; to->di_uid = from->di_uid; to->di_gid = from->di_gid; to->di_nlink = from->di_nlink; @@ -344,6 +343,7 @@ xfs_inode_to_log_dinode( to->di_projid_hi = from->di_projid_hi; memset(to->di_pad, 0, sizeof(to->di_pad)); + memset(to->di_pad3, 0, sizeof(to->di_pad3)); to->di_atime.t_sec = inode->i_atime.tv_sec; to->di_atime.t_nsec = inode->i_atime.tv_nsec; to->di_mtime.t_sec = inode->i_mtime.tv_sec; -- GitLab From 50997470ef95fd8ae0ef6acab3b2e1d886ae2445 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0833/5324] xfs: reinitialise recycled VFS inode correctly We are going to keep certain on-disk information in the VFS inode rather than in a separate XFS specific stucture, so we have to be careful of the VFS code clearing that information when we re-initialise reclaimable cached inodes during lookup. If we don't do this, then we lose critical information from the inode and that results in corruption being detected. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_icache.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 7c26f8611891..9ca2865575ab 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -134,6 +134,26 @@ xfs_inode_free( call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); } +/* + * When we recycle a reclaimable inode, we need to re-initialise the VFS inode + * part of the structure. This is made more complex by the fact we store + * information about the on-disk values in the VFS inode and so we can't just + * overwrite it's values unconditionally. Hence we save the parameters we + * need to retain across reinitialisation, and rewrite them into the VFS inode + * after resetting it's state even if resetting fails. + */ +static int +xfs_reinit_inode( + struct xfs_mount *mp, + struct inode *inode) +{ + int error; + + error = inode_init_always(mp->m_super, inode); + + return error; +} + /* * Check the validity of the inode we just found it the cache */ @@ -208,7 +228,7 @@ xfs_iget_cache_hit( spin_unlock(&ip->i_flags_lock); rcu_read_unlock(); - error = inode_init_always(mp->m_super, inode); + error = xfs_reinit_inode(mp, inode); if (error) { /* * Re-initializing the inode failed, and we are in deep -- GitLab From 54d7b5c1d03e9711cce2d72237d5b3f5c87431f4 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0834/5324] xfs: use vfs inode nlink field everywhere The VFS tracks the inode nlink just like the xfs_icdinode. We can remove the variable from the icdinode and use the VFS inode variable everywhere, reducing the size of the xfs_icdinode by a further 4 bytes. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 6 +-- fs/xfs/libxfs/xfs_inode_buf.h | 1 - fs/xfs/xfs_icache.c | 2 + fs/xfs/xfs_inode.c | 77 ++++++++++++++++------------------- fs/xfs/xfs_inode.h | 2 - fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_iops.c | 3 +- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_log_recover.c | 2 +- 9 files changed, 43 insertions(+), 54 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index fe8f4f349b37..cc509c1af75e 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -210,12 +210,12 @@ xfs_inode_from_disk( * minimum inode version format we support in the rest of the code. */ if (to->di_version == 1) { - to->di_nlink = be16_to_cpu(from->di_onlink); + set_nlink(inode, be16_to_cpu(from->di_onlink)); to->di_projid_lo = 0; to->di_projid_hi = 0; to->di_version = 2; } else { - to->di_nlink = be32_to_cpu(from->di_nlink); + set_nlink(inode, be32_to_cpu(from->di_nlink)); to->di_projid_lo = be16_to_cpu(from->di_projid_lo); to->di_projid_hi = be16_to_cpu(from->di_projid_hi); } @@ -275,7 +275,6 @@ xfs_inode_to_disk( to->di_format = from->di_format; to->di_uid = cpu_to_be32(from->di_uid); to->di_gid = cpu_to_be32(from->di_gid); - to->di_nlink = cpu_to_be32(from->di_nlink); to->di_projid_lo = cpu_to_be16(from->di_projid_lo); to->di_projid_hi = cpu_to_be16(from->di_projid_hi); @@ -286,6 +285,7 @@ xfs_inode_to_disk( to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec); to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec); to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); + to->di_nlink = cpu_to_be32(inode->i_nlink); to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 73ba1d8ffac2..320b72344270 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -34,7 +34,6 @@ struct xfs_icdinode { __uint16_t di_flushiter; /* incremented on flush */ __uint32_t di_uid; /* owner's user id */ __uint32_t di_gid; /* owner's group id */ - __uint32_t di_nlink; /* number of links to file */ __uint16_t di_projid_lo; /* lower part of owner's project id */ __uint16_t di_projid_hi; /* higher part of owner's project id */ xfs_fsize_t di_size; /* number of bytes in file */ diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 9ca2865575ab..4c184f70d43c 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -148,9 +148,11 @@ xfs_reinit_inode( struct inode *inode) { int error; + uint32_t nlink = inode->i_nlink; error = inode_init_always(mp->m_super, inode); + set_nlink(inode, nlink); return error; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7d9c514fd231..18b3bc0c211a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -57,9 +57,9 @@ kmem_zone_t *xfs_inode_zone; */ #define XFS_ITRUNC_MAX_EXTENTS 2 -STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); - -STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *); +STATIC int xfs_iflush_int(struct xfs_inode *, struct xfs_buf *); +STATIC int xfs_iunlink(struct xfs_trans *, struct xfs_inode *); +STATIC int xfs_iunlink_remove(struct xfs_trans *, struct xfs_inode *); /* * helper function to extract extent size hint from inode @@ -803,7 +803,7 @@ xfs_ialloc( ip->i_d.di_version = 2; ip->i_d.di_mode = mode; - ip->i_d.di_nlink = nlink; + set_nlink(inode, nlink); ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); xfs_set_projid(ip, prid); @@ -1086,35 +1086,24 @@ xfs_dir_ialloc( } /* - * Decrement the link count on an inode & log the change. - * If this causes the link count to go to zero, initiate the - * logging activity required to truncate a file. + * Decrement the link count on an inode & log the change. If this causes the + * link count to go to zero, move the inode to AGI unlinked list so that it can + * be freed when the last active reference goes away via xfs_inactive(). */ int /* error */ xfs_droplink( xfs_trans_t *tp, xfs_inode_t *ip) { - int error; - xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); - ASSERT (ip->i_d.di_nlink > 0); - ip->i_d.di_nlink--; drop_nlink(VFS_I(ip)); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = 0; - if (ip->i_d.di_nlink == 0) { - /* - * We're dropping the last link to this file. - * Move the on-disk inode to the AGI unlinked list. - * From xfs_inactive() we will pull the inode from - * the list and free it. - */ - error = xfs_iunlink(tp, ip); - } - return error; + if (VFS_I(ip)->i_nlink) + return 0; + + return xfs_iunlink(tp, ip); } /* @@ -1128,8 +1117,6 @@ xfs_bumplink( xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); ASSERT(ip->i_d.di_version > 1); - ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE)); - ip->i_d.di_nlink++; inc_nlink(VFS_I(ip)); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); return 0; @@ -1387,7 +1374,6 @@ xfs_create_tmpfile( */ xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); - ip->i_d.di_nlink--; error = xfs_iunlink(tp, ip); if (error) goto out_trans_cancel; @@ -1486,7 +1472,10 @@ xfs_link( xfs_bmap_init(&free_list, &first_block); - if (sip->i_d.di_nlink == 0) { + /* + * Handle initial link state of O_TMPFILE inode + */ + if (VFS_I(sip)->i_nlink == 0) { error = xfs_iunlink_remove(tp, sip); if (error) goto error_return; @@ -1673,7 +1662,7 @@ xfs_release( } } - if (ip->i_d.di_nlink == 0) + if (VFS_I(ip)->i_nlink == 0) return 0; if (xfs_can_free_eofblocks(ip, false)) { @@ -1889,7 +1878,7 @@ xfs_inactive( if (mp->m_flags & XFS_MOUNT_RDONLY) return; - if (ip->i_d.di_nlink != 0) { + if (VFS_I(ip)->i_nlink != 0) { /* * force is true because we are evicting an inode from the * cache. Post-eof blocks must be freed, lest we end up with @@ -1946,16 +1935,21 @@ xfs_inactive( } /* - * This is called when the inode's link count goes to 0. - * We place the on-disk inode on a list in the AGI. It - * will be pulled from this list when the inode is freed. + * This is called when the inode's link count goes to 0 or we are creating a + * tmpfile via O_TMPFILE. In the case of a tmpfile, @ignore_linkcount will be + * set to true as the link count is dropped to zero by the VFS after we've + * created the file successfully, so we have to add it to the unlinked list + * while the link count is non-zero. + * + * We place the on-disk inode on a list in the AGI. It will be pulled from this + * list when the inode is freed. */ -int +STATIC int xfs_iunlink( - xfs_trans_t *tp, - xfs_inode_t *ip) + struct xfs_trans *tp, + struct xfs_inode *ip) { - xfs_mount_t *mp; + xfs_mount_t *mp = tp->t_mountp; xfs_agi_t *agi; xfs_dinode_t *dip; xfs_buf_t *agibp; @@ -1965,11 +1959,8 @@ xfs_iunlink( int offset; int error; - ASSERT(ip->i_d.di_nlink == 0); ASSERT(ip->i_d.di_mode != 0); - mp = tp->t_mountp; - /* * Get the agi buffer first. It ensures lock ordering * on the list. @@ -2406,7 +2397,7 @@ xfs_ifree( struct xfs_icluster xic = { 0 }; ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT(ip->i_d.di_nlink == 0); + ASSERT(VFS_I(ip)->i_nlink == 0); ASSERT(ip->i_d.di_nextents == 0); ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); @@ -2574,8 +2565,8 @@ xfs_remove( * If we're removing a directory perform some additional validation. */ if (is_dir) { - ASSERT(ip->i_d.di_nlink >= 2); - if (ip->i_d.di_nlink != 2) { + ASSERT(VFS_I(ip)->i_nlink >= 2); + if (VFS_I(ip)->i_nlink != 2) { error = -ENOTEMPTY; goto out_trans_cancel; } @@ -3031,7 +3022,7 @@ xfs_rename( * Make sure target dir is empty. */ if (!(xfs_dir_isempty(target_ip)) || - (target_ip->i_d.di_nlink > 2)) { + (VFS_I(target_ip)->i_nlink > 2)) { error = -EEXIST; goto out_trans_cancel; } @@ -3138,7 +3129,7 @@ xfs_rename( * intermediate state on disk. */ if (wip) { - ASSERT(VFS_I(wip)->i_nlink == 0 && wip->i_d.di_nlink == 0); + ASSERT(VFS_I(wip)->i_nlink == 0); error = xfs_bumplink(tp, wip); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index aef5452b1a90..e74d13d3076b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -405,8 +405,6 @@ int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_bmap_free *); int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, int, xfs_fsize_t); -int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); - void xfs_iext_realloc(xfs_inode_t *, int, int); void xfs_iunpin_wait(xfs_inode_t *); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 1e5ecbc45459..193e0bdec340 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -338,7 +338,6 @@ xfs_inode_to_log_dinode( to->di_format = from->di_format; to->di_uid = from->di_uid; to->di_gid = from->di_gid; - to->di_nlink = from->di_nlink; to->di_projid_lo = from->di_projid_lo; to->di_projid_hi = from->di_projid_hi; @@ -350,6 +349,7 @@ xfs_inode_to_log_dinode( to->di_mtime.t_nsec = inode->i_mtime.tv_nsec; to->di_ctime.t_sec = inode->i_ctime.tv_sec; to->di_ctime.t_nsec = inode->i_ctime.tv_nsec; + to->di_nlink = inode->i_nlink; to->di_size = from->di_size; to->di_nblocks = from->di_nblocks; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index cd27c6d56dfc..8982e56e07c4 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -460,7 +460,7 @@ xfs_vn_getattr( stat->size = XFS_ISIZE(ip); stat->dev = inode->i_sb->s_dev; stat->mode = ip->i_d.di_mode; - stat->nlink = ip->i_d.di_nlink; + stat->nlink = inode->i_nlink; stat->uid = inode->i_uid; stat->gid = inode->i_gid; stat->ino = ip->i_ino; @@ -1216,7 +1216,6 @@ xfs_setup_inode( hlist_add_fake(&inode->i_hash); inode->i_mode = ip->i_d.di_mode; - set_nlink(inode, ip->i_d.di_nlink); inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid); inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid); diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 2acda42319f5..cfb65273d361 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -85,7 +85,6 @@ xfs_bulkstat_one_int( /* xfs_iget returns the following without needing * further change. */ - buf->bs_nlink = dic->di_nlink; buf->bs_projid_lo = dic->di_projid_lo; buf->bs_projid_hi = dic->di_projid_hi; buf->bs_ino = ino; @@ -94,6 +93,7 @@ xfs_bulkstat_one_int( buf->bs_gid = dic->di_gid; buf->bs_size = dic->di_size; + buf->bs_nlink = inode->i_nlink; buf->bs_atime.tv_sec = inode->i_atime.tv_sec; buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec; buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4b79cf006589..611c25cdb15c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4337,7 +4337,7 @@ xlog_recover_process_one_iunlink( if (error) goto fail_iput; - ASSERT(ip->i_d.di_nlink == 0); + ASSERT(VFS_I(ip)->i_nlink == 0); ASSERT(ip->i_d.di_mode != 0); /* setup for the next pass */ -- GitLab From 9e9a2674e43353f650ecd19a54eba028eafff82e Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0835/5324] xfs: move inode generation count to VFS inode Pull another 4 bytes out of the xfs_icdinode. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 8 ++++---- fs/xfs/libxfs/xfs_inode_buf.h | 1 - fs/xfs/xfs_export.c | 2 +- fs/xfs/xfs_icache.c | 2 ++ fs/xfs/xfs_inode.c | 5 +---- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_ioctl.c | 2 +- fs/xfs/xfs_iops.c | 1 - fs/xfs/xfs_itable.c | 2 +- 9 files changed, 11 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index cc509c1af75e..9113a8d0f148 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -237,6 +237,7 @@ xfs_inode_from_disk( inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec); inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec); inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec); + inode->i_generation = be32_to_cpu(from->di_gen); to->di_size = be64_to_cpu(from->di_size); to->di_nblocks = be64_to_cpu(from->di_nblocks); @@ -248,7 +249,6 @@ xfs_inode_from_disk( to->di_dmevmask = be32_to_cpu(from->di_dmevmask); to->di_dmstate = be16_to_cpu(from->di_dmstate); to->di_flags = be16_to_cpu(from->di_flags); - to->di_gen = be32_to_cpu(from->di_gen); if (to->di_version == 3) { to->di_changecount = be64_to_cpu(from->di_changecount); @@ -286,6 +286,7 @@ xfs_inode_to_disk( to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec); to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); to->di_nlink = cpu_to_be32(inode->i_nlink); + to->di_gen = cpu_to_be32(inode->i_generation); to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); @@ -297,7 +298,6 @@ xfs_inode_to_disk( to->di_dmevmask = cpu_to_be32(from->di_dmevmask); to->di_dmstate = cpu_to_be16(from->di_dmstate); to->di_flags = cpu_to_be16(from->di_flags); - to->di_gen = cpu_to_be32(from->di_gen); if (from->di_version == 3) { to->di_changecount = cpu_to_be64(from->di_changecount); @@ -443,7 +443,7 @@ xfs_iread( !(mp->m_flags & XFS_MOUNT_IKEEP)) { /* initialise the on-disk inode core */ memset(&ip->i_d, 0, sizeof(ip->i_d)); - ip->i_d.di_gen = prandom_u32(); + VFS_I(ip)->i_generation = prandom_u32(); if (xfs_sb_version_hascrc(&mp->m_sb)) ip->i_d.di_version = 3; else @@ -491,7 +491,7 @@ xfs_iread( * that xfs_ialloc won't overwrite or relies on being correct. */ ip->i_d.di_version = dip->di_version; - ip->i_d.di_gen = be32_to_cpu(dip->di_gen); + VFS_I(ip)->i_generation = be32_to_cpu(dip->di_gen); ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); /* diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 320b72344270..29fd9f1cf54b 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -46,7 +46,6 @@ struct xfs_icdinode { __uint32_t di_dmevmask; /* DMIG event mask */ __uint16_t di_dmstate; /* DMIG state info */ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ - __uint32_t di_gen; /* generation number */ __uint64_t di_changecount; /* number of attribute changes */ __uint64_t di_flags2; /* more random flags */ diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 652cd3c5b58c..2816d42507bc 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c @@ -152,7 +152,7 @@ xfs_nfs_get_inode( return ERR_PTR(error); } - if (ip->i_d.di_gen != generation) { + if (VFS_I(ip)->i_generation != generation) { IRELE(ip); return ERR_PTR(-ESTALE); } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 4c184f70d43c..6401e3c07d3a 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -149,10 +149,12 @@ xfs_reinit_inode( { int error; uint32_t nlink = inode->i_nlink; + uint32_t generation = inode->i_generation; error = inode_init_always(mp->m_super, inode); set_nlink(inode, nlink); + inode->i_generation = generation; return error; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 18b3bc0c211a..dfc5b18c8cc2 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -835,9 +835,6 @@ xfs_ialloc( inode->i_atime = tv; inode->i_ctime = tv; - /* - * di_gen will have been taken care of in xfs_iread. - */ ip->i_d.di_extsize = 0; ip->i_d.di_dmevmask = 0; ip->i_d.di_dmstate = 0; @@ -2424,7 +2421,7 @@ xfs_ifree( * Bump the generation count so no one will be confused * by reincarnations of this inode. */ - ip->i_d.di_gen++; + VFS_I(ip)->i_generation++; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); if (xic.deleted) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 193e0bdec340..6367780b8abb 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -350,6 +350,7 @@ xfs_inode_to_log_dinode( to->di_ctime.t_sec = inode->i_ctime.tv_sec; to->di_ctime.t_nsec = inode->i_ctime.tv_nsec; to->di_nlink = inode->i_nlink; + to->di_gen = inode->i_generation; to->di_size = from->di_size; to->di_nblocks = from->di_nblocks; @@ -361,7 +362,6 @@ xfs_inode_to_log_dinode( to->di_dmevmask = from->di_dmevmask; to->di_dmstate = from->di_dmstate; to->di_flags = from->di_flags; - to->di_gen = from->di_gen; if (from->di_version == 3) { to->di_changecount = from->di_changecount; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 478d04e07f95..cdd6c3156d53 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -114,7 +114,7 @@ xfs_find_handle( handle.ha_fid.fid_len = sizeof(xfs_fid_t) - sizeof(handle.ha_fid.fid_len); handle.ha_fid.fid_pad = 0; - handle.ha_fid.fid_gen = ip->i_d.di_gen; + handle.ha_fid.fid_gen = inode->i_generation; handle.ha_fid.fid_ino = ip->i_ino; hsize = XFS_HSIZE(handle); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8982e56e07c4..a4daa3fd3ae9 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1231,7 +1231,6 @@ xfs_setup_inode( break; } - inode->i_generation = ip->i_d.di_gen; i_size_write(inode, ip->i_d.di_size); xfs_diflags_to_iflags(inode, ip); diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index cfb65273d361..6162e65f10b6 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -100,11 +100,11 @@ xfs_bulkstat_one_int( buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec; buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; + buf->bs_gen = inode->i_generation; buf->bs_xflags = xfs_ip2xflags(ip); buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; buf->bs_extents = dic->di_nextents; - buf->bs_gen = dic->di_gen; memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); buf->bs_dmevmask = dic->di_dmevmask; buf->bs_dmstate = dic->di_dmstate; -- GitLab From 83e06f21b439b7b308eda06332a4feef35739e94 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0836/5324] xfs: move di_changecount to VFS inode We can store the di_changecount in the i_version field of the VFS inode and remove another 8 bytes from the xfs_icdinode. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_inode_buf.c | 4 ++-- fs/xfs/libxfs/xfs_inode_buf.h | 1 - fs/xfs/xfs_icache.c | 6 ++++-- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_trans_inode.c | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 9113a8d0f148..05fbefa97fbf 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -251,7 +251,7 @@ xfs_inode_from_disk( to->di_flags = be16_to_cpu(from->di_flags); if (to->di_version == 3) { - to->di_changecount = be64_to_cpu(from->di_changecount); + inode->i_version = be64_to_cpu(from->di_changecount); to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); to->di_flags2 = be64_to_cpu(from->di_flags2); @@ -300,7 +300,7 @@ xfs_inode_to_disk( to->di_flags = cpu_to_be16(from->di_flags); if (from->di_version == 3) { - to->di_changecount = cpu_to_be64(from->di_changecount); + to->di_changecount = cpu_to_be64(inode->i_version); to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); to->di_flags2 = cpu_to_be64(from->di_flags2); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index 29fd9f1cf54b..c51bd1213c96 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -47,7 +47,6 @@ struct xfs_icdinode { __uint16_t di_dmstate; /* DMIG state info */ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ - __uint64_t di_changecount; /* number of attribute changes */ __uint64_t di_flags2; /* more random flags */ xfs_ictimestamp_t di_crtime; /* time created */ diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 6401e3c07d3a..30eafad7cf19 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -138,9 +138,9 @@ xfs_inode_free( * When we recycle a reclaimable inode, we need to re-initialise the VFS inode * part of the structure. This is made more complex by the fact we store * information about the on-disk values in the VFS inode and so we can't just - * overwrite it's values unconditionally. Hence we save the parameters we + * overwrite the values unconditionally. Hence we save the parameters we * need to retain across reinitialisation, and rewrite them into the VFS inode - * after resetting it's state even if resetting fails. + * after reinitialisation even if it fails. */ static int xfs_reinit_inode( @@ -150,11 +150,13 @@ xfs_reinit_inode( int error; uint32_t nlink = inode->i_nlink; uint32_t generation = inode->i_generation; + uint64_t version = inode->i_version; error = inode_init_always(mp->m_super, inode); set_nlink(inode, nlink); inode->i_generation = generation; + inode->i_version = version; return error; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dfc5b18c8cc2..8a970056a2c4 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -841,7 +841,7 @@ xfs_ialloc( ip->i_d.di_flags = 0; if (ip->i_d.di_version == 3) { - ip->i_d.di_changecount = 1; + inode->i_version = 1; ip->i_d.di_flags2 = 0; ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec; diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6367780b8abb..3415c63bc843 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -364,7 +364,7 @@ xfs_inode_to_log_dinode( to->di_flags = from->di_flags; if (from->di_version == 3) { - to->di_changecount = from->di_changecount; + to->di_changecount = inode->i_version; to->di_crtime.t_sec = from->di_crtime.t_sec; to->di_crtime.t_nsec = from->di_crtime.t_nsec; to->di_flags2 = from->di_flags2; diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 3f0d46655ce5..11a3af08b5c7 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -117,7 +117,7 @@ xfs_trans_log_inode( */ if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) && IS_I_VERSION(VFS_I(ip))) { - ip->i_d.di_changecount = ++VFS_I(ip)->i_version; + VFS_I(ip)->i_version++; flags |= XFS_ILOG_CORE; } -- GitLab From c19b3b05ae440de50fffe2ac2a9b27392a7448e9 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: [PATCH 0837/5324] xfs: mode di_mode to vfs inode Move the di_mode value from the xfs_icdinode to the VFS inode, reducing the xfs_icdinode byte another 2 bytes and collapsing another 2 byte hole in the structure. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 6 ++--- fs/xfs/libxfs/xfs_dir2.c | 12 ++++----- fs/xfs/libxfs/xfs_inode_buf.c | 8 +++--- fs/xfs/libxfs/xfs_inode_buf.h | 1 - fs/xfs/libxfs/xfs_inode_fork.c | 2 +- fs/xfs/xfs_bmap_util.c | 4 +-- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_file.c | 6 ++--- fs/xfs/xfs_filestream.c | 4 +-- fs/xfs/xfs_icache.c | 13 ++++++--- fs/xfs/xfs_inode.c | 48 ++++++++++++++++------------------ fs/xfs/xfs_inode.h | 4 +-- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_ioctl.c | 14 +++++----- fs/xfs/xfs_iops.c | 12 +++------ fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_mount.c | 2 +- 18 files changed, 71 insertions(+), 73 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ef00156f4f96..6a051662d8f9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -912,7 +912,7 @@ xfs_bmap_local_to_extents( * We don't want to deal with the case of keeping inode data inline yet. * So sending the data fork of a regular inode is invalid. */ - ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK)); + ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); @@ -1079,7 +1079,7 @@ xfs_bmap_add_attrfork_local( if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) return 0; - if (S_ISDIR(ip->i_d.di_mode)) { + if (S_ISDIR(VFS_I(ip)->i_mode)) { memset(&dargs, 0, sizeof(dargs)); dargs.geo = ip->i_mount->m_dir_geo; dargs.dp = ip; @@ -1091,7 +1091,7 @@ xfs_bmap_add_attrfork_local( return xfs_dir2_sf_to_block(&dargs); } - if (S_ISLNK(ip->i_d.di_mode)) + if (S_ISLNK(VFS_I(ip)->i_mode)) return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, XFS_DATA_FORK, xfs_symlink_local_to_remote); diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 2fb53a5c0a74..af0f9d171f8a 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -176,7 +176,7 @@ xfs_dir_isempty( { xfs_dir2_sf_hdr_t *sfp; - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); if (dp->i_d.di_size == 0) /* might happen during shutdown. */ return 1; if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) @@ -231,7 +231,7 @@ xfs_dir_init( struct xfs_da_args *args; int error; - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino); if (error) return error; @@ -266,7 +266,7 @@ xfs_dir_createname( int rval; int v; /* type-checking value */ - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); if (inum) { rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) @@ -364,7 +364,7 @@ xfs_dir_lookup( int v; /* type-checking value */ int lock_mode; - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_lookup); /* @@ -443,7 +443,7 @@ xfs_dir_removename( int rval; int v; /* type-checking value */ - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); @@ -505,7 +505,7 @@ xfs_dir_replace( int rval; int v; /* type-checking value */ - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 05fbefa97fbf..9d9559eb2835 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -202,13 +202,12 @@ xfs_inode_from_disk( struct xfs_icdinode *to = &ip->i_d; struct inode *inode = VFS_I(ip); - to->di_mode = be16_to_cpu(from->di_mode); - to->di_version = from ->di_version; /* * Convert v1 inodes immediately to v2 inode format as this is the * minimum inode version format we support in the rest of the code. */ + to->di_version = from->di_version; if (to->di_version == 1) { set_nlink(inode, be16_to_cpu(from->di_onlink)); to->di_projid_lo = 0; @@ -238,6 +237,7 @@ xfs_inode_from_disk( inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec); inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec); inode->i_generation = be32_to_cpu(from->di_gen); + inode->i_mode = be16_to_cpu(from->di_mode); to->di_size = be64_to_cpu(from->di_size); to->di_nblocks = be64_to_cpu(from->di_nblocks); @@ -270,7 +270,6 @@ xfs_inode_to_disk( to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); to->di_onlink = 0; - to->di_mode = cpu_to_be16(from->di_mode); to->di_version = from->di_version; to->di_format = from->di_format; to->di_uid = cpu_to_be32(from->di_uid); @@ -287,6 +286,7 @@ xfs_inode_to_disk( to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); to->di_nlink = cpu_to_be32(inode->i_nlink); to->di_gen = cpu_to_be32(inode->i_generation); + to->di_mode = cpu_to_be16(inode->i_mode); to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); @@ -501,7 +501,7 @@ xfs_iread( * the inode is already free and not try to mess * with the uninitialized part of it. */ - ip->i_d.di_mode = 0; + VFS_I(ip)->i_mode = 0; } ASSERT(ip->i_d.di_version >= 2); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index c51bd1213c96..7c4dd321b215 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -28,7 +28,6 @@ struct xfs_dinode; * format specific structures at the appropriate time. */ struct xfs_icdinode { - __uint16_t di_mode; /* mode and type of file */ __int8_t di_version; /* inode version */ __int8_t di_format; /* format of di_c data */ __uint16_t di_flushiter; /* incremented on flush */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 0defbd02f62d..0bf1c747439d 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -120,7 +120,7 @@ xfs_iformat_fork( return -EFSCORRUPTED; } - switch (ip->i_d.di_mode & S_IFMT) { + switch (VFS_I(ip)->i_mode & S_IFMT) { case S_IFIFO: case S_IFCHR: case S_IFBLK: diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 45ec9e40150c..708775613e55 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -821,7 +821,7 @@ bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) { /* prealloc/delalloc exists only on regular files */ - if (!S_ISREG(ip->i_d.di_mode)) + if (!S_ISREG(VFS_I(ip)->i_mode)) return false; /* @@ -1726,7 +1726,7 @@ xfs_swap_extents( xfs_lock_two_inodes(ip, tip, XFS_MMAPLOCK_EXCL); /* Verify that both files have the same format */ - if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) { + if ((VFS_I(ip)->i_mode & S_IFMT) != (VFS_I(tip)->i_mode & S_IFMT)) { error = -EINVAL; goto out_unlock; } diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 642d55d10075..93b3ab0c5435 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -665,7 +665,7 @@ xfs_readdir( if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; - ASSERT(S_ISDIR(dp->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_getdents); args.dp = dp; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 52883ac3cf84..f7333fbba5c2 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -156,9 +156,9 @@ xfs_update_prealloc_flags( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); if (!(flags & XFS_PREALLOC_INVISIBLE)) { - ip->i_d.di_mode &= ~S_ISUID; - if (ip->i_d.di_mode & S_IXGRP) - ip->i_d.di_mode &= ~S_ISGID; + VFS_I(ip)->i_mode &= ~S_ISUID; + if (VFS_I(ip)->i_mode & S_IXGRP) + VFS_I(ip)->i_mode &= ~S_ISGID; xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); } diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index c4c130f9bfb6..a51353a1f87f 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -151,7 +151,7 @@ xfs_filestream_pick_ag( xfs_agnumber_t ag, max_ag = NULLAGNUMBER; int err, trylock, nscan; - ASSERT(S_ISDIR(ip->i_d.di_mode)); + ASSERT(S_ISDIR(VFS_I(ip)->i_mode)); /* 2% of an AG's blocks must be free for it to be chosen. */ minfree = mp->m_sb.sb_agblocks / 50; @@ -319,7 +319,7 @@ xfs_filestream_lookup_ag( xfs_agnumber_t startag, ag = NULLAGNUMBER; struct xfs_mru_cache_elem *mru; - ASSERT(S_ISREG(ip->i_d.di_mode)); + ASSERT(S_ISREG(VFS_I(ip)->i_mode)); pip = xfs_filestream_get_parent(ip); if (!pip) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 30eafad7cf19..bf2d60749278 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,6 +63,9 @@ xfs_inode_alloc( return NULL; } + /* VFS doesn't initialise i_mode! */ + VFS_I(ip)->i_mode = 0; + XFS_STATS_INC(mp, vn_active); ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!spin_is_locked(&ip->i_flags_lock)); @@ -98,7 +101,7 @@ void xfs_inode_free( struct xfs_inode *ip) { - switch (ip->i_d.di_mode & S_IFMT) { + switch (VFS_I(ip)->i_mode & S_IFMT) { case S_IFREG: case S_IFDIR: case S_IFLNK: @@ -151,12 +154,14 @@ xfs_reinit_inode( uint32_t nlink = inode->i_nlink; uint32_t generation = inode->i_generation; uint64_t version = inode->i_version; + umode_t mode = inode->i_mode; error = inode_init_always(mp->m_super, inode); set_nlink(inode, nlink); inode->i_generation = generation; inode->i_version = version; + inode->i_mode = mode; return error; } @@ -211,7 +216,7 @@ xfs_iget_cache_hit( /* * If lookup is racing with unlink return an error immediately. */ - if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) { + if (VFS_I(ip)->i_mode == 0 && !(flags & XFS_IGET_CREATE)) { error = -ENOENT; goto out_error; } @@ -321,7 +326,7 @@ xfs_iget_cache_miss( trace_xfs_iget_miss(ip); - if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { + if ((VFS_I(ip)->i_mode == 0) && !(flags & XFS_IGET_CREATE)) { error = -ENOENT; goto out_destroy; } @@ -470,7 +475,7 @@ xfs_iget( * If we have a real type for an on-disk inode, we can setup the inode * now. If it's a new inode being created, xfs_ialloc will handle it. */ - if (xfs_iflags_test(ip, XFS_INEW) && ip->i_d.di_mode != 0) + if (xfs_iflags_test(ip, XFS_INEW) && VFS_I(ip)->i_mode != 0) xfs_setup_existing_inode(ip); return 0; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8a970056a2c4..26bac4ab79a3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -802,7 +802,7 @@ xfs_ialloc( if (ip->i_d.di_version == 1) ip->i_d.di_version = 2; - ip->i_d.di_mode = mode; + inode->i_mode = mode; set_nlink(inode, nlink); ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); @@ -810,9 +810,8 @@ xfs_ialloc( if (pip && XFS_INHERIT_GID(pip)) { ip->i_d.di_gid = pip->i_d.di_gid; - if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) { - ip->i_d.di_mode |= S_ISGID; - } + if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode)) + inode->i_mode |= S_ISGID; } /* @@ -821,10 +820,9 @@ xfs_ialloc( * (and only if the irix_sgid_inherit compatibility variable is set). */ if ((irix_sgid_inherit) && - (ip->i_d.di_mode & S_ISGID) && - (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) { - ip->i_d.di_mode &= ~S_ISGID; - } + (inode->i_mode & S_ISGID) && + (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) + inode->i_mode &= ~S_ISGID; ip->i_d.di_size = 0; ip->i_d.di_nextents = 0; @@ -1421,7 +1419,7 @@ xfs_link( trace_xfs_link(tdp, target_name); - ASSERT(!S_ISDIR(sip->i_d.di_mode)); + ASSERT(!S_ISDIR(VFS_I(sip)->i_mode)); if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -1628,7 +1626,7 @@ xfs_release( xfs_mount_t *mp = ip->i_mount; int error; - if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) + if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0)) return 0; /* If this is a read-only mount, don't do this (would generate I/O) */ @@ -1863,7 +1861,7 @@ xfs_inactive( * If the inode is already free, then there can be nothing * to clean up here. */ - if (ip->i_d.di_mode == 0) { + if (VFS_I(ip)->i_mode == 0) { ASSERT(ip->i_df.if_real_bytes == 0); ASSERT(ip->i_df.if_broot_bytes == 0); return; @@ -1887,7 +1885,7 @@ xfs_inactive( return; } - if (S_ISREG(ip->i_d.di_mode) && + if (S_ISREG(VFS_I(ip)->i_mode) && (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) truncate = 1; @@ -1896,7 +1894,7 @@ xfs_inactive( if (error) return; - if (S_ISLNK(ip->i_d.di_mode)) + if (S_ISLNK(VFS_I(ip)->i_mode)) error = xfs_inactive_symlink(ip); else if (truncate) error = xfs_inactive_truncate(ip); @@ -1956,7 +1954,7 @@ xfs_iunlink( int offset; int error; - ASSERT(ip->i_d.di_mode != 0); + ASSERT(VFS_I(ip)->i_mode != 0); /* * Get the agi buffer first. It ensures lock ordering @@ -2397,7 +2395,7 @@ xfs_ifree( ASSERT(VFS_I(ip)->i_nlink == 0); ASSERT(ip->i_d.di_nextents == 0); ASSERT(ip->i_d.di_anextents == 0); - ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); + ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); ASSERT(ip->i_d.di_nblocks == 0); /* @@ -2411,7 +2409,7 @@ xfs_ifree( if (error) return error; - ip->i_d.di_mode = 0; /* mark incore inode as free */ + VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ ip->i_d.di_flags = 0; ip->i_d.di_dmevmask = 0; ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ @@ -2508,7 +2506,7 @@ xfs_remove( { xfs_mount_t *mp = dp->i_mount; xfs_trans_t *tp = NULL; - int is_dir = S_ISDIR(ip->i_d.di_mode); + int is_dir = S_ISDIR(VFS_I(ip)->i_mode); int error = 0; xfs_bmap_free_t free_list; xfs_fsblock_t first_block; @@ -2753,7 +2751,7 @@ xfs_cross_rename( if (dp1 != dp2) { dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; - if (S_ISDIR(ip2->i_d.di_mode)) { + if (S_ISDIR(VFS_I(ip2)->i_mode)) { error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, dp1->i_ino, first_block, free_list, spaceres); @@ -2761,7 +2759,7 @@ xfs_cross_rename( goto out_trans_abort; /* transfer ip2 ".." reference to dp1 */ - if (!S_ISDIR(ip1->i_d.di_mode)) { + if (!S_ISDIR(VFS_I(ip1)->i_mode)) { error = xfs_droplink(tp, dp2); if (error) goto out_trans_abort; @@ -2780,7 +2778,7 @@ xfs_cross_rename( ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; } - if (S_ISDIR(ip1->i_d.di_mode)) { + if (S_ISDIR(VFS_I(ip1)->i_mode)) { error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, dp2->i_ino, first_block, free_list, spaceres); @@ -2788,7 +2786,7 @@ xfs_cross_rename( goto out_trans_abort; /* transfer ip1 ".." reference to dp2 */ - if (!S_ISDIR(ip2->i_d.di_mode)) { + if (!S_ISDIR(VFS_I(ip2)->i_mode)) { error = xfs_droplink(tp, dp1); if (error) goto out_trans_abort; @@ -2885,7 +2883,7 @@ xfs_rename( struct xfs_inode *inodes[__XFS_SORT_INODES]; int num_inodes = __XFS_SORT_INODES; bool new_parent = (src_dp != target_dp); - bool src_is_directory = S_ISDIR(src_ip->i_d.di_mode); + bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode); int spaceres; int error; @@ -3014,7 +3012,7 @@ xfs_rename( * target and source are directories and that target can be * destroyed, or that neither is a directory. */ - if (S_ISDIR(target_ip->i_d.di_mode)) { + if (S_ISDIR(VFS_I(target_ip)->i_mode)) { /* * Make sure target dir is empty. */ @@ -3444,7 +3442,7 @@ xfs_iflush_int( __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); goto corrupt_out; } - if (S_ISREG(ip->i_d.di_mode)) { + if (S_ISREG(VFS_I(ip)->i_mode)) { if (XFS_TEST_ERROR( (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), @@ -3454,7 +3452,7 @@ xfs_iflush_int( __func__, ip->i_ino, ip); goto corrupt_out; } - } else if (S_ISDIR(ip->i_d.di_mode)) { + } else if (S_ISDIR(VFS_I(ip)->i_mode)) { if (XFS_TEST_ERROR( (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index e74d13d3076b..d6277494e606 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -88,7 +88,7 @@ static inline struct inode *VFS_I(struct xfs_inode *ip) */ static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip) { - if (S_ISREG(ip->i_d.di_mode)) + if (S_ISREG(VFS_I(ip)->i_mode)) return i_size_read(VFS_I(ip)); return ip->i_d.di_size; } @@ -369,7 +369,7 @@ static inline int xfs_isiflocked(struct xfs_inode *ip) */ #define XFS_INHERIT_GID(pip) \ (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ - ((pip)->i_d.di_mode & S_ISGID)) + (VFS_I(pip)->i_mode & S_ISGID)) int xfs_release(struct xfs_inode *ip); void xfs_inactive(struct xfs_inode *ip); diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 3415c63bc843..c48b5b18d771 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -333,7 +333,6 @@ xfs_inode_to_log_dinode( to->di_magic = XFS_DINODE_MAGIC; - to->di_mode = from->di_mode; to->di_version = from->di_version; to->di_format = from->di_format; to->di_uid = from->di_uid; @@ -351,6 +350,7 @@ xfs_inode_to_log_dinode( to->di_ctime.t_nsec = inode->i_ctime.tv_nsec; to->di_nlink = inode->i_nlink; to->di_gen = inode->i_generation; + to->di_mode = inode->i_mode; to->di_size = from->di_size; to->di_nblocks = from->di_nblocks; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index cdd6c3156d53..81d6d6218803 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -963,7 +963,7 @@ xfs_set_diflags( di_flags |= XFS_DIFLAG_NODEFRAG; if (xflags & FS_XFLAG_FILESTREAM) di_flags |= XFS_DIFLAG_FILESTREAM; - if (S_ISDIR(ip->i_d.di_mode)) { + if (S_ISDIR(VFS_I(ip)->i_mode)) { if (xflags & FS_XFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_RTINHERIT; if (xflags & FS_XFLAG_NOSYMLINKS) @@ -972,7 +972,7 @@ xfs_set_diflags( di_flags |= XFS_DIFLAG_EXTSZINHERIT; if (xflags & FS_XFLAG_PROJINHERIT) di_flags |= XFS_DIFLAG_PROJINHERIT; - } else if (S_ISREG(ip->i_d.di_mode)) { + } else if (S_ISREG(VFS_I(ip)->i_mode)) { if (xflags & FS_XFLAG_REALTIME) di_flags |= XFS_DIFLAG_REALTIME; if (xflags & FS_XFLAG_EXTSIZE) @@ -1128,14 +1128,14 @@ xfs_ioctl_setattr_check_extsize( { struct xfs_mount *mp = ip->i_mount; - if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(ip->i_d.di_mode)) + if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode)) return -EINVAL; if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && - !S_ISDIR(ip->i_d.di_mode)) + !S_ISDIR(VFS_I(ip)->i_mode)) return -EINVAL; - if (S_ISREG(ip->i_d.di_mode) && ip->i_d.di_nextents && + if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) return -EINVAL; @@ -1256,9 +1256,9 @@ xfs_ioctl_setattr( * successful return from chown() */ - if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && + if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) && !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID)) - ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); + VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID); /* Change the ownerships and register project quota modifications */ if (xfs_get_projid(ip) != fa->fsx_projid) { diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index a4daa3fd3ae9..0d38b1d2c420 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -459,7 +459,7 @@ xfs_vn_getattr( stat->size = XFS_ISIZE(ip); stat->dev = inode->i_sb->s_dev; - stat->mode = ip->i_d.di_mode; + stat->mode = inode->i_mode; stat->nlink = inode->i_nlink; stat->uid = inode->i_uid; stat->gid = inode->i_gid; @@ -506,9 +506,6 @@ xfs_setattr_mode( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ip->i_d.di_mode &= S_IFMT; - ip->i_d.di_mode |= mode & ~S_IFMT; - inode->i_mode &= S_IFMT; inode->i_mode |= mode & ~S_IFMT; } @@ -652,9 +649,9 @@ xfs_setattr_nonsize( * The set-user-ID and set-group-ID bits of a file will be * cleared upon successful return from chown() */ - if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && + if ((inode->i_mode & (S_ISUID|S_ISGID)) && !capable(CAP_FSETID)) - ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); + inode->i_mode &= ~(S_ISUID|S_ISGID); /* * Change the ownerships and register quota modifications @@ -764,7 +761,7 @@ xfs_setattr_size( ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL)); - ASSERT(S_ISREG(ip->i_d.di_mode)); + ASSERT(S_ISREG(inode->i_mode)); ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); @@ -1215,7 +1212,6 @@ xfs_setup_inode( /* make the inode look hashed for the writeback code */ hlist_add_fake(&inode->i_hash); - inode->i_mode = ip->i_d.di_mode; inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid); inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid); diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 6162e65f10b6..ce73eb34620d 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -88,7 +88,6 @@ xfs_bulkstat_one_int( buf->bs_projid_lo = dic->di_projid_lo; buf->bs_projid_hi = dic->di_projid_hi; buf->bs_ino = ino; - buf->bs_mode = dic->di_mode; buf->bs_uid = dic->di_uid; buf->bs_gid = dic->di_gid; buf->bs_size = dic->di_size; @@ -101,6 +100,7 @@ xfs_bulkstat_one_int( buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; buf->bs_gen = inode->i_generation; + buf->bs_mode = inode->i_mode; buf->bs_xflags = xfs_ip2xflags(ip); buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 611c25cdb15c..bd6f23b952a5 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4338,7 +4338,7 @@ xlog_recover_process_one_iunlink( goto fail_iput; ASSERT(VFS_I(ip)->i_nlink == 0); - ASSERT(ip->i_d.di_mode != 0); + ASSERT(VFS_I(ip)->i_mode != 0); /* setup for the next pass */ agino = be32_to_cpu(dip->di_next_unlinked); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bb753b359bee..d3061054bad2 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -865,7 +865,7 @@ xfs_mountfs( ASSERT(rip != NULL); - if (unlikely(!S_ISDIR(rip->i_d.di_mode))) { + if (unlikely(!S_ISDIR(VFS_I(rip)->i_mode))) { xfs_warn(mp, "corrupted root inode %llu: not a directory", (unsigned long long)rip->i_ino); xfs_iunlock(rip, XFS_ILOCK_EXCL); -- GitLab From e7d6c9b1163255d8d6594e613eac7a4a8b1806a0 Mon Sep 17 00:00:00 2001 From: Addy Ke Date: Fri, 22 Jan 2016 19:06:47 +0800 Subject: [PATCH 0838/5324] ARM: dts: rockchip: Add arm, pl330-broken-no-flushp quirk for rk3288 platform Pl330 integrated in rk3288 platform doesn't support DMAFLUSHP function. So we add arm,pl330-broken-no-flushp quirk for it. Signed-off-by: Addy Ke Signed-off-by: Shawn Lin Reviewed-by: Doug Anderson Reviewed-by: Sonny Rao Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 6abbab67ce99..0934b6abcaab 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -145,6 +145,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; @@ -155,6 +156,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; status = "disabled"; @@ -166,6 +168,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; }; -- GitLab From 9bed8b41d8da3acdb72d5fafa7ac5ec0016dd188 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 22 Jan 2016 19:06:48 +0800 Subject: [PATCH 0839/5324] ARM: dts: rockchip: Add arm, pl330-broken-no-flushp quirk for rk3xxx platform Pl330 integrated in rk3xxx platform doesn't support DMAFLUSHP function. So we add arm,pl330-broken-no-flushp quirk for it. Signed-off-by: Shawn Lin Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3xxx.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 99eeea70223b..f1581f9d050f 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -78,6 +78,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; }; @@ -88,6 +89,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; status = "disabled"; @@ -99,6 +101,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA2>; clock-names = "apb_pclk"; }; -- GitLab From 29f12bbab4c3997c5c8879ea19cfc47440dedbd8 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Fri, 22 Jan 2016 19:06:49 +0800 Subject: [PATCH 0840/5324] ARM: dts: rockchip: add arm,pl330-broken-no-flushp quirk for rk3036 SoCs Pl330 integrated in rk3036 platform that doesn't support DMAFLUSHP function. So we add 'arm,pl330-broken-no-flushp' quirk for rk3036. Signed-off-by: Caesar Wang Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3036.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index 28fa2f848df8..3864fa142df0 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -106,6 +106,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; -- GitLab From 2a743e3ece0b01454229a442778ea8904696e212 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 6 Feb 2016 23:53:44 +0800 Subject: [PATCH 0841/5324] ARM: sunxi_defconfig: Enable sunxi IR driver A consumer IR receiver is commonly found on Allwinner SoC based development boards and set top boxes. The driver has been available for some time. Enable it by default. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index a9a81a714be4..7d2e7bf81a47 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -92,6 +92,10 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_GPIO=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_DEVICES=y +CONFIG_IR_SUNXI=y CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -- GitLab From d027595be1fd4115e5e6ce4a0ec5f0fd2a82901f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 6 Feb 2016 23:53:45 +0800 Subject: [PATCH 0842/5324] ARM: sunxi_defconfig: Enable A10 audio codec driver The A10 audio codec driver supports the on-chip audio codec found on Allwinner A10, A10s, A13, A20 SoCs. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 7d2e7bf81a47..efa12c88fe1c 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -100,6 +100,10 @@ CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SUN4I_CODEC=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y -- GitLab From 401d32a995d1f374ade9d517f16458c82a6bc6fd Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 6 Feb 2016 23:53:47 +0800 Subject: [PATCH 0843/5324] ARM: sunxi_defconfig: Enable INPUT_EVDEV so axp20x-pek can be used sunxi_defconfig already enables INPUT_AXP20X_PEK, but the device is not exposed to userspace. Enable INPUT_EVDEV so it is. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index efa12c88fe1c..a55c48e27309 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -58,6 +58,7 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_SUN4I_LRADC=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y -- GitLab From 44c23163140964a607c4eb19fc8a85ffa34fa05b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 6 Feb 2016 23:53:49 +0800 Subject: [PATCH 0844/5324] ARM: multi_v7_defconfig: Enable MUSB HDRC driver with Allwinner glue Allwinner SoCs typically have a Mentor Graphics Inventra MUSB high speed dual role controller for USB OTG. Now that the issue with MUSB and USB gadget registration order has been resolved, we can enable this driver in dual role mode. This patch only enables the driver core and Allwinner platform support. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/multi_v7_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 314f6be2dca2..442025629ee9 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -591,6 +591,8 @@ CONFIG_USB_OHCI_EXYNOS=m CONFIG_USB_R8A66597_HCD=m CONFIG_USB_RENESAS_USBHS=m CONFIG_USB_STORAGE=y +CONFIG_USB_MUSB_HDRC=m +CONFIG_USB_MUSB_SUNXI=m CONFIG_USB_DWC3=y CONFIG_USB_DWC2=m CONFIG_USB_CHIPIDEA=y -- GitLab From 0813ce0a49113d2b7ce2275a99396d6444090343 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sat, 6 Feb 2016 23:53:48 +0800 Subject: [PATCH 0845/5324] ARM: multi_v7_defconfig: Enable A10 audio codec driver as module The A10 audio codec driver supports the on-chip audio codec found on Allwinner A10, A10s, A13, A20 SoCs. Build it as a module, since it is not critical. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/multi_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 442025629ee9..b500f18d0c35 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -559,6 +559,7 @@ CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_SOC_RCAR=m CONFIG_SND_SOC_RSRC_CARD=m +CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SOC_SAMSUNG=m CONFIG_SND_SOC_SNOW=m CONFIG_SND_SOC_ODROIDX2=m -- GitLab From bfe981a0952880df43d08a050bf3ae44aaebd795 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Tue, 22 Dec 2015 19:36:44 -0200 Subject: [PATCH 0846/5324] drm: prime: Honour O_RDWR during prime-handle-to-fd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently DRM_IOCTL_PRIME_HANDLE_TO_FD rejects all flags except (DRM|O)_CLOEXEC making it difficult (maybe impossible) for userspace to mmap() the resulting dma-buf even when this is supported by the DRM driver. It is trivial to relax the restriction and permit read/write access. This is safe because the flags are seldom touched by drm; mostly they are passed verbatim to dma_buf calls. v3 (Tiago): removed unused flags variable from drm_prime_handle_to_fd_ioctl. Reviewed-by: Chris Wilson Signed-off-by: Daniel Thompson Signed-off-by: Tiago Vignatti Reviewed-by: Stéphane Marchesin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1450820214-12509-2-git-send-email-tiago.vignatti@intel.com --- drivers/gpu/drm/drm_prime.c | 10 +++------- include/uapi/drm/drm.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 27aa7183b20b..df6cdc76a16e 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -329,7 +329,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { * drm_gem_prime_export - helper library implementation of the export callback * @dev: drm_device to export from * @obj: GEM object to export - * @flags: flags like DRM_CLOEXEC + * @flags: flags like DRM_CLOEXEC and DRM_RDWR * * This is the implementation of the gem_prime_export functions for GEM drivers * using the PRIME helpers. @@ -628,7 +628,6 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_prime_handle *args = data; - uint32_t flags; if (!drm_core_check_feature(dev, DRIVER_PRIME)) return -EINVAL; @@ -637,14 +636,11 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, return -ENOSYS; /* check flags are valid */ - if (args->flags & ~DRM_CLOEXEC) + if (args->flags & ~(DRM_CLOEXEC | DRM_RDWR)) return -EINVAL; - /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */ - flags = args->flags & DRM_CLOEXEC; - return dev->driver->prime_handle_to_fd(dev, file_priv, - args->handle, flags, &args->fd); + args->handle, args->flags, &args->fd); } int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index b4e92eb12044..a0ebfe7c9a28 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -669,6 +669,7 @@ struct drm_set_client_cap { __u64 value; }; +#define DRM_RDWR O_RDWR #define DRM_CLOEXEC O_CLOEXEC struct drm_prime_handle { __u32 handle; -- GitLab From 831e9da7dc5c22fd2a5fb64e999f6e077a4338c3 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Tue, 22 Dec 2015 19:36:45 -0200 Subject: [PATCH 0847/5324] dma-buf: Remove range-based flush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes range-based information used for optimizations in begin_cpu_access and end_cpu_access. We don't have any user nor implementation using range-based flush. It seems a consensus that if we ever want something like that again (or even more robust using 2D, 3D sub-range regions) we can use the upcoming dma-buf sync ioctl for such. Cc: Sumit Semwal Cc: Daniel Vetter Signed-off-by: Tiago Vignatti Reviewed-by: Stéphane Marchesin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1450820214-12509-3-git-send-email-tiago.vignatti@intel.com --- Documentation/dma-buf-sharing.txt | 19 ++++++++----------- drivers/dma-buf/dma-buf.c | 13 ++++--------- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 +- drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | 4 ++-- drivers/gpu/drm/udl/udl_fb.c | 2 -- drivers/staging/android/ion/ion.c | 6 ++---- drivers/staging/android/ion/ion_test.c | 4 ++-- include/linux/dma-buf.h | 12 +++++------- 8 files changed, 24 insertions(+), 38 deletions(-) diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt index 480c8de3c2c4..4f4a84b6903a 100644 --- a/Documentation/dma-buf-sharing.txt +++ b/Documentation/dma-buf-sharing.txt @@ -257,17 +257,15 @@ Access to a dma_buf from the kernel context involves three steps: Interface: int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - size_t start, size_t len, enum dma_data_direction direction) This allows the exporter to ensure that the memory is actually available for cpu access - the exporter might need to allocate or swap-in and pin the backing storage. The exporter also needs to ensure that cpu access is - coherent for the given range and access direction. The range and access - direction can be used by the exporter to optimize the cache flushing, i.e. - access outside of the range or with a different direction (read instead of - write) might return stale or even bogus data (e.g. when the exporter needs to - copy the data to temporary storage). + coherent for the access direction. The direction can be used by the exporter + to optimize the cache flushing, i.e. access with a different direction (read + instead of write) might return stale or even bogus data (e.g. when the + exporter needs to copy the data to temporary storage). This step might fail, e.g. in oom conditions. @@ -322,14 +320,13 @@ Access to a dma_buf from the kernel context involves three steps: 3. Finish access - When the importer is done accessing the range specified in begin_cpu_access, - it needs to announce this to the exporter (to facilitate cache flushing and - unpinning of any pinned resources). The result of any dma_buf kmap calls - after end_cpu_access is undefined. + When the importer is done accessing the CPU, it needs to announce this to + the exporter (to facilitate cache flushing and unpinning of any pinned + resources). The result of any dma_buf kmap calls after end_cpu_access is + undefined. Interface: void dma_buf_end_cpu_access(struct dma_buf *dma_buf, - size_t start, size_t len, enum dma_data_direction dir); diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 155c1464948e..b2ac13b4ddaa 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -539,13 +539,11 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); * preparations. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to prepare cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * * Can return negative error values, returns 0 on success. */ -int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, +int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { int ret = 0; @@ -554,8 +552,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return -EINVAL; if (dmabuf->ops->begin_cpu_access) - ret = dmabuf->ops->begin_cpu_access(dmabuf, start, - len, direction); + ret = dmabuf->ops->begin_cpu_access(dmabuf, direction); return ret; } @@ -567,19 +564,17 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); * actions. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to complete cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * * This call must always succeed. */ -void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, +void dma_buf_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { WARN_ON(!dmabuf); if (dmabuf->ops->end_cpu_access) - dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); + dmabuf->ops->end_cpu_access(dmabuf, direction); } EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index e9c2bfd85b52..65ab2bd54af5 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -196,7 +196,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct * return -EINVAL; } -static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction) +static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) { struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); struct drm_device *dev = obj->base.dev; diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c index 27c297672076..aebae1c2dab2 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c @@ -79,7 +79,7 @@ static void omap_gem_dmabuf_release(struct dma_buf *buffer) static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer, - size_t start, size_t len, enum dma_data_direction dir) + enum dma_data_direction dir) { struct drm_gem_object *obj = buffer->priv; struct page **pages; @@ -94,7 +94,7 @@ static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer, } static void omap_gem_dmabuf_end_cpu_access(struct dma_buf *buffer, - size_t start, size_t len, enum dma_data_direction dir) + enum dma_data_direction dir) { struct drm_gem_object *obj = buffer->priv; omap_gem_put_pages(obj); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 200419d4d43c..c427499133d6 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -409,7 +409,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, if (ufb->obj->base.import_attach) { ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf, - 0, ufb->obj->base.size, DMA_FROM_DEVICE); if (ret) goto unlock; @@ -425,7 +424,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, if (ufb->obj->base.import_attach) { dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, - 0, ufb->obj->base.size, DMA_FROM_DEVICE); } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index e237e9f3312d..0754a37c9674 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1057,8 +1057,7 @@ static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, { } -static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, - size_t len, +static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { struct ion_buffer *buffer = dmabuf->priv; @@ -1076,8 +1075,7 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, return PTR_ERR_OR_ZERO(vaddr); } -static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, - size_t len, +static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { struct ion_buffer *buffer = dmabuf->priv; diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c index b8dcf5a26cc4..da34bc12cd7c 100644 --- a/drivers/staging/android/ion/ion_test.c +++ b/drivers/staging/android/ion/ion_test.c @@ -109,7 +109,7 @@ static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr, if (offset > dma_buf->size || size > dma_buf->size - offset) return -EINVAL; - ret = dma_buf_begin_cpu_access(dma_buf, offset, size, dir); + ret = dma_buf_begin_cpu_access(dma_buf, dir); if (ret) return ret; @@ -139,7 +139,7 @@ static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr, copy_offset = 0; } err: - dma_buf_end_cpu_access(dma_buf, offset, size, dir); + dma_buf_end_cpu_access(dma_buf, dir); return ret; } diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index f98bd7068d55..532108ea0c1c 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -54,7 +54,7 @@ struct dma_buf_attachment; * @release: release this buffer; to be called after the last dma_buf_put. * @begin_cpu_access: [optional] called before cpu access to invalidate cpu * caches and allocate backing storage (if not yet done) - * respectively pin the objet into memory. + * respectively pin the object into memory. * @end_cpu_access: [optional] called after cpu access to flush caches. * @kmap_atomic: maps a page from the buffer into kernel address * space, users may not block until the subsequent unmap call. @@ -93,10 +93,8 @@ struct dma_buf_ops { /* after final dma_buf_put() */ void (*release)(struct dma_buf *); - int (*begin_cpu_access)(struct dma_buf *, size_t, size_t, - enum dma_data_direction); - void (*end_cpu_access)(struct dma_buf *, size_t, size_t, - enum dma_data_direction); + int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); + void (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); void *(*kmap_atomic)(struct dma_buf *, unsigned long); void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *); void *(*kmap)(struct dma_buf *, unsigned long); @@ -224,9 +222,9 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); -int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, +int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction dir); -void dma_buf_end_cpu_access(struct dma_buf *dma_buf, size_t start, size_t len, +void dma_buf_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction dir); void *dma_buf_kmap_atomic(struct dma_buf *, unsigned long); void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *); -- GitLab From 9388187fd7a8d4b4357a587c81958d70bd7e590a Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Tue, 2 Feb 2016 20:30:48 -0600 Subject: [PATCH 0848/5324] ARM: zynq: initialize slcr mapping earlier In preparation for performing additional configuration prior to bringing up L2, move the slcr initialization earlier in the boot process. Signed-off-by: Josh Cartwright Signed-off-by: Michal Simek --- arch/arm/mach-zynq/common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 6f39d03cc27e..860ffb663f02 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -150,8 +150,6 @@ static void __init zynq_init_machine(void) static void __init zynq_timer_init(void) { - zynq_early_slcr_init(); - zynq_clock_init(); of_clk_init(NULL); clocksource_probe(); @@ -186,6 +184,7 @@ static void __init zynq_map_io(void) static void __init zynq_irq_init(void) { + zynq_early_slcr_init(); irqchip_init(); } -- GitLab From 6ded93a1193071fa56b4ce03f6ef2ccbf42ffee5 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Tue, 2 Feb 2016 20:30:49 -0600 Subject: [PATCH 0849/5324] ARM: zynq: address L2 cache data corruption The Zynq has a bug where the L2 cache will return invalid data in some circumstances unless the L2C_RAM register is set to 0x00020202 before the first enabling of the L2 cache. The Xilinx-recommended solution to this problem is to ensure that early one of the earlier bootstages correctly initialize L2C_RAM, however, this issue wasn't discovered and fixed until after their EDK/SDK 14.4 release. For systems built prior to that, and which lack field-upgradable bootloaders, this issue still exists and silent data corruption can be seen in the wild. Fix these systems by ensuring L2C_RAM is properly initialized at the earliest convenient moment prior to the L2 being brought up, which is when the SLCR is first mapped. The Zynq bug is described in more detail by Xilinx AR# 54190 as quoted below. Xilinx AR# 54190 http://www.xilinx.com/support/answers/54190.htm Captured on 2014-09-24 14:43 -0500 = Description = For proper L2 cache operation, the user code must program the slcr.L2C_RAM register (address 0xF800_0A1C) to the value of 0x0002_0202 before enabling the L2 cache. The reset value (0x0001_0101) might cause, very infrequently, the L2 cache to return invalid data. = Solution = It is up to the user code (FSBL or other user code) to set the slcr.L2C_RAM register to the value 0x0002_0202 before enabling the L2 cache. Note: The L2 cache is disabled after reset and is not enabled by the BootROM. Note: The slcr.l2C_RAM register was previously reserved. It is added in the Zynq-7000 AP SoC Technical Reference Manual (TRM) v1.5 as "Reserved". Thanks to Jaeden Amero for initial debugging and triage efforts. Signed-off-by: Josh Cartwright Signed-off-by: Michal Simek --- arch/arm/mach-zynq/slcr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index 26320ebf3493..f0292a30e6f6 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -28,6 +28,7 @@ #define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */ #define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */ #define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */ +#define SLCR_L2C_RAM 0xA1C /* L2C_RAM in AR#54190 */ #define SLCR_UNLOCK_MAGIC 0xDF0D #define SLCR_A9_CPU_CLKSTOP 0x10 @@ -227,6 +228,9 @@ int __init zynq_early_slcr_init(void) /* unlock the SLCR so that registers can be changed */ zynq_slcr_unlock(); + /* See AR#54190 design advisory */ + regmap_update_bits(zynq_slcr_regmap, SLCR_L2C_RAM, 0x70707, 0x20202); + register_restart_handler(&zynq_slcr_restart_nb); pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); -- GitLab From 4965be1fc8dbb3dfc8bf401c78cb78c35d5d0d4d Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 9 Feb 2016 14:35:43 +0530 Subject: [PATCH 0850/5324] ARM: DRA7: hwmod: Fix OCP2SCP sysconfig OCP2SCP doesn't support smart idle wakeup according to Table 26-22. OCP2SCP_SYSCONFIG in AM572x TRM [1] and Table 26-22. OCP2SCP_SYSCONFIG in AM571x TRM [2]. Remove SIDLE_SMART_WKUP from the list of supported SIDLE modes in hwmod data. [1] -> http://www.ti.com/lit/ug/spruhz6e/spruhz6e.pdf [2] -> http://www.ti.com/lit/ug/spruhz7a/spruhz7a.pdf Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 848356e38b74..84c2699e551b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -1482,8 +1482,7 @@ static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_sysc = { .syss_offs = 0x0014, .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, }; -- GitLab From 8fe097a3d99e22355fb8e3bcee59542bf3f46b2d Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Thu, 14 Jan 2016 19:41:10 +0530 Subject: [PATCH 0851/5324] ARM: DRA7: hwmod: Add reset data for PCIe Add PCIe reset data to PCIe hwmods on DRA7x. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Sekhar Nori Reviewed-by: Suman Anna Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 15 +++++++++++++++ arch/arm/mach-omap2/prm7xx.h | 1 + 2 files changed, 16 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 84c2699e551b..b61355e2a771 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -1531,29 +1531,44 @@ static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { }; /* pcie1 */ +static struct omap_hwmod_rst_info dra7xx_pciess1_resets[] = { + { .name = "pcie", .rst_shift = 0 }, +}; + static struct omap_hwmod dra7xx_pciess1_hwmod = { .name = "pcie1", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess1_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess1_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, }, }; +/* pcie2 */ +static struct omap_hwmod_rst_info dra7xx_pciess2_resets[] = { + { .name = "pcie", .rst_shift = 1 }, +}; + /* pcie2 */ static struct omap_hwmod dra7xx_pciess2_hwmod = { .name = "pcie2", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess2_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess2_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS2_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h index cc1e6a2b97f6..294deed956f3 100644 --- a/arch/arm/mach-omap2/prm7xx.h +++ b/arch/arm/mach-omap2/prm7xx.h @@ -360,6 +360,7 @@ /* PRM.L3INIT_PRM register offsets */ #define DRA7XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 #define DRA7XX_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET 0x0010 #define DRA7XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 #define DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c #define DRA7XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 -- GitLab From 9b4fffa14906fce7aabf1f032ddd7efc7a031bba Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Tue, 9 Feb 2016 18:17:48 +1100 Subject: [PATCH 0852/5324] powerpc/powernv: new function to access OPAL msglog Currently, the OPAL msglog/console buffer is exposed as a sysfs file, with the sysfs read handler responsible for retrieving the log from the OPAL buffer. We'd like to be able to use it in xmon as well. Refactor the OPAL msglog code to create a new function, opal_msglog_copy(), that copies to an arbitrary buffer. Separate the initialisation code into generic memcons init and sysfs file creation. Signed-off-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal.h | 3 ++ arch/powerpc/platforms/powernv/opal-msglog.c | 29 +++++++++++++------- arch/powerpc/platforms/powernv/opal.c | 7 +++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 07a99e638449..9d86c6651716 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -248,6 +248,7 @@ extern int opal_elog_init(void); extern void opal_platform_dump_init(void); extern void opal_sys_param_init(void); extern void opal_msglog_init(void); +extern void opal_msglog_sysfs_init(void); extern int opal_async_comp_init(void); extern int opal_sensor_init(void); extern int opal_hmi_handler_init(void); @@ -273,6 +274,8 @@ void opal_free_sg_list(struct opal_sg_list *sg); extern int opal_error_code(int rc); +ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_OPAL_H */ diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c index 44ed78af1a0d..59fa6e1cbc9b 100644 --- a/arch/powerpc/platforms/powernv/opal-msglog.c +++ b/arch/powerpc/platforms/powernv/opal-msglog.c @@ -31,26 +31,25 @@ struct memcons { __be32 in_cons; }; -static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, - struct bin_attribute *bin_attr, char *to, - loff_t pos, size_t count) +static struct memcons *opal_memcons = NULL; + +ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count) { - struct memcons *mc = bin_attr->private; const char *conbuf; ssize_t ret; size_t first_read = 0; uint32_t out_pos, avail; - if (!mc) + if (!opal_memcons) return -ENODEV; - out_pos = be32_to_cpu(ACCESS_ONCE(mc->out_pos)); + out_pos = be32_to_cpu(ACCESS_ONCE(opal_memcons->out_pos)); /* Now we've read out_pos, put a barrier in before reading the new * data it points to in conbuf. */ smp_rmb(); - conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys)); + conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys)); /* When the buffer has wrapped, read from the out_pos marker to the end * of the buffer, and then read the remaining data as in the un-wrapped @@ -58,7 +57,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, if (out_pos & MEMCONS_OUT_POS_WRAP) { out_pos &= MEMCONS_OUT_POS_MASK; - avail = be32_to_cpu(mc->obuf_size) - out_pos; + avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos; ret = memory_read_from_buffer(to, count, &pos, conbuf + out_pos, avail); @@ -76,7 +75,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, } /* Sanity check. The firmware should not do this to us. */ - if (out_pos > be32_to_cpu(mc->obuf_size)) { + if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) { pr_err("OPAL: memory console corruption. Aborting read.\n"); return -EINVAL; } @@ -91,6 +90,13 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, return ret; } +static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, char *to, + loff_t pos, size_t count) +{ + return opal_msglog_copy(to, pos, count); +} + static struct bin_attribute opal_msglog_attr = { .attr = {.name = "msglog", .mode = 0444}, .read = opal_msglog_read @@ -117,8 +123,11 @@ void __init opal_msglog_init(void) return; } - opal_msglog_attr.private = mc; + opal_memcons = mc; +} +void __init opal_msglog_sysfs_init(void) +{ if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) pr_warn("OPAL: sysfs file creation failed\n"); } diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 4e0da5af94a1..0256d0729252 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -724,6 +724,9 @@ static int __init opal_init(void) of_node_put(leds); } + /* Initialise OPAL message log interface */ + opal_msglog_init(); + /* Create "opal" kobject under /sys/firmware */ rc = opal_sysfs_init(); if (rc == 0) { @@ -739,8 +742,8 @@ static int __init opal_init(void) opal_platform_dump_init(); /* Setup system parameters interface */ opal_sys_param_init(); - /* Setup message log interface. */ - opal_msglog_init(); + /* Setup message log sysfs interface. */ + opal_msglog_sysfs_init(); } /* Initialize platform devices: IPMI backend, PRD & flash interface */ -- GitLab From 78385cb398748debb7ea2e36d6d2001830c172bc Mon Sep 17 00:00:00 2001 From: Lyude Date: Tue, 2 Feb 2016 10:49:43 -0500 Subject: [PATCH 0853/5324] drm/i915/skl: Don't skip mst encoders in skl_ddi_pll_select() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't actually check for INTEL_OUTPUT_DP_MST at all in here, as a result we skip assigning a DPLL to any DP MST ports, which makes link training fail: [ 1442.933896] [drm:intel_power_well_enable] enabling DDI D power well [ 1442.933905] [drm:skl_set_power_well] Enabling DDI D power well [ 1442.933957] [drm:intel_mst_pre_enable_dp] 0 [ 1442.935474] [drm:intel_dp_set_signal_levels] Using signal levels 00000000 [ 1442.935477] [drm:intel_dp_set_signal_levels] Using vswing level 0 [ 1442.935480] [drm:intel_dp_set_signal_levels] Using pre-emphasis level 0 [ 1442.936190] [drm:intel_dp_set_signal_levels] Using signal levels 05000000 [ 1442.936193] [drm:intel_dp_set_signal_levels] Using vswing level 1 [ 1442.936195] [drm:intel_dp_set_signal_levels] Using pre-emphasis level 1 [ 1442.936858] [drm:intel_dp_set_signal_levels] Using signal levels 08000000 [ 1442.936862] [drm:intel_dp_set_signal_levels] Using vswing level 2 … [ 1442.998253] [drm:intel_dp_link_training_clock_recovery [i915]] *ERROR* too many full retries, give up [ 1442.998512] [drm:intel_dp_start_link_train [i915]] *ERROR* failed to train DP, aborting After which the pipe state goes completely out of sync: [ 70.075596] [drm:check_crtc_state] [CRTC:25] [ 70.075696] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in ddi_pll_sel (expected 0x00000000, found 0x00000001) [ 70.075747] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in shared_dpll (expected -1, found 0) [ 70.075798] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in dpll_hw_state.ctrl1 (expected 0x00000000, found 0x00000021) [ 70.075840] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in dpll_hw_state.cfgcr1 (expected 0x00000000, found 0x80400173) [ 70.075884] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in dpll_hw_state.cfgcr2 (expected 0x00000000, found 0x000003a5) [ 70.075954] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in base.adjusted_mode.crtc_clock (expected 262750, found 72256) [ 70.075999] [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in port_clock (expected 540000, found 148500) And if you're especially lucky, it keeps going downhill: [ 83.309256] Kernel panic - not syncing: Timeout: Not all CPUs entered broadcast exception handler [ 83.309265] [ 83.309265] ================================= [ 83.309266] [ INFO: inconsistent lock state ] [ 83.309267] 4.5.0-rc1Lyude-Test #265 Not tainted [ 83.309267] --------------------------------- [ 83.309268] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. [ 83.309270] Xorg/1194 [HC0[1]:SC0[0]:HE1:SE1] takes: [ 83.309293] (&(&dev_priv->uncore.lock)->rlock){?.-...}, at: [] gen9_write32+0x63/0x400 [i915] [ 83.309293] {IN-HARDIRQ-W} state was registered at: [ 83.309297] [] __lock_acquire+0x9c4/0x1d00 [ 83.309299] [] lock_acquire+0xce/0x1c0 [ 83.309302] [] _raw_spin_lock_irqsave+0x56/0x90 [ 83.309321] [] gen9_read32+0x52/0x3d0 [i915] [ 83.309332] [] gen8_irq_handler+0x27a/0x6a0 [i915] [ 83.309337] [] handle_irq_event_percpu+0x41/0x300 [ 83.309339] [] handle_irq_event+0x39/0x60 [ 83.309341] [] handle_edge_irq+0x74/0x130 [ 83.309344] [] handle_irq+0x73/0x120 [ 83.309346] [] do_IRQ+0x61/0x120 [ 83.309348] [] ret_from_intr+0x0/0x20 [ 83.309351] [] cpuidle_enter_state+0x105/0x330 [ 83.309353] [] cpuidle_enter+0x17/0x20 [ 83.309356] [] call_cpuidle+0x2a/0x50 [ 83.309358] [] cpu_startup_entry+0x26d/0x3a0 [ 83.309360] [] rest_init+0x13a/0x140 [ 83.309363] [] start_kernel+0x475/0x482 [ 83.309365] [] x86_64_start_reservations+0x2a/0x2c [ 83.309367] [] x86_64_start_kernel+0x13b/0x14a Fixes: 82d354370189 ("drm/i915/skl: Implementation of SKL DPLL programming") Signed-off-by: Lyude Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454428183-994-1-git-send-email-cpaul@redhat.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 6d5b09f2a8a6..32c8991669d1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1531,7 +1531,8 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, DPLL_CFGCR2_KDIV(wrpll_params.kdiv) | DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | wrpll_params.central_freq; - } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { + } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || + intel_encoder->type == INTEL_OUTPUT_DP_MST) { switch (crtc_state->port_clock / 2) { case 81000: ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0); -- GitLab From 5a01d5b61399fb03ffd54edfb68dca411d89dcda Mon Sep 17 00:00:00 2001 From: Lyude Date: Tue, 2 Feb 2016 09:35:09 -0500 Subject: [PATCH 0854/5324] drm/i915/skl: Explicitly check for eDP in skl_ddi_pll_select() Assuming any connector that isn't DP, MST, or HDMI is eDP definitely seems likely to cover up other bugs in the future. Signed-off-by: Lyude Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454423709-21882-2-git-send-email-cpaul@redhat.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 32c8991669d1..cdf2e14aa45d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1546,8 +1546,10 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, } cfgcr1 = cfgcr2 = 0; - } else /* eDP */ + } else if (intel_encoder->type == INTEL_OUTPUT_EDP) { return true; + } else + return false; memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); -- GitLab From 89bf707923ec708b88b44b26bc439b1c188b38da Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 21 Jan 2016 15:26:49 +0100 Subject: [PATCH 0855/5324] ARM: realview: activate SMP on the default defconfig The realview has two defconfigs: realview_defconfig and realview-smp_defconfig. We now have working SMP_ON_UP so make them equal so we can delete the -smp variant. For some reason NO_HZ_FULL was missing from the plain realview_defconfig. Signed-off-by: Linus Walleij --- arch/arm/configs/realview_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 8f56fb3ff51d..9f84c508a5f4 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -1,5 +1,6 @@ # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +CONFIG_NO_HZ_FULL=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_PERF_EVENTS=y @@ -21,6 +22,7 @@ CONFIG_MACH_REALVIEW_PB11MP=y CONFIG_MACH_REALVIEW_PB1176=y CONFIG_MACH_REALVIEW_PBA8=y CONFIG_MACH_REALVIEW_PBX=y +CONFIG_SMP=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -- GitLab From 7a6f752e27e52cc981cf2f629932a76007212300 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 21 Jan 2016 15:40:52 +0100 Subject: [PATCH 0856/5324] ARM: realview: delete realview-smp_defconfig We enabled SMP in the realview_defconfig so delete the SMP-specific defconfig. Signed-off-by: Linus Walleij --- arch/arm/configs/realview-smp_defconfig | 105 ------------------------ 1 file changed, 105 deletions(-) delete mode 100644 arch/arm/configs/realview-smp_defconfig diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig deleted file mode 100644 index 93efdcfcf98f..000000000000 --- a/arch/arm/configs/realview-smp_defconfig +++ /dev/null @@ -1,105 +0,0 @@ -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ_FULL=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_PERF_EVENTS=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_MULTI_V6=y -CONFIG_ARCH_REALVIEW=y -CONFIG_REALVIEW_DT=y -CONFIG_MACH_REALVIEW_EB=y -CONFIG_REALVIEW_EB_ARM1136=y -CONFIG_REALVIEW_EB_ARM1176=y -CONFIG_REALVIEW_EB_A9MP=y -CONFIG_REALVIEW_EB_ARM11MP=y -CONFIG_REALVIEW_EB_ARM11MP_REVB=y -CONFIG_MACH_REALVIEW_PB11MP=y -CONFIG_MACH_REALVIEW_PB1176=y -CONFIG_MACH_REALVIEW_PBA8=y -CONFIG_MACH_REALVIEW_PBX=y -CONFIG_SMP=y -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" -CONFIG_VFP=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_AFS_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_ROM=y -CONFIG_MTD_PHYSMAP=y -CONFIG_ARM_CHARLCD=y -CONFIG_NETDEVICES=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y -CONFIG_SMSC_PHY=y -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_AMBAKMI=y -CONFIG_LEGACY_PTY_COUNT=16 -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_VERSATILE=y -CONFIG_SPI=y -CONFIG_GPIOLIB=y -# CONFIG_HWMON is not set -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ARMAACI=y -CONFIG_USB=y -CONFIG_USB_ISP1760=y -CONFIG_MMC=y -CONFIG_MMC_ARMMMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_VERSATILE=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_PL031=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_FTRACE is not set -CONFIG_DEBUG_USER=y -# CONFIG_CRYPTO_HW is not set -- GitLab From 52abf1eff88d291c5ba092dc93fc8065efd94236 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 21 Jan 2016 15:42:30 +0100 Subject: [PATCH 0857/5324] ARM: realview: enable USB storage in the defconfig It is not uncommon to boot a root filesystem from a USB pendrive and similar, so enable USB mass storage, backed by SCSI and SD block devices in the RealView defconfig. Signed-off-by: Linus Walleij --- arch/arm/configs/realview_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 9f84c508a5f4..9e77dc7b828f 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -48,6 +48,8 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y CONFIG_MTD_PHYSMAP=y CONFIG_ARM_CHARLCD=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_SMC91X=y CONFIG_SMSC911X=y @@ -76,6 +78,7 @@ CONFIG_SND_PCM_OSS=y # CONFIG_SND_DRIVERS is not set CONFIG_SND_ARMAACI=y CONFIG_USB=y +CONFIG_USB_STORAGE=y CONFIG_USB_ISP1760=y CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y -- GitLab From 05abb9754b503dd39b31bc191fe87c7fca957f3e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 21 Dec 2015 15:41:55 +0100 Subject: [PATCH 0858/5324] ARM: dts: armada-38x: adjust board name and compatible for Armada 388 GP As the name of the Device Tree file name suggests, the Armada 388 GP really contains an Armada 388 SoC, so this commit updates the board name and compatible string in the Device Tree file. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-388-gp.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index cd316021d6ce..bed4a8024a4c 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -44,8 +44,8 @@ #include / { - model = "Marvell Armada 385 GP"; - compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380"; + model = "Marvell Armada 388 DB-88F6820-GP"; + compatible = "marvell,a388-gp", "marvell,armada388", "marvell,armada380"; chosen { stdout-path = "serial0:115200n8"; -- GitLab From a8409c65df76033a496c2dbcec303a3a5e4afc3d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 22 Dec 2015 15:28:42 +0100 Subject: [PATCH 0859/5324] ARM: dts: armada-38x: use regulator-boot-on for SATA regulators on Armada 388 GP Really, what we meant by regulator-always-on is that the regulators are already turned on by the bootloader, for which regulator-boot-on is a better description. A net advantage of using regulator-boot-on is that the regulator is not touched at boot time by the kernel, which avoids having the hard drives spinning down and then up again, taking several (~5) seconds of additional boot time. In addition, there is no need to have such properties on the child regulators used for SATA. Having it on the parent regulator that really controls the GPIO is sufficient. Without the patch: [ 3.945866] ata2: SATA link down (SStatus 0 SControl 300) [ 3.995862] ata3: SATA link down (SStatus 0 SControl 300) [ 4.005863] ata4: SATA link down (SStatus 0 SControl 300) [ 9.125861] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300) [ 9.144575] ata1.00: ATA-8: WDC WD5003ABYX-01WERA1, 01.01S02, max UDMA/133 [ 9.151471] ata1.00: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32) (and you can hear the disk spinning down and up during this 5.1 seconds delay) With the patch: [ 3.945988] ata2: SATA link down (SStatus 0 SControl 300) [ 4.005980] ata4: SATA link down (SStatus 0 SControl 300) [ 4.011404] ata3: SATA link down (SStatus 0 SControl 300) [ 4.145978] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300) [ 4.153701] ata1.00: ATA-8: WDC WD5003ABYX-01WERA1, 01.01S02, max UDMA/133 [ 4.160597] ata1.00: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32) Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-388-gp.dts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index bed4a8024a4c..ac3c9445ce57 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -309,7 +309,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 2 GPIO_ACTIVE_HIGH>; }; @@ -318,7 +318,6 @@ regulator-name = "v5.0-sata0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -327,7 +326,6 @@ regulator-name = "v12.0-sata0"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -337,7 +335,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 3 GPIO_ACTIVE_HIGH>; }; @@ -346,7 +344,6 @@ regulator-name = "v5.0-sata1"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -355,7 +352,6 @@ regulator-name = "v12.0-sata1"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -363,7 +359,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata2"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 11 GPIO_ACTIVE_HIGH>; }; @@ -372,7 +368,6 @@ regulator-name = "v5.0-sata2"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -381,7 +376,6 @@ regulator-name = "v12.0-sata2"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -389,7 +383,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata3"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 12 GPIO_ACTIVE_HIGH>; }; @@ -398,7 +392,6 @@ regulator-name = "v5.0-sata3"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata3>; }; @@ -407,7 +400,6 @@ regulator-name = "v12.0-sata3"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata3>; }; }; -- GitLab From 96c78e2b7733f1e0e4170ecead34ff2b11ce0bd1 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 23 Dec 2015 15:05:41 +0100 Subject: [PATCH 0860/5324] ARM: dts: armada-38x: use usb-nop-xceiv PHY for the xhci nodes on Armada 388 GP Using the usb-nop-xceiv PHY for the xhci nodes allows a better representation of the hardware but also a better handling of the regulator. By linking the regulator to the PHY there is no more need to use the regulator-always-on property, then it allows a better power management. The remaining usb node uses the ehci-orion driver which can't be used with the usb-nop-xceiv PHY and must keeps the direct link to the regulator with the regulator-always-on property. Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-388-gp.dts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index ac3c9445ce57..51943598d858 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -229,13 +229,13 @@ /* CON5 */ usb3@f0000 { - vcc-supply = <®_usb2_1_vbus>; + usb-phy = <&usb2_1_phy>; status = "okay"; }; /* CON7 */ usb3@f8000 { - vcc-supply = <®_usb3_vbus>; + usb-phy = <&usb3_phy>; status = "okay"; }; }; @@ -273,13 +273,22 @@ }; }; + usb2_1_phy: usb2_1_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb2_1_vbus>; + }; + + usb3_phy: usb3_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_vbus>; + }; + reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; regulator-name = "usb3-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander1 15 GPIO_ACTIVE_HIGH>; }; @@ -299,7 +308,6 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; }; -- GitLab From ce5cad51f38160e87d1ab5ef9c1bc9c8aabb3b92 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 23 Dec 2015 15:29:17 +0100 Subject: [PATCH 0861/5324] ARM: dts: armada-370: Update the mpp63 function in the device tree on Armada 370 Since the commit a526973e0291 ("pinctrl: mvebu: Fix mapping of pin 63 (gpo -> gpio)"), the mpp63 is no more declared as a GPO but is a GPIO. Even if in the datasheet this pin is described as GPO, the experience of the D-Link DNS-327L board shows that it can be used as a GPIO. This commits generated warnings for the board using this pin as gpo, with this patch the dts are fixed by using the new function (gpio) instead of the old one. The binding documentation has also been updated accordingly. Signed-off-by: Gregory CLEMENT Acked-by: Jason Cooper --- .../bindings/pinctrl/marvell,armada-370-pinctrl.txt | 5 ++++- arch/arm/boot/dts/armada-370-mirabox.dts | 2 +- arch/arm/boot/dts/armada-370-netgear-rn104.dts | 2 +- arch/arm/boot/dts/armada-370-synology-ds213j.dts | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt index add7c38ec7d8..8662f3aaf312 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt @@ -91,6 +91,9 @@ mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rstout), mpp61 61 gpo, dev(we1), uart1(txd), audio(lrclk) mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0), audio(mclk), uart0(cts) -mpp63 63 gpo, spi0(sck), tclk +mpp63 63 gpio, spi0(sck), tclk mpp64 64 gpio, spi0(miso), spi0(cs1) mpp65 65 gpio, spi0(mosi), spi0(cs2) + +Note: According to the datasheet mpp63 is a gpo but there is at least +one example of a gpio usage on the board D-Link DNS-327L diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index 3aa980ad64f0..d5e19cd4d256 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -200,7 +200,7 @@ &pinctrl { pwr_led_pin: pwr-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; stat_led_pins: stat-led-pins { diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index faa474874cb8..11565752b9f6 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -297,7 +297,7 @@ backup_led_pin: backup-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; power_led_pin: power-led-pin { diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts index 836bcc07afc5..8ca7a4340c0f 100644 --- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts +++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts @@ -339,7 +339,7 @@ fan_ctrl_high_pin: fan-ctrl-high-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; fan_alarm_pin: fan-alarm-pin { -- GitLab From 2b1fd39864a57bf37f7003630f9d0f96c8f6923a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 12 Jan 2016 22:07:32 +0200 Subject: [PATCH 0862/5324] ARM: dts: kirkwood: fix pin names for UART/SD selection for OpenRD The UART/SD pin names are swapped, fix that. Signed-off-by: Aaro Koskinen Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-openrd.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index d3330dadf7ed..2a3dafdab09a 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi @@ -40,7 +40,7 @@ pinctrl-0 = <&pmx_select28 &pmx_sdio_cd &pmx_select34>; pinctrl-names = "default"; - pmx_select28: pmx-select-uart-sd { + pmx_select28: pmx-select-rs232-rs484 { marvell,pins = "mpp28"; marvell,function = "gpio"; }; @@ -48,7 +48,7 @@ marvell,pins = "mpp29"; marvell,function = "gpio"; }; - pmx_select34: pmx-select-rs232-rs484 { + pmx_select34: pmx-select-uart-sd { marvell,pins = "mpp34"; marvell,function = "gpio"; }; -- GitLab From 28c494d0c5b7e0993d067086b26c901ae23d3841 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 12 Jan 2016 22:07:33 +0200 Subject: [PATCH 0863/5324] ARM: dts: kirkwood: fix SD slot default configuration for OpenRD The SD card slot was enabled by default with legacy booting. It does not work anymore with DT boot. Fix by providing GPIO configuration that matches the old default. Signed-off-by: Aaro Koskinen Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-openrd.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index 2a3dafdab09a..f65b7273bb0a 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi @@ -65,6 +65,14 @@ status = "okay"; cd-gpios = <&gpio0 29 9>; }; + gpio@10140 { + p2 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + output-high; /* Select SD by default */ + line-name = "SelUARTorSD"; + }; + }; }; }; -- GitLab From 3e2f2db885fb0cb16ae8949d4d2283f1ac272329 Mon Sep 17 00:00:00 2001 From: Roger Shimizu Date: Thu, 21 Jan 2016 23:38:48 +0900 Subject: [PATCH 0864/5324] ARM: dts: kirkwood: relicense dts of ls-wvl/vl and ls-wxl/wsxl under GPLv2/X11 Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-lswvl.dts | 41 +++++++++++++++++++++++++--- arch/arm/boot/dts/kirkwood-lswxl.dts | 41 +++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-lswvl.dts index 36eec7392ab4..04bdc4f19a9f 100644 --- a/arch/arm/boot/dts/kirkwood-lswvl.dts +++ b/arch/arm/boot/dts/kirkwood-lswvl.dts @@ -4,10 +4,43 @@ * Copyright (C) 2015, 2016 * Roger Shimizu * - * 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. + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. */ /dts-v1/; diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-lswxl.dts index b13ec20a7088..930899d13c5d 100644 --- a/arch/arm/boot/dts/kirkwood-lswxl.dts +++ b/arch/arm/boot/dts/kirkwood-lswxl.dts @@ -4,10 +4,43 @@ * Copyright (C) 2015, 2016 * Roger Shimizu * - * 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. + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. */ /dts-v1/; -- GitLab From b05465ff5b5e90d6d25d3f6c4e8ac6b2b3159435 Mon Sep 17 00:00:00 2001 From: Roger Shimizu Date: Thu, 21 Jan 2016 23:38:49 +0900 Subject: [PATCH 0865/5324] ARM: dts: kirkwood: split lswxl dts to linkstation lswsxl and lswxl LS-WXL/WSXL are both kirkwood-6281 based 2-Bay NAS devices, which share many MPP pins. However they are slightly different: - There're two red LED indicator on LS-WXL to show when HDD fails, but there's no such on LS-WSXL. - There's 4-level speed adjustable FAN on LS-WXL, but not LS-WSXL. So after the split, common part goes into .dtsi file: - kirkwood-linkstation.dtsi - kirkwood-linkstation-duo-6281.dtsi while all rest part goes into device specific .dts file: - kirkwood-linkstation-lswsxl.dts - kirkwood-linkstation-lswxl.dts Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- .../bindings/arm/marvell,kirkwood.txt | 3 +- arch/arm/boot/dts/Makefile | 3 +- .../dts/kirkwood-linkstation-duo-6281.dtsi | 186 ++++++++++++++++++ .../boot/dts/kirkwood-linkstation-lswsxl.dts | 57 ++++++ .../boot/dts/kirkwood-linkstation-lswxl.dts | 116 +++++++++++ ...od-lswxl.dts => kirkwood-linkstation.dtsi} | 149 +------------- 6 files changed, 371 insertions(+), 143 deletions(-) create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts rename arch/arm/boot/dts/{kirkwood-lswxl.dts => kirkwood-linkstation.dtsi} (61%) diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt index ab0c9cdf388e..f68bdec8e111 100644 --- a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt +++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt @@ -19,9 +19,10 @@ SoC. Currently known SoC compatibles are: And in addition, the compatible shall be extended with the specific board. Currently known boards are: +"buffalo,linkstation-lswsxl" +"buffalo,linkstation-lswxl" "buffalo,lschlv2" "buffalo,lswvl" -"buffalo,lswxl" "buffalo,lsxhl" "buffalo,lsxl" "cloudengines,pogo02" diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26..6771d0b5dc2a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -189,9 +189,10 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-laplug.dtb \ + kirkwood-linkstation-lswsxl.dtb \ + kirkwood-linkstation-lswxl.dtb \ kirkwood-lschlv2.dtb \ kirkwood-lswvl.dtb \ - kirkwood-lswxl.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ kirkwood-mv88f6281gtw-ge.dtb \ diff --git a/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi new file mode 100644 index 000000000000..cf2e69f0d54f --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi @@ -0,0 +1,186 @@ +/* + * Device Tree common file for kirkwood-6281 based 2-Bay Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +#include "kirkwood.dtsi" +#include "kirkwood-6281.dtsi" +#include "kirkwood-linkstation.dtsi" + +/ { + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,pins = "mpp28"; + marvell,function = "gpio"; + }; + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,pins = "mpp37"; + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,pins = "mpp49"; + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,pins = "mpp36"; + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,pins = "mpp41"; + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp42"; + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,pins = "mpp43"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_keys { + function-button { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + + power-on-switch { + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; + + power-auto-switch { + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + }; + + gpio_leds { + red-alarm-led { + label = "linkstation:red:alarm"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + }; + + red-function-led { + label = "linkstation:red:function"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + amber-info-led { + label = "linkstation:amber:info"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + }; + + blue-function-led { + label = "linkstation:blue:function"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + }; + + blue-power-led { + label = "linkstation:blue:power"; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + default-state = "keep"; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + usb_power: regulator@1 { + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; + + hdd_power0: regulator@2 { + gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy1: ethernet-phy@8 { + device_type = "ethernet-phy"; + reg = <8>; + }; +}; + +ð1 { + status = "okay"; + + ethernet1-port@0 { + phy-handle = <ðphy1>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts new file mode 100644 index 000000000000..4b6450186af5 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WSXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; +#include "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WSXL"; + compatible = "buffalo,lswsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts new file mode 100644 index 000000000000..ecd5c12a805d --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts @@ -0,0 +1,116 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; +#include "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WXL"; + compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp48"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpios = <&gpio1 16 GPIO_ACTIVE_LOW + &gpio1 15 GPIO_ACTIVE_LOW>; + + gpio-fan,speed-map = <0 3 + 1500 2 + 3250 1 + 5000 0>; + + alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-linkstation.dtsi similarity index 61% rename from arch/arm/boot/dts/kirkwood-lswxl.dts rename to arch/arm/boot/dts/kirkwood-linkstation.dtsi index 930899d13c5d..69061b6e987b 100644 --- a/arch/arm/boot/dts/kirkwood-lswxl.dts +++ b/arch/arm/boot/dts/kirkwood-linkstation.dtsi @@ -1,5 +1,5 @@ /* - * Device Tree file for Buffalo Linkstation LS-WXL/WSXL + * Device Tree common file for kirkwood based Buffalo Linkstation * * Copyright (C) 2015, 2016 * Roger Shimizu @@ -43,20 +43,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - / { - model = "Buffalo Linkstation LS-WXL/WSXL"; - compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { /* 128 MB */ - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - chosen { bootargs = "console=ttyS0,115200n8 earlyprintk"; stdout-path = &uart0; @@ -74,67 +61,33 @@ ocp@f1000000 { pinctrl: pin-controller@10000 { pmx_power_hdd0: pmx-power-hdd0 { - marvell,pins = "mpp28"; - marvell,function = "gpio"; - }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp29"; marvell,function = "gpio"; }; pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp37"; - marvell,function = "gpio"; - }; - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp48"; - marvell,function = "gpio"; - }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp46"; marvell,function = "gpio"; }; pmx_led_alarm: pmx-led-alarm { - marvell,pins = "mpp49"; marvell,function = "gpio"; }; pmx_led_function_red: pmx-led-function-red { - marvell,pins = "mpp34"; marvell,function = "gpio"; }; pmx_led_function_blue: pmx-led-function-blue { - marvell,pins = "mpp36"; marvell,function = "gpio"; }; pmx_led_info: pmx-led-info { - marvell,pins = "mpp38"; marvell,function = "gpio"; }; pmx_led_power: pmx-led-power { - marvell,pins = "mpp39"; - marvell,function = "gpio"; - }; - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp40"; marvell,function = "gpio"; }; pmx_button_function: pmx-button-function { - marvell,pins = "mpp41"; marvell,function = "gpio"; }; pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp42"; marvell,function = "gpio"; }; pmx_power_auto_switch: pmx-power-auto-switch { - marvell,pins = "mpp43"; marvell,function = "gpio"; }; }; @@ -145,7 +98,7 @@ sata@80000 { status = "okay"; - nr-ports = <2>; + nr-ports = <1>; }; spi@10600 { @@ -187,24 +140,21 @@ &pmx_power_auto_switch>; pinctrl-names = "default"; - button@1 { + function-button { label = "Function Button"; linux,code = ; - gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; - button@2 { + power-on-switch { label = "Power-on Switch"; linux,code = ; linux,input-type = <5>; - gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; }; - button@3 { + power-auto-switch { label = "Power-auto Switch"; linux,code = ; linux,input-type = <5>; - gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; }; @@ -212,62 +162,8 @@ compatible = "gpio-leds"; pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; + &pmx_led_function_blue>; pinctrl-names = "default"; - - led@1 { - label = "lswxl:blue:func"; - gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - }; - - led@2 { - label = "lswxl:red:alarm"; - gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; - }; - - led@3 { - label = "lswxl:amber:info"; - gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; - }; - - led@4 { - label = "lswxl:blue:power"; - gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - default-state = "keep"; - }; - - led@5 { - label = "lswxl:red:func"; - gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - }; - - led@6 { - label = "lswxl:red:hdderr0"; - gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; - }; - - led@7 { - label = "lswxl:red:hdderr1"; - gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; - }; - }; - - gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - gpios = <&gpio1 16 GPIO_ACTIVE_LOW - &gpio1 15 GPIO_ACTIVE_LOW>; - - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; restart_poweroff { @@ -278,7 +174,7 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + pinctrl-0 = <&pmx_power_hdd0 &pmx_usb_vbus>; pinctrl-names = "default"; usb_power: regulator@1 { @@ -290,8 +186,8 @@ enable-active-high; regulator-always-on; regulator-boot-on; - gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; }; + hdd_power0: regulator@2 { compatible = "regulator-fixed"; reg = <2>; @@ -301,35 +197,6 @@ enable-active-high; regulator-always-on; regulator-boot-on; - gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; - }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; }; }; }; - -&mdio { - status = "okay"; - - ethphy1: ethernet-phy@8 { - device_type = "ethernet-phy"; - reg = <8>; - }; -}; - -ð1 { - status = "okay"; - - ethernet1-port@0 { - phy-handle = <ðphy1>; - }; -}; -- GitLab From 60ff189ca05dedac97af8d9e51c285a44bc9e5a5 Mon Sep 17 00:00:00 2001 From: Roger Shimizu Date: Thu, 21 Jan 2016 23:38:50 +0900 Subject: [PATCH 0866/5324] ARM: dts: kirkwood: split lswvl dts to linkstation lsvl and lswvl LS-WVL/VL are both kirkwood-6282 based NAS devices, which share many MPP pins. However they are slightly different: - LS-WVL is 2-Bay NAS, and LS-VL is only 1-Bay. - There're two red LED indicator on LS-WVL to show when HDD fails, which is similar to LS-WXL, but there's no such on LS-VL. So after the split, common part goes into .dtsi file: - kirkwood-linkstation-6282.dtsi while all rest part goes into device specific .dts file: - kirkwood-linkstation-lsvl.dts - kirkwood-linkstation-lswvl.dts Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- .../bindings/arm/marvell,kirkwood.txt | 3 +- arch/arm/boot/dts/Makefile | 3 +- ...wvl.dts => kirkwood-linkstation-6282.dtsi} | 175 ++---------------- .../boot/dts/kirkwood-linkstation-lsvl.dts | 57 ++++++ .../boot/dts/kirkwood-linkstation-lswvl.dts | 112 +++++++++++ 5 files changed, 189 insertions(+), 161 deletions(-) rename arch/arm/boot/dts/{kirkwood-lswvl.dts => kirkwood-linkstation-6282.dtsi} (56%) create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt index f68bdec8e111..0fc6faa4cddb 100644 --- a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt +++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt @@ -19,10 +19,11 @@ SoC. Currently known SoC compatibles are: And in addition, the compatible shall be extended with the specific board. Currently known boards are: +"buffalo,linkstation-lsvl" "buffalo,linkstation-lswsxl" "buffalo,linkstation-lswxl" +"buffalo,linkstation-lswvl" "buffalo,lschlv2" -"buffalo,lswvl" "buffalo,lsxhl" "buffalo,lsxl" "cloudengines,pogo02" diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 6771d0b5dc2a..91833f905aef 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -189,10 +189,11 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-laplug.dtb \ + kirkwood-linkstation-lsvl.dtb \ kirkwood-linkstation-lswsxl.dtb \ + kirkwood-linkstation-lswvl.dtb \ kirkwood-linkstation-lswxl.dtb \ kirkwood-lschlv2.dtb \ - kirkwood-lswvl.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ kirkwood-mv88f6281gtw-ge.dtb \ diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi similarity index 56% rename from arch/arm/boot/dts/kirkwood-lswvl.dts rename to arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi index 04bdc4f19a9f..6548e68a20d0 100644 --- a/arch/arm/boot/dts/kirkwood-lswvl.dts +++ b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi @@ -1,5 +1,5 @@ /* - * Device Tree file for Buffalo Linkstation LS-WVL/VL + * Device Tree common file for kirkwood-6282 based Buffalo Linkstation * * Copyright (C) 2015, 2016 * Roger Shimizu @@ -43,44 +43,17 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; - #include "kirkwood.dtsi" #include "kirkwood-6282.dtsi" +#include "kirkwood-linkstation.dtsi" / { - model = "Buffalo Linkstation LS-WVL/VL"; - compatible = "buffalo,lswvl", "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; - - memory { /* 256 MB */ - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - mbus { - pcie-controller { - status = "okay"; - pcie@1,0 { - status = "okay"; - }; - }; - }; - ocp@f1000000 { pinctrl: pin-controller@10000 { pmx_power_hdd0: pmx-power-hdd0 { marvell,pins = "mpp8"; marvell,function = "gpio"; }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; pmx_usb_vbus: pmx-usb-vbus { marvell,pins = "mpp12"; marvell,function = "gpio"; @@ -93,14 +66,6 @@ marvell,pins = "mpp17"; marvell,function = "gpio"; }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp35"; - marvell,function = "gpio"; - }; pmx_led_alarm: pmx-led-alarm { marvell,pins = "mpp36"; marvell,function = "gpio"; @@ -138,120 +103,48 @@ marvell,function = "gpio"; }; }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p40", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; }; gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_button_function &pmx_power_switch - &pmx_power_auto_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Function Button"; - linux,code = ; + function-button { gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; }; - button@2 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; + power-on-switch { gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; }; - button@3 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; + power-auto-switch { gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; }; gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm - &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; - pinctrl-names = "default"; - - led@1 { - label = "lswvl:red:alarm"; + red-alarm-led { + label = "linkstation:red:alarm"; gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; }; - led@2 { - label = "lswvl:red:func"; + red-function-led { + label = "linkstation:red:function"; gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; }; - led@3 { - label = "lswvl:amber:info"; + amber-info-led { + label = "linkstation:amber:info"; gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; }; - led@4 { - label = "lswvl:blue:func"; + blue-function-led { + label = "linkstation:blue:function"; gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; }; - led@5 { - label = "lswvl:blue:power"; + blue-power-led { + label = "linkstation:blue:power"; gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; default-state = "keep"; }; - - led@6 { - label = "lswvl:red:hdderr0"; - gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - }; - - led@7 { - label = "lswvl:red:hdderr1"; - gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; - }; }; gpio_fan { @@ -270,50 +163,14 @@ alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; }; - restart_poweroff { - compatible = "restart-poweroff"; - }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; - pinctrl-names = "default"; - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; }; + hdd_power0: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>; }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts new file mode 100644 index 000000000000..edcba5c44b05 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-VL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-VL"; + compatible = "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts new file mode 100644 index 000000000000..954ec1d5b6dc --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts @@ -0,0 +1,112 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WVL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-WVL"; + compatible = "buffalo,lswvl","marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; -- GitLab From 39ac0979de635c8be94e1353afde65524ac1ed03 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 23 Jan 2016 22:37:17 +0200 Subject: [PATCH 0867/5324] ARM: dts: kirkwood: provide template for RS-232/485 configuration for OpenRD Some OpenRD boards have RS-232 and RS-486 connectors wired, but using them needs a custom DTB as the current DTB configures SD card slot instead. This patch adds documentation into the DTS on how to change the configuration. Signed-off-by: Aaro Koskinen Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-openrd.dtsi | 31 +++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index f65b7273bb0a..24f1d30970a0 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi @@ -40,7 +40,7 @@ pinctrl-0 = <&pmx_select28 &pmx_sdio_cd &pmx_select34>; pinctrl-names = "default"; - pmx_select28: pmx-select-rs232-rs484 { + pmx_select28: pmx-select-rs232-rs485 { marvell,pins = "mpp28"; marvell,function = "gpio"; }; @@ -65,10 +65,39 @@ status = "okay"; cd-gpios = <&gpio0 29 9>; }; + gpio@10100 { + p28 { + gpio-hog; + gpios = <28 GPIO_ACTIVE_HIGH>; + /* + * SelRS232or485 selects between RS-232 or RS-485 + * mode for the second UART. + * + * Low: RS-232 + * High: RS-485 + * + * To use the second UART, you need to change also + * the SelUARTorSD. + */ + output-low; + line-name = "SelRS232or485"; + }; + }; gpio@10140 { p2 { gpio-hog; gpios = <2 GPIO_ACTIVE_HIGH>; + /* + * SelUARTorSD selects between the second UART + * (serial@12100) and SD (mvsdio@90000). + * + * Low: UART + * High: SD + * + * When changing this line make sure the newly + * selected device node is enabled and the + * previously selected device node is disabled. + */ output-high; /* Select SD by default */ line-name = "SelUARTorSD"; }; -- GitLab From 34cabc2a58c2f4ad7fe78c0b54685772d7e68420 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 24 Jan 2016 00:36:39 +0200 Subject: [PATCH 0868/5324] ARM: dts: kirkwood: fix audio for OpenRD clients Fix audio on kirkwood-openrd-client: 1) The audio-controller was left disabled. 2) The probe fails because cs42l51 is missing #sound-dai-cells. /sound/simple-audio-card,codec: could not get #sound-dai-cells for /ocp@f1000000/i2c@11000/cs42l51@4a asoc-simple-card sound: parse error -22 asoc-simple-card: probe of sound failed with error -22 3) The mapping is incorrect: asoc-simple-card sound: cs42l51-hifi <-> spdif mapping ok should be: asoc-simple-card sound: cs42l51-hifi <-> i2s mapping ok Reported-by: Rick Thomas Signed-off-by: Aaro Koskinen Reviewed-by: Andrew Lunn Tested-by: Rick Thomas Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/kirkwood-openrd-client.dts | 6 +++++- arch/arm/boot/dts/kirkwood.dtsi | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-openrd-client.dts b/arch/arm/boot/dts/kirkwood-openrd-client.dts index 887b9c1fee43..96ff59d68f44 100644 --- a/arch/arm/boot/dts/kirkwood-openrd-client.dts +++ b/arch/arm/boot/dts/kirkwood-openrd-client.dts @@ -20,6 +20,9 @@ compatible = "marvell,openrd-client", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood"; ocp@f1000000 { + audio-controller@a0000 { + status = "okay"; + }; i2c@11000 { status = "okay"; clock-frequency = <400000>; @@ -27,6 +30,7 @@ cs42l51: cs42l51@4a { compatible = "cirrus,cs42l51"; reg = <0x4a>; + #sound-dai-cells = <0>; }; }; }; @@ -37,7 +41,7 @@ simple-audio-card,mclk-fs = <256>; simple-audio-card,cpu { - sound-dai = <&audio0>; + sound-dai = <&audio0 0>; }; simple-audio-card,codec { diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 7b5a4a18f49c..7445a15e259d 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -381,7 +381,7 @@ audio0: audio-controller@a0000 { compatible = "marvell,kirkwood-audio"; - #sound-dai-cells = <0>; + #sound-dai-cells = <1>; reg = <0xa0000 0x2210>; interrupts = <24>; clocks = <&gate_clk 9>; -- GitLab From 5dda254d0cc5cbdcc81dbce0985c35b68dd5e3b1 Mon Sep 17 00:00:00 2001 From: Mario Lange Date: Tue, 26 Jan 2016 01:44:10 +0900 Subject: [PATCH 0869/5324] ARM: dts: kirkwood: add device tree for buffalo linkstation ls-qvl Add dts file to support Buffalo Linkstation LS-QVL, which is marvell kirkwood based 4-bay 3.5" HDD NAS. Product info: - (JPN) http://buffalo.jp/product/hdd/network/ls-qvl_r5/ - (ENG) http://www.buffalotech.com/products/network-storage/home-and-small-office/linkstation-pro-quad Signed-off-by: Mario Lange Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- .../bindings/arm/marvell,kirkwood.txt | 1 + arch/arm/boot/dts/Makefile | 1 + .../boot/dts/kirkwood-linkstation-lsqvl.dts | 135 ++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt index 0fc6faa4cddb..7d28fe4bf654 100644 --- a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt +++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt @@ -19,6 +19,7 @@ SoC. Currently known SoC compatibles are: And in addition, the compatible shall be extended with the specific board. Currently known boards are: +"buffalo,linkstation-lsqvl" "buffalo,linkstation-lsvl" "buffalo,linkstation-lswsxl" "buffalo,linkstation-lswxl" diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 91833f905aef..30d316dc050f 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -189,6 +189,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-laplug.dtb \ + kirkwood-linkstation-lsqvl.dtb \ kirkwood-linkstation-lsvl.dtb \ kirkwood-linkstation-lswsxl.dtb \ kirkwood-linkstation-lswvl.dtb \ diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts new file mode 100644 index 000000000000..6dc0df2969f0 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts @@ -0,0 +1,135 @@ +/* + * Device Tree file for Buffalo Linkstation LS-QVL + * + * Copyright (C) 2016, Mario Lange + * + * Based on kirkwood-linkstation-lswvl.dts, + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-QVL"; + compatible = "buffalo,lsqvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + pmx_led_hdderr2: pmx-led-hdderr2 { + marvell,pins = "mpp24"; + marvell,function = "gpio"; + }; + pmx_led_hdderr3: pmx-led-hdderr3 { + marvell,pins = "mpp25"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1 + &pmx_led_hdderr2 + &pmx_led_hdderr3>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + }; + + red-hdderr2-led { + label = "linkstation:red:hdderr2"; + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + }; + + red-hdderr3-led { + label = "linkstation:red:hdderr3"; + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; -- GitLab From fde93a0f774f510bfaabccd5ba00f97972be1e12 Mon Sep 17 00:00:00 2001 From: Andrew Donnellan Date: Tue, 9 Feb 2016 18:17:49 +1100 Subject: [PATCH 0870/5324] powerpc/xmon: add command to dump OPAL msglog Add the 'do' command to dump the OPAL msglog in xmon. Signed-off-by: Andrew Donnellan [mpe: Reduce the amount of ifdefery required] Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d5c8a156f63c..47e195d66a9a 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -47,6 +47,9 @@ #include #include +#include +#include + #ifdef CONFIG_PPC64 #include #include @@ -119,6 +122,16 @@ static void dump(void); static void prdump(unsigned long, long); static int ppc_inst_dump(unsigned long, long, int); static void dump_log_buf(void); + +#ifdef CONFIG_PPC_POWERNV +static void dump_opal_msglog(void); +#else +static inline void dump_opal_msglog(void) +{ + printf("Machine is not running OPAL firmware.\n"); +} +#endif + static void backtrace(struct pt_regs *); static void excprint(struct pt_regs *); static void prregs(struct pt_regs *); @@ -202,6 +215,10 @@ Commands:\n\ df dump float values\n\ dd dump double values\n\ dl dump the kernel log buffer\n" +#ifdef CONFIG_PPC_POWERNV + "\ + do dump the OPAL message log\n" +#endif #ifdef CONFIG_PPC64 "\ dp[#] dump paca for current cpu, or cpu #\n\ @@ -2253,6 +2270,8 @@ dump(void) last_cmd = "di\n"; } else if (c == 'l') { dump_log_buf(); + } else if (c == 'o') { + dump_opal_msglog(); } else if (c == 'r') { scanhex(&ndump); if (ndump == 0) @@ -2395,6 +2414,45 @@ dump_log_buf(void) catch_memory_errors = 0; } +#ifdef CONFIG_PPC_POWERNV +static void dump_opal_msglog(void) +{ + unsigned char buf[128]; + ssize_t res; + loff_t pos = 0; + + if (!firmware_has_feature(FW_FEATURE_OPAL)) { + printf("Machine is not running OPAL firmware.\n"); + return; + } + + if (setjmp(bus_error_jmp) != 0) { + printf("Error dumping OPAL msglog!\n"); + return; + } + + catch_memory_errors = 1; + sync(); + + xmon_start_pagination(); + while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) { + if (res < 0) { + printf("Error dumping OPAL msglog! Error: %zd\n", res); + break; + } + buf[res] = '\0'; + printf("%s", buf); + pos += res; + } + xmon_end_pagination(); + + sync(); + /* wait a little while to see if we get a machine check */ + __delay(200); + catch_memory_errors = 0; +} +#endif + /* * Memory operations - move, set, print differences */ -- GitLab From cb4f71c4298853db0c6751b1209e4535956f136c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 27 Jan 2016 16:08:19 +0100 Subject: [PATCH 0871/5324] ARM: dts: armada-38x: change order of ethernet DT nodes on Armada 38x On Armada 38x, the available network interfaces are: - port 0, at 0x70000 - port 1, at 0x30000 - port 2, at 0x34000 Due to the rule saying that DT nodes should be ordered by register addresses, the network interfaces are probed in this order: - port 1, at 0x30000, which gets named eth0 - port 2, at 0x34000, which gets named eth1 - port 0, at 0x70000, which gets named eth2 (if all three ports are enabled at the board level) Unfortunately, the network subsystem doesn't provide any way to rename network interfaces from the kernel (it can only be done from userspace). So, the default naming of the network interfaces is very confusing as it doesn't match the datasheet, nor the naming of the interfaces in the bootloader, nor the naming of the interfaces on labels printed on the board. For example, on the Armada 388 GP, the board has two ports, labelled GE0 and GE1. One has to know that GE0 is eth1 and GE1 is eth0, which isn't really obvious. In order to solve this, this patch proposes to exceptionaly violate the rule of "order DT nodes by register address", and put the 0x70000 node before the 0x30000 node, so that network interfaces get named in a more natural way. Signed-off-by: Thomas Petazzoni Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-38x.dtsi | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index e8b7f6726772..b50784de86e8 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -429,6 +429,27 @@ reg = <0x22000 0x1000>; }; + /* + * As a special exception to the "order by + * register address" rule, the eth0 node is + * placed here to ensure that it gets + * registered as the first interface, since + * the network subsystem doesn't allow naming + * interfaces using DT aliases. Without this, + * the ordering of interfaces is different + * from the one used in U-Boot and the + * labeling of interfaces on the boards, which + * is very confusing for users. + */ + eth0: ethernet@70000 { + compatible = "marvell,armada-370-neta"; + reg = <0x70000 0x4000>; + interrupts-extended = <&mpic 8>; + clocks = <&gateclk 4>; + tx-csum-limit = <9800>; + status = "disabled"; + }; + eth1: ethernet@30000 { compatible = "marvell,armada-370-neta"; reg = <0x30000 0x4000>; @@ -493,15 +514,6 @@ }; }; - eth0: ethernet@70000 { - compatible = "marvell,armada-370-neta"; - reg = <0x70000 0x4000>; - interrupts-extended = <&mpic 8>; - clocks = <&gateclk 4>; - tx-csum-limit = <9800>; - status = "disabled"; - }; - mdio: mdio@72004 { #address-cells = <1>; #size-cells = <0>; -- GitLab From 34d482904c9689dfc8d8cbe5cb1b89582e5bcf37 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 27 Jan 2016 16:08:20 +0100 Subject: [PATCH 0872/5324] ARM: dts: armada-38x: add reference to ETH connectors for A385-AP This commit adds some comments to the Armada 385 AP Device Tree description to indicate which Ethernet interface matches which physical connector on the board. Signed-off-by: Thomas Petazzoni Cc: Maxime Ripard Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-385-db-ap.dts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index acd5b1519edb..86fde0bf552b 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -134,18 +134,21 @@ }; }; + /* CON3 */ ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "sgmii"; }; + /* CON2 */ ethernet@34000 { status = "okay"; phy = <&phy1>; phy-mode = "sgmii"; }; + /* CON4 */ ethernet@70000 { pinctrl-names = "default"; -- GitLab From 346400c801079114e89451b3191eaa4407507841 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Tue, 22 Dec 2015 19:36:47 -0200 Subject: [PATCH 0873/5324] drm/i915: Implement end_cpu_access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is meant to be used with dma-buf mmap, when finishing the CPU access of the mapped pointer. The error case should be rare to happen though, requiring the buffer become active during the sync period and for the end_cpu_access to be interrupted. So we use a uninterruptible mutex_lock to spit out when it ever happens. v2: disable interruption to make sure errors are reported. v3: update to the new end_cpu_access API. v7: use .write = false cause it doesn't need to know whether it's write. Reviewed-by: Chris Wilson Signed-off-by: Tiago Vignatti Reviewed-by: Stéphane Marchesin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1450820214-12509-5-git-send-email-tiago.vignatti@intel.com --- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 65ab2bd54af5..8c9ed2a0a6bf 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -212,6 +212,27 @@ static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_dire return ret; } +static void i915_gem_end_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) +{ + struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + bool was_interruptible; + int ret; + + mutex_lock(&dev->struct_mutex); + was_interruptible = dev_priv->mm.interruptible; + dev_priv->mm.interruptible = false; + + ret = i915_gem_object_set_to_gtt_domain(obj, false); + + dev_priv->mm.interruptible = was_interruptible; + mutex_unlock(&dev->struct_mutex); + + if (unlikely(ret)) + DRM_ERROR("unable to flush buffer following CPU access; rendering may be corrupt\n"); +} + static const struct dma_buf_ops i915_dmabuf_ops = { .map_dma_buf = i915_gem_map_dma_buf, .unmap_dma_buf = i915_gem_unmap_dma_buf, @@ -224,6 +245,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = { .vmap = i915_gem_dmabuf_vmap, .vunmap = i915_gem_dmabuf_vunmap, .begin_cpu_access = i915_gem_begin_cpu_access, + .end_cpu_access = i915_gem_end_cpu_access, }; struct dma_buf *i915_gem_prime_export(struct drm_device *dev, -- GitLab From 2dbf0d90971a5c490f17976596a263913d8074c3 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Tue, 22 Dec 2015 19:36:48 -0200 Subject: [PATCH 0874/5324] drm/i915: Use CPU mapping for userspace dma-buf mmap() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userspace is the one in charge of flush CPU by wrapping mmap with begin{,end}_cpu_access. v2: Remove LLC check cause we have dma-buf sync providers now. Also, fix return before transferring ownership when mmap fails. v3: Fix return values. v4: !obj->base.filp is user triggerable, so removed the WARN_ON. Reviewed-by: Chris Wilson Signed-off-by: Tiago Vignatti Reviewed-by: Stéphane Marchesin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1450820214-12509-6-git-send-email-tiago.vignatti@intel.com --- drivers/gpu/drm/i915/i915_gem_dmabuf.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c index 8c9ed2a0a6bf..1f3eef6fb345 100644 --- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c @@ -193,7 +193,23 @@ static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_n static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) { - return -EINVAL; + struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf); + int ret; + + if (obj->base.size < vma->vm_end - vma->vm_start) + return -EINVAL; + + if (!obj->base.filp) + return -ENODEV; + + ret = obj->base.filp->f_op->mmap(obj->base.filp, vma); + if (ret) + return ret; + + fput(vma->vm_file); + vma->vm_file = get_file(obj->base.filp); + + return 0; } static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, enum dma_data_direction direction) -- GitLab From 47d7777f99da283ff0d6248dd9e83593cf06760c Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 10:59:18 +0100 Subject: [PATCH 0875/5324] drm/core: Add drm_encoder_index. This is useful for adding encoder_mask in crtc_state. Signed-off-by: Maarten Lankhorst Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452160762-30487-2-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/drm_crtc.c | 23 +++++++++++++++++++++++ include/drm/drm_crtc.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6e6514ef9968..4132d58dab93 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1160,6 +1160,29 @@ int drm_encoder_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_encoder_init); +/** + * drm_encoder_index - find the index of a registered encoder + * @encoder: encoder to find index for + * + * Given a registered encoder, return the index of that encoder within a DRM + * device's list of encoders. + */ +unsigned int drm_encoder_index(struct drm_encoder *encoder) +{ + unsigned int index = 0; + struct drm_encoder *tmp; + + drm_for_each_encoder(tmp, encoder->dev) { + if (tmp == encoder) + return index; + + index++; + } + + BUG(); +} +EXPORT_SYMBOL(drm_encoder_index); + /** * drm_encoder_cleanup - cleans up an initialised encoder * @encoder: encoder to cleanup diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c65a212db77e..fd2ace4a18de 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2225,6 +2225,7 @@ int drm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, const struct drm_encoder_funcs *funcs, int encoder_type, const char *name, ...); +extern unsigned int drm_encoder_index(struct drm_encoder *encoder); /** * drm_encoder_crtc_ok - can a given crtc drive a given encoder? -- GitLab From ead8b665705a0926442fbd3f4dbccbec36e5b8f4 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 10:59:19 +0100 Subject: [PATCH 0876/5324] drm/core: Add drm_for_each_encoder_mask, v2. This is similar to the other drm_for_each_*_mask functions. Changes since v1: - Use for_each_if Signed-off-by: Maarten Lankhorst Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452160762-30487-3-git-send-email-maarten.lankhorst@linux.intel.com --- include/drm/drm_crtc.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index fd2ace4a18de..c0226f945d62 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2153,6 +2153,17 @@ struct drm_mode_config { list_for_each_entry((plane), &(dev)->mode_config.plane_list, head) \ for_each_if ((plane_mask) & (1 << drm_plane_index(plane))) +/** + * drm_for_each_encoder_mask - iterate over encoders specified by bitmask + * @encoder: the loop cursor + * @dev: the DRM device + * @encoder_mask: bitmask of encoder indices + * + * Iterate over all encoders specified by bitmask. + */ +#define drm_for_each_encoder_mask(encoder, dev, encoder_mask) \ + list_for_each_entry((encoder), &(dev)->mode_config.encoder_list, head) \ + for_each_if ((encoder_mask) & (1 << drm_encoder_index(encoder))) #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) #define obj_to_connector(x) container_of(x, struct drm_connector, base) -- GitLab From 7811b1240d816cd92cbd70c5a4254346493546f0 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 10:59:20 +0100 Subject: [PATCH 0877/5324] drm/i915: Do not touch best_encoder for load detect. This should only be touched by drm_atomic_helper. Signed-off-by: Maarten Lankhorst Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452160762-30487-4-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7a5ed95f2cd9..0ea5a4e08b49 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10521,7 +10521,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, } connector_state->crtc = crtc; - connector_state->best_encoder = &intel_encoder->base; crtc_state = intel_atomic_get_crtc_state(state, intel_crtc); if (IS_ERR(crtc_state)) { @@ -10617,7 +10616,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, if (IS_ERR(crtc_state)) goto fail; - connector_state->best_encoder = NULL; connector_state->crtc = NULL; crtc_state->base.enable = crtc_state->base.active = false; -- GitLab From 97a8df90875f72ba3b4c3320759fd93cea743261 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 7 Jan 2016 10:59:21 +0100 Subject: [PATCH 0878/5324] drm/atomic: Do not unset crtc when an encoder is stolen While we steal the encoder away from the connector the connector may be updated to use a different encoder. Without this change if 2 connectors swap encoders one of them will end up without a crtc. Signed-off-by: Maarten Lankhorst Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1452160762-30487-5-git-send-email-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/drm_atomic_helper.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 0ab7c24cd7d6..254f6d0fad7c 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -134,7 +134,6 @@ steal_encoder(struct drm_atomic_state *state, struct drm_crtc_state *crtc_state; struct drm_connector *connector; struct drm_connector_state *connector_state; - int ret; /* * We can only steal an encoder coming from a connector, which means we @@ -165,9 +164,6 @@ steal_encoder(struct drm_atomic_state *state, if (IS_ERR(connector_state)) return PTR_ERR(connector_state); - ret = drm_atomic_set_crtc_for_connector(connector_state, NULL); - if (ret) - return ret; connector_state->best_encoder = NULL; } -- GitLab From e87a52b38943608531ff63ea397b1ae5dd48e341 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 28 Jan 2016 15:04:58 +0100 Subject: [PATCH 0879/5324] drm/atomic: Add encoder_mask to crtc_state, v3. This allows iteration over encoders without requiring connection_mutex. Changes since v1: - Add a set_best_encoder helper function and update encoder_mask inside it. Changes since v2: - Relax the WARN_ON(!crtc), with explanation. - Call set_best_encoder when connector is moved between crtc's. - Add some paranoia to steal_encoder to prevent accidentally setting best_encoder to NULL. Signed-off-by: Maarten Lankhorst Reviewed-by: Gustavo Padovan Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/56AA200A.6070501@linux.intel.com --- drivers/gpu/drm/drm_atomic_helper.c | 53 ++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_display.c | 3 ++ include/drm/drm_crtc.h | 2 ++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 254f6d0fad7c..2b430b05f35d 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -125,6 +125,47 @@ get_current_crtc_for_encoder(struct drm_device *dev, return NULL; } +static void +set_best_encoder(struct drm_atomic_state *state, + struct drm_connector_state *conn_state, + struct drm_encoder *encoder) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + + if (conn_state->best_encoder) { + /* Unset the encoder_mask in the old crtc state. */ + crtc = conn_state->connector->state->crtc; + + /* A NULL crtc is an error here because we should have + * duplicated a NULL best_encoder when crtc was NULL. + * As an exception restoring duplicated atomic state + * during resume is allowed, so don't warn when + * best_encoder is equal to encoder we intend to set. + */ + WARN_ON(!crtc && encoder != conn_state->best_encoder); + if (crtc) { + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); + + crtc_state->encoder_mask &= + ~(1 << drm_encoder_index(conn_state->best_encoder)); + } + } + + if (encoder) { + crtc = conn_state->crtc; + WARN_ON(!crtc); + if (crtc) { + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); + + crtc_state->encoder_mask |= + 1 << drm_encoder_index(encoder); + } + } + + conn_state->best_encoder = encoder; +} + static int steal_encoder(struct drm_atomic_state *state, struct drm_encoder *encoder, @@ -164,7 +205,10 @@ steal_encoder(struct drm_atomic_state *state, if (IS_ERR(connector_state)) return PTR_ERR(connector_state); - connector_state->best_encoder = NULL; + if (connector_state->best_encoder != encoder) + continue; + + set_best_encoder(state, connector_state, NULL); } return 0; @@ -212,7 +256,7 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) connector->base.id, connector->name); - connector_state->best_encoder = NULL; + set_best_encoder(state, connector_state, NULL); return 0; } @@ -241,6 +285,8 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) } if (new_encoder == connector_state->best_encoder) { + set_best_encoder(state, connector_state, new_encoder); + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", connector->base.id, connector->name, @@ -275,7 +321,8 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) if (WARN_ON(!connector_state->crtc)) return -EINVAL; - connector_state->best_encoder = new_encoder; + set_best_encoder(state, connector_state, new_encoder); + idx = drm_crtc_index(connector_state->crtc); crtc_state = state->crtc_states[idx]; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0ea5a4e08b49..e1e7cdee3bbd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15591,6 +15591,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) crtc->base.state->active = crtc->active; crtc->base.enabled = crtc->active; crtc->base.state->connector_mask = 0; + crtc->base.state->encoder_mask = 0; /* Because we only establish the connector -> encoder -> * crtc links if something is active, this means the @@ -15830,6 +15831,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) */ encoder->base.crtc->state->connector_mask |= 1 << drm_connector_index(&connector->base); + encoder->base.crtc->state->encoder_mask |= + 1 << drm_encoder_index(&encoder->base); } } else { diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c0226f945d62..51287f36b214 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -307,6 +307,7 @@ struct drm_plane_helper_funcs; * @connectors_changed: connectors to this crtc have been updated * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes * @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors + * @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders * @last_vblank_count: for helpers and drivers to capture the vblank of the * update to ensure framebuffer cleanup isn't done too early * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings @@ -341,6 +342,7 @@ struct drm_crtc_state { u32 plane_mask; u32 connector_mask; + u32 encoder_mask; /* last_vblank_count: for vblank waits before cleanup */ u32 last_vblank_count; -- GitLab From 156d7d4120e1c860fde667fc30eeae84bc3e7a25 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0880/5324] vga_switcheroo: Add handler flags infrastructure Allow handlers to declare their capabilities and allow clients to obtain that information. So far we have these use cases: * If the handler is able to switch DDC separately, clients need to probe EDID with drm_get_edid_switcheroo(). We should allow them to detect a capable handler to ensure this function only gets called when needed. * Likewise if the handler is unable to switch AUX separately, the active client needs to communicate link training parameters to the inactive client, which may then skip the AUX handshake and set up its output with these pre-calibrated values (DisplayPort specification v1.1a, section 2.5.3.3). Clients need a way to recognize such a situation. The flags for the radeon_atpx_handler and amdgpu_atpx_handler are initially set to 0, this can later on be amended with handler_flags |= VGA_SWITCHEROO_CAN_SWITCH_DDC; when a ->switch_ddc callback is added. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Reviewed-by: Darren Hart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/2b0d93ed6e511ca09e95e45e0b35627f330fabce.1452525860.git.lukas@wunner.de --- Documentation/DocBook/gpu.tmpl | 1 + .../gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 3 +- drivers/gpu/drm/nouveau/nouveau_acpi.c | 2 +- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 3 +- drivers/gpu/vga/vga_switcheroo.c | 22 ++++++++++++++- drivers/platform/x86/apple-gmux.c | 2 +- include/linux/vga_switcheroo.h | 28 +++++++++++++++++-- 7 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 49c97913c5ae..d6579d8c1341 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -3422,6 +3422,7 @@ int num_ioctls; Public constants +!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler_flags_t !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id !Finclude/linux/vga_switcheroo.h vga_switcheroo_state diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 3c895863fcf5..fa948dcbdd5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -552,13 +552,14 @@ static bool amdgpu_atpx_detect(void) void amdgpu_register_atpx_handler(void) { bool r; + enum vga_switcheroo_handler_flags_t handler_flags = 0; /* detect if we have any ATPX + 2 VGA in the system */ r = amdgpu_atpx_detect(); if (!r) return; - vga_switcheroo_register_handler(&amdgpu_atpx_handler); + vga_switcheroo_register_handler(&amdgpu_atpx_handler, handler_flags); } /** diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index d5e6938cc6bc..cdf522770cfa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -314,7 +314,7 @@ void nouveau_register_dsm_handler(void) if (!r) return; - vga_switcheroo_register_handler(&nouveau_dsm_handler); + vga_switcheroo_register_handler(&nouveau_dsm_handler, 0); } /* Must be called for Optimus models before the card can be turned off */ diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index c4b4f298a283..56482e35d43e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -551,13 +551,14 @@ static bool radeon_atpx_detect(void) void radeon_register_atpx_handler(void) { bool r; + enum vga_switcheroo_handler_flags_t handler_flags = 0; /* detect if we have any ATPX + 2 VGA in the system */ r = radeon_atpx_detect(); if (!r) return; - vga_switcheroo_register_handler(&radeon_atpx_handler); + vga_switcheroo_register_handler(&radeon_atpx_handler, handler_flags); } /** diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 665ab9fd0e01..e89f6ad5d83e 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -126,6 +126,7 @@ static DEFINE_MUTEX(vgasr_mutex); * (counting only vga clients, not audio clients) * @clients: list of registered clients * @handler: registered handler + * @handler_flags: flags of registered handler * * vga_switcheroo private data. Currently only one vga_switcheroo instance * per system is supported. @@ -142,6 +143,7 @@ struct vgasr_priv { struct list_head clients; const struct vga_switcheroo_handler *handler; + enum vga_switcheroo_handler_flags_t handler_flags; }; #define ID_BIT_AUDIO 0x100 @@ -190,13 +192,15 @@ static void vga_switcheroo_enable(void) /** * vga_switcheroo_register_handler() - register handler * @handler: handler callbacks + * @handler_flags: handler flags * * Register handler. Enable vga_switcheroo if two vga clients have already * registered. * * Return: 0 on success, -EINVAL if a handler was already registered. */ -int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler) +int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, + enum vga_switcheroo_handler_flags_t handler_flags) { mutex_lock(&vgasr_mutex); if (vgasr_priv.handler) { @@ -205,6 +209,7 @@ int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler } vgasr_priv.handler = handler; + vgasr_priv.handler_flags = handler_flags; if (vga_switcheroo_ready()) { pr_info("enabled\n"); vga_switcheroo_enable(); @@ -222,6 +227,7 @@ EXPORT_SYMBOL(vga_switcheroo_register_handler); void vga_switcheroo_unregister_handler(void) { mutex_lock(&vgasr_mutex); + vgasr_priv.handler_flags = 0; vgasr_priv.handler = NULL; if (vgasr_priv.active) { pr_info("disabled\n"); @@ -232,6 +238,20 @@ void vga_switcheroo_unregister_handler(void) } EXPORT_SYMBOL(vga_switcheroo_unregister_handler); +/** + * vga_switcheroo_handler_flags() - obtain handler flags + * + * Helper for clients to obtain the handler flags bitmask. + * + * Return: Handler flags. A value of 0 means that no handler is registered + * or that the handler has no special capabilities. + */ +enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) +{ + return vgasr_priv.handler_flags; +} +EXPORT_SYMBOL(vga_switcheroo_handler_flags); + static int register_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, enum vga_switcheroo_client_id id, bool active, diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index f236250ac106..c401d4936b65 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -705,7 +705,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) init_completion(&gmux_data->powerchange_done); gmux_enable_interrupts(gmux_data); - if (vga_switcheroo_register_handler(&gmux_handler)) { + if (vga_switcheroo_register_handler(&gmux_handler, 0)) { ret = -ENODEV; goto err_register_handler; } diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index 69e1d4a1f1b3..a745f4f0f729 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -35,6 +35,26 @@ struct pci_dev; +/** + * enum vga_switcheroo_handler_flags_t - handler flags bitmask + * @VGA_SWITCHEROO_CAN_SWITCH_DDC: whether the handler is able to switch the + * DDC lines separately. This signals to clients that they should call + * drm_get_edid_switcheroo() to probe the EDID + * @VGA_SWITCHEROO_NEEDS_EDP_CONFIG: whether the handler is unable to switch + * the AUX channel separately. This signals to clients that the active + * GPU needs to train the link and communicate the link parameters to the + * inactive GPU (mediated by vga_switcheroo). The inactive GPU may then + * skip the AUX handshake and set up its output with these pre-calibrated + * values (DisplayPort specification v1.1a, section 2.5.3.3) + * + * Handler flags bitmask. Used by handlers to declare their capabilities upon + * registering with vga_switcheroo. + */ +enum vga_switcheroo_handler_flags_t { + VGA_SWITCHEROO_CAN_SWITCH_DDC = (1 << 0), + VGA_SWITCHEROO_NEEDS_EDP_CONFIG = (1 << 1), +}; + /** * enum vga_switcheroo_state - client power state * @VGA_SWITCHEROO_OFF: off @@ -132,8 +152,10 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev, void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info); -int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler); +int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, + enum vga_switcheroo_handler_flags_t handler_flags); void vga_switcheroo_unregister_handler(void); +enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void); int vga_switcheroo_process_delayed_switch(void); @@ -150,11 +172,13 @@ static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} static inline int vga_switcheroo_register_client(struct pci_dev *dev, const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; } static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {} -static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler) { return 0; } +static inline int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler, + enum vga_switcheroo_handler_flags_t handler_flags) { return 0; } static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, enum vga_switcheroo_client_id id) { return 0; } static inline void vga_switcheroo_unregister_handler(void) {} +static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) { return 0; } static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } -- GitLab From e4cb81d7e49c806fa557cf0ff4f3f40bd7a9cb7c Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0881/5324] vga_switcheroo: Add support for switching only the DDC Originally by Seth Forshee , 2012-10-04: During graphics driver initialization it's useful to be able to mux only the DDC to the inactive client in order to read the EDID. Add a switch_ddc callback to allow capable handlers to provide this functionality, and add vga_switcheroo_switch_ddc() to allow DRM to mux only the DDC. Modified by Dave Airlie , 2012-12-22: I can't figure out why I didn't like this, but I rewrote this [...] to lock/unlock the ddc lines [...]. I think I'd prefer something like that otherwise the interface got really ugly. Modified by Lukas Wunner , 2015-04 - 2015-10: Change semantics of ->switch_ddc handler callback to return previous DDC owner. Original version tried to determine previous DDC owner with find_active_client() but this fails if the inactive client registers before the active client. Don't lock vgasr_mutex in _lock_ddc() / _unlock_ddc(), it can cause deadlocks because (a) during switch (with vgasr_mutex already held), GPU is woken and probes its outputs, tries to re-acquire vgasr_mutex to lock DDC lines; (b) Likewise during switch, GPU is suspended and calls cancel_delayed_work_sync() to stop output polling, if poll task is running at this moment we may wait forever for it to finish. Instead, lock mux_hw_lock when unregistering the handler because the only reason why we'd want to lock vgasr_mutex in _lock_ddc() / _unlock_ddc() is to block the handler from disappearing while DDC lines are switched. Also acquire mux_hw_lock in stage2 to avoid race condition where reading the EDID and switching happens simultaneously. Likewise on MIGD / MDIS commands and on runtime suspend. v2.1: Overhaul locking, squash commits (Daniel Vetter) v2.2: Readability improvements (Thierry Reding) v2.3: Overhaul locking once more v2.4: Retain semantics of ->switchto handler callback to switch all pins, including DDC (Daniel Vetter) v5: Rename ddc_lock to mux_hw_lock: Since we acquire this both when calling ->switch_ddc and ->switchto, it protects not just access to the DDC lines but to the mux in general. This is in line with the DRM convention to use low-level locks to avoid concurrent hw access (e.g. i2c, dp_aux) which are often called hw_lock (Daniel Vetter) Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Cc: Seth Forshee Cc: Dave Airlie Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/e81ae9722b84c5ed591805fee3ea6dbf5dc6c4b3.1452525860.git.lukas@wunner.de --- drivers/gpu/vga/vga_switcheroo.c | 97 +++++++++++++++++++++++++++++++- include/linux/vga_switcheroo.h | 8 +++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index e89f6ad5d83e..cbd7c986d926 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -74,9 +74,17 @@ * there can thus be up to three clients: Two vga clients (GPUs) and one audio * client (on the discrete GPU). The code is mostly prepared to support * machines with more than two GPUs should they become available. + * * The GPU to which the outputs are currently switched is called the * active client in vga_switcheroo parlance. The GPU not in use is the - * inactive client. + * inactive client. When the inactive client's DRM driver is loaded, + * it will be unable to probe the panel's EDID and hence depends on + * VBIOS to provide its display modes. If the VBIOS modes are bogus or + * if there is no VBIOS at all (which is common on the MacBook Pro), + * a client may alternatively request that the DDC lines are temporarily + * switched to it, provided that the handler supports this. Switching + * only the DDC lines and not the entire output avoids unnecessary + * flickering. */ /** @@ -127,6 +135,9 @@ static DEFINE_MUTEX(vgasr_mutex); * @clients: list of registered clients * @handler: registered handler * @handler_flags: flags of registered handler + * @mux_hw_lock: protects mux state + * (in particular while DDC lines are temporarily switched) + * @old_ddc_owner: client to which DDC lines will be switched back on unlock * * vga_switcheroo private data. Currently only one vga_switcheroo instance * per system is supported. @@ -144,6 +155,8 @@ struct vgasr_priv { const struct vga_switcheroo_handler *handler; enum vga_switcheroo_handler_flags_t handler_flags; + struct mutex mux_hw_lock; + int old_ddc_owner; }; #define ID_BIT_AUDIO 0x100 @@ -158,6 +171,7 @@ static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv); /* only one switcheroo per system */ static struct vgasr_priv vgasr_priv = { .clients = LIST_HEAD_INIT(vgasr_priv.clients), + .mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock), }; static bool vga_switcheroo_ready(void) @@ -227,6 +241,7 @@ EXPORT_SYMBOL(vga_switcheroo_register_handler); void vga_switcheroo_unregister_handler(void) { mutex_lock(&vgasr_mutex); + mutex_lock(&vgasr_priv.mux_hw_lock); vgasr_priv.handler_flags = 0; vgasr_priv.handler = NULL; if (vgasr_priv.active) { @@ -234,6 +249,7 @@ void vga_switcheroo_unregister_handler(void) vga_switcheroo_debugfs_fini(&vgasr_priv); vgasr_priv.active = false; } + mutex_unlock(&vgasr_priv.mux_hw_lock); mutex_unlock(&vgasr_mutex); } EXPORT_SYMBOL(vga_switcheroo_unregister_handler); @@ -432,6 +448,76 @@ void vga_switcheroo_client_fb_set(struct pci_dev *pdev, } EXPORT_SYMBOL(vga_switcheroo_client_fb_set); +/** + * vga_switcheroo_lock_ddc() - temporarily switch DDC lines to a given client + * @pdev: client pci device + * + * Temporarily switch DDC lines to the client identified by @pdev + * (but leave the outputs otherwise switched to where they are). + * This allows the inactive client to probe EDID. The DDC lines must + * afterwards be switched back by calling vga_switcheroo_unlock_ddc(), + * even if this function returns an error. + * + * Return: Previous DDC owner on success or a negative int on error. + * Specifically, %-ENODEV if no handler has registered or if the handler + * does not support switching the DDC lines. Also, a negative value + * returned by the handler is propagated back to the caller. + * The return value has merely an informational purpose for any caller + * which might be interested in it. It is acceptable to ignore the return + * value and simply rely on the result of the subsequent EDID probe, + * which will be %NULL if DDC switching failed. + */ +int vga_switcheroo_lock_ddc(struct pci_dev *pdev) +{ + enum vga_switcheroo_client_id id; + + mutex_lock(&vgasr_priv.mux_hw_lock); + if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) { + vgasr_priv.old_ddc_owner = -ENODEV; + return -ENODEV; + } + + id = vgasr_priv.handler->get_client_id(pdev); + vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id); + return vgasr_priv.old_ddc_owner; +} +EXPORT_SYMBOL(vga_switcheroo_lock_ddc); + +/** + * vga_switcheroo_unlock_ddc() - switch DDC lines back to previous owner + * @pdev: client pci device + * + * Switch DDC lines back to the previous owner after calling + * vga_switcheroo_lock_ddc(). This must be called even if + * vga_switcheroo_lock_ddc() returned an error. + * + * Return: Previous DDC owner on success (i.e. the client identifier of @pdev) + * or a negative int on error. + * Specifically, %-ENODEV if no handler has registered or if the handler + * does not support switching the DDC lines. Also, a negative value + * returned by the handler is propagated back to the caller. + * Finally, invoking this function without calling vga_switcheroo_lock_ddc() + * first is not allowed and will result in %-EINVAL. + */ +int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) +{ + enum vga_switcheroo_client_id id; + int ret = vgasr_priv.old_ddc_owner; + + if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock))) + return -EINVAL; + + if (vgasr_priv.old_ddc_owner >= 0) { + id = vgasr_priv.handler->get_client_id(pdev); + if (vgasr_priv.old_ddc_owner != id) + ret = vgasr_priv.handler->switch_ddc( + vgasr_priv.old_ddc_owner); + } + mutex_unlock(&vgasr_priv.mux_hw_lock); + return ret; +} +EXPORT_SYMBOL(vga_switcheroo_unlock_ddc); + /** * DOC: Manual switching and manual power control * @@ -569,7 +655,9 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) console_unlock(); } + mutex_lock(&vgasr_priv.mux_hw_lock); ret = vgasr_priv.handler->switchto(new_client->id); + mutex_unlock(&vgasr_priv.mux_hw_lock); if (ret) return ret; @@ -684,7 +772,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, vgasr_priv.delayed_switch_active = false; if (just_mux) { + mutex_lock(&vgasr_priv.mux_hw_lock); ret = vgasr_priv.handler->switchto(client_id); + mutex_unlock(&vgasr_priv.mux_hw_lock); goto out; } @@ -896,8 +986,11 @@ static int vga_switcheroo_runtime_suspend(struct device *dev) if (ret) return ret; mutex_lock(&vgasr_mutex); - if (vgasr_priv.handler->switchto) + if (vgasr_priv.handler->switchto) { + mutex_lock(&vgasr_priv.mux_hw_lock); vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD); + mutex_unlock(&vgasr_priv.mux_hw_lock); + } vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF); mutex_unlock(&vgasr_mutex); return 0; diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index a745f4f0f729..b39a5f3153bd 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -102,6 +102,9 @@ enum vga_switcheroo_client_id { * Mandatory. For muxless machines this should be a no-op. Returning 0 * denotes success, anything else failure (in which case the switch is * aborted) + * @switch_ddc: switch DDC lines to given client. + * Optional. Should return the previous DDC owner on success or a + * negative int on failure * @power_state: cut or reinstate power of given client. * Optional. The return value is ignored * @get_client_id: determine if given pci device is integrated or discrete GPU. @@ -113,6 +116,7 @@ enum vga_switcheroo_client_id { struct vga_switcheroo_handler { int (*init)(void); int (*switchto)(enum vga_switcheroo_client_id id); + int (*switch_ddc)(enum vga_switcheroo_client_id id); int (*power_state)(enum vga_switcheroo_client_id id, enum vga_switcheroo_state state); enum vga_switcheroo_client_id (*get_client_id)(struct pci_dev *pdev); @@ -156,6 +160,8 @@ int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler enum vga_switcheroo_handler_flags_t handler_flags); void vga_switcheroo_unregister_handler(void); enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void); +int vga_switcheroo_lock_ddc(struct pci_dev *pdev); +int vga_switcheroo_unlock_ddc(struct pci_dev *pdev); int vga_switcheroo_process_delayed_switch(void); @@ -179,6 +185,8 @@ static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, enum vga_switcheroo_client_id id) { return 0; } static inline void vga_switcheroo_unregister_handler(void) {} static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) { return 0; } +static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; } +static inline int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) { return -ENODEV; } static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } -- GitLab From 3e46304e74d2780dc7d909ec26c454b87feeda2a Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0882/5324] apple-gmux: Track switch state gmux has 3 switch registers: * GMUX_PORT_SWITCH_DISPLAY switches the panel * GMUX_PORT_SWITCH_DDC switches the panel's DDC lines (only on pre-retinas; on retinas this is a no-op) * GMUX_PORT_SWITCH_EXTERNAL switches the external DP port(s) (only on models without Thunderbolt, i.e. introduced before 2011; those with Thunderbolt switch only HPD/AUX, not the main link) Currently we switch all 3 registers in unison. gmux does not preserve the switch state during suspend, so we currently read GMUX_PORT_SWITCH_DISPLAY before suspend and restore all 3 registers to this value on resume. With the upcoming ->switch_ddc callback, GMUX_PORT_SWITCH_DDC may temporarily contain a different value than the other 2 registers. If we happen to suspend at this moment, we'll write an incorrect value to GMUX_PORT_SWITCH_DDC on resume. Also, on models with Thunderbolt the integrated GPU is unable to drive the external DP port(s), so we want to keep GMUX_PORT_SWITCH_EXTERNAL permanently switched to the discrete GPU on those machines. Consequently we can no longer assume that GMUX_PORT_SWITCH_DISPLAY represents the correct value for all 3 registers on suspend. Track the state of all 3 registers: Add gmux_read_switch_state() and gmux_write_switch_state(). Instead of reading the switch state on every suspend, read it once on driver initialization so that we know the current switch state all the time. (This allows us to use some optimizations and shortcuts, e.g. we can skip switching DDC if we know that it's already switched to the requested GPU.) Change the ->switchto callback to use gmux_write_switch_state(). Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Reviewed-by: Darren Hart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/5679f414cb0ddf1654dcc359571f3764b275edf0.1452525860.git.lukas@wunner.de --- drivers/platform/x86/apple-gmux.c | 67 +++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index c401d4936b65..5c6c708e56b8 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -57,7 +57,9 @@ struct apple_gmux_data { /* switcheroo data */ acpi_handle dhandle; int gpe; - enum vga_switcheroo_client_id resume_client_id; + enum vga_switcheroo_client_id switch_state_display; + enum vga_switcheroo_client_id switch_state_ddc; + enum vga_switcheroo_client_id switch_state_external; enum vga_switcheroo_state power_state; struct completion powerchange_done; }; @@ -368,17 +370,49 @@ static const struct backlight_ops gmux_bl_ops = { * for the selected GPU. */ +static void gmux_read_switch_state(struct apple_gmux_data *gmux_data) +{ + if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DDC) == 1) + gmux_data->switch_state_ddc = VGA_SWITCHEROO_IGD; + else + gmux_data->switch_state_ddc = VGA_SWITCHEROO_DIS; + + if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) + gmux_data->switch_state_display = VGA_SWITCHEROO_IGD; + else + gmux_data->switch_state_display = VGA_SWITCHEROO_DIS; + + if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL) == 2) + gmux_data->switch_state_external = VGA_SWITCHEROO_IGD; + else + gmux_data->switch_state_external = VGA_SWITCHEROO_DIS; +} + +static void gmux_write_switch_state(struct apple_gmux_data *gmux_data) +{ + if (gmux_data->switch_state_ddc == VGA_SWITCHEROO_IGD) + gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 1); + else + gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 2); + + if (gmux_data->switch_state_display == VGA_SWITCHEROO_IGD) + gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); + else + gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); + + if (gmux_data->switch_state_external == VGA_SWITCHEROO_IGD) + gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); + else + gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); +} + static int gmux_switchto(enum vga_switcheroo_client_id id) { - if (id == VGA_SWITCHEROO_IGD) { - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); - } else { - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); - gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); - } + apple_gmux_data->switch_state_ddc = id; + apple_gmux_data->switch_state_display = id; + apple_gmux_data->switch_state_external = id; + + gmux_write_switch_state(apple_gmux_data); return 0; } @@ -440,15 +474,6 @@ static int gmux_get_client_id(struct pci_dev *pdev) return VGA_SWITCHEROO_DIS; } -static enum vga_switcheroo_client_id -gmux_active_client(struct apple_gmux_data *gmux_data) -{ - if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) - return VGA_SWITCHEROO_IGD; - - return VGA_SWITCHEROO_DIS; -} - static const struct vga_switcheroo_handler gmux_handler = { .switchto = gmux_switchto, .power_state = gmux_set_power_state, @@ -513,7 +538,6 @@ static int gmux_suspend(struct device *dev) struct pnp_dev *pnp = to_pnp_dev(dev); struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); - gmux_data->resume_client_id = gmux_active_client(gmux_data); gmux_disable_interrupts(gmux_data); return 0; } @@ -524,7 +548,7 @@ static int gmux_resume(struct device *dev) struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); gmux_enable_interrupts(gmux_data); - gmux_switchto(gmux_data->resume_client_id); + gmux_write_switch_state(gmux_data); if (gmux_data->power_state == VGA_SWITCHEROO_OFF) gmux_set_discrete_state(gmux_data, gmux_data->power_state); return 0; @@ -704,6 +728,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) apple_gmux_data = gmux_data; init_completion(&gmux_data->powerchange_done); gmux_enable_interrupts(gmux_data); + gmux_read_switch_state(gmux_data); if (vga_switcheroo_register_handler(&gmux_handler, 0)) { ret = -ENODEV; -- GitLab From f798d9652874bfb3cdbcafa865964c0784ab2a0f Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0883/5324] apple-gmux: Add switch_ddc support Originally by Seth Forshee , 2012-10-04: The gmux allows muxing the DDC independently from the display, so support this functionality. This will allow reading the EDID for the inactive GPU, fixing issues with machines that either don't have a VBT or have invalid mode data in the VBT. Modified by Lukas Wunner , 2015-04 - 2015-12: Change semantics of ->switch_ddc handler callback to return previous DDC owner. Original version tried to determine previous DDC owner with find_active_client() in vga_switcheroo but this fails if the inactive client registers before the active client. v2.4: Retain semantics of ->switchto handler callback to switch all pins, including DDC (Daniel Vetter) v4: Advertise ->switch_ddc handler callback only on the pre-retina Macbook Pro. The retina uses eDP instead of LVDS and gmux no longer does the muxing itself but merely controls an external mux. That mux is incapable of switching the AUX channel separately from the main link. It's an NXP CBTL06142 (alternate parts: TI HD3SS212, Pericom PI3VDP12412, see datasheets below). v5: Rebase on "apple-gmux: Track switch state". Rebase on "vga_switcheroo: Add handler flags infrastructure". Rebase on 5d170139eb10 ("Constify vga_switcheroo_handler"), requires 2 structs, 1x with ->switchto for pre-retinas, 1x without for retinas). Add error message if handler registration with vga_switcheroo fails. Teardowns identifying the mux: http://www.electronicproducts.com/-whatsinside_text-145.aspx http://slideshare.net/jjwu6266/apple-2012-wwdc-apple-macbook-pro-with-retina-display http://www.techrepublic.com/blog/cracking-open/teardown-shows-retina-macbook-pro-is-nearly-impossible-to-upgrade-difficult-to-work-on/ Mux Datasheets: http://www.nxp.com/documents/data_sheet/CBTL06141.pdf http://www.ti.com/lit/ds/symlink/hd3ss212.pdf https://www.pericom.com/assets/Datasheets/PI3VDP12412.pdf Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Cc: Seth Forshee Signed-off-by: Lukas Wunner Reviewed-by: Darren Hart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/17fe8bfb0415d713bb4174f84ac9aae5d7d9a5f8.1452525860.git.lukas@wunner.de --- drivers/platform/x86/apple-gmux.c | 45 ++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 5c6c708e56b8..1384a393f2f7 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -417,6 +417,25 @@ static int gmux_switchto(enum vga_switcheroo_client_id id) return 0; } +static int gmux_switch_ddc(enum vga_switcheroo_client_id id) +{ + enum vga_switcheroo_client_id old_ddc_owner = + apple_gmux_data->switch_state_ddc; + + if (id == old_ddc_owner) + return id; + + pr_debug("Switching DDC from %d to %d\n", old_ddc_owner, id); + apple_gmux_data->switch_state_ddc = id; + + if (id == VGA_SWITCHEROO_IGD) + gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); + else + gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); + + return old_ddc_owner; +} + /** * DOC: Power control * @@ -474,12 +493,19 @@ static int gmux_get_client_id(struct pci_dev *pdev) return VGA_SWITCHEROO_DIS; } -static const struct vga_switcheroo_handler gmux_handler = { +static const struct vga_switcheroo_handler gmux_handler_indexed = { .switchto = gmux_switchto, .power_state = gmux_set_power_state, .get_client_id = gmux_get_client_id, }; +static const struct vga_switcheroo_handler gmux_handler_classic = { + .switchto = gmux_switchto, + .switch_ddc = gmux_switch_ddc, + .power_state = gmux_set_power_state, + .get_client_id = gmux_get_client_id, +}; + /** * DOC: Interrupt * @@ -730,8 +756,21 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) gmux_enable_interrupts(gmux_data); gmux_read_switch_state(gmux_data); - if (vga_switcheroo_register_handler(&gmux_handler, 0)) { - ret = -ENODEV; + /* + * Retina MacBook Pros cannot switch the panel's AUX separately + * and need eDP pre-calibration. They are distinguishable from + * pre-retinas by having an "indexed" gmux. + * + * Pre-retina MacBook Pros can switch the panel's DDC separately. + */ + if (gmux_data->indexed) + ret = vga_switcheroo_register_handler(&gmux_handler_indexed, + VGA_SWITCHEROO_NEEDS_EDP_CONFIG); + else + ret = vga_switcheroo_register_handler(&gmux_handler_classic, + VGA_SWITCHEROO_CAN_SWITCH_DDC); + if (ret) { + pr_err("Failed to register vga_switcheroo handler\n"); goto err_register_handler; } -- GitLab From 5cb8eaa227d1870a68fc99a90edc8be0dbacca41 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0884/5324] drm/edid: Switch DDC when reading the EDID Originally by Seth Forshee , 2012-10-04: Some dual graphics machines support muxing the DDC separately from the display, so make use of this functionality when reading the EDID on the inactive GPU. Also serialize drm_get_edid() with a mutex to avoid races on the DDC mux state. Modified by Dave Airlie , 2012-12-22: I can't figure out why I didn't like this, but I rewrote this [...] to lock/unlock the ddc lines [...]. I think I'd prefer something like that otherwise the interface got really ugly. Modified by Lukas Wunner , 2015-04 - 2015-09: v3: Move vga_switcheroo calls to a wrapper around drm_get_edid() which drivers can call on muxed machines. This avoids other drivers having to go through the vga_switcheroo motions even though they are never used on a muxed platform (Thierry Reding, Daniel Vetter, Alex Deucher) Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Pierre Moreau [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina 15"] Tested-by: William Brown [MBP 8,2 2011 intel SNB + amd turks pre-retina 15"] Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Cc: Seth Forshee Cc: Dave Airlie Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/b898d0da4c134f2642d0122479006863e1830723.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++ include/drm/drm_crtc.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 04cb4877fabd..fdb1eb014586 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1394,6 +1395,31 @@ struct edid *drm_get_edid(struct drm_connector *connector, } EXPORT_SYMBOL(drm_get_edid); +/** + * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output + * @connector: connector we're probing + * @adapter: I2C adapter to use for DDC + * + * Wrapper around drm_get_edid() for laptops with dual GPUs using one set of + * outputs. The wrapper adds the requisite vga_switcheroo calls to temporarily + * switch DDC to the GPU which is retrieving EDID. + * + * Return: Pointer to valid EDID or %NULL if we couldn't find any. + */ +struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, + struct i2c_adapter *adapter) +{ + struct pci_dev *pdev = connector->dev->pdev; + struct edid *edid; + + vga_switcheroo_lock_ddc(pdev); + edid = drm_get_edid(connector, adapter); + vga_switcheroo_unlock_ddc(pdev); + + return edid; +} +EXPORT_SYMBOL(drm_get_edid_switcheroo); + /** * drm_edid_duplicate - duplicate an EDID and the extensions * @edid: EDID to duplicate diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 51287f36b214..ad53d2ffd48c 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2296,6 +2296,8 @@ extern void drm_property_destroy_user_blobs(struct drm_device *dev, extern bool drm_probe_ddc(struct i2c_adapter *adapter); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); +extern struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, + struct i2c_adapter *adapter); extern struct edid *drm_edid_duplicate(const struct edid *edid); extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); extern void drm_mode_config_init(struct drm_device *dev); -- GitLab From 4eddaeecf92341bf94ce1bf9dd98bb2cee267b14 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0885/5324] drm/i915: Switch DDC when reading the EDID The pre-retina MacBook Pro uses an LVDS panel and a gmux controller to switch the panel between its two GPUs. The panel mode in VBIOS is notoriously bogus on these machines and some models have no VBIOS at all. Use drm_get_edid_switcheroo() in lieu of drm_get_edid() on LVDS if the vga_switcheroo handler is capable of temporarily switching the panel's DDC lines to the integrated GPU. This allows us to retrieve the EDID if the panel is currently muxed to the discrete GPU. This only enables EDID probing on the pre-retina MBP (2008 - 2013). The retina MBP (2012 - present) uses eDP and gmux is not capable of switching AUX separately from the main link on these models. This will be addressed in later patches. List of pre-retina MBPs with dual GPUs, one of them Intel: [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina 15"] [MBP 6,1 2010 intel ILK + nvidia GT216 pre-retina 17"] [MBP 8,2 2011 intel SNB + amd turks pre-retina 15"] [MBP 8,3 2011 intel SNB + amd turks pre-retina 17"] [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] v3: Commit newly added due to introduction of drm_get_edid_switcheroo() wrapper which drivers need to opt-in to. v5: Rebase on "vga_switcheroo: Add handler flags infrastructure", i.e. call drm_get_edid_switcheroo() only if the handler indicates that DDC is switchable. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/bb095e14a2259be7fdd10092f9d6874a9be8f27b.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/i915/intel_lvds.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0da0240caf81..811ddf7799f0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1080,7 +1081,12 @@ void intel_lvds_init(struct drm_device *dev) * preferred mode is the right one. */ mutex_lock(&dev->mode_config.mutex); - edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin)); + if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) + edid = drm_get_edid_switcheroo(connector, + intel_gmbus_get_adapter(dev_priv, pin)); + else + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, pin)); if (edid) { if (drm_add_edid_modes(connector, edid)) { drm_mode_connector_update_edid_property(connector, -- GitLab From 39c1c9011c44e4cf1db80e83abf24958f5902289 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0886/5324] drm/nouveau: Switch DDC when reading the EDID The pre-retina MacBook Pro uses an LVDS panel and a gmux controller to switch the panel between its two GPUs. The panel mode in VBIOS is notoriously bogus on these machines. Use drm_get_edid_switcheroo() in lieu of drm_get_edid() on LVDS if the vga_switcheroo handler is capable of temporarily switching the panel's DDC lines to the discrete GPU. This allows us to retrieve the EDID if the panel is currently muxed to the integrated GPU. Likewise, ask vga_switcheroo to switch DDC before probing LVDS connectors. This only enables EDID probing on the pre-retina MBP (2008 - 2013). The retina MBP (2012 - present) uses eDP and gmux is not capable of switching AUX separately from the main link on these models. This will be addressed in later patches. List of pre-retina MBPs with dual GPUs, either or both Nvidia: [MBP 5,1 2008 nvidia MCP79 + G96 pre-retina 15"] [MBP 5,2 2009 nvidia MCP79 + G96 pre-retina 17"] [MBP 5,3 2009 nvidia MCP79 + G96 pre-retina 15"] [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina 15"] [MBP 6,1 2010 intel ILK + nvidia GT216 pre-retina 17"] [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] v3: Commit newly added due to introduction of drm_get_edid_switcheroo() wrapper which drivers need to opt-in to. v5: Rebase on "vga_switcheroo: Add handler flags infrastructure", i.e. call drm_get_edid_switcheroo() only if the handler indicates that DDC is switchable. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/e9466eb3d66b5b30f1e93c3b3da79d8b9ad0830f.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/nouveau/nouveau_connector.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index fcebfae5d426..ae96ebc490fb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -153,6 +154,17 @@ nouveau_connector_ddc_detect(struct drm_connector *connector) if (ret == 0) break; } else + if ((vga_switcheroo_handler_flags() & + VGA_SWITCHEROO_CAN_SWITCH_DDC) && + nv_encoder->dcb->type == DCB_OUTPUT_LVDS && + nv_encoder->i2c) { + int ret; + vga_switcheroo_lock_ddc(dev->pdev); + ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50); + vga_switcheroo_unlock_ddc(dev->pdev); + if (ret) + break; + } else if (nv_encoder->i2c) { if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) break; @@ -265,7 +277,14 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) nv_encoder = nouveau_connector_ddc_detect(connector); if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { - nv_connector->edid = drm_get_edid(connector, i2c); + if ((vga_switcheroo_handler_flags() & + VGA_SWITCHEROO_CAN_SWITCH_DDC) && + nv_connector->type == DCB_CONNECTOR_LVDS) + nv_connector->edid = drm_get_edid_switcheroo(connector, + i2c); + else + nv_connector->edid = drm_get_edid(connector, i2c); + drm_mode_connector_update_edid_property(connector, nv_connector->edid); if (!nv_connector->edid) { -- GitLab From 47eb8f739e6910a157962d2e6e8ce5eb06374e83 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0887/5324] drm/radeon: Switch DDC when reading the EDID The pre-retina MacBook Pro uses an LVDS panel and a gmux controller to switch the panel between its two GPUs. The panel mode in VBIOS is notoriously bogus on these machines. Use drm_get_edid_switcheroo() in lieu of drm_get_edid() on LVDS if the vga_switcheroo handler is capable of temporarily switching the panel's DDC lines to the discrete GPU. This allows us to retrieve the EDID if the panel is currently muxed to the integrated GPU. This only enables EDID probing on the pre-retina MBP (2008 - 2013). The retina MBP (2012 - present) uses eDP and gmux is not capable of switching AUX separately from the main link on these models. This will be addressed in later patches. List of pre-retina MBPs with dual GPUs, one of them AMD: [MBP 8,2 2011 intel SNB + amd turks pre-retina 15"] [MBP 8,3 2011 intel SNB + amd turks pre-retina 17"] v3: Commit newly added due to introduction of drm_get_edid_switcheroo() wrapper which drivers need to opt-in to. v5: Rebase on "vga_switcheroo: Add handler flags infrastructure", i.e. call drm_get_edid_switcheroo() only if the handler indicates that DDC is switchable. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/dae71655e8c484fbef492d3389c157975f9622c9.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/radeon/radeon_connectors.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 340f3f549f29..cfcc099c537d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -34,6 +34,7 @@ #include "atom.h" #include +#include static int radeon_dp_handle_hpd(struct drm_connector *connector) { @@ -344,6 +345,11 @@ static void radeon_connector_get_edid(struct drm_connector *connector) else if (radeon_connector->ddc_bus) radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); + } else if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC && + connector->connector_type == DRM_MODE_CONNECTOR_LVDS && + radeon_connector->ddc_bus) { + radeon_connector->edid = drm_get_edid_switcheroo(&radeon_connector->base, + &radeon_connector->ddc_bus->adapter); } else if (radeon_connector->ddc_bus) { radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); -- GitLab From 2413306c2566b729a9d17a81e9d1181e6f354d6a Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0888/5324] apple-gmux: Add helper for presence detect Centralize gmux' ACPI HID in a header file and add apple_gmux_present(). This can be used by other drivers to activate quirks specific to dual GPU MacBook Pros & Mac Pros. The alternative would be to hardcode DMI or PCI IDs and amend them whenever Apple introduces a new machine. Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Reviewed-by: Darren Hart Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/89c23769058a340e5e11d4a7102f3793d3b0c94c.1452525860.git.lukas@wunner.de --- Documentation/DocBook/gpu.tmpl | 4 ++++ drivers/platform/x86/apple-gmux.c | 3 ++- include/linux/apple-gmux.h | 39 +++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 include/linux/apple-gmux.h diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index d6579d8c1341..fe6b36a2fd98 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -3451,6 +3451,10 @@ int num_ioctls; Backlight control !Pdrivers/platform/x86/apple-gmux.c Backlight control + + Public functions +!Iinclude/linux/apple-gmux.h + diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 1384a393f2f7..4034d2d4c507 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -828,7 +829,7 @@ static void gmux_remove(struct pnp_dev *pnp) } static const struct pnp_device_id gmux_device_ids[] = { - {"APP000B", 0}, + {GMUX_ACPI_HID, 0}, {"", 0} }; diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h new file mode 100644 index 000000000000..feebc2840462 --- /dev/null +++ b/include/linux/apple-gmux.h @@ -0,0 +1,39 @@ +/* + * apple-gmux.h - microcontroller built into dual GPU MacBook Pro & Mac Pro + * Copyright (C) 2015 Lukas Wunner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef LINUX_APPLE_GMUX_H +#define LINUX_APPLE_GMUX_H + +#include + +#define GMUX_ACPI_HID "APP000B" + +/** + * apple_gmux_present() - detect if gmux is built into the machine + * + * Drivers may use this to activate quirks specific to dual GPU MacBook Pros + * and Mac Pros, e.g. for deferred probing, runtime pm and backlight. + * + * Return: %true if gmux is present and the kernel was configured + * with CONFIG_APPLE_GMUX, %false otherwise. + */ +static inline bool apple_gmux_present(void) +{ + return IS_ENABLED(CONFIG_APPLE_GMUX) && acpi_dev_present(GMUX_ACPI_HID); +} + +#endif /* LINUX_APPLE_GMUX_H */ -- GitLab From 704ab614ec1201138032003c03113a81526638ab Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0889/5324] drm/i915: Defer probe if gmux is present but its driver isn't gmux is a microcontroller built into dual GPU MacBook Pros. On pre-retina MBPs, if we're the inactive GPU, we need apple-gmux to temporarily switch DDC so that we can probe the panel's EDID. The checks for CONFIG_VGA_ARB and CONFIG_VGA_SWITCHEROO are necessary because if either of them is disabled but gmux is present, the driver would never load, even if we're the active GPU. (vga_default_device() would evaluate to NULL and vga_switcheroo_handler_flags() would evaluate to 0.) Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/f56ee6a0600a3e1bb5bed4d0db4ed9ade7445c47.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/i915/i915_drv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 11d8414edbbe..44912ecebc1a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -35,9 +35,12 @@ #include "i915_trace.h" #include "intel_drv.h" +#include #include #include #include +#include +#include #include static struct drm_driver driver; @@ -969,6 +972,15 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (PCI_FUNC(pdev->devfn)) return -ENODEV; + /* + * apple-gmux is needed on dual GPU MacBook Pro + * to probe the panel if we're the inactive GPU. + */ + if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && + apple_gmux_present() && pdev != vga_default_device() && + !vga_switcheroo_handler_flags()) + return -EPROBE_DEFER; + return drm_get_pci_dev(pdev, ent, &driver); } -- GitLab From 98b3a3402eb6e38c3bf5dd4281e60e1f186f0041 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0890/5324] drm/nouveau: Defer probe if gmux is present but its driver isn't gmux is a microcontroller built into dual GPU MacBook Pros. On pre-retina MBPs, if we're the inactive GPU, we need apple-gmux to temporarily switch DDC so that we can probe the panel's EDID. The checks for CONFIG_VGA_ARB and CONFIG_VGA_SWITCHEROO are necessary because if either of them is disabled but gmux is present, the driver would never load, even if we're the active GPU. (vga_default_device() would evaluate to NULL and vga_switcheroo_handler_flags() would evaluate to 0.) Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"] Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/d9542ca5041178165d3ff286c90cc99634f7d2ce.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/nouveau/nouveau_drm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2f2f252e3fb6..bb8498c9b13e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -22,11 +22,13 @@ * Authors: Ben Skeggs */ +#include #include #include #include #include #include +#include #include #include "drmP.h" @@ -312,6 +314,15 @@ static int nouveau_drm_probe(struct pci_dev *pdev, bool boot = false; int ret; + /* + * apple-gmux is needed on dual GPU MacBook Pro + * to probe the panel if we're the inactive GPU. + */ + if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && + apple_gmux_present() && pdev != vga_default_device() && + !vga_switcheroo_handler_flags()) + return -EPROBE_DEFER; + /* remove conflicting drivers (vesafb, efifb etc) */ aper = alloc_apertures(3); if (!aper) -- GitLab From 14d2000182ed1cb6baf0fe8dc60a3664a832fc01 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Mon, 11 Jan 2016 20:09:20 +0100 Subject: [PATCH 0891/5324] drm/radeon: Defer probe if gmux is present but its driver isn't gmux is a microcontroller built into dual GPU MacBook Pros. On pre-retina MBPs, if we're the inactive GPU, we need apple-gmux to temporarily switch DDC so that we can probe the panel's EDID. The checks for CONFIG_VGA_ARB and CONFIG_VGA_SWITCHEROO are necessary because if either of them is disabled but gmux is present, the driver would never load, even if we're the active GPU. (vga_default_device() would evaluate to NULL and vga_switcheroo_handler_flags() would evaluate to 0.) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/552da6d85a82092146af7b0693595fa2a9ea376b.1452525860.git.lukas@wunner.de --- drivers/gpu/drm/radeon/radeon_drv.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index e266ffc520d2..cad25557650f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -34,9 +34,11 @@ #include "radeon_drv.h" #include +#include #include #include #include +#include #include #include @@ -319,6 +321,15 @@ static int radeon_pci_probe(struct pci_dev *pdev, { int ret; + /* + * apple-gmux is needed on dual GPU MacBook Pro + * to probe the panel if we're the inactive GPU. + */ + if (IS_ENABLED(CONFIG_VGA_ARB) && IS_ENABLED(CONFIG_VGA_SWITCHEROO) && + apple_gmux_present() && pdev != vga_default_device() && + !vga_switcheroo_handler_flags()) + return -EPROBE_DEFER; + /* Get rid of things like offb */ ret = radeon_kick_out_firmware_fb(pdev); if (ret) -- GitLab From 305e0b2a7a85e8bd65818cb3636b205f784ed377 Mon Sep 17 00:00:00 2001 From: Roger Shimizu Date: Sat, 6 Feb 2016 14:59:52 +0900 Subject: [PATCH 0892/5324] ARM: dts: orion5x: split linkstation lswtgl into common and device parts In order to support more linkstation devices, common part of current .dts file goes into .dtsi file. Some .dtsi start with "mvebu-" prefix because other kirkwood based linkstation devices are similar, and will be migrated to use these .dtsi some time later. - orion5x-linkstation.dtsi - mvebu-linkstation-fan.dtsi - mvebu-linkstation-gpio-simple.dtsi while all rest part remains in device specific .dts file: - orion5x-linkstation-lswtgl.dts Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/mvebu-linkstation-fan.dtsi | 72 ++++++ .../dts/mvebu-linkstation-gpio-simple.dtsi | 105 ++++++++ .../boot/dts/orion5x-linkstation-lswtgl.dts | 243 ++++-------------- arch/arm/boot/dts/orion5x-linkstation.dtsi | 180 +++++++++++++ 4 files changed, 402 insertions(+), 198 deletions(-) create mode 100644 arch/arm/boot/dts/mvebu-linkstation-fan.dtsi create mode 100644 arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi create mode 100644 arch/arm/boot/dts/orion5x-linkstation.dtsi diff --git a/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi new file mode 100644 index 000000000000..e211a3c47a76 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi @@ -0,0 +1,72 @@ +/* + * Device Tree common file for gpio-fan on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/ { + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpio-fan,speed-map = + <0 3 + 1500 2 + 3250 1 + 5000 0>; + }; +}; + +&pinctrl { + pmx_fan_low: pmx-fan-low { + marvell,function = "gpio"; + }; + + pmx_fan_high: pmx-fan-high { + marvell,function = "gpio"; + }; + + pmx_fan_lock: pmx-fan-lock { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi new file mode 100644 index 000000000000..68d75e79a360 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi @@ -0,0 +1,105 @@ +/* + * Device Tree common file for gpio-{keys,leds} on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +#include + +/ { + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_switch>; + pinctrl-names = "default"; + + power-on-switch { + label = "Power-on Switch"; + linux,code = ; + linux,input-type = <5>; + }; + + power-auto-switch { + label = "Power-auto Switch"; + linux,code = ; + linux,input-type = <5>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info>; + pinctrl-names = "default"; + + blue-power-led { + label = "linkstation:blue:power"; + default-state = "keep"; + }; + + red-alarm-led { + label = "linkstation:red:alarm"; + }; + + amber-info-led { + label = "linkstation:amber:info"; + }; + }; +}; + +&pinctrl { + pmx_power_switch: pmx-power-switch { + marvell,function = "gpio"; + }; + + pmx_led_power: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_alarm: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_info: pmx-leds { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts index aae8a7aceab7..0eead400f427 100644 --- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts +++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts @@ -45,9 +45,10 @@ /dts-v1/; +#include "orion5x-linkstation.dtsi" +#include "mvebu-linkstation-gpio-simple.dtsi" +#include "mvebu-linkstation-fan.dtsi" #include -#include -#include "orion5x-mv88f5182.dtsi" / { model = "Buffalo Linkstation LS-WTGL"; @@ -58,247 +59,93 @@ reg = <0x00000000 0x4000000>; }; - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - linux,stdout-path = &uart0; - }; - - soc { - ranges = , - , - ; - - internal-regs { - pinctrl: pinctrl@10000 { - pinctrl-names = "default"; - - pmx_led_power: pmx-leds { - marvell,pins = "mpp0"; - marvell,function = "gpio"; - }; - - pmx_led_alarm: pmx-leds { - marvell,pins = "mpp2"; - marvell,function = "gpio"; - }; - - pmx_led_info: pmx-leds { - marvell,pins = "mpp3"; - marvell,function = "gpio"; - }; - - pmx_power_hdd: pmx-power-hdd { - marvell,pins = "mpp1"; - marvell,function = "gpio"; - }; - - pmx_usb_power: pmx-usb-power { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - - pmx_sata0: pmx-sata0 { - marvell,pins = "mpp12"; - marvell,function = "sata0"; - }; - - pmx_sata1: pmx-sata1 { - marvell,pins = "mpp13"; - marvell,function = "sata1"; - }; - - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp14"; - marvell,function = "gpio"; - }; - - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp6"; - marvell,function = "gpio"; - }; - - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp8", "mpp10"; - marvell,function = "gpio"; - }; - }; - }; - }; - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; + power-on-switch { gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; }; - button@2 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; + power-auto-switch { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; }; }; gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_power &pmx_led_alarm - &pmx_led_info>; - pinctrl-names = "default"; - - led@1 { - label = "lswtgl:blue:power"; + blue-power-led { gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; - default-state = "keep"; }; - led@2 { - label = "lswtgl:red:alarm"; + red-alarm-led { gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; }; - led@3 { - label = "lswtgl:amber:info"; + amber-info-led { gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; }; }; gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - gpios = <&gpio0 14 GPIO_ACTIVE_LOW &gpio0 17 GPIO_ACTIVE_LOW>; - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; }; +}; - restart_poweroff { - compatible = "restart-poweroff"; +&pinctrl { + pmx_led_power: pmx-leds { + marvell,pins = "mpp0"; + marvell,function = "gpio"; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd &pmx_usb_power>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; - - hdd_power: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - }; + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; }; -}; - -&devbus_bootcs { - status = "okay"; - devbus,keep-config; - flash@0 { - compatible = "jedec-flash"; - reg = <0 0x40000>; - bank-width = <1>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - header@0 { - reg = <0 0x30000>; - read-only; - }; - - uboot@30000 { - reg = <0x30000 0xF000>; - read-only; - }; + pmx_led_alarm: pmx-leds { + marvell,pins = "mpp2"; + marvell,function = "gpio"; + }; - uboot_env@3F000 { - reg = <0x3F000 0x1000>; - }; - }; + pmx_led_info: pmx-leds { + marvell,pins = "mpp3"; + marvell,function = "gpio"; }; -}; -&mdio { - status = "okay"; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp6"; + marvell,function = "gpio"; + }; - ethphy: ethernet-phy { - reg = <8>; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp8", "mpp10"; + marvell,function = "gpio"; }; -}; -ð { - status = "okay"; + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; - ethernet-port@0 { - phy-handle = <ðphy>; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp14"; + marvell,function = "gpio"; }; -}; -&ehci0 { - status = "okay"; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; }; -&i2c { - status = "okay"; - - rtc { - compatible = "ricoh,rs5c372a"; - reg = <0x32>; - }; +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; -&wdt { - status = "disabled"; +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; }; &sata { - pinctrl-0 = <&pmx_sata0 &pmx_sata1>; - pinctrl-names = "default"; - status = "okay"; nr-ports = <2>; }; - -&uart0 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi new file mode 100644 index 000000000000..ed456ab35fd8 --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi @@ -0,0 +1,180 @@ +/* + * Device Tree common file for orion5x based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +#include "orion5x-mv88f5182.dtsi" + +/ { + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + linux,stdout-path = &uart0; + }; + + soc { + ranges = , + , + ; + }; + + restart_poweroff { + compatible = "restart-poweroff"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_usb &pmx_power_hdd>; + pinctrl-names = "default"; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + + hdd_power: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "HDD Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,function = "gpio"; + }; +}; + +&devbus_bootcs { + status = "okay"; + devbus,keep-config; + + flash@0 { + compatible = "jedec-flash"; + reg = <0 0x40000>; + bank-width = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + header@0 { + reg = <0 0x30000>; + read-only; + }; + + uboot@30000 { + reg = <0x30000 0xF000>; + read-only; + }; + + uboot_env@3F000 { + reg = <0x3F000 0x1000>; + }; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy: ethernet-phy { + reg = <8>; + }; +}; + +ð { + status = "okay"; + + ethernet-port@0 { + phy-handle = <ðphy>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c { + status = "okay"; + + rtc { + compatible = "ricoh,rs5c372a"; + reg = <0x32>; + }; +}; + +&wdt { + status = "disabled"; +}; + +&sata { + status = "okay"; + nr-ports = <1>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; -- GitLab From b1742ffa9ddb347a8bcb8e5f7dcf4d3a790f9041 Mon Sep 17 00:00:00 2001 From: Roger Shimizu Date: Sat, 6 Feb 2016 14:59:53 +0900 Subject: [PATCH 0893/5324] ARM: dts: orion5x: add device tree for buffalo linkstation ls-gl Add dts file to support Buffalo Linkstation LS-GL (a.k.a Buffalo Linkstation Pro/Live), which is marvell orion5x based 3.5" HDD NAS. Product info: - (JPN) http://buffalo.jp/products/catalog/item/l/ls-gl/ - (ENG) http://www.buffalotech.com/products/network-storage/linkstation/linkstation-pro This device tree is based on the board file: arch/arm/mach-orion5x/kurobox_pro-setup.c However, that board file also support Kurobox Pro, which is not supported by device tree yet. So the board file is not removed. Signed-off-by: Roger Shimizu Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/Makefile | 1 + .../arm/boot/dts/orion5x-linkstation-lsgl.dts | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 arch/arm/boot/dts/orion5x-linkstation-lsgl.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 30d316dc050f..66f464dd814a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -517,6 +517,7 @@ dtb-$(CONFIG_SOC_DRA7XX) += \ dtb-$(CONFIG_ARCH_ORION5X) += \ orion5x-lacie-d2-network.dtb \ orion5x-lacie-ethernet-disk-mini-v2.dtb \ + orion5x-linkstation-lsgl.dtb \ orion5x-linkstation-lswtgl.dtb \ orion5x-lswsgl.dtb \ orion5x-maxtor-shared-storage-2.dtb \ diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts new file mode 100644 index 000000000000..1cf644bfd7ea --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts @@ -0,0 +1,87 @@ +/* + * Device Tree file for Buffalo Linkstation LS-GL + * (also known as Buffalo Linkstation Pro/Live) + * + * Copyright (C) 2016 + * Roger Shimizu + * + * Based on the board file arch/arm/mach-orion5x/kurobox_pro-setup.c + * Copyright (C) Ronen Shitrit + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) 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 shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , 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. + */ + +/dts-v1/; + +#include "orion5x-linkstation.dtsi" +#include + +/ { + model = "Buffalo Linkstation Pro/Live"; + compatible = "buffalo,lsgl", "marvell,orion5x-88f5182", "marvell,orion5x"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; +}; + +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; +}; + +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; +}; + +&ehci1 { + status = "okay"; +}; -- GitLab From 26447231fe8cb695369a392d8e018c035455ac8c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 15 Dec 2015 13:36:35 +0000 Subject: [PATCH 0894/5324] arm64: dts: prepare foundation-v8.dts to cope with GICv3 To prepare the ARM foundation model to support GICv3, we adjust the #address-cells property of the current GICv2 node to be compatible with the two cells required for GICv3 later. Signed-off-by: Andre Przywara Acked-by: Marc Zyngier Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/foundation-v8.dts | 88 +++++++++++------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 4eac8dcea423..3c5595deeba6 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -75,7 +75,7 @@ gic: interrupt-controller@2c001000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, <0x0 0x2c002000 0 0x1000>, @@ -116,49 +116,49 @@ #interrupt-cells = <1>; interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 4>, - <0 0 1 &gic 0 1 4>, - <0 0 2 &gic 0 2 4>, - <0 0 3 &gic 0 3 4>, - <0 0 4 &gic 0 4 4>, - <0 0 5 &gic 0 5 4>, - <0 0 6 &gic 0 6 4>, - <0 0 7 &gic 0 7 4>, - <0 0 8 &gic 0 8 4>, - <0 0 9 &gic 0 9 4>, - <0 0 10 &gic 0 10 4>, - <0 0 11 &gic 0 11 4>, - <0 0 12 &gic 0 12 4>, - <0 0 13 &gic 0 13 4>, - <0 0 14 &gic 0 14 4>, - <0 0 15 &gic 0 15 4>, - <0 0 16 &gic 0 16 4>, - <0 0 17 &gic 0 17 4>, - <0 0 18 &gic 0 18 4>, - <0 0 19 &gic 0 19 4>, - <0 0 20 &gic 0 20 4>, - <0 0 21 &gic 0 21 4>, - <0 0 22 &gic 0 22 4>, - <0 0 23 &gic 0 23 4>, - <0 0 24 &gic 0 24 4>, - <0 0 25 &gic 0 25 4>, - <0 0 26 &gic 0 26 4>, - <0 0 27 &gic 0 27 4>, - <0 0 28 &gic 0 28 4>, - <0 0 29 &gic 0 29 4>, - <0 0 30 &gic 0 30 4>, - <0 0 31 &gic 0 31 4>, - <0 0 32 &gic 0 32 4>, - <0 0 33 &gic 0 33 4>, - <0 0 34 &gic 0 34 4>, - <0 0 35 &gic 0 35 4>, - <0 0 36 &gic 0 36 4>, - <0 0 37 &gic 0 37 4>, - <0 0 38 &gic 0 38 4>, - <0 0 39 &gic 0 39 4>, - <0 0 40 &gic 0 40 4>, - <0 0 41 &gic 0 41 4>, - <0 0 42 &gic 0 42 4>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; ethernet@2,02000000 { compatible = "smsc,lan91c111"; -- GitLab From e6b512285a46c71e056e15985140d8a078937b7d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 15 Dec 2015 13:36:36 +0000 Subject: [PATCH 0895/5324] arm64: dts: Foundation model: increase GICC region to allow EOImode=1 The Foundation model GIC mapping is wrong, as the GICC region should be 8kB instead of 4kB (the model implements the GICv2 architecture). This defect prevents the driver from switching to EOImode==1. Signed-off-by: Andre Przywara Reviewed-by: Marc Zyngier Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/foundation-v8.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 3c5595deeba6..57ad9fed107c 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -78,7 +78,7 @@ #address-cells = <2>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, - <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c002000 0 0x2000>, <0x0 0x2c004000 0 0x2000>, <0x0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; -- GitLab From d11a8979667818d44f25ebe4efeed258d9f770e8 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 15 Dec 2015 13:36:37 +0000 Subject: [PATCH 0896/5324] arm64: dts: split Foundation model dts to put the GIC separately The ARMv8 Foundation model can be run with a GICv2 or a GICv3. To prepare for the GICv3 version of the .dts without code duplication, move most of the nodes of the existing DT (except the GIC) into an include file and just keep that include statement and the GIC node in the current foundation-v8.dts. Signed-off-by: Andre Przywara Acked-by: Marc Zyngier Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/foundation-v8.dts | 223 +------------------- arch/arm64/boot/dts/arm/foundation-v8.dtsi | 228 +++++++++++++++++++++ 2 files changed, 230 insertions(+), 221 deletions(-) create mode 100644 arch/arm64/boot/dts/arm/foundation-v8.dtsi diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 57ad9fed107c..71168077312d 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -1,77 +1,12 @@ /* * ARM Ltd. * - * ARMv8 Foundation model DTS + * ARMv8 Foundation model DTS (GICv2 configuration) */ -/dts-v1/; - -/memreserve/ 0x80000000 0x00010000; +#include "foundation-v8.dtsi" / { - model = "Foundation-v8A"; - compatible = "arm,foundation-aarch64", "arm,vexpress"; - interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - - chosen { }; - - aliases { - serial0 = &v2m_serial0; - serial1 = &v2m_serial1; - serial2 = &v2m_serial2; - serial3 = &v2m_serial3; - }; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - - L2_0: l2-cache0 { - compatible = "cache"; - }; - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x00000000 0x80000000 0 0x80000000>, - <0x00000008 0x80000000 0 0x80000000>; - }; - gic: interrupt-controller@2c001000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; @@ -83,158 +18,4 @@ <0x0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - clock-frequency = <100000000>; - }; - - pmu { - compatible = "arm,armv8-pmuv3"; - interrupts = <0 60 4>, - <0 61 4>, - <0 62 4>, - <0 63 4>; - }; - - smb { - compatible = "arm,vexpress,v2m-p1", "simple-bus"; - arm,v2m-memory-map = "rs1"; - #address-cells = <2>; /* SMB chipselect number and offset */ - #size-cells = <1>; - - ranges = <0 0 0 0x08000000 0x04000000>, - <1 0 0 0x14000000 0x04000000>, - <2 0 0 0x18000000 0x04000000>, - <3 0 0 0x1c000000 0x04000000>, - <4 0 0 0x0c000000 0x04000000>, - <5 0 0 0x10000000 0x04000000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 0 0 4>, - <0 0 1 &gic 0 0 0 1 4>, - <0 0 2 &gic 0 0 0 2 4>, - <0 0 3 &gic 0 0 0 3 4>, - <0 0 4 &gic 0 0 0 4 4>, - <0 0 5 &gic 0 0 0 5 4>, - <0 0 6 &gic 0 0 0 6 4>, - <0 0 7 &gic 0 0 0 7 4>, - <0 0 8 &gic 0 0 0 8 4>, - <0 0 9 &gic 0 0 0 9 4>, - <0 0 10 &gic 0 0 0 10 4>, - <0 0 11 &gic 0 0 0 11 4>, - <0 0 12 &gic 0 0 0 12 4>, - <0 0 13 &gic 0 0 0 13 4>, - <0 0 14 &gic 0 0 0 14 4>, - <0 0 15 &gic 0 0 0 15 4>, - <0 0 16 &gic 0 0 0 16 4>, - <0 0 17 &gic 0 0 0 17 4>, - <0 0 18 &gic 0 0 0 18 4>, - <0 0 19 &gic 0 0 0 19 4>, - <0 0 20 &gic 0 0 0 20 4>, - <0 0 21 &gic 0 0 0 21 4>, - <0 0 22 &gic 0 0 0 22 4>, - <0 0 23 &gic 0 0 0 23 4>, - <0 0 24 &gic 0 0 0 24 4>, - <0 0 25 &gic 0 0 0 25 4>, - <0 0 26 &gic 0 0 0 26 4>, - <0 0 27 &gic 0 0 0 27 4>, - <0 0 28 &gic 0 0 0 28 4>, - <0 0 29 &gic 0 0 0 29 4>, - <0 0 30 &gic 0 0 0 30 4>, - <0 0 31 &gic 0 0 0 31 4>, - <0 0 32 &gic 0 0 0 32 4>, - <0 0 33 &gic 0 0 0 33 4>, - <0 0 34 &gic 0 0 0 34 4>, - <0 0 35 &gic 0 0 0 35 4>, - <0 0 36 &gic 0 0 0 36 4>, - <0 0 37 &gic 0 0 0 37 4>, - <0 0 38 &gic 0 0 0 38 4>, - <0 0 39 &gic 0 0 0 39 4>, - <0 0 40 &gic 0 0 0 40 4>, - <0 0 41 &gic 0 0 0 41 4>, - <0 0 42 &gic 0 0 0 42 4>; - - ethernet@2,02000000 { - compatible = "smsc,lan91c111"; - reg = <2 0x02000000 0x10000>; - interrupts = <15>; - }; - - v2m_clk24mhz: clk24mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "v2m:clk24mhz"; - }; - - v2m_refclk1mhz: refclk1mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000>; - clock-output-names = "v2m:refclk1mhz"; - }; - - v2m_refclk32khz: refclk32khz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "v2m:refclk32khz"; - }; - - iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 3 0 0x200000>; - - v2m_sysreg: sysreg@010000 { - compatible = "arm,vexpress-sysreg"; - reg = <0x010000 0x1000>; - }; - - v2m_serial0: uart@090000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x090000 0x1000>; - interrupts = <5>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial1: uart@0a0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0a0000 0x1000>; - interrupts = <6>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial2: uart@0b0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0b0000 0x1000>; - interrupts = <7>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial3: uart@0c0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0c0000 0x1000>; - interrupts = <8>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - virtio_block@0130000 { - compatible = "virtio,mmio"; - reg = <0x130000 0x200>; - interrupts = <42>; - }; - }; - }; }; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi new file mode 100644 index 000000000000..9314f3943269 --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -0,0 +1,228 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { + model = "Foundation-v8A"; + compatible = "arm,foundation-aarch64", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache0 { + compatible = "cache"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + clock-frequency = <100000000>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + smb { + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x200>; + interrupts = <42>; + }; + }; + }; +}; -- GitLab From 6ba29e916e15c11341b0e043ed643555143e9e64 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 15 Dec 2015 13:36:38 +0000 Subject: [PATCH 0897/5324] arm64: dts: add .dts for GICv3 Foundation model The ARMv8 Foundation model sports a command line parameter to use a GICv3 emulation instead of the default GICv2 interrupt controller. Add a new .dts file which reuses most of the definitions of the existing model while just adding the required properties for the GICv3 node. This allows the public Foundation model to run with a GICv3. Signed-off-by: Andre Przywara Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/Makefile | 2 +- .../boot/dts/arm/foundation-v8-gicv3.dts | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index bb3c07209676..46d342d0d435 100644 --- a/arch/arm64/boot/dts/arm/Makefile +++ b/arch/arm64/boot/dts/arm/Makefile @@ -1,4 +1,4 @@ -dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb foundation-v8-gicv3.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb diff --git a/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts new file mode 100644 index 000000000000..35588dfa095c --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts @@ -0,0 +1,30 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS (GICv3 configuration) + */ + +#include "foundation-v8.dtsi" + +/ { + gic: interrupt-controller@2f000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x2f000000 0x0 0x10000>, + <0x0 0x2f100000 0x0 0x200000>, + <0x0 0x2c000000 0x0 0x2000>, + <0x0 0x2c010000 0x0 0x2000>, + <0x0 0x2c02f000 0x0 0x2000>; + interrupts = <1 9 4>; + + its: its@2f020000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2f020000 0x0 0x20000>; + }; + }; +}; -- GitLab From 36582c60de2789feb91b63ff4ed8ec9381fa4d1e Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 11 Jan 2016 17:16:08 +0000 Subject: [PATCH 0898/5324] arm64: dts: move juno pcie-controller to base file The PCIe controller is found on all Juno SoC version. However it's not functional on R0 due to some hardware bug. In preparation to add Juno R2 support, this patch moves the pcie-controller defination to base DTS file. It's marked as disabled by default and is enabled for Juno R1 explicitly. Acked-by: Liviu Dudau Signed-off-by: Sudeep Holla --- arch/arm64/boot/dts/arm/juno-base.dtsi | 22 ++++++++++++++++++++++ arch/arm64/boot/dts/arm/juno-r1.dts | 25 ++++--------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index dd5158eb5872..b501721baf77 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -75,6 +75,28 @@ }; }; + pcie_ctlr: pcie-controller@40000000 { + compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; + device_type = "pci"; + reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ + bus-range = <0 255>; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, + <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, + <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, + <0 0 0 2 &gic 0 0 0 137 4>, + <0 0 0 3 &gic 0 0 0 138 4>, + <0 0 0 4 &gic 0 0 0 139 4>; + msi-parent = <&v2m_0>; + status = "disabled"; + }; + scpi { compatible = "arm,scpi"; mboxes = <&mailbox 1>; diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts index 8826f834f54f..d95d9e7e2dc0 100644 --- a/arch/arm64/boot/dts/arm/juno-r1.dts +++ b/arch/arm64/boot/dts/arm/juno-r1.dts @@ -172,29 +172,12 @@ }; #include "juno-base.dtsi" - - pcie-controller@40000000 { - compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; - device_type = "pci"; - reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ - bus-range = <0 255>; - linux,pci-domain = <0>; - #address-cells = <3>; - #size-cells = <2>; - dma-coherent; - ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, - <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, - <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, - <0 0 0 2 &gic 0 0 0 137 4>, - <0 0 0 3 &gic 0 0 0 138 4>, - <0 0 0 4 &gic 0 0 0 139 4>; - msi-parent = <&v2m_0>; - }; }; &memtimer { status = "okay"; }; + +&pcie_ctlr { + status = "okay"; +}; -- GitLab From e6d7f6dc857f6e8efafc68217a598bd5d532034f Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 22 Dec 2015 17:45:29 +0000 Subject: [PATCH 0899/5324] arm64: dts: Add support for Juno r2 board Juno r2 is identical to Juno r1 with Cortex A57 cores replaced by Cortex A72 cores. Acked-by: Rob Herring Acked-by: Liviu Dudau Signed-off-by: Sudeep Holla --- .../devicetree/bindings/arm/arm-boards | 1 + arch/arm64/boot/dts/arm/Makefile | 2 +- arch/arm64/boot/dts/arm/juno-r2.dts | 183 ++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/arm/juno-r2.dts diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 1a709970e7f7..70601a58c433 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -180,6 +180,7 @@ described under the RS1 memory mapping. Required properties (in root node): compatible = "arm,juno"; /* For Juno r0 board */ compatible = "arm,juno-r1"; /* For Juno r1 board */ + compatible = "arm,juno-r2"; /* For Juno r2 board */ Required nodes: The description for the board must include: diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index 46d342d0d435..75cc2aa10101 100644 --- a/arch/arm64/boot/dts/arm/Makefile +++ b/arch/arm64/boot/dts/arm/Makefile @@ -1,5 +1,5 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb foundation-v8-gicv3.dtb -dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts new file mode 100644 index 000000000000..88ecd6182b67 --- /dev/null +++ b/arch/arm64/boot/dts/arm/juno-r2.dts @@ -0,0 +1,183 @@ +/* + * ARM Ltd. Juno Platform + * + * Copyright (c) 2015 ARM Ltd. + * + * This file is licensed under a dual GPLv2 or BSD license. + */ + +/dts-v1/; + +#include + +/ { + model = "ARM Juno development board (r2)"; + compatible = "arm,juno-r2", "arm,juno", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&A72_0>; + }; + core1 { + cpu = <&A72_1>; + }; + }; + + cluster1 { + core0 { + cpu = <&A53_0>; + }; + core1 { + cpu = <&A53_1>; + }; + core2 { + cpu = <&A53_2>; + }; + core3 { + cpu = <&A53_3>; + }; + }; + }; + + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + + A72_0: cpu@0 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_1: cpu@1 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x1>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_0: cpu@100 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_1: cpu@101 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x101>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_2: cpu@102 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x102>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_3: cpu@103 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x103>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_L2: l2-cache0 { + compatible = "cache"; + }; + + A53_L2: l2-cache1 { + compatible = "cache"; + }; + }; + + pmu_a72 { + compatible = "arm,cortex-a72-pmu"; + interrupts = , + ; + interrupt-affinity = <&A72_0>, + <&A72_1>; + }; + + pmu_a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&A53_0>, + <&A53_1>, + <&A53_2>, + <&A53_3>; + }; + + #include "juno-base.dtsi" +}; + +&memtimer { + status = "okay"; +}; + +&pcie_ctlr { + status = "okay"; +}; -- GitLab From c6b90653f1f7ea383734f8ce9e8df285a0c23f5b Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Thu, 4 Feb 2016 18:06:10 +0100 Subject: [PATCH 0900/5324] drivers/perf: arm_pmu: make info messages more verbose On a big.LITTLE system e.g. with Cortex A57 and A53 in case not all cores are online at PMU probe time we might get hw perfevents: failed to probe PMU! hw perfevents: failed to register PMU devices! making it unclear which cores failed, here. Add the device tree full name which failed and the error value resulting in a more verbose and helpful message like hw perfevents: /soc/pmu_a53: failed to probe PMU! Error -6 hw perfevents: /soc/pmu_a53: failed to register PMU devices! Error -6 Signed-off-by: Dirk Behme Signed-off-by: Will Deacon --- drivers/perf/arm_pmu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index eb5bee07526b..ca63a452393a 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -907,7 +907,8 @@ int arm_pmu_device_probe(struct platform_device *pdev, } if (ret) { - pr_info("failed to probe PMU!\n"); + pr_info("%s: failed to probe PMU! Error %i\n", + node->full_name, ret); goto out_free; } @@ -927,7 +928,8 @@ int arm_pmu_device_probe(struct platform_device *pdev, out_destroy: cpu_pmu_destroy(pmu); out_free: - pr_info("failed to register PMU devices!\n"); + pr_info("%s: failed to register PMU devices! Error %i\n", + node->full_name, ret); kfree(pmu); return ret; } -- GitLab From ba58148b6f0408b791e097ab2967c8f6da959fd9 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 22 Jan 2016 12:25:32 -0600 Subject: [PATCH 0901/5324] quota: Fixup comments about return value of Q_[X]GETNEXTQUOTA We actually return ENOENT, not ESRCH, when there is no structure with higher ID from ->get_nextdqblk. Fixup comments. Signed-off-by: Jan Kara --- fs/quota/quota.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 0ebc90496525..a925f629a00a 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -224,7 +224,7 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, /* * Return quota for next active quota >= this id, if any exists, - * otherwise return -ESRCH via ->get_nextdqblk + * otherwise return -ENOENT via ->get_nextdqblk */ static int quota_getnextquota(struct super_block *sb, int type, qid_t id, void __user *addr) @@ -655,7 +655,7 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id, /* * Return quota for next active quota >= this id, if any exists, - * otherwise return -ESRCH via ->get_nextdqblk. + * otherwise return -ENOENT via ->get_nextdqblk. */ static int quota_getnextxquota(struct super_block *sb, int type, qid_t id, void __user *addr) -- GitLab From 7955118eafc4a2621fd88e92b505919af344583f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 25 Jan 2016 16:13:53 +0100 Subject: [PATCH 0902/5324] quota: Allow Q_GETQUOTA for frozen filesystem quota_cmd_write() forgot to list Q_GETQUOTA among commands allowed for frozen filesystem. Thus Q_GETQUOTA quotactl would unnecessarily block on frozen filesystems. Fix the issue by properly listing Q_GETQUOTA. Signed-off-by: Jan Kara --- fs/quota/quota.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/quota/quota.c b/fs/quota/quota.c index a925f629a00a..8e297c92f7d4 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -768,6 +768,7 @@ static int quotactl_cmd_write(int cmd) switch (cmd) { case Q_GETFMT: case Q_GETINFO: + case Q_GETQUOTA: case Q_GETNEXTQUOTA: case Q_SYNC: case Q_XGETQSTAT: -- GitLab From 525e2c56c341cb8b31bbe1694f0582077f454969 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Fri, 15 Jan 2016 02:44:19 -0600 Subject: [PATCH 0903/5324] udf: Parameterize output length in udf_put_filename Make the desired output length a parameter rather than have it hard-coded to UDF_NAME_LEN. Although all call sites still have this length the same, this parameterization will make the function more universal and also consistent with udf_get_filename. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/namei.c | 10 ++++++---- fs/udf/udfdecl.h | 4 ++-- fs/udf/unicode.c | 10 +++++----- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 42eafb91f7ff..f82c70d73aba 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -362,8 +362,9 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, *err = -EINVAL; goto out_err; } - namelen = udf_put_filename(sb, dentry->d_name.name, name, - dentry->d_name.len); + namelen = udf_put_filename(sb, dentry->d_name.name, + dentry->d_name.len, + name, UDF_NAME_LEN); if (!namelen) { *err = -ENAMETOOLONG; goto out_err; @@ -997,8 +998,9 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, } if (pc->componentType == 5) { - namelen = udf_put_filename(sb, compstart, name, - symname - compstart); + namelen = udf_put_filename(sb, compstart, + symname - compstart, + name, UDF_NAME_LEN); if (!namelen) goto out_no_entry; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index fa0044b6b81d..4a47c7267614 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -216,8 +216,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, /* unicode.c */ extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, int); -extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, - int); +extern int udf_put_filename(struct super_block *, const uint8_t *, int, + uint8_t *, int); extern int udf_build_ustr(struct ustr *, dstring *, int); extern int udf_CS0toUTF8(struct ustr *, const struct ustr *); diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index e788a05aab83..47e61883275d 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -395,22 +395,22 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, return ret; } -int udf_put_filename(struct super_block *sb, const uint8_t *sname, - uint8_t *dname, int flen) +int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, + uint8_t *dname, int dlen) { struct ustr unifilename; int namelen; - if (!udf_char_to_ustr(&unifilename, sname, flen)) + if (!udf_char_to_ustr(&unifilename, sname, slen)) return 0; if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { - namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN); + namelen = udf_UTF8toCS0(dname, &unifilename, dlen); if (!namelen) return 0; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, - &unifilename, UDF_NAME_LEN); + &unifilename, dlen); if (!namelen) return 0; } else -- GitLab From 3e7fc2055c931b1c27a9834a753611c879492a34 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Fri, 15 Jan 2016 02:44:20 -0600 Subject: [PATCH 0904/5324] udf: Join functions for UTF8 and NLS conversions There is no much sense to have separate functions for UTF8 and NLS conversions, since UTF8 encoding is actually the special case of NLS. However, although UTF8 is also supported by general NLS framework, it would be good to have separate UTF8 character conversion functions (char2uni and uni2char) locally in UDF code, so that they could be used even if NLS support is not enabled in the kernel configuration. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/unicode.c | 278 +++++++++++++++-------------------------------- 1 file changed, 90 insertions(+), 188 deletions(-) diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 47e61883275d..4d7a674ebce5 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -76,151 +76,72 @@ static void udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) memcpy(dest->u_name, ptr + 1, exactsize - 1); } -/* - * udf_CS0toUTF8 - * - * PURPOSE - * Convert OSTA Compressed Unicode to the UTF-8 equivalent. - * - * PRE-CONDITIONS - * utf Pointer to UTF-8 output buffer. - * ocu Pointer to OSTA Compressed Unicode input buffer - * of size UDF_NAME_LEN bytes. - * both of type "struct ustr *" - * - * POST-CONDITIONS - * >= 0 on success. - * - * HISTORY - * November 12, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ -int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) +static int udf_uni2char_utf8(wchar_t uni, + unsigned char *out, + int boundlen) { - const uint8_t *ocu; - uint8_t cmp_id, ocu_len; - int i; - - ocu_len = ocu_i->u_len; - if (ocu_len == 0) { - memset(utf_o, 0, sizeof(struct ustr)); - return 0; - } - - cmp_id = ocu_i->u_cmpID; - if (cmp_id != 8 && cmp_id != 16) { - memset(utf_o, 0, sizeof(struct ustr)); - pr_err("unknown compression code (%d) stri=%s\n", - cmp_id, ocu_i->u_name); - return -EINVAL; - } - - ocu = ocu_i->u_name; - utf_o->u_len = 0; - for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { - - /* Expand OSTA compressed Unicode to Unicode */ - uint32_t c = ocu[i++]; - if (cmp_id == 16) - c = (c << 8) | ocu[i++]; - - /* Compress Unicode to UTF-8 */ - if (c < 0x80U) - utf_o->u_name[utf_o->u_len++] = (uint8_t)c; - else if (c < 0x800U) { - if (utf_o->u_len > (UDF_NAME_LEN - 4)) - break; - utf_o->u_name[utf_o->u_len++] = - (uint8_t)(0xc0 | (c >> 6)); - utf_o->u_name[utf_o->u_len++] = - (uint8_t)(0x80 | (c & 0x3f)); - } else { - if (utf_o->u_len > (UDF_NAME_LEN - 5)) - break; - utf_o->u_name[utf_o->u_len++] = - (uint8_t)(0xe0 | (c >> 12)); - utf_o->u_name[utf_o->u_len++] = - (uint8_t)(0x80 | - ((c >> 6) & 0x3f)); - utf_o->u_name[utf_o->u_len++] = - (uint8_t)(0x80 | (c & 0x3f)); - } + int u_len = 0; + + if (boundlen <= 0) + return -ENAMETOOLONG; + + if (uni < 0x80) { + out[u_len++] = (unsigned char)uni; + } else if (uni < 0x800) { + if (boundlen < 2) + return -ENAMETOOLONG; + out[u_len++] = (unsigned char)(0xc0 | (uni >> 6)); + out[u_len++] = (unsigned char)(0x80 | (uni & 0x3f)); + } else { + if (boundlen < 3) + return -ENAMETOOLONG; + out[u_len++] = (unsigned char)(0xe0 | (uni >> 12)); + out[u_len++] = (unsigned char)(0x80 | ((uni >> 6) & 0x3f)); + out[u_len++] = (unsigned char)(0x80 | (uni & 0x3f)); } - utf_o->u_cmpID = 8; - - return utf_o->u_len; + return u_len; } -/* - * - * udf_UTF8toCS0 - * - * PURPOSE - * Convert UTF-8 to the OSTA Compressed Unicode equivalent. - * - * DESCRIPTION - * This routine is only called by udf_lookup(). - * - * PRE-CONDITIONS - * ocu Pointer to OSTA Compressed Unicode output - * buffer of size UDF_NAME_LEN bytes. - * utf Pointer to UTF-8 input buffer. - * utf_len Length of UTF-8 input buffer in bytes. - * - * POST-CONDITIONS - * Zero on success. - * - * HISTORY - * November 12, 1997 - Andrew E. Mileski - * Written, tested, and released. - */ -static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) +static int udf_char2uni_utf8(const unsigned char *in, + int boundlen, + wchar_t *uni) { - unsigned c, i, max_val, utf_char; - int utf_cnt, u_len, u_ch; + unsigned int utf_char; + unsigned char c; + int utf_cnt, u_len; - memset(ocu, 0, sizeof(dstring) * length); - ocu[0] = 8; - max_val = 0xffU; - u_ch = 1; - -try_again: - u_len = 0U; - utf_char = 0U; - utf_cnt = 0U; - for (i = 0U; i < utf->u_len; i++) { - /* Name didn't fit? */ - if (u_len + 1 + u_ch >= length) - return 0; - - c = (uint8_t)utf->u_name[i]; + utf_char = 0; + utf_cnt = 0; + for (u_len = 0; u_len < boundlen;) { + c = in[u_len++]; /* Complete a multi-byte UTF-8 character */ if (utf_cnt) { - utf_char = (utf_char << 6) | (c & 0x3fU); + utf_char = (utf_char << 6) | (c & 0x3f); if (--utf_cnt) continue; } else { /* Check for a multi-byte UTF-8 character */ - if (c & 0x80U) { + if (c & 0x80) { /* Start a multi-byte UTF-8 character */ - if ((c & 0xe0U) == 0xc0U) { - utf_char = c & 0x1fU; + if ((c & 0xe0) == 0xc0) { + utf_char = c & 0x1f; utf_cnt = 1; - } else if ((c & 0xf0U) == 0xe0U) { - utf_char = c & 0x0fU; + } else if ((c & 0xf0) == 0xe0) { + utf_char = c & 0x0f; utf_cnt = 2; - } else if ((c & 0xf8U) == 0xf0U) { - utf_char = c & 0x07U; + } else if ((c & 0xf8) == 0xf0) { + utf_char = c & 0x07; utf_cnt = 3; - } else if ((c & 0xfcU) == 0xf8U) { - utf_char = c & 0x03U; + } else if ((c & 0xfc) == 0xf8) { + utf_char = c & 0x03; utf_cnt = 4; - } else if ((c & 0xfeU) == 0xfcU) { - utf_char = c & 0x01U; + } else if ((c & 0xfe) == 0xfc) { + utf_char = c & 0x01; utf_cnt = 5; } else { - goto error_out; + utf_cnt = -1; + break; } continue; } else { @@ -228,36 +149,19 @@ static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) utf_char = c; } } - - /* Choose no compression if necessary */ - if (utf_char > max_val) { - if (max_val == 0xffU) { - max_val = 0xffffU; - ocu[0] = (uint8_t)0x10U; - u_ch = 2; - goto try_again; - } - goto error_out; - } - - if (max_val == 0xffffU) - ocu[++u_len] = (uint8_t)(utf_char >> 8); - ocu[++u_len] = (uint8_t)(utf_char & 0xffU); + *uni = utf_char; + break; } - if (utf_cnt) { -error_out: - ocu[++u_len] = '?'; - printk(KERN_DEBUG pr_fmt("bad UTF-8 character\n")); + *uni = '?'; + return -EINVAL; } - - ocu[length - 1] = (uint8_t)u_len + 1; - - return u_len + 1; + return u_len; } -static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, - const struct ustr *ocu_i) +static int udf_name_from_CS0(struct ustr *utf_o, + const struct ustr *ocu_i, + int (*conv_f)(wchar_t, unsigned char *, int)) { const uint8_t *ocu; uint8_t cmp_id, ocu_len; @@ -286,11 +190,13 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, if (cmp_id == 16) c = (c << 8) | ocu[i++]; - len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - 2 - utf_o->u_len); + len = conv_f(c, &utf_o->u_name[utf_o->u_len], + UDF_NAME_LEN - 2 - utf_o->u_len); /* Valid character? */ if (len >= 0) utf_o->u_len += len; + else if (len == -ENAMETOOLONG) + break; else utf_o->u_name[utf_o->u_len++] = '?'; } @@ -299,26 +205,26 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, return utf_o->u_len; } -static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, - int length) +static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length, + int (*conv_f)(const unsigned char *, int, wchar_t *)) { - int len; - unsigned i, max_val; - uint16_t uni_char; + int i, len; + unsigned int max_val; + wchar_t uni_char; int u_len, u_ch; memset(ocu, 0, sizeof(dstring) * length); ocu[0] = 8; - max_val = 0xffU; + max_val = 0xff; u_ch = 1; try_again: - u_len = 0U; - for (i = 0U; i < uni->u_len; i++) { + u_len = 0; + for (i = 0; i < uni->u_len; i++) { /* Name didn't fit? */ if (u_len + 1 + u_ch >= length) return 0; - len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); + len = conv_f(&uni->u_name[i], uni->u_len - i, &uni_char); if (!len) continue; /* Invalid character, deal with it */ @@ -328,15 +234,15 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, } if (uni_char > max_val) { - max_val = 0xffffU; - ocu[0] = (uint8_t)0x10U; + max_val = 0xffff; + ocu[0] = 0x10; u_ch = 2; goto try_again; } - if (max_val == 0xffffU) + if (max_val == 0xffff) ocu[++u_len] = (uint8_t)(uni_char >> 8); - ocu[++u_len] = (uint8_t)(uni_char & 0xffU); + ocu[++u_len] = (uint8_t)(uni_char & 0xff); i += len - 1; } @@ -344,10 +250,16 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, return u_len + 1; } +int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) +{ + return udf_name_from_CS0(utf_o, ocu_i, udf_uni2char_utf8); +} + int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, uint8_t *dname, int dlen) { struct ustr *filename, *unifilename; + int (*conv_f)(wchar_t, unsigned char *, int); int ret; if (!slen) @@ -365,23 +277,18 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, udf_build_ustr_exact(unifilename, sname, slen); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { - ret = udf_CS0toUTF8(filename, unifilename); - if (ret < 0) { - udf_debug("Failed in udf_get_filename: sname = %s\n", - sname); - goto out2; - } + conv_f = udf_uni2char_utf8; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { - ret = udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename, - unifilename); - if (ret < 0) { - udf_debug("Failed in udf_get_filename: sname = %s\n", - sname); - goto out2; - } + conv_f = UDF_SB(sb)->s_nls_map->uni2char; } else BUG(); + ret = udf_name_from_CS0(filename, unifilename, conv_f); + if (ret < 0) { + udf_debug("Failed in udf_get_filename: sname = %s\n", sname); + goto out2; + } + ret = udf_translate_to_linux(dname, dlen, filename->u_name, filename->u_len, unifilename->u_name, unifilename->u_len); @@ -399,24 +306,19 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, uint8_t *dname, int dlen) { struct ustr unifilename; - int namelen; + int (*conv_f)(const unsigned char *, int, wchar_t *); if (!udf_char_to_ustr(&unifilename, sname, slen)) return 0; if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { - namelen = udf_UTF8toCS0(dname, &unifilename, dlen); - if (!namelen) - return 0; + conv_f = udf_char2uni_utf8; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { - namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, - &unifilename, dlen); - if (!namelen) - return 0; + conv_f = UDF_SB(sb)->s_nls_map->char2uni; } else - return 0; + BUG(); - return namelen; + return udf_name_to_CS0(dname, &unifilename, dlen, conv_f); } #define ILLEGAL_CHAR_MARK '_' -- GitLab From 9fba70569d9c3c253dba10ebbe3359f2157e504c Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Fri, 15 Jan 2016 02:44:21 -0600 Subject: [PATCH 0905/5324] udf: Adjust UDF_NAME_LEN to better reflect actual restrictions Actual name length restriction is 254 bytes, this is used in 'ustr' structure, and this is what fits into UDF File Ident structures. And in most cases the constant is used as UDF_NAME_LEN-2. So, it's better to just modify the constant to make it closer to reality. Also, in some cases it's useful to have a separate constant for the maximum length of file name field in CS0 encoding in UDF File Ident structures. Also, remove the unused UDF_PATH_LEN constant. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/namei.c | 10 +++++----- fs/udf/super.c | 2 +- fs/udf/udfdecl.h | 6 +++--- fs/udf/unicode.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index f82c70d73aba..9eb9c6440270 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -291,7 +291,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, struct udf_fileident_bh fibh; struct fileIdentDesc *fi; - if (dentry->d_name.len > UDF_NAME_LEN - 2) + if (dentry->d_name.len > UDF_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); #ifdef UDF_RECOVERY @@ -351,7 +351,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, struct udf_inode_info *dinfo; fibh->sbh = fibh->ebh = NULL; - name = kmalloc(UDF_NAME_LEN, GFP_NOFS); + name = kmalloc(UDF_NAME_LEN_CS0, GFP_NOFS); if (!name) { *err = -ENOMEM; goto out_err; @@ -364,7 +364,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, } namelen = udf_put_filename(sb, dentry->d_name.name, dentry->d_name.len, - name, UDF_NAME_LEN); + name, UDF_NAME_LEN_CS0); if (!namelen) { *err = -ENAMETOOLONG; goto out_err; @@ -915,7 +915,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, iinfo = UDF_I(inode); down_write(&iinfo->i_data_sem); - name = kmalloc(UDF_NAME_LEN, GFP_NOFS); + name = kmalloc(UDF_NAME_LEN_CS0, GFP_NOFS); if (!name) { err = -ENOMEM; goto out_no_entry; @@ -1000,7 +1000,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, if (pc->componentType == 5) { namelen = udf_put_filename(sb, compstart, symname - compstart, - name, UDF_NAME_LEN); + name, UDF_NAME_LEN_CS0); if (!namelen) goto out_no_entry; diff --git a/fs/udf/super.c b/fs/udf/super.c index a522c15a0bfd..ffb35f7eab38 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2358,7 +2358,7 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) le32_to_cpu(lvidiu->numDirs)) : 0) + buf->f_bfree; buf->f_ffree = buf->f_bfree; - buf->f_namelen = UDF_NAME_LEN - 2; + buf->f_namelen = UDF_NAME_LEN; buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 4a47c7267614..47a228248c5b 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -49,8 +49,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb, #define UDF_EXTENT_FLAG_MASK 0xC0000000 #define UDF_NAME_PAD 4 -#define UDF_NAME_LEN 256 -#define UDF_PATH_LEN 1023 +#define UDF_NAME_LEN 254 +#define UDF_NAME_LEN_CS0 255 static inline size_t udf_file_entry_alloc_offset(struct inode *inode) { @@ -108,7 +108,7 @@ struct generic_desc { struct ustr { uint8_t u_cmpID; - uint8_t u_name[UDF_NAME_LEN - 2]; + uint8_t u_name[UDF_NAME_LEN]; uint8_t u_len; }; diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 4d7a674ebce5..5599e7535401 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -33,7 +33,7 @@ static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) { - if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN - 2)) + if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN)) return 0; memset(dest, 0, sizeof(struct ustr)); @@ -184,14 +184,14 @@ static int udf_name_from_CS0(struct ustr *utf_o, ocu = ocu_i->u_name; utf_o->u_len = 0; - for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { + for (i = 0; (i < ocu_len) && (utf_o->u_len < UDF_NAME_LEN);) { /* Expand OSTA compressed Unicode to Unicode */ uint32_t c = ocu[i++]; if (cmp_id == 16) c = (c << 8) | ocu[i++]; len = conv_f(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - 2 - utf_o->u_len); + UDF_NAME_LEN - utf_o->u_len); /* Valid character? */ if (len >= 0) utf_o->u_len += len; -- GitLab From 066b9cded00b8e3212df74a417bb074f3f3a1fe0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 26 Jan 2016 21:07:30 +0100 Subject: [PATCH 0906/5324] udf: Use separate buffer for copying split names Code in udf_find_entry() and udf_readdir() used the same buffer for storing filename that was split among blocks and for the resulting filename in utf8. This worked because udf_get_filename() first internally copied the name into a different buffer and only then performed a conversion into the destination buffer. However we want to get rid of intermediate buffers so use separate buffer for converted name and name split between blocks so that we don't have the same source and destination buffer when converting split names. Signed-off-by: Jan Kara --- fs/udf/dir.c | 13 +++++++++++-- fs/udf/namei.c | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 541d9c65014d..b51b371b874a 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -45,7 +45,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) int block, iblock; loff_t nf_pos; int flen; - unsigned char *fname = NULL; + unsigned char *fname = NULL, *copy_name = NULL; unsigned char *nameptr; uint16_t liu; uint8_t lfi; @@ -143,7 +143,15 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) if (poffset >= lfi) { nameptr = (char *)(fibh.ebh->b_data + poffset - lfi); } else { - nameptr = fname; + if (!copy_name) { + copy_name = kmalloc(UDF_NAME_LEN, + GFP_NOFS); + if (!copy_name) { + ret = -ENOMEM; + goto out; + } + } + nameptr = copy_name; memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); memcpy(nameptr + lfi - poffset, @@ -185,6 +193,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) brelse(fibh.sbh); brelse(epos.bh); kfree(fname); + kfree(copy_name); return ret; } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9eb9c6440270..a2ba11eca995 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -165,7 +165,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, struct fileIdentDesc *fi = NULL; loff_t f_pos; int block, flen; - unsigned char *fname = NULL; + unsigned char *fname = NULL, *copy_name = NULL; unsigned char *nameptr; uint8_t lfi; uint16_t liu; @@ -236,7 +236,15 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi); else { - nameptr = fname; + if (!copy_name) { + copy_name = kmalloc(UDF_NAME_LEN, + GFP_NOFS); + if (!copy_name) { + fi = ERR_PTR(-ENOMEM); + goto out_err; + } + } + nameptr = copy_name; memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); memcpy(nameptr + lfi - poffset, @@ -279,6 +287,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, out_ok: brelse(epos.bh); kfree(fname); + kfree(copy_name); return fi; } -- GitLab From 9293fcfbc1812a22ad5ce1b542eb90c1bbe01be1 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Fri, 15 Jan 2016 02:44:22 -0600 Subject: [PATCH 0907/5324] udf: Remove struct ustr as non-needed intermediate storage Although 'struct ustr' tries to structurize the data by combining the string and its length, it doesn't actually make much benefit, since it saves only one parameter, but introduces an extra copying of the whole buffer, serving as an intermediate storage. It looks quite inefficient and not actually needed. This commit gets rid of the struct ustr by changing the parameters of some functions appropriately. Also, it removes using 'dstring' type, since it doesn't make much sense too. Just using the occasion, add a 'const' qualifier to udf_get_filename to make consistent parameters sets. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/super.c | 36 +++++------- fs/udf/udfdecl.h | 13 +---- fs/udf/unicode.c | 146 +++++++++++++++-------------------------------- 3 files changed, 61 insertions(+), 134 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index ffb35f7eab38..fa92fe839fda 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -887,18 +887,14 @@ static int udf_find_fileset(struct super_block *sb, static int udf_load_pvoldesc(struct super_block *sb, sector_t block) { struct primaryVolDesc *pvoldesc; - struct ustr *instr, *outstr; + uint8_t *outstr; struct buffer_head *bh; uint16_t ident; int ret = -ENOMEM; - instr = kmalloc(sizeof(struct ustr), GFP_NOFS); - if (!instr) - return -ENOMEM; - - outstr = kmalloc(sizeof(struct ustr), GFP_NOFS); + outstr = kmalloc(128, GFP_NOFS); if (!outstr) - goto out1; + return -ENOMEM; bh = udf_read_tagged(sb, block, block, &ident); if (!bh) { @@ -923,31 +919,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) #endif } - if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) { - ret = udf_CS0toUTF8(outstr, instr); - if (ret < 0) - goto out_bh; + ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32); + if (ret < 0) + goto out_bh; - strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, - outstr->u_len > 31 ? 31 : outstr->u_len); - udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); - } + strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); + udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident); - if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) { - ret = udf_CS0toUTF8(outstr, instr); - if (ret < 0) - goto out_bh; + ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128); + if (ret < 0) + goto out_bh; - udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); - } + outstr[ret] = 0; + udf_debug("volSetIdent[] = '%s'\n", outstr); ret = 0; out_bh: brelse(bh); out2: kfree(outstr); -out1: - kfree(instr); return ret; } diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 47a228248c5b..972b70625614 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -106,12 +106,6 @@ struct generic_desc { __le32 volDescSeqNum; }; -struct ustr { - uint8_t u_cmpID; - uint8_t u_name[UDF_NAME_LEN]; - uint8_t u_len; -}; - /* super.c */ @@ -214,12 +208,11 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, } /* unicode.c */ -extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, - int); +extern int udf_get_filename(struct super_block *, const uint8_t *, int, + uint8_t *, int); extern int udf_put_filename(struct super_block *, const uint8_t *, int, uint8_t *, int); -extern int udf_build_ustr(struct ustr *, dstring *, int); -extern int udf_CS0toUTF8(struct ustr *, const struct ustr *); +extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int); /* ialloc.c */ extern void udf_free_inode(struct inode *); diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index 5599e7535401..dc5990f4c952 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -28,53 +28,8 @@ #include "udf_sb.h" -static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, - int); - -static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) -{ - if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN)) - return 0; - - memset(dest, 0, sizeof(struct ustr)); - memcpy(dest->u_name, src, strlen); - dest->u_cmpID = 0x08; - dest->u_len = strlen; - - return strlen; -} - -/* - * udf_build_ustr - */ -int udf_build_ustr(struct ustr *dest, dstring *ptr, int size) -{ - int usesize; - - if (!dest || !ptr || !size) - return -1; - BUG_ON(size < 2); - - usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name)); - usesize = min(usesize, size - 2); - dest->u_cmpID = ptr[0]; - dest->u_len = usesize; - memcpy(dest->u_name, ptr + 1, usesize); - memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize); - - return 0; -} - -/* - * udf_build_ustr_exact - */ -static void udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize) -{ - memset(dest, 0, sizeof(struct ustr)); - dest->u_cmpID = ptr[0]; - dest->u_len = exactsize - 1; - memcpy(dest->u_name, ptr + 1, exactsize - 1); -} +static int udf_translate_to_linux(uint8_t *, int, const uint8_t *, int, + const uint8_t *, int); static int udf_uni2char_utf8(wchar_t uni, unsigned char *out, @@ -159,53 +114,50 @@ static int udf_char2uni_utf8(const unsigned char *in, return u_len; } -static int udf_name_from_CS0(struct ustr *utf_o, - const struct ustr *ocu_i, +static int udf_name_from_CS0(uint8_t *str_o, int str_max_len, + const uint8_t *ocu, int ocu_len, int (*conv_f)(wchar_t, unsigned char *, int)) { - const uint8_t *ocu; - uint8_t cmp_id, ocu_len; + uint8_t cmp_id; int i, len; + int str_o_len = 0; + if (str_max_len <= 0) + return 0; - ocu_len = ocu_i->u_len; if (ocu_len == 0) { - memset(utf_o, 0, sizeof(struct ustr)); + memset(str_o, 0, str_max_len); return 0; } - cmp_id = ocu_i->u_cmpID; + cmp_id = ocu[0]; if (cmp_id != 8 && cmp_id != 16) { - memset(utf_o, 0, sizeof(struct ustr)); - pr_err("unknown compression code (%d) stri=%s\n", - cmp_id, ocu_i->u_name); + memset(str_o, 0, str_max_len); + pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu); return -EINVAL; } - ocu = ocu_i->u_name; - utf_o->u_len = 0; - for (i = 0; (i < ocu_len) && (utf_o->u_len < UDF_NAME_LEN);) { + for (i = 1; (i < ocu_len) && (str_o_len < str_max_len);) { /* Expand OSTA compressed Unicode to Unicode */ uint32_t c = ocu[i++]; if (cmp_id == 16) c = (c << 8) | ocu[i++]; - len = conv_f(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - utf_o->u_len); + len = conv_f(c, &str_o[str_o_len], str_max_len - str_o_len); /* Valid character? */ if (len >= 0) - utf_o->u_len += len; + str_o_len += len; else if (len == -ENAMETOOLONG) break; else - utf_o->u_name[utf_o->u_len++] = '?'; + str_o[str_o_len++] = '?'; } - utf_o->u_cmpID = 8; - return utf_o->u_len; + return str_o_len; } -static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length, +static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len, + const uint8_t *str_i, int str_len, int (*conv_f)(const unsigned char *, int, wchar_t *)) { int i, len; @@ -213,18 +165,21 @@ static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length, wchar_t uni_char; int u_len, u_ch; - memset(ocu, 0, sizeof(dstring) * length); + if (ocu_max_len <= 0) + return 0; + + memset(ocu, 0, ocu_max_len); ocu[0] = 8; max_val = 0xff; u_ch = 1; try_again: - u_len = 0; - for (i = 0; i < uni->u_len; i++) { + u_len = 1; + for (i = 0; i < str_len; i++) { /* Name didn't fit? */ - if (u_len + 1 + u_ch >= length) + if (u_len + u_ch > ocu_max_len) return 0; - len = conv_f(&uni->u_name[i], uni->u_len - i, &uni_char); + len = conv_f(&str_i[i], str_len - i, &uni_char); if (!len) continue; /* Invalid character, deal with it */ @@ -241,41 +196,37 @@ static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length, } if (max_val == 0xffff) - ocu[++u_len] = (uint8_t)(uni_char >> 8); - ocu[++u_len] = (uint8_t)(uni_char & 0xff); + ocu[u_len++] = (uint8_t)(uni_char >> 8); + ocu[u_len++] = (uint8_t)(uni_char & 0xff); i += len - 1; } - ocu[length - 1] = (uint8_t)u_len + 1; - return u_len + 1; + return u_len; } -int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) +int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len) { - return udf_name_from_CS0(utf_o, ocu_i, udf_uni2char_utf8); + return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len, + udf_uni2char_utf8); } -int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, +int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen, uint8_t *dname, int dlen) { - struct ustr *filename, *unifilename; + uint8_t *filename; int (*conv_f)(wchar_t, unsigned char *, int); int ret; if (!slen) return -EIO; - filename = kmalloc(sizeof(struct ustr), GFP_NOFS); + if (dlen <= 0) + return 0; + + filename = kmalloc(dlen, GFP_NOFS); if (!filename) return -ENOMEM; - unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS); - if (!unifilename) { - ret = -ENOMEM; - goto out1; - } - - udf_build_ustr_exact(unifilename, sname, slen); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { conv_f = udf_uni2char_utf8; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { @@ -283,21 +234,18 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, } else BUG(); - ret = udf_name_from_CS0(filename, unifilename, conv_f); + ret = udf_name_from_CS0(filename, dlen, sname, slen, conv_f); if (ret < 0) { udf_debug("Failed in udf_get_filename: sname = %s\n", sname); goto out2; } - ret = udf_translate_to_linux(dname, dlen, - filename->u_name, filename->u_len, - unifilename->u_name, unifilename->u_len); + ret = udf_translate_to_linux(dname, dlen, filename, dlen, + sname + 1, slen - 1); /* Zero length filename isn't valid... */ if (ret == 0) ret = -EINVAL; out2: - kfree(unifilename); -out1: kfree(filename); return ret; } @@ -305,12 +253,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, uint8_t *dname, int dlen) { - struct ustr unifilename; int (*conv_f)(const unsigned char *, int, wchar_t *); - if (!udf_char_to_ustr(&unifilename, sname, slen)) - return 0; - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { conv_f = udf_char2uni_utf8; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { @@ -318,7 +262,7 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, } else BUG(); - return udf_name_to_CS0(dname, &unifilename, dlen, conv_f); + return udf_name_to_CS0(dname, dlen, sname, slen, conv_f); } #define ILLEGAL_CHAR_MARK '_' @@ -329,8 +273,8 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, #define CRC_LEN 5 static int udf_translate_to_linux(uint8_t *newName, int newLen, - uint8_t *udfName, int udfLen, - uint8_t *fidName, int fidNameLen) + const uint8_t *udfName, int udfLen, + const uint8_t *fidName, int fidNameLen) { int index, newIndex = 0, needsCRC = 0; int extIndex = 0, newExtIndex = 0, hasExt = 0; -- GitLab From 484a10f49387e4386bf2708532e75bf78ffea2cb Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Fri, 15 Jan 2016 02:44:23 -0600 Subject: [PATCH 0908/5324] udf: Merge linux specific translation into CS0 conversion function Current implementation of udf_translate_to_linux function does not support multi-bytes characters at all: it counts bytes while calculating extension length, when inserting CRC inside the name it doesn't take into account inter-character boundaries and can break into the middle of the character. The most efficient way to properly support multi-bytes characters is merging of translation operations directly into conversion function. This can help to avoid extra passes along the string or parsing the multi-bytes character back into unicode to find out it's length. Signed-off-by: Andrew Gabbasov Signed-off-by: Jan Kara --- fs/udf/unicode.c | 280 +++++++++++++++++++++++++---------------------- 1 file changed, 152 insertions(+), 128 deletions(-) diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index dc5990f4c952..3ff42f4437f3 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c @@ -28,9 +28,6 @@ #include "udf_sb.h" -static int udf_translate_to_linux(uint8_t *, int, const uint8_t *, int, - const uint8_t *, int); - static int udf_uni2char_utf8(wchar_t uni, unsigned char *out, int boundlen) @@ -114,13 +111,83 @@ static int udf_char2uni_utf8(const unsigned char *in, return u_len; } +#define ILLEGAL_CHAR_MARK '_' +#define EXT_MARK '.' +#define CRC_MARK '#' +#define EXT_SIZE 5 +/* Number of chars we need to store generated CRC to make filename unique */ +#define CRC_LEN 5 + +static int udf_name_conv_char(uint8_t *str_o, int str_o_max_len, + int *str_o_idx, + const uint8_t *str_i, int str_i_max_len, + int *str_i_idx, + int u_ch, int *needsCRC, + int (*conv_f)(wchar_t, unsigned char *, int), + int translate) +{ + uint32_t c; + int illChar = 0; + int len, gotch = 0; + + for (; (!gotch) && (*str_i_idx < str_i_max_len); *str_i_idx += u_ch) { + if (*str_o_idx >= str_o_max_len) { + *needsCRC = 1; + return gotch; + } + + /* Expand OSTA compressed Unicode to Unicode */ + c = str_i[*str_i_idx]; + if (u_ch > 1) + c = (c << 8) | str_i[*str_i_idx + 1]; + + if (translate && (c == '/' || c == 0)) + illChar = 1; + else if (illChar) + break; + else + gotch = 1; + } + if (illChar) { + *needsCRC = 1; + c = ILLEGAL_CHAR_MARK; + gotch = 1; + } + if (gotch) { + len = conv_f(c, &str_o[*str_o_idx], str_o_max_len - *str_o_idx); + /* Valid character? */ + if (len >= 0) + *str_o_idx += len; + else if (len == -ENAMETOOLONG) { + *needsCRC = 1; + gotch = 0; + } else { + str_o[(*str_o_idx)++] = '?'; + *needsCRC = 1; + } + } + return gotch; +} + static int udf_name_from_CS0(uint8_t *str_o, int str_max_len, const uint8_t *ocu, int ocu_len, - int (*conv_f)(wchar_t, unsigned char *, int)) + int (*conv_f)(wchar_t, unsigned char *, int), + int translate) { + uint32_t c; uint8_t cmp_id; - int i, len; - int str_o_len = 0; + int idx, len; + int u_ch; + int needsCRC = 0; + int ext_i_len, ext_max_len; + int str_o_len = 0; /* Length of resulting output */ + int ext_o_len = 0; /* Extension output length */ + int ext_crc_len = 0; /* Extension output length if used with CRC */ + int i_ext = -1; /* Extension position in input buffer */ + int o_crc = 0; /* Rightmost possible output pos for CRC+ext */ + unsigned short valueCRC; + uint8_t ext[EXT_SIZE * NLS_MAX_CHARSET_SIZE + 1]; + uint8_t crc[CRC_LEN]; if (str_max_len <= 0) return 0; @@ -133,24 +200,88 @@ static int udf_name_from_CS0(uint8_t *str_o, int str_max_len, cmp_id = ocu[0]; if (cmp_id != 8 && cmp_id != 16) { memset(str_o, 0, str_max_len); - pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu); + pr_err("unknown compression code (%d)\n", cmp_id); return -EINVAL; } + u_ch = cmp_id >> 3; - for (i = 1; (i < ocu_len) && (str_o_len < str_max_len);) { - /* Expand OSTA compressed Unicode to Unicode */ - uint32_t c = ocu[i++]; - if (cmp_id == 16) - c = (c << 8) | ocu[i++]; + ocu++; + ocu_len--; - len = conv_f(c, &str_o[str_o_len], str_max_len - str_o_len); - /* Valid character? */ - if (len >= 0) - str_o_len += len; - else if (len == -ENAMETOOLONG) + if (ocu_len % u_ch) { + pr_err("incorrect filename length (%d)\n", ocu_len + 1); + return -EINVAL; + } + + if (translate) { + /* Look for extension */ + for (idx = ocu_len - u_ch, ext_i_len = 0; + (idx >= 0) && (ext_i_len < EXT_SIZE); + idx -= u_ch, ext_i_len++) { + c = ocu[idx]; + if (u_ch > 1) + c = (c << 8) | ocu[idx + 1]; + + if (c == EXT_MARK) { + if (ext_i_len) + i_ext = idx; + break; + } + } + if (i_ext >= 0) { + /* Convert extension */ + ext_max_len = min_t(int, sizeof(ext), str_max_len); + ext[ext_o_len++] = EXT_MARK; + idx = i_ext + u_ch; + while (udf_name_conv_char(ext, ext_max_len, &ext_o_len, + ocu, ocu_len, &idx, + u_ch, &needsCRC, + conv_f, translate)) { + if ((ext_o_len + CRC_LEN) < str_max_len) + ext_crc_len = ext_o_len; + } + } + } + + idx = 0; + while (1) { + if (translate && (idx == i_ext)) { + if (str_o_len > (str_max_len - ext_o_len)) + needsCRC = 1; break; - else - str_o[str_o_len++] = '?'; + } + + if (!udf_name_conv_char(str_o, str_max_len, &str_o_len, + ocu, ocu_len, &idx, + u_ch, &needsCRC, conv_f, translate)) + break; + + if (translate && + (str_o_len <= (str_max_len - ext_o_len - CRC_LEN))) + o_crc = str_o_len; + } + + if (translate) { + if (str_o_len <= 2 && str_o[0] == '.' && + (str_o_len == 1 || str_o[1] == '.')) + needsCRC = 1; + if (needsCRC) { + str_o_len = o_crc; + valueCRC = crc_itu_t(0, ocu, ocu_len); + crc[0] = CRC_MARK; + crc[1] = hex_asc_upper_hi(valueCRC >> 8); + crc[2] = hex_asc_upper_lo(valueCRC >> 8); + crc[3] = hex_asc_upper_hi(valueCRC); + crc[4] = hex_asc_upper_lo(valueCRC); + len = min_t(int, CRC_LEN, str_max_len - str_o_len); + memcpy(&str_o[str_o_len], crc, len); + str_o_len += len; + ext_o_len = ext_crc_len; + } + if (ext_o_len > 0) { + memcpy(&str_o[str_o_len], ext, ext_o_len); + str_o_len += ext_o_len; + } } return str_o_len; @@ -207,13 +338,12 @@ static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len, int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len) { return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len, - udf_uni2char_utf8); + udf_uni2char_utf8, 0); } int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen, uint8_t *dname, int dlen) { - uint8_t *filename; int (*conv_f)(wchar_t, unsigned char *, int); int ret; @@ -223,10 +353,6 @@ int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen, if (dlen <= 0) return 0; - filename = kmalloc(dlen, GFP_NOFS); - if (!filename) - return -ENOMEM; - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { conv_f = udf_uni2char_utf8; } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { @@ -234,19 +360,10 @@ int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen, } else BUG(); - ret = udf_name_from_CS0(filename, dlen, sname, slen, conv_f); - if (ret < 0) { - udf_debug("Failed in udf_get_filename: sname = %s\n", sname); - goto out2; - } - - ret = udf_translate_to_linux(dname, dlen, filename, dlen, - sname + 1, slen - 1); + ret = udf_name_from_CS0(dname, dlen, sname, slen, conv_f, 1); /* Zero length filename isn't valid... */ if (ret == 0) ret = -EINVAL; -out2: - kfree(filename); return ret; } @@ -265,96 +382,3 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, return udf_name_to_CS0(dname, dlen, sname, slen, conv_f); } -#define ILLEGAL_CHAR_MARK '_' -#define EXT_MARK '.' -#define CRC_MARK '#' -#define EXT_SIZE 5 -/* Number of chars we need to store generated CRC to make filename unique */ -#define CRC_LEN 5 - -static int udf_translate_to_linux(uint8_t *newName, int newLen, - const uint8_t *udfName, int udfLen, - const uint8_t *fidName, int fidNameLen) -{ - int index, newIndex = 0, needsCRC = 0; - int extIndex = 0, newExtIndex = 0, hasExt = 0; - unsigned short valueCRC; - uint8_t curr; - - if (udfName[0] == '.' && - (udfLen == 1 || (udfLen == 2 && udfName[1] == '.'))) { - needsCRC = 1; - newIndex = udfLen; - memcpy(newName, udfName, udfLen); - } else { - for (index = 0; index < udfLen; index++) { - curr = udfName[index]; - if (curr == '/' || curr == 0) { - needsCRC = 1; - curr = ILLEGAL_CHAR_MARK; - while (index + 1 < udfLen && - (udfName[index + 1] == '/' || - udfName[index + 1] == 0)) - index++; - } - if (curr == EXT_MARK && - (udfLen - index - 1) <= EXT_SIZE) { - if (udfLen == index + 1) - hasExt = 0; - else { - hasExt = 1; - extIndex = index; - newExtIndex = newIndex; - } - } - if (newIndex < newLen) - newName[newIndex++] = curr; - else - needsCRC = 1; - } - } - if (needsCRC) { - uint8_t ext[EXT_SIZE]; - int localExtIndex = 0; - - if (hasExt) { - int maxFilenameLen; - for (index = 0; - index < EXT_SIZE && extIndex + index + 1 < udfLen; - index++) { - curr = udfName[extIndex + index + 1]; - - if (curr == '/' || curr == 0) { - needsCRC = 1; - curr = ILLEGAL_CHAR_MARK; - while (extIndex + index + 2 < udfLen && - (index + 1 < EXT_SIZE && - (udfName[extIndex + index + 2] == '/' || - udfName[extIndex + index + 2] == 0))) - index++; - } - ext[localExtIndex++] = curr; - } - maxFilenameLen = newLen - CRC_LEN - localExtIndex; - if (newIndex > maxFilenameLen) - newIndex = maxFilenameLen; - else - newIndex = newExtIndex; - } else if (newIndex > newLen - CRC_LEN) - newIndex = newLen - CRC_LEN; - newName[newIndex++] = CRC_MARK; - valueCRC = crc_itu_t(0, fidName, fidNameLen); - newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); - newName[newIndex++] = hex_asc_upper_lo(valueCRC >> 8); - newName[newIndex++] = hex_asc_upper_hi(valueCRC); - newName[newIndex++] = hex_asc_upper_lo(valueCRC); - - if (hasExt) { - newName[newIndex++] = EXT_MARK; - for (index = 0; index < localExtIndex; index++) - newName[newIndex++] = ext[index]; - } - } - - return newIndex; -} -- GitLab From be6257b251cebd2deb8c76d43e387e28e3f7412d Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 25 Jan 2016 19:24:50 +0100 Subject: [PATCH 0909/5324] quota: Add support for ->get_nextdqblk() for VFS quota Add infrastructure for supporting get_nextdqblk() callback for VFS quotas. Translate the operation into a callback to appropriate filesystem and consequently to quota format callback. Signed-off-by: Jan Kara --- fs/ext4/super.c | 1 + fs/quota/dquot.c | 39 +++++++++++++++++++++++++++++++++++++++ fs/reiserfs/super.c | 1 + include/linux/quota.h | 3 +++ include/linux/quotaops.h | 3 +++ 5 files changed, 47 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3ed01ec011d7..b5bcbddceb91 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1132,6 +1132,7 @@ static const struct dquot_operations ext4_quota_operations = { .alloc_dquot = dquot_alloc, .destroy_dquot = dquot_destroy, .get_projid = ext4_get_projid, + .get_next_id = dquot_get_next_id, }; static const struct quotactl_ops ext4_qctl_operations = { diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 3c3b81bb6dfe..7e0137bde6d6 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2031,6 +2031,21 @@ int dquot_commit_info(struct super_block *sb, int type) } EXPORT_SYMBOL(dquot_commit_info); +int dquot_get_next_id(struct super_block *sb, struct kqid *qid) +{ + struct quota_info *dqopt = sb_dqopt(sb); + int err; + + if (!dqopt->ops[qid->type]->get_next_id) + return -ENOSYS; + mutex_lock(&dqopt->dqio_mutex); + err = dqopt->ops[qid->type]->get_next_id(sb, qid); + mutex_unlock(&dqopt->dqio_mutex); + + return err; +} +EXPORT_SYMBOL(dquot_get_next_id); + /* * Definitions of diskquota operations. */ @@ -2042,6 +2057,7 @@ const struct dquot_operations dquot_operations = { .write_info = dquot_commit_info, .alloc_dquot = dquot_alloc, .destroy_dquot = dquot_destroy, + .get_next_id = dquot_get_next_id, }; EXPORT_SYMBOL(dquot_operations); @@ -2565,6 +2581,27 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid, } EXPORT_SYMBOL(dquot_get_dqblk); +int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid, + struct qc_dqblk *di) +{ + struct dquot *dquot; + int err; + + if (!sb->dq_op->get_next_id) + return -ENOSYS; + err = sb->dq_op->get_next_id(sb, qid); + if (err < 0) + return err; + dquot = dqget(sb, *qid); + if (IS_ERR(dquot)) + return PTR_ERR(dquot); + do_get_dqblk(dquot, di); + dqput(dquot); + + return 0; +} +EXPORT_SYMBOL(dquot_get_next_dqblk); + #define VFS_QC_MASK \ (QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \ QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \ @@ -2765,6 +2802,7 @@ const struct quotactl_ops dquot_quotactl_ops = { .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, + .get_nextdqblk = dquot_get_next_dqblk, .set_dqblk = dquot_set_dqblk }; EXPORT_SYMBOL(dquot_quotactl_ops); @@ -2776,6 +2814,7 @@ const struct quotactl_ops dquot_quotactl_sysfile_ops = { .get_state = dquot_get_state, .set_info = dquot_set_dqinfo, .get_dqblk = dquot_get_dqblk, + .get_nextdqblk = dquot_get_next_dqblk, .set_dqblk = dquot_set_dqblk }; EXPORT_SYMBOL(dquot_quotactl_sysfile_ops); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c0306ec8ed7b..b8f2d1e8c645 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -802,6 +802,7 @@ static const struct dquot_operations reiserfs_quota_operations = { .write_info = reiserfs_write_info, .alloc_dquot = dquot_alloc, .destroy_dquot = dquot_destroy, + .get_next_id = dquot_get_next_id, }; static const struct quotactl_ops reiserfs_qctl_operations = { diff --git a/include/linux/quota.h b/include/linux/quota.h index fba92f5c1a63..9dfb6bce8c9e 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -306,6 +306,7 @@ struct quota_format_ops { int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */ int (*commit_dqblk)(struct dquot *dquot); /* Write structure for one user */ int (*release_dqblk)(struct dquot *dquot); /* Called when last reference to dquot is being dropped */ + int (*get_next_id)(struct super_block *sb, struct kqid *qid); /* Get next ID with existing structure in the quota file */ }; /* Operations working with dquots */ @@ -321,6 +322,8 @@ struct dquot_operations { * quota code only */ qsize_t *(*get_reserved_space) (struct inode *); int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */ + /* Get next ID with active quota structure */ + int (*get_next_id) (struct super_block *sb, struct kqid *qid); }; struct path; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 7a57c28eb5e7..f00fa86ac966 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -82,6 +82,7 @@ int dquot_commit(struct dquot *dquot); int dquot_acquire(struct dquot *dquot); int dquot_release(struct dquot *dquot); int dquot_commit_info(struct super_block *sb, int type); +int dquot_get_next_id(struct super_block *sb, struct kqid *qid); int dquot_mark_dquot_dirty(struct dquot *dquot); int dquot_file_open(struct inode *inode, struct file *file); @@ -99,6 +100,8 @@ int dquot_get_state(struct super_block *sb, struct qc_state *state); int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii); int dquot_get_dqblk(struct super_block *sb, struct kqid id, struct qc_dqblk *di); +int dquot_get_next_dqblk(struct super_block *sb, struct kqid *id, + struct qc_dqblk *di); int dquot_set_dqblk(struct super_block *sb, struct kqid id, struct qc_dqblk *di); -- GitLab From 0066373d9f9320f69f24b080ee00d10f14397355 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 25 Jan 2016 20:39:27 +0100 Subject: [PATCH 0910/5324] quota_v2: Implement get_next_id() for V2 quota format Implement functions to get id of next existing quota structure in quota file for quota tree based formats and thus for V2 quota format. Signed-off-by: Jan Kara --- fs/quota/quota_tree.c | 67 +++++++++++++++++++++++++++++++++++-- fs/quota/quota_v2.c | 6 ++++ include/linux/dqblk_qtree.h | 2 ++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index 58efb83dec1c..0738972e8d3f 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -22,10 +22,9 @@ MODULE_LICENSE("GPL"); #define __QUOTA_QT_PARANOIA -static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth) +static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) { unsigned int epb = info->dqi_usable_bs >> 2; - qid_t id = from_kqid(&init_user_ns, qid); depth = info->dqi_qtree_depth - depth - 1; while (depth--) @@ -33,6 +32,13 @@ static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth) return id % epb; } +static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth) +{ + qid_t id = from_kqid(&init_user_ns, qid); + + return __get_index(info, id, depth); +} + /* Number of entries in one blocks */ static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info) { @@ -668,3 +674,60 @@ int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) return 0; } EXPORT_SYMBOL(qtree_release_dquot); + +static int find_next_id(struct qtree_mem_dqinfo *info, qid_t *id, + unsigned int blk, int depth) +{ + char *buf = getdqbuf(info->dqi_usable_bs); + __le32 *ref = (__le32 *)buf; + ssize_t ret; + unsigned int epb = info->dqi_usable_bs >> 2; + unsigned int level_inc = 1; + int i; + + if (!buf) + return -ENOMEM; + + for (i = depth; i < info->dqi_qtree_depth - 1; i++) + level_inc *= epb; + + ret = read_blk(info, blk, buf); + if (ret < 0) { + quota_error(info->dqi_sb, + "Can't read quota tree block %u", blk); + goto out_buf; + } + for (i = __get_index(info, *id, depth); i < epb; i++) { + if (ref[i] == cpu_to_le32(0)) { + *id += level_inc; + continue; + } + if (depth == info->dqi_qtree_depth - 1) { + ret = 0; + goto out_buf; + } + ret = find_next_id(info, id, le32_to_cpu(ref[i]), depth + 1); + if (ret != -ENOENT) + break; + } + if (i == epb) { + ret = -ENOENT; + goto out_buf; + } +out_buf: + kfree(buf); + return ret; +} + +int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid) +{ + qid_t id = from_kqid(&init_user_ns, *qid); + int ret; + + ret = find_next_id(info, &id, QT_TREEOFF, 0); + if (ret < 0) + return ret; + *qid = make_kqid(&init_user_ns, qid->type, id); + return 0; +} +EXPORT_SYMBOL(qtree_get_next_id); diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index ed85d4f35c04..ca71bf881ad1 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -304,6 +304,11 @@ static int v2_free_file_info(struct super_block *sb, int type) return 0; } +static int v2_get_next_id(struct super_block *sb, struct kqid *qid) +{ + return qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid); +} + static const struct quota_format_ops v2_format_ops = { .check_quota_file = v2_check_quota_file, .read_file_info = v2_read_file_info, @@ -312,6 +317,7 @@ static const struct quota_format_ops v2_format_ops = { .read_dqblk = v2_read_dquot, .commit_dqblk = v2_write_dquot, .release_dqblk = v2_release_dquot, + .get_next_id = v2_get_next_id, }; static struct quota_format_type v2r0_quota_format = { diff --git a/include/linux/dqblk_qtree.h b/include/linux/dqblk_qtree.h index ff8b55359648..0de21e935976 100644 --- a/include/linux/dqblk_qtree.h +++ b/include/linux/dqblk_qtree.h @@ -15,6 +15,7 @@ #define QTREE_DEL_REWRITE 6 struct dquot; +struct kqid; /* Operations */ struct qtree_fmt_operations { @@ -52,5 +53,6 @@ static inline int qtree_depth(struct qtree_mem_dqinfo *info) entries *= epb; return i; } +int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid); #endif /* _LINUX_DQBLK_QTREE_H */ -- GitLab From 5a9530e498ed25173d426cd93e31a04468d0dc24 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 4 Feb 2016 14:50:26 +0100 Subject: [PATCH 0911/5324] ocfs2: Implement get_next_id() Implement get_next_id() callback to enable use of Q_GETNEXTQUOTA quotactl for OCFS2. Signed-off-by: Jan Kara --- fs/ocfs2/ocfs2_trace.h | 2 ++ fs/ocfs2/quota_global.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/fs/ocfs2/ocfs2_trace.h b/fs/ocfs2/ocfs2_trace.h index 6cb019b7c6a8..a52a2dbc064e 100644 --- a/fs/ocfs2/ocfs2_trace.h +++ b/fs/ocfs2/ocfs2_trace.h @@ -2035,6 +2035,8 @@ DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_release_dquot); DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_acquire_dquot); +DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_get_next_id); + DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_mark_dquot_dirty); /* End of trace events for fs/ocfs2/quota_global.c. */ diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 9c9dd30bc945..91bc674203ed 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -860,6 +860,30 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) return status; } +static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid) +{ + int type = qid->type; + struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; + int status = 0; + + trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type); + status = ocfs2_lock_global_qf(info, 0); + if (status < 0) + goto out; + status = ocfs2_qinfo_lock(info, 0); + if (status < 0) + goto out_global; + status = qtree_get_next_id(&info->dqi_gi, qid); + ocfs2_qinfo_unlock(info, 0); +out_global: + ocfs2_unlock_global_qf(info, 0); +out: + /* Avoid logging ENOENT since it just means there isn't next ID */ + if (status && status != -ENOENT) + mlog_errno(status); + return status; +} + static int ocfs2_mark_dquot_dirty(struct dquot *dquot) { unsigned long mask = (1 << (DQ_LASTSET_B + QIF_ILIMITS_B)) | @@ -968,4 +992,5 @@ const struct dquot_operations ocfs2_quota_operations = { .write_info = ocfs2_write_info, .alloc_dquot = ocfs2_alloc_dquot, .destroy_dquot = ocfs2_destroy_dquot, + .get_next_id = ocfs2_get_next_id, }; -- GitLab From b977025153a6f43ec5070d2f7a26f2ecb22c0319 Mon Sep 17 00:00:00 2001 From: Nathan Rossi Date: Wed, 3 Feb 2016 22:41:05 +1000 Subject: [PATCH 0912/5324] ARM: dts: zynq: Enable USB and USB PHY for ZYBO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setup the USB controller and configure it to operate in host mode. Additionally add the USB phy node for the ZYBO, including reset gpio which is connected to a external MIO pin. Signed-off-by: Nathan Rossi Cc: Rob Herring Cc: Mark Rutland Cc: Michal Simek Cc: Sören Brinkmann Signed-off-by: Michal Simek --- arch/arm/boot/dts/zynq-zybo.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts index 16c9cacd668d..8f085b3d23cd 100644 --- a/arch/arm/boot/dts/zynq-zybo.dts +++ b/arch/arm/boot/dts/zynq-zybo.dts @@ -33,6 +33,11 @@ stdout-path = "serial0:115200n8"; }; + usb_phy0: phy0 { + #phy-cells = <0>; + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio0 46 1>; + }; }; &clkc { @@ -56,3 +61,9 @@ &uart1 { status = "okay"; }; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; -- GitLab From af3997b569dbd2ff50318c874fa4618d8b628fb0 Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Fri, 5 Feb 2016 13:29:28 +0200 Subject: [PATCH 0913/5324] drm/i915: Skip DDI PLL selection for DSI Skip DDI PLL selection if display type is DSI/MIPI. Signed-off-by: Mika Kahola Reviewed-by: Sivakumar Thulasimani Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1454671768-27062-1-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_display.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5bc9a364b04a..76421c962216 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9848,8 +9848,13 @@ static void broadwell_modeset_commit_cdclk(struct drm_atomic_state *old_state) static int haswell_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { - if (!intel_ddi_pll_select(crtc, crtc_state)) - return -EINVAL; + struct intel_encoder *intel_encoder = + intel_ddi_get_crtc_new_encoder(crtc_state); + + if (intel_encoder->type != INTEL_OUTPUT_DSI) { + if (!intel_ddi_pll_select(crtc, crtc_state)) + return -EINVAL; + } crtc->lowfreq_avail = false; -- GitLab From 44084efc2fd804e3b40159a19e1c4874f56f73ab Mon Sep 17 00:00:00 2001 From: Insu Yun Date: Thu, 28 Jan 2016 18:54:36 -0500 Subject: [PATCH 0914/5324] ch7006: correctly handling failed allocation Since drm_property_create_range can be failed in memory pressure, it needs to be checked and return -ENOMEM. Signed-off-by: Insu Yun Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454025276-13465-1-git-send-email-wuninsu@gmail.com --- drivers/gpu/drm/i2c/ch7006_drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 90db5f4dcce5..0594c45f7164 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -253,6 +253,8 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder, drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); + if (!priv->scale_property) + return -ENOMEM; drm_object_attach_property(&connector->base, conf->tv_select_subconnector_property, priv->select_subconnector); -- GitLab From 67fe85dd6df202d66a46054486d2b339ebed84c4 Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Thu, 4 Feb 2016 15:03:52 +0100 Subject: [PATCH 0915/5324] drm: modes: add missing [drm] to message printing The warning message in drm_mode_parse_command_line_for_connector miss the [drm] at beginning. This patch add it and take the opportunity to convert printk(KERN_WARNING to pr_warn() Signed-off-by: LABBE Corentin Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454594633-15100-1-git-send-email-clabbe.montjoie@gmail.com --- drivers/gpu/drm/drm_modes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 20775c05235a..f7448a5e95a9 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1371,8 +1371,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, } done: if (i >= 0) { - printk(KERN_WARNING - "parse error at position %i in video mode '%s'\n", + pr_warn("[drm] parse error at position %i in video mode '%s'\n", i, name); mode->specified = false; return false; -- GitLab From e9f8250f2f92b0e087aef84a33014372375c73db Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Fri, 5 Feb 2016 13:57:43 -0800 Subject: [PATCH 0916/5324] drm/msm: remove the drm_device_is_unplugged check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag is only used for drm/udl. Signed-off-by: Haixia Shi Reviewed-by: Stéphane Marchesin Reviewed-by: David Herrmann Acked-by: Rob Clark Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454709464-2536-1-git-send-email-hshi@chromium.org --- drivers/gpu/drm/msm/msm_fbdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d95af6eba602..e119c2979509 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -65,9 +65,6 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma) struct drm_device *dev = helper->dev; int ret = 0; - if (drm_device_is_unplugged(dev)) - return -ENODEV; - ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma); if (ret) { pr_err("%s:drm_gem_mmap_obj fail\n", __func__); -- GitLab From 4c61716c2bfaaf1b8837a67775662008b4f42225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 9 Feb 2016 17:29:44 +0200 Subject: [PATCH 0917/5324] drm: Add drm_format_plane_width() and drm_format_plane_height() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a few helpers to get the dimensions of the chroma plane(s). v2: Add kernel-doc (Daniel) v3: Fix kerneldoc "Returns:" style (Daniel) Uninline the functions and check for num_planes (Daniel) v4: Add the required EXPORT_SYMBOL()s Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1455031784-10941-1-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_crtc.c | 42 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4132d58dab93..65258acddb90 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -5737,6 +5737,48 @@ int drm_format_vert_chroma_subsampling(uint32_t format) } EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); +/** + * drm_format_plane_width - width of the plane given the first plane + * @width: width of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The width of @plane, given that the width of the first plane is @width. + */ +int drm_format_plane_width(int width, uint32_t format, int plane) +{ + if (plane >= drm_format_num_planes(format)) + return 0; + + if (plane == 0) + return width; + + return width / drm_format_horz_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_width); + +/** + * drm_format_plane_height - height of the plane given the first plane + * @height: height of the first plane + * @format: pixel format + * @plane: plane index + * + * Returns: + * The height of @plane, given that the height of the first plane is @height. + */ +int drm_format_plane_height(int height, uint32_t format, int plane) +{ + if (plane >= drm_format_num_planes(format)) + return 0; + + if (plane == 0) + return height; + + return height / drm_format_vert_chroma_subsampling(format); +} +EXPORT_SYMBOL(drm_format_plane_height); + /** * drm_rotation_simplify() - Try to simplify the rotation * @rotation: Rotation to be simplified diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ad53d2ffd48c..8c7fb3d0f9d0 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -2498,6 +2498,8 @@ extern int drm_format_num_planes(uint32_t format); extern int drm_format_plane_cpp(uint32_t format, int plane); extern int drm_format_horz_chroma_subsampling(uint32_t format); extern int drm_format_vert_chroma_subsampling(uint32_t format); +extern int drm_format_plane_width(int width, uint32_t format, int plane); +extern int drm_format_plane_height(int height, uint32_t format, int plane); extern const char *drm_get_format_name(uint32_t format); extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, unsigned int supported_rotations); -- GitLab From 2430a94d1e719b7b4af2a65b781a4c036eb22e64 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 9 Feb 2016 20:19:14 +0900 Subject: [PATCH 0918/5324] clk: fix __clk_init_parent() for single parent clocks Before commit b3d192d5121f ("clk: simplify __clk_init_parent()"), __clk_init_parent() called .get_parent() only for multi-parent clocks. That commit changed the behavior to call .get_parent() if available even for single-parent clocks and root clocks. It turned out a problem because there are some single-parent clocks that implement .get_parent() callback and return non-zero index. The SOCFPGA clock is the case; the commit broke the SOCFPGA boards. To keep the original behavior, invoke .get_parent() only when num_parents is greater than 1. Fixes: b3d192d5121f ("clk: simplify __clk_init_parent()") Signed-off-by: Masahiro Yamada Reported-by: Dinh Nguyen Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index cd8382c83f48..67cd2f116c3b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1662,7 +1662,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) { u8 index = 0; - if (core->ops->get_parent) + if (core->num_parents > 1 && core->ops->get_parent) index = core->ops->get_parent(core->hw); return clk_core_get_parent_by_index(core, index); -- GitLab From 3d0ddadbe6dde5639f565e3456ae112679e288af Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 9 Feb 2016 23:31:27 +0800 Subject: [PATCH 0919/5324] ARM: sunxi_defconfig: Enable MUSB HDRC driver with Allwinner glue Allwinner SoCs typically have a Mentor Graphics Inventra MUSB dual role controller for USB OTG. Now that the issue with MUSB and USB gadget registration order has been resolved, we can enable this driver in dual role mode. This requires the NOP USB transceiver driver, which is also enabled. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index a55c48e27309..81a1b92fd4e6 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -110,6 +110,10 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SUNXI=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_SUNXI=y CONFIG_NEW_LEDS=y -- GitLab From bd10bce87820fa3af9ee160c31723958af7df0ba Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Tue, 9 Feb 2016 10:25:32 +0100 Subject: [PATCH 0920/5324] ARM: dts: sun7i: Enable USB DRC on MK808C Enable the otg/drc usb controller on the MK808C. Signed-off-by: Marcus Cooper Signed-off-by: Maxime Ripard Reviewed-by: Hans de Goede --- arch/arm/boot/dts/sun7i-a20-mk808c.dts | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20-mk808c.dts b/arch/arm/boot/dts/sun7i-a20-mk808c.dts index c9e648d17a1e..90ff4a267025 100644 --- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts +++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts @@ -53,6 +53,7 @@ #include #include +#include / { model = "mk808c"; @@ -125,6 +126,30 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + +&pio { + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_usb1_vbus { status = "okay"; }; @@ -145,7 +170,17 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; -- GitLab From d3e84a93184137951241f71f8696bddc8b32b36c Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Tue, 9 Feb 2016 10:33:28 +0100 Subject: [PATCH 0921/5324] ARM: dts: sun7i: Enable USB DRC on Olimex A20 EVB Enable the otg/drc usb controller on the Olimex A20 EVB. Signed-off-by: Marcus Cooper Signed-off-by: Maxime Ripard Reviewed-by: Hans de Goede --- .../arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts index c3c626b2cfa2..23aacce4d6c7 100644 --- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts @@ -198,6 +198,10 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + &pio { ahci_pwr_pin_olimex_som_evb: ahci_pwr_pin@1 { allwinner,pins = "PC3"; @@ -219,6 +223,20 @@ allwinner,drive = ; allwinner,pull = ; }; + + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; }; ®_ahci_5v { @@ -254,6 +272,10 @@ regulator-name = "avcc"; }; +®_usb0_vbus { + status = "okay"; +}; + ®_usb1_vbus { status = "okay"; }; @@ -268,7 +290,17 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH04 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH05 */ + usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; -- GitLab From 16af4e9705b1dee1a5b2e5d82632b584399fdf6d Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 28 Jan 2016 10:29:35 +0900 Subject: [PATCH 0922/5324] ARM: dts: r7s72100: use GIC_* defines Use GIC_* defines for GIC interrupt cells in r7s72100 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/r7s72100.dtsi | 161 ++++++++++++++++---------------- 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 4657d7fb5bce..a5938c72d5bd 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -10,6 +10,7 @@ */ #include +#include #include / { @@ -152,10 +153,10 @@ scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>, - <0 191 IRQ_TYPE_LEVEL_HIGH>, - <0 192 IRQ_TYPE_LEVEL_HIGH>, - <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF0>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -165,10 +166,10 @@ scif1: serial@e8007800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007800 64>; - interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>, - <0 195 IRQ_TYPE_LEVEL_HIGH>, - <0 196 IRQ_TYPE_LEVEL_HIGH>, - <0 193 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF1>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -178,10 +179,10 @@ scif2: serial@e8008000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008000 64>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>, - <0 197 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF2>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -191,10 +192,10 @@ scif3: serial@e8008800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008800 64>; - interrupts = <0 202 IRQ_TYPE_LEVEL_HIGH>, - <0 203 IRQ_TYPE_LEVEL_HIGH>, - <0 204 IRQ_TYPE_LEVEL_HIGH>, - <0 201 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF3>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -204,10 +205,10 @@ scif4: serial@e8009000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009000 64>; - interrupts = <0 206 IRQ_TYPE_LEVEL_HIGH>, - <0 207 IRQ_TYPE_LEVEL_HIGH>, - <0 208 IRQ_TYPE_LEVEL_HIGH>, - <0 205 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF4>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -217,10 +218,10 @@ scif5: serial@e8009800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009800 64>; - interrupts = <0 210 IRQ_TYPE_LEVEL_HIGH>, - <0 211 IRQ_TYPE_LEVEL_HIGH>, - <0 212 IRQ_TYPE_LEVEL_HIGH>, - <0 209 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF5>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -230,10 +231,10 @@ scif6: serial@e800a000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a000 64>; - interrupts = <0 214 IRQ_TYPE_LEVEL_HIGH>, - <0 215 IRQ_TYPE_LEVEL_HIGH>, - <0 216 IRQ_TYPE_LEVEL_HIGH>, - <0 213 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF6>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -243,10 +244,10 @@ scif7: serial@e800a800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a800 64>; - interrupts = <0 218 IRQ_TYPE_LEVEL_HIGH>, - <0 219 IRQ_TYPE_LEVEL_HIGH>, - <0 220 IRQ_TYPE_LEVEL_HIGH>, - <0 217 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF7>; clock-names = "sci_ick"; power-domains = <&cpg_clocks>; @@ -256,9 +257,9 @@ spi0: spi@e800c800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800c800 0x24>; - interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>, - <0 239 IRQ_TYPE_LEVEL_HIGH>, - <0 240 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI0>; power-domains = <&cpg_clocks>; @@ -271,9 +272,9 @@ spi1: spi@e800d000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d000 0x24>; - interrupts = <0 241 IRQ_TYPE_LEVEL_HIGH>, - <0 242 IRQ_TYPE_LEVEL_HIGH>, - <0 243 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI1>; power-domains = <&cpg_clocks>; @@ -286,9 +287,9 @@ spi2: spi@e800d800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d800 0x24>; - interrupts = <0 244 IRQ_TYPE_LEVEL_HIGH>, - <0 245 IRQ_TYPE_LEVEL_HIGH>, - <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI2>; power-domains = <&cpg_clocks>; @@ -301,9 +302,9 @@ spi3: spi@e800e000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e000 0x24>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>, - <0 248 IRQ_TYPE_LEVEL_HIGH>, - <0 249 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI3>; power-domains = <&cpg_clocks>; @@ -316,9 +317,9 @@ spi4: spi@e800e800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e800 0x24>; - interrupts = <0 250 IRQ_TYPE_LEVEL_HIGH>, - <0 251 IRQ_TYPE_LEVEL_HIGH>, - <0 252 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI4>; power-domains = <&cpg_clocks>; @@ -342,14 +343,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee000 0x44>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, - <0 158 IRQ_TYPE_EDGE_RISING>, - <0 159 IRQ_TYPE_EDGE_RISING>, - <0 160 IRQ_TYPE_LEVEL_HIGH>, - <0 161 IRQ_TYPE_LEVEL_HIGH>, - <0 162 IRQ_TYPE_LEVEL_HIGH>, - <0 163 IRQ_TYPE_LEVEL_HIGH>, - <0 164 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C0>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -361,14 +362,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee400 0x44>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>, - <0 166 IRQ_TYPE_EDGE_RISING>, - <0 167 IRQ_TYPE_EDGE_RISING>, - <0 168 IRQ_TYPE_LEVEL_HIGH>, - <0 169 IRQ_TYPE_LEVEL_HIGH>, - <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C1>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -380,14 +381,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee800 0x44>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>, - <0 174 IRQ_TYPE_EDGE_RISING>, - <0 175 IRQ_TYPE_EDGE_RISING>, - <0 176 IRQ_TYPE_LEVEL_HIGH>, - <0 177 IRQ_TYPE_LEVEL_HIGH>, - <0 178 IRQ_TYPE_LEVEL_HIGH>, - <0 179 IRQ_TYPE_LEVEL_HIGH>, - <0 180 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C2>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -399,14 +400,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfeec00 0x44>; - interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>, - <0 182 IRQ_TYPE_EDGE_RISING>, - <0 183 IRQ_TYPE_EDGE_RISING>, - <0 184 IRQ_TYPE_LEVEL_HIGH>, - <0 185 IRQ_TYPE_LEVEL_HIGH>, - <0 186 IRQ_TYPE_LEVEL_HIGH>, - <0 187 IRQ_TYPE_LEVEL_HIGH>, - <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C3>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -416,7 +417,7 @@ mtu2: timer@fcff0000 { compatible = "renesas,mtu2-r7s72100", "renesas,mtu2"; reg = <0xfcff0000 0x400>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "tgi0a"; clocks = <&mstp3_clks R7S72100_CLK_MTU2>; clock-names = "fck"; -- GitLab From 10bbad96d4bc135d0bb0ea64e996a8870d42d989 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 28 Jan 2016 10:29:44 +0900 Subject: [PATCH 0923/5324] ARM: dts: sh73a0: use GIC_* defines Use GIC_* defines for GIC interrupt cells in sh73a0 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/boot/dts/sh73a0.dtsi | 168 +++++++++++++++++----------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 3a6056f9f0d2..453280c41d27 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -58,7 +58,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -70,8 +70,8 @@ sbsc2: memory-controller@fb400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfb400000 0x400>; - interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc1>; }; @@ -79,22 +79,22 @@ sbsc1: memory-controller@fe400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfe400000 0x400>; - interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc0>; }; pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; cmt1: timer@e6138000 { compatible = "renesas,cmt-48-sh73a0", "renesas,cmt-48"; reg = <0xe6138000 0x200>; - interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -113,14 +113,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH - 0 2 IRQ_TYPE_LEVEL_HIGH - 0 3 IRQ_TYPE_LEVEL_HIGH - 0 4 IRQ_TYPE_LEVEL_HIGH - 0 5 IRQ_TYPE_LEVEL_HIGH - 0 6 IRQ_TYPE_LEVEL_HIGH - 0 7 IRQ_TYPE_LEVEL_HIGH - 0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -135,14 +135,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH - 0 10 IRQ_TYPE_LEVEL_HIGH - 0 11 IRQ_TYPE_LEVEL_HIGH - 0 12 IRQ_TYPE_LEVEL_HIGH - 0 13 IRQ_TYPE_LEVEL_HIGH - 0 14 IRQ_TYPE_LEVEL_HIGH - 0 15 IRQ_TYPE_LEVEL_HIGH - 0 16 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -157,14 +157,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH - 0 18 IRQ_TYPE_LEVEL_HIGH - 0 19 IRQ_TYPE_LEVEL_HIGH - 0 20 IRQ_TYPE_LEVEL_HIGH - 0 21 IRQ_TYPE_LEVEL_HIGH - 0 22 IRQ_TYPE_LEVEL_HIGH - 0 23 IRQ_TYPE_LEVEL_HIGH - 0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -179,14 +179,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH - 0 26 IRQ_TYPE_LEVEL_HIGH - 0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH - 0 31 IRQ_TYPE_LEVEL_HIGH - 0 32 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -197,10 +197,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6820000 0x425>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH - 0 168 IRQ_TYPE_LEVEL_HIGH - 0 169 IRQ_TYPE_LEVEL_HIGH - 0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks SH73A0_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,10 +211,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6822000 0x425>; - interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH - 0 52 IRQ_TYPE_LEVEL_HIGH - 0 53 IRQ_TYPE_LEVEL_HIGH - 0 54 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -225,10 +225,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6824000 0x425>; - interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH - 0 172 IRQ_TYPE_LEVEL_HIGH - 0 173 IRQ_TYPE_LEVEL_HIGH - 0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -239,10 +239,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6826000 0x425>; - interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH - 0 184 IRQ_TYPE_LEVEL_HIGH - 0 185 IRQ_TYPE_LEVEL_HIGH - 0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -253,10 +253,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6828000 0x425>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH - 0 188 IRQ_TYPE_LEVEL_HIGH - 0 189 IRQ_TYPE_LEVEL_HIGH - 0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC4>; power-domains = <&pd_c5>; status = "disabled"; @@ -265,8 +265,8 @@ mmcif: mmc@e6bd0000 { compatible = "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH - 0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -276,7 +276,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e20000 0x0064>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_MSIOF0>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -287,7 +287,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e10000 0x0064>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF1>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -298,7 +298,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e00000 0x0064>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF2>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -309,7 +309,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6c90000 0x0064>; - interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF3>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -320,9 +320,9 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee100000 0x100>; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH - 0 84 IRQ_TYPE_LEVEL_HIGH - 0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -333,8 +333,8 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee120000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH - 0 89 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI1>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -345,8 +345,8 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee140000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH - 0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI2>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -357,7 +357,7 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -367,7 +367,7 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -377,7 +377,7 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -387,7 +387,7 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -397,7 +397,7 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -407,7 +407,7 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -417,7 +417,7 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -427,7 +427,7 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -437,7 +437,7 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-sh73a0", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFB>; clock-names = "sci_ick"; power-domains = <&pd_a3sp>; @@ -579,7 +579,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2"; reg = <0xec230000 0x400>; - interrupts = <0 146 0x4>; + interrupts = ; power-domains = <&pd_a4mp>; status = "disabled"; }; @@ -591,7 +591,7 @@ #size-cells = <1>; ranges = <0 0 0x20000000>; reg = <0xfec10000 0x400>; - interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&zb_clk>; power-domains = <&pd_a4s>; }; -- GitLab From b14ce2321b9c63f807719358c64bbe7aa973731c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 28 Jan 2016 10:29:54 +0900 Subject: [PATCH 0924/5324] ARM: dts: emev2: use GIC_* defines Use GIC_* defines for GIC interrupt cells in emev2 device tree. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/emev2.dtsi | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 57795da616cb..bcce6f50c93d 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -9,6 +9,7 @@ */ #include "skeleton.dtsi" +#include #include / { @@ -53,8 +54,8 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; clocks@e0110000 { @@ -158,7 +159,7 @@ timer@e0180000 { compatible = "renesas,em-sti"; reg = <0xe0180000 0x54>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&sti_sclk>; clock-names = "sclk"; }; @@ -166,7 +167,7 @@ uart0: serial@e1020000 { compatible = "renesas,em-uart"; reg = <0xe1020000 0x38>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usia_u0_sclk>; clock-names = "sclk"; }; @@ -174,7 +175,7 @@ uart1: serial@e1030000 { compatible = "renesas,em-uart"; reg = <0xe1030000 0x38>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u1_sclk>; clock-names = "sclk"; }; @@ -182,7 +183,7 @@ uart2: serial@e1040000 { compatible = "renesas,em-uart"; reg = <0xe1040000 0x38>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u2_sclk>; clock-names = "sclk"; }; @@ -190,7 +191,7 @@ uart3: serial@e1050000 { compatible = "renesas,em-uart"; reg = <0xe1050000 0x38>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u3_sclk>; clock-names = "sclk"; }; @@ -203,8 +204,8 @@ gpio0: gpio@e0050000 { compatible = "renesas,em-gio"; reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>, - <0 68 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 0 32>; #gpio-cells = <2>; @@ -215,8 +216,8 @@ gpio1: gpio@e0050080 { compatible = "renesas,em-gio"; reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>, - <0 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 32 32>; #gpio-cells = <2>; @@ -227,8 +228,8 @@ gpio2: gpio@e0050100 { compatible = "renesas,em-gio"; reg = <0xe0050100 0x2c>, <0xe0050140 0x20>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>, - <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 64 32>; #gpio-cells = <2>; @@ -239,8 +240,8 @@ gpio3: gpio@e0050180 { compatible = "renesas,em-gio"; reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>, - <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 96 32>; #gpio-cells = <2>; @@ -251,8 +252,8 @@ gpio4: gpio@e0050200 { compatible = "renesas,em-gio"; reg = <0xe0050200 0x2c>, <0xe0050240 0x20>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>, - <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 128 31>; #gpio-cells = <2>; @@ -266,7 +267,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe0070000 0x28>; - interrupts = <0 32 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic0_sclk>; clock-names = "sclk"; status = "disabled"; @@ -277,7 +278,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe10a0000 0x28>; - interrupts = <0 33 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic1_sclk>; clock-names = "sclk"; status = "disabled"; -- GitLab From 720e9096e3c205dd71f951a9ff295f988a45e207 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:02 +0100 Subject: [PATCH 0925/5324] ARM: dts: r8a7778: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7778.dtsi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index fc5e7243467a..8ea1792c5146 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -297,7 +297,8 @@ }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; @@ -307,7 +308,8 @@ }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; @@ -317,7 +319,8 @@ }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; @@ -327,7 +330,8 @@ }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; @@ -337,7 +341,8 @@ }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; @@ -347,7 +352,8 @@ }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; -- GitLab From b2ac44fa39569094131b2a998e60023a10794b17 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:03 +0100 Subject: [PATCH 0926/5324] ARM: dts: r8a7779: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779.dtsi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 93f3fdf95e31..1671839f55a6 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -211,7 +211,8 @@ }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; @@ -221,7 +222,8 @@ }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; @@ -231,7 +233,8 @@ }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; @@ -241,7 +244,8 @@ }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; @@ -251,7 +255,8 @@ }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; @@ -261,7 +266,8 @@ }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; -- GitLab From a20dc9f2e4e18ecdf1114b43d2320503f6033917 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:04 +0100 Subject: [PATCH 0927/5324] ARM: dts: r8a7790: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index cc7eccf0ada7..1d94dfd53141 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -585,7 +585,8 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; @@ -597,7 +598,8 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>; @@ -609,7 +611,8 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>; @@ -621,7 +624,8 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>; @@ -633,7 +637,8 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>; @@ -645,7 +650,8 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>; @@ -657,7 +663,8 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; @@ -669,7 +676,8 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; @@ -681,7 +689,8 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; @@ -693,7 +702,8 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; -- GitLab From b5b52dd7d014eea55ba122ae8eaf142f6f902aae Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:05 +0100 Subject: [PATCH 0928/5324] ARM: dts: r8a7791: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 6b3b02c0c58a..e7537ba68b5e 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -564,7 +564,8 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>; @@ -576,7 +577,8 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>; @@ -588,7 +590,8 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>; @@ -600,7 +603,8 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>; @@ -612,7 +616,8 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>; @@ -624,7 +629,8 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>; @@ -636,7 +642,8 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>; @@ -648,7 +655,8 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>; @@ -660,7 +668,8 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>; @@ -672,7 +681,8 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; @@ -684,7 +694,8 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; @@ -696,7 +707,8 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; @@ -708,7 +720,8 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; @@ -720,7 +733,8 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; @@ -732,7 +746,8 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; @@ -744,7 +759,8 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; @@ -756,7 +772,8 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; @@ -768,7 +785,8 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; -- GitLab From 3ffc90a3e97771e0bd5402a52962f3d91c2bb27a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:06 +0100 Subject: [PATCH 0929/5324] ARM: dts: r8a7793: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 6817f14314e2..b49f9271ceb3 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -479,7 +479,8 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>; @@ -491,7 +492,8 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>; @@ -503,7 +505,8 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>; @@ -515,7 +518,8 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>; @@ -527,7 +531,8 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>; @@ -539,7 +544,8 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>; @@ -551,7 +557,8 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>; @@ -563,7 +570,8 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>; @@ -575,7 +583,8 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>; @@ -587,7 +596,8 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; @@ -599,7 +609,8 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; @@ -611,7 +622,8 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; @@ -623,7 +635,8 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; @@ -635,7 +648,8 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; @@ -647,7 +661,8 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; @@ -659,7 +674,8 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; @@ -671,7 +687,8 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; @@ -683,7 +700,8 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; -- GitLab From 06930a1f9d875e42e17e408dd26240f7fa4e49b9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 10:32:07 +0100 Subject: [PATCH 0930/5324] ARM: dts: r8a7794: Add SCIF fallback compatibility strings Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 21be4bdc4001..a49bf303a02d 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -282,7 +282,8 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>; @@ -294,7 +295,8 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>; @@ -306,7 +308,8 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>; @@ -318,7 +321,8 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>; @@ -330,7 +334,8 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>; @@ -342,7 +347,8 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>; @@ -354,7 +360,8 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>; @@ -366,7 +373,8 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>; @@ -378,7 +386,8 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>; @@ -390,7 +399,8 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; @@ -402,7 +412,8 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; @@ -414,7 +425,8 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; @@ -426,7 +438,8 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; @@ -438,7 +451,8 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; @@ -450,7 +464,8 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; @@ -462,7 +477,8 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; @@ -474,7 +490,8 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; @@ -486,7 +503,8 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; -- GitLab From 46ae0e376b0dfe827ed7b675ff24a98d5f525c8a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:31 +0100 Subject: [PATCH 0931/5324] ARM: dts: sh73a0: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/sh73a0.dtsi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 453280c41d27..bf825ca4f6f7 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -359,7 +359,7 @@ reg = <0xe6c40000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -369,7 +369,7 @@ reg = <0xe6c50000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -379,7 +379,7 @@ reg = <0xe6c60000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -389,7 +389,7 @@ reg = <0xe6c70000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -399,7 +399,7 @@ reg = <0xe6c80000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -409,7 +409,7 @@ reg = <0xe6cb0000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -419,7 +419,7 @@ reg = <0xe6cc0000 0x100>; interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -429,7 +429,7 @@ reg = <0xe6cd0000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -439,7 +439,7 @@ reg = <0xe6c30000 0x100>; interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; -- GitLab From 92489120be987cb83a23d3c6ea013501f438c41e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:32 +0100 Subject: [PATCH 0932/5324] ARM: dts: r7s72100: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r7s72100.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index a5938c72d5bd..89e46ebef1bc 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -158,7 +158,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -171,7 +171,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -184,7 +184,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -197,7 +197,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -210,7 +210,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -223,7 +223,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -236,7 +236,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -249,7 +249,7 @@ , ; clocks = <&mstp4_clks R7S72100_CLK_SCIF7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; -- GitLab From d4be2f1bfdf7f2f6b3551d783edf676e9af00815 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:33 +0100 Subject: [PATCH 0933/5324] ARM: dts: r8a73a4: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a73a4.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 64f3efcd7ba5..138414a7d170 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -335,7 +335,7 @@ reg = <0 0xe6c20000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -345,7 +345,7 @@ reg = <0 0xe6c30000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -355,7 +355,7 @@ reg = <0 0xe6c40000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -365,7 +365,7 @@ reg = <0 0xe6c50000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -375,7 +375,7 @@ reg = <0 0xe6ce0000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -385,7 +385,7 @@ reg = <0 0xe6cf0000 0 0x100>; interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_c4>; status = "disabled"; }; -- GitLab From 0995b9a8d618b7e2a57eeb191bdb7f11dd18ba3e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:34 +0100 Subject: [PATCH 0934/5324] ARM: dts: r8a7740: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7740.dtsi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 36bcb39cca03..995fbda74b7a 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -214,7 +214,7 @@ reg = <0xe6c40000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -224,7 +224,7 @@ reg = <0xe6c50000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -234,7 +234,7 @@ reg = <0xe6c60000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -244,7 +244,7 @@ reg = <0xe6c70000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -254,7 +254,7 @@ reg = <0xe6c80000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -264,7 +264,7 @@ reg = <0xe6cb0000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -274,7 +274,7 @@ reg = <0xe6cc0000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -284,7 +284,7 @@ reg = <0xe6cd0000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -294,7 +294,7 @@ reg = <0xe6c30000 0x100>; interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; -- GitLab From 258b3c31897cefca8430b5d1de4ccbab0049efbc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:35 +0100 Subject: [PATCH 0935/5324] ARM: dts: r8a7778: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7778.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 8ea1792c5146..50784e2b632d 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -302,7 +302,7 @@ reg = <0xffe40000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -313,7 +313,7 @@ reg = <0xffe41000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -324,7 +324,7 @@ reg = <0xffe42000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -335,7 +335,7 @@ reg = <0xffe43000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -346,7 +346,7 @@ reg = <0xffe44000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -357,7 +357,7 @@ reg = <0xffe45000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; -- GitLab From b406f38d4b4d06f617d4e2a826abadda7327b652 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:36 +0100 Subject: [PATCH 0936/5324] ARM: dts: r8a7779: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 1671839f55a6..8fddfae13865 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -216,7 +216,7 @@ reg = <0xffe40000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -227,7 +227,7 @@ reg = <0xffe41000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -238,7 +238,7 @@ reg = <0xffe42000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -249,7 +249,7 @@ reg = <0xffe43000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -260,7 +260,7 @@ reg = <0xffe44000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -271,7 +271,7 @@ reg = <0xffe45000 0x100>; interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; -- GitLab From 6c6e12a1f90d9b1cc5ae7428f43aeee33049c2ee Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:37 +0100 Subject: [PATCH 0937/5324] ARM: dts: r8a7790: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 1d94dfd53141..c5672745a1e5 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -590,7 +590,7 @@ reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -603,7 +603,7 @@ reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -616,7 +616,7 @@ reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -629,7 +629,7 @@ reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -642,7 +642,7 @@ reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -655,7 +655,7 @@ reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -668,7 +668,7 @@ reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -681,7 +681,7 @@ reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -694,7 +694,7 @@ reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -707,7 +707,7 @@ reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; -- GitLab From bb7ca1952e120aba212538563c3ecd476a6a22f5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:38 +0100 Subject: [PATCH 0938/5324] ARM: dts: r8a7791: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index e7537ba68b5e..194e9464b748 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -569,7 +569,7 @@ reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -582,7 +582,7 @@ reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -595,7 +595,7 @@ reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -608,7 +608,7 @@ reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -621,7 +621,7 @@ reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -634,7 +634,7 @@ reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -647,7 +647,7 @@ reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -660,7 +660,7 @@ reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -673,7 +673,7 @@ reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -686,7 +686,7 @@ reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -699,7 +699,7 @@ reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -712,7 +712,7 @@ reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -725,7 +725,7 @@ reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -738,7 +738,7 @@ reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -751,7 +751,7 @@ reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -764,7 +764,7 @@ reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -777,7 +777,7 @@ reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -790,7 +790,7 @@ reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; -- GitLab From 48f27c190c475d2b83d0d1c464f0ced6c5b17838 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:39 +0100 Subject: [PATCH 0939/5324] ARM: dts: r8a7793: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index b49f9271ceb3..07af584915c6 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -484,7 +484,7 @@ reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -497,7 +497,7 @@ reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -510,7 +510,7 @@ reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -523,7 +523,7 @@ reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -536,7 +536,7 @@ reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -549,7 +549,7 @@ reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -562,7 +562,7 @@ reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -575,7 +575,7 @@ reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -588,7 +588,7 @@ reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -601,7 +601,7 @@ reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -614,7 +614,7 @@ reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -627,7 +627,7 @@ reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -640,7 +640,7 @@ reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -653,7 +653,7 @@ reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -666,7 +666,7 @@ reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -679,7 +679,7 @@ reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -692,7 +692,7 @@ reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -705,7 +705,7 @@ reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; -- GitLab From 1b463bd51042927e041775dc1ca5af63e7e5592b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 29 Jan 2016 10:47:40 +0100 Subject: [PATCH 0940/5324] ARM: dts: r8a7794: Rename the serial port clock to fck The clock is really the device functional clock, not the interface clock. Rename it. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794.dtsi | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index a49bf303a02d..b03a77b3d22f 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -287,7 +287,7 @@ reg = <0 0xe6c40000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -300,7 +300,7 @@ reg = <0 0xe6c50000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -313,7 +313,7 @@ reg = <0 0xe6c60000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -326,7 +326,7 @@ reg = <0 0xe6c70000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -339,7 +339,7 @@ reg = <0 0xe6c78000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -352,7 +352,7 @@ reg = <0 0xe6c80000 0 64>; interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -365,7 +365,7 @@ reg = <0 0xe6c20000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -378,7 +378,7 @@ reg = <0 0xe6c30000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -391,7 +391,7 @@ reg = <0 0xe6ce0000 0 64>; interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -404,7 +404,7 @@ reg = <0 0xe6e60000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -417,7 +417,7 @@ reg = <0 0xe6e68000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -430,7 +430,7 @@ reg = <0 0xe6e58000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -443,7 +443,7 @@ reg = <0 0xe6ea8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -456,7 +456,7 @@ reg = <0 0xe6ee0000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -469,7 +469,7 @@ reg = <0 0xe6ee8000 0 64>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -482,7 +482,7 @@ reg = <0 0xe62c0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -495,7 +495,7 @@ reg = <0 0xe62c8000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -508,7 +508,7 @@ reg = <0 0xe62d0000 0 96>; interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; -- GitLab From 5fb544da5f9a77ef723b685181d4e763f6a1b2eb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:37 +0100 Subject: [PATCH 0941/5324] ARM: dts: r8a7778: Add BRG support for SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (S1 and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF device nodes. This increases the range and accuracy of supported baud rates on SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7778.dtsi | 39 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 50784e2b632d..f83a348fc07a 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -301,8 +301,9 @@ "renesas,scif"; reg = <0xffe40000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF0>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -312,8 +313,9 @@ "renesas,scif"; reg = <0xffe41000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF1>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -323,8 +325,9 @@ "renesas,scif"; reg = <0xffe42000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF2>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -334,8 +337,9 @@ "renesas,scif"; reg = <0xffe43000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF3>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -345,8 +349,9 @@ "renesas,scif"; reg = <0xffe44000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF4>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -356,8 +361,9 @@ "renesas,scif"; reg = <0xffe45000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7778_CLK_SCIF5>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -444,6 +450,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@ffc80000 { compatible = "renesas,r8a7778-cpg-clocks"; -- GitLab From f2be5f00d5eef701871cb1bc2b573dd5a75f66d3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:38 +0100 Subject: [PATCH 0942/5324] ARM: dts: r8a7779: Add BRG support for SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (S1 and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF device nodes. This increases the range and accuracy of supported baud rates on SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779.dtsi | 39 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 8fddfae13865..a0cc08e6295b 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -215,8 +215,9 @@ "renesas,scif"; reg = <0xffe40000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF0>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -226,8 +227,9 @@ "renesas,scif"; reg = <0xffe41000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF1>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -237,8 +239,9 @@ "renesas,scif"; reg = <0xffe42000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF2>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -248,8 +251,9 @@ "renesas,scif"; reg = <0xffe43000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF3>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -259,8 +263,9 @@ "renesas,scif"; reg = <0xffe44000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF4>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -270,8 +275,9 @@ "renesas,scif"; reg = <0xffe45000 0x100>; interrupts = ; - clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; - clock-names = "fck"; + clocks = <&mstp0_clks R8A7779_CLK_SCIF5>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -447,6 +453,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: clocks@ffc80000 { compatible = "renesas,r8a7779-cpg-clocks"; -- GitLab From 42af65e88df70a32c3c1afa0e6d35022b379c6ae Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:39 +0100 Subject: [PATCH 0943/5324] ARM: dts: r8a7790: Add BRG support for (H)SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (ZS_CLK and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF and HSCIF device nodes. This increases the range and accuracy of supported baud rates on (H)SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index c5672745a1e5..c9583fa6cae7 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -667,8 +667,9 @@ "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7790_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -680,8 +681,9 @@ "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7790_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -693,8 +695,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -706,8 +709,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -996,6 +1000,15 @@ clock-output-names = "audio_clk_c"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; -- GitLab From 394730a1337c578da7a5dc26671187c10ce3a9cd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:40 +0100 Subject: [PATCH 0944/5324] ARM: dts: r8a7791: Add BRG support for (H)SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (ZS_CLK and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF and HSCIF device nodes. This increases the range and accuracy of supported baud rates on (H)SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 194e9464b748..14aa62539ff2 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -685,8 +685,9 @@ "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -698,8 +699,9 @@ "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -711,8 +713,9 @@ "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -724,8 +727,9 @@ "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -737,8 +741,9 @@ "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -750,8 +755,9 @@ "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -763,8 +769,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -776,8 +783,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -789,8 +797,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -1049,6 +1058,15 @@ status = "disabled"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; -- GitLab From 166d8ca693a9a1f4f3285ba03d9aebe7f679753f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:41 +0100 Subject: [PATCH 0945/5324] ARM: dts: r8a7793: Add BRG support for SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (ZS_CLK and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF and HSCIF device nodes. This increases the range and accuracy of supported baud rates on (H)SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 07af584915c6..45dba1c79a43 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -600,8 +600,9 @@ "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -613,8 +614,9 @@ "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -626,8 +628,9 @@ "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -639,8 +642,9 @@ "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -652,8 +656,9 @@ "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -665,8 +670,9 @@ "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -678,8 +684,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -691,8 +698,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -704,8 +712,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -805,6 +814,15 @@ clock-output-names = "audio_clk_c"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7793-cpg-clocks", -- GitLab From a864446f9662be8aba43e2969c9f1264e22aa500 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:04:42 +0100 Subject: [PATCH 0946/5324] ARM: dts: r8a7794: Add BRG support for (H)SCIF Add the device node for the external SCIF_CLK. The presence of the SCIF_CLK crystal and its clock frequency depends on the actual board. Add the two optional clock sources (ZS_CLK and SCIF_CLK for the internal resp. external clock) for the Baud Rate Generator for External Clock (BRG) to all SCIF and HSCIF device nodes. This increases the range and accuracy of supported baud rates on (H)SCIF. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794.dtsi | 54 ++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index b03a77b3d22f..7d4c5597af5b 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -403,8 +403,9 @@ "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -416,8 +417,9 @@ "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -429,8 +431,9 @@ "renesas,scif"; reg = <0 0xe6e58000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -442,8 +445,9 @@ "renesas,scif"; reg = <0 0xe6ea8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -455,8 +459,9 @@ "renesas,scif"; reg = <0 0xe6ee0000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -468,8 +473,9 @@ "renesas,scif"; reg = <0 0xe6ee8000 0 64>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -481,8 +487,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -494,8 +501,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -507,8 +515,9 @@ "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; interrupts = ; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; - clock-names = "fck"; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -815,6 +824,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7794-cpg-clocks", -- GitLab From 8a758a9493d8cac4afde82918590a11bbb24c85c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:18 +0100 Subject: [PATCH 0947/5324] ARM: dts: alt: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794-alt.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts index 773f304d1142..ca9bc4fff287 100644 --- a/arch/arm/boot/dts/r8a7794-alt.dts +++ b/arch/arm/boot/dts/r8a7794-alt.dts @@ -103,6 +103,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0"; renesas,function = "du"; @@ -113,6 +116,11 @@ renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -205,6 +213,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &qspi { pinctrl-0 = <&qspi_pins>; pinctrl-names = "default"; -- GitLab From 33ef9688ae45d19bf11c75a7c403a4f20804720d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:19 +0100 Subject: [PATCH 0948/5324] ARM: dts: bockw: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7778-bockw.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7778-bockw.dts b/arch/arm/boot/dts/r8a7778-bockw.dts index a52b359e2ae2..21e3b9dda2da 100644 --- a/arch/arm/boot/dts/r8a7778-bockw.dts +++ b/arch/arm/boot/dts/r8a7778-bockw.dts @@ -126,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_a", "scif0_ctrl"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + mmc_pins: mmc { renesas,groups = "mmc_data8", "mmc_ctrl"; renesas,function = "mmc"; @@ -217,3 +225,8 @@ status = "okay"; }; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; -- GitLab From 81a81ba9412c2c29309abd8752bcf771c22335a1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:20 +0100 Subject: [PATCH 0949/5324] ARM: dts: gose: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7793-gose.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index 2fa052036dbc..cfe142c2ba38 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -236,6 +236,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + i2c2_pins: i2c2 { renesas,groups = "i2c2"; renesas,function = "i2c2"; @@ -256,6 +259,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -316,6 +324,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &qspi { pinctrl-0 = <&qspi_pins>; pinctrl-names = "default"; -- GitLab From 338f7ebf46e184746e63bcb93b3e5dbee95564a3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:21 +0100 Subject: [PATCH 0950/5324] ARM: dts: koelsch: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates: - SCIF: - Supports now 50, 75, 110, 1152000, 1500000, 2000000, and 4000000 bps, - Perfect match for standard 50-460800, and 9216000 bps. - More accurate 576000 bps. - HSCIF: - Supports now 50, 75, 110, 134, 150, and 200 bps, - Perfect match for standard 50-460800, and 9216000 bps. - More accurate 576000, 1152000, 3000000, 3500000, and 4000000 bps. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 45256f3cc835..0ad71b81d3a2 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -320,6 +320,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + i2c2_pins: i2c2 { renesas,groups = "i2c2"; renesas,function = "i2c2"; @@ -340,6 +343,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -440,6 +448,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; -- GitLab From 1781460c9accb106b0887985754b63be1b4c63f8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:22 +0100 Subject: [PATCH 0951/5324] ARM: dts: lager: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 052dcee4790d..cdc0414f5f07 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -291,6 +291,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0"; renesas,function = "du"; @@ -301,6 +304,11 @@ renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -485,6 +493,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &msiof1 { pinctrl-0 = <&msiof1_pins>; pinctrl-names = "default"; -- GitLab From e50b5ac88d3e1c4cf6f74797be6f13bc9109b037 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:23 +0100 Subject: [PATCH 0952/5324] ARM: dts: marzen: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779-marzen.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index fe396c8d58db..e111d35d02ae 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -165,6 +165,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { du0 { renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0"; @@ -176,6 +179,11 @@ }; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_b"; + renesas,function = "scif_clk"; + }; + ethernet_pins: ethernet { intc { renesas,groups = "intc_irq1_b"; @@ -222,6 +230,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; -- GitLab From 19417bd9c5112f58ea63e97ba72edabd5e1cc0fe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:24 +0100 Subject: [PATCH 0953/5324] ARM: dts: porter: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-porter.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 5015eaa0ae50..ed1f6f884e2b 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -143,11 +143,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -221,6 +229,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; -- GitLab From c3373b09ba0391bcd9e992b0a2ce52d48d33e47b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Jan 2016 11:17:25 +0100 Subject: [PATCH 0954/5324] ARM: dts: silk: Enable SCIF_CLK frequency and pins Add and enable the external crystal for the SCIF_CLK and its pinctrl, to be used by the Baud Rate Generator for External Clock (BRG) on (H)SCIF. This increases the range and accuracy of supported baud rates. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7794-silk.dts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts index 98b8bcca84da..66f077a3ca41 100644 --- a/arch/arm/boot/dts/r8a7794-silk.dts +++ b/arch/arm/boot/dts/r8a7794-silk.dts @@ -126,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif2_pins: serial2 { renesas,groups = "scif2_data"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -184,6 +192,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; -- GitLab From 4f66f247f70bda47ec2410d007520004ba8761de Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 8 Feb 2016 21:55:12 +0000 Subject: [PATCH 0955/5324] ARM: dts: rockchip: replace gpio-key,wakeup with wakeup-source property Keyboard driver for GPIO buttons(gpio-keys) checks for the legacy "gpio-key,wakeup" boolean property to enable gpio buttons as wakeup source. Few dts files assign value "1" to gpio-key,wakeup and in one instance a value "0" is assigned probably assuming it won't be enabled as a wakeup source. Since the presence of the boolean property indicates it is enabled, value of "0" have no value. This patch replaces the legacy "gpio-key,wakeup" with the unified "wakeup-source" property which inturn fixes the above mentioned issue. Signed-off-by: Sudeep Holla Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a-bqcurie2.dts | 3 +-- arch/arm/boot/dts/rk3066a-rayeager.dts | 2 +- arch/arm/boot/dts/rk3188-radxarock.dts | 2 +- arch/arm/boot/dts/rk3288-evb.dtsi | 2 +- arch/arm/boot/dts/rk3288-firefly.dtsi | 2 +- arch/arm/boot/dts/rk3288-popmetal.dts | 2 +- arch/arm/boot/dts/rk3288-r89.dts | 2 +- arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi | 2 +- arch/arm/boot/dts/rk3288-veyron.dtsi | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 8a58bb3d7b6b..6d2a5b3a84a8 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -86,7 +86,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; button@1 { @@ -94,7 +94,6 @@ linux,code = <104>; label = "GPIO Key Vol-"; linux,input-type = <1>; - gpio-key,wakeup = <0>; debounce-interval = <100>; }; /* VOL+ comes somehow thru the ADC */ diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 84f44f5ee3de..05533005a809 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -65,7 +65,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index 66fa87d1e2c2..0b6924c97b6b 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -63,7 +63,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 4faabdb65868..78d47f7d2938 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -110,7 +110,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 49ec20d24082..98c586a43c73 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -91,7 +91,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index 65c475642d5a..2ff9689d2e1b 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -74,7 +74,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index 17f13c73fe5e..510a1d0d7abb 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -73,7 +73,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi index 136d650dd05f..610769d99522 100644 --- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi @@ -108,7 +108,7 @@ lid { label = "Lid"; gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = <0>; /* SW_LID */ linux,input-type = <5>; /* EV_SW */ debounce-interval = <1>; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 5e61f07724d4..0350f79f57da 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -64,7 +64,7 @@ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; linux,code = ; debounce-interval = <100>; - gpio-key,wakeup; + wakeup-source; }; }; -- GitLab From 6dfb54049f9a99b24fe5d5cd2d3af19eadc8f31f Mon Sep 17 00:00:00 2001 From: Douglas Miller Date: Mon, 23 Nov 2015 09:01:15 -0600 Subject: [PATCH 0956/5324] powerpc/xmon: Add xmon command to dump process/task similar to ps(1) Add 'P' command with optional task_struct address to dump all/one task's information: task pointer, kernel stack pointer, PID, PPID, state (interpreted), CPU where (last) running, and command. Signed-off-by: Douglas Miller Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 47e195d66a9a..942796fa4767 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -163,6 +163,7 @@ static int cpu_cmd(void); static void csum(void); static void bootcmds(void); static void proccall(void); +static void show_tasks(void); void dump_segments(void); static void symbol_lookup(void); static void xmon_show_stack(unsigned long sp, unsigned long lr, @@ -238,6 +239,7 @@ Commands:\n\ mz zero a block of memory\n\ mi show information about memory allocation\n\ p call a procedure\n\ + P list processes/tasks\n\ r print registers\n\ s single step\n" #ifdef CONFIG_SPU_BASE @@ -967,6 +969,9 @@ cmds(struct pt_regs *excp) case 'p': proccall(); break; + case 'P': + show_tasks(); + break; #ifdef CONFIG_PPC_STD_MMU case 'u': dump_segments(); @@ -2566,6 +2571,61 @@ memzcan(void) printf("%.8x\n", a - mskip); } +static void show_task(struct task_struct *tsk) +{ + char state; + + /* + * Cloned from kdb_task_state_char(), which is not entirely + * appropriate for calling from xmon. This could be moved + * to a common, generic, routine used by both. + */ + state = (tsk->state == 0) ? 'R' : + (tsk->state < 0) ? 'U' : + (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' : + (tsk->state & TASK_STOPPED) ? 'T' : + (tsk->state & TASK_TRACED) ? 'C' : + (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' : + (tsk->exit_state & EXIT_DEAD) ? 'E' : + (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?'; + + printf("%p %016lx %6d %6d %c %2d %s\n", tsk, + tsk->thread.ksp, + tsk->pid, tsk->parent->pid, + state, task_thread_info(tsk)->cpu, + tsk->comm); +} + +static void show_tasks(void) +{ + unsigned long tskv; + struct task_struct *tsk = NULL; + + printf(" task_struct ->thread.ksp PID PPID S P CMD\n"); + + if (scanhex(&tskv)) + tsk = (struct task_struct *)tskv; + + if (setjmp(bus_error_jmp) != 0) { + catch_memory_errors = 0; + printf("*** Error dumping task %p\n", tsk); + return; + } + + catch_memory_errors = 1; + sync(); + + if (tsk) + show_task(tsk); + else + for_each_process(tsk) + show_task(tsk); + + sync(); + __delay(200); + catch_memory_errors = 0; +} + static void proccall(void) { unsigned long args[8]; -- GitLab From e6f49b118f73a769ec51ed28a085e9dccd67f9a1 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 8 Feb 2016 21:55:12 +0000 Subject: [PATCH 0957/5324] arm64: dts: rockchip: replace gpio-key,wakeup with wakeup-source property Keyboard driver for GPIO buttons(gpio-keys) checks for the legacy "gpio-key,wakeup" boolean property to enable gpio buttons as wakeup source. Few dts files assign value "1" to gpio-key,wakeup and in one instance a value "0" is assigned probably assuming it won't be enabled as a wakeup source. Since the presence of the boolean property indicates it is enabled, value of "0" have no value. This patch replaces the legacy "gpio-key,wakeup" with the unified "wakeup-source" property which inturn fixes the above mentioned issue. Signed-off-by: Sudeep Holla Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi | 2 +- arch/arm64/boot/dts/rockchip/rk3368-r88.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 8c219ccf67a3..6e27b22704df 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -111,7 +111,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 104cbee762bb..1f2b642e794a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -71,7 +71,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; -- GitLab From 4db9a9ba602b38bd1fd80c4b3851dd15740a4fad Mon Sep 17 00:00:00 2001 From: Sylvain Lemieux Date: Tue, 9 Feb 2016 13:29:10 -0500 Subject: [PATCH 0958/5324] clk: lpc32xx: do not register clock "0" The following errors are display in the console during the power-on: [ 0.000000] lpc32xx_usb_clk_init: failed to register (null) clock: -12 [ 0.000000] lpc32xx_clk_init: failed to register (null) clock: -12 There is no need to register clock "0"; the first clock used is 1; Signed-off-by: Sylvain Lemieux Acked-by: Vladimir Zapolskiy [sboyd@codeaurora.org: s/prepare/register/] Signed-off-by: Stephen Boyd --- drivers/clk/nxp/clk-lpc32xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 10dd0fdaa474..981ff0dd88b4 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -1515,7 +1515,7 @@ static void __init lpc32xx_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_CLK_MAX; i++) { clk[i] = lpc32xx_clk_register(i); if (IS_ERR(clk[i])) { pr_err("failed to register %s clock: %ld\n", @@ -1555,7 +1555,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) { usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET); if (IS_ERR(usb_clk[i])) { pr_err("failed to register %s clock: %ld\n", -- GitLab From ccc9662da5494a7c4ff5ed5d167285b5a28d5fb3 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 9 Feb 2016 15:50:24 +1100 Subject: [PATCH 0959/5324] powerpc/powernv: Simplify definitions of EEH debugfs handlers The EEH debugfs handlers have same prototype. This introduces a macro to define them, then to simplify the code. No logical changes. Signed-off-by: Gavin Shan Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/eeh-powernv.c | 60 +++++++------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 5f152b95ca0c..3f1cb35d9cdf 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -167,42 +167,26 @@ static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val) return 0; } -static int pnv_eeh_outb_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xD10, val); -} - -static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xD10, val); -} - -static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xD90, val); -} - -static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xD90, val); -} - -static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xE10, val); -} - -static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xE10, val); -} +#define PNV_EEH_DBGFS_ENTRY(name, reg) \ +static int pnv_eeh_dbgfs_set_##name(void *data, u64 val) \ +{ \ + return pnv_eeh_dbgfs_set(data, reg, val); \ +} \ + \ +static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val) \ +{ \ + return pnv_eeh_dbgfs_get(data, reg, val); \ +} \ + \ +DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name, \ + pnv_eeh_dbgfs_get_##name, \ + pnv_eeh_dbgfs_set_##name, \ + "0x%llx\n") + +PNV_EEH_DBGFS_ENTRY(outb, 0xD10); +PNV_EEH_DBGFS_ENTRY(inbA, 0xD90); +PNV_EEH_DBGFS_ENTRY(inbB, 0xE10); -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get, - pnv_eeh_outb_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get, - pnv_eeh_inbA_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get, - pnv_eeh_inbB_dbgfs_set, "0x%llx\n"); #endif /* CONFIG_DEBUG_FS */ /** @@ -268,13 +252,13 @@ static int pnv_eeh_post_init(void) debugfs_create_file("err_injct_outbound", 0600, phb->dbgfs, hose, - &pnv_eeh_outb_dbgfs_ops); + &pnv_eeh_dbgfs_ops_outb); debugfs_create_file("err_injct_inboundA", 0600, phb->dbgfs, hose, - &pnv_eeh_inbA_dbgfs_ops); + &pnv_eeh_dbgfs_ops_inbA); debugfs_create_file("err_injct_inboundB", 0600, phb->dbgfs, hose, - &pnv_eeh_inbB_dbgfs_ops); + &pnv_eeh_dbgfs_ops_inbB); #endif /* CONFIG_DEBUG_FS */ } -- GitLab From b0331854190e70b9d96d39257230def45f832877 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:14 +0800 Subject: [PATCH 0960/5324] powerpc/powernv: don't enable SRIOV when VF BAR has non 64bit-prefetchable BAR On PHB3, we enable SRIOV devices by mapping IOV BAR with M64 BARs. If a SRIOV device's IOV BAR is not 64bit-prefetchable, this is not assigned from 64bit prefetchable window, which means M64 BAR can't work on it. The reason is PCI bridges support only 2 memory windows and the kernel code programs bridges in the way that one window is 32bit-nonprefetchable and the other one is 64bit-prefetchable. So if devices' IOV BAR is 64bit and non-prefetchable, it will be mapped into 32bit space and therefore M64 cannot be used for it. This patch makes this explicit and truncate IOV resource in this case to save MMIO space. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 35 ++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 573ae1994097..58b0e230a382 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -872,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - /* * The actual IOV BAR range is determined by the start address * and the actual size for num_vfs VFs BAR. This check is to @@ -903,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); res2 = *res; res->start += size * offset; @@ -1263,9 +1257,6 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - for (j = 0; j < vf_groups; j++) { do { win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, @@ -1552,6 +1543,12 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) pdn = pci_get_pdn(pdev); if (phb->type == PNV_PHB_IODA2) { + if (!pdn->vfs_expanded) { + dev_info(&pdev->dev, "don't support this SRIOV device" + " with non 64bit-prefetchable IOV BAR\n"); + return -ENOSPC; + } + /* Calculate available PE for required VFs */ mutex_lock(&phb->ioda.pe_alloc_mutex); pdn->offset = bitmap_find_next_zero_area( @@ -2877,9 +2874,10 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) if (!res->flags || res->parent) continue; if (!pnv_pci_is_mem_pref_64(res->flags)) { - dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n", + dev_warn(&pdev->dev, "Don't support SR-IOV with" + " non M64 VF BAR%d: %pR. \n", i, res); - continue; + goto truncate_iov; } size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); @@ -2898,11 +2896,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) res = &pdev->resource[i + PCI_IOV_RESOURCES]; if (!res->flags || res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) { - dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n", - i, res); - continue; - } dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); @@ -2912,6 +2905,16 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) i, res, mul); } pdn->vfs_expanded = mul; + + return; + +truncate_iov: + /* To save MMIO space, IOV BAR is truncated. */ + for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { + res = &pdev->resource[i + PCI_IOV_RESOURCES]; + res->flags = 0; + res->end = res->start - 1; + } } #endif /* CONFIG_PCI_IOV */ -- GitLab From 7fbe7a9374f8bb18db653f4693861c8625d01db1 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:15 +0800 Subject: [PATCH 0961/5324] powerpc/powernv: simplify the calculation of iov resource alignment The alignment of IOV BAR on PowerNV platform is the total size of the IOV BAR. No matter whether the IOV BAR is extended with number of roundup_pow_of_two(total_vfs) or number of max PE number (256), the total size could be calculated by (vfs_expanded * VF_BAR_size). This patch simplifies the pnv_pci_iov_resource_alignment() by removing the first case. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 58b0e230a382..15e6ff18dcd5 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -3129,17 +3129,21 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno) { struct pci_dn *pdn = pci_get_pdn(pdev); - resource_size_t align, iov_align; - - iov_align = resource_size(&pdev->resource[resno]); - if (iov_align) - return iov_align; + resource_size_t align; + /* + * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the + * SR-IOV. While from hardware perspective, the range mapped by M64 + * BAR should be size aligned. + * + * This function returns the total IOV BAR size if M64 BAR is in + * Shared PE mode or just VF BAR size if not. + */ align = pci_iov_resource_size(pdev, resno); - if (pdn->vfs_expanded) - return pdn->vfs_expanded * align; + if (!pdn->vfs_expanded) + return align; - return align; + return pdn->vfs_expanded * align; } #endif /* CONFIG_PCI_IOV */ -- GitLab From ee8222fe95e40ade9f50b852095d4626631ebbbe Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:16 +0800 Subject: [PATCH 0962/5324] powerpc/powernv: use one M64 BAR in Single PE mode for one VF BAR In current implementation, when VF BAR is bigger than 64MB, it uses 4 M64 BARs in Single PE mode to cover the number of VFs required to be enabled. By doing so, several VFs would be in one VF Group and leads to interference between VFs in the same group. And in this patch, m64_wins is renamed to m64_map, which means index number of the M64 BAR used to map the VF BAR. Based on Gavin's comments. Also makes sure the VF BAR size is bigger than 32MB when M64 BAR is used in Single PE mode. This patch changes the design by using one M64 BAR in Single PE mode for one VF BAR. This gives absolute isolation for VFs. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pci-bridge.h | 5 +- arch/powerpc/platforms/powernv/pci-ioda.c | 177 +++++++++------------- 2 files changed, 75 insertions(+), 107 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 54843ca5fa2b..11d3543a57f2 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -216,10 +216,9 @@ struct pci_dn { u16 vfs_expanded; /* number of VFs IOV BAR expanded */ u16 num_vfs; /* number of VFs enabled*/ int offset; /* PE# for the first VF PE */ -#define M64_PER_IOV 4 - int m64_per_iov; + bool m64_single_mode; /* Use M64 BAR in Single Mode */ #define IODA_INVALID_M64 (-1) - int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV]; + int (*m64_map)[PCI_SRIOV_NUM_BARS]; #endif /* CONFIG_PCI_IOV */ #endif struct list_head child_list; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 15e6ff18dcd5..4004c0a842ca 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1190,29 +1190,36 @@ static void pnv_pci_ioda_setup_PEs(void) } #ifdef CONFIG_PCI_IOV -static int pnv_pci_vf_release_m64(struct pci_dev *pdev) +static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs) { struct pci_bus *bus; struct pci_controller *hose; struct pnv_phb *phb; struct pci_dn *pdn; int i, j; + int m64_bars; bus = pdev->bus; hose = pci_bus_to_host(bus); phb = hose->private_data; pdn = pci_get_pdn(pdev); + if (pdn->m64_single_mode) + m64_bars = num_vfs; + else + m64_bars = 1; + for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) - for (j = 0; j < M64_PER_IOV; j++) { - if (pdn->m64_wins[i][j] == IODA_INVALID_M64) + for (j = 0; j < m64_bars; j++) { + if (pdn->m64_map[j][i] == IODA_INVALID_M64) continue; opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0); - clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc); - pdn->m64_wins[i][j] = IODA_INVALID_M64; + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0); + clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc); + pdn->m64_map[j][i] = IODA_INVALID_M64; } + kfree(pdn->m64_map); return 0; } @@ -1229,8 +1236,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) int total_vfs; resource_size_t size, start; int pe_num; - int vf_groups; - int vf_per_group; + int m64_bars; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1238,26 +1244,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) pdn = pci_get_pdn(pdev); total_vfs = pci_sriov_get_totalvfs(pdev); - /* Initialize the m64_wins to IODA_INVALID_M64 */ - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) - for (j = 0; j < M64_PER_IOV; j++) - pdn->m64_wins[i][j] = IODA_INVALID_M64; + if (pdn->m64_single_mode) + m64_bars = num_vfs; + else + m64_bars = 1; + + pdn->m64_map = kmalloc(sizeof(*pdn->m64_map) * m64_bars, GFP_KERNEL); + if (!pdn->m64_map) + return -ENOMEM; + /* Initialize the m64_map to IODA_INVALID_M64 */ + for (i = 0; i < m64_bars ; i++) + for (j = 0; j < PCI_SRIOV_NUM_BARS; j++) + pdn->m64_map[i][j] = IODA_INVALID_M64; - if (pdn->m64_per_iov == M64_PER_IOV) { - vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV; - vf_per_group = (num_vfs <= M64_PER_IOV)? 1: - roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - } else { - vf_groups = 1; - vf_per_group = 1; - } for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { res = &pdev->resource[i + PCI_IOV_RESOURCES]; if (!res->flags || !res->parent) continue; - for (j = 0; j < vf_groups; j++) { + for (j = 0; j < m64_bars; j++) { do { win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, phb->ioda.m64_bar_idx + 1, 0); @@ -1266,12 +1272,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) goto m64_failed; } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc)); - pdn->m64_wins[i][j] = win; + pdn->m64_map[j][i] = win; - if (pdn->m64_per_iov == M64_PER_IOV) { + if (pdn->m64_single_mode) { size = pci_iov_resource_size(pdev, PCI_IOV_RESOURCES + i); - size = size * vf_per_group; start = res->start + size * j; } else { size = resource_size(res); @@ -1279,16 +1284,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) } /* Map the M64 here */ - if (pdn->m64_per_iov == M64_PER_IOV) { + if (pdn->m64_single_mode) { pe_num = pdn->offset + j; rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe_num, OPAL_M64_WINDOW_TYPE, - pdn->m64_wins[i][j], 0); + pdn->m64_map[j][i], 0); } rc = opal_pci_set_phb_mem_window(phb->opal_id, OPAL_M64_WINDOW_TYPE, - pdn->m64_wins[i][j], + pdn->m64_map[j][i], start, 0, /* unused */ size); @@ -1300,12 +1305,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) goto m64_failed; } - if (pdn->m64_per_iov == M64_PER_IOV) + if (pdn->m64_single_mode) rc = opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2); + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2); else rc = opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1); + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1); if (rc != OPAL_SUCCESS) { dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n", @@ -1317,7 +1322,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) return 0; m64_failed: - pnv_pci_vf_release_m64(pdev); + pnv_pci_vf_release_m64(pdev, num_vfs); return -EBUSY; } @@ -1344,15 +1349,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe iommu_free_table(tbl, of_node_full_name(dev->dev.of_node)); } -static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) +static void pnv_ioda_release_vf_PE(struct pci_dev *pdev) { struct pci_bus *bus; struct pci_controller *hose; struct pnv_phb *phb; struct pnv_ioda_pe *pe, *pe_n; struct pci_dn *pdn; - u16 vf_index; - int64_t rc; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1362,35 +1365,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) if (!pdev->is_physfn) return; - if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { - int vf_group; - int vf_per_group; - int vf_index1; - - vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - - for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) - for (vf_index = vf_group * vf_per_group; - vf_index < (vf_group + 1) * vf_per_group && - vf_index < num_vfs; - vf_index++) - for (vf_index1 = vf_group * vf_per_group; - vf_index1 < (vf_group + 1) * vf_per_group && - vf_index1 < num_vfs; - vf_index1++){ - - rc = opal_pci_set_peltv(phb->opal_id, - pdn->offset + vf_index, - pdn->offset + vf_index1, - OPAL_REMOVE_PE_FROM_DOMAIN); - - if (rc) - dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n", - __func__, - pdn->offset + vf_index1, rc); - } - } - list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) { if (pe->parent_dev != pdev) continue; @@ -1425,14 +1399,14 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) num_vfs = pdn->num_vfs; /* Release VF PEs */ - pnv_ioda_release_vf_PE(pdev, num_vfs); + pnv_ioda_release_vf_PE(pdev); if (phb->type == PNV_PHB_IODA2) { - if (pdn->m64_per_iov == 1) + if (!pdn->m64_single_mode) pnv_pci_vf_resource_shift(pdev, -pdn->offset); /* Release M64 windows */ - pnv_pci_vf_release_m64(pdev); + pnv_pci_vf_release_m64(pdev, num_vfs); /* Release PE numbers */ bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); @@ -1451,7 +1425,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) int pe_num; u16 vf_index; struct pci_dn *pdn; - int64_t rc; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1496,37 +1469,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) pnv_pci_ioda2_setup_dma_pe(phb, pe); } - - if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { - int vf_group; - int vf_per_group; - int vf_index1; - - vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - - for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) { - for (vf_index = vf_group * vf_per_group; - vf_index < (vf_group + 1) * vf_per_group && - vf_index < num_vfs; - vf_index++) { - for (vf_index1 = vf_group * vf_per_group; - vf_index1 < (vf_group + 1) * vf_per_group && - vf_index1 < num_vfs; - vf_index1++) { - - rc = opal_pci_set_peltv(phb->opal_id, - pdn->offset + vf_index, - pdn->offset + vf_index1, - OPAL_ADD_PE_TO_DOMAIN); - - if (rc) - dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n", - __func__, - pdn->offset + vf_index1, rc); - } - } - } - } } int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) @@ -1549,6 +1491,15 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) return -ENOSPC; } + /* + * When M64 BARs functions in Single PE mode, the number of VFs + * could be enabled must be less than the number of M64 BARs. + */ + if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) { + dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n"); + return -EBUSY; + } + /* Calculate available PE for required VFs */ mutex_lock(&phb->ioda.pe_alloc_mutex); pdn->offset = bitmap_find_next_zero_area( @@ -1576,7 +1527,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) * the IOV BAR according to the PE# allocated to the VFs. * Otherwise, the PE# for the VF will conflict with others. */ - if (pdn->m64_per_iov == 1) { + if (!pdn->m64_single_mode) { ret = pnv_pci_vf_resource_shift(pdev, pdn->offset); if (ret) goto m64_failed; @@ -1609,8 +1560,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) /* Allocate PCI data */ add_dev_pci_data(pdev); - pnv_pci_sriov_enable(pdev, num_vfs); - return 0; + return pnv_pci_sriov_enable(pdev, num_vfs); } #endif /* CONFIG_PCI_IOV */ @@ -2864,9 +2814,9 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) pdn = pci_get_pdn(pdev); pdn->vfs_expanded = 0; + pdn->m64_single_mode = false; total_vfs = pci_sriov_get_totalvfs(pdev); - pdn->m64_per_iov = 1; mul = phb->ioda.total_pe; for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { @@ -2886,8 +2836,8 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) if (size > (1 << 26)) { dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n", i, res); - pdn->m64_per_iov = M64_PER_IOV; mul = roundup_pow_of_two(total_vfs); + pdn->m64_single_mode = true; break; } } @@ -2897,8 +2847,14 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) if (!res->flags || res->parent) continue; - dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); + /* + * On PHB3, the minimum size alignment of M64 BAR in single + * mode is 32MB. + */ + if (pdn->m64_single_mode && (size < SZ_32M)) + goto truncate_iov; + dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); res->end = res->start + size * mul - 1; dev_dbg(&pdev->dev, " %pR\n", res); dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", @@ -3128,6 +3084,8 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno) { + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn = pci_get_pdn(pdev); resource_size_t align; @@ -3136,12 +3094,23 @@ static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, * SR-IOV. While from hardware perspective, the range mapped by M64 * BAR should be size aligned. * + * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra + * powernv-specific hardware restriction is gone. But if just use the + * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with + * in one segment of M64 #15, which introduces the PE conflict between + * PF and VF. Based on this, the minimum alignment of an IOV BAR is + * m64_segsize. + * * This function returns the total IOV BAR size if M64 BAR is in * Shared PE mode or just VF BAR size if not. + * If the M64 BAR is in Single PE mode, return the VF BAR size or + * M64 segment size if IOV BAR size is less. */ align = pci_iov_resource_size(pdev, resno); if (!pdn->vfs_expanded) return align; + if (pdn->m64_single_mode) + return max(align, (resource_size_t)phb->ioda.m64_segsize); return pdn->vfs_expanded * align; } -- GitLab From f2dd0afeea0ed0e740c4b066c76a556a8b870e58 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:17 +0800 Subject: [PATCH 0963/5324] powerpc/powernv: replace the hard coded boundary with gate At the moment 64bit-prefetchable window can be maximum 64GB, which is currently got from device tree. This means that in shared mode the maximum supported VF BAR size is 64GB/256=256MB. While this size could exhaust the whole 64bit-prefetchable window. This is a design decision to set a boundary to 64MB of the VF BAR size. Since VF BAR size with 64MB would occupy a quarter of the 64bit-prefetchable window, this is affordable. This patch replaces magic limit of 64MB with "gate", which is 1/4 of the M64 Segment Size(m64_segsize >> 2) and adds comment to explain the reason for it. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 28 +++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 4004c0a842ca..b8c01fc1a6c1 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2798,8 +2798,9 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } #ifdef CONFIG_PCI_IOV static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) { - struct pci_controller *hose; - struct pnv_phb *phb; + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + struct pnv_phb *phb = hose->private_data; + const resource_size_t gate = phb->ioda.m64_segsize >> 2; struct resource *res; int i; resource_size_t size; @@ -2809,9 +2810,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) if (!pdev->is_physfn || pdev->is_added) return; - hose = pci_bus_to_host(pdev->bus); - phb = hose->private_data; - pdn = pci_get_pdn(pdev); pdn->vfs_expanded = 0; pdn->m64_single_mode = false; @@ -2832,10 +2830,22 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); - /* bigger than 64M */ - if (size > (1 << 26)) { - dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n", - i, res); + /* + * If bigger than quarter of M64 segment size, just round up + * power of two. + * + * Generally, one M64 BAR maps one IOV BAR. To avoid conflict + * with other devices, IOV BAR size is expanded to be + * (total_pe * VF_BAR_size). When VF_BAR_size is half of M64 + * segment size , the expanded size would equal to half of the + * whole M64 space size, which will exhaust the M64 Space and + * limit the system flexibility. This is a design decision to + * set the boundary to quarter of the M64 segment size. + */ + if (size > gate) { + dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size " + "is bigger than %lld, roundup power2\n", + i, res, gate); mul = roundup_pow_of_two(total_vfs); pdn->m64_single_mode = true; break; -- GitLab From dfcc8d45c33baa670f20fe4860adb3ffde39cecf Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:18 +0800 Subject: [PATCH 0964/5324] powerpc/powernv: boundary the total VF BAR size instead of the individual one Each VF could have 6 BARs at most. When the total BAR size exceeds the gate, after expanding it will also exhaust the M64 Window. This patch limits the boundary by checking the total VF BAR size instead of the individual BAR. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b8c01fc1a6c1..0c7e6ba80b07 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2803,7 +2803,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) const resource_size_t gate = phb->ioda.m64_segsize >> 2; struct resource *res; int i; - resource_size_t size; + resource_size_t size, total_vf_bar_sz; struct pci_dn *pdn; int mul, total_vfs; @@ -2816,6 +2816,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) total_vfs = pci_sriov_get_totalvfs(pdev); mul = phb->ioda.total_pe; + total_vf_bar_sz = 0; for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { res = &pdev->resource[i + PCI_IOV_RESOURCES]; @@ -2828,7 +2829,8 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) goto truncate_iov; } - size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); + total_vf_bar_sz += pci_iov_resource_size(pdev, + i + PCI_IOV_RESOURCES); /* * If bigger than quarter of M64 segment size, just round up @@ -2842,11 +2844,11 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) * limit the system flexibility. This is a design decision to * set the boundary to quarter of the M64 segment size. */ - if (size > gate) { - dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size " - "is bigger than %lld, roundup power2\n", - i, res, gate); + if (total_vf_bar_sz > gate) { mul = roundup_pow_of_two(total_vfs); + dev_info(&pdev->dev, + "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n", + total_vf_bar_sz, gate, mul); pdn->m64_single_mode = true; break; } -- GitLab From be283eeb7f6d9165b3c50f5222123ac25cf0d417 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Thu, 22 Oct 2015 09:22:19 +0800 Subject: [PATCH 0965/5324] powerpc/powernv: allocate sparse PE# when using M64 BAR in Single PE mode When M64 BAR is set to Single PE mode, the PE# assigned to VF could be sparse. This patch restructures the code to allocate sparse PE# for VFs when M64 BAR is set to Single PE mode. Also it rename the offset to pe_num_map to reflect the content is the PE number. Signed-off-by: Wei Yang Reviewed-by: Gavin Shan Acked-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pci-bridge.h | 2 +- arch/powerpc/platforms/powernv/pci-ioda.c | 81 +++++++++++++++++------ 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 11d3543a57f2..b0b43f5fbc5f 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -215,7 +215,7 @@ struct pci_dn { #ifdef CONFIG_PCI_IOV u16 vfs_expanded; /* number of VFs IOV BAR expanded */ u16 num_vfs; /* number of VFs enabled*/ - int offset; /* PE# for the first VF PE */ + int *pe_num_map; /* PE# for the first VF PE or array */ bool m64_single_mode; /* Use M64 BAR in Single Mode */ #define IODA_INVALID_M64 (-1) int (*m64_map)[PCI_SRIOV_NUM_BARS]; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 0c7e6ba80b07..dc868586315d 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1285,7 +1285,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) /* Map the M64 here */ if (pdn->m64_single_mode) { - pe_num = pdn->offset + j; + pe_num = pdn->pe_num_map[j]; rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe_num, OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0); @@ -1389,7 +1389,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) struct pnv_phb *phb; struct pci_dn *pdn; struct pci_sriov *iov; - u16 num_vfs; + u16 num_vfs, i; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1403,14 +1403,21 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) if (phb->type == PNV_PHB_IODA2) { if (!pdn->m64_single_mode) - pnv_pci_vf_resource_shift(pdev, -pdn->offset); + pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map); /* Release M64 windows */ pnv_pci_vf_release_m64(pdev, num_vfs); /* Release PE numbers */ - bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); - pdn->offset = 0; + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + if (pdn->pe_num_map[i] != IODA_INVALID_PE) + pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); + } + } else + bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); + /* Releasing pe_num_map */ + kfree(pdn->pe_num_map); } } @@ -1436,7 +1443,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) /* Reserve PE for each VF */ for (vf_index = 0; vf_index < num_vfs; vf_index++) { - pe_num = pdn->offset + vf_index; + if (pdn->m64_single_mode) + pe_num = pdn->pe_num_map[vf_index]; + else + pe_num = *pdn->pe_num_map + vf_index; pe = &phb->ioda.pe_array[pe_num]; pe->pe_number = pe_num; @@ -1478,6 +1488,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) struct pnv_phb *phb; struct pci_dn *pdn; int ret; + u16 i; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1500,20 +1511,44 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) return -EBUSY; } + /* Allocating pe_num_map */ + if (pdn->m64_single_mode) + pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map) * num_vfs, + GFP_KERNEL); + else + pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL); + + if (!pdn->pe_num_map) + return -ENOMEM; + + if (pdn->m64_single_mode) + for (i = 0; i < num_vfs; i++) + pdn->pe_num_map[i] = IODA_INVALID_PE; + /* Calculate available PE for required VFs */ - mutex_lock(&phb->ioda.pe_alloc_mutex); - pdn->offset = bitmap_find_next_zero_area( - phb->ioda.pe_alloc, phb->ioda.total_pe, - 0, num_vfs, 0); - if (pdn->offset >= phb->ioda.total_pe) { + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb); + if (pdn->pe_num_map[i] == IODA_INVALID_PE) { + ret = -EBUSY; + goto m64_failed; + } + } + } else { + mutex_lock(&phb->ioda.pe_alloc_mutex); + *pdn->pe_num_map = bitmap_find_next_zero_area( + phb->ioda.pe_alloc, phb->ioda.total_pe, + 0, num_vfs, 0); + if (*pdn->pe_num_map >= phb->ioda.total_pe) { + mutex_unlock(&phb->ioda.pe_alloc_mutex); + dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); + kfree(pdn->pe_num_map); + return -EBUSY; + } + bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); mutex_unlock(&phb->ioda.pe_alloc_mutex); - dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); - pdn->offset = 0; - return -EBUSY; } - bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs); pdn->num_vfs = num_vfs; - mutex_unlock(&phb->ioda.pe_alloc_mutex); /* Assign M64 window accordingly */ ret = pnv_pci_vf_assign_m64(pdev, num_vfs); @@ -1528,7 +1563,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) * Otherwise, the PE# for the VF will conflict with others. */ if (!pdn->m64_single_mode) { - ret = pnv_pci_vf_resource_shift(pdev, pdn->offset); + ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map); if (ret) goto m64_failed; } @@ -1540,8 +1575,16 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) return 0; m64_failed: - bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); - pdn->offset = 0; + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + if (pdn->pe_num_map[i] != IODA_INVALID_PE) + pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); + } + } else + bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); + + /* Releasing pe_num_map */ + kfree(pdn->pe_num_map); return ret; } -- GitLab From e4f226b1580b36550727c324b404207f8d2f3b71 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Tue, 9 Feb 2016 02:47:45 -0500 Subject: [PATCH 0966/5324] powerpc/perf/hv-gpci: Increase request buffer size The GPCI hcall allows for a 4K buffer but we limit the buffer to 1K. The problem with a 1K buffer is if a request results in returning more values than can be accomodated in the 1K buffer the request will fail. The buffer we are using is currently allocated on the stack and hence limited in size. Instead use a per-CPU 4K buffer like we do with 24x7 counters (hv-24x7.c). While here, rename the macro GPCI_MAX_DATA_BYTES to HGPCI_MAX_DATA_BYTES for consistency with 24x7 counters. Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Michael Ellerman --- arch/powerpc/perf/hv-gpci.c | 43 +++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 856fe6e03c2a..7aa37236bb70 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -127,8 +127,16 @@ static const struct attribute_group *attr_groups[] = { NULL, }; -#define GPCI_MAX_DATA_BYTES \ - (1024 - sizeof(struct hv_get_perf_counter_info_params)) +#define HGPCI_REQ_BUFFER_SIZE 4096 +#define HGPCI_MAX_DATA_BYTES \ + (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params)) + +DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t)); + +struct hv_gpci_request_buffer { + struct hv_get_perf_counter_info_params params; + uint8_t bytes[HGPCI_MAX_DATA_BYTES]; +} __packed; static unsigned long single_gpci_request(u32 req, u32 starting_index, u16 secondary_index, u8 version_in, u32 offset, u8 length, @@ -137,24 +145,21 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, unsigned long ret; size_t i; u64 count; + struct hv_gpci_request_buffer *arg; + + arg = (void *)get_cpu_var(hv_gpci_reqb); + memset(arg, 0, HGPCI_REQ_BUFFER_SIZE); - struct { - struct hv_get_perf_counter_info_params params; - uint8_t bytes[GPCI_MAX_DATA_BYTES]; - } __packed __aligned(sizeof(uint64_t)) arg = { - .params = { - .counter_request = cpu_to_be32(req), - .starting_index = cpu_to_be32(starting_index), - .secondary_index = cpu_to_be16(secondary_index), - .counter_info_version_in = version_in, - } - }; + arg->params.counter_request = cpu_to_be32(req); + arg->params.starting_index = cpu_to_be32(starting_index); + arg->params.secondary_index = cpu_to_be16(secondary_index); + arg->params.counter_info_version_in = version_in; ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, - virt_to_phys(&arg), sizeof(arg)); + virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); if (ret) { pr_devel("hcall failed: 0x%lx\n", ret); - return ret; + goto out; } /* @@ -163,9 +168,11 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, */ count = 0; for (i = offset; i < offset + length; i++) - count |= arg.bytes[i] << (i - offset); + count |= arg->bytes[i] << (i - offset); *value = count; +out: + put_cpu_var(hv_gpci_reqb); return ret; } @@ -245,10 +252,10 @@ static int h_gpci_event_init(struct perf_event *event) } /* last byte within the buffer? */ - if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) { + if ((event_get_offset(event) + length) > HGPCI_MAX_DATA_BYTES) { pr_devel("request outside of buffer: %zu > %zu\n", (size_t)event_get_offset(event) + length, - GPCI_MAX_DATA_BYTES); + HGPCI_MAX_DATA_BYTES); return -EINVAL; } -- GitLab From b0388bf1088d992b45aa8af14d3151ae57848b17 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:11 +1100 Subject: [PATCH 0967/5324] xfs: remove XBF_DONE flag wrapper macros They only set/clear/check a flag, no need for obfuscating this with a macro. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 2 +- fs/xfs/xfs_buf.h | 4 ---- fs/xfs/xfs_buf_item.c | 6 +++--- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_log.c | 4 ++-- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_mount.c | 2 +- fs/xfs/xfs_trans_buf.c | 4 ++-- 8 files changed, 11 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 435c7de42e5f..9a2191b91137 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -650,7 +650,7 @@ xfs_buf_read_map( if (bp) { trace_xfs_buf_read(bp, flags, _RET_IP_); - if (!XFS_BUF_ISDONE(bp)) { + if (!(bp->b_flags & XBF_DONE)) { XFS_STATS_INC(target->bt_mount, xb_get_read); bp->b_ops = ops; _xfs_buf_read(bp, flags); diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index c75721acd867..03b5d3a61b0e 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -321,10 +321,6 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) -#define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE) -#define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE) -#define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE) - #define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC) #define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) #define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 7e986da34f6c..901e4d721958 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -493,7 +493,7 @@ xfs_buf_item_unpin( xfs_buf_hold(bp); bp->b_flags |= XBF_ASYNC; xfs_buf_ioerror(bp, -EIO); - XFS_BUF_UNDONE(bp); + bp->b_flags &= ~XBF_DONE; xfs_buf_stale(bp); xfs_buf_ioend(bp); } @@ -1067,7 +1067,7 @@ xfs_buf_iodone_callbacks( */ if (XFS_FORCED_SHUTDOWN(mp)) { xfs_buf_stale(bp); - XFS_BUF_DONE(bp); + bp->b_flags |= XBF_DONE; trace_xfs_buf_item_iodone(bp, _RET_IP_); goto do_callbacks; } @@ -1113,7 +1113,7 @@ xfs_buf_iodone_callbacks( * sure to return the error to the caller of xfs_bwrite(). */ xfs_buf_stale(bp); - XFS_BUF_DONE(bp); + bp->b_flags |= XBF_DONE; trace_xfs_buf_error_relse(bp, _RET_IP_); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ceba1a83cacc..a7be69a79321 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3313,7 +3313,7 @@ xfs_iflush_cluster( * mark it as stale and brelse. */ if (bp->b_iodone) { - XFS_BUF_UNDONE(bp); + bp->b_flags &= ~XBF_DONE; xfs_buf_stale(bp); xfs_buf_ioerror(bp, -EIO); xfs_buf_ioend(bp); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9c9a1c9bcc7f..aa8c9bfaa35d 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -3979,7 +3979,7 @@ xfs_log_force_umount( log->l_flags & XLOG_ACTIVE_RECOVERY) { mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; if (mp->m_sb_bp) - XFS_BUF_DONE(mp->m_sb_bp); + mp->m_sb_bp->b_flags |= XBF_DONE; return 0; } @@ -4009,7 +4009,7 @@ xfs_log_force_umount( spin_lock(&log->l_icloglock); mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; if (mp->m_sb_bp) - XFS_BUF_DONE(mp->m_sb_bp); + mp->m_sb_bp->b_flags |= XBF_DONE; /* * Mark the log and the iclogs with IO error flags to prevent any diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index da37beb76f6e..545ff3c03243 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4926,7 +4926,7 @@ xlog_do_recover( * updates, re-read in the superblock and reverify it. */ bp = xfs_getsb(log->l_mp, 0); - XFS_BUF_UNDONE(bp); + bp->b_flags &= ~XBF_DONE; ASSERT(!(XFS_BUF_ISWRITE(bp))); XFS_BUF_READ(bp); XFS_BUF_UNASYNC(bp); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bb753b359bee..2c951899344a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1284,7 +1284,7 @@ xfs_getsb( } xfs_buf_hold(bp); - ASSERT(XFS_BUF_ISDONE(bp)); + ASSERT(bp->b_flags & XBF_DONE); return bp; } diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 75798412859a..ed6f61fd3539 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -155,7 +155,7 @@ xfs_trans_get_buf_map( ASSERT(xfs_buf_islocked(bp)); if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) { xfs_buf_stale(bp); - XFS_BUF_DONE(bp); + bp->b_flags |= XBF_DONE; } ASSERT(bp->b_transp == tp); @@ -518,7 +518,7 @@ xfs_trans_log_buf(xfs_trans_t *tp, * inside the b_bdstrat callback so that this won't get written to * disk. */ - XFS_BUF_DONE(bp); + bp->b_flags |= XBF_DONE; ASSERT(atomic_read(&bip->bli_refcount) > 0); bp->b_iodone = xfs_buf_iodone_callbacks; -- GitLab From 1157b32c732cbab75320e429559c0ec9f5d382e4 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:11 +1100 Subject: [PATCH 0968/5324] xfs: remove XBF_ASYNC flag wrapper macros They only set/clear/check a flag, no need for obfuscating this with a macro. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.h | 4 ---- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_log.c | 8 +++----- fs/xfs/xfs_log_recover.c | 3 +-- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 03b5d3a61b0e..2a28d1ccbfb9 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -321,10 +321,6 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) -#define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC) -#define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) -#define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) - #define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) #define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) #define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 901e4d721958..838df068fad4 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -1090,7 +1090,7 @@ xfs_buf_iodone_callbacks( * errors tend to affect the whole device and a failing log write * will make us give up. But we really ought to do better here. */ - if (XFS_BUF_ISASYNC(bp)) { + if (bp->b_flags & XBF_ASYNC) { ASSERT(bp->b_iodone != NULL); trace_xfs_buf_item_iodone_async(bp, _RET_IP_); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index aa8c9bfaa35d..19db3daad8a9 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1212,7 +1212,7 @@ xlog_iodone(xfs_buf_t *bp) } /* log I/O is always issued ASYNC */ - ASSERT(XFS_BUF_ISASYNC(bp)); + ASSERT(bp->b_flags & XBF_ASYNC); xlog_state_done_syncing(iclog, aborted); /* @@ -1865,8 +1865,7 @@ xlog_sync( bp->b_io_length = BTOBB(count); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); - XFS_BUF_ASYNC(bp); - bp->b_flags |= XBF_SYNCIO; + bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { bp->b_flags |= XBF_FUA; @@ -1911,8 +1910,7 @@ xlog_sync( (char *)&iclog->ic_header + count, split); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); - XFS_BUF_ASYNC(bp); - bp->b_flags |= XBF_SYNCIO; + bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) bp->b_flags |= XBF_FUA; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 545ff3c03243..f00cce9bf830 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4926,10 +4926,9 @@ xlog_do_recover( * updates, re-read in the superblock and reverify it. */ bp = xfs_getsb(log->l_mp, 0); - bp->b_flags &= ~XBF_DONE; + bp->b_flags &= ~(XBF_DONE | XBF_ASYNC); ASSERT(!(XFS_BUF_ISWRITE(bp))); XFS_BUF_READ(bp); - XFS_BUF_UNASYNC(bp); bp->b_ops = &xfs_sb_buf_ops; error = xfs_buf_submit_wait(bp); -- GitLab From 0cac682ff683bac968c24a4774c69c3a9ff35013 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:11 +1100 Subject: [PATCH 0969/5324] xfs: remove XBF_READ flag wrapper macros They only set/clear/check a flag, no need for obfuscating this with a macro. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.h | 4 ---- fs/xfs/xfs_log_recover.c | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 2a28d1ccbfb9..329e612460a6 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -321,10 +321,6 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) -#define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) -#define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) -#define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ) - #define XFS_BUF_WRITE(bp) ((bp)->b_flags |= XBF_WRITE) #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f00cce9bf830..e747bad5b64e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -190,7 +190,7 @@ xlog_bread_noalign( ASSERT(nbblks <= bp->b_length); XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); - XFS_BUF_READ(bp); + bp->b_flags |= XBF_READ; bp->b_io_length = nbblks; bp->b_error = 0; @@ -4928,7 +4928,7 @@ xlog_do_recover( bp = xfs_getsb(log->l_mp, 0); bp->b_flags &= ~(XBF_DONE | XBF_ASYNC); ASSERT(!(XFS_BUF_ISWRITE(bp))); - XFS_BUF_READ(bp); + bp->b_flags |= XBF_READ; bp->b_ops = &xfs_sb_buf_ops; error = xfs_buf_submit_wait(bp); -- GitLab From b68c08219a6726fb68dca2d56e024d2e2c1654f5 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:11 +1100 Subject: [PATCH 0970/5324] xfs: remove XBF_WRITE flag wrapper macros They only set/clear/check a flag, no need for obfuscating this with a macro. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.h | 4 ---- fs/xfs/xfs_log.c | 8 +++----- fs/xfs/xfs_log_recover.c | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 329e612460a6..a1189625cca4 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -321,10 +321,6 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) -#define XFS_BUF_WRITE(bp) ((bp)->b_flags |= XBF_WRITE) -#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) -#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) - /* * These macros use the IO block map rather than b_bn. b_bn is now really * just for the buffer cache index for cached buffers. As IO does not use b_bn diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 19db3daad8a9..edf20b204235 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1865,7 +1865,7 @@ xlog_sync( bp->b_io_length = BTOBB(count); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); - bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO); + bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { bp->b_flags |= XBF_FUA; @@ -1892,12 +1892,11 @@ xlog_sync( /* account for log which doesn't start at block #0 */ XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart); + /* * Don't call xfs_bwrite here. We do log-syncs even when the filesystem * is shutting down. */ - XFS_BUF_WRITE(bp); - error = xlog_bdstrat(bp); if (error) { xfs_buf_ioerror_alert(bp, "xlog_sync"); @@ -1910,7 +1909,7 @@ xlog_sync( (char *)&iclog->ic_header + count, split); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); - bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO); + bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) bp->b_flags |= XBF_FUA; @@ -1919,7 +1918,6 @@ xlog_sync( /* account for internal log which doesn't start at block #0 */ XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart); - XFS_BUF_WRITE(bp); error = xlog_bdstrat(bp); if (error) { xfs_buf_ioerror_alert(bp, "xlog_sync (split)"); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index e747bad5b64e..50a75ecf279e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4927,7 +4927,7 @@ xlog_do_recover( */ bp = xfs_getsb(log->l_mp, 0); bp->b_flags &= ~(XBF_DONE | XBF_ASYNC); - ASSERT(!(XFS_BUF_ISWRITE(bp))); + ASSERT(!(bp->b_flags & XBF_WRITE)); bp->b_flags |= XBF_READ; bp->b_ops = &xfs_sb_buf_ops; -- GitLab From 5cfd28b6abc2bd53f225c82e5083d898b3a158fe Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:11 +1100 Subject: [PATCH 0971/5324] xfs: remove XBF_STALE flag wrapper macros They only set/clear/check a flag, no need for obfuscating this with a macro. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.h | 4 +--- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_trans_buf.c | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index a1189625cca4..98b7ee97aeae 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -302,6 +302,7 @@ extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, /* Buffer Utility Routines */ extern void *xfs_buf_offset(struct xfs_buf *, size_t); +extern void xfs_buf_stale(struct xfs_buf *bp); /* Delayed Write Buffer Routines */ extern bool xfs_buf_delwri_queue(struct xfs_buf *, struct list_head *); @@ -317,9 +318,6 @@ extern void xfs_buf_terminate(void); XBF_SYNCIO|XBF_FUA|XBF_FLUSH| \ XBF_WRITE_FAIL)) -void xfs_buf_stale(struct xfs_buf *bp); -#define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) -#define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) /* * These macros use the IO block map rather than b_bn. b_bn is now really diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 838df068fad4..99e91a0e554e 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -431,7 +431,7 @@ xfs_buf_item_unpin( if (freed && stale) { ASSERT(bip->bli_flags & XFS_BLI_STALE); ASSERT(xfs_buf_islocked(bp)); - ASSERT(XFS_BUF_ISSTALE(bp)); + ASSERT(bp->b_flags & XBF_STALE); ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL); trace_xfs_buf_item_unpin_stale(bip); diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index ed6f61fd3539..8ee29ca132dc 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -534,8 +534,8 @@ xfs_trans_log_buf(xfs_trans_t *tp, */ if (bip->bli_flags & XFS_BLI_STALE) { bip->bli_flags &= ~XFS_BLI_STALE; - ASSERT(XFS_BUF_ISSTALE(bp)); - XFS_BUF_UNSTALE(bp); + ASSERT(bp->b_flags & XBF_STALE); + bp->b_flags &= ~XBF_STALE; bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL; } @@ -600,7 +600,7 @@ xfs_trans_binval( * If the buffer is already invalidated, then * just return. */ - ASSERT(XFS_BUF_ISSTALE(bp)); + ASSERT(bp->b_flags & XBF_STALE); ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY))); ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_INODE_BUF)); ASSERT(!(bip->__bli_format.blf_flags & XFS_BLFT_MASK)); -- GitLab From 12877da58429affc988403817b88d901fe01f8c1 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 10 Feb 2016 15:01:30 +1100 Subject: [PATCH 0972/5324] xfs: remove XFS_BUF_ZEROFLAGS macro The places where we use this macro already clear unnecessary IO flags (e.g. through xfs_bwrite()) or never have unexpected IO flags set on them in the first place (e.g. iclog buffers). Remove the macro from these locations, and where necessary clear only the specific flags that are conditional in the current buffer context. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.h | 6 ------ fs/xfs/xfs_log.c | 4 ++-- fs/xfs/xfs_log_recover.c | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 98b7ee97aeae..4eb89bd4ee73 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -313,12 +313,6 @@ extern int xfs_buf_delwri_submit_nowait(struct list_head *); extern int xfs_buf_init(void); extern void xfs_buf_terminate(void); -#define XFS_BUF_ZEROFLAGS(bp) \ - ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC| \ - XBF_SYNCIO|XBF_FUA|XBF_FLUSH| \ - XBF_WRITE_FAIL)) - - /* * These macros use the IO block map rather than b_bn. b_bn is now really * just for the buffer cache index for cached buffers. As IO does not use b_bn diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index edf20b204235..40b700d3f426 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1864,7 +1864,7 @@ xlog_sync( bp->b_io_length = BTOBB(count); bp->b_fspriv = iclog; - XFS_BUF_ZEROFLAGS(bp); + bp->b_flags &= ~(XBF_FUA | XBF_FLUSH); bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { @@ -1908,7 +1908,7 @@ xlog_sync( xfs_buf_associate_memory(bp, (char *)&iclog->ic_header + count, split); bp->b_fspriv = iclog; - XFS_BUF_ZEROFLAGS(bp); + bp->b_flags &= ~(XBF_FUA | XBF_FLUSH); bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) bp->b_flags |= XBF_FUA; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 50a75ecf279e..837e8d09aa5a 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -275,7 +275,6 @@ xlog_bwrite( ASSERT(nbblks <= bp->b_length); XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); - XFS_BUF_ZEROFLAGS(bp); xfs_buf_hold(bp); xfs_buf_lock(bp); bp->b_io_length = nbblks; -- GitLab From 52dfa12e45510fce566fb240135420d7a0b5d0e6 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 9 Feb 2016 21:11:12 +0100 Subject: [PATCH 0973/5324] drm/gma500: fix error path in gma_intel_setup_gmbus() The current code fails to call i2c_del_adapter on dev_prev->gmbus[0].adapter, and if the for loop above failed already at i==0, all hell breaks loose when we do the loop body for i = -1,-2,... Signed-off-by: Rasmus Villemoes Link: http://patchwork.freedesktop.org/patch/msgid/1455048677-19882-2-git-send-email-linux@rasmusvillemoes.dk Reviewed-by: Andy Shevchenko Signed-off-by: Daniel Vetter --- drivers/gpu/drm/gma500/intel_gmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 566d330aaeea..e7e22187c539 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c @@ -436,7 +436,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) return 0; err: - while (--i) { + while (i--) { struct intel_gmbus *bus = &dev_priv->gmbus[i]; i2c_del_adapter(&bus->adapter); } -- GitLab From da3b891b0fb88605bb2d16adaf1ef2a1f16403ba Mon Sep 17 00:00:00 2001 From: Lyude Date: Thu, 4 Feb 2016 10:43:21 -0500 Subject: [PATCH 0974/5324] drm/i915/skl: Fix typo in DPLL_CFGCR1 definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We accidentally point both cfgcr registers for the second shared DPLL to the same location in i915_reg.h. This results in a lot of hw pipe state mismatches whenever we try to do a modeset that requires allocating the DPLL to a CRTC: [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in dpll_hw_state.cfgcr1 (expected 0x80000168, found 0x000004a5) [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in base.adjusted_mode.crtc_clock (expected 108000, found 49500) [drm:intel_pipe_config_compare [i915]] *ERROR* mismatch in port_clock (expected 108000, found 49500) This usually ends up causing blank monitors, since the DPLL never can get set to the right clock. Fixes: 086f8e84a085 ("drm/i915: Prefix raw register defines with underscore") Signed-off-by: Lyude Cc: drm-intel-fixes@lists.freedesktop.org Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454600601-21900-1-git-send-email-cpaul@redhat.com --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 188ad5de020f..665ae4846731 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7545,7 +7545,7 @@ enum skl_disp_power_wells { #define DPLL_CFGCR2_PDIV_7 (4<<2) #define DPLL_CFGCR2_CENTRAL_FREQ_MASK (3) -#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR2) +#define DPLL_CFGCR1(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR1, _DPLL2_CFGCR1) #define DPLL_CFGCR2(id) _MMIO_PIPE((id) - SKL_DPLL1, _DPLL1_CFGCR2, _DPLL2_CFGCR2) /* BXT display engine PLL */ -- GitLab From 8c448cadd4dd1bb3a8f34a93eaceb464d6e7a1db Mon Sep 17 00:00:00 2001 From: Gabriel Feceoru Date: Fri, 22 Jan 2016 13:28:45 +0200 Subject: [PATCH 0975/5324] drm/i915: Handle PipeC fused off on IVB/HSW/BDW Some Gen7/8 production parts may have the Display Pipe C fused off. In this case, the display hardware will prevent the enable bit in PIPE_CONF register (for Pipe C) from being set to 1. Fixed by adjusting pipe_count to reflect this. v2: Rename HSW_PIPE_C_DISABLE to IVB_PIPE_C_DISABLE as it already exists on ivybridge (Ville) v3: Remove unnecessary MMIO read, correct the description (Damien) v4: Be more specific in description (Patrick) Signed-off-by: Gabriel Feceoru Reviewed-by: Patrik Jakobsson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453462125-21519-1-git-send-email-gabriel.feceoru@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/i915_reg.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a42eb58f7c41..35c2b33560b4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -808,6 +808,9 @@ static void intel_device_info_runtime_init(struct drm_device *dev) !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { DRM_INFO("Display fused off, disabling\n"); info->num_pipes = 0; + } else if (fuse_strap & IVB_PIPE_C_DISABLE) { + DRM_INFO("PipeC fused off\n"); + info->num_pipes -= 1; } } else if (info->num_pipes > 0 && INTEL_INFO(dev)->gen == 9) { u32 dfsm = I915_READ(SKL_DFSM); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 665ae4846731..144586ee74d5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5949,6 +5949,7 @@ enum skl_disp_power_wells { #define ILK_INTERNAL_GRAPHICS_DISABLE (1 << 31) #define ILK_INTERNAL_DISPLAY_DISABLE (1 << 30) #define ILK_DISPLAY_DEBUG_DISABLE (1 << 29) +#define IVB_PIPE_C_DISABLE (1 << 28) #define ILK_HDCP_DISABLE (1 << 25) #define ILK_eDP_A_DISABLE (1 << 24) #define HSW_CDCLK_LIMIT (1 << 24) -- GitLab From 1b39a917a9e00378c02c50ad86632ed3d872bfad Mon Sep 17 00:00:00 2001 From: Nick Hoath Date: Fri, 22 Jan 2016 23:10:06 +0000 Subject: [PATCH 0976/5324] drm/i915: fix context/engine cleanup order Swap the order of context & engine cleanup, so that contexts are cleaned up first, and *then* engines. This is a more sensible order anyway, but in particular has become necessary since the 'intel_ring_initialized() must be simple and inline' patch, which now uses ring->dev as an 'initialised' flag, so it can now be NULL after engine teardown. This in turn can cause a problem in the context code, which (used to) check the ring->dev->struct_mutex -- causing a fault if ring->dev was NULL. Also rename the cleanup function to reflect what it actually does (cleanup engines, not a ringbuffer), and fix an annoying whitespace issue. v2: Also make the fix in i915_load_modeset_init, not just in i915_driver_unload (Chris Wilson) v3: Had extra stuff in it. v4: Reverted extra stuff (so we're back to v2). Rebased and updated commentary above (Dave Gordon). Signed-off-by: Nick Hoath Signed-off-by: David Gordon Reviewed-by: Chris Wilson Cc: Mika Kuoppala Cc: Daniel Vetter Cc: Chris Wilson Signed-off-by: Dave Gordon Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453504211-7982-2-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 23 ++++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 35c2b33560b4..571d7e62953b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -444,8 +444,8 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); + i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: intel_guc_ucode_fini(dev); @@ -1256,8 +1256,8 @@ int i915_driver_unload(struct drm_device *dev) intel_guc_ucode_fini(dev); mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); + i915_gem_cleanup_engines(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8216665405eb..e11eef1e5134 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3058,7 +3058,7 @@ int i915_gem_init_rings(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice); void i915_gem_init_swizzling(struct drm_device *dev); -void i915_gem_cleanup_ringbuffer(struct drm_device *dev); +void i915_gem_cleanup_engines(struct drm_device *dev); int __must_check i915_gpu_idle(struct drm_device *dev); int __must_check i915_gem_suspend(struct drm_device *dev); void __i915_add_request(struct drm_i915_gem_request *req, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e9b19bca1383..de57e7f0be0f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4913,7 +4913,7 @@ i915_gem_init_hw(struct drm_device *dev) req = i915_gem_request_alloc(ring, NULL); if (IS_ERR(req)) { ret = PTR_ERR(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4926,7 +4926,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -4934,7 +4934,7 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); goto out; } @@ -5009,7 +5009,7 @@ int i915_gem_init(struct drm_device *dev) } void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) +i915_gem_cleanup_engines(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; @@ -5018,13 +5018,14 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) for_each_ring(ring, dev_priv, i) dev_priv->gt.cleanup_ring(ring); - if (i915.enable_execlists) - /* - * Neither the BIOS, ourselves or any other kernel - * expects the system to be in execlists mode on startup, - * so we need to reset the GPU back to legacy mode. - */ - intel_gpu_reset(dev); + if (i915.enable_execlists) { + /* + * Neither the BIOS, ourselves or any other kernel + * expects the system to be in execlists mode on startup, + * so we need to reset the GPU back to legacy mode. + */ + intel_gpu_reset(dev); + } } static void -- GitLab From 06e6ff8f10513ae863adeddf21510c99171a6283 Mon Sep 17 00:00:00 2001 From: Arun Siluvery Date: Thu, 28 Jan 2016 17:18:41 +0000 Subject: [PATCH 0977/5324] drm/i915: Capture PCI revision and subsytem details in error state Revision id along with device id is useful in better identification of the HW and its limitations so include this detail in error state. v2: make it clear that it is PCI revision and We might as well dump PCI subsystem details while we update this (Ville, Chris). Cc: Chris Wilson Signed-off-by: Arun Siluvery Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1454001521-7701-1-git-send-email-arun.siluvery@linux.intel.com --- drivers/gpu/drm/i915/i915_gpu_error.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 7eeb24427785..978c026963b8 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -365,6 +365,10 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, err_printf(m, "Reset count: %u\n", error->reset_count); err_printf(m, "Suspend count: %u\n", error->suspend_count); err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device); + err_printf(m, "PCI Revision: 0x%02x\n", dev->pdev->revision); + err_printf(m, "PCI Subsystem: %04x:%04x\n", + dev->pdev->subsystem_vendor, + dev->pdev->subsystem_device); err_printf(m, "IOMMU enabled?: %d\n", error->iommu); if (HAS_CSR(dev)) { -- GitLab From 9f5ac8ed4013c616bd3b29147808c8b2f057c251 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Jan 2016 14:37:58 +0100 Subject: [PATCH 0978/5324] agp/intel-gtt: Don't leak the scratch page Recently discovered by enabling CONFIG_DMA_API_DEBUG in our CI. By the looks of it broken since forever. v2: Don't forget to set the scratch page back to wb (Chris). Reuse intel_gtt_teardown_scratch_page for that (and fix it up to treat needs_dmar y/n correctly). Cc: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93793 Signed-off-by: Daniel Vetter Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453901881-26425-1-git-send-email-daniel.vetter@ffwll.ch --- drivers/char/agp/intel-gtt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1341a94cc779..e657f989745e 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -555,8 +555,10 @@ static unsigned int intel_gtt_mappable_entries(void) static void intel_gtt_teardown_scratch_page(void) { set_pages_wb(intel_private.scratch_page, 1); - pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (intel_private.needs_dmar) + pci_unmap_page(intel_private.pcidev, + intel_private.scratch_page_dma, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); __free_page(intel_private.scratch_page); } @@ -1430,6 +1432,8 @@ void intel_gmch_remove(void) if (--intel_private.refcount) return; + if (intel_private.scratch_page) + intel_gtt_teardown_scratch_page(); if (intel_private.pcidev) pci_dev_put(intel_private.pcidev); if (intel_private.bridge_dev) -- GitLab From 3e99a6b9561402909fdb3b0028764d42557e0103 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Jan 2016 14:37:59 +0100 Subject: [PATCH 0979/5324] drm/i915: Stop depending upon CONFIG_AGP_INTEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AGP_INTEL driver provides an interface for very old userspace to control the GART (though the GART itself was only ever emulated on Intel systems). The pci bridge discovery code is also used by the i915.ko driver to set up the GTT on old systems, but it does not require the old userspace interface. When i915.ko selects the old interface, it binds another user to the core GTT routines, and in particular creates a second reference to the scratch pages allocated. This hinders resource leak debugging for when we unload i915.ko as we want to assert that all DMA pages have been released, but we appear to leak because of the secondary interface which persists after i915.ko unloads. All i915.ko users do not require the old /dev/agpgart interface so stop selecting it and simplify our debugging by dropping the historical baggage. Note that by selecting AGP=n it was already possible to unselect AGP_INTEL. But since we've dropped support for any of the AGP stuff long ago there's really no point for this any more. Also note that we still need INTEL_GTT, which is the underlying, shared, driver for the graphics GART on gen1-5. v2: Entirely new commit message (Chris, Ville). Cc: Ville Syrjälä Cc: Chris Wilson Signed-off-by: Daniel Vetter Reviewed-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1453901881-26425-2-git-send-email-daniel.vetter@ffwll.ch --- drivers/gpu/drm/i915/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 051eab33e4c7..4c59793c4ccb 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -2,9 +2,7 @@ config DRM_I915 tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics" depends on DRM depends on X86 && PCI - depends on (AGP || AGP=n) select INTEL_GTT - select AGP_INTEL if AGP select INTERVAL_TREE # we need shmfs for the swappable backing store, and in particular # the shmem_readpage() which depends upon tmpfs -- GitLab From 2e3cd19bbd1a39e09f8e6a8020b79136d3fc3c7a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 10 Feb 2016 09:22:04 +0100 Subject: [PATCH 0980/5324] ARM: plat-versatile: Remove unused clock.c file This file isn't compiled anymore because PLAT_VERSATILE_CLOCK is never selected. Remove the file and the config. Acked-by: Arnd Bergmann Signed-off-by: Stephen Boyd Signed-off-by: Linus Walleij --- arch/arm/plat-versatile/Kconfig | 3 -- arch/arm/plat-versatile/Makefile | 1 - arch/arm/plat-versatile/clock.c | 74 -------------------------------- 3 files changed, 78 deletions(-) delete mode 100644 arch/arm/plat-versatile/clock.c diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 49b8ef91584a..98b9b8e9f698 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -1,8 +1,5 @@ if PLAT_VERSATILE -config PLAT_VERSATILE_CLOCK - bool - config PLAT_VERSATILE_SCHED_CLOCK bool diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 03c4900ac3f4..bff3ba889882 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1,5 +1,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c deleted file mode 100644 index 5c8b6564fdc2..000000000000 --- a/arch/arm/plat-versatile/clock.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/arch/arm/plat-versatile/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include - -#include - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - long ret = -EIO; - if (clk->ops && clk->ops->round) - ret = clk->ops->round(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - if (clk->ops && clk->ops->set) - ret = clk->ops->set(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -long icst_clk_round(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(icst_clk_round); - -int icst_clk_set(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->ops->setvco(clk, vco); - - return 0; -} -EXPORT_SYMBOL(icst_clk_set); -- GitLab From 34d2f4d3a4d6a6b204ebfd12d1d2c159360d41a4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 27 Jan 2016 14:11:42 -0800 Subject: [PATCH 0981/5324] ARM: Use generic clkdev.h header Get rid of the clkdev.h file in the ARM port and use the generic one because we've gotten rid of all the machine specific mach/clkdev.h files. Acked-by: Arnd Bergmann Signed-off-by: Stephen Boyd Signed-off-by: Linus Walleij --- arch/arm/include/asm/Kbuild | 1 + arch/arm/include/asm/clkdev.h | 31 ------------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 arch/arm/include/asm/clkdev.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 16da6380eb85..43cd07708cf9 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += bitsperlong.h +generic-y += clkdev.h generic-y += cputime.h generic-y += current.h generic-y += early_ioremap.h diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h deleted file mode 100644 index 4e8a4b27d7c7..000000000000 --- a/arch/arm/include/asm/clkdev.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm/include/asm/clkdev.h - * - * Copyright (C) 2008 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Helper for the clk API to assist looking up a struct clk. - */ -#ifndef __ASM_CLKDEV_H -#define __ASM_CLKDEV_H - -#include - -#ifndef CONFIG_COMMON_CLK -#ifdef CONFIG_HAVE_MACH_CLKDEV -#include -#else -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) -#endif -#endif - -static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) -{ - return kzalloc(size, GFP_KERNEL); -} - -#endif -- GitLab From 2417c8c03f508841b85bf61acc91836b7b0e2560 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Tue, 9 Feb 2016 21:11:13 +0100 Subject: [PATCH 0982/5324] drm/i915: fix error path in intel_setup_gmbus() This fails to undo the setup for pin==0; moreover, something interesting happens if the setup failed already at pin==0. Signed-off-by: Rasmus Villemoes Fixes: f899fc64cda8 ("drm/i915: use GMBUS to manage i2c links") Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1455048677-19882-3-git-send-email-linux@rasmusvillemoes.dk --- drivers/gpu/drm/i915/intel_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 25254b5c1ac5..deb8282c26d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -683,7 +683,7 @@ int intel_setup_gmbus(struct drm_device *dev) return 0; err: - while (--pin) { + while (pin--) { if (!intel_gmbus_is_valid_pin(dev_priv, pin)) continue; -- GitLab From d2f79f223f931dfadf98c42a9d426999d5e3397c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:12:23 +0100 Subject: [PATCH 0983/5324] reset: ath79: Make reset_control_ops const The ath79_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel Acked-by: Alban Bedel --- drivers/reset/reset-ath79.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index 692fc890e94b..ccb940a8d9fb 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c @@ -70,7 +70,7 @@ static int ath79_reset_status(struct reset_controller_dev *rcdev, return !!(val & BIT(id)); } -static struct reset_control_ops ath79_reset_ops = { +static const struct reset_control_ops ath79_reset_ops = { .assert = ath79_reset_assert, .deassert = ath79_reset_deassert, .status = ath79_reset_status, -- GitLab From 0e18e60e1bded4b3c8c0eb29ac297ff7336ba5c7 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:11:59 +0100 Subject: [PATCH 0984/5324] reset: hi6220: Make reset_control_ops const The hi6220_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel --- drivers/reset/hisilicon/hi6220_reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/hisilicon/hi6220_reset.c b/drivers/reset/hisilicon/hi6220_reset.c index 744b2e796442..8f55fd4a2630 100644 --- a/drivers/reset/hisilicon/hi6220_reset.c +++ b/drivers/reset/hisilicon/hi6220_reset.c @@ -57,7 +57,7 @@ static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev, return 0; } -static struct reset_control_ops hi6220_reset_ops = { +static const struct reset_control_ops hi6220_reset_ops = { .assert = hi6220_reset_assert, .deassert = hi6220_reset_deassert, }; -- GitLab From 387eb3f3d574ebf43b3afe83da59a99481866b78 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:13:41 +0100 Subject: [PATCH 0985/5324] reset: socfpga: Make reset_control_ops const The socfpga_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel --- drivers/reset/reset-socfpga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index b7d773d9248c..cd05a7032b17 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -90,7 +90,7 @@ static int socfpga_reset_status(struct reset_controller_dev *rcdev, return !(reg & BIT(offset)); } -static struct reset_control_ops socfpga_reset_ops = { +static const struct reset_control_ops socfpga_reset_ops = { .assert = socfpga_reset_assert, .deassert = socfpga_reset_deassert, .status = socfpga_reset_status, -- GitLab From 356d108f8780b58a6aa966e17d64f332f1917730 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:14:52 +0100 Subject: [PATCH 0986/5324] reset: zynq: Make reset_control_ops const The zynq_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel --- drivers/reset/reset-zynq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/reset-zynq.c b/drivers/reset/reset-zynq.c index c6b3cd8b40ad..a7e87bc45885 100644 --- a/drivers/reset/reset-zynq.c +++ b/drivers/reset/reset-zynq.c @@ -86,7 +86,7 @@ static int zynq_reset_status(struct reset_controller_dev *rcdev, return !!(reg & BIT(offset)); } -static struct reset_control_ops zynq_reset_ops = { +static const struct reset_control_ops zynq_reset_ops = { .assert = zynq_reset_assert, .deassert = zynq_reset_deassert, .status = zynq_reset_status, -- GitLab From f673ed4d5fdc123b1552525de30741cd8dfde53f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 17 Jan 2016 15:15:13 +0100 Subject: [PATCH 0987/5324] reset: sti: Make reset_control_ops const The syscfg_reset_ops structure is never modified. Make it const. Signed-off-by: Philipp Zabel --- drivers/reset/sti/reset-syscfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c index 1600cc7557f5..9bd57a5eee72 100644 --- a/drivers/reset/sti/reset-syscfg.c +++ b/drivers/reset/sti/reset-syscfg.c @@ -134,7 +134,7 @@ static int syscfg_reset_status(struct reset_controller_dev *rcdev, return rst->active_low ? !ret_val : !!ret_val; } -static struct reset_control_ops syscfg_reset_ops = { +static const struct reset_control_ops syscfg_reset_ops = { .reset = syscfg_reset_dev, .assert = syscfg_reset_assert, .deassert = syscfg_reset_deassert, -- GitLab From a6356f930233ff3b240b45069e7665ca357e739e Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Thu, 12 Dec 2013 18:23:35 +0000 Subject: [PATCH 0988/5324] Documentation: drm: Add DT bindings for ARM HDLCD Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Acked-by: Rob Herring Signed-off-by: Liviu Dudau --- .../devicetree/bindings/display/arm,hdlcd.txt | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/arm,hdlcd.txt diff --git a/Documentation/devicetree/bindings/display/arm,hdlcd.txt b/Documentation/devicetree/bindings/display/arm,hdlcd.txt new file mode 100644 index 000000000000..78bc24296f3e --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,hdlcd.txt @@ -0,0 +1,79 @@ +ARM HDLCD + +This is a display controller found on several development platforms produced +by ARM Ltd and in more modern of its' Fast Models. The HDLCD is an RGB +streamer that reads the data from a framebuffer and sends it to a single +digital encoder (DVI or HDMI). + +Required properties: + - compatible: "arm,hdlcd" + - reg: Physical base address and length of the controller's registers. + - interrupts: One interrupt used by the display controller to notify the + interrupt controller when any of the interrupt sources programmed in + the interrupt mask register have activated. + - clocks: A list of phandle + clock-specifier pairs, one for each + entry in 'clock-names'. + - clock-names: A list of clock names. For HDLCD it should contain: + - "pxlclk" for the clock feeding the output PLL of the controller. + +Required sub-nodes: + - port: The HDLCD connection to an encoder chip. The connection is modeled + using the OF graph bindings specified in + Documentation/devicetree/bindings/graph.txt. + +Optional properties: + - memory-region: phandle to a node describing memory (see + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) to be + used for the framebuffer; if not present, the framebuffer may be located + anywhere in memory. + + +Example: + +/ { + ... + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0 0x2b000000 0 0x1000>; + interrupts = ; + clocks = <&oscclk5>; + clock-names = "pxlclk"; + port { + hdlcd_output: endpoint@0 { + remote-endpoint = <&hdmi_enc_input>; + }; + }; + }; + + /* HDMI encoder on I2C bus */ + i2c@7ffa0000 { + .... + hdmi-transmitter@70 { + compatible = "....."; + reg = <0x70>; + port@0 { + hdmi_enc_input: endpoint { + remote-endpoint = <&hdlcd_output>; + }; + + hdmi_enc_output: endpoint { + remote-endpoint = <&hdmi_1_port>; + }; + }; + }; + + }; + + hdmi1: connector@1 { + compatible = "hdmi-connector"; + type = "a"; + port { + hdmi_1_port: endpoint { + remote-endpoint = <&hdmi_enc_output>; + }; + }; + }; + + ... +}; -- GitLab From 9fd9288ed0899f9e318a97d73e777d6d3357265e Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Thu, 2 Apr 2015 19:50:29 +0100 Subject: [PATCH 0989/5324] arm64: dts: Add HDLCD support on Juno platforms ARM's Juno platforms have two HDLCD controllers, each linked to an NXP TDA19988 HDMI transmitter that provides output encoding. Add them to the device tree. Acked-by: Sudeep Holla Signed-off-by: Liviu Dudau --- arch/arm64/boot/dts/arm/juno-base.dtsi | 46 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index b501721baf77..31d5d44db233 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -114,8 +114,8 @@ scpi_clk: scpi_clocks@3 { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; - clock-indices = <3>, <4>; - clock-output-names = "pxlclk0", "pxlclk1"; + clock-indices = <3>; + clock-output-names = "pxlclk"; }; }; @@ -145,6 +145,34 @@ clock-names = "apb_pclk"; }; + hdlcd@7ff50000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff50000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd1_output: endpoint@0 { + remote-endpoint = <&tda998x_1_input>; + }; + }; + }; + + hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff60000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: endpoint@0 { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + soc_uart0: uart@7ff80000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x7ff80000 0x0 0x1000>; @@ -163,14 +191,24 @@ i2c-sda-hold-time-ns = <500>; clocks = <&soc_smc50mhz>; - dvi0: dvi-transmitter@70 { + hdmi-transmitter@70 { compatible = "nxp,tda998x"; reg = <0x70>; + port { + tda998x_0_input: endpoint@0 { + remote-endpoint = <&hdlcd0_output>; + }; + }; }; - dvi1: dvi-transmitter@71 { + hdmi-transmitter@71 { compatible = "nxp,tda998x"; reg = <0x71>; + port { + tda998x_1_input: endpoint@0 { + remote-endpoint = <&hdlcd1_output>; + }; + }; }; }; -- GitLab From 4cacf91fcb1d7118e93caf9cb6651d7f7b56e58d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 24 Feb 2015 11:34:01 +0100 Subject: [PATCH 0990/5324] drm: add drm_of_encoder_active_endpoint helpers This patch adds a helper to parse the encoder endpoint connected to the encoder's crtc and two helpers to return its id and port id. This can be used to determine input mux setting from endpoint or port ids. Suggested-by: Daniel Kurtz Reviewed-by: Daniel Kurtz Signed-off-by: Philipp Zabel --- drivers/gpu/drm/drm_of.c | 34 ++++++++++++++++++++++++++++++++++ include/drm/drm_of.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 493c05c9ce4f..bc98bb94264d 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -149,3 +149,37 @@ int drm_of_component_probe(struct device *dev, return component_master_add_with_match(dev, m_ops, match); } EXPORT_SYMBOL(drm_of_component_probe); + +/* + * drm_of_encoder_active_endpoint - return the active encoder endpoint + * @node: device tree node containing encoder input ports + * @encoder: drm_encoder + * + * Given an encoder device node and a drm_encoder with a connected crtc, + * parse the encoder endpoint connecting to the crtc port. + */ +int drm_of_encoder_active_endpoint(struct device_node *node, + struct drm_encoder *encoder, + struct of_endpoint *endpoint) +{ + struct device_node *ep; + struct drm_crtc *crtc = encoder->crtc; + struct device_node *port; + int ret; + + if (!node || !crtc) + return -EINVAL; + + for_each_endpoint_of_node(node, ep) { + port = of_graph_get_remote_port(ep); + of_node_put(port); + if (port == crtc->port) { + ret = of_graph_parse_endpoint(ep, endpoint); + of_node_put(ep); + return ret; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h index 8544665ee4f4..3fd87b386ed7 100644 --- a/include/drm/drm_of.h +++ b/include/drm/drm_of.h @@ -1,9 +1,12 @@ #ifndef __DRM_OF_H__ #define __DRM_OF_H__ +#include + struct component_master_ops; struct device; struct drm_device; +struct drm_encoder; struct device_node; #ifdef CONFIG_OF @@ -12,6 +15,9 @@ extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, extern int drm_of_component_probe(struct device *dev, int (*compare_of)(struct device *, void *), const struct component_master_ops *m_ops); +extern int drm_of_encoder_active_endpoint(struct device_node *node, + struct drm_encoder *encoder, + struct of_endpoint *endpoint); #else static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, struct device_node *port) @@ -26,6 +32,33 @@ drm_of_component_probe(struct device *dev, { return -EINVAL; } + +static inline int drm_of_encoder_active_endpoint(struct device_node *node, + struct drm_encoder *encoder, + struct of_endpoint *endpoint) +{ + return -EINVAL; +} #endif +static inline int drm_of_encoder_active_endpoint_id(struct device_node *node, + struct drm_encoder *encoder) +{ + struct of_endpoint endpoint; + int ret = drm_of_encoder_active_endpoint(node, encoder, + &endpoint); + + return ret ?: endpoint.id; +} + +static inline int drm_of_encoder_active_port_id(struct device_node *node, + struct drm_encoder *encoder) +{ + struct of_endpoint endpoint; + int ret = drm_of_encoder_active_endpoint(node, encoder, + &endpoint); + + return ret ?: endpoint.port; +} + #endif /* __DRM_OF_H__ */ -- GitLab From 8e22d79240d95c92b6cbc4c4e4139848de458927 Mon Sep 17 00:00:00 2001 From: Liviu Dudau Date: Thu, 2 Apr 2015 19:48:39 +0100 Subject: [PATCH 0991/5324] drm: Add support for ARM's HDLCD controller. The HDLCD controller is a display controller that supports resolutions up to 4096x4096 pixels. It is present on various development boards produced by ARM Ltd and emulated by the latest Fast Models from the company. Cc: David Airlie Cc: Robin Murphy Signed-off-by: Liviu Dudau [Kconfig cleanup and !CONFIG_PM fixes] Signed-off-by: Arnd Bergmann Acked-by: Daniel Vetter --- drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/arm/Kconfig | 27 ++ drivers/gpu/drm/arm/Makefile | 2 + drivers/gpu/drm/arm/hdlcd_crtc.c | 327 ++++++++++++++++++ drivers/gpu/drm/arm/hdlcd_drv.c | 550 +++++++++++++++++++++++++++++++ drivers/gpu/drm/arm/hdlcd_drv.h | 42 +++ drivers/gpu/drm/arm/hdlcd_regs.h | 87 +++++ 8 files changed, 1038 insertions(+) create mode 100644 drivers/gpu/drm/arm/Kconfig create mode 100644 drivers/gpu/drm/arm/Makefile create mode 100644 drivers/gpu/drm/arm/hdlcd_crtc.c create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.c create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.h create mode 100644 drivers/gpu/drm/arm/hdlcd_regs.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8ae7ab68cb97..438e92d4c389 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -106,6 +106,8 @@ config DRM_TDFX Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), graphics card. If M is selected, the module will be called tdfx. +source "drivers/gpu/drm/arm/Kconfig" + config DRM_R128 tristate "ATI Rage 128" depends on DRM && PCI diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 61766dec6a8d..f80fdbaeb641 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -33,6 +33,7 @@ CFLAGS_drm_trace_points.o := -I$(src) obj-$(CONFIG_DRM) += drm.o obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o +obj-$(CONFIG_DRM_ARM) += arm/ obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig new file mode 100644 index 000000000000..eaed454e043c --- /dev/null +++ b/drivers/gpu/drm/arm/Kconfig @@ -0,0 +1,27 @@ +config DRM_ARM + bool + help + Choose this option to select drivers for ARM's devices + +config DRM_HDLCD + tristate "ARM HDLCD" + depends on DRM && OF && (ARM || ARM64) + depends on COMMON_CLK + select DRM_ARM + select DRM_KMS_HELPER + select DRM_KMS_FB_HELPER + select DRM_KMS_CMA_HELPER + help + Choose this option if you have an ARM High Definition Colour LCD + controller. + + If M is selected the module will be called hdlcd. + +config DRM_HDLCD_SHOW_UNDERRUN + bool "Show underrun conditions" + depends on DRM_HDLCD + default n + help + Enable this option to show in red colour the pixels that the + HDLCD device did not fetch from framebuffer due to underrun + conditions. diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile new file mode 100644 index 000000000000..89dcb7bab93a --- /dev/null +++ b/drivers/gpu/drm/arm/Makefile @@ -0,0 +1,2 @@ +hdlcd-y := hdlcd_drv.o hdlcd_crtc.o +obj-$(CONFIG_DRM_HDLCD) += hdlcd.o diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c new file mode 100644 index 000000000000..fef1b04c2aab --- /dev/null +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2013-2015 ARM Limited + * Author: Liviu Dudau + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Implementation of a CRTC class for the HDLCD driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include