diff options
Diffstat (limited to 'include')
152 files changed, 5463 insertions, 1623 deletions
diff --git a/include/acpi/acpi_hest.h b/include/acpi/acpi_hest.h new file mode 100644 index 000000000000..63194d03cb2d --- /dev/null +++ b/include/acpi/acpi_hest.h @@ -0,0 +1,12 @@ +#ifndef __ACPI_HEST_H +#define __ACPI_HEST_H + +#include <linux/pci.h> + +#ifdef CONFIG_ACPI +extern int acpi_hest_firmware_first_pci(struct pci_dev *pci); +#else +static inline int acpi_hest_firmware_first_pci(struct pci_dev *pci) { return 0; } +#endif + +#endif diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 740ac3ad8fd0..8b668ead6d6e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -295,6 +295,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx void acpi_processor_ppc_init(void); void acpi_processor_ppc_exit(void); int acpi_processor_ppc_has_changed(struct acpi_processor *pr); +extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit); #else static inline void acpi_processor_ppc_init(void) { @@ -316,6 +317,11 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) } return 0; } +static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) +{ + return -ENODEV; +} + #endif /* CONFIG_CPU_FREQ */ /* in processor_throttling.c */ diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h index c8946465e63a..ecc44a8e2b44 100644 --- a/include/asm-generic/bitops/atomic.h +++ b/include/asm-generic/bitops/atomic.h @@ -15,19 +15,19 @@ # define ATOMIC_HASH_SIZE 4 # define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ])) -extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; +extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; /* Can't use raw_spin_lock_irq because of #include problems, so * this is the substitute */ #define _atomic_spin_lock_irqsave(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ local_irq_save(f); \ - __raw_spin_lock(s); \ + arch_spin_lock(s); \ } while(0) #define _atomic_spin_unlock_irqrestore(l,f) do { \ - raw_spinlock_t *s = ATOMIC_HASH(l); \ - __raw_spin_unlock(s); \ + arch_spinlock_t *s = ATOMIC_HASH(l); \ + arch_spin_unlock(s); \ local_irq_restore(f); \ } while(0) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 4b6755984d24..18c435d7c082 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -113,22 +113,22 @@ extern void warn_slowpath_null(const char *file, const int line); #endif #define WARN_ON_ONCE(condition) ({ \ - static int __warned; \ + static bool __warned; \ int __ret_warn_once = !!(condition); \ \ if (unlikely(__ret_warn_once)) \ if (WARN_ON(!__warned)) \ - __warned = 1; \ + __warned = true; \ unlikely(__ret_warn_once); \ }) #define WARN_ONCE(condition, format...) ({ \ - static int __warned; \ + static bool __warned; \ int __ret_warn_once = !!(condition); \ \ if (unlikely(__ret_warn_once)) \ if (WARN(!__warned, format)) \ - __warned = 1; \ + __warned = true; \ unlikely(__ret_warn_once); \ }) diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h index 495dc8af4044..681ddf3e844c 100644 --- a/include/asm-generic/fcntl.h +++ b/include/asm-generic/fcntl.h @@ -3,8 +3,6 @@ #include <linux/types.h> -/* open/fcntl - O_SYNC is only implemented on blocks devices and on files - located on an ext2 file system */ #define O_ACCMODE 00000003 #define O_RDONLY 00000000 #define O_WRONLY 00000001 @@ -27,8 +25,8 @@ #ifndef O_NONBLOCK #define O_NONBLOCK 00004000 #endif -#ifndef O_SYNC -#define O_SYNC 00010000 +#ifndef O_DSYNC +#define O_DSYNC 00010000 /* used to be O_SYNC, see below */ #endif #ifndef FASYNC #define FASYNC 00020000 /* fcntl, for BSD compatibility */ @@ -51,6 +49,25 @@ #ifndef O_CLOEXEC #define O_CLOEXEC 02000000 /* set close_on_exec */ #endif + +/* + * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using + * the O_SYNC flag. We continue to use the existing numerical value + * for O_DSYNC semantics now, but using the correct symbolic name for it. + * This new value is used to request true Posix O_SYNC semantics. It is + * defined in this strange way to make sure applications compiled against + * new headers get at least O_DSYNC semantics on older kernels. + * + * This has the nice side-effect that we can simply test for O_DSYNC + * wherever we do not care if O_DSYNC or O_SYNC is used. + * + * Note: __O_SYNC must never be used directly. + */ +#ifndef O_SYNC +#define __O_SYNC 04000000 +#define O_SYNC (__O_SYNC|O_DSYNC) +#endif + #ifndef O_NDELAY #define O_NDELAY O_NONBLOCK #endif diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 66d6106a2067..204bed37e82d 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -28,6 +28,7 @@ static inline int gpio_is_valid(int number) return ((unsigned)number) < ARCH_NR_GPIOS; } +struct device; struct seq_file; struct module; @@ -181,6 +182,8 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) #ifndef CONFIG_GPIO_SYSFS +struct device; + /* sysfs support is only available with gpiolib, where it's optional */ static inline int gpio_export(unsigned gpio, bool direction_may_change) diff --git a/include/asm-generic/mman-common.h b/include/asm-generic/mman-common.h index 5ee13b2fd223..20111265afd8 100644 --- a/include/asm-generic/mman-common.h +++ b/include/asm-generic/mman-common.h @@ -19,6 +19,11 @@ #define MAP_TYPE 0x0f /* Mask for type of mapping */ #define MAP_FIXED 0x10 /* Interpret addr exactly */ #define MAP_ANONYMOUS 0x20 /* don't use a file */ +#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED +# define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could be uninitialized */ +#else +# define MAP_UNINITIALIZED 0x0 /* Don't support this flag */ +#endif #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 90079c373f1c..8087b90d4673 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -56,6 +56,9 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; #define __raw_get_cpu_var(var) \ (*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset)) +#define this_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, my_cpu_offset) +#define __this_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, __my_cpu_offset) + #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA extern void setup_per_cpu_areas(void); @@ -66,6 +69,8 @@ extern void setup_per_cpu_areas(void); #define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var))) #define __get_cpu_var(var) per_cpu_var(var) #define __raw_get_cpu_var(var) per_cpu_var(var) +#define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) +#define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) #endif /* SMP */ diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index 7c38c147e5e6..6a0b30f78a62 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h @@ -622,9 +622,13 @@ __SYSCALL(__NR_move_pages, sys_move_pages) __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) #define __NR_perf_event_open 241 __SYSCALL(__NR_perf_event_open, sys_perf_event_open) +#define __NR_accept4 242 +__SYSCALL(__NR_accept4, sys_accept4) +#define __NR_recvmmsg 243 +__SYSCALL(__NR_recvmmsg, sys_recvmmsg) #undef __NR_syscalls -#define __NR_syscalls 242 +#define __NR_syscalls 244 /* * All syscalls below here should go away really, @@ -802,7 +806,7 @@ __SYSCALL(__NR_fork, sys_ni_syscall) #define __NR_statfs __NR3264_statfs #define __NR_fstatfs __NR3264_fstatfs #define __NR_truncate __NR3264_truncate -#define __NR_ftruncate __NR3264_truncate +#define __NR_ftruncate __NR3264_ftruncate #define __NR_lseek __NR3264_lseek #define __NR_sendfile __NR3264_sendfile #define __NR_newfstatat __NR3264_fstatat @@ -818,7 +822,7 @@ __SYSCALL(__NR_fork, sys_ni_syscall) #define __NR_statfs64 __NR3264_statfs #define __NR_fstatfs64 __NR3264_fstatfs #define __NR_truncate64 __NR3264_truncate -#define __NR_ftruncate64 __NR3264_truncate +#define __NR_ftruncate64 __NR3264_ftruncate #define __NR_llseek __NR3264_lseek #define __NR_sendfile64 __NR3264_sendfile #define __NR_fstatat64 __NR3264_fstatat diff --git a/include/drm/Kbuild b/include/drm/Kbuild index b940fdfa3b25..cfa6af43c9ea 100644 --- a/include/drm/Kbuild +++ b/include/drm/Kbuild @@ -8,3 +8,4 @@ unifdef-y += radeon_drm.h unifdef-y += sis_drm.h unifdef-y += savage_drm.h unifdef-y += via_drm.h +unifdef-y += nouveau_drm.h diff --git a/include/drm/drm.h b/include/drm/drm.h index 7cb50bdde46d..e3f46e0cb7dc 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -36,17 +36,27 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) + #include <linux/types.h> -#include <asm/ioctl.h> /* For _IO* macros */ -#define DRM_IOCTL_NR(n) _IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#include <asm/ioctl.h> +typedef unsigned int drm_handle_t; -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 +#else /* One of the BSDs */ + +#include <sys/ioccom.h> +#include <sys/types.h> +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef unsigned long drm_handle_t; + +#endif #define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ @@ -59,7 +69,6 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned int drm_handle_t; typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; @@ -454,6 +463,7 @@ struct drm_irq_busid { enum drm_vblank_seq_type { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ @@ -461,8 +471,8 @@ enum drm_vblank_seq_type { }; #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ - _DRM_VBLANK_NEXTONMISS) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ + _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) struct drm_wait_vblank_request { enum drm_vblank_seq_type type; @@ -686,6 +696,8 @@ struct drm_gem_open { #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) +#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) /** * Device specific ioctls should only be in their respective headers @@ -698,6 +710,35 @@ struct drm_gem_open { #define DRM_COMMAND_BASE 0x40 #define DRM_COMMAND_END 0xA0 +/** + * Header for events written back to userspace on the drm fd. The + * type defines the type of event, the length specifies the total + * length of the event (including the header), and user_data is + * typically a 64 bit value passed with the ioctl that triggered the + * event. A read on the drm fd will always only return complete + * events, that is, if for example the read buffer is 100 bytes, and + * there are two 64 byte events pending, only one will be returned. + * + * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and + * up are chipset specific. + */ +struct drm_event { + __u32 type; + __u32 length; +}; + +#define DRM_EVENT_VBLANK 0x01 +#define DRM_EVENT_FLIP_COMPLETE 0x02 + +struct drm_event_vblank { + struct drm_event base; + __u64 user_data; + __u32 tv_sec; + __u32 tv_usec; + __u32 sequence; + __u32 reserved; +}; + /* typedef area */ #ifndef __KERNEL__ typedef struct drm_clip_rect drm_clip_rect_t; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c8e64bbadbcf..19ef8ebdc662 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -245,16 +245,6 @@ extern void drm_ut_debug_printk(unsigned int request_level, #endif -#define DRM_PROC_LIMIT (PAGE_SIZE-80) - -#define DRM_PROC_PRINT(fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; } - -#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } - /*@}*/ /***********************************************************************/ @@ -265,19 +255,8 @@ extern void drm_ut_debug_printk(unsigned int request_level, #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) -#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) #define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/** - * Get the private SAREA mapping. - * - * \param _dev DRM device. - * \param _ctx context number. - * \param _map output mapping. - */ -#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ - (_map) = (_dev)->context_sareas[_ctx]; \ -} while(0) /** * Test that the hardware lock is held by the caller, returning otherwise. @@ -297,18 +276,6 @@ do { \ } while (0) /** - * Copy and IOCTL return string to user space - */ -#define DRM_COPY( name, value ) \ - len = strlen( value ); \ - if ( len > name##_len ) len = name##_len; \ - name##_len = strlen( value ); \ - if ( len && name ) { \ - if ( copy_to_user( name, value, len ) ) \ - return -EFAULT; \ - } - -/** * Ioctl function type. * * \param inode device inode. @@ -322,6 +289,9 @@ typedef int drm_ioctl_t(struct drm_device *dev, void *data, typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg); +#define DRM_IOCTL_NR(n) _IOC_NR(n) +#define DRM_MAJOR 226 + #define DRM_AUTH 0x1 #define DRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 @@ -426,6 +396,14 @@ struct drm_buf_entry { struct drm_freelist freelist; }; +/* Event queued up for userspace to read */ +struct drm_pending_event { + struct drm_event *event; + struct list_head link; + struct drm_file *file_priv; + void (*destroy)(struct drm_pending_event *event); +}; + /** File private data */ struct drm_file { int authenticated; @@ -449,6 +427,10 @@ struct drm_file { struct drm_master *master; /* master this node is currently associated with N.B. not always minor->master */ struct list_head fbs; + + wait_queue_head_t event_wait; + struct list_head event_list; + int event_space; }; /** Wait queue */ @@ -795,6 +777,15 @@ struct drm_driver { /* Master routines */ int (*master_create)(struct drm_device *dev, struct drm_master *master); void (*master_destroy)(struct drm_device *dev, struct drm_master *master); + /** + * master_set is called whenever the minor master is set. + * master_drop is called whenever the minor master is dropped. + */ + + int (*master_set)(struct drm_device *dev, struct drm_file *file_priv, + bool from_open); + void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv, + bool from_release); int (*proc_init)(struct drm_minor *minor); void (*proc_cleanup)(struct drm_minor *minor); @@ -900,6 +891,12 @@ struct drm_minor { struct drm_mode_group mode_group; }; +struct drm_pending_vblank_event { + struct drm_pending_event base; + int pipe; + struct drm_event_vblank event; +}; + /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. @@ -999,6 +996,12 @@ struct drm_device { u32 max_vblank_count; /**< size of vblank counter register */ + /** + * List of events + */ + struct list_head vblank_event_list; + spinlock_t event_lock; + /*@} */ cycles_t ctx_start; cycles_t lck_start; @@ -1135,6 +1138,8 @@ extern int drm_lastclose(struct drm_device *dev); extern int drm_open(struct inode *inode, struct file *filp); extern int drm_stub_open(struct inode *inode, struct file *filp); extern int drm_fasync(int fd, struct file *filp, int on); +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); /* Mapping support (drm_vm.h) */ @@ -1295,6 +1300,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc); extern void drm_handle_vblank(struct drm_device *dev, int crtc); extern int drm_vblank_get(struct drm_device *dev, int crtc); extern void drm_vblank_put(struct drm_device *dev, int crtc); +extern void drm_vblank_off(struct drm_device *dev, int crtc); extern void drm_vblank_cleanup(struct drm_device *dev); /* Modesetting support */ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); @@ -1519,14 +1525,27 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) { + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + if (size * nmemb <= PAGE_SIZE) return kcalloc(nmemb, size, GFP_KERNEL); + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); +} + +/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ +static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) +{ if (size != 0 && nmemb > ULONG_MAX / size) return NULL; + if (size * nmemb <= PAGE_SIZE) + return kmalloc(nmemb * size, GFP_KERNEL); + return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); + GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); } static __inline void drm_free_large(void *ptr) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b69347b8904f..fdf43abc36db 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -123,7 +123,7 @@ struct drm_display_mode { int type; /* Proposed mode values */ - int clock; + int clock; /* in kHz */ int hdisplay; int hsync_start; int hsync_end; @@ -164,8 +164,8 @@ struct drm_display_mode { int *private; int private_flags; - int vrefresh; - float hsync; + int vrefresh; /* in Hz */ + int hsync; /* in kHz */ }; enum drm_connector_status { @@ -242,6 +242,21 @@ struct drm_framebuffer_funcs { int (*create_handle)(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int *handle); + /** + * Optinal callback for the dirty fb ioctl. + * + * Userspace can notify the driver via this callback + * that a area of the framebuffer has changed and should + * be flushed to the display hardware. + * + * See documentation in drm_mode.h for the struct + * drm_mode_fb_dirty_cmd for more information as all + * the semantics and arguments have a one to one mapping + * on this function. + */ + int (*dirty)(struct drm_framebuffer *framebuffer, unsigned flags, + unsigned color, struct drm_clip_rect *clips, + unsigned num_clips); }; struct drm_framebuffer { @@ -256,7 +271,7 @@ struct drm_framebuffer { unsigned int depth; int bits_per_pixel; int flags; - void *fbdev; + struct fb_info *fbdev; u32 pseudo_palette[17]; struct list_head filp_head; /* if you are using the helper */ @@ -290,6 +305,7 @@ struct drm_property { struct drm_crtc; struct drm_connector; struct drm_encoder; +struct drm_pending_vblank_event; /** * drm_crtc_funcs - control CRTCs for a given device @@ -333,6 +349,19 @@ struct drm_crtc_funcs { void (*destroy)(struct drm_crtc *crtc); int (*set_config)(struct drm_mode_set *set); + + /* + * Flip to the given framebuffer. This implements the page + * flip ioctl descibed in drm_mode.h, specifically, the + * implementation must return immediately and block all + * rendering to the current fb until the flip has completed. + * If userspace set the event flag in the ioctl, the event + * argument will point to an event to send back when the flip + * completes, otherwise it will be NULL. + */ + int (*page_flip)(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event); }; /** @@ -596,6 +625,7 @@ struct drm_mode_config { /* Optional properties */ struct drm_property *scaling_mode_property; struct drm_property *dithering_mode_property; + struct drm_property *dirty_info_property; }; #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) @@ -667,6 +697,7 @@ extern void drm_mode_validate_size(struct drm_device *dev, extern void drm_mode_prune_invalid(struct drm_device *dev, struct list_head *mode_list, bool verbose); extern void drm_mode_sort(struct list_head *mode_list); +extern int drm_mode_hsync(struct drm_display_mode *mode); extern int drm_mode_vrefresh(struct drm_display_mode *mode); extern void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags); @@ -703,6 +734,7 @@ extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats char *formats[]); extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); extern int drm_mode_create_dithering_property(struct drm_device *dev); +extern int drm_mode_create_dirty_info_property(struct drm_device *dev); extern char *drm_get_encoder_name(struct drm_encoder *encoder); extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, @@ -711,7 +743,8 @@ extern void drm_mode_connector_detach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); -extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); +extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, + uint32_t id, uint32_t type); /* IOCTLs */ extern int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -730,6 +763,8 @@ extern int drm_mode_rmfb(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_getfb(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mode_dirtyfb_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); extern int drm_mode_addmode_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_rmmode_ioctl(struct drm_device *dev, @@ -756,6 +791,8 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern bool drm_detect_hdmi_monitor(struct edid *edid); +extern int drm_mode_page_flip_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool reduced, bool interlaced, bool margins); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h new file mode 100644 index 000000000000..a49e791db0b0 --- /dev/null +++ b/include/drm/drm_dp_helper.h @@ -0,0 +1,180 @@ +/* + * Copyright © 2008 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _DRM_DP_HELPER_H_ +#define _DRM_DP_HELPER_H_ + +/* From the VESA DisplayPort spec */ + +#define AUX_NATIVE_WRITE 0x8 +#define AUX_NATIVE_READ 0x9 +#define AUX_I2C_WRITE 0x0 +#define AUX_I2C_READ 0x1 +#define AUX_I2C_STATUS 0x2 +#define AUX_I2C_MOT 0x4 + +#define AUX_NATIVE_REPLY_ACK (0x0 << 4) +#define AUX_NATIVE_REPLY_NACK (0x1 << 4) +#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) +#define AUX_NATIVE_REPLY_MASK (0x3 << 4) + +#define AUX_I2C_REPLY_ACK (0x0 << 6) +#define AUX_I2C_REPLY_NACK (0x1 << 6) +#define AUX_I2C_REPLY_DEFER (0x2 << 6) +#define AUX_I2C_REPLY_MASK (0x3 << 6) + +/* AUX CH addresses */ +/* DPCD */ +#define DP_DPCD_REV 0x000 + +#define DP_MAX_LINK_RATE 0x001 + +#define DP_MAX_LANE_COUNT 0x002 +# define DP_MAX_LANE_COUNT_MASK 0x1f +# define DP_ENHANCED_FRAME_CAP (1 << 7) + +#define DP_MAX_DOWNSPREAD 0x003 +# define DP_NO_AUX_HANDSHAKE_LINK_TRAINING (1 << 6) + +#define DP_NORP 0x004 + +#define DP_DOWNSTREAMPORT_PRESENT 0x005 +# define DP_DWN_STRM_PORT_PRESENT (1 << 0) +# define DP_DWN_STRM_PORT_TYPE_MASK 0x06 +/* 00b = DisplayPort */ +/* 01b = Analog */ +/* 10b = TMDS or HDMI */ +/* 11b = Other */ +# define DP_FORMAT_CONVERSION (1 << 3) + +#define DP_MAIN_LINK_CHANNEL_CODING 0x006 + +/* link configuration */ +#define DP_LINK_BW_SET 0x100 +# define DP_LINK_BW_1_62 0x06 +# define DP_LINK_BW_2_7 0x0a + +#define DP_LANE_COUNT_SET 0x101 +# define DP_LANE_COUNT_MASK 0x0f +# define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) + +#define DP_TRAINING_PATTERN_SET 0x102 +# define DP_TRAINING_PATTERN_DISABLE 0 +# define DP_TRAINING_PATTERN_1 1 +# define DP_TRAINING_PATTERN_2 2 +# define DP_TRAINING_PATTERN_MASK 0x3 + +# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) +# define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) +# define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) +# define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) +# define DP_LINK_QUAL_PATTERN_MASK (3 << 2) + +# define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) +# define DP_LINK_SCRAMBLING_DISABLE (1 << 5) + +# define DP_SYMBOL_ERROR_COUNT_BOTH (0 << 6) +# define DP_SYMBOL_ERROR_COUNT_DISPARITY (1 << 6) +# define DP_SYMBOL_ERROR_COUNT_SYMBOL (2 << 6) +# define DP_SYMBOL_ERROR_COUNT_MASK (3 << 6) + +#define DP_TRAINING_LANE0_SET 0x103 +#define DP_TRAINING_LANE1_SET 0x104 +#define DP_TRAINING_LANE2_SET 0x105 +#define DP_TRAINING_LANE3_SET 0x106 + +# define DP_TRAIN_VOLTAGE_SWING_MASK 0x3 +# define DP_TRAIN_VOLTAGE_SWING_SHIFT 0 +# define DP_TRAIN_MAX_SWING_REACHED (1 << 2) +# define DP_TRAIN_VOLTAGE_SWING_400 (0 << 0) +# define DP_TRAIN_VOLTAGE_SWING_600 (1 << 0) +# define DP_TRAIN_VOLTAGE_SWING_800 (2 << 0) +# define DP_TRAIN_VOLTAGE_SWING_1200 (3 << 0) + +# define DP_TRAIN_PRE_EMPHASIS_MASK (3 << 3) +# define DP_TRAIN_PRE_EMPHASIS_0 (0 << 3) +# define DP_TRAIN_PRE_EMPHASIS_3_5 (1 << 3) +# define DP_TRAIN_PRE_EMPHASIS_6 (2 << 3) +# define DP_TRAIN_PRE_EMPHASIS_9_5 (3 << 3) + +# define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 +# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) + +#define DP_DOWNSPREAD_CTRL 0x107 +# define DP_SPREAD_AMP_0_5 (1 << 4) + +#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 +# define DP_SET_ANSI_8B10B (1 << 0) + +#define DP_LANE0_1_STATUS 0x202 +#define DP_LANE2_3_STATUS 0x203 +# define DP_LANE_CR_DONE (1 << 0) +# define DP_LANE_CHANNEL_EQ_DONE (1 << 1) +# define DP_LANE_SYMBOL_LOCKED (1 << 2) + +#define DP_CHANNEL_EQ_BITS (DP_LANE_CR_DONE | \ + DP_LANE_CHANNEL_EQ_DONE | \ + DP_LANE_SYMBOL_LOCKED) + +#define DP_LANE_ALIGN_STATUS_UPDATED 0x204 + +#define DP_INTERLANE_ALIGN_DONE (1 << 0) +#define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6) +#define DP_LINK_STATUS_UPDATED (1 << 7) + +#define DP_SINK_STATUS 0x205 + +#define DP_RECEIVE_PORT_0_STATUS (1 << 0) +#define DP_RECEIVE_PORT_1_STATUS (1 << 1) + +#define DP_ADJUST_REQUEST_LANE0_1 0x206 +#define DP_ADJUST_REQUEST_LANE2_3 0x207 +# define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 +# define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 +# define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c +# define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 +# define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 +# define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 +# define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 +# define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 + +#define DP_SET_POWER 0x600 +# define DP_SET_POWER_D0 0x1 +# define DP_SET_POWER_D3 0x2 + +#define MODE_I2C_START 1 +#define MODE_I2C_WRITE 2 +#define MODE_I2C_READ 4 +#define MODE_I2C_STOP 8 + +struct i2c_algo_dp_aux_data { + bool running; + u16 address; + int (*aux_ch) (struct i2c_adapter *adapter, + int mode, uint8_t write_byte, + uint8_t *read_byte); +}; + +int +i2c_dp_aux_add_bus(struct i2c_adapter *adapter); + +#endif /* _DRM_DP_HELPER_H_ */ diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 7d6c9a2dfcbb..d33c3e038606 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -106,6 +106,10 @@ struct detailed_data_color_point { u8 wpindex2[3]; } __attribute__((packed)); +struct cvt_timing { + u8 code[3]; +} __attribute__((packed)); + struct detailed_non_pixel { u8 pad1; u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name @@ -117,9 +121,13 @@ struct detailed_non_pixel { struct detailed_data_monitor_range range; struct detailed_data_wpindex color; struct std_timing timings[5]; + struct cvt_timing cvt[4]; } data; } __attribute__((packed)); +#define EDID_DETAIL_EST_TIMINGS 0xf7 +#define EDID_DETAIL_CVT_3BYTE 0xf8 +#define EDID_DETAIL_COLOR_MGMT_DATA 0xf9 #define EDID_DETAIL_STD_MODES 0xfa #define EDID_DETAIL_MONITOR_CPDATA 0xfb #define EDID_DETAIL_MONITOR_NAME 0xfc diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 62329f9a42cb..4c10be39a43b 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -66,6 +66,13 @@ extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, unsigned long size, unsigned alignment, int atomic); +extern struct drm_mm_node *drm_mm_get_block_range_generic( + struct drm_mm_node *node, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int atomic); static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, unsigned long size, unsigned alignment) @@ -78,11 +85,38 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *pa { return drm_mm_get_block_generic(parent, size, alignment, 1); } +static inline struct drm_mm_node *drm_mm_get_block_range( + struct drm_mm_node *parent, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + return drm_mm_get_block_range_generic(parent, size, alignment, + start, end, 0); +} +static inline struct drm_mm_node *drm_mm_get_block_atomic_range( + struct drm_mm_node *parent, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + return drm_mm_get_block_range_generic(parent, size, alignment, + start, end, 1); +} extern void drm_mm_put_block(struct drm_mm_node *cur); extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size, unsigned alignment, int best_match); +extern struct drm_mm_node *drm_mm_search_free_in_range( + const struct drm_mm *mm, + unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end, + int best_match); extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size); extern void drm_mm_takedown(struct drm_mm *mm); @@ -99,6 +133,7 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) return block->mm; } +extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix); #ifdef CONFIG_DEBUG_FS int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm); #endif diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 1f908416aedb..43009bc2e757 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -27,9 +27,6 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H -#include <linux/kernel.h> -#include <linux/types.h> - #define DRM_DISPLAY_INFO_LEN 32 #define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 @@ -78,6 +75,11 @@ #define DRM_MODE_DITHERING_OFF 0 #define DRM_MODE_DITHERING_ON 1 +/* Dirty info options */ +#define DRM_MODE_DIRTY_OFF 0 +#define DRM_MODE_DIRTY_ON 1 +#define DRM_MODE_DIRTY_ANNOTATE 2 + struct drm_mode_modeinfo { __u32 clock; __u16 hdisplay, hsync_start, hsync_end, htotal, hskew; @@ -225,6 +227,45 @@ struct drm_mode_fb_cmd { __u32 handle; }; +#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 +#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 +#define DRM_MODE_FB_DIRTY_FLAGS 0x03 + +/* + * Mark a region of a framebuffer as dirty. + * + * Some hardware does not automatically update display contents + * as a hardware or software draw to a framebuffer. This ioctl + * allows userspace to tell the kernel and the hardware what + * regions of the framebuffer have changed. + * + * The kernel or hardware is free to update more then just the + * region specified by the clip rects. The kernel or hardware + * may also delay and/or coalesce several calls to dirty into a + * single update. + * + * Userspace may annotate the updates, the annotates are a + * promise made by the caller that the change is either a copy + * of pixels or a fill of a single color in the region specified. + * + * If the DRM_MODE_FB_DIRTY_ANNOTATE_COPY flag is given then + * the number of updated regions are half of num_clips given, + * where the clip rects are paired in src and dst. The width and + * height of each one of the pairs must match. + * + * If the DRM_MODE_FB_DIRTY_ANNOTATE_FILL flag is given the caller + * promises that the region specified of the clip rects is filled + * completely with a single color as given in the color argument. + */ + +struct drm_mode_fb_dirty_cmd { + __u32 fb_id; + __u32 flags; + __u32 color; + __u32 num_clips; + __u64 clips_ptr; +}; + struct drm_mode_mode_cmd { __u32 connector_id; struct drm_mode_modeinfo mode; @@ -268,4 +309,37 @@ struct drm_mode_crtc_lut { __u64 blue; }; +#define DRM_MODE_PAGE_FLIP_EVENT 0x01 +#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT + +/* + * Request a page flip on the specified crtc. + * + * This ioctl will ask KMS to schedule a page flip for the specified + * crtc. Once any pending rendering targeting the specified fb (as of + * ioctl time) has completed, the crtc will be reprogrammed to display + * that fb after the next vertical refresh. The ioctl returns + * immediately, but subsequent rendering to the current fb will block + * in the execbuffer ioctl until the page flip happens. If a page + * flip is already pending as the ioctl is called, EBUSY will be + * returned. + * + * The ioctl supports one flag, DRM_MODE_PAGE_FLIP_EVENT, which will + * request that drm sends back a vblank event (see drm.h: struct + * drm_event_vblank) when the page flip is done. The user_data field + * passed in with this ioctl will be returned as the user_data field + * in the vblank event struct. + * + * The reserved field must be zero until we figure out something + * clever to use it for. + */ + +struct drm_mode_crtc_page_flip { + __u32 crtc_id; + __u32 fb_id; + __u32 flags; + __u32 reserved; + __u64 user_data; +}; + #endif diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h index 26641e95e0a4..393369147a2d 100644 --- a/include/drm/drm_os_linux.h +++ b/include/drm/drm_os_linux.h @@ -123,5 +123,5 @@ do { \ remove_wait_queue(&(queue), &entry); \ } while (0) -#define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) +#define DRM_WAKEUP( queue ) wake_up( queue ) #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) diff --git a/include/drm/i2c/ch7006.h b/include/drm/i2c/ch7006.h new file mode 100644 index 000000000000..8390b437a1f8 --- /dev/null +++ b/include/drm/i2c/ch7006.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * All Rights Reserved. + * + * 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 __DRM_I2C_CH7006_H__ +#define __DRM_I2C_CH7006_H__ + +/** + * struct ch7006_encoder_params + * + * Describes how the ch7006 is wired up with the GPU. It should be + * used as the @params parameter of its @set_config method. + * + * See "http://www.chrontel.com/pdf/7006.pdf" for their precise + * meaning. + */ +struct ch7006_encoder_params { + enum { + CH7006_FORMAT_RGB16 = 0, + CH7006_FORMAT_YCrCb24m16, + CH7006_FORMAT_RGB24m16, + CH7006_FORMAT_RGB15, + CH7006_FORMAT_RGB24m12C, + CH7006_FORMAT_RGB24m12I, + CH7006_FORMAT_RGB24m8, + CH7006_FORMAT_RGB16m8, + CH7006_FORMAT_RGB15m8, + CH7006_FORMAT_YCrCb24m8, + } input_format; + + enum { + CH7006_CLOCK_SLAVE = 0, + CH7006_CLOCK_MASTER, + } clock_mode; + + enum { + CH7006_CLOCK_EDGE_NEG = 0, + CH7006_CLOCK_EDGE_POS, + } clock_edge; + + int xcm, pcm; + + enum { + CH7006_SYNC_SLAVE = 0, + CH7006_SYNC_MASTER, + } sync_direction; + + enum { + CH7006_SYNC_SEPARATED = 0, + CH7006_SYNC_EMBEDDED, + } sync_encoding; + + enum { + CH7006_POUT_1_8V = 0, + CH7006_POUT_3_3V, + } pout_level; + + enum { + CH7006_ACTIVE_HSYNC = 0, + CH7006_ACTIVE_DSTART, + } active_detect; +}; + +#endif diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7e0cb1da92e6..ec3f5e80a5df 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -27,11 +27,11 @@ #ifndef _I915_DRM_H_ #define _I915_DRM_H_ +#include "drm.h" + /* Please note that modifications to all structs defined here are * subject to backwards-compatibility constraints. */ -#include <linux/types.h> -#include "drm.h" /* Each region is a minimum of 16k, and there are at most 255 of them. */ @@ -186,6 +186,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_MMAP_GTT 0x24 #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 #define DRM_I915_GEM_MADVISE 0x26 +#define DRM_I915_OVERLAY_PUT_IMAGE 0x27 +#define DRM_I915_OVERLAY_ATTRS 0x28 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -221,8 +223,10 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) -#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id) +#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) +#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) +#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -266,6 +270,8 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_CHIPSET_ID 4 #define I915_PARAM_HAS_GEM 5 #define I915_PARAM_NUM_FENCES_AVAIL 6 +#define I915_PARAM_HAS_OVERLAY 7 +#define I915_PARAM_HAS_PAGEFLIPPING 8 typedef struct drm_i915_getparam { int param; @@ -686,4 +692,70 @@ struct drm_i915_gem_madvise { __u32 retained; }; +/* flags */ +#define I915_OVERLAY_TYPE_MASK 0xff +#define I915_OVERLAY_YUV_PLANAR 0x01 +#define I915_OVERLAY_YUV_PACKED 0x02 +#define I915_OVERLAY_RGB 0x03 + +#define I915_OVERLAY_DEPTH_MASK 0xff00 +#define I915_OVERLAY_RGB24 0x1000 +#define I915_OVERLAY_RGB16 0x2000 +#define I915_OVERLAY_RGB15 0x3000 +#define I915_OVERLAY_YUV422 0x0100 +#define I915_OVERLAY_YUV411 0x0200 +#define I915_OVERLAY_YUV420 0x0300 +#define I915_OVERLAY_YUV410 0x0400 + +#define I915_OVERLAY_SWAP_MASK 0xff0000 +#define I915_OVERLAY_NO_SWAP 0x000000 +#define I915_OVERLAY_UV_SWAP 0x010000 +#define I915_OVERLAY_Y_SWAP 0x020000 +#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000 + +#define I915_OVERLAY_FLAGS_MASK 0xff000000 +#define I915_OVERLAY_ENABLE 0x01000000 + +struct drm_intel_overlay_put_image { + /* various flags and src format description */ + __u32 flags; + /* source picture description */ + __u32 bo_handle; + /* stride values and offsets are in bytes, buffer relative */ + __u16 stride_Y; /* stride for packed formats */ + __u16 stride_UV; + __u32 offset_Y; /* offset for packet formats */ + __u32 offset_U; + __u32 offset_V; + /* in pixels */ + __u16 src_width; + __u16 src_height; + /* to compensate the scaling factors for partially covered surfaces */ + __u16 src_scan_width; + __u16 src_scan_height; + /* output crtc description */ + __u32 crtc_id; + __u16 dst_x; + __u16 dst_y; + __u16 dst_width; + __u16 dst_height; +}; + +/* flags */ +#define I915_OVERLAY_UPDATE_ATTRS (1<<0) +#define I915_OVERLAY_UPDATE_GAMMA (1<<1) +struct drm_intel_overlay_attrs { + __u32 flags; + __u32 color_key; + __s32 brightness; + __u32 contrast; + __u32 saturation; + __u32 gamma0; + __u32 gamma1; + __u32 gamma2; + __u32 gamma3; + __u32 gamma4; + __u32 gamma5; +}; + #endif /* _I915_DRM_H_ */ diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 325fd6fb4a42..3ffbc4798afa 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h @@ -35,7 +35,7 @@ #ifndef __MGA_DRM_H__ #define __MGA_DRM_H__ -#include <linux/types.h> +#include "drm.h" /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (mga_sarea.h) diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h new file mode 100644 index 000000000000..1e67c441ea82 --- /dev/null +++ b/include/drm/nouveau_drm.h @@ -0,0 +1,220 @@ +/* + * Copyright 2005 Stephane Marchesin. + * All Rights Reserved. + * + * 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 __NOUVEAU_DRM_H__ +#define __NOUVEAU_DRM_H__ + +#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15 + +struct drm_nouveau_channel_alloc { + uint32_t fb_ctxdma_handle; + uint32_t tt_ctxdma_handle; + + int channel; + + /* Notifier memory */ + uint32_t notifier_handle; + + /* DRM-enforced subchannel assignments */ + struct { + uint32_t handle; + uint32_t grclass; + } subchan[8]; + uint32_t nr_subchan; +}; + +struct drm_nouveau_channel_free { + int channel; +}; + +struct drm_nouveau_grobj_alloc { + int channel; + uint32_t handle; + int class; +}; + +struct drm_nouveau_notifierobj_alloc { + uint32_t channel; + uint32_t handle; + uint32_t size; + uint32_t offset; +}; + +struct drm_nouveau_gpuobj_free { + int channel; + uint32_t handle; +}; + +/* FIXME : maybe unify {GET,SET}PARAMs */ +#define NOUVEAU_GETPARAM_PCI_VENDOR 3 +#define NOUVEAU_GETPARAM_PCI_DEVICE 4 +#define NOUVEAU_GETPARAM_BUS_TYPE 5 +#define NOUVEAU_GETPARAM_FB_PHYSICAL 6 +#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 +#define NOUVEAU_GETPARAM_FB_SIZE 8 +#define NOUVEAU_GETPARAM_AGP_SIZE 9 +#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10 +#define NOUVEAU_GETPARAM_CHIPSET_ID 11 +#define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 +struct drm_nouveau_getparam { + uint64_t param; + uint64_t value; +}; + +struct drm_nouveau_setparam { + uint64_t param; + uint64_t value; +}; + +#define NOUVEAU_GEM_DOMAIN_CPU (1 << 0) +#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) +#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) +#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) + +struct drm_nouveau_gem_info { + uint32_t handle; + uint32_t domain; + uint64_t size; + uint64_t offset; + uint64_t map_handle; + uint32_t tile_mode; + uint32_t tile_flags; +}; + +struct drm_nouveau_gem_new { + struct drm_nouveau_gem_info info; + uint32_t channel_hint; + uint32_t align; +}; + +struct drm_nouveau_gem_pushbuf_bo { + uint64_t user_priv; + uint32_t handle; + uint32_t read_domains; + uint32_t write_domains; + uint32_t valid_domains; + uint32_t presumed_ok; + uint32_t presumed_domain; + uint64_t presumed_offset; +}; + +#define NOUVEAU_GEM_RELOC_LOW (1 << 0) +#define NOUVEAU_GEM_RELOC_HIGH (1 << 1) +#define NOUVEAU_GEM_RELOC_OR (1 << 2) +struct drm_nouveau_gem_pushbuf_reloc { + uint32_t bo_index; + uint32_t reloc_index; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; +}; + +#define NOUVEAU_GEM_MAX_BUFFERS 1024 +#define NOUVEAU_GEM_MAX_RELOCS 1024 + +struct drm_nouveau_gem_pushbuf { + uint32_t channel; + uint32_t nr_dwords; + uint32_t nr_buffers; + uint32_t nr_relocs; + uint64_t dwords; + uint64_t buffers; + uint64_t relocs; +}; + +struct drm_nouveau_gem_pushbuf_call { + uint32_t channel; + uint32_t handle; + uint32_t offset; + uint32_t nr_buffers; + uint32_t nr_relocs; + uint32_t nr_dwords; + uint64_t buffers; + uint64_t relocs; + uint32_t suffix0; + uint32_t suffix1; + /* below only accessed for CALL2 */ + uint64_t vram_available; + uint64_t gart_available; +}; + +struct drm_nouveau_gem_pin { + uint32_t handle; + uint32_t domain; + uint64_t offset; +}; + +struct drm_nouveau_gem_unpin { + uint32_t handle; +}; + +#define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 +#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 +#define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 +struct drm_nouveau_gem_cpu_prep { + uint32_t handle; + uint32_t flags; +}; + +struct drm_nouveau_gem_cpu_fini { + uint32_t handle; +}; + +struct drm_nouveau_gem_tile { + uint32_t handle; + uint32_t offset; + uint32_t size; + uint32_t tile_mode; + uint32_t tile_flags; +}; + +enum nouveau_bus_type { + NV_AGP = 0, + NV_PCI = 1, + NV_PCIE = 2, +}; + +struct drm_nouveau_sarea { +}; + +#define DRM_NOUVEAU_CARD_INIT 0x00 +#define DRM_NOUVEAU_GETPARAM 0x01 +#define DRM_NOUVEAU_SETPARAM 0x02 +#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 +#define DRM_NOUVEAU_CHANNEL_FREE 0x04 +#define DRM_NOUVEAU_GROBJ_ALLOC 0x05 +#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 +#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 +#define DRM_NOUVEAU_GEM_NEW 0x40 +#define DRM_NOUVEAU_GEM_PUSHBUF 0x41 +#define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42 +#define DRM_NOUVEAU_GEM_PIN 0x43 /* !KMS only */ +#define DRM_NOUVEAU_GEM_UNPIN 0x44 /* !KMS only */ +#define DRM_NOUVEAU_GEM_CPU_PREP 0x45 +#define DRM_NOUVEAU_GEM_CPU_FINI 0x46 +#define DRM_NOUVEAU_GEM_INFO 0x47 +#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48 + +#endif /* __NOUVEAU_DRM_H__ */ diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3b9932ab1756..39537f3cf98a 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -33,7 +33,7 @@ #ifndef __RADEON_DRM_H__ #define __RADEON_DRM_H__ -#include <linux/types.h> +#include "drm.h" /* WARNING: If you change any of these defines, make sure to change the * defines in the X server file (radeon_sarea.h) diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 491146170522..81eb9f45883c 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -44,6 +44,29 @@ struct ttm_bo_device; struct drm_mm_node; + +/** + * struct ttm_placement + * + * @fpfn: first valid page frame number to put the object + * @lpfn: last valid page frame number to put the object + * @num_placement: number of prefered placements + * @placement: prefered placements + * @num_busy_placement: number of prefered placements when need to evict buffer + * @busy_placement: prefered placements when need to evict buffer + * + * Structure indicating the placement you request for an object. + */ +struct ttm_placement { + unsigned fpfn; + unsigned lpfn; + unsigned num_placement; + const uint32_t *placement; + unsigned num_busy_placement; + const uint32_t *busy_placement; +}; + + /** * struct ttm_mem_reg * @@ -109,10 +132,6 @@ struct ttm_tt; * the object is destroyed. * @event_queue: Queue for processes waiting on buffer object status change. * @lock: spinlock protecting mostly synchronization members. - * @proposed_placement: Proposed placement for the buffer. Changed only by the - * creator prior to validation as opposed to bo->mem.proposed_flags which is - * changed by the implementation prior to a buffer move if it wants to outsmart - * the buffer creator / user. This latter happens, for example, at eviction. * @mem: structure describing current placement. * @persistant_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member @@ -177,7 +196,6 @@ struct ttm_buffer_object { * Members protected by the bo::reserved lock. */ - uint32_t proposed_placement; struct ttm_mem_reg mem; struct file *persistant_swap_storage; struct ttm_tt *ttm; @@ -285,29 +303,30 @@ ttm_bo_reference(struct ttm_buffer_object *bo) * Note: It might be necessary to block validations before the * wait by reserving the buffer. * Returns -EBUSY if no_wait is true and the buffer is busy. - * Returns -ERESTART if interrupted by a signal. + * Returns -ERESTARTSYS if interrupted by a signal. */ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, bool interruptible, bool no_wait); /** - * ttm_buffer_object_validate + * ttm_bo_validate * * @bo: The buffer object. - * @proposed_placement: Proposed_placement for the buffer object. + * @placement: Proposed placement for the buffer object. * @interruptible: Sleep interruptible if sleeping. * @no_wait: Return immediately if the buffer is busy. * * Changes placement and caching policy of the buffer object - * according to bo::proposed_flags. + * according proposed placement. * Returns - * -EINVAL on invalid proposed_flags. + * -EINVAL on invalid proposed placement. * -ENOMEM on out-of-memory condition. * -EBUSY if no_wait is true and buffer busy. - * -ERESTART if interrupted by a signal. + * -ERESTARTSYS if interrupted by a signal. */ -extern int ttm_buffer_object_validate(struct ttm_buffer_object *bo, - uint32_t proposed_placement, - bool interruptible, bool no_wait); +extern int ttm_bo_validate(struct ttm_buffer_object *bo, + struct ttm_placement *placement, + bool interruptible, bool no_wait); + /** * ttm_bo_unref * @@ -328,7 +347,7 @@ extern void ttm_bo_unref(struct ttm_buffer_object **bo); * waiting for buffer idle. This lock is recursive. * Returns * -EBUSY if the buffer is busy and no_wait is true. - * -ERESTART if interrupted by a signal. + * -ERESTARTSYS if interrupted by a signal. */ extern int @@ -343,7 +362,7 @@ ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait); extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); /** - * ttm_buffer_object_init + * ttm_bo_init * * @bdev: Pointer to a ttm_bo_device struct. * @bo: Pointer to a ttm_buffer_object to be initialized. @@ -371,20 +390,20 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); * Returns * -ENOMEM: Out of memory. * -EINVAL: Invalid placement flags. - * -ERESTART: Interrupted by signal while sleeping waiting for resources. + * -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources. */ -extern int ttm_buffer_object_init(struct ttm_bo_device *bdev, - struct ttm_buffer_object *bo, - unsigned long size, - enum ttm_bo_type type, - uint32_t flags, - uint32_t page_alignment, - unsigned long buffer_start, - bool interrubtible, - struct file *persistant_swap_storage, - size_t acc_size, - void (*destroy) (struct ttm_buffer_object *)); +extern int ttm_bo_init(struct ttm_bo_device *bdev, + struct ttm_buffer_object *bo, + unsigned long size, + enum ttm_bo_type type, + struct ttm_placement *placement, + uint32_t page_alignment, + unsigned long buffer_start, + bool interrubtible, + struct file *persistant_swap_storage, + size_t acc_size, + void (*destroy) (struct ttm_buffer_object *)); /** * ttm_bo_synccpu_object_init * @@ -405,47 +424,43 @@ extern int ttm_buffer_object_init(struct ttm_bo_device *bdev, * GEM user interface. * @p_bo: On successful completion *p_bo points to the created object. * - * This function allocates a ttm_buffer_object, and then calls - * ttm_buffer_object_init on that object. - * The destroy function is set to kfree(). + * This function allocates a ttm_buffer_object, and then calls ttm_bo_init + * on that object. The destroy function is set to kfree(). * Returns * -ENOMEM: Out of memory. * -EINVAL: Invalid placement flags. - * -ERESTART: Interrupted by signal while waiting for resources. + * -ERESTARTSYS: Interrupted by signal while waiting for resources. */ -extern int ttm_buffer_object_create(struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - uint32_t flags, - uint32_t page_alignment, - unsigned long buffer_start, - bool interruptible, - struct file *persistant_swap_storage, - struct ttm_buffer_object **p_bo); +extern int ttm_bo_create(struct ttm_bo_device *bdev, + unsigned long size, + enum ttm_bo_type type, + struct ttm_placement *placement, + uint32_t page_alignment, + unsigned long buffer_start, + bool interruptible, + struct file *persistant_swap_storage, + struct ttm_buffer_object **p_bo); /** * ttm_bo_check_placement * - * @bo: the buffer object. - * @set_flags: placement flags to set. - * @clr_flags: placement flags to clear. + * @bo: the buffer object. + * @placement: placements * * Performs minimal validity checking on an intended change of * placement flags. * Returns * -EINVAL: Intended change is invalid or not allowed. */ - extern int ttm_bo_check_placement(struct ttm_buffer_object *bo, - uint32_t set_flags, uint32_t clr_flags); + struct ttm_placement *placement); /** * ttm_bo_init_mm * * @bdev: Pointer to a ttm_bo_device struct. * @mem_type: The memory type. - * @p_offset: offset for managed area in pages. * @p_size: size managed area in pages. * * Initialize a manager for a given memory type. @@ -458,7 +473,7 @@ extern int ttm_bo_check_placement(struct ttm_buffer_object *bo, */ extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, - unsigned long p_offset, unsigned long p_size); + unsigned long p_size); /** * ttm_bo_clean_mm * @@ -503,7 +518,7 @@ extern int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type); * * Returns: * -EINVAL: Invalid or uninitialized memory type. - * -ERESTART: The call was interrupted by a signal while waiting to + * -ERESTARTSYS: The call was interrupted by a signal while waiting to * evict a buffer. */ @@ -606,7 +621,7 @@ extern int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, * be called from the fops::read and fops::write method. * Returns: * See man (2) write, man(2) read. In particular, - * the function may return -EINTR if + * the function may return -ERESTARTSYS if * interrupted by a signal. */ diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e8cd6d20aed2..ff7664e0c3cd 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -242,12 +242,6 @@ struct ttm_mem_type_manager { /** * struct ttm_bo_driver * - * @mem_type_prio: Priority array of memory types to place a buffer object in - * if it fits without evicting buffers from any of these memory types. - * @mem_busy_prio: Priority array of memory types to place a buffer object in - * if it needs to evict buffers to make room. - * @num_mem_type_prio: Number of elements in the @mem_type_prio array. - * @num_mem_busy_prio: Number of elements in the @num_mem_busy_prio array. * @create_ttm_backend_entry: Callback to create a struct ttm_backend. * @invalidate_caches: Callback to invalidate read caches when a buffer object * has been evicted. @@ -265,11 +259,6 @@ struct ttm_mem_type_manager { */ struct ttm_bo_driver { - const uint32_t *mem_type_prio; - const uint32_t *mem_busy_prio; - uint32_t num_mem_type_prio; - uint32_t num_mem_busy_prio; - /** * struct ttm_bo_driver member create_ttm_backend_entry * @@ -306,7 +295,8 @@ struct ttm_bo_driver { * finished, they'll end up in bo->mem.flags */ - uint32_t(*evict_flags) (struct ttm_buffer_object *bo); + void(*evict_flags) (struct ttm_buffer_object *bo, + struct ttm_placement *placement); /** * struct ttm_bo_driver member move: * @@ -545,6 +535,15 @@ extern int ttm_tt_set_user(struct ttm_tt *ttm, extern int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); /** + * ttm_tt_populate: + * + * @ttm: The struct ttm_tt to contain the backing pages. + * + * Add backing pages to all of @ttm + */ +extern int ttm_tt_populate(struct ttm_tt *ttm); + +/** * ttm_ttm_destroy: * * @ttm: The struct ttm_tt. @@ -639,12 +638,12 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, * -EBUSY: No space available (only if no_wait == 1). * -ENOMEM: Could not allocate memory for the buffer object, either due to * fragmentation or concurrent allocators. - * -ERESTART: An interruptible sleep was interrupted by a signal. + * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. */ extern int ttm_bo_mem_space(struct ttm_buffer_object *bo, - uint32_t proposed_placement, - struct ttm_mem_reg *mem, - bool interruptible, bool no_wait); + struct ttm_placement *placement, + struct ttm_mem_reg *mem, + bool interruptible, bool no_wait); /** * ttm_bo_wait_for_cpu * @@ -654,7 +653,7 @@ extern int ttm_bo_mem_space(struct ttm_buffer_object *bo, * Wait until a buffer object is no longer sync'ed for CPU access. * Returns: * -EBUSY: Buffer object was sync'ed for CPU access. (only if no_wait == 1). - * -ERESTART: An interruptible sleep was interrupted by a signal. + * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. */ extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); @@ -758,7 +757,7 @@ extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); * -EAGAIN: The reservation may cause a deadlock. * Release all buffer reservations, wait for @bo to become unreserved and * try again. (only if use_sequence == 1). - * -ERESTART: A wait for the buffer to become unreserved was interrupted by + * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by * a signal. Release all buffer reservations and return to user-space. */ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, @@ -799,7 +798,7 @@ extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, * * Returns: * -EBUSY: If no_wait == 1 and the buffer is already reserved. - * -ERESTART: If interruptible == 1 and the process received a signal + * -ERESTARTSYS: If interruptible == 1 and the process received a signal * while sleeping. */ extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo, diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h new file mode 100644 index 000000000000..cd2c475da9ea --- /dev/null +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +#ifndef _TTM_EXECBUF_UTIL_H_ +#define _TTM_EXECBUF_UTIL_H_ + +#include "ttm/ttm_bo_api.h" +#include <linux/list.h> + +/** + * struct ttm_validate_buffer + * + * @head: list head for thread-private list. + * @bo: refcounted buffer object pointer. + * @new_sync_obj_arg: New sync_obj_arg for @bo, to be used once + * adding a new sync object. + * @reservied: Indicates whether @bo has been reserved for validation. + */ + +struct ttm_validate_buffer { + struct list_head head; + struct ttm_buffer_object *bo; + void *new_sync_obj_arg; + bool reserved; +}; + +/** + * function ttm_eu_backoff_reservation + * + * @list: thread private list of ttm_validate_buffer structs. + * + * Undoes all buffer validation reservations for bos pointed to by + * the list entries. + */ + +extern void ttm_eu_backoff_reservation(struct list_head *list); + +/** + * function ttm_eu_reserve_buffers + * + * @list: thread private list of ttm_validate_buffer structs. + * @val_seq: A unique sequence number. + * + * Tries to reserve bos pointed to by the list entries for validation. + * If the function returns 0, all buffers are marked as "unfenced", + * taken off the lru lists and are not synced for write CPU usage. + * + * If the function detects a deadlock due to multiple threads trying to + * reserve the same buffers in reverse order, all threads except one will + * back off and retry. This function may sleep while waiting for + * CPU write reservations to be cleared, and for other threads to + * unreserve their buffers. + * + * This function may return -ERESTART or -EAGAIN if the calling process + * receives a signal while waiting. In that case, no buffers on the list + * will be reserved upon return. + * + * Buffers reserved by this function should be unreserved by + * a call to either ttm_eu_backoff_reservation() or + * ttm_eu_fence_buffer_objects() when command submission is complete or + * has failed. + */ + +extern int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq); + +/** + * function ttm_eu_fence_buffer_objects. + * + * @list: thread private list of ttm_validate_buffer structs. + * @sync_obj: The new sync object for the buffers. + * + * This function should be called when command submission is complete, and + * it will add a new sync object to bos pointed to by entries on @list. + * It also unreserves all buffers, putting them on lru lists. + * + */ + +extern void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj); + +#endif diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h new file mode 100644 index 000000000000..81ba0b0b891a --- /dev/null +++ b/include/drm/ttm/ttm_lock.h @@ -0,0 +1,247 @@ +/************************************************************************** + * + * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ + +/** @file ttm_lock.h + * This file implements a simple replacement for the buffer manager use + * of the DRM heavyweight hardware lock. + * The lock is a read-write lock. Taking it in read mode and write mode + * is relatively fast, and intended for in-kernel use only. + * + * The vt mode is used only when there is a need to block all + * user-space processes from validating buffers. + * It's allowed to leave kernel space with the vt lock held. + * If a user-space process dies while having the vt-lock, + * it will be released during the file descriptor release. The vt lock + * excludes write lock and read lock. + * + * The suspend mode is used to lock out all TTM users when preparing for + * and executing suspend operations. + * + */ + +#ifndef _TTM_LOCK_H_ +#define _TTM_LOCK_H_ + +#include "ttm/ttm_object.h" +#include <linux/wait.h> +#include <asm/atomic.h> + +/** + * struct ttm_lock + * + * @base: ttm base object used solely to release the lock if the client + * holding the lock dies. + * @queue: Queue for processes waiting for lock change-of-status. + * @lock: Spinlock protecting some lock members. + * @rw: Read-write lock counter. Protected by @lock. + * @flags: Lock state. Protected by @lock. + * @kill_takers: Boolean whether to kill takers of the lock. + * @signal: Signal to send when kill_takers is true. + */ + +struct ttm_lock { + struct ttm_base_object base; + wait_queue_head_t queue; + spinlock_t lock; + int32_t rw; + uint32_t flags; + bool kill_takers; + int signal; + struct ttm_object_file *vt_holder; +}; + + +/** + * ttm_lock_init + * + * @lock: Pointer to a struct ttm_lock + * Initializes the lock. + */ +extern void ttm_lock_init(struct ttm_lock *lock); + +/** + * ttm_read_unlock + * + * @lock: Pointer to a struct ttm_lock + * + * Releases a read lock. + */ +extern void ttm_read_unlock(struct ttm_lock *lock); + +/** + * ttm_read_lock + * + * @lock: Pointer to a struct ttm_lock + * @interruptible: Interruptible sleeping while waiting for a lock. + * + * Takes the lock in read mode. + * Returns: + * -ERESTARTSYS If interrupted by a signal and interruptible is true. + */ +extern int ttm_read_lock(struct ttm_lock *lock, bool interruptible); + +/** + * ttm_read_trylock + * + * @lock: Pointer to a struct ttm_lock + * @interruptible: Interruptible sleeping while waiting for a lock. + * + * Tries to take the lock in read mode. If the lock is already held + * in write mode, the function will return -EBUSY. If the lock is held + * in vt or suspend mode, the function will sleep until these modes + * are unlocked. + * + * Returns: + * -EBUSY The lock was already held in write mode. + * -ERESTARTSYS If interrupted by a signal and interruptible is true. + */ +extern int ttm_read_trylock(struct ttm_lock *lock, bool interruptible); + +/** + * ttm_write_unlock + * + * @lock: Pointer to a struct ttm_lock + * + * Releases a write lock. + */ +extern void ttm_write_unlock(struct ttm_lock *lock); + +/** + * ttm_write_lock + * + * @lock: Pointer to a struct ttm_lock + * @interruptible: Interruptible sleeping while waiting for a lock. + * + * Takes the lock in write mode. + * Returns: + * -ERESTARTSYS If interrupted by a signal and interruptible is true. + */ +extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible); + +/** + * ttm_lock_downgrade + * + * @lock: Pointer to a struct ttm_lock + * + * Downgrades a write lock to a read lock. + */ +extern void ttm_lock_downgrade(struct ttm_lock *lock); + +/** + * ttm_suspend_lock + * + * @lock: Pointer to a struct ttm_lock + * + * Takes the lock in suspend mode. Excludes read and write mode. + */ +extern void ttm_suspend_lock(struct ttm_lock *lock); + +/** + * ttm_suspend_unlock + * + * @lock: Pointer to a struct ttm_lock + * + * Releases a suspend lock + */ +extern void ttm_suspend_unlock(struct ttm_lock *lock); + +/** + * ttm_vt_lock + * + * @lock: Pointer to a struct ttm_lock + * @interruptible: Interruptible sleeping while waiting for a lock. + * @tfile: Pointer to a struct ttm_object_file to register the lock with. + * + * Takes the lock in vt mode. + * Returns: + * -ERESTARTSYS If interrupted by a signal and interruptible is true. + * -ENOMEM: Out of memory when locking. + */ +extern int ttm_vt_lock(struct ttm_lock *lock, bool interruptible, + struct ttm_object_file *tfile); + +/** + * ttm_vt_unlock + * + * @lock: Pointer to a struct ttm_lock + * + * Releases a vt lock. + * Returns: + * -EINVAL If the lock was not held. + */ +extern int ttm_vt_unlock(struct ttm_lock *lock); + +/** + * ttm_write_unlock + * + * @lock: Pointer to a struct ttm_lock + * + * Releases a write lock. + */ +extern void ttm_write_unlock(struct ttm_lock *lock); + +/** + * ttm_write_lock + * + * @lock: Pointer to a struct ttm_lock + * @interruptible: Interruptible sleeping while waiting for a lock. + * + * Takes the lock in write mode. + * Returns: + * -ERESTARTSYS If interrupted by a signal and interruptible is true. + */ +extern int ttm_write_lock(struct ttm_lock *lock, bool interruptible); + +/** + * ttm_lock_set_kill + * + * @lock: Pointer to a struct ttm_lock + * @val: Boolean whether to kill processes taking the lock. + * @signal: Signal to send to the process taking the lock. + * + * The kill-when-taking-lock functionality is used to kill processes that keep + * on using the TTM functionality when its resources has been taken down, for + * example when the X server exits. A typical sequence would look like this: + * - X server takes lock in write mode. + * - ttm_lock_set_kill() is called with @val set to true. + * - As part of X server exit, TTM resources are taken down. + * - X server releases the lock on file release. + * - Another dri client wants to render, takes the lock and is killed. + * + */ +static inline void ttm_lock_set_kill(struct ttm_lock *lock, bool val, + int signal) +{ + lock->kill_takers = val; + if (val) + lock->signal = signal; +} + +#endif diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h index 6983a7cf4da4..b199170b3c2c 100644 --- a/include/drm/ttm/ttm_memory.h +++ b/include/drm/ttm/ttm_memory.h @@ -33,6 +33,7 @@ #include <linux/wait.h> #include <linux/errno.h> #include <linux/kobject.h> +#include <linux/mm.h> /** * struct ttm_mem_shrink - callback to shrink TTM memory usage. diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h new file mode 100644 index 000000000000..703ca4db0a29 --- /dev/null +++ b/include/drm/ttm/ttm_object.h @@ -0,0 +1,267 @@ +/************************************************************************** + * + * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> + */ +/** @file ttm_object.h + * + * Base- and reference object implementation for the various + * ttm objects. Implements reference counting, minimal security checks + * and release on file close. + */ + +#ifndef _TTM_OBJECT_H_ +#define _TTM_OBJECT_H_ + +#include <linux/list.h> +#include "drm_hashtab.h" +#include <linux/kref.h> +#include <ttm/ttm_memory.h> + +/** + * enum ttm_ref_type + * + * Describes what type of reference a ref object holds. + * + * TTM_REF_USAGE is a simple refcount on a base object. + * + * TTM_REF_SYNCCPU_READ is a SYNCCPU_READ reference on a + * buffer object. + * + * TTM_REF_SYNCCPU_WRITE is a SYNCCPU_WRITE reference on a + * buffer object. + * + */ + +enum ttm_ref_type { + TTM_REF_USAGE, + TTM_REF_SYNCCPU_READ, + TTM_REF_SYNCCPU_WRITE, + TTM_REF_NUM +}; + +/** + * enum ttm_object_type + * + * One entry per ttm object type. + * Device-specific types should use the + * ttm_driver_typex types. + */ + +enum ttm_object_type { + ttm_fence_type, + ttm_buffer_type, + ttm_lock_type, + ttm_driver_type0 = 256, + ttm_driver_type1 +}; + +struct ttm_object_file; +struct ttm_object_device; + +/** + * struct ttm_base_object + * + * @hash: hash entry for the per-device object hash. + * @type: derived type this object is base class for. + * @shareable: Other ttm_object_files can access this object. + * + * @tfile: Pointer to ttm_object_file of the creator. + * NULL if the object was not created by a user request. + * (kernel object). + * + * @refcount: Number of references to this object, not + * including the hash entry. A reference to a base object can + * only be held by a ref object. + * + * @refcount_release: A function to be called when there are + * no more references to this object. This function should + * destroy the object (or make sure destruction eventually happens), + * and when it is called, the object has + * already been taken out of the per-device hash. The parameter + * "base" should be set to NULL by the function. + * + * @ref_obj_release: A function to be called when a reference object + * with another ttm_ref_type than TTM_REF_USAGE is deleted. + * this function may, for example, release a lock held by a user-space + * process. + * + * This struct is intended to be used as a base struct for objects that + * are visible to user-space. It provides a global name, race-safe + * access and refcounting, minimal access contol and hooks for unref actions. + */ + +struct ttm_base_object { + struct drm_hash_item hash; + enum ttm_object_type object_type; + bool shareable; + struct ttm_object_file *tfile; + struct kref refcount; + void (*refcount_release) (struct ttm_base_object **base); + void (*ref_obj_release) (struct ttm_base_object *base, + enum ttm_ref_type ref_type); +}; + +/** + * ttm_base_object_init + * + * @tfile: Pointer to a struct ttm_object_file. + * @base: The struct ttm_base_object to initialize. + * @shareable: This object is shareable with other applcations. + * (different @tfile pointers.) + * @type: The object type. + * @refcount_release: See the struct ttm_base_object description. + * @ref_obj_release: See the struct ttm_base_object description. + * + * Initializes a struct ttm_base_object. + */ + +extern int ttm_base_object_init(struct ttm_object_file *tfile, + struct ttm_base_object *base, + bool shareable, + enum ttm_object_type type, + void (*refcount_release) (struct ttm_base_object + **), + void (*ref_obj_release) (struct ttm_base_object + *, + enum ttm_ref_type + ref_type)); + +/** + * ttm_base_object_lookup + * + * @tfile: Pointer to a struct ttm_object_file. + * @key: Hash key + * + * Looks up a struct ttm_base_object with the key @key. + * Also verifies that the object is visible to the application, by + * comparing the @tfile argument and checking the object shareable flag. + */ + +extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file + *tfile, uint32_t key); + +/** + * ttm_base_object_unref + * + * @p_base: Pointer to a pointer referncing a struct ttm_base_object. + * + * Decrements the base object refcount and clears the pointer pointed to by + * p_base. + */ + +extern void ttm_base_object_unref(struct ttm_base_object **p_base); + +/** + * ttm_ref_object_add. + * + * @tfile: A struct ttm_object_file representing the application owning the + * ref_object. + * @base: The base object to reference. + * @ref_type: The type of reference. + * @existed: Upon completion, indicates that an identical reference object + * already existed, and the refcount was upped on that object instead. + * + * Adding a ref object to a base object is basically like referencing the + * base object, but a user-space application holds the reference. When the + * file corresponding to @tfile is closed, all its reference objects are + * deleted. A reference object can have different types depending on what + * it's intended for. It can be refcounting to prevent object destruction, + * When user-space takes a lock, it can add a ref object to that lock to + * make sure the lock is released if the application dies. A ref object + * will hold a single reference on a base object. + */ +extern int ttm_ref_object_add(struct ttm_object_file *tfile, + struct ttm_base_object *base, + enum ttm_ref_type ref_type, bool *existed); +/** + * ttm_ref_object_base_unref + * + * @key: Key representing the base object. + * @ref_type: Ref type of the ref object to be dereferenced. + * + * Unreference a ref object with type @ref_type + * on the base object identified by @key. If there are no duplicate + * references, the ref object will be destroyed and the base object + * will be unreferenced. + */ +extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile, + unsigned long key, + enum ttm_ref_type ref_type); + +/** + * ttm_object_file_init - initialize a struct ttm_object file + * + * @tdev: A struct ttm_object device this file is initialized on. + * @hash_order: Order of the hash table used to hold the reference objects. + * + * This is typically called by the file_ops::open function. + */ + +extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device + *tdev, + unsigned int hash_order); + +/** + * ttm_object_file_release - release data held by a ttm_object_file + * + * @p_tfile: Pointer to pointer to the ttm_object_file object to release. + * *p_tfile will be set to NULL by this function. + * + * Releases all data associated by a ttm_object_file. + * Typically called from file_ops::release. The caller must + * ensure that there are no concurrent users of tfile. + */ + +extern void ttm_object_file_release(struct ttm_object_file **p_tfile); + +/** + * ttm_object device init - initialize a struct ttm_object_device + * + * @hash_order: Order of hash table used to hash the base objects. + * + * This function is typically called on device initialization to prepare + * data structures needed for ttm base and ref objects. + */ + +extern struct ttm_object_device *ttm_object_device_init + (struct ttm_mem_global *mem_glob, unsigned int hash_order); + +/** + * ttm_object_device_release - release data held by a ttm_object_device + * + * @p_tdev: Pointer to pointer to the ttm_object_device object to release. + * *p_tdev will be set to NULL by this function. + * + * Releases all data associated by a ttm_object_device. + * Typically called from driver::unload before the destruction of the + * device private data structure. + */ + +extern void ttm_object_device_release(struct ttm_object_device **p_tdev); + +#endif diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h index 170786e5c2ff..fd11a5bd892d 100644 --- a/include/drm/via_drm.h +++ b/include/drm/via_drm.h @@ -24,7 +24,7 @@ #ifndef _VIA_DRM_H_ #define _VIA_DRM_H_ -#include <linux/types.h> +#include "drm.h" /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 5a5385749e16..f72914db2a11 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -214,7 +214,6 @@ unifdef-y += futex.h unifdef-y += fs.h unifdef-y += gameport.h unifdef-y += generic_serial.h -unifdef-y += hayesesp.h unifdef-y += hdlcdrv.h unifdef-y += hdlc.h unifdef-y += hdreg.h diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h index 57b1846a3c87..3e09b345f4d6 100644 --- a/include/linux/atmel-mci.h +++ b/include/linux/atmel-mci.h @@ -3,8 +3,6 @@ #define ATMEL_MCI_MAX_NR_SLOTS 2 -#include <linux/dw_dmac.h> - /** * struct mci_slot_pdata - board-specific per-slot configuration * @bus_width: Number of data lines wired up the slot @@ -34,7 +32,7 @@ struct mci_slot_pdata { * @slot: Per-slot configuration data. */ struct mci_platform_data { - struct dw_dma_slave dma_slave; + struct mci_dma_data *dma_slave; struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; }; diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 47536197ffdd..e287863ac053 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -43,6 +43,8 @@ extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls); #ifdef CONFIG_HOTPLUG_CPU extern void unregister_cpu(struct cpu *cpu); +extern ssize_t arch_cpu_probe(const char *, size_t); +extern ssize_t arch_cpu_release(const char *, size_t); #endif struct notifier_block; @@ -115,6 +117,19 @@ extern void put_online_cpus(void); #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) int cpu_down(unsigned int cpu); +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE +extern void cpu_hotplug_driver_lock(void); +extern void cpu_hotplug_driver_unlock(void); +#else +static inline void cpu_hotplug_driver_lock(void) +{ +} + +static inline void cpu_hotplug_driver_unlock(void) +{ +} +#endif + #else /* CONFIG_HOTPLUG_CPU */ #define get_online_cpus() do { } while (0) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 79a2340d83cd..4de02b10007f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -232,6 +232,7 @@ struct cpufreq_driver { /* optional */ unsigned int (*getavg) (struct cpufreq_policy *policy, unsigned int cpu); + int (*bios_limit) (int cpu, unsigned int *limit); int (*exit) (struct cpufreq_policy *policy); int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 789cf5f920ce..d77b54733c5b 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -84,6 +84,7 @@ extern const struct cpumask *const cpu_active_mask; #define num_online_cpus() cpumask_weight(cpu_online_mask) #define num_possible_cpus() cpumask_weight(cpu_possible_mask) #define num_present_cpus() cpumask_weight(cpu_present_mask) +#define num_active_cpus() cpumask_weight(cpu_active_mask) #define cpu_online(cpu) cpumask_test_cpu((cpu), cpu_online_mask) #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask) #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask) @@ -92,6 +93,7 @@ extern const struct cpumask *const cpu_active_mask; #define num_online_cpus() 1 #define num_possible_cpus() 1 #define num_present_cpus() 1 +#define num_active_cpus() 1 #define cpu_online(cpu) ((cpu) == 0) #define cpu_possible(cpu) ((cpu) == 0) #define cpu_present(cpu) ((cpu) == 0) diff --git a/include/linux/cs5535.h b/include/linux/cs5535.h new file mode 100644 index 000000000000..d5a1d4810b80 --- /dev/null +++ b/include/linux/cs5535.h @@ -0,0 +1,172 @@ +/* + * AMD CS5535/CS5536 definitions + * Copyright (C) 2006 Advanced Micro Devices, Inc. + * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#ifndef _CS5535_H +#define _CS5535_H + +/* MSRs */ +#define MSR_GLIU_P2D_RO0 0x10000029 + +#define MSR_LX_GLD_MSR_CONFIG 0x48002001 +#define MSR_LX_MSR_PADSEL 0x48002011 /* NOT 0x48000011; the data + * sheet has the wrong value */ +#define MSR_GLCP_SYS_RSTPLL 0x4C000014 +#define MSR_GLCP_DOTPLL 0x4C000015 + +#define MSR_LBAR_SMB 0x5140000B +#define MSR_LBAR_GPIO 0x5140000C +#define MSR_LBAR_MFGPT 0x5140000D +#define MSR_LBAR_ACPI 0x5140000E +#define MSR_LBAR_PMS 0x5140000F + +#define MSR_DIVIL_SOFT_RESET 0x51400017 + +#define MSR_PIC_YSEL_LOW 0x51400020 +#define MSR_PIC_YSEL_HIGH 0x51400021 +#define MSR_PIC_ZSEL_LOW 0x51400022 +#define MSR_PIC_ZSEL_HIGH 0x51400023 +#define MSR_PIC_IRQM_LPC 0x51400025 + +#define MSR_MFGPT_IRQ 0x51400028 +#define MSR_MFGPT_NR 0x51400029 +#define MSR_MFGPT_SETUP 0x5140002B + +#define MSR_LX_SPARE_MSR 0x80000011 /* DC-specific */ + +#define MSR_GX_GLD_MSR_CONFIG 0xC0002001 +#define MSR_GX_MSR_PADSEL 0xC0002011 + +/* resource sizes */ +#define LBAR_GPIO_SIZE 0xFF +#define LBAR_MFGPT_SIZE 0x40 +#define LBAR_ACPI_SIZE 0x40 +#define LBAR_PMS_SIZE 0x80 + +/* VSA2 magic values */ +#define VSA_VRC_INDEX 0xAC1C +#define VSA_VRC_DATA 0xAC1E +#define VSA_VR_UNLOCK 0xFC53 /* unlock virtual register */ +#define VSA_VR_SIGNATURE 0x0003 +#define VSA_VR_MEM_SIZE 0x0200 +#define AMD_VSA_SIG 0x4132 /* signature is ascii 'VSA2' */ +#define GSW_VSA_SIG 0x534d /* General Software signature */ + +#include <linux/io.h> + +static inline int cs5535_has_vsa2(void) +{ + static int has_vsa2 = -1; + + if (has_vsa2 == -1) { + uint16_t val; + + /* + * The VSA has virtual registers that we can query for a + * signature. + */ + outw(VSA_VR_UNLOCK, VSA_VRC_INDEX); + outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX); + + val = inw(VSA_VRC_DATA); + has_vsa2 = (val == AMD_VSA_SIG || val == GSW_VSA_SIG); + } + + return has_vsa2; +} + +/* GPIOs */ +#define GPIO_OUTPUT_VAL 0x00 +#define GPIO_OUTPUT_ENABLE 0x04 +#define GPIO_OUTPUT_OPEN_DRAIN 0x08 +#define GPIO_OUTPUT_INVERT 0x0C +#define GPIO_OUTPUT_AUX1 0x10 +#define GPIO_OUTPUT_AUX2 0x14 +#define GPIO_PULL_UP 0x18 +#define GPIO_PULL_DOWN 0x1C +#define GPIO_INPUT_ENABLE 0x20 +#define GPIO_INPUT_INVERT 0x24 +#define GPIO_INPUT_FILTER 0x28 +#define GPIO_INPUT_EVENT_COUNT 0x2C +#define GPIO_READ_BACK 0x30 +#define GPIO_INPUT_AUX1 0x34 +#define GPIO_EVENTS_ENABLE 0x38 +#define GPIO_LOCK_ENABLE 0x3C +#define GPIO_POSITIVE_EDGE_EN 0x40 +#define GPIO_NEGATIVE_EDGE_EN 0x44 +#define GPIO_POSITIVE_EDGE_STS 0x48 +#define GPIO_NEGATIVE_EDGE_STS 0x4C + +#define GPIO_MAP_X 0xE0 +#define GPIO_MAP_Y 0xE4 +#define GPIO_MAP_Z 0xE8 +#define GPIO_MAP_W 0xEC + +void cs5535_gpio_set(unsigned offset, unsigned int reg); +void cs5535_gpio_clear(unsigned offset, unsigned int reg); +int cs5535_gpio_isset(unsigned offset, unsigned int reg); + +/* MFGPTs */ + +#define MFGPT_MAX_TIMERS 8 +#define MFGPT_TIMER_ANY (-1) + +#define MFGPT_DOMAIN_WORKING 1 +#define MFGPT_DOMAIN_STANDBY 2 +#define MFGPT_DOMAIN_ANY (MFGPT_DOMAIN_WORKING | MFGPT_DOMAIN_STANDBY) + +#define MFGPT_CMP1 0 +#define MFGPT_CMP2 1 + +#define MFGPT_EVENT_IRQ 0 +#define MFGPT_EVENT_NMI 1 +#define MFGPT_EVENT_RESET 3 + +#define MFGPT_REG_CMP1 0 +#define MFGPT_REG_CMP2 2 +#define MFGPT_REG_COUNTER 4 +#define MFGPT_REG_SETUP 6 + +#define MFGPT_SETUP_CNTEN (1 << 15) +#define MFGPT_SETUP_CMP2 (1 << 14) +#define MFGPT_SETUP_CMP1 (1 << 13) +#define MFGPT_SETUP_SETUP (1 << 12) +#define MFGPT_SETUP_STOPEN (1 << 11) +#define MFGPT_SETUP_EXTEN (1 << 10) +#define MFGPT_SETUP_REVEN (1 << 5) +#define MFGPT_SETUP_CLKSEL (1 << 4) + +struct cs5535_mfgpt_timer; + +extern uint16_t cs5535_mfgpt_read(struct cs5535_mfgpt_timer *timer, + uint16_t reg); +extern void cs5535_mfgpt_write(struct cs5535_mfgpt_timer *timer, uint16_t reg, + uint16_t value); + +extern int cs5535_mfgpt_toggle_event(struct cs5535_mfgpt_timer *timer, int cmp, + int event, int enable); +extern int cs5535_mfgpt_set_irq(struct cs5535_mfgpt_timer *timer, int cmp, + int *irq, int enable); +extern struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer, + int domain); +extern void cs5535_mfgpt_free_timer(struct cs5535_mfgpt_timer *timer); + +static inline int cs5535_mfgpt_setup_irq(struct cs5535_mfgpt_timer *timer, + int cmp, int *irq) +{ + return cs5535_mfgpt_set_irq(timer, cmp, irq, 1); +} + +static inline int cs5535_mfgpt_release_irq(struct cs5535_mfgpt_timer *timer, + int cmp, int *irq) +{ + return cs5535_mfgpt_set_irq(timer, cmp, irq, 0); +} + +#endif diff --git a/include/linux/ctype.h b/include/linux/ctype.h index afa36392297a..a3d6ee0044f9 100644 --- a/include/linux/ctype.h +++ b/include/linux/ctype.h @@ -15,7 +15,7 @@ #define _X 0x40 /* hex digit */ #define _SP 0x80 /* hard space (0x20) */ -extern unsigned char _ctype[]; +extern const unsigned char _ctype[]; #define __ismask(x) (_ctype[(int)(unsigned char)(x)]) @@ -27,6 +27,7 @@ extern unsigned char _ctype[]; #define islower(c) ((__ismask(c)&(_L)) != 0) #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) #define ispunct(c) ((__ismask(c)&(_P)) != 0) +/* Note: isspace() must return false for %NUL-terminator */ #define isspace(c) ((__ismask(c)&(_S)) != 0) #define isupper(c) ((__ismask(c)&(_U)) != 0) #define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) diff --git a/include/linux/device.h b/include/linux/device.h index 2ea3e4921812..2a73d9bcbc9c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -558,7 +558,7 @@ extern void wait_for_device_probe(void); #ifdef CONFIG_DEVTMPFS extern int devtmpfs_create_node(struct device *dev); extern int devtmpfs_delete_node(struct device *dev); -extern int devtmpfs_mount(const char *mountpoint); +extern int devtmpfs_mount(const char *mntdir); #else static inline int devtmpfs_create_node(struct device *dev) { return 0; } static inline int devtmpfs_delete_node(struct device *dev) { return 0; } diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index a0d9422a1569..f8c2e1767500 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -57,8 +57,7 @@ extern int ddebug_remove_module(char *mod_name); { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \ DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ if (__dynamic_dbg_enabled(descriptor)) \ - printk(KERN_DEBUG KBUILD_MODNAME ":" pr_fmt(fmt), \ - ##__VA_ARGS__); \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) @@ -69,9 +68,7 @@ extern int ddebug_remove_module(char *mod_name); { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \ DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ if (__dynamic_dbg_enabled(descriptor)) \ - dev_printk(KERN_DEBUG, dev, \ - KBUILD_MODNAME ": " fmt, \ - ##__VA_ARGS__); \ + dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ } while (0) #else @@ -81,8 +78,10 @@ static inline int ddebug_remove_module(char *mod) return 0; } -#define dynamic_pr_debug(fmt, ...) do { } while (0) -#define dynamic_dev_dbg(dev, format, ...) do { } while (0) +#define dynamic_pr_debug(fmt, ...) \ + do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) +#define dynamic_dev_dbg(dev, format, ...) \ + do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0) #endif #endif diff --git a/include/linux/efi.h b/include/linux/efi.h index ce4581fbc08b..fb737bc19a8c 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -280,11 +280,7 @@ efi_guidcmp (efi_guid_t left, efi_guid_t right) static inline char * efi_guid_unparse(efi_guid_t *guid, char *out) { - sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid->b[3], guid->b[2], guid->b[1], guid->b[0], - guid->b[5], guid->b[4], guid->b[7], guid->b[6], - guid->b[8], guid->b[9], guid->b[10], guid->b[11], - guid->b[12], guid->b[13], guid->b[14], guid->b[15]); + sprintf(out, "%pUl", guid->b); return out; } diff --git a/include/linux/err.h b/include/linux/err.h index ec87f3142bf3..1b12642636c7 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -34,6 +34,11 @@ static inline long IS_ERR(const void *ptr) return IS_ERR_VALUE((unsigned long)ptr); } +static inline long IS_ERR_OR_NULL(const void *ptr) +{ + return !ptr || IS_ERR_VALUE((unsigned long)ptr); +} + /** * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type * @ptr: The pointer to cast. diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h index 121720d74e15..2dfa7076e8b6 100644 --- a/include/linux/ext2_fs.h +++ b/include/linux/ext2_fs.h @@ -565,14 +565,14 @@ struct ext2_dir_entry_2 { * other bits are reserved for now. */ enum { - EXT2_FT_UNKNOWN, - EXT2_FT_REG_FILE, - EXT2_FT_DIR, - EXT2_FT_CHRDEV, - EXT2_FT_BLKDEV, - EXT2_FT_FIFO, - EXT2_FT_SOCK, - EXT2_FT_SYMLINK, + EXT2_FT_UNKNOWN = 0, + EXT2_FT_REG_FILE = 1, + EXT2_FT_DIR = 2, + EXT2_FT_CHRDEV = 3, + EXT2_FT_BLKDEV = 4, + EXT2_FT_FIFO = 5, + EXT2_FT_SOCK = 6, + EXT2_FT_SYMLINK = 7, EXT2_FT_MAX }; diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 7499b3667798..6b049030fbe6 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -918,6 +918,8 @@ extern void ext3_abort (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4))); extern void ext3_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4))); +extern void ext3_msg(struct super_block *, const char *, const char *, ...) + __attribute__ ((format (printf, 3, 4))); extern void ext3_update_dynamic_rev (struct super_block *sb); #define ext3_std_error(sb, errno) \ diff --git a/include/linux/fb.h b/include/linux/fb.h index de9c722e7b90..369767bd873e 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -763,6 +763,7 @@ struct fb_tile_ops { * takes over; acceleration engine should be in a quiescent state */ /* hints */ +#define FBINFO_VIRTFB 0x0004 /* FB is System RAM, not device. */ #define FBINFO_PARTIAL_PAN_OK 0x0040 /* otw use pan only for double-buffering */ #define FBINFO_READS_FAST 0x0080 /* soft-copy faster than rendering */ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index d31544628436..043811f0d277 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -4,6 +4,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/compiler.h> +#include <linux/gfp.h> #define FW_ACTION_NOHOTPLUG 0 #define FW_ACTION_HOTPLUG 1 @@ -38,7 +39,7 @@ int request_firmware(const struct firmware **fw, const char *name, struct device *device); int request_firmware_nowait( struct module *module, int uevent, - const char *name, struct device *device, void *context, + const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)); void release_firmware(const struct firmware *fw); @@ -51,7 +52,7 @@ static inline int request_firmware(const struct firmware **fw, } static inline int request_firmware_nowait( struct module *module, int uevent, - const char *name, struct device *device, void *context, + const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { return -EINVAL; diff --git a/include/linux/fs.h b/include/linux/fs.h index 891f7d642e5c..a057f48eb156 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2091,8 +2091,6 @@ extern int filemap_fdatawait_range(struct address_space *, loff_t lstart, extern int filemap_write_and_wait(struct address_space *mapping); extern int filemap_write_and_wait_range(struct address_space *mapping, loff_t lstart, loff_t lend); -extern int wait_on_page_writeback_range(struct address_space *mapping, - pgoff_t start, pgoff_t end); extern int __filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end, int sync_mode); extern int filemap_fdatawrite_range(struct address_space *mapping, diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 43fc95d822d5..28e33fea5107 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -74,7 +74,12 @@ struct spi_device; struct fsl_spi_platform_data { u32 initial_spmode; /* initial SPMODE value */ s16 bus_num; - bool qe_mode; + unsigned int flags; +#define SPI_QE_CPU_MODE (1 << 0) /* QE CPU ("PIO") mode */ +#define SPI_CPM_MODE (1 << 1) /* CPM/QE ("DMA") mode */ +#define SPI_CPM1 (1 << 2) /* SPI unit is in CPM1 block */ +#define SPI_CPM2 (1 << 3) /* SPI unit is in CPM2 block */ +#define SPI_QE (1 << 4) /* SPI unit is in QE block */ /* board specific information */ u16 max_chipselect; void (*cs_control)(struct spi_device *spi, bool on); @@ -90,6 +95,10 @@ struct mpc8xx_pcmcia_ops { * lead to a deep sleep (i.e. power removed from the core, * instead of just the clock). */ +#if defined(CONFIG_PPC_83xx) && defined(CONFIG_SUSPEND) int fsl_deep_sleep(void); +#else +static inline int fsl_deep_sleep(void) { return 0; } +#endif #endif /* _FSL_DEVICE_H_ */ diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 47bbdf9c38d0..38f8d6553831 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -57,6 +57,7 @@ struct trace_iterator { /* The below is zeroed out in pipe_read */ struct trace_seq seq; struct trace_entry *ent; + int leftover; int cpu; u64 ts; diff --git a/include/linux/gigaset_dev.h b/include/linux/gigaset_dev.h index 5dc4a316ca37..258ba82937e7 100644 --- a/include/linux/gigaset_dev.h +++ b/include/linux/gigaset_dev.h @@ -16,15 +16,23 @@ #include <linux/ioctl.h> +/* The magic IOCTL value for this interface. */ #define GIGASET_IOCTL 0x47 -#define GIGVER_DRIVER 0 -#define GIGVER_COMPAT 1 -#define GIGVER_FWBASE 2 +/* enable/disable device control via character device (lock out ISDN subsys) */ +#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int) -#define GIGASET_REDIR _IOWR (GIGASET_IOCTL, 0, int) -#define GIGASET_CONFIG _IOWR (GIGASET_IOCTL, 1, int) -#define GIGASET_BRKCHARS _IOW (GIGASET_IOCTL, 2, unsigned char[6]) //FIXME [6] okay? -#define GIGASET_VERSION _IOWR (GIGASET_IOCTL, 3, unsigned[4]) +/* enable adapter configuration mode (M10x only) */ +#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int) + +/* set break characters (M105 only) */ +#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6]) + +/* get version information selected by arg[0] */ +#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4]) +/* values for GIGASET_VERSION arg[0] */ +#define GIGVER_DRIVER 0 /* get driver version */ +#define GIGVER_COMPAT 1 /* get interface compatibility version */ +#define GIGVER_FWBASE 2 /* get base station firmware version */ #endif diff --git a/include/linux/hayesesp.h b/include/linux/hayesesp.h deleted file mode 100644 index 92b08cfe4a75..000000000000 --- a/include/linux/hayesesp.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef HAYESESP_H -#define HAYESESP_H - -struct hayes_esp_config { - short flow_on; - short flow_off; - short rx_trigger; - short tx_trigger; - short pio_threshold; - unsigned char rx_timeout; - char dma_channel; -}; - -#ifdef __KERNEL__ - -#define ESP_DMA_CHANNEL 0 -#define ESP_RX_TRIGGER 768 -#define ESP_TX_TRIGGER 768 -#define ESP_FLOW_OFF 1016 -#define ESP_FLOW_ON 944 -#define ESP_RX_TMOUT 128 -#define ESP_PIO_THRESHOLD 32 - -#define ESP_IN_MAJOR 57 /* major dev # for dial in */ -#define ESP_OUT_MAJOR 58 /* major dev # for dial out */ -#define ESPC_SCALE 3 -#define UART_ESI_BASE 0x00 -#define UART_ESI_SID 0x01 -#define UART_ESI_RX 0x02 -#define UART_ESI_TX 0x02 -#define UART_ESI_CMD1 0x04 -#define UART_ESI_CMD2 0x05 -#define UART_ESI_STAT1 0x04 -#define UART_ESI_STAT2 0x05 -#define UART_ESI_RWS 0x07 - -#define UART_IER_DMA_TMOUT 0x80 -#define UART_IER_DMA_TC 0x08 - -#define ESI_SET_IRQ 0x04 -#define ESI_SET_DMA_TMOUT 0x05 -#define ESI_SET_SRV_MASK 0x06 -#define ESI_SET_ERR_MASK 0x07 -#define ESI_SET_FLOW_CNTL 0x08 -#define ESI_SET_FLOW_CHARS 0x09 -#define ESI_SET_FLOW_LVL 0x0a -#define ESI_SET_TRIGGER 0x0b -#define ESI_SET_RX_TIMEOUT 0x0c -#define ESI_SET_FLOW_TMOUT 0x0d -#define ESI_WRITE_UART 0x0e -#define ESI_READ_UART 0x0f -#define ESI_SET_MODE 0x10 -#define ESI_GET_ERR_STAT 0x12 -#define ESI_GET_UART_STAT 0x13 -#define ESI_GET_RX_AVAIL 0x14 -#define ESI_GET_TX_AVAIL 0x15 -#define ESI_START_DMA_RX 0x16 -#define ESI_START_DMA_TX 0x17 -#define ESI_ISSUE_BREAK 0x1a -#define ESI_FLUSH_RX 0x1b -#define ESI_FLUSH_TX 0x1c -#define ESI_SET_BAUD 0x1d -#define ESI_SET_ENH_IRQ 0x1f -#define ESI_SET_REINTR 0x20 -#define ESI_SET_PRESCALAR 0x23 -#define ESI_NO_COMMAND 0xff - -#define ESP_STAT_RX_TIMEOUT 0x01 -#define ESP_STAT_DMA_RX 0x02 -#define ESP_STAT_DMA_TX 0x04 -#define ESP_STAT_NEVER_DMA 0x08 -#define ESP_STAT_USE_PIO 0x10 - -#define ESP_MAGIC 0x53ee -#define ESP_XMIT_SIZE 4096 - -struct esp_struct { - int magic; - struct tty_port port; - spinlock_t lock; - int io_port; - int irq; - int read_status_mask; - int ignore_status_mask; - int timeout; - int stat_flags; - int custom_divisor; - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - int IER; /* Interrupt Enable Register */ - int MCR; /* Modem control register */ - unsigned long last_active; - int line; - unsigned char *xmit_buf; - int xmit_head; - int xmit_tail; - int xmit_cnt; - wait_queue_head_t break_wait; - struct async_icount icount; /* kernel counters for the 4 input interrupts */ - struct hayes_esp_config config; /* port configuration */ - struct esp_struct *next_port; /* For the linked list */ -}; - -struct esp_pio_buffer { - unsigned char data[1024]; - struct esp_pio_buffer *next; -}; - -#endif /* __KERNEL__ */ - - -#endif /* ESP_H */ - diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 9bace4b9f4fe..5d86fb2309d2 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -162,18 +162,23 @@ struct hrtimer_clock_base { * @expires_next: absolute time of the next event which was scheduled * via clock_set_next_event() * @hres_active: State of high resolution mode - * @check_clocks: Indictator, when set evaluate time source and clock - * event devices whether high resolution mode can be - * activated. - * @nr_events: Total number of timer interrupt events + * @hang_detected: The last hrtimer interrupt detected a hang + * @nr_events: Total number of hrtimer interrupt events + * @nr_retries: Total number of hrtimer interrupt retries + * @nr_hangs: Total number of hrtimer interrupt hangs + * @max_hang_time: Maximum time spent in hrtimer_interrupt */ struct hrtimer_cpu_base { - spinlock_t lock; + raw_spinlock_t lock; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next; int hres_active; + int hang_detected; unsigned long nr_events; + unsigned long nr_retries; + unsigned long nr_hangs; + ktime_t max_hang_time; #endif }; @@ -435,47 +440,4 @@ extern u64 ktime_divns(const ktime_t kt, s64 div); /* Show pending timers: */ extern void sysrq_timer_list_show(void); -/* - * Timer-statistics info: - */ -#ifdef CONFIG_TIMER_STATS - -extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, - void *timerf, char *comm, - unsigned int timer_flag); - -static inline void timer_stats_account_hrtimer(struct hrtimer *timer) -{ - if (likely(!timer_stats_active)) - return; - timer_stats_update_stats(timer, timer->start_pid, timer->start_site, - timer->function, timer->start_comm, 0); -} - -extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, - void *addr); - -static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) -{ - __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); -} - -static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer) -{ - timer->start_site = NULL; -} -#else -static inline void timer_stats_account_hrtimer(struct hrtimer *timer) -{ -} - -static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) -{ -} - -static inline void timer_stats_hrtimer_clear_start_info(struct hrtimer *timer) -{ -} -#endif - #endif diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 41a59afc70fa..78b4bc64c006 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -23,6 +23,12 @@ void reset_vma_resv_huge_pages(struct vm_area_struct *vma); int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int hugetlb_overcommit_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int hugetlb_treat_movable_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); + +#ifdef CONFIG_NUMA +int hugetlb_mempolicy_sysctl_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +#endif + int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index a03daed08c59..41235c93e4e9 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -20,19 +20,18 @@ enum { #ifdef CONFIG_HAVE_HW_BREAKPOINT -/* As it's for in-kernel or ptrace use, we want it to be pinned */ -#define DEFINE_BREAKPOINT_ATTR(name) \ -struct perf_event_attr name = { \ - .type = PERF_TYPE_BREAKPOINT, \ - .size = sizeof(name), \ - .pinned = 1, \ -}; - static inline void hw_breakpoint_init(struct perf_event_attr *attr) { + memset(attr, 0, sizeof(*attr)); + attr->type = PERF_TYPE_BREAKPOINT; attr->size = sizeof(*attr); + /* + * As it's for in-kernel or ptrace use, we want it to be pinned + * and to call its callback every hits. + */ attr->pinned = 1; + attr->sample_period = 1; } static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) @@ -52,27 +51,24 @@ static inline int hw_breakpoint_len(struct perf_event *bp) extern struct perf_event * register_user_hw_breakpoint(struct perf_event_attr *attr, - perf_callback_t triggered, + perf_overflow_handler_t triggered, struct task_struct *tsk); /* FIXME: only change from the attr, and don't unregister */ -extern struct perf_event * -modify_user_hw_breakpoint(struct perf_event *bp, - struct perf_event_attr *attr, - perf_callback_t triggered, - struct task_struct *tsk); +extern int +modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr); /* * Kernel breakpoints are not associated with any particular thread. */ extern struct perf_event * register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, - perf_callback_t triggered, + perf_overflow_handler_t triggered, int cpu); extern struct perf_event ** register_wide_hw_breakpoint(struct perf_event_attr *attr, - perf_callback_t triggered); + perf_overflow_handler_t triggered); extern int register_perf_hw_breakpoint(struct perf_event *bp); extern int __register_perf_hw_breakpoint(struct perf_event *bp); @@ -93,20 +89,18 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) static inline struct perf_event * register_user_hw_breakpoint(struct perf_event_attr *attr, - perf_callback_t triggered, + perf_overflow_handler_t triggered, struct task_struct *tsk) { return NULL; } -static inline struct perf_event * +static inline int modify_user_hw_breakpoint(struct perf_event *bp, - struct perf_event_attr *attr, - perf_callback_t triggered, - struct task_struct *tsk) { return NULL; } + struct perf_event_attr *attr) { return -ENOSYS; } static inline struct perf_event * register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, - perf_callback_t triggered, + perf_overflow_handler_t triggered, int cpu) { return NULL; } static inline struct perf_event ** register_wide_hw_breakpoint(struct perf_event_attr *attr, - perf_callback_t triggered) { return NULL; } + perf_overflow_handler_t triggered) { return NULL; } static inline int register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } static inline int diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 419ab546b266..02fc617782ef 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -110,7 +110,7 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, * @driver: Device driver model driver * @id_table: List of I2C devices supported by this driver * @detect: Callback for device detection - * @address_data: The I2C addresses to probe (for detect) + * @address_list: The I2C addresses to probe (for detect) * @clients: List of detected clients we created (for i2c-core use only) * * The driver.owner field should be set to the module owner of this driver. @@ -161,8 +161,8 @@ struct i2c_driver { const struct i2c_device_id *id_table; /* Device detection callback for automatic device creation */ - int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); - const struct i2c_client_address_data *address_data; + int (*detect)(struct i2c_client *, struct i2c_board_info *); + const unsigned short *address_list; struct list_head clients; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) @@ -391,14 +391,6 @@ static inline void i2c_unlock_adapter(struct i2c_adapter *adapter) #define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */ #define I2C_CLASS_SPD (1<<7) /* SPD EEPROMs and similar */ -/* i2c_client_address_data is the struct for holding default client - * addresses for a driver and for the parameters supplied on the - * command line - */ -struct i2c_client_address_data { - const unsigned short *normal_i2c; -}; - /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU @@ -576,82 +568,4 @@ union i2c_smbus_data { #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ #define I2C_SMBUS_I2C_BLOCK_DATA 8 - -#ifdef __KERNEL__ - -/* These defines are used for probing i2c client addresses */ -/* The length of the option lists */ -#define I2C_CLIENT_MAX_OPTS 48 - -/* Default fill of many variables */ -#define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END} - -/* I2C_CLIENT_MODULE_PARM creates a module parameter, and puts it in the - module header */ - -#define I2C_CLIENT_MODULE_PARM(var,desc) \ - static unsigned short var[I2C_CLIENT_MAX_OPTS] = I2C_CLIENT_DEFAULTS; \ - static unsigned int var##_num; \ - module_param_array(var, short, &var##_num, 0); \ - MODULE_PARM_DESC(var, desc) - -#define I2C_CLIENT_INSMOD_COMMON \ -static const struct i2c_client_address_data addr_data = { \ - .normal_i2c = normal_i2c, \ -} - -/* These are the ones you want to use in your own drivers. Pick the one - which matches the number of devices the driver differenciates between. */ -#define I2C_CLIENT_INSMOD \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_1(chip1) \ -enum chips { any_chip, chip1 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_2(chip1, chip2) \ -enum chips { any_chip, chip1, chip2 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ -enum chips { any_chip, chip1, chip2, chip3 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ -enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7 }; \ -I2C_CLIENT_INSMOD_COMMON - -#define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ -enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ - chip7, chip8 }; \ -I2C_CLIENT_INSMOD_COMMON -#endif /* __KERNEL__ */ #endif /* _LINUX_I2C_H */ diff --git a/include/linux/i2c/tps65010.h b/include/linux/i2c/tps65010.h index 918c5354d9b8..08aa92278d71 100644 --- a/include/linux/i2c/tps65010.h +++ b/include/linux/i2c/tps65010.h @@ -72,6 +72,21 @@ #define TPS_VDCDC1 0x0c # define TPS_ENABLE_LP (1 << 3) #define TPS_VDCDC2 0x0d +# define TPS_LP_COREOFF (1 << 7) +# define TPS_VCORE_1_8V (7<<4) +# define TPS_VCORE_1_5V (6 << 4) +# define TPS_VCORE_1_4V (5 << 4) +# define TPS_VCORE_1_3V (4 << 4) +# define TPS_VCORE_1_2V (3 << 4) +# define TPS_VCORE_1_1V (2 << 4) +# define TPS_VCORE_1_0V (1 << 4) +# define TPS_VCORE_0_85V (0 << 4) +# define TPS_VCORE_LP_1_2V (3 << 2) +# define TPS_VCORE_LP_1_1V (2 << 2) +# define TPS_VCORE_LP_1_0V (1 << 2) +# define TPS_VCORE_LP_0_85V (0 << 2) +# define TPS_VIB (1 << 1) +# define TPS_VCORE_DISCH (1 << 0) #define TPS_VREGS1 0x0e # define TPS_LDO2_ENABLE (1 << 7) # define TPS_LDO2_OFF (1 << 6) @@ -152,6 +167,10 @@ extern int tps65010_config_vregs1(unsigned value); */ extern int tps65013_set_low_pwr(unsigned mode); +/* tps65010_set_vdcdc2 + * value to be written to VDCDC2 + */ +extern int tps65010_config_vdcdc2(unsigned value); struct i2c_client; diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl.h index 5306a759cbde..bf1c5be1f5b6 100644 --- a/include/linux/i2c/twl4030.h +++ b/include/linux/i2c/twl.h @@ -22,8 +22,8 @@ * */ -#ifndef __TWL4030_H_ -#define __TWL4030_H_ +#ifndef __TWL_H_ +#define __TWL_H_ #include <linux/types.h> #include <linux/input/matrix_keypad.h> @@ -61,28 +61,112 @@ #define TWL4030_MODULE_PWMA 0x0E #define TWL4030_MODULE_PWMB 0x0F +#define TWL5031_MODULE_ACCESSORY 0x10 +#define TWL5031_MODULE_INTERRUPTS 0x11 + /* Slave 3 (i2c address 0x4b) */ -#define TWL4030_MODULE_BACKUP 0x10 -#define TWL4030_MODULE_INT 0x11 -#define TWL4030_MODULE_PM_MASTER 0x12 -#define TWL4030_MODULE_PM_RECEIVER 0x13 -#define TWL4030_MODULE_RTC 0x14 -#define TWL4030_MODULE_SECURED_REG 0x15 +#define TWL4030_MODULE_BACKUP 0x12 +#define TWL4030_MODULE_INT 0x13 +#define TWL4030_MODULE_PM_MASTER 0x14 +#define TWL4030_MODULE_PM_RECEIVER 0x15 +#define TWL4030_MODULE_RTC 0x16 +#define TWL4030_MODULE_SECURED_REG 0x17 + +#define TWL_MODULE_USB TWL4030_MODULE_USB +#define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE +#define TWL_MODULE_PIH TWL4030_MODULE_PIH +#define TWL_MODULE_MADC TWL4030_MODULE_MADC +#define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE +#define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER +#define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER +#define TWL_MODULE_RTC TWL4030_MODULE_RTC + +#define GPIO_INTR_OFFSET 0 +#define KEYPAD_INTR_OFFSET 1 +#define BCI_INTR_OFFSET 2 +#define MADC_INTR_OFFSET 3 +#define USB_INTR_OFFSET 4 +#define BCI_PRES_INTR_OFFSET 9 +#define USB_PRES_INTR_OFFSET 10 +#define RTC_INTR_OFFSET 11 + +/* + * Offset from TWL6030_IRQ_BASE / pdata->irq_base + */ +#define PWR_INTR_OFFSET 0 +#define HOTDIE_INTR_OFFSET 12 +#define SMPSLDO_INTR_OFFSET 13 +#define BATDETECT_INTR_OFFSET 14 +#define SIMDETECT_INTR_OFFSET 15 +#define MMCDETECT_INTR_OFFSET 16 +#define GASGAUGE_INTR_OFFSET 17 +#define USBOTG_INTR_OFFSET 4 +#define CHARGER_INTR_OFFSET 2 +#define RSV_INTR_OFFSET 0 + +/* INT register offsets */ +#define REG_INT_STS_A 0x00 +#define REG_INT_STS_B 0x01 +#define REG_INT_STS_C 0x02 + +#define REG_INT_MSK_LINE_A 0x03 +#define REG_INT_MSK_LINE_B 0x04 +#define REG_INT_MSK_LINE_C 0x05 + +#define REG_INT_MSK_STS_A 0x06 +#define REG_INT_MSK_STS_B 0x07 +#define REG_INT_MSK_STS_C 0x08 + +/* MASK INT REG GROUP A */ +#define TWL6030_PWR_INT_MASK 0x07 +#define TWL6030_RTC_INT_MASK 0x18 +#define TWL6030_HOTDIE_INT_MASK 0x20 +#define TWL6030_SMPSLDOA_INT_MASK 0xC0 + +/* MASK INT REG GROUP B */ +#define TWL6030_SMPSLDOB_INT_MASK 0x01 +#define TWL6030_BATDETECT_INT_MASK 0x02 +#define TWL6030_SIMDETECT_INT_MASK 0x04 +#define TWL6030_MMCDETECT_INT_MASK 0x08 +#define TWL6030_GPADC_INT_MASK 0x60 +#define TWL6030_GASGAUGE_INT_MASK 0x80 + +/* MASK INT REG GROUP C */ +#define TWL6030_USBOTG_INT_MASK 0x0F +#define TWL6030_CHARGER_CTRL_INT_MASK 0x10 +#define TWL6030_CHARGER_FAULT_INT_MASK 0x60 + + +#define TWL4030_CLASS_ID 0x4030 +#define TWL6030_CLASS_ID 0x6030 +unsigned int twl_rev(void); +#define GET_TWL_REV (twl_rev()) +#define TWL_CLASS_IS(class, id) \ +static inline int twl_class_is_ ##class(void) \ +{ \ + return ((id) == (GET_TWL_REV)) ? 1 : 0; \ +} + +TWL_CLASS_IS(4030, TWL4030_CLASS_ID) +TWL_CLASS_IS(6030, TWL6030_CLASS_ID) /* * Read and write single 8-bit registers */ -int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg); -int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); +int twl_i2c_write_u8(u8 mod_no, u8 val, u8 reg); +int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); /* * Read and write several 8-bit registers at once. * - * IMPORTANT: For twl4030_i2c_write(), allocate num_bytes + 1 + * IMPORTANT: For twl_i2c_write(), allocate num_bytes + 1 * for the value, and populate your data starting at offset 1. */ -int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); -int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); +int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); +int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); + +int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); +int twl6030_interrupt_mask(u8 bit_mask, u8 offset); /*----------------------------------------------------------------------*/ @@ -221,6 +305,38 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); /*----------------------------------------------------------------------*/ +/* + * Accessory Interrupts + */ +#define TWL5031_ACIIMR_LSB 0x05 +#define TWL5031_ACIIMR_MSB 0x06 +#define TWL5031_ACIIDR_LSB 0x07 +#define TWL5031_ACIIDR_MSB 0x08 +#define TWL5031_ACCISR1 0x0F +#define TWL5031_ACCIMR1 0x10 +#define TWL5031_ACCISR2 0x11 +#define TWL5031_ACCIMR2 0x12 +#define TWL5031_ACCSIR 0x13 +#define TWL5031_ACCEDR1 0x14 +#define TWL5031_ACCSIHCTRL 0x15 + +/*----------------------------------------------------------------------*/ + +/* + * Battery Charger Controller + */ + +#define TWL5031_INTERRUPTS_BCIISR1 0x0 +#define TWL5031_INTERRUPTS_BCIIMR1 0x1 +#define TWL5031_INTERRUPTS_BCIISR2 0x2 +#define TWL5031_INTERRUPTS_BCIIMR2 0x3 +#define TWL5031_INTERRUPTS_BCISIR 0x4 +#define TWL5031_INTERRUPTS_BCIEDR1 0x5 +#define TWL5031_INTERRUPTS_BCIEDR2 0x6 +#define TWL5031_INTERRUPTS_BCISIHCTRL 0x7 + +/*----------------------------------------------------------------------*/ + /* Power bus message definitions */ /* The TWL4030/5030 splits its power-management resources (the various @@ -250,6 +366,7 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); #define RES_TYPE_ALL 0x7 +/* Resource states */ #define RES_STATE_WRST 0xF #define RES_STATE_ACTIVE 0xE #define RES_STATE_SLEEP 0x8 @@ -310,8 +427,18 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); #define MSG_SINGULAR(devgrp, id, state) \ ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state)) +#define MSG_BROADCAST_ALL(devgrp, state) \ + ((devgrp) << 5 | (state)) + +#define MSG_BROADCAST_REF MSG_BROADCAST_ALL +#define MSG_BROADCAST_PROV MSG_BROADCAST_ALL +#define MSG_BROADCAST__CLK_RST MSG_BROADCAST_ALL /*----------------------------------------------------------------------*/ +struct twl4030_clock_init_data { + bool ck32k_lowpwr_enable; +}; + struct twl4030_bci_platform_data { int *battery_tmp_tbl; unsigned int tblsize; @@ -391,12 +518,15 @@ struct twl4030_resconfig { u8 devgroup; /* Processor group that Power resource belongs to */ u8 type; /* Power resource addressed, 6 / broadcast message */ u8 type2; /* Power resource addressed, 3 / broadcast message */ + u8 remap_off; /* off state remapping */ + u8 remap_sleep; /* sleep state remapping */ }; struct twl4030_power_data { struct twl4030_script **scripts; unsigned num; struct twl4030_resconfig *resource_config; +#define TWL4030_RESCONFIG_UNDEF ((u8)-1) }; extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); @@ -421,6 +551,7 @@ struct twl4030_codec_data { struct twl4030_platform_data { unsigned irq_base, irq_end; + struct twl4030_clock_init_data *clock; struct twl4030_bci_platform_data *bci; struct twl4030_gpio_platform_data *gpio; struct twl4030_madc_platform_data *madc; @@ -429,19 +560,31 @@ struct twl4030_platform_data { struct twl4030_power_data *power; struct twl4030_codec_data *codec; - /* LDO regulators */ + /* Common LDO regulators for TWL4030/TWL6030 */ struct regulator_init_data *vdac; + struct regulator_init_data *vaux1; + struct regulator_init_data *vaux2; + struct regulator_init_data *vaux3; + /* TWL4030 LDO regulators */ struct regulator_init_data *vpll1; struct regulator_init_data *vpll2; struct regulator_init_data *vmmc1; struct regulator_init_data *vmmc2; struct regulator_init_data *vsim; - struct regulator_init_data *vaux1; - struct regulator_init_data *vaux2; - struct regulator_init_data *vaux3; struct regulator_init_data *vaux4; - - /* REVISIT more to come ... _nothing_ should be hard-wired */ + struct regulator_init_data *vio; + struct regulator_init_data *vdd1; + struct regulator_init_data *vdd2; + struct regulator_init_data *vintana1; + struct regulator_init_data *vintana2; + struct regulator_init_data *vintdig; + /* TWL6030 LDO regulators */ + struct regulator_init_data *vmmc; + struct regulator_init_data *vpp; + struct regulator_init_data *vusim; + struct regulator_init_data *vana; + struct regulator_init_data *vcxio; + struct regulator_init_data *vusb; }; /*----------------------------------------------------------------------*/ @@ -473,6 +616,7 @@ int twl4030_sih_setup(int module); * VIO is generally fixed. */ +/* TWL4030 SMPS/LDO's */ /* EXTERNAL dc-to-dc buck converters */ #define TWL4030_REG_VDD1 0 #define TWL4030_REG_VDD2 1 @@ -499,4 +643,31 @@ int twl4030_sih_setup(int module); #define TWL4030_REG_VUSB1V8 18 #define TWL4030_REG_VUSB3V1 19 +/* TWL6030 SMPS/LDO's */ +/* EXTERNAL dc-to-dc buck convertor contollable via SR */ +#define TWL6030_REG_VDD1 30 +#define TWL6030_REG_VDD2 31 +#define TWL6030_REG_VDD3 32 + +/* Non SR compliant dc-to-dc buck convertors */ +#define TWL6030_REG_VMEM 33 +#define TWL6030_REG_V2V1 34 +#define TWL6030_REG_V1V29 35 +#define TWL6030_REG_V1V8 36 + +/* EXTERNAL LDOs */ +#define TWL6030_REG_VAUX1_6030 37 +#define TWL6030_REG_VAUX2_6030 38 +#define TWL6030_REG_VAUX3_6030 39 +#define TWL6030_REG_VMMC 40 +#define TWL6030_REG_VPP 41 +#define TWL6030_REG_VUSIM 42 +#define TWL6030_REG_VANA 43 +#define TWL6030_REG_VCXIO 44 +#define TWL6030_REG_VDAC 45 +#define TWL6030_REG_VUSB 46 + +/* INTERNAL LDOs */ +#define TWL6030_REG_VRTC 47 + #endif /* End of __TWL4030_H */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 005e1525ab86..299b4121f914 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -137,8 +137,6 @@ extern struct ctl_table ether_table[]; extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_BUF_SIZE 18 -#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] #endif diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 8d10aa7fd4c9..5ed8b9c50355 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -111,6 +111,12 @@ extern struct cred init_cred; # define INIT_PERF_EVENTS(tsk) #endif +#ifdef CONFIG_FS_JOURNAL_INFO +#define INIT_JOURNAL_INFO .journal_info = NULL, +#else +#define INIT_JOURNAL_INFO +#endif + /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -162,10 +168,9 @@ extern struct cred init_cred; .signal = {{0}}}, \ .blocked = {{0}}, \ .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ - .journal_info = NULL, \ .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ .fs_excl = ATOMIC_INIT(0), \ - .pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ .timer_slack_ns = 50000, /* 50 usec default slack */ \ .pids = { \ [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ @@ -173,6 +178,7 @@ extern struct cred init_cred; [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ }, \ .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ + INIT_JOURNAL_INFO \ INIT_IDS \ INIT_PERF_EVENTS(tsk) \ INIT_TRACE_IRQFLAGS \ diff --git a/include/linux/irq.h b/include/linux/irq.h index a287cfc0b1a6..451481c082b5 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -192,7 +192,7 @@ struct irq_desc { unsigned int irq_count; /* For detecting broken IRQs */ unsigned long last_unhandled; /* Aging timer for unhandled count */ unsigned int irqs_unhandled; - spinlock_t lock; + raw_spinlock_t lock; #ifdef CONFIG_SMP cpumask_var_t affinity; unsigned int node; diff --git a/include/linux/isicom.h b/include/linux/isicom.h index bbd42197298f..b92e05650639 100644 --- a/include/linux/isicom.h +++ b/include/linux/isicom.h @@ -67,6 +67,7 @@ #define FIRMWARE_LOADED 0x0001 #define BOARD_ACTIVE 0x0002 +#define BOARD_INIT 0x0004 /* isi_port status bitmap */ diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 792274269f2b..d8e9b3d1c23c 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -107,18 +107,6 @@ static inline void print_symbol(const char *fmt, unsigned long addr) __builtin_extract_return_addr((void *)addr)); } -/* - * Pretty-print a function pointer. This function is deprecated. - * Please use the "%pF" vsprintf format instead. - */ -static inline void __deprecated print_fn_descriptor_symbol(const char *fmt, void *addr) -{ -#if defined(CONFIG_IA64) || defined(CONFIG_PPC64) - addr = *(void **)addr; -#endif - print_symbol(fmt, (unsigned long)addr); -} - static inline void print_ip_sym(unsigned long ip) { printk("[<%p>] %pS\n", (void *) ip, (void *) ip); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3fa4c590cf12..4d9c916d06d9 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -251,10 +251,10 @@ extern int printk_delay_msec; * Print a one-time message (analogous to WARN_ONCE() et al): */ #define printk_once(x...) ({ \ - static bool __print_once = true; \ + static bool __print_once; \ \ - if (__print_once) { \ - __print_once = false; \ + if (!__print_once) { \ + __print_once = true; \ printk(x); \ } \ }) @@ -397,15 +397,58 @@ static inline char *pack_hex_byte(char *buf, u8 byte) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #elif defined(CONFIG_DYNAMIC_DEBUG) /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */ -#define pr_debug(fmt, ...) do { \ - dynamic_pr_debug(fmt, ##__VA_ARGS__); \ - } while (0) +#define pr_debug(fmt, ...) \ + dynamic_pr_debug(fmt, ##__VA_ARGS__) #else #define pr_debug(fmt, ...) \ ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) #endif /* + * ratelimited messages with local ratelimit_state, + * no local ratelimit_state used in the !PRINTK case + */ +#ifdef CONFIG_PRINTK +#define printk_ratelimited(fmt, ...) ({ \ + static struct ratelimit_state _rs = { \ + .interval = DEFAULT_RATELIMIT_INTERVAL, \ + .burst = DEFAULT_RATELIMIT_BURST, \ + }; \ + \ + if (!__ratelimit(&_rs)) \ + printk(fmt, ##__VA_ARGS__); \ +}) +#else +/* No effect, but we still get type checking even in the !PRINTK case: */ +#define printk_ratelimited printk +#endif + +#define pr_emerg_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define pr_alert_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_crit_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define pr_notice_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) +/* no pr_cont_ratelimited, don't do that... */ +/* If you are writing a driver, please use dev_dbg instead */ +#if defined(DEBUG) +#define pr_debug_ratelimited(fmt, ...) \ + printk_ratelimited(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) +#else +#define pr_debug_ratelimited(fmt, ...) \ + ({ if (0) printk_ratelimited(KERN_DEBUG pr_fmt(fmt), \ + ##__VA_ARGS__); 0; }) +#endif + +/* * General tracing related utility functions - trace_printk(), * tracing_on/tracing_off and tracing_start()/tracing_stop * diff --git a/include/linux/ksm.h b/include/linux/ksm.h index a485c14ecd5d..bed5f16ba827 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h @@ -9,8 +9,12 @@ #include <linux/bitops.h> #include <linux/mm.h> +#include <linux/pagemap.h> +#include <linux/rmap.h> #include <linux/sched.h> -#include <linux/vmstat.h> + +struct stable_node; +struct mem_cgroup; #ifdef CONFIG_KSM int ksm_madvise(struct vm_area_struct *vma, unsigned long start, @@ -34,23 +38,60 @@ static inline void ksm_exit(struct mm_struct *mm) /* * A KSM page is one of those write-protected "shared pages" or "merged pages" * which KSM maps into multiple mms, wherever identical anonymous page content - * is found in VM_MERGEABLE vmas. It's a PageAnon page, with NULL anon_vma. + * is found in VM_MERGEABLE vmas. It's a PageAnon page, pointing not to any + * anon_vma, but to that page's node of the stable tree. */ static inline int PageKsm(struct page *page) { - return ((unsigned long)page->mapping == PAGE_MAPPING_ANON); + return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) == + (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); +} + +static inline struct stable_node *page_stable_node(struct page *page) +{ + return PageKsm(page) ? page_rmapping(page) : NULL; +} + +static inline void set_page_stable_node(struct page *page, + struct stable_node *stable_node) +{ + page->mapping = (void *)stable_node + + (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM); } /* - * But we have to avoid the checking which page_add_anon_rmap() performs. + * When do_swap_page() first faults in from swap what used to be a KSM page, + * no problem, it will be assigned to this vma's anon_vma; but thereafter, + * it might be faulted into a different anon_vma (or perhaps to a different + * offset in the same anon_vma). do_swap_page() cannot do all the locking + * needed to reconstitute a cross-anon_vma KSM page: for now it has to make + * a copy, and leave remerging the pages to a later pass of ksmd. + * + * We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE, + * but what if the vma was unmerged while the page was swapped out? */ -static inline void page_add_ksm_rmap(struct page *page) +struct page *ksm_does_need_to_copy(struct page *page, + struct vm_area_struct *vma, unsigned long address); +static inline struct page *ksm_might_need_to_copy(struct page *page, + struct vm_area_struct *vma, unsigned long address) { - if (atomic_inc_and_test(&page->_mapcount)) { - page->mapping = (void *) PAGE_MAPPING_ANON; - __inc_zone_page_state(page, NR_ANON_PAGES); - } + struct anon_vma *anon_vma = page_anon_vma(page); + + if (!anon_vma || + (anon_vma == vma->anon_vma && + page->index == linear_page_index(vma, address))) + return page; + + return ksm_does_need_to_copy(page, vma, address); } + +int page_referenced_ksm(struct page *page, + struct mem_cgroup *memcg, unsigned long *vm_flags); +int try_to_unmap_ksm(struct page *page, enum ttu_flags flags); +int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *, + struct vm_area_struct *, unsigned long, void *), void *arg); +void ksm_migrate_page(struct page *newpage, struct page *oldpage); + #else /* !CONFIG_KSM */ static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, @@ -73,7 +114,32 @@ static inline int PageKsm(struct page *page) return 0; } -/* No stub required for page_add_ksm_rmap(page) */ +static inline struct page *ksm_might_need_to_copy(struct page *page, + struct vm_area_struct *vma, unsigned long address) +{ + return page; +} + +static inline int page_referenced_ksm(struct page *page, + struct mem_cgroup *memcg, unsigned long *vm_flags) +{ + return 0; +} + +static inline int try_to_unmap_ksm(struct page *page, enum ttu_flags flags) +{ + return 0; +} + +static inline int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page*, + struct vm_area_struct *, unsigned long, void *), void *arg) +{ + return 0; +} + +static inline void ksm_migrate_page(struct page *newpage, struct page *oldpage) +{ +} #endif /* !CONFIG_KSM */ -#endif +#endif /* __LINUX_KSM_H */ diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 2d241da07236..a24de0b1858e 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -496,6 +496,7 @@ struct kvm_ioeventfd { #define KVM_CAP_VCPU_EVENTS 41 #endif #define KVM_CAP_S390_PSW 42 +#define KVM_CAP_PPC_SEGSTATE 43 #ifdef KVM_CAP_IRQ_ROUTING diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index 3cc2f2c53e4c..f1ca0dcc1628 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -43,6 +43,21 @@ struct lis3lv02d_platform_data { #define LIS3_WAKEUP_Z_HI (1 << 5) unsigned char wakeup_flags; unsigned char wakeup_thresh; +#define LIS3_NO_MAP 0 +#define LIS3_DEV_X 1 +#define LIS3_DEV_Y 2 +#define LIS3_DEV_Z 3 +#define LIS3_INV_DEV_X -1 +#define LIS3_INV_DEV_Y -2 +#define LIS3_INV_DEV_Z -3 + s8 axis_x; + s8 axis_y; + s8 axis_z; + int (*setup_resources)(void); + int (*release_resources)(void); + /* Limits for selftest are specified in chip data sheet */ + s16 st_min_limits[3]; /* min pass limit x, y, z */ + s16 st_max_limits[3]; /* max pass limit x, y, z */ }; #endif /* __LIS3LV02D_H_ */ diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index fed969281a41..35b07b773e6c 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -69,7 +69,6 @@ extern void online_page(struct page *page); /* VM interface that may be used by firmware interface */ extern int online_pages(unsigned long, unsigned long); extern void __offline_isolated_pages(unsigned long, unsigned long); -extern int offline_pages(unsigned long, unsigned long, unsigned long); /* reasonably generic interface to expand the physical pages in a zone */ extern int __add_pages(int nid, struct zone *zone, unsigned long start_pfn, diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 085c903fe0f1..1cc966cd3e5f 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -201,6 +201,7 @@ extern void mpol_fix_fork_child_flag(struct task_struct *p); extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol, nodemask_t **nodemask); +extern bool init_nodemask_of_mempolicy(nodemask_t *mask); extern unsigned slab_node(struct mempolicy *policy); extern enum zone_type policy_zone; @@ -328,6 +329,8 @@ static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, return node_zonelist(0, gfp_flags); } +static inline bool init_nodemask_of_mempolicy(nodemask_t *m) { return false; } + static inline int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags) diff --git a/include/linux/mfd/88pm8607.h b/include/linux/mfd/88pm8607.h new file mode 100644 index 000000000000..f41b428d2cec --- /dev/null +++ b/include/linux/mfd/88pm8607.h @@ -0,0 +1,217 @@ +/* + * Marvell 88PM8607 Interface + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang <haojian.zhuang@marvell.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. + */ + +#ifndef __LINUX_MFD_88PM8607_H +#define __LINUX_MFD_88PM8607_H + +enum { + PM8607_ID_BUCK1 = 0, + PM8607_ID_BUCK2, + PM8607_ID_BUCK3, + + PM8607_ID_LDO1, + PM8607_ID_LDO2, + PM8607_ID_LDO3, + PM8607_ID_LDO4, + PM8607_ID_LDO5, + PM8607_ID_LDO6, + PM8607_ID_LDO7, + PM8607_ID_LDO8, + PM8607_ID_LDO9, + PM8607_ID_LDO10, + PM8607_ID_LDO12, + PM8607_ID_LDO14, + + PM8607_ID_RG_MAX, +}; + +#define CHIP_ID (0x40) +#define CHIP_ID_MASK (0xF8) + +/* Interrupt Registers */ +#define PM8607_STATUS_1 (0x01) +#define PM8607_STATUS_2 (0x02) +#define PM8607_INT_STATUS1 (0x03) +#define PM8607_INT_STATUS2 (0x04) +#define PM8607_INT_STATUS3 (0x05) +#define PM8607_INT_MASK_1 (0x06) +#define PM8607_INT_MASK_2 (0x07) +#define PM8607_INT_MASK_3 (0x08) + +/* Regulator Control Registers */ +#define PM8607_LDO1 (0x10) +#define PM8607_LDO2 (0x11) +#define PM8607_LDO3 (0x12) +#define PM8607_LDO4 (0x13) +#define PM8607_LDO5 (0x14) +#define PM8607_LDO6 (0x15) +#define PM8607_LDO7 (0x16) +#define PM8607_LDO8 (0x17) +#define PM8607_LDO9 (0x18) +#define PM8607_LDO10 (0x19) +#define PM8607_LDO12 (0x1A) +#define PM8607_LDO14 (0x1B) +#define PM8607_SLEEP_MODE1 (0x1C) +#define PM8607_SLEEP_MODE2 (0x1D) +#define PM8607_SLEEP_MODE3 (0x1E) +#define PM8607_SLEEP_MODE4 (0x1F) +#define PM8607_GO (0x20) +#define PM8607_SLEEP_BUCK1 (0x21) +#define PM8607_SLEEP_BUCK2 (0x22) +#define PM8607_SLEEP_BUCK3 (0x23) +#define PM8607_BUCK1 (0x24) +#define PM8607_BUCK2 (0x25) +#define PM8607_BUCK3 (0x26) +#define PM8607_BUCK_CONTROLS (0x27) +#define PM8607_SUPPLIES_EN11 (0x2B) +#define PM8607_SUPPLIES_EN12 (0x2C) +#define PM8607_GROUP1 (0x2D) +#define PM8607_GROUP2 (0x2E) +#define PM8607_GROUP3 (0x2F) +#define PM8607_GROUP4 (0x30) +#define PM8607_GROUP5 (0x31) +#define PM8607_GROUP6 (0x32) +#define PM8607_SUPPLIES_EN21 (0x33) +#define PM8607_SUPPLIES_EN22 (0x34) + +/* RTC Control Registers */ +#define PM8607_RTC1 (0xA0) +#define PM8607_RTC_COUNTER1 (0xA1) +#define PM8607_RTC_COUNTER2 (0xA2) +#define PM8607_RTC_COUNTER3 (0xA3) +#define PM8607_RTC_COUNTER4 (0xA4) +#define PM8607_RTC_EXPIRE1 (0xA5) +#define PM8607_RTC_EXPIRE2 (0xA6) +#define PM8607_RTC_EXPIRE3 (0xA7) +#define PM8607_RTC_EXPIRE4 (0xA8) +#define PM8607_RTC_TRIM1 (0xA9) +#define PM8607_RTC_TRIM2 (0xAA) +#define PM8607_RTC_TRIM3 (0xAB) +#define PM8607_RTC_TRIM4 (0xAC) +#define PM8607_RTC_MISC1 (0xAD) +#define PM8607_RTC_MISC2 (0xAE) +#define PM8607_RTC_MISC3 (0xAF) + +/* Misc Registers */ +#define PM8607_CHIP_ID (0x00) +#define PM8607_LDO1 (0x10) +#define PM8607_DVC3 (0x26) +#define PM8607_MISC1 (0x40) + +/* bit definitions for PM8607 events */ +#define PM8607_EVENT_ONKEY (1 << 0) +#define PM8607_EVENT_EXTON (1 << 1) +#define PM8607_EVENT_CHG (1 << 2) +#define PM8607_EVENT_BAT (1 << 3) +#define PM8607_EVENT_RTC (1 << 4) +#define PM8607_EVENT_CC (1 << 5) +#define PM8607_EVENT_VBAT (1 << 8) +#define PM8607_EVENT_VCHG (1 << 9) +#define PM8607_EVENT_VSYS (1 << 10) +#define PM8607_EVENT_TINT (1 << 11) +#define PM8607_EVENT_GPADC0 (1 << 12) +#define PM8607_EVENT_GPADC1 (1 << 13) +#define PM8607_EVENT_GPADC2 (1 << 14) +#define PM8607_EVENT_GPADC3 (1 << 15) +#define PM8607_EVENT_AUDIO_SHORT (1 << 16) +#define PM8607_EVENT_PEN (1 << 17) +#define PM8607_EVENT_HEADSET (1 << 18) +#define PM8607_EVENT_HOOK (1 << 19) +#define PM8607_EVENT_MICIN (1 << 20) +#define PM8607_EVENT_CHG_TIMEOUT (1 << 21) +#define PM8607_EVENT_CHG_DONE (1 << 22) +#define PM8607_EVENT_CHG_FAULT (1 << 23) + +/* bit definitions of Status Query Interface */ +#define PM8607_STATUS_CC (1 << 3) +#define PM8607_STATUS_PEN (1 << 4) +#define PM8607_STATUS_HEADSET (1 << 5) +#define PM8607_STATUS_HOOK (1 << 6) +#define PM8607_STATUS_MICIN (1 << 7) +#define PM8607_STATUS_ONKEY (1 << 8) +#define PM8607_STATUS_EXTON (1 << 9) +#define PM8607_STATUS_CHG (1 << 10) +#define PM8607_STATUS_BAT (1 << 11) +#define PM8607_STATUS_VBUS (1 << 12) +#define PM8607_STATUS_OV (1 << 13) + +/* bit definitions of BUCK3 */ +#define PM8607_BUCK3_DOUBLE (1 << 6) + +/* bit definitions of Misc1 */ +#define PM8607_MISC1_PI2C (1 << 0) + +/* Interrupt Number in 88PM8607 */ +enum { + PM8607_IRQ_ONKEY = 0, + PM8607_IRQ_EXTON, + PM8607_IRQ_CHG, + PM8607_IRQ_BAT, + PM8607_IRQ_RTC, + PM8607_IRQ_VBAT = 8, + PM8607_IRQ_VCHG, + PM8607_IRQ_VSYS, + PM8607_IRQ_TINT, + PM8607_IRQ_GPADC0, + PM8607_IRQ_GPADC1, + PM8607_IRQ_GPADC2, + PM8607_IRQ_GPADC3, + PM8607_IRQ_AUDIO_SHORT = 16, + PM8607_IRQ_PEN, + PM8607_IRQ_HEADSET, + PM8607_IRQ_HOOK, + PM8607_IRQ_MICIN, + PM8607_IRQ_CHG_FAIL, + PM8607_IRQ_CHG_DONE, + PM8607_IRQ_CHG_FAULT, +}; + +enum { + PM8607_CHIP_A0 = 0x40, + PM8607_CHIP_A1 = 0x41, + PM8607_CHIP_B0 = 0x48, +}; + + +struct pm8607_chip { + struct device *dev; + struct mutex io_lock; + struct i2c_client *client; + + int (*read)(struct pm8607_chip *chip, int reg, int bytes, void *dest); + int (*write)(struct pm8607_chip *chip, int reg, int bytes, void *src); + + int buck3_double; /* DVC ramp slope double */ + unsigned char chip_id; + +}; + +#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */ + +enum { + GI2C_PORT = 0, + PI2C_PORT, +}; + +struct pm8607_platform_data { + int i2c_port; /* Controlled by GI2C or PI2C */ + struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; +}; + +extern int pm8607_reg_read(struct pm8607_chip *, int); +extern int pm8607_reg_write(struct pm8607_chip *, int, unsigned char); +extern int pm8607_bulk_read(struct pm8607_chip *, int, int, + unsigned char *); +extern int pm8607_bulk_write(struct pm8607_chip *, int, int, + unsigned char *); +extern int pm8607_set_bits(struct pm8607_chip *, int, unsigned char, + unsigned char); +#endif /* __LINUX_MFD_88PM8607_H */ diff --git a/include/linux/mfd/ab4500.h b/include/linux/mfd/ab4500.h new file mode 100644 index 000000000000..a42a7033ae53 --- /dev/null +++ b/include/linux/mfd/ab4500.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2009 ST-Ericsson + * + * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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. + * + * AB4500 device core funtions, for client access + */ +#ifndef MFD_AB4500_H +#define MFD_AB4500_H + +#include <linux/device.h> + +/* + * AB4500 bank addresses + */ +#define AB4500_SYS_CTRL1_BLOCK 0x1 +#define AB4500_SYS_CTRL2_BLOCK 0x2 +#define AB4500_REGU_CTRL1 0x3 +#define AB4500_REGU_CTRL2 0x4 +#define AB4500_USB 0x5 +#define AB4500_TVOUT 0x6 +#define AB4500_DBI 0x7 +#define AB4500_ECI_AV_ACC 0x8 +#define AB4500_RESERVED 0x9 +#define AB4500_GPADC 0xA +#define AB4500_CHARGER 0xB +#define AB4500_GAS_GAUGE 0xC +#define AB4500_AUDIO 0xD +#define AB4500_INTERRUPT 0xE +#define AB4500_RTC 0xF +#define AB4500_MISC 0x10 +#define AB4500_DEBUG 0x12 +#define AB4500_PROD_TEST 0x13 +#define AB4500_OTP_EMUL 0x15 + +/* + * System control 1 register offsets. + * Bank = 0x01 + */ +#define AB4500_TURNON_STAT_REG 0x0100 +#define AB4500_RESET_STAT_REG 0x0101 +#define AB4500_PONKEY1_PRESS_STAT_REG 0x0102 + +#define AB4500_FSM_STAT1_REG 0x0140 +#define AB4500_FSM_STAT2_REG 0x0141 +#define AB4500_SYSCLK_REQ_STAT_REG 0x0142 +#define AB4500_USB_STAT1_REG 0x0143 +#define AB4500_USB_STAT2_REG 0x0144 +#define AB4500_STATUS_SPARE1_REG 0x0145 +#define AB4500_STATUS_SPARE2_REG 0x0146 + +#define AB4500_CTRL1_REG 0x0180 +#define AB4500_CTRL2_REG 0x0181 + +/* + * System control 2 register offsets. + * bank = 0x02 + */ +#define AB4500_CTRL3_REG 0x0200 +#define AB4500_MAIN_WDOG_CTRL_REG 0x0201 +#define AB4500_MAIN_WDOG_TIMER_REG 0x0202 +#define AB4500_LOW_BAT_REG 0x0203 +#define AB4500_BATT_OK_REG 0x0204 +#define AB4500_SYSCLK_TIMER_REG 0x0205 +#define AB4500_SMPSCLK_CTRL_REG 0x0206 +#define AB4500_SMPSCLK_SEL1_REG 0x0207 +#define AB4500_SMPSCLK_SEL2_REG 0x0208 +#define AB4500_SMPSCLK_SEL3_REG 0x0209 +#define AB4500_SYSULPCLK_CONF_REG 0x020A +#define AB4500_SYSULPCLK_CTRL1_REG 0x020B +#define AB4500_SYSCLK_CTRL_REG 0x020C +#define AB4500_SYSCLK_REQ1_VALID_REG 0x020D +#define AB4500_SYSCLK_REQ_VALID_REG 0x020E +#define AB4500_SYSCTRL_SPARE_REG 0x020F +#define AB4500_PAD_CONF_REG 0x0210 + +/* + * Regu control1 register offsets + * Bank = 0x03 + */ +#define AB4500_REGU_SERIAL_CTRL1_REG 0x0300 +#define AB4500_REGU_SERIAL_CTRL2_REG 0x0301 +#define AB4500_REGU_SERIAL_CTRL3_REG 0x0302 +#define AB4500_REGU_REQ_CTRL1_REG 0x0303 +#define AB4500_REGU_REQ_CTRL2_REG 0x0304 +#define AB4500_REGU_REQ_CTRL3_REG 0x0305 +#define AB4500_REGU_REQ_CTRL4_REG 0x0306 +#define AB4500_REGU_MISC1_REG 0x0380 +#define AB4500_REGU_OTGSUPPLY_CTRL_REG 0x0381 +#define AB4500_REGU_VUSB_CTRL_REG 0x0382 +#define AB4500_REGU_VAUDIO_SUPPLY_REG 0x0383 +#define AB4500_REGU_CTRL1_SPARE_REG 0x0384 + +/* + * Regu control2 Vmod register offsets + */ +#define AB4500_REGU_VMOD_REGU_REG 0x0440 +#define AB4500_REGU_VMOD_SEL1_REG 0x0441 +#define AB4500_REGU_VMOD_SEL2_REG 0x0442 +#define AB4500_REGU_CTRL_DISCH_REG 0x0443 +#define AB4500_REGU_CTRL_DISCH2_REG 0x0444 + +/* + * USB/ULPI register offsets + * Bank : 0x5 + */ +#define AB4500_USB_LINE_STAT_REG 0x0580 +#define AB4500_USB_LINE_CTRL1_REG 0x0581 +#define AB4500_USB_LINE_CTRL2_REG 0x0582 +#define AB4500_USB_LINE_CTRL3_REG 0x0583 +#define AB4500_USB_LINE_CTRL4_REG 0x0584 +#define AB4500_USB_LINE_CTRL5_REG 0x0585 +#define AB4500_USB_OTG_CTRL_REG 0x0587 +#define AB4500_USB_OTG_STAT_REG 0x0588 +#define AB4500_USB_OTG_STAT_REG 0x0588 +#define AB4500_USB_CTRL_SPARE_REG 0x0589 +#define AB4500_USB_PHY_CTRL_REG 0x058A + +/* + * TVOUT / CTRL register offsets + * Bank : 0x06 + */ +#define AB4500_TVOUT_CTRL_REG 0x0680 + +/* + * DBI register offsets + * Bank : 0x07 + */ +#define AB4500_DBI_REG1_REG 0x0700 +#define AB4500_DBI_REG2_REG 0x0701 + +/* + * ECI regsiter offsets + * Bank : 0x08 + */ +#define AB4500_ECI_CTRL_REG 0x0800 +#define AB4500_ECI_HOOKLEVEL_REG 0x0801 +#define AB4500_ECI_DATAOUT_REG 0x0802 +#define AB4500_ECI_DATAIN_REG 0x0803 + +/* + * AV Connector register offsets + * Bank : 0x08 + */ +#define AB4500_AV_CONN_REG 0x0840 + +/* + * Accessory detection register offsets + * Bank : 0x08 + */ +#define AB4500_ACC_DET_DB1_REG 0x0880 +#define AB4500_ACC_DET_DB2_REG 0x0881 + +/* + * GPADC register offsets + * Bank : 0x0A + */ +#define AB4500_GPADC_CTRL1_REG 0x0A00 +#define AB4500_GPADC_CTRL2_REG 0x0A01 +#define AB4500_GPADC_CTRL3_REG 0x0A02 +#define AB4500_GPADC_AUTO_TIMER_REG 0x0A03 +#define AB4500_GPADC_STAT_REG 0x0A04 +#define AB4500_GPADC_MANDATAL_REG 0x0A05 +#define AB4500_GPADC_MANDATAH_REG 0x0A06 +#define AB4500_GPADC_AUTODATAL_REG 0x0A07 +#define AB4500_GPADC_AUTODATAH_REG 0x0A08 +#define AB4500_GPADC_MUX_CTRL_REG 0x0A09 + +/* + * Charger / status register offfsets + * Bank : 0x0B + */ +#define AB4500_CH_STATUS1_REG 0x0B00 +#define AB4500_CH_STATUS2_REG 0x0B01 +#define AB4500_CH_USBCH_STAT1_REG 0x0B02 +#define AB4500_CH_USBCH_STAT2_REG 0x0B03 +#define AB4500_CH_FSM_STAT_REG 0x0B04 +#define AB4500_CH_STAT_REG 0x0B05 + +/* + * Charger / control register offfsets + * Bank : 0x0B + */ +#define AB4500_CH_VOLT_LVL_REG 0x0B40 + +/* + * Charger / main control register offfsets + * Bank : 0x0B + */ +#define AB4500_MCH_CTRL1 0x0B80 +#define AB4500_MCH_CTRL2 0x0B81 +#define AB4500_MCH_IPT_CURLVL_REG 0x0B82 +#define AB4500_CH_WD_REG 0x0B83 + +/* + * Charger / USB control register offsets + * Bank : 0x0B + */ +#define AB4500_USBCH_CTRL1_REG 0x0BC0 +#define AB4500_USBCH_CTRL2_REG 0x0BC1 +#define AB4500_USBCH_IPT_CRNTLVL_REG 0x0BC2 + +/* + * RTC bank register offsets + * Bank : 0xF + */ +#define AB4500_RTC_SOFF_STAT_REG 0x0F00 +#define AB4500_RTC_CC_CONF_REG 0x0F01 +#define AB4500_RTC_READ_REQ_REG 0x0F02 +#define AB4500_RTC_WATCH_TSECMID_REG 0x0F03 +#define AB4500_RTC_WATCH_TSECHI_REG 0x0F04 +#define AB4500_RTC_WATCH_TMIN_LOW_REG 0x0F05 +#define AB4500_RTC_WATCH_TMIN_MID_REG 0x0F06 +#define AB4500_RTC_WATCH_TMIN_HI_REG 0x0F07 +#define AB4500_RTC_ALRM_MIN_LOW_REG 0x0F08 +#define AB4500_RTC_ALRM_MIN_MID_REG 0x0F09 +#define AB4500_RTC_ALRM_MIN_HI_REG 0x0F0A +#define AB4500_RTC_STAT_REG 0x0F0B +#define AB4500_RTC_BKUP_CHG_REG 0x0F0C +#define AB4500_RTC_FORCE_BKUP_REG 0x0F0D +#define AB4500_RTC_CALIB_REG 0x0F0E +#define AB4500_RTC_SWITCH_STAT_REG 0x0F0F + +/* + * PWM Out generators + * Bank: 0x10 + */ +#define AB4500_PWM_OUT_CTRL1_REG 0x1060 +#define AB4500_PWM_OUT_CTRL2_REG 0x1061 +#define AB4500_PWM_OUT_CTRL3_REG 0x1062 +#define AB4500_PWM_OUT_CTRL4_REG 0x1063 +#define AB4500_PWM_OUT_CTRL5_REG 0x1064 +#define AB4500_PWM_OUT_CTRL6_REG 0x1065 +#define AB4500_PWM_OUT_CTRL7_REG 0x1066 + +#define AB4500_I2C_PAD_CTRL_REG 0x1067 +#define AB4500_REV_REG 0x1080 + +/** + * struct ab4500 + * @spi: spi device structure + * @tx_buf: transmit buffer + * @rx_buf: receive buffer + * @lock: sync primitive + */ +struct ab4500 { + struct spi_device *spi; + unsigned long tx_buf[4]; + unsigned long rx_buf[4]; + struct mutex lock; +}; + +int ab4500_write(struct ab4500 *ab4500, unsigned char block, + unsigned long addr, unsigned char data); +int ab4500_read(struct ab4500 *ab4500, unsigned char block, + unsigned long addr); + +#endif /* MFD_AB4500_H */ diff --git a/include/linux/mfd/adp5520.h b/include/linux/mfd/adp5520.h new file mode 100644 index 000000000000..ac37558a4673 --- /dev/null +++ b/include/linux/mfd/adp5520.h @@ -0,0 +1,299 @@ +/* + * Definitions and platform data for Analog Devices + * ADP5520/ADP5501 MFD PMICs (Backlight, LED, GPIO and Keys) + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + + +#ifndef __LINUX_MFD_ADP5520_H +#define __LINUX_MFD_ADP5520_H + +#define ID_ADP5520 5520 +#define ID_ADP5501 5501 + +/* + * ADP5520/ADP5501 Register Map + */ + +#define ADP5520_MODE_STATUS 0x00 +#define ADP5520_INTERRUPT_ENABLE 0x01 +#define ADP5520_BL_CONTROL 0x02 +#define ADP5520_BL_TIME 0x03 +#define ADP5520_BL_FADE 0x04 +#define ADP5520_DAYLIGHT_MAX 0x05 +#define ADP5520_DAYLIGHT_DIM 0x06 +#define ADP5520_OFFICE_MAX 0x07 +#define ADP5520_OFFICE_DIM 0x08 +#define ADP5520_DARK_MAX 0x09 +#define ADP5520_DARK_DIM 0x0A +#define ADP5520_BL_VALUE 0x0B +#define ADP5520_ALS_CMPR_CFG 0x0C +#define ADP5520_L2_TRIP 0x0D +#define ADP5520_L2_HYS 0x0E +#define ADP5520_L3_TRIP 0x0F +#define ADP5520_L3_HYS 0x10 +#define ADP5520_LED_CONTROL 0x11 +#define ADP5520_LED_TIME 0x12 +#define ADP5520_LED_FADE 0x13 +#define ADP5520_LED1_CURRENT 0x14 +#define ADP5520_LED2_CURRENT 0x15 +#define ADP5520_LED3_CURRENT 0x16 + +/* + * ADP5520 Register Map + */ + +#define ADP5520_GPIO_CFG_1 0x17 +#define ADP5520_GPIO_CFG_2 0x18 +#define ADP5520_GPIO_IN 0x19 +#define ADP5520_GPIO_OUT 0x1A +#define ADP5520_GPIO_INT_EN 0x1B +#define ADP5520_GPIO_INT_STAT 0x1C +#define ADP5520_GPIO_INT_LVL 0x1D +#define ADP5520_GPIO_DEBOUNCE 0x1E +#define ADP5520_GPIO_PULLUP 0x1F +#define ADP5520_KP_INT_STAT_1 0x20 +#define ADP5520_KP_INT_STAT_2 0x21 +#define ADP5520_KR_INT_STAT_1 0x22 +#define ADP5520_KR_INT_STAT_2 0x23 +#define ADP5520_KEY_STAT_1 0x24 +#define ADP5520_KEY_STAT_2 0x25 + +/* + * MODE_STATUS bits + */ + +#define ADP5520_nSTNBY (1 << 7) +#define ADP5520_BL_EN (1 << 6) +#define ADP5520_DIM_EN (1 << 5) +#define ADP5520_OVP_INT (1 << 4) +#define ADP5520_CMPR_INT (1 << 3) +#define ADP5520_GPI_INT (1 << 2) +#define ADP5520_KR_INT (1 << 1) +#define ADP5520_KP_INT (1 << 0) + +/* + * INTERRUPT_ENABLE bits + */ + +#define ADP5520_AUTO_LD_EN (1 << 4) +#define ADP5520_CMPR_IEN (1 << 3) +#define ADP5520_OVP_IEN (1 << 2) +#define ADP5520_KR_IEN (1 << 1) +#define ADP5520_KP_IEN (1 << 0) + +/* + * BL_CONTROL bits + */ + +#define ADP5520_BL_LVL ((x) << 5) +#define ADP5520_BL_LAW ((x) << 4) +#define ADP5520_BL_AUTO_ADJ (1 << 3) +#define ADP5520_OVP_EN (1 << 2) +#define ADP5520_FOVR (1 << 1) +#define ADP5520_KP_BL_EN (1 << 0) + +/* + * ALS_CMPR_CFG bits + */ + +#define ADP5520_L3_OUT (1 << 3) +#define ADP5520_L2_OUT (1 << 2) +#define ADP5520_L3_EN (1 << 1) + +#define ADP5020_MAX_BRIGHTNESS 0x7F + +#define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4)) +#define BL_CTRL_VAL(law, auto) (((1 & (auto)) << 3) | ((0x3 & (law)) << 4)) +#define ALS_CMPR_CFG_VAL(filt, l3_en) (((0x7 & filt) << 5) | l3_en) + +/* + * LEDs subdevice bits and masks + */ + +#define ADP5520_01_MAXLEDS 3 + +#define ADP5520_FLAG_LED_MASK 0x3 +#define ADP5520_FLAG_OFFT_SHIFT 8 +#define ADP5520_FLAG_OFFT_MASK 0x3 + +#define ADP5520_R3_MODE (1 << 5) +#define ADP5520_C3_MODE (1 << 4) +#define ADP5520_LED_LAW (1 << 3) +#define ADP5520_LED3_EN (1 << 2) +#define ADP5520_LED2_EN (1 << 1) +#define ADP5520_LED1_EN (1 << 0) + +/* + * GPIO subdevice bits and masks + */ + +#define ADP5520_MAXGPIOS 8 + +#define ADP5520_GPIO_C3 (1 << 7) /* LED2 or GPIO7 aka C3 */ +#define ADP5520_GPIO_C2 (1 << 6) +#define ADP5520_GPIO_C1 (1 << 5) +#define ADP5520_GPIO_C0 (1 << 4) +#define ADP5520_GPIO_R3 (1 << 3) /* LED3 or GPIO3 aka R3 */ +#define ADP5520_GPIO_R2 (1 << 2) +#define ADP5520_GPIO_R1 (1 << 1) +#define ADP5520_GPIO_R0 (1 << 0) + +struct adp5520_gpio_platform_data { + unsigned gpio_start; + u8 gpio_en_mask; + u8 gpio_pullup_mask; +}; + +/* + * Keypad subdevice bits and masks + */ + +#define ADP5520_MAXKEYS 16 + +#define ADP5520_COL_C3 (1 << 7) /* LED2 or GPIO7 aka C3 */ +#define ADP5520_COL_C2 (1 << 6) +#define ADP5520_COL_C1 (1 << 5) +#define ADP5520_COL_C0 (1 << 4) +#define ADP5520_ROW_R3 (1 << 3) /* LED3 or GPIO3 aka R3 */ +#define ADP5520_ROW_R2 (1 << 2) +#define ADP5520_ROW_R1 (1 << 1) +#define ADP5520_ROW_R0 (1 << 0) + +#define ADP5520_KEY(row, col) (col + row * 4) +#define ADP5520_KEYMAPSIZE ADP5520_MAXKEYS + +struct adp5520_keys_platform_data { + int rows_en_mask; /* Number of rows */ + int cols_en_mask; /* Number of columns */ + const unsigned short *keymap; /* Pointer to keymap */ + unsigned short keymapsize; /* Keymap size */ + unsigned repeat:1; /* Enable key repeat */ +}; + + +/* + * LEDs subdevice platform data + */ + +#define FLAG_ID_ADP5520_LED1_ADP5501_LED0 1 /* ADP5520 PIN ILED */ +#define FLAG_ID_ADP5520_LED2_ADP5501_LED1 2 /* ADP5520 PIN C3 */ +#define FLAG_ID_ADP5520_LED3_ADP5501_LED2 3 /* ADP5520 PIN R3 */ + +#define ADP5520_LED_DIS_BLINK (0 << ADP5520_FLAG_OFFT_SHIFT) +#define ADP5520_LED_OFFT_600ms (1 << ADP5520_FLAG_OFFT_SHIFT) +#define ADP5520_LED_OFFT_800ms (2 << ADP5520_FLAG_OFFT_SHIFT) +#define ADP5520_LED_OFFT_1200ms (3 << ADP5520_FLAG_OFFT_SHIFT) + +#define ADP5520_LED_ONT_200ms 0 +#define ADP5520_LED_ONT_600ms 1 +#define ADP5520_LED_ONT_800ms 2 +#define ADP5520_LED_ONT_1200ms 3 + +struct adp5520_leds_platform_data { + int num_leds; + struct led_info *leds; + u8 fade_in; /* Backlight Fade-In Timer */ + u8 fade_out; /* Backlight Fade-Out Timer */ + u8 led_on_time; +}; + +/* + * Backlight subdevice platform data + */ + +#define ADP5520_FADE_T_DIS 0 /* Fade Timer Disabled */ +#define ADP5520_FADE_T_300ms 1 /* 0.3 Sec */ +#define ADP5520_FADE_T_600ms 2 +#define ADP5520_FADE_T_900ms 3 +#define ADP5520_FADE_T_1200ms 4 +#define ADP5520_FADE_T_1500ms 5 +#define ADP5520_FADE_T_1800ms 6 +#define ADP5520_FADE_T_2100ms 7 +#define ADP5520_FADE_T_2400ms 8 +#define ADP5520_FADE_T_2700ms 9 +#define ADP5520_FADE_T_3000ms 10 +#define ADP5520_FADE_T_3500ms 11 +#define ADP5520_FADE_T_4000ms 12 +#define ADP5520_FADE_T_4500ms 13 +#define ADP5520_FADE_T_5000ms 14 +#define ADP5520_FADE_T_5500ms 15 /* 5.5 Sec */ + +#define ADP5520_BL_LAW_LINEAR 0 +#define ADP5520_BL_LAW_SQUARE 1 +#define ADP5520_BL_LAW_CUBIC1 2 +#define ADP5520_BL_LAW_CUBIC2 3 + +#define ADP5520_BL_AMBL_FILT_80ms 0 /* Light sensor filter time */ +#define ADP5520_BL_AMBL_FILT_160ms 1 +#define ADP5520_BL_AMBL_FILT_320ms 2 +#define ADP5520_BL_AMBL_FILT_640ms 3 +#define ADP5520_BL_AMBL_FILT_1280ms 4 +#define ADP5520_BL_AMBL_FILT_2560ms 5 +#define ADP5520_BL_AMBL_FILT_5120ms 6 +#define ADP5520_BL_AMBL_FILT_10240ms 7 /* 10.24 sec */ + + /* + * Blacklight current 0..30mA + */ +#define ADP5520_BL_CUR_mA(I) ((I * 127) / 30) + + /* + * L2 comparator current 0..1000uA + */ +#define ADP5520_L2_COMP_CURR_uA(I) ((I * 255) / 1000) + + /* + * L3 comparator current 0..127uA + */ +#define ADP5520_L3_COMP_CURR_uA(I) ((I * 255) / 127) + +struct adp5520_backlight_platform_data { + u8 fade_in; /* Backlight Fade-In Timer */ + u8 fade_out; /* Backlight Fade-Out Timer */ + u8 fade_led_law; /* fade-on/fade-off transfer characteristic */ + + u8 en_ambl_sens; /* 1 = enable ambient light sensor */ + u8 abml_filt; /* Light sensor filter time */ + u8 l1_daylight_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l1_daylight_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l2_office_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l2_office_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l3_dark_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l3_dark_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l2_trip; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1000 uA */ + u8 l2_hyst; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1000 uA */ + u8 l3_trip; /* use L3_COMP_CURR_uA(I) 0 <= I <= 127 uA */ + u8 l3_hyst; /* use L3_COMP_CURR_uA(I) 0 <= I <= 127 uA */ +}; + +/* + * MFD chip platform data + */ + +struct adp5520_platform_data { + struct adp5520_keys_platform_data *keys; + struct adp5520_gpio_platform_data *gpio; + struct adp5520_leds_platform_data *leds; + struct adp5520_backlight_platform_data *backlight; +}; + +/* + * MFD chip functions + */ + +extern int adp5520_read(struct device *dev, int reg, uint8_t *val); +extern int adp5520_write(struct device *dev, int reg, u8 val); +extern int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask); + +extern int adp5520_register_notifier(struct device *dev, + struct notifier_block *nb, unsigned int events); + +extern int adp5520_unregister_notifier(struct device *dev, + struct notifier_block *nb, unsigned int events); + +#endif /* __LINUX_MFD_ADP5520_H */ diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h index 3402042ddc31..40c372165f3e 100644 --- a/include/linux/mfd/ezx-pcap.h +++ b/include/linux/mfd/ezx-pcap.h @@ -231,9 +231,6 @@ void pcap_set_ts_bits(struct pcap_chip *, u32); #define PCAP_LED_4MA 1 #define PCAP_LED_5MA 2 #define PCAP_LED_9MA 3 -#define PCAP_LED_GPIO_VAL_MASK 0x00ffffff -#define PCAP_LED_GPIO_EN 0x01000000 -#define PCAP_LED_GPIO_INVERT 0x02000000 #define PCAP_LED_T_MASK 0xf #define PCAP_LED_C_MASK 0x3 #define PCAP_BL_MASK 0x1f diff --git a/include/linux/mfd/mc13783-private.h b/include/linux/mfd/mc13783-private.h index 47e698cb0f16..95cf9360553f 100644 --- a/include/linux/mfd/mc13783-private.h +++ b/include/linux/mfd/mc13783-private.h @@ -24,52 +24,23 @@ #include <linux/platform_device.h> #include <linux/mfd/mc13783.h> -#include <linux/workqueue.h> #include <linux/mutex.h> - -struct mc13783_irq { - void (*handler)(int, void *); - void *data; -}; - -#define MC13783_NUM_IRQ 2 -#define MC13783_IRQ_TS 0 -#define MC13783_IRQ_REGULATOR 1 - -#define MC13783_ADC_MODE_TS 1 -#define MC13783_ADC_MODE_SINGLE_CHAN 2 -#define MC13783_ADC_MODE_MULT_CHAN 3 +#include <linux/interrupt.h> struct mc13783 { - int revision; - struct device *dev; - struct spi_device *spi_device; - - int (*read_dev)(void *data, char reg, int count, u32 *dst); - int (*write_dev)(void *data, char reg, int count, const u32 *src); - - struct mutex io_lock; - void *io_data; + struct spi_device *spidev; + struct mutex lock; int irq; - unsigned int flags; + int flags; - struct mc13783_irq irq_handler[MC13783_NUM_IRQ]; - struct work_struct work; - struct completion adc_done; - unsigned int ts_active; - struct mutex adc_conv_lock; + irq_handler_t irqhandler[MC13783_NUM_IRQ]; + void *irqdata[MC13783_NUM_IRQ]; + /* XXX these should go as platformdata to the regulator subdevice */ struct mc13783_regulator_init_data *regulators; int num_regulators; }; -int mc13783_reg_read(struct mc13783 *, int reg_num, u32 *); -int mc13783_reg_write(struct mc13783 *, int, u32); -int mc13783_set_bits(struct mc13783 *, int, u32, u32); -int mc13783_free_irq(struct mc13783 *mc13783, int irq); -int mc13783_register_irq(struct mc13783 *mc13783, int irq, - void (*handler) (int, void *), void *data); - #define MC13783_REG_INTERRUPT_STATUS_0 0 #define MC13783_REG_INTERRUPT_MASK_0 1 #define MC13783_REG_INTERRUPT_SENSE_0 2 @@ -136,55 +107,6 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq, #define MC13783_REG_TEST_3 63 #define MC13783_REG_NB 64 - -/* - * Interrupt Status - */ -#define MC13783_INT_STAT_ADCDONEI (1 << 0) -#define MC13783_INT_STAT_ADCBISDONEI (1 << 1) -#define MC13783_INT_STAT_TSI (1 << 2) -#define MC13783_INT_STAT_WHIGHI (1 << 3) -#define MC13783_INT_STAT_WLOWI (1 << 4) -#define MC13783_INT_STAT_CHGDETI (1 << 6) -#define MC13783_INT_STAT_CHGOVI (1 << 7) -#define MC13783_INT_STAT_CHGREVI (1 << 8) -#define MC13783_INT_STAT_CHGSHORTI (1 << 9) -#define MC13783_INT_STAT_CCCVI (1 << 10) -#define MC13783_INT_STAT_CHGCURRI (1 << 11) -#define MC13783_INT_STAT_BPONI (1 << 12) -#define MC13783_INT_STAT_LOBATLI (1 << 13) -#define MC13783_INT_STAT_LOBATHI (1 << 14) -#define MC13783_INT_STAT_UDPI (1 << 15) -#define MC13783_INT_STAT_USBI (1 << 16) -#define MC13783_INT_STAT_IDI (1 << 19) -#define MC13783_INT_STAT_Unused (1 << 20) -#define MC13783_INT_STAT_SE1I (1 << 21) -#define MC13783_INT_STAT_CKDETI (1 << 22) -#define MC13783_INT_STAT_UDMI (1 << 23) - -/* - * Interrupt Mask - */ -#define MC13783_INT_MASK_ADCDONEM (1 << 0) -#define MC13783_INT_MASK_ADCBISDONEM (1 << 1) -#define MC13783_INT_MASK_TSM (1 << 2) -#define MC13783_INT_MASK_WHIGHM (1 << 3) -#define MC13783_INT_MASK_WLOWM (1 << 4) -#define MC13783_INT_MASK_CHGDETM (1 << 6) -#define MC13783_INT_MASK_CHGOVM (1 << 7) -#define MC13783_INT_MASK_CHGREVM (1 << 8) -#define MC13783_INT_MASK_CHGSHORTM (1 << 9) -#define MC13783_INT_MASK_CCCVM (1 << 10) -#define MC13783_INT_MASK_CHGCURRM (1 << 11) -#define MC13783_INT_MASK_BPONM (1 << 12) -#define MC13783_INT_MASK_LOBATLM (1 << 13) -#define MC13783_INT_MASK_LOBATHM (1 << 14) -#define MC13783_INT_MASK_UDPM (1 << 15) -#define MC13783_INT_MASK_USBM (1 << 16) -#define MC13783_INT_MASK_IDM (1 << 19) -#define MC13783_INT_MASK_SE1M (1 << 21) -#define MC13783_INT_MASK_CKDETM (1 << 22) - /* * Reg Regulator Mode 0 */ @@ -284,113 +206,15 @@ int mc13783_register_irq(struct mc13783 *mc13783, int irq, #define MC13783_SWCTRL_SW3_STBY (1 << 21) #define MC13783_SWCTRL_SW3_MODE (1 << 22) -/* - * ADC/Touch - */ -#define MC13783_ADC0_LICELLCON (1 << 0) -#define MC13783_ADC0_CHRGICON (1 << 1) -#define MC13783_ADC0_BATICON (1 << 2) -#define MC13783_ADC0_RTHEN (1 << 3) -#define MC13783_ADC0_DTHEN (1 << 4) -#define MC13783_ADC0_UIDEN (1 << 5) -#define MC13783_ADC0_ADOUTEN (1 << 6) -#define MC13783_ADC0_ADOUTPER (1 << 7) -#define MC13783_ADC0_ADREFEN (1 << 10) -#define MC13783_ADC0_ADREFMODE (1 << 11) -#define MC13783_ADC0_TSMOD0 (1 << 12) -#define MC13783_ADC0_TSMOD1 (1 << 13) -#define MC13783_ADC0_TSMOD2 (1 << 14) -#define MC13783_ADC0_CHRGRAWDIV (1 << 15) -#define MC13783_ADC0_ADINC1 (1 << 16) -#define MC13783_ADC0_ADINC2 (1 << 17) -#define MC13783_ADC0_WCOMP (1 << 18) -#define MC13783_ADC0_ADCBIS0 (1 << 23) - -#define MC13783_ADC1_ADEN (1 << 0) -#define MC13783_ADC1_RAND (1 << 1) -#define MC13783_ADC1_ADSEL (1 << 3) -#define MC13783_ADC1_TRIGMASK (1 << 4) -#define MC13783_ADC1_ADA10 (1 << 5) -#define MC13783_ADC1_ADA11 (1 << 6) -#define MC13783_ADC1_ADA12 (1 << 7) -#define MC13783_ADC1_ADA20 (1 << 8) -#define MC13783_ADC1_ADA21 (1 << 9) -#define MC13783_ADC1_ADA22 (1 << 10) -#define MC13783_ADC1_ATO0 (1 << 11) -#define MC13783_ADC1_ATO1 (1 << 12) -#define MC13783_ADC1_ATO2 (1 << 13) -#define MC13783_ADC1_ATO3 (1 << 14) -#define MC13783_ADC1_ATO4 (1 << 15) -#define MC13783_ADC1_ATO5 (1 << 16) -#define MC13783_ADC1_ATO6 (1 << 17) -#define MC13783_ADC1_ATO7 (1 << 18) -#define MC13783_ADC1_ATOX (1 << 19) -#define MC13783_ADC1_ASC (1 << 20) -#define MC13783_ADC1_ADTRIGIGN (1 << 21) -#define MC13783_ADC1_ADONESHOT (1 << 22) -#define MC13783_ADC1_ADCBIS1 (1 << 23) - -#define MC13783_ADC1_CHAN0_SHIFT 5 -#define MC13783_ADC1_CHAN1_SHIFT 8 - -#define MC13783_ADC2_ADD10 (1 << 2) -#define MC13783_ADC2_ADD11 (1 << 3) -#define MC13783_ADC2_ADD12 (1 << 4) -#define MC13783_ADC2_ADD13 (1 << 5) -#define MC13783_ADC2_ADD14 (1 << 6) -#define MC13783_ADC2_ADD15 (1 << 7) -#define MC13783_ADC2_ADD16 (1 << 8) -#define MC13783_ADC2_ADD17 (1 << 9) -#define MC13783_ADC2_ADD18 (1 << 10) -#define MC13783_ADC2_ADD19 (1 << 11) -#define MC13783_ADC2_ADD20 (1 << 14) -#define MC13783_ADC2_ADD21 (1 << 15) -#define MC13783_ADC2_ADD22 (1 << 16) -#define MC13783_ADC2_ADD23 (1 << 17) -#define MC13783_ADC2_ADD24 (1 << 18) -#define MC13783_ADC2_ADD25 (1 << 19) -#define MC13783_ADC2_ADD26 (1 << 20) -#define MC13783_ADC2_ADD27 (1 << 21) -#define MC13783_ADC2_ADD28 (1 << 22) -#define MC13783_ADC2_ADD29 (1 << 23) +static inline int mc13783_set_bits(struct mc13783 *mc13783, unsigned int offset, + u32 mask, u32 val) +{ + int ret; + mc13783_lock(mc13783); + ret = mc13783_reg_rmw(mc13783, offset, mask, val); + mc13783_unlock(mc13783); -#define MC13783_ADC3_WHIGH0 (1 << 0) -#define MC13783_ADC3_WHIGH1 (1 << 1) -#define MC13783_ADC3_WHIGH2 (1 << 2) -#define MC13783_ADC3_WHIGH3 (1 << 3) -#define MC13783_ADC3_WHIGH4 (1 << 4) -#define MC13783_ADC3_WHIGH5 (1 << 5) -#define MC13783_ADC3_ICID0 (1 << 6) -#define MC13783_ADC3_ICID1 (1 << 7) -#define MC13783_ADC3_ICID2 (1 << 8) -#define MC13783_ADC3_WLOW0 (1 << 9) -#define MC13783_ADC3_WLOW1 (1 << 10) -#define MC13783_ADC3_WLOW2 (1 << 11) -#define MC13783_ADC3_WLOW3 (1 << 12) -#define MC13783_ADC3_WLOW4 (1 << 13) -#define MC13783_ADC3_WLOW5 (1 << 14) -#define MC13783_ADC3_ADCBIS2 (1 << 23) - -#define MC13783_ADC4_ADDBIS10 (1 << 2) -#define MC13783_ADC4_ADDBIS11 (1 << 3) -#define MC13783_ADC4_ADDBIS12 (1 << 4) -#define MC13783_ADC4_ADDBIS13 (1 << 5) -#define MC13783_ADC4_ADDBIS14 (1 << 6) -#define MC13783_ADC4_ADDBIS15 (1 << 7) -#define MC13783_ADC4_ADDBIS16 (1 << 8) -#define MC13783_ADC4_ADDBIS17 (1 << 9) -#define MC13783_ADC4_ADDBIS18 (1 << 10) -#define MC13783_ADC4_ADDBIS19 (1 << 11) -#define MC13783_ADC4_ADDBIS20 (1 << 14) -#define MC13783_ADC4_ADDBIS21 (1 << 15) -#define MC13783_ADC4_ADDBIS22 (1 << 16) -#define MC13783_ADC4_ADDBIS23 (1 << 17) -#define MC13783_ADC4_ADDBIS24 (1 << 18) -#define MC13783_ADC4_ADDBIS25 (1 << 19) -#define MC13783_ADC4_ADDBIS26 (1 << 20) -#define MC13783_ADC4_ADDBIS27 (1 << 21) -#define MC13783_ADC4_ADDBIS28 (1 << 22) -#define MC13783_ADC4_ADDBIS29 (1 << 23) + return ret; +} #endif /* __LINUX_MFD_MC13783_PRIV_H */ - diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h index b3a2a7243573..35680409b8cf 100644 --- a/include/linux/mfd/mc13783.h +++ b/include/linux/mfd/mc13783.h @@ -1,28 +1,50 @@ /* - * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * Copyright 2009 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> * - * Initial development of this code was funded by - * Phytec Messtechnik GmbH, http://www.phytec.de - * - * 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 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, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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. */ +#ifndef __LINUX_MFD_MC13783_H +#define __LINUX_MFD_MC13783_H -#ifndef __INCLUDE_LINUX_MFD_MC13783_H -#define __INCLUDE_LINUX_MFD_MC13783_H +#include <linux/interrupt.h> struct mc13783; + +void mc13783_lock(struct mc13783 *mc13783); +void mc13783_unlock(struct mc13783 *mc13783); + +int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val); +int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val); +int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset, + u32 mask, u32 val); + +int mc13783_irq_request(struct mc13783 *mc13783, int irq, + irq_handler_t handler, const char *name, void *dev); +int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq, + irq_handler_t handler, const char *name, void *dev); +int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev); +int mc13783_ackirq(struct mc13783 *mc13783, int irq); + +int mc13783_mask(struct mc13783 *mc13783, int irq); +int mc13783_unmask(struct mc13783 *mc13783, int irq); + +#define MC13783_ADC0 43 +#define MC13783_ADC0_ADREFEN (1 << 10) +#define MC13783_ADC0_ADREFMODE (1 << 11) +#define MC13783_ADC0_TSMOD0 (1 << 12) +#define MC13783_ADC0_TSMOD1 (1 << 13) +#define MC13783_ADC0_TSMOD2 (1 << 14) +#define MC13783_ADC0_ADINC1 (1 << 16) +#define MC13783_ADC0_ADINC2 (1 << 17) + +#define MC13783_ADC0_TSMOD_MASK (MC13783_ADC0_TSMOD0 | \ + MC13783_ADC0_TSMOD1 | \ + MC13783_ADC0_TSMOD2) + +/* to be cleaned up */ struct regulator_init_data; struct mc13783_regulator_init_data { @@ -30,23 +52,30 @@ struct mc13783_regulator_init_data { struct regulator_init_data *init_data; }; -struct mc13783_platform_data { - struct mc13783_regulator_init_data *regulators; +struct mc13783_regulator_platform_data { int num_regulators; - unsigned int flags; + struct mc13783_regulator_init_data *regulators; }; -/* mc13783_platform_data flags */ +struct mc13783_platform_data { + int num_regulators; + struct mc13783_regulator_init_data *regulators; + #define MC13783_USE_TOUCHSCREEN (1 << 0) #define MC13783_USE_CODEC (1 << 1) #define MC13783_USE_ADC (1 << 2) #define MC13783_USE_RTC (1 << 3) #define MC13783_USE_REGULATOR (1 << 4) + unsigned int flags; +}; + +#define MC13783_ADC_MODE_TS 1 +#define MC13783_ADC_MODE_SINGLE_CHAN 2 +#define MC13783_ADC_MODE_MULT_CHAN 3 int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, unsigned int channel, unsigned int *sample); -void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status); #define MC13783_SW_SW1A 0 #define MC13783_SW_SW1B 1 @@ -80,5 +109,46 @@ void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status); #define MC13783_REGU_V3 29 #define MC13783_REGU_V4 30 -#endif /* __INCLUDE_LINUX_MFD_MC13783_H */ +#define MC13783_IRQ_ADCDONE 0 +#define MC13783_IRQ_ADCBISDONE 1 +#define MC13783_IRQ_TS 2 +#define MC13783_IRQ_WHIGH 3 +#define MC13783_IRQ_WLOW 4 +#define MC13783_IRQ_CHGDET 6 +#define MC13783_IRQ_CHGOV 7 +#define MC13783_IRQ_CHGREV 8 +#define MC13783_IRQ_CHGSHORT 9 +#define MC13783_IRQ_CCCV 10 +#define MC13783_IRQ_CHGCURR 11 +#define MC13783_IRQ_BPON 12 +#define MC13783_IRQ_LOBATL 13 +#define MC13783_IRQ_LOBATH 14 +#define MC13783_IRQ_UDP 15 +#define MC13783_IRQ_USB 16 +#define MC13783_IRQ_ID 19 +#define MC13783_IRQ_SE1 21 +#define MC13783_IRQ_CKDET 22 +#define MC13783_IRQ_UDM 23 +#define MC13783_IRQ_1HZ 24 +#define MC13783_IRQ_TODA 25 +#define MC13783_IRQ_ONOFD1 27 +#define MC13783_IRQ_ONOFD2 28 +#define MC13783_IRQ_ONOFD3 29 +#define MC13783_IRQ_SYSRST 30 +#define MC13783_IRQ_RTCRST 31 +#define MC13783_IRQ_PC 32 +#define MC13783_IRQ_WARM 33 +#define MC13783_IRQ_MEMHLD 34 +#define MC13783_IRQ_PWRRDY 35 +#define MC13783_IRQ_THWARNL 36 +#define MC13783_IRQ_THWARNH 37 +#define MC13783_IRQ_CLK 38 +#define MC13783_IRQ_SEMAF 39 +#define MC13783_IRQ_MC2B 41 +#define MC13783_IRQ_HSDET 42 +#define MC13783_IRQ_HSL 43 +#define MC13783_IRQ_ALSPTH 44 +#define MC13783_IRQ_AHSSHORT 45 +#define MC13783_NUM_IRQ 46 +#endif /* __LINUX_MFD_MC13783_H */ diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 9aba7b779fbc..3398bd9aab11 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h @@ -29,7 +29,12 @@ struct pcf50633_platform_data { char **batteries; int num_batteries; - int charging_restart_interval; + /* + * Should be set accordingly to the reference resistor used, see + * I_{ch(ref)} charger reference current in the pcf50633 User + * Manual. + */ + int charger_reference_current_ma; /* Callbacks */ void (*probe_done)(struct pcf50633 *); @@ -40,10 +45,6 @@ struct pcf50633_platform_data { u8 resumers[5]; }; -struct pcf50633_subdev_pdata { - struct pcf50633 *pcf; -}; - struct pcf50633_irq { void (*handler) (int, void *); void *data; @@ -217,5 +218,9 @@ enum pcf50633_reg_int5 { #define PCF50633_REG_LEDCTL 0x2a #define PCF50633_REG_LEDDIM 0x2b -#endif +static inline struct pcf50633 *dev_to_pcf50633(struct device *dev) +{ + return dev_get_drvdata(dev); +} +#endif diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h index 4119579acf2c..df4f5fa88de3 100644 --- a/include/linux/mfd/pcf50633/mbc.h +++ b/include/linux/mfd/pcf50633/mbc.h @@ -128,6 +128,7 @@ enum pcf50633_reg_mbcs3 { int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma); int pcf50633_mbc_get_status(struct pcf50633 *); +int pcf50633_mbc_get_usb_online_status(struct pcf50633 *); #endif diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 91eb493bf14c..5184b79c700b 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -16,7 +16,6 @@ #define __MFD_WM831X_CORE_H__ #include <linux/interrupt.h> -#include <linux/workqueue.h> /* * Register values. @@ -117,6 +116,7 @@ #define WM831X_DC3_SLEEP_CONTROL 0x4063 #define WM831X_DC4_CONTROL 0x4064 #define WM831X_DC4_SLEEP_CONTROL 0x4065 +#define WM832X_DC4_SLEEP_CONTROL 0x4067 #define WM831X_EPE1_CONTROL 0x4066 #define WM831X_EPE2_CONTROL 0x4067 #define WM831X_LDO1_CONTROL 0x4068 @@ -235,6 +235,8 @@ struct regulator_dev; +#define WM831X_NUM_IRQ_REGS 5 + struct wm831x { struct mutex io_lock; @@ -248,10 +250,11 @@ struct wm831x { int irq; /* Our chip IRQ */ struct mutex irq_lock; - struct workqueue_struct *irq_wq; - struct work_struct irq_work; unsigned int irq_base; - int irq_masks[5]; + int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */ + int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ + + int num_gpio; struct mutex auxadc_lock; @@ -278,12 +281,30 @@ int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, int wm831x_irq_init(struct wm831x *wm831x, int irq); void wm831x_irq_exit(struct wm831x *wm831x); -int __must_check wm831x_request_irq(struct wm831x *wm831x, - unsigned int irq, irq_handler_t handler, - unsigned long flags, const char *name, - void *dev); -void wm831x_free_irq(struct wm831x *wm831x, unsigned int, void *); -void wm831x_disable_irq(struct wm831x *wm831x, int irq); -void wm831x_enable_irq(struct wm831x *wm831x, int irq); +static inline int __must_check wm831x_request_irq(struct wm831x *wm831x, + unsigned int irq, + irq_handler_t handler, + unsigned long flags, + const char *name, + void *dev) +{ + return request_threaded_irq(irq, NULL, handler, flags, name, dev); +} + +static inline void wm831x_free_irq(struct wm831x *wm831x, + unsigned int irq, void *dev) +{ + free_irq(irq, dev); +} + +static inline void wm831x_disable_irq(struct wm831x *wm831x, int irq) +{ + disable_irq(irq); +} + +static inline void wm831x_enable_irq(struct wm831x *wm831x, int irq) +{ + enable_irq(irq); +} #endif diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 90d820260aad..415c228743d5 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -91,6 +91,7 @@ struct wm831x_pdata { /** Called after subdevices are set up */ int (*post_init)(struct wm831x *wm831x); + int irq_base; int gpio_base; struct wm831x_backlight_pdata *backlight; struct wm831x_backup_pdata *backup; diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 1d595de6a055..43868899bf49 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -15,7 +15,7 @@ #include <linux/kernel.h> #include <linux/mutex.h> -#include <linux/workqueue.h> +#include <linux/interrupt.h> #include <linux/mfd/wm8350/audio.h> #include <linux/mfd/wm8350/gpio.h> @@ -601,7 +601,7 @@ extern const u16 wm8352_mode3_defaults[]; struct wm8350; struct wm8350_irq { - void (*handler) (struct wm8350 *, int, void *); + irq_handler_t handler; void *data; }; @@ -646,10 +646,12 @@ struct wm8350 { * @init: Function called during driver initialisation. Should be * used by the platform to configure GPIO functions and similar. * @irq_high: Set if WM8350 IRQ is active high. + * @irq_base: Base IRQ for genirq (not currently used). */ struct wm8350_platform_data { int (*init)(struct wm8350 *wm8350); int irq_high; + int irq_base; }; @@ -676,11 +678,13 @@ int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src); * WM8350 internal interrupts */ int wm8350_register_irq(struct wm8350 *wm8350, int irq, - void (*handler) (struct wm8350 *, int, void *), - void *data); + irq_handler_t handler, unsigned long flags, + const char *name, void *data); int wm8350_free_irq(struct wm8350 *wm8350, int irq); int wm8350_mask_irq(struct wm8350 *wm8350, int irq); int wm8350_unmask_irq(struct wm8350 *wm8350, int irq); - +int wm8350_irq_init(struct wm8350 *wm8350, int irq, + struct wm8350_platform_data *pdata); +int wm8350_irq_exit(struct wm8350 *wm8350); #endif diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h index ed91e8f5d298..71af3d6ebe9d 100644 --- a/include/linux/mfd/wm8350/gpio.h +++ b/include/linux/mfd/wm8350/gpio.h @@ -173,6 +173,24 @@ #define WM8350_GPIO_DEBOUNCE_ON 1 /* + * R30 (0x1E) - GPIO Interrupt Status + */ +#define WM8350_GP12_EINT 0x1000 +#define WM8350_GP11_EINT 0x0800 +#define WM8350_GP10_EINT 0x0400 +#define WM8350_GP9_EINT 0x0200 +#define WM8350_GP8_EINT 0x0100 +#define WM8350_GP7_EINT 0x0080 +#define WM8350_GP6_EINT 0x0040 +#define WM8350_GP5_EINT 0x0020 +#define WM8350_GP4_EINT 0x0010 +#define WM8350_GP3_EINT 0x0008 +#define WM8350_GP2_EINT 0x0004 +#define WM8350_GP1_EINT 0x0002 +#define WM8350_GP0_EINT 0x0001 + + +/* * R128 (0x80) - GPIO Debounce */ #define WM8350_GP12_DB 0x1000 diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 527602cdea1c..7f085c97c799 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -12,7 +12,8 @@ typedef struct page *new_page_t(struct page *, unsigned long private, int **); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct address_space *, struct page *, struct page *); -extern int migrate_pages(struct list_head *l, new_page_t x, unsigned long); +extern int migrate_pages(struct list_head *l, new_page_t x, + unsigned long private, int offlining); extern int fail_migrate_page(struct address_space *, struct page *, struct page *); @@ -26,10 +27,7 @@ extern int migrate_vmas(struct mm_struct *mm, static inline int putback_lru_pages(struct list_head *l) { return 0; } static inline int migrate_pages(struct list_head *l, new_page_t x, - unsigned long private) { return -ENOSYS; } - -static inline int migrate_pages_to(struct list_head *pagelist, - struct vm_area_struct *vma, int dest) { return 0; } + unsigned long private, int offlining) { return -ENOSYS; } static inline int migrate_prep(void) { return -ENOSYS; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 24c395694f4d..9d65ae4ba0e0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -620,13 +620,22 @@ void page_address_init(void); /* * On an anonymous page mapped into a user virtual memory area, * page->mapping points to its anon_vma, not to a struct address_space; - * with the PAGE_MAPPING_ANON bit set to distinguish it. + * with the PAGE_MAPPING_ANON bit set to distinguish it. See rmap.h. + * + * On an anonymous page in a VM_MERGEABLE area, if CONFIG_KSM is enabled, + * the PAGE_MAPPING_KSM bit may be set along with the PAGE_MAPPING_ANON bit; + * and then page->mapping points, not to an anon_vma, but to a private + * structure which KSM associates with that merged page. See ksm.h. + * + * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is currently never used. * * Please note that, confusingly, "page_mapping" refers to the inode * address_space which maps the page from disk; whereas "page_mapped" * refers to user virtual address space into which the page is mapped. */ #define PAGE_MAPPING_ANON 1 +#define PAGE_MAPPING_KSM 2 +#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM) extern struct address_space swapper_space; static inline struct address_space *page_mapping(struct page *page) @@ -634,16 +643,19 @@ static inline struct address_space *page_mapping(struct page *page) struct address_space *mapping = page->mapping; VM_BUG_ON(PageSlab(page)); -#ifdef CONFIG_SWAP if (unlikely(PageSwapCache(page))) mapping = &swapper_space; - else -#endif - if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON)) + else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON)) mapping = NULL; return mapping; } +/* Neutral page->mapping pointer to address_space or anon_vma or other */ +static inline void *page_rmapping(struct page *page) +{ + return (void *)((unsigned long)page->mapping & ~PAGE_MAPPING_FLAGS); +} + static inline int PageAnon(struct page *page) { return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0; @@ -758,6 +770,7 @@ unsigned long unmap_vmas(struct mmu_gather **tlb, * @pmd_entry: if set, called for each non-empty PMD (3rd-level) entry * @pte_entry: if set, called for each non-empty PTE (4th-level) entry * @pte_hole: if set, called for each hole at all levels + * @hugetlb_entry: if set, called for each hugetlb entry * * (see walk_page_range for more details) */ @@ -767,6 +780,8 @@ struct mm_walk { int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *); int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *); int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *); + int (*hugetlb_entry)(pte_t *, unsigned long, unsigned long, + struct mm_walk *); struct mm_struct *mm; void *private; }; diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h index 6913b71d9ab2..b31bd9e9bca3 100644 --- a/include/linux/mtd/ubi.h +++ b/include/linux/mtd/ubi.h @@ -174,6 +174,8 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc, struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode); struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, int mode); +struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode); + int ubi_register_volume_notifier(struct notifier_block *nb, int ignore_existing); int ubi_unregister_volume_notifier(struct notifier_block *nb); diff --git a/include/linux/namei.h b/include/linux/namei.h index ec0f607b364a..028946750289 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -76,7 +76,6 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); extern void release_open_intent(struct nameidata *); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); -extern struct dentry *lookup_one_noperm(const char *, struct dentry *); extern int follow_down(struct path *); extern int follow_up(struct path *); diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index c4c060208109..9b8299af3741 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -128,6 +128,8 @@ #define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040 #define SEQ4_STATUS_LEASE_MOVED 0x00000080 #define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 +#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 +#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 #define NFS4_MAX_UINT64 (~(u64)0) @@ -528,6 +530,7 @@ enum { NFSPROC4_CLNT_DESTROY_SESSION, NFSPROC4_CLNT_SEQUENCE, NFSPROC4_CLNT_GET_LEASE_TIME, + NFSPROC4_CLNT_RECLAIM_COMPLETE, }; /* nfs41 types */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 320569eabe3b..34fc6be5bfcf 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -209,6 +209,7 @@ struct nfs4_session { unsigned long session_state; u32 hash_alg; u32 ssv_len; + struct completion complete; /* The fore and back channel */ struct nfs4_channel_attrs fc_attrs; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 62f63fb0c4c8..51071b335751 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -170,8 +170,9 @@ struct nfs4_sequence_args { struct nfs4_sequence_res { struct nfs4_session *sr_session; u8 sr_slotid; /* slot used to send request */ - unsigned long sr_renewal_time; int sr_status; /* sequence operation status */ + unsigned long sr_renewal_time; + u32 sr_status_flags; }; struct nfs4_get_lease_time_args { @@ -938,6 +939,16 @@ struct nfs41_create_session_args { struct nfs41_create_session_res { struct nfs_client *client; }; + +struct nfs41_reclaim_complete_args { + /* In the future extend to include curr_fh for use with migration */ + unsigned char one_fs:1; + struct nfs4_sequence_args seq_args; +}; + +struct nfs41_reclaim_complete_res { + struct nfs4_sequence_res seq_res; +}; #endif /* CONFIG_NFS_V4_1 */ struct nfs_page; diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index ce520402e840..3fe02cf8b65a 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h @@ -151,6 +151,8 @@ struct nilfs_super_root { #define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */ #define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order semantics also for data */ +#define NILFS_MOUNT_NORECOVERY 0x4000 /* Disable write access during + mount-time recovery */ /** @@ -403,6 +405,28 @@ struct nilfs_segment_summary { #define NILFS_SS_GC 0x0010 /* segment written for cleaner operation */ /** + * struct nilfs_btree_node - B-tree node + * @bn_flags: flags + * @bn_level: level + * @bn_nchildren: number of children + * @bn_pad: padding + */ +struct nilfs_btree_node { + __u8 bn_flags; + __u8 bn_level; + __le16 bn_nchildren; + __le32 bn_pad; +}; + +/* flags */ +#define NILFS_BTREE_NODE_ROOT 0x01 + +/* level */ +#define NILFS_BTREE_LEVEL_DATA 0 +#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) +#define NILFS_BTREE_LEVEL_MAX 14 + +/** * struct nilfs_palloc_group_desc - block group descriptor * @pg_nfrees: number of free entries in block group */ diff --git a/include/linux/node.h b/include/linux/node.h index 681a697b9a86..06292dac3eab 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -21,13 +21,19 @@ #include <linux/sysdev.h> #include <linux/cpumask.h> +#include <linux/workqueue.h> struct node { struct sys_device sysdev; + +#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS) + struct work_struct node_work; +#endif }; struct memory_block; extern struct node node_devices[]; +typedef void (*node_registration_func_t)(struct node *); extern int register_node(struct node *, int, struct node *); extern void unregister_node(struct node *node); @@ -39,6 +45,11 @@ extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, int nid); extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); + +#ifdef CONFIG_HUGETLBFS +extern void register_hugetlbfs_with_node(node_registration_func_t doregister, + node_registration_func_t unregister); +#endif #else static inline int register_one_node(int nid) { @@ -65,6 +76,11 @@ static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) { return 0; } + +static inline void register_hugetlbfs_with_node(node_registration_func_t reg, + node_registration_func_t unreg) +{ +} #endif #define to_node(sys_device) container_of(sys_device, struct node, sysdev) diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index b359c4a9ec9e..454997cccbd8 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -245,14 +245,19 @@ static inline int __next_node(int n, const nodemask_t *srcp) return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1)); } +static inline void init_nodemask_of_node(nodemask_t *mask, int node) +{ + nodes_clear(*mask); + node_set(node, *mask); +} + #define nodemask_of_node(node) \ ({ \ typeof(_unused_nodemask_arg_) m; \ if (sizeof(m) == sizeof(unsigned long)) { \ - m.bits[0] = 1UL<<(node); \ + m.bits[0] = 1UL << (node); \ } else { \ - nodes_clear(m); \ - node_set((node), m); \ + init_nodemask_of_node(&m, (node)); \ } \ m; \ }) @@ -480,15 +485,17 @@ static inline int num_node_state(enum node_states state) #define for_each_online_node(node) for_each_node_state(node, N_ONLINE) /* - * For nodemask scrach area.(See CPUMASK_ALLOC() in cpumask.h) + * For nodemask scrach area. + * NODEMASK_ALLOC(type, name) allocates an object with a specified type and + * name. */ - -#if NODES_SHIFT > 8 /* nodemask_t > 64 bytes */ -#define NODEMASK_ALLOC(x, m) struct x *m = kmalloc(sizeof(*m), GFP_KERNEL) -#define NODEMASK_FREE(m) kfree(m) +#if NODES_SHIFT > 8 /* nodemask_t > 256 bytes */ +#define NODEMASK_ALLOC(type, name, gfp_flags) \ + type *name = kmalloc(sizeof(*name), gfp_flags) +#define NODEMASK_FREE(m) kfree(m) #else -#define NODEMASK_ALLOC(x, m) struct x _m, *m = &_m -#define NODEMASK_FREE(m) +#define NODEMASK_ALLOC(type, name, gfp_flags) type _name, *name = &_name +#define NODEMASK_FREE(m) do {} while (0) #endif /* A example struture for using NODEMASK_ALLOC, used in mempolicy. */ @@ -497,8 +504,10 @@ struct nodemask_scratch { nodemask_t mask2; }; -#define NODEMASK_SCRATCH(x) NODEMASK_ALLOC(nodemask_scratch, x) -#define NODEMASK_SCRATCH_FREE(x) NODEMASK_FREE(x) +#define NODEMASK_SCRATCH(x) \ + NODEMASK_ALLOC(struct nodemask_scratch, x, \ + GFP_KERNEL | __GFP_NORETRY) +#define NODEMASK_SCRATCH_FREE(x) NODEMASK_FREE(x) #endif /* __LINUX_NODEMASK_H */ diff --git a/include/linux/numa.h b/include/linux/numa.h index a31a7301b159..3aaa31603a86 100644 --- a/include/linux/numa.h +++ b/include/linux/numa.h @@ -10,4 +10,6 @@ #define MAX_NUMNODES (1 << NODES_SHIFT) +#define NUMA_NO_NODE (-1) + #endif /* _LINUX_NUMA_H */ diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h new file mode 100644 index 000000000000..f46c40ac6d45 --- /dev/null +++ b/include/linux/omapfb.h @@ -0,0 +1,251 @@ +/* + * File: include/linux/omapfb.h + * + * Framebuffer driver for TI OMAP boards + * + * Copyright (C) 2004 Nokia Corporation + * Author: Imre Deak <imre.deak@nokia.com> + * + * 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 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, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __LINUX_OMAPFB_H__ +#define __LINUX_OMAPFB_H__ + +#include <linux/fb.h> +#include <linux/ioctl.h> +#include <linux/types.h> + +/* IOCTL commands. */ + +#define OMAP_IOW(num, dtype) _IOW('O', num, dtype) +#define OMAP_IOR(num, dtype) _IOR('O', num, dtype) +#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype) +#define OMAP_IO(num) _IO('O', num) + +#define OMAPFB_MIRROR OMAP_IOW(31, int) +#define OMAPFB_SYNC_GFX OMAP_IO(37) +#define OMAPFB_VSYNC OMAP_IO(38) +#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int) +#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps) +#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int) +#define OMAPFB_LCD_TEST OMAP_IOW(45, int) +#define OMAPFB_CTRL_TEST OMAP_IOW(46, int) +#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old) +#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key) +#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key) +#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info) +#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info) +#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window) +#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info) +#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info) +#define OMAPFB_WAITFORVSYNC OMAP_IO(57) +#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read) +#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode) +#define OMAPFB_WAITFORGO OMAP_IO(60) +#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info) +#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info) + +#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff +#define OMAPFB_CAPS_LCDC_MASK 0x00fff000 +#define OMAPFB_CAPS_PANEL_MASK 0xff000000 + +#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000 +#define OMAPFB_CAPS_TEARSYNC 0x00002000 +#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000 +#define OMAPFB_CAPS_PLANE_SCALE 0x00008000 +#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000 +#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000 +#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000 +#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000 +#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000 + +/* Values from DSP must map to lower 16-bits */ +#define OMAPFB_FORMAT_MASK 0x00ff +#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100 +#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200 +#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400 +#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800 +#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000 + +#define OMAPFB_MEMTYPE_SDRAM 0 +#define OMAPFB_MEMTYPE_SRAM 1 +#define OMAPFB_MEMTYPE_MAX 1 + +enum omapfb_color_format { + OMAPFB_COLOR_RGB565 = 0, + OMAPFB_COLOR_YUV422, + OMAPFB_COLOR_YUV420, + OMAPFB_COLOR_CLUT_8BPP, + OMAPFB_COLOR_CLUT_4BPP, + OMAPFB_COLOR_CLUT_2BPP, + OMAPFB_COLOR_CLUT_1BPP, + OMAPFB_COLOR_RGB444, + OMAPFB_COLOR_YUY422, + + OMAPFB_COLOR_ARGB16, + OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */ + OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */ + OMAPFB_COLOR_ARGB32, + OMAPFB_COLOR_RGBA32, + OMAPFB_COLOR_RGBX32, +}; + +struct omapfb_update_window { + __u32 x, y; + __u32 width, height; + __u32 format; + __u32 out_x, out_y; + __u32 out_width, out_height; + __u32 reserved[8]; +}; + +struct omapfb_update_window_old { + __u32 x, y; + __u32 width, height; + __u32 format; +}; + +enum omapfb_plane { + OMAPFB_PLANE_GFX = 0, + OMAPFB_PLANE_VID1, + OMAPFB_PLANE_VID2, +}; + +enum omapfb_channel_out { + OMAPFB_CHANNEL_OUT_LCD = 0, + OMAPFB_CHANNEL_OUT_DIGIT, +}; + +struct omapfb_plane_info { + __u32 pos_x; + __u32 pos_y; + __u8 enabled; + __u8 channel_out; + __u8 mirror; + __u8 reserved1; + __u32 out_width; + __u32 out_height; + __u32 reserved2[12]; +}; + +struct omapfb_mem_info { + __u32 size; + __u8 type; + __u8 reserved[3]; +}; + +struct omapfb_caps { + __u32 ctrl; + __u32 plane_color; + __u32 wnd_color; +}; + +enum omapfb_color_key_type { + OMAPFB_COLOR_KEY_DISABLED = 0, + OMAPFB_COLOR_KEY_GFX_DST, + OMAPFB_COLOR_KEY_VID_SRC, +}; + +struct omapfb_color_key { + __u8 channel_out; + __u32 background; + __u32 trans_key; + __u8 key_type; +}; + +enum omapfb_update_mode { + OMAPFB_UPDATE_DISABLED = 0, + OMAPFB_AUTO_UPDATE, + OMAPFB_MANUAL_UPDATE +}; + +struct omapfb_memory_read { + __u16 x; + __u16 y; + __u16 w; + __u16 h; + size_t buffer_size; + void __user *buffer; +}; + +struct omapfb_ovl_colormode { + __u8 overlay_idx; + __u8 mode_idx; + __u32 bits_per_pixel; + __u32 nonstd; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + +struct omapfb_vram_info { + __u32 total; + __u32 free; + __u32 largest_free_block; + __u32 reserved[5]; +}; + +struct omapfb_tearsync_info { + __u8 enabled; + __u8 reserved1[3]; + __u16 line; + __u16 reserved2; +}; + +#ifdef __KERNEL__ + +#include <plat/board.h> + +#ifdef CONFIG_ARCH_OMAP1 +#define OMAPFB_PLANE_NUM 1 +#else +#define OMAPFB_PLANE_NUM 3 +#endif + +struct omapfb_mem_region { + u32 paddr; + void __iomem *vaddr; + unsigned long size; + u8 type; /* OMAPFB_PLANE_MEM_* */ + enum omapfb_color_format format;/* OMAPFB_COLOR_* */ + unsigned format_used:1; /* Must be set when format is set. + * Needed b/c of the badly chosen 0 + * base for OMAPFB_COLOR_* values + */ + unsigned alloc:1; /* allocated by the driver */ + unsigned map:1; /* kernel mapped by the driver */ +}; + +struct omapfb_mem_desc { + int region_cnt; + struct omapfb_mem_region region[OMAPFB_PLANE_NUM]; +}; + +struct omapfb_platform_data { + struct omap_lcd_config lcd; + struct omapfb_mem_desc mem_desc; + void *ctrl_platform_data; +}; + +/* in arch/arm/plat-omap/fb.c */ +extern void omapfb_set_platform_data(struct omapfb_platform_data *data); +extern void omapfb_set_ctrl_platform_data(void *pdata); +extern void omapfb_reserve_sdram(void); + +#endif + +#endif /* __OMAPFB_H */ diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6b202b173955..49e907bd067f 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -99,7 +99,7 @@ enum pageflags { PG_buddy, /* Page is free, on buddy lists */ PG_swapbacked, /* Page is backed by RAM/swap */ PG_unevictable, /* Page is "unevictable" */ -#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT +#ifdef CONFIG_MMU PG_mlocked, /* Page is vma mlocked */ #endif #ifdef CONFIG_ARCH_USES_PG_UNCACHED @@ -259,12 +259,10 @@ PAGEFLAG_FALSE(SwapCache) PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) TESTCLEARFLAG(Unevictable, unevictable) -#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT -#define MLOCK_PAGES 1 +#ifdef CONFIG_MMU PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked) TESTSCFLAG(Mlocked, mlocked) __TESTCLEARFLAG(Mlocked, mlocked) #else -#define MLOCK_PAGES 0 PAGEFLAG_FALSE(Mlocked) SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked) __TESTCLEARFLAG_FALSE(Mlocked) #endif @@ -393,7 +391,7 @@ static inline void __ClearPageTail(struct page *page) #endif /* !PAGEFLAGS_EXTENDED */ -#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT +#ifdef CONFIG_MMU #define __PG_MLOCKED (1 << PG_mlocked) #else #define __PG_MLOCKED 0 diff --git a/include/linux/pci.h b/include/linux/pci.h index f5c7cd343e56..bf1e67080849 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -218,6 +218,7 @@ struct pci_dev { unsigned int class; /* 3 bytes: (base,sub,prog-if) */ u8 revision; /* PCI revision, low byte of class word */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ + u8 pcie_cap; /* PCI-E capability offset */ u8 pcie_type; /* PCI-E device/port type */ u8 rom_base_reg; /* which config register controls the ROM */ u8 pin; /* which interrupt pin this device uses */ @@ -280,6 +281,7 @@ struct pci_dev { unsigned int is_virtfn:1; unsigned int reset_fn:1; unsigned int is_hotplug_bridge:1; + unsigned int aer_firmware_first:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ @@ -635,7 +637,13 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); -struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn); +struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, + unsigned int devfn); +static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, + unsigned int devfn) +{ + return pci_get_domain_bus_and_slot(0, bus, devfn); +} struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); int pci_dev_present(const struct pci_device_id *ids); @@ -701,6 +709,7 @@ void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); void pci_clear_master(struct pci_dev *dev); int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); +int pci_set_cacheline_size(struct pci_dev *dev); #define HAVE_PCI_SET_MWI int __must_check pci_set_mwi(struct pci_dev *dev); int pci_try_set_mwi(struct pci_dev *dev); @@ -1246,6 +1255,8 @@ extern int pci_pci_problems; extern unsigned long pci_cardbus_io_size; extern unsigned long pci_cardbus_mem_size; +extern u8 __devinitdata pci_dfl_cache_line_size; +extern u8 pci_cache_line_size; extern unsigned long pci_hotplug_io_size; extern unsigned long pci_hotplug_mem_size; @@ -1290,5 +1301,34 @@ extern void pci_hp_create_module_link(struct pci_slot *pci_slot); extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); #endif +/** + * pci_pcie_cap - get the saved PCIe capability offset + * @dev: PCI device + * + * PCIe capability offset is calculated at PCI device initialization + * time and saved in the data structure. This function returns saved + * PCIe capability offset. Using this instead of pci_find_capability() + * reduces unnecessary search in the PCI configuration space. If you + * need to calculate PCIe capability offset from raw device for some + * reasons, please use pci_find_capability() instead. + */ +static inline int pci_pcie_cap(struct pci_dev *dev) +{ + return dev->pcie_cap; +} + +/** + * pci_is_pcie - check if the PCI device is PCI Express capable + * @dev: PCI device + * + * Retrun true if the PCI device is PCI Express capable, false otherwise. + */ +static inline bool pci_is_pcie(struct pci_dev *dev) +{ + return !!pci_pcie_cap(dev); +} + +void pci_request_acs(void); + #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index eae1f864c934..cca8a044e2b6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2295,6 +2295,20 @@ #define PCI_DEVICE_ID_MPC8536 0x0051 #define PCI_DEVICE_ID_P2020E 0x0070 #define PCI_DEVICE_ID_P2020 0x0071 +#define PCI_DEVICE_ID_P2010E 0x0078 +#define PCI_DEVICE_ID_P2010 0x0079 +#define PCI_DEVICE_ID_P1020E 0x0100 +#define PCI_DEVICE_ID_P1020 0x0101 +#define PCI_DEVICE_ID_P1011E 0x0108 +#define PCI_DEVICE_ID_P1011 0x0109 +#define PCI_DEVICE_ID_P1022E 0x0110 +#define PCI_DEVICE_ID_P1022 0x0111 +#define PCI_DEVICE_ID_P1013E 0x0118 +#define PCI_DEVICE_ID_P1013 0x0119 +#define PCI_DEVICE_ID_P4080E 0x0400 +#define PCI_DEVICE_ID_P4080 0x0401 +#define PCI_DEVICE_ID_P4040E 0x0408 +#define PCI_DEVICE_ID_P4040 0x0409 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 #define PCI_DEVICE_ID_MPC8610 0x7018 diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index dd0bed4f1cf0..9f2ad0aa3c39 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -365,6 +365,11 @@ #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ +/* PCI Bridge Subsystem ID registers */ + +#define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */ +#define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */ + /* PCI Express capability registers */ #define PCI_EXP_FLAGS 2 /* Capabilities register */ @@ -502,6 +507,7 @@ #define PCI_EXT_CAP_ID_VC 2 #define PCI_EXT_CAP_ID_DSN 3 #define PCI_EXT_CAP_ID_PWR 4 +#define PCI_EXT_CAP_ID_ACS 13 #define PCI_EXT_CAP_ID_ARI 14 #define PCI_EXT_CAP_ID_ATS 15 #define PCI_EXT_CAP_ID_SRIOV 16 @@ -662,4 +668,16 @@ #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ +/* Access Control Service */ +#define PCI_ACS_CAP 0x04 /* ACS Capability Register */ +#define PCI_ACS_SV 0x01 /* Source Validation */ +#define PCI_ACS_TB 0x02 /* Translation Blocking */ +#define PCI_ACS_RR 0x04 /* P2P Request Redirect */ +#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */ +#define PCI_ACS_UF 0x10 /* Upstream Forwarding */ +#define PCI_ACS_EC 0x20 /* P2P Egress Control */ +#define PCI_ACS_DT 0x40 /* Direct Translated P2P */ +#define PCI_ACS_CTRL 0x06 /* ACS Control Register */ +#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */ + #endif /* LINUX_PCI_REGS_H */ diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index b4c79545330b..6775532b92a9 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -10,10 +10,7 @@ #define _PCIEPORT_IF_H_ /* Port Type */ -#define PCIE_RC_PORT 4 /* Root port of RC */ -#define PCIE_SW_UPSTREAM_PORT 5 /* Upstream port of Switch */ -#define PCIE_SW_DOWNSTREAM_PORT 6 /* Downstream port of Switch */ -#define PCIE_ANY_PORT 7 +#define PCIE_ANY_PORT (~0) /* Service Type */ #define PCIE_PORT_SERVICE_PME_SHIFT 0 /* Power Management Event */ @@ -25,17 +22,6 @@ #define PCIE_PORT_SERVICE_VC_SHIFT 3 /* Virtual Channel */ #define PCIE_PORT_SERVICE_VC (1 << PCIE_PORT_SERVICE_VC_SHIFT) -/* Root/Upstream/Downstream Port's Interrupt Mode */ -#define PCIE_PORT_NO_IRQ (-1) -#define PCIE_PORT_INTx_MODE 0 -#define PCIE_PORT_MSI_MODE 1 -#define PCIE_PORT_MSIX_MODE 2 - -struct pcie_port_data { - int port_type; /* Type of the port */ - int port_irq_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ -}; - struct pcie_device { int irq; /* Service IRQ/MSI/MSI-X Vector */ struct pci_dev *port; /* Root/Upstream/Downstream Port */ diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 9bd03193ecd4..5a5d6ce4bd55 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -60,6 +60,7 @@ #define DEFINE_PER_CPU_SECTION(type, name, sec) \ __PCPU_DUMMY_ATTRS char __pcpu_scope_##name; \ + extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES __weak \ __typeof__(type) per_cpu__##name diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 878836ca999c..cf5efbcf716c 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -34,8 +34,6 @@ #ifdef CONFIG_SMP -#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA - /* minimum unit size, also is the maximum supported allocation size */ #define PCPU_MIN_UNIT_SIZE PFN_ALIGN(64 << 10) @@ -130,30 +128,9 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size, #define per_cpu_ptr(ptr, cpu) SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))) extern void *__alloc_reserved_percpu(size_t size, size_t align); - -#else /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */ - -struct percpu_data { - void *ptrs[1]; -}; - -/* pointer disguising messes up the kmemleak objects tracking */ -#ifndef CONFIG_DEBUG_KMEMLEAK -#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) -#else -#define __percpu_disguise(pdata) (struct percpu_data *)(pdata) -#endif - -#define per_cpu_ptr(ptr, cpu) \ -({ \ - struct percpu_data *__p = __percpu_disguise(ptr); \ - (__typeof__(ptr))__p->ptrs[(cpu)]; \ -}) - -#endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */ - extern void *__alloc_percpu(size_t size, size_t align); extern void free_percpu(void *__pdata); +extern phys_addr_t per_cpu_ptr_to_phys(void *addr); #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA extern void __init setup_per_cpu_areas(void); @@ -179,6 +156,11 @@ static inline void free_percpu(void *p) kfree(p); } +static inline phys_addr_t per_cpu_ptr_to_phys(void *addr) +{ + return __pa(addr); +} + static inline void __init setup_per_cpu_areas(void) { } static inline void *pcpu_lpage_remapped(void *kaddr) @@ -188,8 +170,8 @@ static inline void *pcpu_lpage_remapped(void *kaddr) #endif /* CONFIG_SMP */ -#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ - __alignof__(type)) +#define alloc_percpu(type) \ + (typeof(type) *)__alloc_percpu(sizeof(type), __alignof__(type)) /* * Optional methods for optimized non-lvalue per-cpu variable access. @@ -243,4 +225,404 @@ do { \ # define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=) #endif +/* + * Branching function to split up a function into a set of functions that + * are called for different scalar sizes of the objects handled. + */ + +extern void __bad_size_call_parameter(void); + +#define __pcpu_size_call_return(stem, variable) \ +({ typeof(variable) pscr_ret__; \ + switch(sizeof(variable)) { \ + case 1: pscr_ret__ = stem##1(variable);break; \ + case 2: pscr_ret__ = stem##2(variable);break; \ + case 4: pscr_ret__ = stem##4(variable);break; \ + case 8: pscr_ret__ = stem##8(variable);break; \ + default: \ + __bad_size_call_parameter();break; \ + } \ + pscr_ret__; \ +}) + +#define __pcpu_size_call(stem, variable, ...) \ +do { \ + switch(sizeof(variable)) { \ + case 1: stem##1(variable, __VA_ARGS__);break; \ + case 2: stem##2(variable, __VA_ARGS__);break; \ + case 4: stem##4(variable, __VA_ARGS__);break; \ + case 8: stem##8(variable, __VA_ARGS__);break; \ + default: \ + __bad_size_call_parameter();break; \ + } \ +} while (0) + +/* + * Optimized manipulation for memory allocated through the per cpu + * allocator or for addresses of per cpu variables (can be determined + * using per_cpu_var(xx). + * + * These operation guarantee exclusivity of access for other operations + * on the *same* processor. The assumption is that per cpu data is only + * accessed by a single processor instance (the current one). + * + * The first group is used for accesses that must be done in a + * preemption safe way since we know that the context is not preempt + * safe. Interrupts may occur. If the interrupt modifies the variable + * too then RMW actions will not be reliable. + * + * The arch code can provide optimized functions in two ways: + * + * 1. Override the function completely. F.e. define this_cpu_add(). + * The arch must then ensure that the various scalar format passed + * are handled correctly. + * + * 2. Provide functions for certain scalar sizes. F.e. provide + * this_cpu_add_2() to provide per cpu atomic operations for 2 byte + * sized RMW actions. If arch code does not provide operations for + * a scalar size then the fallback in the generic code will be + * used. + */ + +#define _this_cpu_generic_read(pcp) \ +({ typeof(pcp) ret__; \ + preempt_disable(); \ + ret__ = *this_cpu_ptr(&(pcp)); \ + preempt_enable(); \ + ret__; \ +}) + +#ifndef this_cpu_read +# ifndef this_cpu_read_1 +# define this_cpu_read_1(pcp) _this_cpu_generic_read(pcp) +# endif +# ifndef this_cpu_read_2 +# define this_cpu_read_2(pcp) _this_cpu_generic_read(pcp) +# endif +# ifndef this_cpu_read_4 +# define this_cpu_read_4(pcp) _this_cpu_generic_read(pcp) +# endif +# ifndef this_cpu_read_8 +# define this_cpu_read_8(pcp) _this_cpu_generic_read(pcp) +# endif +# define this_cpu_read(pcp) __pcpu_size_call_return(this_cpu_read_, (pcp)) +#endif + +#define _this_cpu_generic_to_op(pcp, val, op) \ +do { \ + preempt_disable(); \ + *__this_cpu_ptr(&pcp) op val; \ + preempt_enable(); \ +} while (0) + +#ifndef this_cpu_write +# ifndef this_cpu_write_1 +# define this_cpu_write_1(pcp, val) _this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef this_cpu_write_2 +# define this_cpu_write_2(pcp, val) _this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef this_cpu_write_4 +# define this_cpu_write_4(pcp, val) _this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef this_cpu_write_8 +# define this_cpu_write_8(pcp, val) _this_cpu_generic_to_op((pcp), (val), =) +# endif +# define this_cpu_write(pcp, val) __pcpu_size_call(this_cpu_write_, (pcp), (val)) +#endif + +#ifndef this_cpu_add +# ifndef this_cpu_add_1 +# define this_cpu_add_1(pcp, val) _this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef this_cpu_add_2 +# define this_cpu_add_2(pcp, val) _this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef this_cpu_add_4 +# define this_cpu_add_4(pcp, val) _this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef this_cpu_add_8 +# define this_cpu_add_8(pcp, val) _this_cpu_generic_to_op((pcp), (val), +=) +# endif +# define this_cpu_add(pcp, val) __pcpu_size_call(this_cpu_add_, (pcp), (val)) +#endif + +#ifndef this_cpu_sub +# define this_cpu_sub(pcp, val) this_cpu_add((pcp), -(val)) +#endif + +#ifndef this_cpu_inc +# define this_cpu_inc(pcp) this_cpu_add((pcp), 1) +#endif + +#ifndef this_cpu_dec +# define this_cpu_dec(pcp) this_cpu_sub((pcp), 1) +#endif + +#ifndef this_cpu_and +# ifndef this_cpu_and_1 +# define this_cpu_and_1(pcp, val) _this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef this_cpu_and_2 +# define this_cpu_and_2(pcp, val) _this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef this_cpu_and_4 +# define this_cpu_and_4(pcp, val) _this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef this_cpu_and_8 +# define this_cpu_and_8(pcp, val) _this_cpu_generic_to_op((pcp), (val), &=) +# endif +# define this_cpu_and(pcp, val) __pcpu_size_call(this_cpu_and_, (pcp), (val)) +#endif + +#ifndef this_cpu_or +# ifndef this_cpu_or_1 +# define this_cpu_or_1(pcp, val) _this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef this_cpu_or_2 +# define this_cpu_or_2(pcp, val) _this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef this_cpu_or_4 +# define this_cpu_or_4(pcp, val) _this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef this_cpu_or_8 +# define this_cpu_or_8(pcp, val) _this_cpu_generic_to_op((pcp), (val), |=) +# endif +# define this_cpu_or(pcp, val) __pcpu_size_call(this_cpu_or_, (pcp), (val)) +#endif + +#ifndef this_cpu_xor +# ifndef this_cpu_xor_1 +# define this_cpu_xor_1(pcp, val) _this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef this_cpu_xor_2 +# define this_cpu_xor_2(pcp, val) _this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef this_cpu_xor_4 +# define this_cpu_xor_4(pcp, val) _this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef this_cpu_xor_8 +# define this_cpu_xor_8(pcp, val) _this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# define this_cpu_xor(pcp, val) __pcpu_size_call(this_cpu_or_, (pcp), (val)) +#endif + +/* + * Generic percpu operations that do not require preemption handling. + * Either we do not care about races or the caller has the + * responsibility of handling preemptions issues. Arch code can still + * override these instructions since the arch per cpu code may be more + * efficient and may actually get race freeness for free (that is the + * case for x86 for example). + * + * If there is no other protection through preempt disable and/or + * disabling interupts then one of these RMW operations can show unexpected + * behavior because the execution thread was rescheduled on another processor + * or an interrupt occurred and the same percpu variable was modified from + * the interrupt context. + */ +#ifndef __this_cpu_read +# ifndef __this_cpu_read_1 +# define __this_cpu_read_1(pcp) (*__this_cpu_ptr(&(pcp))) +# endif +# ifndef __this_cpu_read_2 +# define __this_cpu_read_2(pcp) (*__this_cpu_ptr(&(pcp))) +# endif +# ifndef __this_cpu_read_4 +# define __this_cpu_read_4(pcp) (*__this_cpu_ptr(&(pcp))) +# endif +# ifndef __this_cpu_read_8 +# define __this_cpu_read_8(pcp) (*__this_cpu_ptr(&(pcp))) +# endif +# define __this_cpu_read(pcp) __pcpu_size_call_return(__this_cpu_read_, (pcp)) +#endif + +#define __this_cpu_generic_to_op(pcp, val, op) \ +do { \ + *__this_cpu_ptr(&(pcp)) op val; \ +} while (0) + +#ifndef __this_cpu_write +# ifndef __this_cpu_write_1 +# define __this_cpu_write_1(pcp, val) __this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef __this_cpu_write_2 +# define __this_cpu_write_2(pcp, val) __this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef __this_cpu_write_4 +# define __this_cpu_write_4(pcp, val) __this_cpu_generic_to_op((pcp), (val), =) +# endif +# ifndef __this_cpu_write_8 +# define __this_cpu_write_8(pcp, val) __this_cpu_generic_to_op((pcp), (val), =) +# endif +# define __this_cpu_write(pcp, val) __pcpu_size_call(__this_cpu_write_, (pcp), (val)) +#endif + +#ifndef __this_cpu_add +# ifndef __this_cpu_add_1 +# define __this_cpu_add_1(pcp, val) __this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef __this_cpu_add_2 +# define __this_cpu_add_2(pcp, val) __this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef __this_cpu_add_4 +# define __this_cpu_add_4(pcp, val) __this_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef __this_cpu_add_8 +# define __this_cpu_add_8(pcp, val) __this_cpu_generic_to_op((pcp), (val), +=) +# endif +# define __this_cpu_add(pcp, val) __pcpu_size_call(__this_cpu_add_, (pcp), (val)) +#endif + +#ifndef __this_cpu_sub +# define __this_cpu_sub(pcp, val) __this_cpu_add((pcp), -(val)) +#endif + +#ifndef __this_cpu_inc +# define __this_cpu_inc(pcp) __this_cpu_add((pcp), 1) +#endif + +#ifndef __this_cpu_dec +# define __this_cpu_dec(pcp) __this_cpu_sub((pcp), 1) +#endif + +#ifndef __this_cpu_and +# ifndef __this_cpu_and_1 +# define __this_cpu_and_1(pcp, val) __this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef __this_cpu_and_2 +# define __this_cpu_and_2(pcp, val) __this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef __this_cpu_and_4 +# define __this_cpu_and_4(pcp, val) __this_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef __this_cpu_and_8 +# define __this_cpu_and_8(pcp, val) __this_cpu_generic_to_op((pcp), (val), &=) +# endif +# define __this_cpu_and(pcp, val) __pcpu_size_call(__this_cpu_and_, (pcp), (val)) +#endif + +#ifndef __this_cpu_or +# ifndef __this_cpu_or_1 +# define __this_cpu_or_1(pcp, val) __this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef __this_cpu_or_2 +# define __this_cpu_or_2(pcp, val) __this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef __this_cpu_or_4 +# define __this_cpu_or_4(pcp, val) __this_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef __this_cpu_or_8 +# define __this_cpu_or_8(pcp, val) __this_cpu_generic_to_op((pcp), (val), |=) +# endif +# define __this_cpu_or(pcp, val) __pcpu_size_call(__this_cpu_or_, (pcp), (val)) +#endif + +#ifndef __this_cpu_xor +# ifndef __this_cpu_xor_1 +# define __this_cpu_xor_1(pcp, val) __this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef __this_cpu_xor_2 +# define __this_cpu_xor_2(pcp, val) __this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef __this_cpu_xor_4 +# define __this_cpu_xor_4(pcp, val) __this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef __this_cpu_xor_8 +# define __this_cpu_xor_8(pcp, val) __this_cpu_generic_to_op((pcp), (val), ^=) +# endif +# define __this_cpu_xor(pcp, val) __pcpu_size_call(__this_cpu_xor_, (pcp), (val)) +#endif + +/* + * IRQ safe versions of the per cpu RMW operations. Note that these operations + * are *not* safe against modification of the same variable from another + * processors (which one gets when using regular atomic operations) + . They are guaranteed to be atomic vs. local interrupts and + * preemption only. + */ +#define irqsafe_cpu_generic_to_op(pcp, val, op) \ +do { \ + unsigned long flags; \ + local_irq_save(flags); \ + *__this_cpu_ptr(&(pcp)) op val; \ + local_irq_restore(flags); \ +} while (0) + +#ifndef irqsafe_cpu_add +# ifndef irqsafe_cpu_add_1 +# define irqsafe_cpu_add_1(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef irqsafe_cpu_add_2 +# define irqsafe_cpu_add_2(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef irqsafe_cpu_add_4 +# define irqsafe_cpu_add_4(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), +=) +# endif +# ifndef irqsafe_cpu_add_8 +# define irqsafe_cpu_add_8(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), +=) +# endif +# define irqsafe_cpu_add(pcp, val) __pcpu_size_call(irqsafe_cpu_add_, (pcp), (val)) +#endif + +#ifndef irqsafe_cpu_sub +# define irqsafe_cpu_sub(pcp, val) irqsafe_cpu_add((pcp), -(val)) +#endif + +#ifndef irqsafe_cpu_inc +# define irqsafe_cpu_inc(pcp) irqsafe_cpu_add((pcp), 1) +#endif + +#ifndef irqsafe_cpu_dec +# define irqsafe_cpu_dec(pcp) irqsafe_cpu_sub((pcp), 1) +#endif + +#ifndef irqsafe_cpu_and +# ifndef irqsafe_cpu_and_1 +# define irqsafe_cpu_and_1(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef irqsafe_cpu_and_2 +# define irqsafe_cpu_and_2(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef irqsafe_cpu_and_4 +# define irqsafe_cpu_and_4(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), &=) +# endif +# ifndef irqsafe_cpu_and_8 +# define irqsafe_cpu_and_8(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), &=) +# endif +# define irqsafe_cpu_and(pcp, val) __pcpu_size_call(irqsafe_cpu_and_, (val)) +#endif + +#ifndef irqsafe_cpu_or +# ifndef irqsafe_cpu_or_1 +# define irqsafe_cpu_or_1(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef irqsafe_cpu_or_2 +# define irqsafe_cpu_or_2(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef irqsafe_cpu_or_4 +# define irqsafe_cpu_or_4(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), |=) +# endif +# ifndef irqsafe_cpu_or_8 +# define irqsafe_cpu_or_8(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), |=) +# endif +# define irqsafe_cpu_or(pcp, val) __pcpu_size_call(irqsafe_cpu_or_, (val)) +#endif + +#ifndef irqsafe_cpu_xor +# ifndef irqsafe_cpu_xor_1 +# define irqsafe_cpu_xor_1(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef irqsafe_cpu_xor_2 +# define irqsafe_cpu_xor_2(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef irqsafe_cpu_xor_4 +# define irqsafe_cpu_xor_4(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), ^=) +# endif +# ifndef irqsafe_cpu_xor_8 +# define irqsafe_cpu_xor_8(pcp, val) irqsafe_cpu_generic_to_op((pcp), (val), ^=) +# endif +# define irqsafe_cpu_xor(pcp, val) __pcpu_size_call(irqsafe_cpu_xor_, (val)) +#endif + #endif /* __LINUX_PERCPU_H */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 43adbd7f0010..da7bdc23f279 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -18,10 +18,6 @@ #include <linux/ioctl.h> #include <asm/byteorder.h> -#ifdef CONFIG_HAVE_HW_BREAKPOINT -#include <asm/hw_breakpoint.h> -#endif - /* * User-space ABI bits: */ @@ -215,12 +211,12 @@ struct perf_event_attr { __u32 wakeup_watermark; /* bytes before wakeup */ }; - union { - struct { /* Hardware breakpoint info */ - __u64 bp_addr; - __u32 bp_type; - __u32 bp_len; - }; + struct { /* Hardware breakpoint info */ + __u64 bp_addr; + __u32 bp_type; + __u32 bp_len; + __u64 __bp_reserved_1; + __u64 __bp_reserved_2; }; __u32 __reserved_2; @@ -451,6 +447,10 @@ enum perf_callchain_context { # include <asm/perf_event.h> #endif +#ifdef CONFIG_HAVE_HW_BREAKPOINT +#include <asm/hw_breakpoint.h> +#endif + #include <linux/list.h> #include <linux/mutex.h> #include <linux/rculist.h> @@ -565,10 +565,12 @@ struct perf_pending_entry { void (*func)(struct perf_pending_entry *); }; -typedef void (*perf_callback_t)(struct perf_event *, void *); - struct perf_sample_data; +typedef void (*perf_overflow_handler_t)(struct perf_event *, int, + struct perf_sample_data *, + struct pt_regs *regs); + /** * struct perf_event - performance event kernel representation: */ @@ -660,18 +662,12 @@ struct perf_event { struct pid_namespace *ns; u64 id; - void (*overflow_handler)(struct perf_event *event, - int nmi, struct perf_sample_data *data, - struct pt_regs *regs); + perf_overflow_handler_t overflow_handler; #ifdef CONFIG_EVENT_PROFILE struct event_filter *filter; #endif - perf_callback_t callback; - - perf_callback_t event_callback; - #endif /* CONFIG_PERF_EVENTS */ }; @@ -685,7 +681,7 @@ struct perf_event_context { * Protect the states of the events in the list, * nr_active, and the list: */ - spinlock_t lock; + raw_spinlock_t lock; /* * Protect the list of events. Locking either mutex or lock * is sufficient to ensure the list doesn't change; to change @@ -781,7 +777,7 @@ extern struct perf_event * perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, pid_t pid, - perf_callback_t callback); + perf_overflow_handler_t callback); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); @@ -876,6 +872,8 @@ extern void perf_output_copy(struct perf_output_handle *handle, const void *buf, unsigned int len); extern int perf_swevent_get_recursion_context(void); extern void perf_swevent_put_recursion_context(int rctx); +extern void perf_event_enable(struct perf_event *event); +extern void perf_event_disable(struct perf_event *event); #else static inline void perf_event_task_sched_in(struct task_struct *task, int cpu) { } @@ -906,7 +904,8 @@ static inline void perf_event_fork(struct task_struct *tsk) { } static inline void perf_event_init(void) { } static inline int perf_swevent_get_recursion_context(void) { return -1; } static inline void perf_swevent_put_recursion_context(int rctx) { } - +static inline void perf_event_enable(struct perf_event *event) { } +static inline void perf_event_disable(struct perf_event *event) { } #endif #define perf_output_put(handle, x) \ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 3c6675c2444b..71ff887ca44e 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -83,6 +83,8 @@ struct early_platform_driver { struct platform_driver *pdrv; struct list_head list; int requested_id; + char *buffer; + int bufsize; }; #define EARLY_PLATFORM_ID_UNSET -2 @@ -102,21 +104,29 @@ extern int early_platform_driver_probe(char *class_str, int nr_probe, int user_only); extern void early_platform_cleanup(void); +#define early_platform_init(class_string, platdrv) \ + early_platform_init_buffer(class_string, platdrv, NULL, 0) #ifndef MODULE -#define early_platform_init(class_string, platform_driver) \ +#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ static __initdata struct early_platform_driver early_driver = { \ .class_str = class_string, \ - .pdrv = platform_driver, \ + .buffer = buf, \ + .bufsize = bufsiz, \ + .pdrv = platdrv, \ .requested_id = EARLY_PLATFORM_ID_UNSET, \ }; \ -static int __init early_platform_driver_setup_func(char *buf) \ +static int __init early_platform_driver_setup_func(char *buffer) \ { \ - return early_platform_driver_register(&early_driver, buf); \ + return early_platform_driver_register(&early_driver, buffer); \ } \ early_param(class_string, early_platform_driver_setup_func) #else /* MODULE */ -#define early_platform_init(class_string, platform_driver) +#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ +static inline char *early_platform_driver_setup_func(void) \ +{ \ + return bufsiz ? buf : NULL; \ +} #endif /* MODULE */ #endif /* _PLATFORM_DEVICE_H_ */ diff --git a/include/linux/plist.h b/include/linux/plist.h index 45926d77d6ac..8227f717c70f 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h @@ -81,7 +81,8 @@ struct plist_head { struct list_head prio_list; struct list_head node_list; #ifdef CONFIG_DEBUG_PI_LIST - spinlock_t *lock; + raw_spinlock_t *rawlock; + spinlock_t *spinlock; #endif }; @@ -91,9 +92,11 @@ struct plist_node { }; #ifdef CONFIG_DEBUG_PI_LIST -# define PLIST_HEAD_LOCK_INIT(_lock) .lock = _lock +# define PLIST_HEAD_LOCK_INIT(_lock) .spinlock = _lock +# define PLIST_HEAD_LOCK_INIT_RAW(_lock) .rawlock = _lock #else # define PLIST_HEAD_LOCK_INIT(_lock) +# define PLIST_HEAD_LOCK_INIT_RAW(_lock) #endif #define _PLIST_HEAD_INIT(head) \ @@ -107,11 +110,22 @@ struct plist_node { */ #define PLIST_HEAD_INIT(head, _lock) \ { \ - _PLIST_HEAD_INIT(head), \ + _PLIST_HEAD_INIT(head), \ PLIST_HEAD_LOCK_INIT(&(_lock)) \ } /** + * PLIST_HEAD_INIT_RAW - static struct plist_head initializer + * @head: struct plist_head variable name + * @_lock: lock to initialize for this list + */ +#define PLIST_HEAD_INIT_RAW(head, _lock) \ +{ \ + _PLIST_HEAD_INIT(head), \ + PLIST_HEAD_LOCK_INIT_RAW(&(_lock)) \ +} + +/** * PLIST_NODE_INIT - static struct plist_node initializer * @node: struct plist_node variable name * @__prio: initial node priority @@ -119,13 +133,13 @@ struct plist_node { #define PLIST_NODE_INIT(node, __prio) \ { \ .prio = (__prio), \ - .plist = { _PLIST_HEAD_INIT((node).plist) }, \ + .plist = { _PLIST_HEAD_INIT((node).plist) }, \ } /** * plist_head_init - dynamic struct plist_head initializer * @head: &struct plist_head pointer - * @lock: list spinlock, remembered for debugging + * @lock: spinlock protecting the list (debugging) */ static inline void plist_head_init(struct plist_head *head, spinlock_t *lock) @@ -133,7 +147,24 @@ plist_head_init(struct plist_head *head, spinlock_t *lock) INIT_LIST_HEAD(&head->prio_list); INIT_LIST_HEAD(&head->node_list); #ifdef CONFIG_DEBUG_PI_LIST - head->lock = lock; + head->spinlock = lock; + head->rawlock = NULL; +#endif +} + +/** + * plist_head_init_raw - dynamic struct plist_head initializer + * @head: &struct plist_head pointer + * @lock: raw_spinlock protecting the list (debugging) + */ +static inline void +plist_head_init_raw(struct plist_head *head, raw_spinlock_t *lock) +{ + INIT_LIST_HEAD(&head->prio_list); + INIT_LIST_HEAD(&head->node_list); +#ifdef CONFIG_DEBUG_PI_LIST + head->rawlock = lock; + head->spinlock = NULL; #endif } diff --git a/include/linux/pm.h b/include/linux/pm.h index 0d65934246af..198b8f9fe05e 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -219,7 +219,7 @@ struct dev_pm_ops { * to RAM and hibernation. */ #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ -struct dev_pm_ops name = { \ +const struct dev_pm_ops name = { \ .suspend = suspend_fn, \ .resume = resume_fn, \ .freeze = suspend_fn, \ diff --git a/include/linux/quota.h b/include/linux/quota.h index ce9a9b2e5cd4..e70e62194243 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -73,6 +73,8 @@ /* Quota format type IDs */ #define QFMT_VFS_OLD 1 #define QFMT_VFS_V0 2 +#define QFMT_OCFS2 3 +#define QFMT_VFS_V1 4 /* Size of block in which space limits are passed through the quota * interface */ @@ -334,7 +336,7 @@ struct quotactl_ops { struct quota_format_type { int qf_fmt_id; /* Quota format id */ - struct quota_format_ops *qf_ops; /* Operations of format */ + const struct quota_format_ops *qf_ops; /* Operations of format */ struct module *qf_owner; /* Module implementing quota format */ struct quota_format_type *qf_next; }; @@ -394,7 +396,7 @@ struct quota_info { struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ - struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ + const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ }; int register_quota_format(struct quota_format_type *fmt); diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h index d92480f8285c..1cbbd2c11aa9 100644 --- a/include/linux/raid/pq.h +++ b/include/linux/raid/pq.h @@ -78,6 +78,25 @@ struct raid6_calls { /* Selected algorithm */ extern struct raid6_calls raid6_call; +/* Various routine sets */ +extern const struct raid6_calls raid6_intx1; +extern const struct raid6_calls raid6_intx2; +extern const struct raid6_calls raid6_intx4; +extern const struct raid6_calls raid6_intx8; +extern const struct raid6_calls raid6_intx16; +extern const struct raid6_calls raid6_intx32; +extern const struct raid6_calls raid6_mmxx1; +extern const struct raid6_calls raid6_mmxx2; +extern const struct raid6_calls raid6_sse1x1; +extern const struct raid6_calls raid6_sse1x2; +extern const struct raid6_calls raid6_sse2x1; +extern const struct raid6_calls raid6_sse2x2; +extern const struct raid6_calls raid6_sse2x4; +extern const struct raid6_calls raid6_altivec1; +extern const struct raid6_calls raid6_altivec2; +extern const struct raid6_calls raid6_altivec4; +extern const struct raid6_calls raid6_altivec8; + /* Algorithm list */ extern const struct raid6_calls * const raid6_algos[]; int raid6_select_algo(void); diff --git a/include/linux/rmap.h b/include/linux/rmap.h index cb0ba7032609..b019ae64e2ab 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -26,6 +26,9 @@ */ struct anon_vma { spinlock_t lock; /* Serialize access to vma list */ +#ifdef CONFIG_KSM + atomic_t ksm_refcount; +#endif /* * NOTE: the LSB of the head.next is set by * mm_take_all_locks() _after_ taking the above lock. So the @@ -38,6 +41,34 @@ struct anon_vma { }; #ifdef CONFIG_MMU +#ifdef CONFIG_KSM +static inline void ksm_refcount_init(struct anon_vma *anon_vma) +{ + atomic_set(&anon_vma->ksm_refcount, 0); +} + +static inline int ksm_refcount(struct anon_vma *anon_vma) +{ + return atomic_read(&anon_vma->ksm_refcount); +} +#else +static inline void ksm_refcount_init(struct anon_vma *anon_vma) +{ +} + +static inline int ksm_refcount(struct anon_vma *anon_vma) +{ + return 0; +} +#endif /* CONFIG_KSM */ + +static inline struct anon_vma *page_anon_vma(struct page *page) +{ + if (((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != + PAGE_MAPPING_ANON) + return NULL; + return page_rmapping(page); +} static inline void anon_vma_lock(struct vm_area_struct *vma) { @@ -62,6 +93,7 @@ void __anon_vma_merge(struct vm_area_struct *, struct vm_area_struct *); void anon_vma_unlink(struct vm_area_struct *); void anon_vma_link(struct vm_area_struct *); void __anon_vma_link(struct vm_area_struct *); +void anon_vma_free(struct anon_vma *); /* * rmap interfaces called when adding or removing pte of page @@ -81,6 +113,9 @@ static inline void page_dup_rmap(struct page *page) */ int page_referenced(struct page *, int is_locked, struct mem_cgroup *cnt, unsigned long *vm_flags); +int page_referenced_one(struct page *, struct vm_area_struct *, + unsigned long address, unsigned int *mapcount, unsigned long *vm_flags); + enum ttu_flags { TTU_UNMAP = 0, /* unmap mode */ TTU_MIGRATION = 1, /* migration mode */ @@ -94,6 +129,8 @@ enum ttu_flags { #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK) int try_to_unmap(struct page *, enum ttu_flags flags); +int try_to_unmap_one(struct page *, struct vm_area_struct *, + unsigned long address, enum ttu_flags flags); /* * Called from mm/filemap_xip.c to unmap empty zero page @@ -127,6 +164,12 @@ struct anon_vma *page_lock_anon_vma(struct page *page); void page_unlock_anon_vma(struct anon_vma *anon_vma); int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); +/* + * Called by migrate.c to remove migration ptes, but might be used more later. + */ +int rmap_walk(struct page *page, int (*rmap_one)(struct page *, + struct vm_area_struct *, unsigned long, void *), void *arg); + #else /* !CONFIG_MMU */ #define anon_vma_init() do {} while (0) diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index f19b00b7d530..281d8fd775e8 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -24,7 +24,7 @@ * @owner: the mutex owner */ struct rt_mutex { - spinlock_t wait_lock; + raw_spinlock_t wait_lock; struct plist_head wait_list; struct task_struct *owner; #ifdef CONFIG_DEBUG_RT_MUTEXES @@ -63,8 +63,8 @@ struct hrtimer_sleeper; #endif #define __RT_MUTEX_INITIALIZER(mutexname) \ - { .wait_lock = __SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list, mutexname.wait_lock) \ + { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ + , .wait_list = PLIST_HEAD_INIT_RAW(mutexname.wait_list, mutexname.wait_lock) \ , .owner = NULL \ __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h new file mode 100644 index 000000000000..71e0b00b6f2c --- /dev/null +++ b/include/linux/rwlock.h @@ -0,0 +1,125 @@ +#ifndef __LINUX_RWLOCK_H +#define __LINUX_RWLOCK_H + +#ifndef __LINUX_SPINLOCK_H +# error "please don't include this file directly" +#endif + +/* + * rwlock related methods + * + * split out from spinlock.h + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void __rwlock_init(rwlock_t *lock, const char *name, + struct lock_class_key *key); +# define rwlock_init(lock) \ +do { \ + static struct lock_class_key __key; \ + \ + __rwlock_init((lock), #lock, &__key); \ +} while (0) +#else +# define rwlock_init(lock) \ + do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0) +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void do_raw_read_lock(rwlock_t *lock); +#define do_raw_read_lock_flags(lock, flags) do_raw_read_lock(lock) + extern int do_raw_read_trylock(rwlock_t *lock); + extern void do_raw_read_unlock(rwlock_t *lock); + extern void do_raw_write_lock(rwlock_t *lock); +#define do_raw_write_lock_flags(lock, flags) do_raw_write_lock(lock) + extern int do_raw_write_trylock(rwlock_t *lock); + extern void do_raw_write_unlock(rwlock_t *lock); +#else +# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) +# define do_raw_read_lock_flags(lock, flags) \ + arch_read_lock_flags(&(lock)->raw_lock, *(flags)) +# define do_raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) +# define do_raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock) +# define do_raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock) +# define do_raw_write_lock_flags(lock, flags) \ + arch_write_lock_flags(&(lock)->raw_lock, *(flags)) +# define do_raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock) +# define do_raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock) +#endif + +#define read_can_lock(rwlock) arch_read_can_lock(&(rwlock)->raw_lock) +#define write_can_lock(rwlock) arch_write_can_lock(&(rwlock)->raw_lock) + +/* + * Define the various rw_lock methods. Note we define these + * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various + * methods are defined as nops in the case they are not required. + */ +#define read_trylock(lock) __cond_lock(lock, _raw_read_trylock(lock)) +#define write_trylock(lock) __cond_lock(lock, _raw_write_trylock(lock)) + +#define write_lock(lock) _raw_write_lock(lock) +#define read_lock(lock) _raw_read_lock(lock) + +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _raw_read_lock_irqsave(lock); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _raw_write_lock_irqsave(lock); \ + } while (0) + +#else + +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_read_lock_irqsave(lock, flags); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_write_lock_irqsave(lock, flags); \ + } while (0) + +#endif + +#define read_lock_irq(lock) _raw_read_lock_irq(lock) +#define read_lock_bh(lock) _raw_read_lock_bh(lock) +#define write_lock_irq(lock) _raw_write_lock_irq(lock) +#define write_lock_bh(lock) _raw_write_lock_bh(lock) +#define read_unlock(lock) _raw_read_unlock(lock) +#define write_unlock(lock) _raw_write_unlock(lock) +#define read_unlock_irq(lock) _raw_read_unlock_irq(lock) +#define write_unlock_irq(lock) _raw_write_unlock_irq(lock) + +#define read_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_read_unlock_irqrestore(lock, flags); \ + } while (0) +#define read_unlock_bh(lock) _raw_read_unlock_bh(lock) + +#define write_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_write_unlock_irqrestore(lock, flags); \ + } while (0) +#define write_unlock_bh(lock) _raw_write_unlock_bh(lock) + +#define write_trylock_irqsave(lock, flags) \ +({ \ + local_irq_save(flags); \ + write_trylock(lock) ? \ + 1 : ({ local_irq_restore(flags); 0; }); \ +}) + +#endif /* __LINUX_RWLOCK_H */ diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h new file mode 100644 index 000000000000..9c9f0495d37c --- /dev/null +++ b/include/linux/rwlock_api_smp.h @@ -0,0 +1,282 @@ +#ifndef __LINUX_RWLOCK_API_SMP_H +#define __LINUX_RWLOCK_API_SMP_H + +#ifndef __LINUX_SPINLOCK_API_SMP_H +# error "please don't include this file directly" +#endif + +/* + * include/linux/rwlock_api_smp.h + * + * spinlock API declarations on SMP (and debug) + * (implemented in kernel/spinlock.c) + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ + +void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock); +void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock); +unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock) + __acquires(lock); +unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock) + __acquires(lock); +int __lockfunc _raw_read_trylock(rwlock_t *lock); +int __lockfunc _raw_write_trylock(rwlock_t *lock); +void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock); +void __lockfunc +_raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(lock); +void __lockfunc +_raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) + __releases(lock); + +#ifdef CONFIG_INLINE_READ_LOCK +#define _raw_read_lock(lock) __raw_read_lock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK +#define _raw_write_lock(lock) __raw_write_lock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_BH +#define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_BH +#define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_IRQ +#define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ +#define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE +#define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE +#define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock) +#endif + +#ifdef CONFIG_INLINE_READ_TRYLOCK +#define _raw_read_trylock(lock) __raw_read_trylock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_TRYLOCK +#define _raw_write_trylock(lock) __raw_write_trylock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK +#define _raw_read_unlock(lock) __raw_read_unlock(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK +#define _raw_write_unlock(lock) __raw_write_unlock(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_BH +#define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH +#define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ +#define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ +#define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock) +#endif + +#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE +#define _raw_read_unlock_irqrestore(lock, flags) \ + __raw_read_unlock_irqrestore(lock, flags) +#endif + +#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE +#define _raw_write_unlock_irqrestore(lock, flags) \ + __raw_write_unlock_irqrestore(lock, flags) +#endif + +static inline int __raw_read_trylock(rwlock_t *lock) +{ + preempt_disable(); + if (do_raw_read_trylock(lock)) { + rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); + return 1; + } + preempt_enable(); + return 0; +} + +static inline int __raw_write_trylock(rwlock_t *lock) +{ + preempt_disable(); + if (do_raw_write_trylock(lock)) { + rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); + return 1; + } + preempt_enable(); + return 0; +} + +/* + * If lockdep is enabled then we use the non-preemption spin-ops + * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are + * not re-enabled during lock-acquire (which the preempt-spin-ops do): + */ +#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) + +static inline void __raw_read_lock(rwlock_t *lock) +{ + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); +} + +static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock) +{ + unsigned long flags; + + local_irq_save(flags); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock, + do_raw_read_lock_flags, &flags); + return flags; +} + +static inline void __raw_read_lock_irq(rwlock_t *lock) +{ + local_irq_disable(); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); +} + +static inline void __raw_read_lock_bh(rwlock_t *lock) +{ + local_bh_disable(); + preempt_disable(); + rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); +} + +static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock) +{ + unsigned long flags; + + local_irq_save(flags); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock, + do_raw_write_lock_flags, &flags); + return flags; +} + +static inline void __raw_write_lock_irq(rwlock_t *lock) +{ + local_irq_disable(); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); +} + +static inline void __raw_write_lock_bh(rwlock_t *lock) +{ + local_bh_disable(); + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); +} + +static inline void __raw_write_lock(rwlock_t *lock) +{ + preempt_disable(); + rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); + LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); +} + +#endif /* CONFIG_PREEMPT */ + +static inline void __raw_write_unlock(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_write_unlock(lock); + preempt_enable(); +} + +static inline void __raw_read_unlock(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_read_unlock(lock); + preempt_enable(); +} + +static inline void +__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_read_unlock(lock); + local_irq_restore(flags); + preempt_enable(); +} + +static inline void __raw_read_unlock_irq(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_read_unlock(lock); + local_irq_enable(); + preempt_enable(); +} + +static inline void __raw_read_unlock_bh(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_read_unlock(lock); + preempt_enable_no_resched(); + local_bh_enable_ip((unsigned long)__builtin_return_address(0)); +} + +static inline void __raw_write_unlock_irqrestore(rwlock_t *lock, + unsigned long flags) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_write_unlock(lock); + local_irq_restore(flags); + preempt_enable(); +} + +static inline void __raw_write_unlock_irq(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_write_unlock(lock); + local_irq_enable(); + preempt_enable(); +} + +static inline void __raw_write_unlock_bh(rwlock_t *lock) +{ + rwlock_release(&lock->dep_map, 1, _RET_IP_); + do_raw_write_unlock(lock); + preempt_enable_no_resched(); + local_bh_enable_ip((unsigned long)__builtin_return_address(0)); +} + +#endif /* __LINUX_RWLOCK_API_SMP_H */ diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h new file mode 100644 index 000000000000..bd31808c7d8e --- /dev/null +++ b/include/linux/rwlock_types.h @@ -0,0 +1,56 @@ +#ifndef __LINUX_RWLOCK_TYPES_H +#define __LINUX_RWLOCK_TYPES_H + +/* + * include/linux/rwlock_types.h - generic rwlock type definitions + * and initializers + * + * portions Copyright 2005, Red Hat, Inc., Ingo Molnar + * Released under the General Public License (GPL). + */ +typedef struct { + arch_rwlock_t raw_lock; +#ifdef CONFIG_GENERIC_LOCKBREAK + unsigned int break_lock; +#endif +#ifdef CONFIG_DEBUG_SPINLOCK + unsigned int magic, owner_cpu; + void *owner; +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif +} rwlock_t; + +#define RWLOCK_MAGIC 0xdeaf1eed + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } +#else +# define RW_DEP_MAP_INIT(lockname) +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK +#define __RW_LOCK_UNLOCKED(lockname) \ + (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \ + .magic = RWLOCK_MAGIC, \ + .owner = SPINLOCK_OWNER_INIT, \ + .owner_cpu = -1, \ + RW_DEP_MAP_INIT(lockname) } +#else +#define __RW_LOCK_UNLOCKED(lockname) \ + (rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \ + RW_DEP_MAP_INIT(lockname) } +#endif + +/* + * RW_LOCK_UNLOCKED defeat lockdep state tracking and is hence + * deprecated. + * + * Please use DEFINE_RWLOCK() or __RW_LOCK_UNLOCKED() as appropriate. + */ +#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init) + +#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x) + +#endif /* __LINUX_RWLOCK_TYPES_H */ diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h index 6c3c0f6c261f..bdfcc2527970 100644 --- a/include/linux/rwsem-spinlock.h +++ b/include/linux/rwsem-spinlock.h @@ -68,11 +68,7 @@ extern int __down_write_trylock(struct rw_semaphore *sem); extern void __up_read(struct rw_semaphore *sem); extern void __up_write(struct rw_semaphore *sem); extern void __downgrade_write(struct rw_semaphore *sem); - -static inline int rwsem_is_locked(struct rw_semaphore *sem) -{ - return (sem->activity != 0); -} +extern int rwsem_is_locked(struct rw_semaphore *sem); #endif /* __KERNEL__ */ #endif /* _LINUX_RWSEM_SPINLOCK_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 89115ec7d43f..5c858f38e81a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1102,7 +1102,7 @@ struct sched_class { void (*set_curr_task) (struct rq *rq); void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); - void (*task_new) (struct rq *rq, struct task_struct *p); + void (*task_fork) (struct task_struct *p); void (*switched_from) (struct rq *this_rq, struct task_struct *task, int running); @@ -1111,7 +1111,8 @@ struct sched_class { void (*prio_changed) (struct rq *this_rq, struct task_struct *task, int oldprio, int running); - unsigned int (*get_rr_interval) (struct task_struct *task); + unsigned int (*get_rr_interval) (struct rq *rq, + struct task_struct *task); #ifdef CONFIG_FAIR_GROUP_SCHED void (*moved_group) (struct task_struct *p); @@ -1151,8 +1152,6 @@ struct sched_entity { u64 start_runtime; u64 avg_wakeup; - u64 avg_running; - #ifdef CONFIG_SCHEDSTATS u64 wait_start; u64 wait_max; @@ -1175,7 +1174,6 @@ struct sched_entity { u64 nr_failed_migrations_running; u64 nr_failed_migrations_hot; u64 nr_forced_migrations; - u64 nr_forced2_migrations; u64 nr_wakeups; u64 nr_wakeups_sync; @@ -1411,7 +1409,7 @@ struct task_struct { #endif /* Protection of the PI data structures: */ - spinlock_t pi_lock; + raw_spinlock_t pi_lock; #ifdef CONFIG_RT_MUTEXES /* PI waiters blocked on a rt_mutex held by this task */ @@ -1448,8 +1446,10 @@ struct task_struct { gfp_t lockdep_reclaim_gfp; #endif +#ifdef CONFIG_FS_JOURNAL_INFO /* journalling filesystem info */ void *journal_info; +#endif /* stacked block device info */ struct bio *bio_list, **bio_tail; @@ -1840,7 +1840,8 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) extern int sched_clock_stable; #endif -extern unsigned long long sched_clock(void); +/* ftrace calls sched_clock() directly */ +extern unsigned long long notrace sched_clock(void); extern void sched_clock_init(void); extern u64 sched_clock_cpu(int cpu); @@ -1903,14 +1904,22 @@ extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_shares_ratelimit; extern unsigned int sysctl_sched_shares_thresh; extern unsigned int sysctl_sched_child_runs_first; + +enum sched_tunable_scaling { + SCHED_TUNABLESCALING_NONE, + SCHED_TUNABLESCALING_LOG, + SCHED_TUNABLESCALING_LINEAR, + SCHED_TUNABLESCALING_END, +}; +extern enum sched_tunable_scaling sysctl_sched_tunable_scaling; + #ifdef CONFIG_SCHED_DEBUG -extern unsigned int sysctl_sched_features; extern unsigned int sysctl_sched_migration_cost; extern unsigned int sysctl_sched_nr_migrate; extern unsigned int sysctl_sched_time_avg; extern unsigned int sysctl_timer_migration; -int sched_nr_latency_handler(struct ctl_table *table, int write, +int sched_proc_update_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos); #endif diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 850d057500de..ca6b2b317991 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -110,7 +110,7 @@ extern struct cache_sizes malloc_sizes[]; void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags); extern size_t slab_buffer_size(struct kmem_cache *cachep); #else @@ -166,7 +166,7 @@ found: extern void *__kmalloc_node(size_t size, gfp_t flags, int node); extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, gfp_t flags, int nodeid); diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 5ad70a60fd74..1e14beb23f9b 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -217,7 +217,7 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags); #else static __always_inline void * @@ -266,7 +266,7 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) void *__kmalloc_node(size_t size, gfp_t flags, int node); void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, int node); diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h new file mode 100644 index 000000000000..2e8db3d2d2e5 --- /dev/null +++ b/include/linux/spi/sh_msiof.h @@ -0,0 +1,10 @@ +#ifndef __SPI_SH_MSIOF_H__ +#define __SPI_SH_MSIOF_H__ + +struct sh_msiof_spi_info { + int tx_fifo_override; + int rx_fifo_override; + u16 num_chipselect; +}; + +#endif /* __SPI_SH_MSIOF_H__ */ diff --git a/include/linux/spi/xilinx_spi.h b/include/linux/spi/xilinx_spi.h new file mode 100644 index 000000000000..6f17278810b0 --- /dev/null +++ b/include/linux/spi/xilinx_spi.h @@ -0,0 +1,20 @@ +#ifndef __LINUX_SPI_XILINX_SPI_H +#define __LINUX_SPI_XILINX_SPI_H + +/** + * struct xspi_platform_data - Platform data of the Xilinx SPI driver + * @num_chipselect: Number of chip select by the IP. + * @little_endian: If registers should be accessed little endian or not. + * @bits_per_word: Number of bits per word. + * @devices: Devices to add when the driver is probed. + * @num_devices: Number of devices in the devices array. + */ +struct xspi_platform_data { + u16 num_chipselect; + bool little_endian; + u8 bits_per_word; + struct spi_board_info *devices; + u8 num_devices; +}; + +#endif /* __LINUX_SPI_XILINX_SPI_H */ diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 71dccfeb0d88..86088213334a 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -8,13 +8,13 @@ * * on SMP builds: * - * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the + * asm/spinlock_types.h: contains the arch_spinlock_t/arch_rwlock_t and the * initializers * * linux/spinlock_types.h: * defines the generic type and initializers * - * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel + * asm/spinlock.h: contains the arch_spin_*()/etc. lowlevel * implementations, mostly inline assembly code * * (also included on UP-debug builds:) @@ -34,7 +34,7 @@ * defines the generic type and initializers * * linux/spinlock_up.h: - * contains the __raw_spin_*()/etc. version of UP + * contains the arch_spin_*()/etc. version of UP * builds. (which are NOPs on non-debug, non-preempt * builds) * @@ -75,12 +75,12 @@ #define __lockfunc __attribute__((section(".spinlock.text"))) /* - * Pull the raw_spinlock_t and raw_rwlock_t definitions: + * Pull the arch_spinlock_t and arch_rwlock_t definitions: */ #include <linux/spinlock_types.h> /* - * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): + * Pull the arch_spin*() functions/declarations (UP-nondebug doesnt need them): */ #ifdef CONFIG_SMP # include <asm/spinlock.h> @@ -89,45 +89,31 @@ #endif #ifdef CONFIG_DEBUG_SPINLOCK - extern void __spin_lock_init(spinlock_t *lock, const char *name, - struct lock_class_key *key); -# define spin_lock_init(lock) \ + extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, + struct lock_class_key *key); +# define raw_spin_lock_init(lock) \ do { \ static struct lock_class_key __key; \ \ - __spin_lock_init((lock), #lock, &__key); \ + __raw_spin_lock_init((lock), #lock, &__key); \ } while (0) #else -# define spin_lock_init(lock) \ - do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0) +# define raw_spin_lock_init(lock) \ + do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0) #endif -#ifdef CONFIG_DEBUG_SPINLOCK - extern void __rwlock_init(rwlock_t *lock, const char *name, - struct lock_class_key *key); -# define rwlock_init(lock) \ -do { \ - static struct lock_class_key __key; \ - \ - __rwlock_init((lock), #lock, &__key); \ -} while (0) -#else -# define rwlock_init(lock) \ - do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0) -#endif - -#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) +#define raw_spin_is_locked(lock) arch_spin_is_locked(&(lock)->raw_lock) #ifdef CONFIG_GENERIC_LOCKBREAK -#define spin_is_contended(lock) ((lock)->break_lock) +#define raw_spin_is_contended(lock) ((lock)->break_lock) #else -#ifdef __raw_spin_is_contended -#define spin_is_contended(lock) __raw_spin_is_contended(&(lock)->raw_lock) +#ifdef arch_spin_is_contended +#define raw_spin_is_contended(lock) arch_spin_is_contended(&(lock)->raw_lock) #else -#define spin_is_contended(lock) (((void)(lock), 0)) -#endif /*__raw_spin_is_contended*/ +#define raw_spin_is_contended(lock) (((void)(lock), 0)) +#endif /*arch_spin_is_contended*/ #endif /* The lock does not imply full memory barrier. */ @@ -136,182 +122,260 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #endif /** - * spin_unlock_wait - wait until the spinlock gets unlocked + * raw_spin_unlock_wait - wait until the spinlock gets unlocked * @lock: the spinlock in question. */ -#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock) +#define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK - extern void _raw_spin_lock(spinlock_t *lock); -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) - extern int _raw_spin_trylock(spinlock_t *lock); - extern void _raw_spin_unlock(spinlock_t *lock); - extern void _raw_read_lock(rwlock_t *lock); -#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock) - extern int _raw_read_trylock(rwlock_t *lock); - extern void _raw_read_unlock(rwlock_t *lock); - extern void _raw_write_lock(rwlock_t *lock); -#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock) - extern int _raw_write_trylock(rwlock_t *lock); - extern void _raw_write_unlock(rwlock_t *lock); + extern void do_raw_spin_lock(raw_spinlock_t *lock); +#define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock) + extern int do_raw_spin_trylock(raw_spinlock_t *lock); + extern void do_raw_spin_unlock(raw_spinlock_t *lock); #else -# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) -# define _raw_spin_lock_flags(lock, flags) \ - __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) -# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) -# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) -# define _raw_read_lock_flags(lock, flags) \ - __raw_read_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) -# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) -# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) -# define _raw_write_lock_flags(lock, flags) \ - __raw_write_lock_flags(&(lock)->raw_lock, *(flags)) -# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) -# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) +static inline void do_raw_spin_lock(raw_spinlock_t *lock) +{ + arch_spin_lock(&lock->raw_lock); +} + +static inline void +do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) +{ + arch_spin_lock_flags(&lock->raw_lock, *flags); +} + +static inline int do_raw_spin_trylock(raw_spinlock_t *lock) +{ + return arch_spin_trylock(&(lock)->raw_lock); +} + +static inline void do_raw_spin_unlock(raw_spinlock_t *lock) +{ + arch_spin_unlock(&lock->raw_lock); +} #endif -#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) -#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) - /* - * Define the various spin_lock and rw_lock methods. Note we define these - * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various - * methods are defined as nops in the case they are not required. + * Define the various spin_lock methods. Note we define these + * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The + * various methods are defined as nops in the case they are not + * required. */ -#define spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) -#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock)) -#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock)) +#define raw_spin_trylock(lock) __cond_lock(lock, _raw_spin_trylock(lock)) -#define spin_lock(lock) _spin_lock(lock) +#define raw_spin_lock(lock) _raw_spin_lock(lock) #ifdef CONFIG_DEBUG_LOCK_ALLOC -# define spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) -# define spin_lock_nest_lock(lock, nest_lock) \ +# define raw_spin_lock_nested(lock, subclass) \ + _raw_spin_lock_nested(lock, subclass) + +# define raw_spin_lock_nest_lock(lock, nest_lock) \ do { \ typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\ - _spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ + _raw_spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ } while (0) #else -# define spin_lock_nested(lock, subclass) _spin_lock(lock) -# define spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) +# define raw_spin_lock_nested(lock, subclass) _raw_spin_lock(lock) +# define raw_spin_lock_nest_lock(lock, nest_lock) _raw_spin_lock(lock) #endif -#define write_lock(lock) _write_lock(lock) -#define read_lock(lock) _read_lock(lock) - #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -#define spin_lock_irqsave(lock, flags) \ +#define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave(lock); \ - } while (0) -#define read_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - flags = _read_lock_irqsave(lock); \ - } while (0) -#define write_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - flags = _write_lock_irqsave(lock); \ + flags = _raw_spin_lock_irqsave(lock); \ } while (0) #ifdef CONFIG_DEBUG_LOCK_ALLOC -#define spin_lock_irqsave_nested(lock, flags, subclass) \ +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave_nested(lock, subclass); \ + flags = _raw_spin_lock_irqsave_nested(lock, subclass); \ } while (0) #else -#define spin_lock_irqsave_nested(lock, flags, subclass) \ +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ do { \ typecheck(unsigned long, flags); \ - flags = _spin_lock_irqsave(lock); \ + flags = _raw_spin_lock_irqsave(lock); \ } while (0) #endif #else -#define spin_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _spin_lock_irqsave(lock, flags); \ - } while (0) -#define read_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _read_lock_irqsave(lock, flags); \ - } while (0) -#define write_lock_irqsave(lock, flags) \ +#define raw_spin_lock_irqsave(lock, flags) \ do { \ typecheck(unsigned long, flags); \ - _write_lock_irqsave(lock, flags); \ + _raw_spin_lock_irqsave(lock, flags); \ } while (0) -#define spin_lock_irqsave_nested(lock, flags, subclass) \ - spin_lock_irqsave(lock, flags) -#endif +#define raw_spin_lock_irqsave_nested(lock, flags, subclass) \ + raw_spin_lock_irqsave(lock, flags) -#define spin_lock_irq(lock) _spin_lock_irq(lock) -#define spin_lock_bh(lock) _spin_lock_bh(lock) -#define read_lock_irq(lock) _read_lock_irq(lock) -#define read_lock_bh(lock) _read_lock_bh(lock) -#define write_lock_irq(lock) _write_lock_irq(lock) -#define write_lock_bh(lock) _write_lock_bh(lock) -#define spin_unlock(lock) _spin_unlock(lock) -#define read_unlock(lock) _read_unlock(lock) -#define write_unlock(lock) _write_unlock(lock) -#define spin_unlock_irq(lock) _spin_unlock_irq(lock) -#define read_unlock_irq(lock) _read_unlock_irq(lock) -#define write_unlock_irq(lock) _write_unlock_irq(lock) - -#define spin_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _spin_unlock_irqrestore(lock, flags); \ - } while (0) -#define spin_unlock_bh(lock) _spin_unlock_bh(lock) +#endif -#define read_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _read_unlock_irqrestore(lock, flags); \ - } while (0) -#define read_unlock_bh(lock) _read_unlock_bh(lock) +#define raw_spin_lock_irq(lock) _raw_spin_lock_irq(lock) +#define raw_spin_lock_bh(lock) _raw_spin_lock_bh(lock) +#define raw_spin_unlock(lock) _raw_spin_unlock(lock) +#define raw_spin_unlock_irq(lock) _raw_spin_unlock_irq(lock) -#define write_unlock_irqrestore(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ - _write_unlock_irqrestore(lock, flags); \ +#define raw_spin_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _raw_spin_unlock_irqrestore(lock, flags); \ } while (0) -#define write_unlock_bh(lock) _write_unlock_bh(lock) +#define raw_spin_unlock_bh(lock) _raw_spin_unlock_bh(lock) -#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) +#define raw_spin_trylock_bh(lock) \ + __cond_lock(lock, _raw_spin_trylock_bh(lock)) -#define spin_trylock_irq(lock) \ +#define raw_spin_trylock_irq(lock) \ ({ \ local_irq_disable(); \ - spin_trylock(lock) ? \ + raw_spin_trylock(lock) ? \ 1 : ({ local_irq_enable(); 0; }); \ }) -#define spin_trylock_irqsave(lock, flags) \ +#define raw_spin_trylock_irqsave(lock, flags) \ ({ \ local_irq_save(flags); \ - spin_trylock(lock) ? \ + raw_spin_trylock(lock) ? \ 1 : ({ local_irq_restore(flags); 0; }); \ }) -#define write_trylock_irqsave(lock, flags) \ -({ \ - local_irq_save(flags); \ - write_trylock(lock) ? \ - 1 : ({ local_irq_restore(flags); 0; }); \ +/** + * raw_spin_can_lock - would raw_spin_trylock() succeed? + * @lock: the spinlock in question. + */ +#define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) + +/* Include rwlock functions */ +#include <linux/rwlock.h> + +/* + * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: + */ +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +# include <linux/spinlock_api_smp.h> +#else +# include <linux/spinlock_api_up.h> +#endif + +/* + * Map the spin_lock functions to the raw variants for PREEMPT_RT=n + */ + +static inline raw_spinlock_t *spinlock_check(spinlock_t *lock) +{ + return &lock->rlock; +} + +#define spin_lock_init(_lock) \ +do { \ + spinlock_check(_lock); \ + raw_spin_lock_init(&(_lock)->rlock); \ +} while (0) + +static inline void spin_lock(spinlock_t *lock) +{ + raw_spin_lock(&lock->rlock); +} + +static inline void spin_lock_bh(spinlock_t *lock) +{ + raw_spin_lock_bh(&lock->rlock); +} + +static inline int spin_trylock(spinlock_t *lock) +{ + return raw_spin_trylock(&lock->rlock); +} + +#define spin_lock_nested(lock, subclass) \ +do { \ + raw_spin_lock_nested(spinlock_check(lock), subclass); \ +} while (0) + +#define spin_lock_nest_lock(lock, nest_lock) \ +do { \ + raw_spin_lock_nest_lock(spinlock_check(lock), nest_lock); \ +} while (0) + +static inline void spin_lock_irq(spinlock_t *lock) +{ + raw_spin_lock_irq(&lock->rlock); +} + +#define spin_lock_irqsave(lock, flags) \ +do { \ + raw_spin_lock_irqsave(spinlock_check(lock), flags); \ +} while (0) + +#define spin_lock_irqsave_nested(lock, flags, subclass) \ +do { \ + raw_spin_lock_irqsave_nested(spinlock_check(lock), flags, subclass); \ +} while (0) + +static inline void spin_unlock(spinlock_t *lock) +{ + raw_spin_unlock(&lock->rlock); +} + +static inline void spin_unlock_bh(spinlock_t *lock) +{ + raw_spin_unlock_bh(&lock->rlock); +} + +static inline void spin_unlock_irq(spinlock_t *lock) +{ + raw_spin_unlock_irq(&lock->rlock); +} + +static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +{ + raw_spin_unlock_irqrestore(&lock->rlock, flags); +} + +static inline int spin_trylock_bh(spinlock_t *lock) +{ + return raw_spin_trylock_bh(&lock->rlock); +} + +static inline int spin_trylock_irq(spinlock_t *lock) +{ + return raw_spin_trylock_irq(&lock->rlock); +} + +#define spin_trylock_irqsave(lock, flags) \ +({ \ + raw_spin_trylock_irqsave(spinlock_check(lock), flags); \ }) +static inline void spin_unlock_wait(spinlock_t *lock) +{ + raw_spin_unlock_wait(&lock->rlock); +} + +static inline int spin_is_locked(spinlock_t *lock) +{ + return raw_spin_is_locked(&lock->rlock); +} + +static inline int spin_is_contended(spinlock_t *lock) +{ + return raw_spin_is_contended(&lock->rlock); +} + +static inline int spin_can_lock(spinlock_t *lock) +{ + return raw_spin_can_lock(&lock->rlock); +} + +static inline void assert_spin_locked(spinlock_t *lock) +{ + assert_raw_spin_locked(&lock->rlock); +} + /* * Pull the atomic_t declaration: * (asm-mips/atomic.h needs above definitions) @@ -329,19 +393,4 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define atomic_dec_and_lock(atomic, lock) \ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) -/** - * spin_can_lock - would spin_trylock() succeed? - * @lock: the spinlock in question. - */ -#define spin_can_lock(lock) (!spin_is_locked(lock)) - -/* - * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: - */ -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -# include <linux/spinlock_api_smp.h> -#else -# include <linux/spinlock_api_up.h> -#endif - #endif /* __LINUX_SPINLOCK_H */ diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 8264a7f459bc..e253ccd7a604 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -17,165 +17,76 @@ int in_lock_functions(unsigned long addr); -#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) - -void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) - __acquires(lock); -void __lockfunc _spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *map) - __acquires(lock); -void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock); -void __lockfunc _spin_lock_irq(spinlock_t *lock) __acquires(lock); -void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); -void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); -unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock) - __acquires(lock); -unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass) - __acquires(lock); -unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) - __acquires(lock); -unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) - __acquires(lock); -int __lockfunc _spin_trylock(spinlock_t *lock); -int __lockfunc _read_trylock(rwlock_t *lock); -int __lockfunc _write_trylock(rwlock_t *lock); -int __lockfunc _spin_trylock_bh(spinlock_t *lock); -void __lockfunc _spin_unlock(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_bh(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_irq(spinlock_t *lock) __releases(lock); -void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock); -void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock); -void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) - __releases(lock); -void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) - __releases(lock); -void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) - __releases(lock); +#define assert_raw_spin_locked(x) BUG_ON(!raw_spin_is_locked(x)) + +void __lockfunc _raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) + __acquires(lock); +void __lockfunc +_raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map) + __acquires(lock); +void __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock) __acquires(lock); +void __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock) + __acquires(lock); + +unsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock) + __acquires(lock); +unsigned long __lockfunc +_raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass) + __acquires(lock); +int __lockfunc _raw_spin_trylock(raw_spinlock_t *lock); +int __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock); +void __lockfunc _raw_spin_unlock(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) __releases(lock); +void __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock) __releases(lock); +void __lockfunc +_raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) + __releases(lock); #ifdef CONFIG_INLINE_SPIN_LOCK -#define _spin_lock(lock) __spin_lock(lock) -#endif - -#ifdef CONFIG_INLINE_READ_LOCK -#define _read_lock(lock) __read_lock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK -#define _write_lock(lock) __write_lock(lock) +#define _raw_spin_lock(lock) __raw_spin_lock(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_BH -#define _spin_lock_bh(lock) __spin_lock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_READ_LOCK_BH -#define _read_lock_bh(lock) __read_lock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_BH -#define _write_lock_bh(lock) __write_lock_bh(lock) +#define _raw_spin_lock_bh(lock) __raw_spin_lock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_IRQ -#define _spin_lock_irq(lock) __spin_lock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_READ_LOCK_IRQ -#define _read_lock_irq(lock) __read_lock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ -#define _write_lock_irq(lock) __write_lock_irq(lock) +#define _raw_spin_lock_irq(lock) __raw_spin_lock_irq(lock) #endif #ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE -#define _spin_lock_irqsave(lock) __spin_lock_irqsave(lock) -#endif - -#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE -#define _read_lock_irqsave(lock) __read_lock_irqsave(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE -#define _write_lock_irqsave(lock) __write_lock_irqsave(lock) +#define _raw_spin_lock_irqsave(lock) __raw_spin_lock_irqsave(lock) #endif #ifdef CONFIG_INLINE_SPIN_TRYLOCK -#define _spin_trylock(lock) __spin_trylock(lock) -#endif - -#ifdef CONFIG_INLINE_READ_TRYLOCK -#define _read_trylock(lock) __read_trylock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_TRYLOCK -#define _write_trylock(lock) __write_trylock(lock) +#define _raw_spin_trylock(lock) __raw_spin_trylock(lock) #endif #ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH -#define _spin_trylock_bh(lock) __spin_trylock_bh(lock) +#define _raw_spin_trylock_bh(lock) __raw_spin_trylock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK -#define _spin_unlock(lock) __spin_unlock(lock) -#endif - -#ifdef CONFIG_INLINE_READ_UNLOCK -#define _read_unlock(lock) __read_unlock(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK -#define _write_unlock(lock) __write_unlock(lock) +#define _raw_spin_unlock(lock) __raw_spin_unlock(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_BH -#define _spin_unlock_bh(lock) __spin_unlock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_READ_UNLOCK_BH -#define _read_unlock_bh(lock) __read_unlock_bh(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH -#define _write_unlock_bh(lock) __write_unlock_bh(lock) +#define _raw_spin_unlock_bh(lock) __raw_spin_unlock_bh(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ -#define _spin_unlock_irq(lock) __spin_unlock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ -#define _read_unlock_irq(lock) __read_unlock_irq(lock) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ -#define _write_unlock_irq(lock) __write_unlock_irq(lock) +#define _raw_spin_unlock_irq(lock) __raw_spin_unlock_irq(lock) #endif #ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE -#define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags) -#endif - -#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE -#define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags) -#endif - -#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE -#define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags) +#define _raw_spin_unlock_irqrestore(lock, flags) __raw_spin_unlock_irqrestore(lock, flags) #endif -static inline int __spin_trylock(spinlock_t *lock) +static inline int __raw_spin_trylock(raw_spinlock_t *lock) { preempt_disable(); - if (_raw_spin_trylock(lock)) { + if (do_raw_spin_trylock(lock)) { spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); return 1; } @@ -183,28 +94,6 @@ static inline int __spin_trylock(spinlock_t *lock) return 0; } -static inline int __read_trylock(rwlock_t *lock) -{ - preempt_disable(); - if (_raw_read_trylock(lock)) { - rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); - return 1; - } - preempt_enable(); - return 0; -} - -static inline int __write_trylock(rwlock_t *lock) -{ - preempt_disable(); - if (_raw_write_trylock(lock)) { - rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); - return 1; - } - preempt_enable(); - return 0; -} - /* * If lockdep is enabled then we use the non-preemption spin-ops * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are @@ -212,14 +101,7 @@ static inline int __write_trylock(rwlock_t *lock) */ #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) -static inline void __read_lock(rwlock_t *lock) -{ - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - -static inline unsigned long __spin_lock_irqsave(spinlock_t *lock) +static inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock) { unsigned long flags; @@ -228,205 +110,79 @@ static inline unsigned long __spin_lock_irqsave(spinlock_t *lock) spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); /* * On lockdep we dont want the hand-coded irq-enable of - * _raw_spin_lock_flags() code, because lockdep assumes + * do_raw_spin_lock_flags() code, because lockdep assumes * that interrupts are not re-enabled during lock-acquire: */ #ifdef CONFIG_LOCKDEP - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); #else - _raw_spin_lock_flags(lock, &flags); + do_raw_spin_lock_flags(lock, &flags); #endif return flags; } -static inline void __spin_lock_irq(spinlock_t *lock) +static inline void __raw_spin_lock_irq(raw_spinlock_t *lock) { local_irq_disable(); preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -static inline void __spin_lock_bh(spinlock_t *lock) +static inline void __raw_spin_lock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); -} - -static inline unsigned long __read_lock_irqsave(rwlock_t *lock) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_read_trylock, _raw_read_lock, - _raw_read_lock_flags, &flags); - return flags; -} - -static inline void __read_lock_irq(rwlock_t *lock) -{ - local_irq_disable(); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - -static inline void __read_lock_bh(rwlock_t *lock) -{ - local_bh_disable(); - preempt_disable(); - rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); -} - -static inline unsigned long __write_lock_irqsave(rwlock_t *lock) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED_FLAGS(lock, _raw_write_trylock, _raw_write_lock, - _raw_write_lock_flags, &flags); - return flags; -} - -static inline void __write_lock_irq(rwlock_t *lock) -{ - local_irq_disable(); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -static inline void __write_lock_bh(rwlock_t *lock) -{ - local_bh_disable(); - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); -} - -static inline void __spin_lock(spinlock_t *lock) +static inline void __raw_spin_lock(raw_spinlock_t *lock) { preempt_disable(); spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_spin_trylock, _raw_spin_lock); -} - -static inline void __write_lock(rwlock_t *lock) -{ - preempt_disable(); - rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); - LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); + LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } #endif /* CONFIG_PREEMPT */ -static inline void __spin_unlock(spinlock_t *lock) +static inline void __raw_spin_unlock(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); - preempt_enable(); -} - -static inline void __write_unlock(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - preempt_enable(); -} - -static inline void __read_unlock(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_spin_unlock(lock); preempt_enable(); } -static inline void __spin_unlock_irqrestore(spinlock_t *lock, +static inline void __raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); local_irq_restore(flags); preempt_enable(); } -static inline void __spin_unlock_irq(spinlock_t *lock) +static inline void __raw_spin_unlock_irq(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); + do_raw_spin_unlock(lock); local_irq_enable(); preempt_enable(); } -static inline void __spin_unlock_bh(spinlock_t *lock) +static inline void __raw_spin_unlock_bh(raw_spinlock_t *lock) { spin_release(&lock->dep_map, 1, _RET_IP_); - _raw_spin_unlock(lock); - preempt_enable_no_resched(); - local_bh_enable_ip((unsigned long)__builtin_return_address(0)); -} - -static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - local_irq_restore(flags); - preempt_enable(); -} - -static inline void __read_unlock_irq(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); - local_irq_enable(); - preempt_enable(); -} - -static inline void __read_unlock_bh(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_read_unlock(lock); + do_raw_spin_unlock(lock); preempt_enable_no_resched(); local_bh_enable_ip((unsigned long)__builtin_return_address(0)); } -static inline void __write_unlock_irqrestore(rwlock_t *lock, - unsigned long flags) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - local_irq_restore(flags); - preempt_enable(); -} - -static inline void __write_unlock_irq(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - local_irq_enable(); - preempt_enable(); -} - -static inline void __write_unlock_bh(rwlock_t *lock) -{ - rwlock_release(&lock->dep_map, 1, _RET_IP_); - _raw_write_unlock(lock); - preempt_enable_no_resched(); - local_bh_enable_ip((unsigned long)__builtin_return_address(0)); -} - -static inline int __spin_trylock_bh(spinlock_t *lock) +static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) { local_bh_disable(); preempt_disable(); - if (_raw_spin_trylock(lock)) { + if (do_raw_spin_trylock(lock)) { spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); return 1; } @@ -435,4 +191,6 @@ static inline int __spin_trylock_bh(spinlock_t *lock) return 0; } +#include <linux/rwlock_api_smp.h> + #endif /* __LINUX_SPINLOCK_API_SMP_H */ diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index 04e1d3164576..af1f47229e70 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h @@ -16,7 +16,7 @@ #define in_lock_functions(ADDR) 0 -#define assert_spin_locked(lock) do { (void)(lock); } while (0) +#define assert_raw_spin_locked(lock) do { (void)(lock); } while (0) /* * In the UP-nondebug case there's no real locking going on, so the @@ -40,7 +40,8 @@ do { preempt_enable(); __release(lock); (void)(lock); } while (0) #define __UNLOCK_BH(lock) \ - do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0) + do { preempt_enable_no_resched(); local_bh_enable(); \ + __release(lock); (void)(lock); } while (0) #define __UNLOCK_IRQ(lock) \ do { local_irq_enable(); __UNLOCK(lock); } while (0) @@ -48,34 +49,37 @@ #define __UNLOCK_IRQRESTORE(lock, flags) \ do { local_irq_restore(flags); __UNLOCK(lock); } while (0) -#define _spin_lock(lock) __LOCK(lock) -#define _spin_lock_nested(lock, subclass) __LOCK(lock) -#define _read_lock(lock) __LOCK(lock) -#define _write_lock(lock) __LOCK(lock) -#define _spin_lock_bh(lock) __LOCK_BH(lock) -#define _read_lock_bh(lock) __LOCK_BH(lock) -#define _write_lock_bh(lock) __LOCK_BH(lock) -#define _spin_lock_irq(lock) __LOCK_IRQ(lock) -#define _read_lock_irq(lock) __LOCK_IRQ(lock) -#define _write_lock_irq(lock) __LOCK_IRQ(lock) -#define _spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) -#define _spin_trylock(lock) ({ __LOCK(lock); 1; }) -#define _read_trylock(lock) ({ __LOCK(lock); 1; }) -#define _write_trylock(lock) ({ __LOCK(lock); 1; }) -#define _spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; }) -#define _spin_unlock(lock) __UNLOCK(lock) -#define _read_unlock(lock) __UNLOCK(lock) -#define _write_unlock(lock) __UNLOCK(lock) -#define _spin_unlock_bh(lock) __UNLOCK_BH(lock) -#define _write_unlock_bh(lock) __UNLOCK_BH(lock) -#define _read_unlock_bh(lock) __UNLOCK_BH(lock) -#define _spin_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _read_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _write_unlock_irq(lock) __UNLOCK_IRQ(lock) -#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) -#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) -#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_spin_lock(lock) __LOCK(lock) +#define _raw_spin_lock_nested(lock, subclass) __LOCK(lock) +#define _raw_read_lock(lock) __LOCK(lock) +#define _raw_write_lock(lock) __LOCK(lock) +#define _raw_spin_lock_bh(lock) __LOCK_BH(lock) +#define _raw_read_lock_bh(lock) __LOCK_BH(lock) +#define _raw_write_lock_bh(lock) __LOCK_BH(lock) +#define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_read_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_write_lock_irq(lock) __LOCK_IRQ(lock) +#define _raw_spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags) +#define _raw_spin_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_read_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_write_trylock(lock) ({ __LOCK(lock); 1; }) +#define _raw_spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; }) +#define _raw_spin_unlock(lock) __UNLOCK(lock) +#define _raw_read_unlock(lock) __UNLOCK(lock) +#define _raw_write_unlock(lock) __UNLOCK(lock) +#define _raw_spin_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_write_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_read_unlock_bh(lock) __UNLOCK_BH(lock) +#define _raw_spin_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_read_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_write_unlock_irq(lock) __UNLOCK_IRQ(lock) +#define _raw_spin_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_read_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) +#define _raw_write_unlock_irqrestore(lock, flags) \ + __UNLOCK_IRQRESTORE(lock, flags) #endif /* __LINUX_SPINLOCK_API_UP_H */ diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index 68d88f71f1a2..851b7783720d 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -17,8 +17,8 @@ #include <linux/lockdep.h> -typedef struct { - raw_spinlock_t raw_lock; +typedef struct raw_spinlock { + arch_spinlock_t raw_lock; #ifdef CONFIG_GENERIC_LOCKBREAK unsigned int break_lock; #endif @@ -29,26 +29,10 @@ typedef struct { #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif -} spinlock_t; +} raw_spinlock_t; #define SPINLOCK_MAGIC 0xdead4ead -typedef struct { - raw_rwlock_t raw_lock; -#ifdef CONFIG_GENERIC_LOCKBREAK - unsigned int break_lock; -#endif -#ifdef CONFIG_DEBUG_SPINLOCK - unsigned int magic, owner_cpu; - void *owner; -#endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; -#endif -} rwlock_t; - -#define RWLOCK_MAGIC 0xdeaf1eed - #define SPINLOCK_OWNER_INIT ((void *)-1L) #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -57,44 +41,56 @@ typedef struct { # define SPIN_DEP_MAP_INIT(lockname) #endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } +#ifdef CONFIG_DEBUG_SPINLOCK +# define SPIN_DEBUG_INIT(lockname) \ + .magic = SPINLOCK_MAGIC, \ + .owner_cpu = -1, \ + .owner = SPINLOCK_OWNER_INIT, #else -# define RW_DEP_MAP_INIT(lockname) +# define SPIN_DEBUG_INIT(lockname) #endif -#ifdef CONFIG_DEBUG_SPINLOCK -# define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ - .magic = SPINLOCK_MAGIC, \ - .owner = SPINLOCK_OWNER_INIT, \ - .owner_cpu = -1, \ - SPIN_DEP_MAP_INIT(lockname) } -#define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ - .magic = RWLOCK_MAGIC, \ - .owner = SPINLOCK_OWNER_INIT, \ - .owner_cpu = -1, \ - RW_DEP_MAP_INIT(lockname) } -#else -# define __SPIN_LOCK_UNLOCKED(lockname) \ - (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ - SPIN_DEP_MAP_INIT(lockname) } -#define __RW_LOCK_UNLOCKED(lockname) \ - (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ - RW_DEP_MAP_INIT(lockname) } +#define __RAW_SPIN_LOCK_INITIALIZER(lockname) \ + { \ + .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ + SPIN_DEBUG_INIT(lockname) \ + SPIN_DEP_MAP_INIT(lockname) } + +#define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ + (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname) + +#define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) + +typedef struct spinlock { + union { + struct raw_spinlock rlock; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map)) + struct { + u8 __padding[LOCK_PADSIZE]; + struct lockdep_map dep_map; + }; #endif + }; +} spinlock_t; + +#define __SPIN_LOCK_INITIALIZER(lockname) \ + { { .rlock = __RAW_SPIN_LOCK_INITIALIZER(lockname) } } + +#define __SPIN_LOCK_UNLOCKED(lockname) \ + (spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname) /* - * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and - * are hence deprecated. - * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or - * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate. + * SPIN_LOCK_UNLOCKED defeats lockdep state tracking and is hence + * deprecated. + * Please use DEFINE_SPINLOCK() or __SPIN_LOCK_UNLOCKED() as + * appropriate. */ #define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init) -#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init) #define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) -#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x) + +#include <linux/rwlock_types.h> #endif /* __LINUX_SPINLOCK_TYPES_H */ diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h index 04135b0e198e..c09b6407ae1b 100644 --- a/include/linux/spinlock_types_up.h +++ b/include/linux/spinlock_types_up.h @@ -16,22 +16,22 @@ typedef struct { volatile unsigned int slock; -} raw_spinlock_t; +} arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#define __ARCH_SPIN_LOCK_UNLOCKED { 1 } #else -typedef struct { } raw_spinlock_t; +typedef struct { } arch_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { } +#define __ARCH_SPIN_LOCK_UNLOCKED { } #endif typedef struct { /* no debug version on UP */ -} raw_rwlock_t; +} arch_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED { } +#define __ARCH_RW_LOCK_UNLOCKED { } #endif /* __LINUX_SPINLOCK_TYPES_UP_H */ diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index d4841ed8215b..b14f6a91e19f 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -18,21 +18,21 @@ */ #ifdef CONFIG_DEBUG_SPINLOCK -#define __raw_spin_is_locked(x) ((x)->slock == 0) +#define arch_spin_is_locked(x) ((x)->slock == 0) -static inline void __raw_spin_lock(raw_spinlock_t *lock) +static inline void arch_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; } static inline void -__raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { local_irq_save(flags); lock->slock = 0; } -static inline int __raw_spin_trylock(raw_spinlock_t *lock) +static inline int arch_spin_trylock(arch_spinlock_t *lock) { char oldval = lock->slock; @@ -41,7 +41,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) return oldval > 0; } -static inline void __raw_spin_unlock(raw_spinlock_t *lock) +static inline void arch_spin_unlock(arch_spinlock_t *lock) { lock->slock = 1; } @@ -49,28 +49,28 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) /* * Read-write spinlocks. No debug version. */ -#define __raw_read_lock(lock) do { (void)(lock); } while (0) -#define __raw_write_lock(lock) do { (void)(lock); } while (0) -#define __raw_read_trylock(lock) ({ (void)(lock); 1; }) -#define __raw_write_trylock(lock) ({ (void)(lock); 1; }) -#define __raw_read_unlock(lock) do { (void)(lock); } while (0) -#define __raw_write_unlock(lock) do { (void)(lock); } while (0) +#define arch_read_lock(lock) do { (void)(lock); } while (0) +#define arch_write_lock(lock) do { (void)(lock); } while (0) +#define arch_read_trylock(lock) ({ (void)(lock); 1; }) +#define arch_write_trylock(lock) ({ (void)(lock); 1; }) +#define arch_read_unlock(lock) do { (void)(lock); } while (0) +#define arch_write_unlock(lock) do { (void)(lock); } while (0) #else /* DEBUG_SPINLOCK */ -#define __raw_spin_is_locked(lock) ((void)(lock), 0) +#define arch_spin_is_locked(lock) ((void)(lock), 0) /* for sched.c and kernel_lock.c: */ -# define __raw_spin_lock(lock) do { (void)(lock); } while (0) -# define __raw_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) -# define __raw_spin_unlock(lock) do { (void)(lock); } while (0) -# define __raw_spin_trylock(lock) ({ (void)(lock); 1; }) +# define arch_spin_lock(lock) do { (void)(lock); } while (0) +# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) +# define arch_spin_unlock(lock) do { (void)(lock); } while (0) +# define arch_spin_trylock(lock) ({ (void)(lock); 1; }) #endif /* DEBUG_SPINLOCK */ -#define __raw_spin_is_contended(lock) (((void)(lock), 0)) +#define arch_spin_is_contended(lock) (((void)(lock), 0)) -#define __raw_read_can_lock(lock) (((void)(lock), 1)) -#define __raw_write_can_lock(lock) (((void)(lock), 1)) +#define arch_read_can_lock(lock) (((void)(lock), 1)) +#define arch_write_can_lock(lock) (((void)(lock), 1)) -#define __raw_spin_unlock_wait(lock) \ - do { cpu_relax(); } while (__raw_spin_is_locked(lock)) +#define arch_spin_unlock_wait(lock) \ + do { cpu_relax(); } while (arch_spin_is_locked(lock)) #endif /* __LINUX_SPINLOCK_UP_H */ diff --git a/include/linux/string.h b/include/linux/string.h index b8508868d5ad..651839a2a755 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -62,7 +62,15 @@ extern char * strnchr(const char *, size_t, int); #ifndef __HAVE_ARCH_STRRCHR extern char * strrchr(const char *,int); #endif -extern char * __must_check strstrip(char *); +extern char * __must_check skip_spaces(const char *); + +extern char *strim(char *); + +static inline __must_check char *strstrip(char *str) +{ + return strim(str); +} + #ifndef __HAVE_ARCH_STRSTR extern char * strstr(const char *,const char *); #endif diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 401097781fc0..1906782ec86b 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -130,12 +130,14 @@ struct rpc_task_setup { #define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */ #define RPC_TASK_KILLED 0x0100 /* task was killed */ #define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */ +#define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) +#define RPC_IS_SOFTCONN(t) ((t)->tk_flags & RPC_TASK_SOFTCONN) #define RPC_TASK_RUNNING 0 #define RPC_TASK_QUEUED 1 diff --git a/include/linux/swap.h b/include/linux/swap.h index 4ec90019c1a4..a2602a8207a6 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -145,38 +145,43 @@ enum { SWP_DISCARDABLE = (1 << 2), /* blkdev supports discard */ SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */ SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ + SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ /* add others here before... */ SWP_SCANNING = (1 << 8), /* refcount in scan_swap_map */ }; #define SWAP_CLUSTER_MAX 32 -#define SWAP_MAP_MAX 0x7ffe -#define SWAP_MAP_BAD 0x7fff -#define SWAP_HAS_CACHE 0x8000 /* There is a swap cache of entry. */ -#define SWAP_COUNT_MASK (~SWAP_HAS_CACHE) +#define SWAP_MAP_MAX 0x3e /* Max duplication count, in first swap_map */ +#define SWAP_MAP_BAD 0x3f /* Note pageblock is bad, in first swap_map */ +#define SWAP_HAS_CACHE 0x40 /* Flag page is cached, in first swap_map */ +#define SWAP_CONT_MAX 0x7f /* Max count, in each swap_map continuation */ +#define COUNT_CONTINUED 0x80 /* See swap_map continuation for full count */ +#define SWAP_MAP_SHMEM 0xbf /* Owned by shmem/tmpfs, in first swap_map */ + /* * The in-memory structure used to track swap areas. */ struct swap_info_struct { - unsigned long flags; - int prio; /* swap priority */ - int next; /* next entry on swap list */ - struct file *swap_file; - struct block_device *bdev; - struct list_head extent_list; - struct swap_extent *curr_swap_extent; - unsigned short *swap_map; - unsigned int lowest_bit; - unsigned int highest_bit; + unsigned long flags; /* SWP_USED etc: see above */ + signed short prio; /* swap priority of this type */ + signed char type; /* strange name for an index */ + signed char next; /* next type on the swap list */ + unsigned int max; /* extent of the swap_map */ + unsigned char *swap_map; /* vmalloc'ed array of usage counts */ + unsigned int lowest_bit; /* index of first free in swap_map */ + unsigned int highest_bit; /* index of last free in swap_map */ + unsigned int pages; /* total of usable pages of swap */ + unsigned int inuse_pages; /* number of those currently in use */ + unsigned int cluster_next; /* likely index for next allocation */ + unsigned int cluster_nr; /* countdown to next cluster search */ unsigned int lowest_alloc; /* while preparing discard cluster */ unsigned int highest_alloc; /* while preparing discard cluster */ - unsigned int cluster_next; - unsigned int cluster_nr; - unsigned int pages; - unsigned int max; - unsigned int inuse_pages; - unsigned int old_block_size; + struct swap_extent *curr_swap_extent; + struct swap_extent first_swap_extent; + struct block_device *bdev; /* swap device or bdev of swap file */ + struct file *swap_file; /* seldom referenced */ + unsigned int old_block_size; /* seldom referenced */ }; struct swap_list_t { @@ -273,6 +278,7 @@ extern int scan_unevictable_register_node(struct node *node); extern void scan_unevictable_unregister_node(struct node *node); extern int kswapd_run(int nid); +extern void kswapd_stop(int nid); #ifdef CONFIG_MMU /* linux/mm/shmem.c */ @@ -309,17 +315,18 @@ extern long total_swap_pages; extern void si_swapinfo(struct sysinfo *); extern swp_entry_t get_swap_page(void); extern swp_entry_t get_swap_page_of_type(int); -extern void swap_duplicate(swp_entry_t); -extern int swapcache_prepare(swp_entry_t); extern int valid_swaphandles(swp_entry_t, unsigned long *); +extern int add_swap_count_continuation(swp_entry_t, gfp_t); +extern void swap_shmem_alloc(swp_entry_t); +extern int swap_duplicate(swp_entry_t); +extern int swapcache_prepare(swp_entry_t); extern void swap_free(swp_entry_t); extern void swapcache_free(swp_entry_t, struct page *page); extern int free_swap_and_cache(swp_entry_t); extern int swap_type_of(dev_t, sector_t, struct block_device **); extern unsigned int count_swap_pages(int, int); -extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t); +extern sector_t map_swap_page(struct page *, struct block_device **); extern sector_t swapdev_block(int, pgoff_t); -extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int reuse_swap_page(struct page *); extern int try_to_free_swap(struct page *); struct backing_dev_info; @@ -384,8 +391,18 @@ static inline void show_swap_cache_info(void) #define free_swap_and_cache(swp) is_migration_entry(swp) #define swapcache_prepare(swp) is_migration_entry(swp) -static inline void swap_duplicate(swp_entry_t swp) +static inline int add_swap_count_continuation(swp_entry_t swp, gfp_t gfp_mask) { + return 0; +} + +static inline void swap_shmem_alloc(swp_entry_t swp) +{ +} + +static inline int swap_duplicate(swp_entry_t swp) +{ + return 0; } static inline void swap_free(swp_entry_t swp) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index bc70c5810fec..939a61507ac5 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -834,4 +834,8 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]); asmlinkage long sys_perf_event_open( struct perf_event_attr __user *attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags); + +asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); #endif diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 09077f6ed128..5cf397ceb726 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -14,6 +14,7 @@ struct trace_seq { unsigned char buffer[PAGE_SIZE]; unsigned int len; unsigned int readpos; + int full; }; static inline void @@ -21,6 +22,7 @@ trace_seq_init(struct trace_seq *s) { s->len = 0; s->readpos = 0; + s->full = 0; } /* @@ -33,7 +35,7 @@ extern int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) __attribute__ ((format (printf, 2, 0))); extern int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); -extern void trace_print_seq(struct seq_file *m, struct trace_seq *s); +extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt); extern int trace_seq_puts(struct trace_seq *s, const char *str); @@ -55,8 +57,9 @@ trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) return 0; } -static inline void trace_print_seq(struct seq_file *m, struct trace_seq *s) +static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) { + return 0; } static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) diff --git a/include/linux/tty.h b/include/linux/tty.h index f0f43d08d8b8..ef3a2947b102 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -190,9 +190,17 @@ struct tty_port_operations { /* Control the DTR line */ void (*dtr_rts)(struct tty_port *port, int raise); /* Called when the last close completes or a hangup finishes - IFF the port was initialized. Do not use to free resources */ + IFF the port was initialized. Do not use to free resources. Called + under the port mutex to serialize against activate/shutdowns */ void (*shutdown)(struct tty_port *port); void (*drop)(struct tty_port *port); + /* Called under the port mutex from tty_port_open, serialized using + the port mutex */ + /* FIXME: long term getting the tty argument *out* of this would be + good for consoles */ + int (*activate)(struct tty_port *port, struct tty_struct *tty); + /* Called on the final put of a port */ + void (*destruct)(struct tty_port *port); }; struct tty_port { @@ -206,12 +214,14 @@ struct tty_port { wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ struct mutex mutex; /* Locking */ + struct mutex buf_mutex; /* Buffer alloc lock */ unsigned char *xmit_buf; /* Optional buffer */ unsigned int close_delay; /* Close port delay */ unsigned int closing_wait; /* Delay for output */ int drain_delay; /* Set to zero if no pure time based drain is needed else set to size of fifo */ + struct kref kref; /* Ref counter */ }; /* @@ -340,8 +350,6 @@ extern void tty_write_flush(struct tty_struct *); extern struct ktermios tty_std_termios; -extern int kmsg_redirect; - extern void console_init(void); extern int vcs_init(void); @@ -439,7 +447,7 @@ extern void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, int first_ok); -extern void tty_release_dev(struct file *filp); +extern int tty_release(struct inode *inode, struct file *filp); extern int tty_init_termios(struct tty_struct *tty); extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); @@ -454,6 +462,15 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay); extern void tty_port_init(struct tty_port *port); extern int tty_port_alloc_xmit_buf(struct tty_port *port); extern void tty_port_free_xmit_buf(struct tty_port *port); +extern void tty_port_put(struct tty_port *port); + +extern inline struct tty_port *tty_port_get(struct tty_port *port) +{ + if (port) + kref_get(&port->kref); + return port; +} + extern struct tty_struct *tty_port_tty_get(struct tty_port *port); extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); extern int tty_port_carrier_raised(struct tty_port *port); @@ -467,6 +484,8 @@ extern int tty_port_close_start(struct tty_port *port, extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty); extern void tty_port_close(struct tty_port *port, struct tty_struct *tty, struct file *filp); +extern int tty_port_open(struct tty_port *port, + struct tty_struct *tty, struct file *filp); extern inline int tty_port_users(struct tty_port *port) { return port->count + port->blocked_open; diff --git a/include/linux/usb.h b/include/linux/usb.h index a34fa89f1474..e101a2d04d75 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -331,6 +331,7 @@ struct usb_bus { u8 otg_port; /* 0, or number of OTG/HNP port */ unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ + unsigned sg_tablesize; /* 0 or largest number of sg list entries */ int devnum_next; /* Next open device number in * round-robin allocation */ @@ -428,11 +429,9 @@ struct usb_tt; * @last_busy: time of last use * @autosuspend_delay: in jiffies * @connect_time: time device was first connected - * @auto_pm: autosuspend/resume in progress * @do_remote_wakeup: remote wakeup should be enabled * @reset_resume: needs reset instead of resume * @autosuspend_disabled: autosuspend disabled by the user - * @autoresume_disabled: autoresume disabled by the user * @skip_sys_resume: skip the next system resume * @wusb_dev: if this is a Wireless USB device, link to the WUSB * specific data for the device. @@ -513,11 +512,9 @@ struct usb_device { int autosuspend_delay; unsigned long connect_time; - unsigned auto_pm:1; unsigned do_remote_wakeup:1; unsigned reset_resume:1; unsigned autosuspend_disabled:1; - unsigned autoresume_disabled:1; unsigned skip_sys_resume:1; #endif struct wusb_dev *wusb_dev; @@ -543,22 +540,20 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); /* USB autosuspend and autoresume */ #ifdef CONFIG_USB_SUSPEND -extern int usb_autopm_set_interface(struct usb_interface *intf); extern int usb_autopm_get_interface(struct usb_interface *intf); extern void usb_autopm_put_interface(struct usb_interface *intf); extern int usb_autopm_get_interface_async(struct usb_interface *intf); extern void usb_autopm_put_interface_async(struct usb_interface *intf); -static inline void usb_autopm_enable(struct usb_interface *intf) +static inline void usb_autopm_get_interface_no_resume( + struct usb_interface *intf) { - atomic_set(&intf->pm_usage_cnt, 0); - usb_autopm_set_interface(intf); + atomic_inc(&intf->pm_usage_cnt); } - -static inline void usb_autopm_disable(struct usb_interface *intf) +static inline void usb_autopm_put_interface_no_suspend( + struct usb_interface *intf) { - atomic_set(&intf->pm_usage_cnt, 1); - usb_autopm_set_interface(intf); + atomic_dec(&intf->pm_usage_cnt); } static inline void usb_mark_last_busy(struct usb_device *udev) @@ -568,12 +563,8 @@ static inline void usb_mark_last_busy(struct usb_device *udev) #else -static inline int usb_autopm_set_interface(struct usb_interface *intf) -{ return 0; } - static inline int usb_autopm_get_interface(struct usb_interface *intf) { return 0; } - static inline int usb_autopm_get_interface_async(struct usb_interface *intf) { return 0; } @@ -581,9 +572,11 @@ static inline void usb_autopm_put_interface(struct usb_interface *intf) { } static inline void usb_autopm_put_interface_async(struct usb_interface *intf) { } -static inline void usb_autopm_enable(struct usb_interface *intf) +static inline void usb_autopm_get_interface_no_resume( + struct usb_interface *intf) { } -static inline void usb_autopm_disable(struct usb_interface *intf) +static inline void usb_autopm_put_interface_no_suspend( + struct usb_interface *intf) { } static inline void usb_mark_last_busy(struct usb_device *udev) { } @@ -626,6 +619,10 @@ extern struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, unsigned ifnum); extern struct usb_host_interface *usb_altnum_to_altsetting( const struct usb_interface *intf, unsigned int altnum); +extern struct usb_host_interface *usb_find_alt_setting( + struct usb_host_config *config, + unsigned int iface_num, + unsigned int alt_num); /** diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 4f6bb3d2160e..738ea1a691cb 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -127,6 +127,7 @@ struct usb_function { /* private: */ /* internals */ struct list_head list; + DECLARE_BITMAP(endpoints, 32); }; int usb_add_function(struct usb_configuration *, struct usb_function *); diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 2443c0e7a80c..52bb917641f0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -33,6 +33,23 @@ enum usb_otg_state { OTG_STATE_A_VBUS_ERR, }; +#define USB_OTG_PULLUP_ID (1 << 0) +#define USB_OTG_PULLDOWN_DP (1 << 1) +#define USB_OTG_PULLDOWN_DM (1 << 2) +#define USB_OTG_EXT_VBUS_INDICATOR (1 << 3) +#define USB_OTG_DRV_VBUS (1 << 4) +#define USB_OTG_DRV_VBUS_EXT (1 << 5) + +struct otg_transceiver; + +/* for transceivers connected thru an ULPI interface, the user must + * provide access ops + */ +struct otg_io_access_ops { + int (*read)(struct otg_transceiver *otg, u32 reg); + int (*write)(struct otg_transceiver *otg, u32 val, u32 reg); +}; + /* * the otg driver needs to interact with both device side and host side * usb controllers. it decides which controller is active at a given @@ -42,6 +59,7 @@ enum usb_otg_state { struct otg_transceiver { struct device *dev; const char *label; + unsigned int flags; u8 default_a; enum usb_otg_state state; @@ -49,10 +67,17 @@ struct otg_transceiver { struct usb_bus *host; struct usb_gadget *gadget; + struct otg_io_access_ops *io_ops; + void __iomem *io_priv; + /* to pass extra port status to the root hub */ u16 port_status; u16 port_change; + /* initialize/shutdown the OTG controller */ + int (*init)(struct otg_transceiver *otg); + void (*shutdown)(struct otg_transceiver *otg); + /* bind/unbind the host controller */ int (*set_host)(struct otg_transceiver *otg, struct usb_bus *host); @@ -65,6 +90,10 @@ struct otg_transceiver { int (*set_power)(struct otg_transceiver *otg, unsigned mA); + /* effective for A-peripheral, ignored for B devices */ + int (*set_vbus)(struct otg_transceiver *otg, + bool enabled); + /* for non-OTG B devices: set transceiver into suspend mode */ int (*set_suspend)(struct otg_transceiver *otg, int suspend); @@ -85,6 +114,38 @@ extern int otg_set_transceiver(struct otg_transceiver *); extern void usb_nop_xceiv_register(void); extern void usb_nop_xceiv_unregister(void); +/* helpers for direct access thru low-level io interface */ +static inline int otg_io_read(struct otg_transceiver *otg, u32 reg) +{ + if (otg->io_ops && otg->io_ops->read) + return otg->io_ops->read(otg, reg); + + return -EINVAL; +} + +static inline int otg_io_write(struct otg_transceiver *otg, u32 reg, u32 val) +{ + if (otg->io_ops && otg->io_ops->write) + return otg->io_ops->write(otg, reg, val); + + return -EINVAL; +} + +static inline int +otg_init(struct otg_transceiver *otg) +{ + if (otg->init) + return otg->init(otg); + + return 0; +} + +static inline void +otg_shutdown(struct otg_transceiver *otg) +{ + if (otg->shutdown) + otg->shutdown(otg); +} /* for usb host and peripheral controller drivers */ extern struct otg_transceiver *otg_get_transceiver(void); @@ -97,6 +158,12 @@ otg_start_hnp(struct otg_transceiver *otg) return otg->start_hnp(otg); } +/* Context: can sleep */ +static inline int +otg_set_vbus(struct otg_transceiver *otg, bool enabled) +{ + return otg->set_vbus(otg, enabled); +} /* for HCDs */ static inline int @@ -105,7 +172,6 @@ otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) return otg->set_host(otg, host); } - /* for usb peripheral controller drivers */ /* Context: can sleep */ diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index ce911ebf91e8..acf6e457c04b 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -39,8 +39,6 @@ enum port_dev_state { * @serial: pointer back to the struct usb_serial owner of this port. * @port: pointer to the corresponding tty_port for this port. * @lock: spinlock to grab when updating portions of this structure. - * @mutex: mutex used to synchronize serial_open() and serial_close() - * access for this port. * @number: the number of the port (the minor number). * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. @@ -77,7 +75,6 @@ struct usb_serial_port { struct usb_serial *serial; struct tty_port port; spinlock_t lock; - struct mutex mutex; unsigned char number; unsigned char *interrupt_in_buffer; diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h new file mode 100644 index 000000000000..20675c6ebc4d --- /dev/null +++ b/include/linux/usb/ulpi.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_USB_ULPI_H +#define __LINUX_USB_ULPI_H + +struct otg_transceiver *otg_ulpi_create(struct otg_io_access_ops *ops, + unsigned int flags); + +#endif /* __LINUX_USB_ULPI_H */ diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 3d15fb9bc116..a4b947e470a5 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -56,7 +56,9 @@ US_FLAG(SANE_SENSE, 0x00008000) \ /* Sane Sense (> 18 bytes) */ \ US_FLAG(CAPACITY_OK, 0x00010000) \ - /* READ CAPACITY response is correct */ + /* READ CAPACITY response is correct */ \ + US_FLAG(BAD_SENSE, 0x00020000) \ + /* Bad Sense (never more than 18 bytes) */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h index b2a7d8ba6ee3..15591d2ea400 100644 --- a/include/linux/usbdevice_fs.h +++ b/include/linux/usbdevice_fs.h @@ -128,6 +128,29 @@ struct usbdevfs_hub_portinfo { #ifdef __KERNEL__ #ifdef CONFIG_COMPAT #include <linux/compat.h> + +struct usbdevfs_ctrltransfer32 { + u8 bRequestType; + u8 bRequest; + u16 wValue; + u16 wIndex; + u16 wLength; + u32 timeout; /* in milliseconds */ + compat_caddr_t data; +}; + +struct usbdevfs_bulktransfer32 { + compat_uint_t ep; + compat_uint_t len; + compat_uint_t timeout; /* in milliseconds */ + compat_caddr_t data; +}; + +struct usbdevfs_disconnectsignal32 { + compat_int_t signr; + compat_caddr_t context; +}; + struct usbdevfs_urb32 { unsigned char type; unsigned char endpoint; @@ -153,7 +176,9 @@ struct usbdevfs_ioctl32 { #endif /* __KERNEL__ */ #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) +#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) #define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) +#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32) #define USBDEVFS_RESETEP _IOR('U', 3, unsigned int) #define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface) #define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int) @@ -166,6 +191,7 @@ struct usbdevfs_ioctl32 { #define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *) #define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32) #define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) +#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32) #define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) #define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 2d0f222388a8..ee03bba9c5df 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -40,6 +40,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, PGSCAN_ZONE_RECLAIM_FAILED, #endif PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, + KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, + KSWAPD_SKIP_CONGESTION_WAIT, PAGEOUTRUN, ALLOCSTALL, PGROTATED, #ifdef CONFIG_HUGETLB_PAGE HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, @@ -76,24 +78,22 @@ DECLARE_PER_CPU(struct vm_event_state, vm_event_states); static inline void __count_vm_event(enum vm_event_item item) { - __get_cpu_var(vm_event_states).event[item]++; + __this_cpu_inc(per_cpu_var(vm_event_states).event[item]); } static inline void count_vm_event(enum vm_event_item item) { - get_cpu_var(vm_event_states).event[item]++; - put_cpu(); + this_cpu_inc(per_cpu_var(vm_event_states).event[item]); } static inline void __count_vm_events(enum vm_event_item item, long delta) { - __get_cpu_var(vm_event_states).event[item] += delta; + __this_cpu_add(per_cpu_var(vm_event_states).event[item], delta); } static inline void count_vm_events(enum vm_event_item item, long delta) { - get_cpu_var(vm_event_states).event[item] += delta; - put_cpu(); + this_cpu_add(per_cpu_var(vm_event_states).event[item], delta); } extern void all_vm_events(unsigned long *); diff --git a/include/linux/vt.h b/include/linux/vt.h index 7ffa11f06232..3fb9944e50a6 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -84,4 +84,19 @@ struct vt_setactivate { #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ +#ifdef CONFIG_VT_CONSOLE + +extern int vt_kmsg_redirect(int new); + +#else + +static inline int vt_kmsg_redirect(int new) +{ + return 0; +} + +#endif + +#define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) + #endif /* _LINUX_VT_H */ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index cf24c20de9e4..9466e860d8c2 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -25,6 +25,7 @@ typedef void (*work_func_t)(struct work_struct *work); struct work_struct { atomic_long_t data; #define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ +#define WORK_STRUCT_STATIC 1 /* static initializer (debugobjects) */ #define WORK_STRUCT_FLAG_MASK (3UL) #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) struct list_head entry; @@ -35,6 +36,7 @@ struct work_struct { }; #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) +#define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(2) struct delayed_work { struct work_struct work; @@ -63,7 +65,7 @@ struct execute_work { #endif #define __WORK_INITIALIZER(n, f) { \ - .data = WORK_DATA_INIT(), \ + .data = WORK_DATA_STATIC_INIT(), \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \ @@ -91,6 +93,14 @@ struct execute_work { #define PREPARE_DELAYED_WORK(_work, _func) \ PREPARE_WORK(&(_work)->work, (_func)) +#ifdef CONFIG_DEBUG_OBJECTS_WORK +extern void __init_work(struct work_struct *work, int onstack); +extern void destroy_work_on_stack(struct work_struct *work); +#else +static inline void __init_work(struct work_struct *work, int onstack) { } +static inline void destroy_work_on_stack(struct work_struct *work) { } +#endif + /* * initialize all of a work item in one go * @@ -99,24 +109,36 @@ struct execute_work { * to generate better code. */ #ifdef CONFIG_LOCKDEP -#define INIT_WORK(_work, _func) \ +#define __INIT_WORK(_work, _func, _onstack) \ do { \ static struct lock_class_key __key; \ \ + __init_work((_work), _onstack); \ (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) #else -#define INIT_WORK(_work, _func) \ +#define __INIT_WORK(_work, _func, _onstack) \ do { \ + __init_work((_work), _onstack); \ (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) #endif +#define INIT_WORK(_work, _func) \ + do { \ + __INIT_WORK((_work), (_func), 0); \ + } while (0) + +#define INIT_WORK_ON_STACK(_work, _func) \ + do { \ + __INIT_WORK((_work), (_func), 1); \ + } while (0) + #define INIT_DELAYED_WORK(_work, _func) \ do { \ INIT_WORK(&(_work)->work, (_func)); \ @@ -125,22 +147,16 @@ struct execute_work { #define INIT_DELAYED_WORK_ON_STACK(_work, _func) \ do { \ - INIT_WORK(&(_work)->work, (_func)); \ + INIT_WORK_ON_STACK(&(_work)->work, (_func)); \ init_timer_on_stack(&(_work)->timer); \ } while (0) -#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ +#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ do { \ INIT_WORK(&(_work)->work, (_func)); \ init_timer_deferrable(&(_work)->timer); \ } while (0) -#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \ - do { \ - INIT_WORK(&(_work)->work, (_func)); \ - init_timer_on_stack(&(_work)->timer); \ - } while (0) - /** * work_pending - Find out whether a work item is currently pending * @work: The work item in question diff --git a/include/net/compat.h b/include/net/compat.h index 3c7d4e38fa1d..28d5428ec6a2 100644 --- a/include/net/compat.h +++ b/include/net/compat.h @@ -46,7 +46,7 @@ extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsi extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *, unsigned, unsigned, - struct timespec __user *); + struct compat_timespec __user *); extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 92838d3a1ab7..e46674d5daea 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -53,7 +53,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) return inet6_ehashfn(net, laddr, lport, faddr, fport); } -extern void __inet6_hash(struct sock *sk); +extern int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp); /* * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 41cbddd25b70..74358d1b3f43 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -251,7 +251,7 @@ extern void inet_put_port(struct sock *sk); void inet_hashinfo_init(struct inet_hashinfo *h); -extern void __inet_hash_nolisten(struct sock *sk); +extern int __inet_hash_nolisten(struct sock *sk, struct inet_timewait_sock *tw); extern void inet_hash(struct sock *sk); extern void inet_unhash(struct sock *sk); @@ -391,10 +391,12 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, } extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, - struct sock *sk, u32 port_offset, + struct sock *sk, + u32 port_offset, int (*check_established)(struct inet_timewait_death_row *, struct sock *, __u16, struct inet_timewait_sock **), - void (*hash)(struct sock *sk)); + int (*hash)(struct sock *sk, struct inet_timewait_sock *twp)); + extern int inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk); #endif /* _INET_HASHTABLES_H */ diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index b801ade2295e..79f67eae8a7e 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -201,6 +201,9 @@ extern void inet_twsk_put(struct inet_timewait_sock *tw); extern int inet_twsk_unhash(struct inet_timewait_sock *tw); +extern int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, + struct inet_hashinfo *hashinfo); + extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state); diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 0302f31a2fb7..b0173202cad9 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -88,12 +88,7 @@ struct neigh_statistics { unsigned long unres_discards; /* number of unresolved drops */ }; -#define NEIGH_CACHE_STAT_INC(tbl, field) \ - do { \ - preempt_disable(); \ - (per_cpu_ptr((tbl)->stats, smp_processor_id())->field)++; \ - preempt_enable(); \ - } while (0) +#define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) struct neighbour { struct neighbour *next; diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 5cf7270e3ffc..a0904adfb8f7 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -293,11 +293,11 @@ extern unsigned int nf_conntrack_htable_size; extern unsigned int nf_conntrack_max; #define NF_CT_STAT_INC(net, count) \ - (per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++) + __this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC_ATOMIC(net, count) \ do { \ local_bh_disable(); \ - per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++; \ + __this_cpu_inc((net)->ct.stat->count); \ local_bh_enable(); \ } while (0) diff --git a/include/net/snmp.h b/include/net/snmp.h index 8c842e06bec8..f0d756f2ac99 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -136,45 +136,31 @@ struct linux_xfrm_mib { #define SNMP_STAT_BHPTR(name) (name[0]) #define SNMP_STAT_USRPTR(name) (name[1]) -#define SNMP_INC_STATS_BH(mib, field) \ - (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++) -#define SNMP_INC_STATS_USER(mib, field) \ - do { \ - per_cpu_ptr(mib[1], get_cpu())->mibs[field]++; \ - put_cpu(); \ - } while (0) -#define SNMP_INC_STATS(mib, field) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]++; \ - put_cpu(); \ - } while (0) -#define SNMP_DEC_STATS(mib, field) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \ - put_cpu(); \ - } while (0) -#define SNMP_ADD_STATS(mib, field, addend) \ - do { \ - per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \ - put_cpu(); \ - } while (0) -#define SNMP_ADD_STATS_BH(mib, field, addend) \ - (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) -#define SNMP_ADD_STATS_USER(mib, field, addend) \ - do { \ - per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \ - put_cpu(); \ - } while (0) +#define SNMP_INC_STATS_BH(mib, field) \ + __this_cpu_inc(mib[0]->mibs[field]) +#define SNMP_INC_STATS_USER(mib, field) \ + this_cpu_inc(mib[1]->mibs[field]) +#define SNMP_INC_STATS(mib, field) \ + this_cpu_inc(mib[!in_softirq()]->mibs[field]) +#define SNMP_DEC_STATS(mib, field) \ + this_cpu_dec(mib[!in_softirq()]->mibs[field]) +#define SNMP_ADD_STATS_BH(mib, field, addend) \ + __this_cpu_add(mib[0]->mibs[field], addend) +#define SNMP_ADD_STATS_USER(mib, field, addend) \ + this_cpu_add(mib[1]->mibs[field], addend) #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\ + __typeof__(mib[0]) ptr; \ + preempt_disable(); \ + ptr = this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\ - put_cpu(); \ + preempt_enable(); \ } while (0) #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ do { \ - __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\ + __typeof__(mib[0]) ptr = \ + __this_cpu_ptr((mib)[!in_softirq()]); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend;\ } while (0) diff --git a/include/net/tcp.h b/include/net/tcp.h index 5740b85bc5a0..1b6f7d348cee 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1261,29 +1261,6 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu #define tcp_for_write_queue_from_safe(skb, tmp, sk) \ skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp) -/* This function calculates a "timeout" which is equivalent to the timeout of a - * TCP connection after "boundary" unsuccessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ -static inline bool retransmits_timed_out(const struct sock *sk, - unsigned int boundary) -{ - unsigned int timeout, linear_backoff_thresh; - - if (!inet_csk(sk)->icsk_retransmits) - return false; - - linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); - - if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; - else - timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + - (boundary - linear_backoff_thresh) * TCP_RTO_MAX; - - return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout; -} - static inline struct sk_buff *tcp_send_head(struct sock *sk) { return sk->sk_send_head; diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index afc2bfb9e917..75fa3530345b 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -126,8 +126,8 @@ typedef struct irq_req_t { #define IRQ_TYPE_TIME 0x01 #define IRQ_TYPE_DYNAMIC_SHARING 0x02 #define IRQ_FORCED_PULSE 0x04 -#define IRQ_FIRST_SHARED 0x08 -//#define IRQ_HANDLE_PRESENT 0x10 +#define IRQ_FIRST_SHARED 0x08 /* unused */ +#define IRQ_HANDLE_PRESENT 0x10 /* unused */ #define IRQ_PULSE_ALLOCATED 0x100 /* Bits in IRQInfo1 field */ diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index d403c12f7978..ee148573c114 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -82,7 +82,7 @@ struct pcmcia_device { /* the hardware "function" device; certain subdevices can * share one hardware "function" device. */ u8 func; - struct config_t* function_config; + struct config_t *function_config; struct list_head socket_device_list; @@ -121,14 +121,14 @@ struct pcmcia_device { u16 manf_id; u16 card_id; - char * prod_id[4]; + char *prod_id[4]; u64 dma_mask; struct device dev; #ifdef CONFIG_PCMCIA_IOCTL /* device driver wanted by cardmgr */ - struct pcmcia_driver * cardmgr; + struct pcmcia_driver *cardmgr; #endif /* data private to drivers */ diff --git a/include/pcmcia/mem_op.h b/include/pcmcia/mem_op.h index 8d19b9401a5b..0fa06e5d5376 100644 --- a/include/pcmcia/mem_op.h +++ b/include/pcmcia/mem_op.h @@ -15,8 +15,8 @@ #ifndef _LINUX_MEM_OP_H #define _LINUX_MEM_OP_H +#include <linux/io.h> #include <asm/uaccess.h> -#include <asm/io.h> /* If UNSAFE_MEMCPY is defined, we use the (optimized) system routines diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 7c23be706f12..cbfba885eb85 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -154,7 +154,7 @@ struct pcmcia_socket { struct list_head socket_list; struct completion socket_released; - /* deprecated */ + /* deprecated */ unsigned int sock; /* socket number */ @@ -164,7 +164,7 @@ struct pcmcia_socket { u_int map_size; u_int io_offset; u_int pci_irq; - struct pci_dev * cb_dev; + struct pci_dev *cb_dev; /* socket setup is done so resources should be able to be allocated. @@ -179,9 +179,9 @@ struct pcmcia_socket { u8 reserved:5; /* socket operations */ - struct pccard_operations * ops; - struct pccard_resource_ops * resource_ops; - void * resource_data; + struct pccard_operations *ops; + struct pccard_resource_ops *resource_ops; + void *resource_data; /* Zoom video behaviour is so chip specific its not worth adding this to _ops */ @@ -245,7 +245,7 @@ struct pcmcia_socket { /* cardbus (32-bit) */ #ifdef CONFIG_CARDBUS - struct resource * cb_cis_res; + struct resource *cb_cis_res; void __iomem *cb_cis_virt; #endif /* CONFIG_CARDBUS */ diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 318f76535bd4..d0b6cd3afb2f 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -38,7 +38,7 @@ TRACE_EVENT(ext4_free_inode, __entry->blocks = inode->i_blocks; ), - TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu", + TP_printk("dev %s ino %lu mode 0%o uid %u gid %u blocks %llu", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, __entry->mode, __entry->uid, __entry->gid, (unsigned long long) __entry->blocks) @@ -61,7 +61,7 @@ TRACE_EVENT(ext4_request_inode, __entry->mode = mode; ), - TP_printk("dev %s dir %lu mode %d", + TP_printk("dev %s dir %lu mode 0%o", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->dir, __entry->mode) ); @@ -85,7 +85,7 @@ TRACE_EVENT(ext4_allocate_inode, __entry->mode = mode; ), - TP_printk("dev %s ino %lu dir %lu mode %d", + TP_printk("dev %s ino %lu dir %lu mode 0%o", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, (unsigned long) __entry->dir, __entry->mode) ); @@ -305,7 +305,6 @@ TRACE_EVENT(ext4_da_writepages_result, __field( int, ret ) __field( int, pages_written ) __field( long, pages_skipped ) - __field( char, encountered_congestion ) __field( char, more_io ) __field( char, no_nrwrite_index_update ) __field( pgoff_t, writeback_index ) @@ -317,17 +316,16 @@ TRACE_EVENT(ext4_da_writepages_result, __entry->ret = ret; __entry->pages_written = pages_written; __entry->pages_skipped = wbc->pages_skipped; - __entry->encountered_congestion = wbc->encountered_congestion; __entry->more_io = wbc->more_io; __entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update; __entry->writeback_index = inode->i_mapping->writeback_index; ), - TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d writeback_index %lu", + TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld more_io %d no_nrwrite_index_update %d writeback_index %lu", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, __entry->ret, __entry->pages_written, __entry->pages_skipped, - __entry->encountered_congestion, __entry->more_io, + __entry->more_io, __entry->no_nrwrite_index_update, (unsigned long) __entry->writeback_index) ); @@ -591,30 +589,32 @@ TRACE_EVENT(ext4_allocate_blocks, TRACE_EVENT(ext4_free_blocks, TP_PROTO(struct inode *inode, __u64 block, unsigned long count, - int metadata), + int flags), - TP_ARGS(inode, block, count, metadata), + TP_ARGS(inode, block, count, flags), TP_STRUCT__entry( __field( dev_t, dev ) __field( ino_t, ino ) + __field( umode_t, mode ) __field( __u64, block ) __field( unsigned long, count ) - __field( int, metadata ) - + __field( int, flags ) ), TP_fast_assign( __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; __entry->block = block; __entry->count = count; - __entry->metadata = metadata; + __entry->flags = flags; ), - TP_printk("dev %s ino %lu block %llu count %lu metadata %d", + TP_printk("dev %s ino %lu mode 0%o block %llu count %lu flags %d", jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, - __entry->block, __entry->count, __entry->metadata) + __entry->mode, __entry->block, __entry->count, + __entry->flags) ); TRACE_EVENT(ext4_sync_file, @@ -848,6 +848,32 @@ TRACE_EVENT(ext4_mballoc_free, __entry->result_len, __entry->result_logical) ); +TRACE_EVENT(ext4_forget, + TP_PROTO(struct inode *inode, int is_metadata, __u64 block), + + TP_ARGS(inode, is_metadata, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( int, is_metadata ) + __field( __u64, block ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->is_metadata = is_metadata; + __entry->block = block; + ), + + TP_printk("dev %s ino %lu mode 0%o is_metadata %d block %llu", + jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino, + __entry->mode, __entry->is_metadata, __entry->block) +); + #endif /* _TRACE_EXT4_H */ /* This part must be outside protection */ diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index e5ce87a0498d..9496b965d62a 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -301,8 +301,8 @@ TRACE_EVENT(itimer_state, __entry->interval_usec = value->it_interval.tv_usec; ), - TP_printk("which=%d expires=%lu it_value=%lu.%lu it_interval=%lu.%lu", - __entry->which, __entry->expires, + TP_printk("which=%d expires=%llu it_value=%ld.%ld it_interval=%ld.%ld", + __entry->which, (unsigned long long)__entry->expires, __entry->value_sec, __entry->value_usec, __entry->interval_sec, __entry->interval_usec) ); @@ -331,8 +331,8 @@ TRACE_EVENT(itimer_expire, __entry->pid = pid_nr(pid); ), - TP_printk("which=%d pid=%d now=%lu", __entry->which, - (int) __entry->pid, __entry->now) + TP_printk("which=%d pid=%d now=%llu", __entry->which, + (int) __entry->pid, (unsigned long long)__entry->now) ); #endif /* _TRACE_TIMER_H */ diff --git a/include/xen/xen.h b/include/xen/xen.h new file mode 100644 index 000000000000..a16402418d31 --- /dev/null +++ b/include/xen/xen.h @@ -0,0 +1,32 @@ +#ifndef _XEN_XEN_H +#define _XEN_XEN_H + +enum xen_domain_type { + XEN_NATIVE, /* running on bare hardware */ + XEN_PV_DOMAIN, /* running in a PV domain */ + XEN_HVM_DOMAIN, /* running in a Xen hvm domain */ +}; + +#ifdef CONFIG_XEN +extern enum xen_domain_type xen_domain_type; +#else +#define xen_domain_type XEN_NATIVE +#endif + +#define xen_domain() (xen_domain_type != XEN_NATIVE) +#define xen_pv_domain() (xen_domain() && \ + xen_domain_type == XEN_PV_DOMAIN) +#define xen_hvm_domain() (xen_domain() && \ + xen_domain_type == XEN_HVM_DOMAIN) + +#ifdef CONFIG_XEN_DOM0 +#include <xen/interface/xen.h> +#include <asm/xen/hypervisor.h> + +#define xen_initial_domain() (xen_pv_domain() && \ + xen_start_info->flags & SIF_INITDOMAIN) +#else /* !CONFIG_XEN_DOM0 */ +#define xen_initial_domain() (0) +#endif /* CONFIG_XEN_DOM0 */ + +#endif /* _XEN_XEN_H */ |